github.com/weaviate/weaviate@v1.24.6/usecases/auth/authorization/adminlist/authorizer.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package adminlist
    13  
    14  import (
    15  	"github.com/weaviate/weaviate/entities/models"
    16  	"github.com/weaviate/weaviate/usecases/auth/authorization/errors"
    17  )
    18  
    19  const AnonymousPrincipalUsername = "anonymous"
    20  
    21  // Authorizer provides either full (admin) or no access
    22  type Authorizer struct {
    23  	adminUsers     map[string]int
    24  	readOnlyUsers  map[string]int
    25  	adminGroups    map[string]int
    26  	readOnlyGroups map[string]int
    27  }
    28  
    29  // New Authorizer using the AdminList method
    30  func New(cfg Config) *Authorizer {
    31  	a := &Authorizer{}
    32  	a.addAdminUserList(cfg.Users)
    33  	a.addReadOnlyUserList(cfg.ReadOnlyUsers)
    34  	a.addAdminGroupList(cfg.Groups)
    35  	a.addReadOnlyGroupList(cfg.ReadOnlyGroups)
    36  	return a
    37  }
    38  
    39  // Authorize will give full access (to any resource!) if the user is part of
    40  // the admin list or no access at all if they are not
    41  func (a *Authorizer) Authorize(principal *models.Principal, verb, resource string) error {
    42  	if principal == nil {
    43  		principal = newAnonymousPrincipal()
    44  	}
    45  
    46  	if _, ok := a.adminUsers[principal.Username]; ok {
    47  		return nil
    48  	}
    49  
    50  	for _, group := range principal.Groups {
    51  		if _, ok := a.adminGroups[group]; ok {
    52  			return nil
    53  		}
    54  	}
    55  
    56  	if verb == "get" || verb == "list" {
    57  		if _, ok := a.readOnlyUsers[principal.Username]; ok {
    58  			return nil
    59  		}
    60  		for _, group := range principal.Groups {
    61  			if _, ok := a.readOnlyGroups[group]; ok {
    62  				return nil
    63  			}
    64  		}
    65  	}
    66  
    67  	return errors.NewForbidden(principal, verb, resource)
    68  }
    69  
    70  func (a *Authorizer) addAdminUserList(users []string) {
    71  	// build a map for more efficient lookup on long lists
    72  	if a.adminUsers == nil {
    73  		a.adminUsers = map[string]int{}
    74  	}
    75  
    76  	for _, user := range users {
    77  		a.adminUsers[user] = 1
    78  	}
    79  }
    80  
    81  func (a *Authorizer) addReadOnlyUserList(users []string) {
    82  	// build a map for more efficient lookup on long lists
    83  	if a.readOnlyUsers == nil {
    84  		a.readOnlyUsers = map[string]int{}
    85  	}
    86  
    87  	for _, user := range users {
    88  		a.readOnlyUsers[user] = 1
    89  	}
    90  }
    91  
    92  func (a *Authorizer) addAdminGroupList(groups []string) {
    93  	// build a map for more efficient lookup on long lists
    94  	if a.adminGroups == nil {
    95  		a.adminGroups = map[string]int{}
    96  	}
    97  
    98  	for _, group := range groups {
    99  		a.adminGroups[group] = 1
   100  	}
   101  }
   102  
   103  func (a *Authorizer) addReadOnlyGroupList(groups []string) {
   104  	// build a map for more efficient lookup on long lists
   105  	if a.readOnlyGroups == nil {
   106  		a.readOnlyGroups = map[string]int{}
   107  	}
   108  
   109  	for _, group := range groups {
   110  		a.readOnlyGroups[group] = 1
   111  	}
   112  }
   113  
   114  func newAnonymousPrincipal() *models.Principal {
   115  	return &models.Principal{
   116  		Username: AnonymousPrincipalUsername,
   117  	}
   118  }