github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/testing/fakeauthorizer.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package testing
     5  
     6  import (
     7  	"strings"
     8  
     9  	"gopkg.in/juju/names.v2"
    10  
    11  	"github.com/juju/juju/permission"
    12  )
    13  
    14  // FakeAuthorizer implements the facade.Authorizer interface.
    15  type FakeAuthorizer struct {
    16  	Tag         names.Tag
    17  	Controller  bool
    18  	ModelUUID   string
    19  	AdminTag    names.UserTag
    20  	HasWriteTag names.UserTag
    21  }
    22  
    23  func (fa FakeAuthorizer) AuthOwner(tag names.Tag) bool {
    24  	return fa.Tag == tag
    25  }
    26  
    27  func (fa FakeAuthorizer) AuthController() bool {
    28  	return fa.Controller
    29  }
    30  
    31  // AuthMachineAgent returns whether the current client is a machine agent.
    32  func (fa FakeAuthorizer) AuthMachineAgent() bool {
    33  	_, isMachine := fa.GetAuthTag().(names.MachineTag)
    34  	return isMachine
    35  }
    36  
    37  // AuthApplicationAgent returns whether the current client is an application operator.
    38  func (fa FakeAuthorizer) AuthApplicationAgent() bool {
    39  	_, isApp := fa.GetAuthTag().(names.ApplicationTag)
    40  	return isApp
    41  }
    42  
    43  // AuthUnitAgent returns whether the current client is a unit agent.
    44  func (fa FakeAuthorizer) AuthUnitAgent() bool {
    45  	_, isUnit := fa.GetAuthTag().(names.UnitTag)
    46  	return isUnit
    47  }
    48  
    49  // AuthClient returns whether the authenticated entity is a client
    50  // user.
    51  func (fa FakeAuthorizer) AuthClient() bool {
    52  	_, isUser := fa.GetAuthTag().(names.UserTag)
    53  	return isUser
    54  }
    55  
    56  func (fa FakeAuthorizer) GetAuthTag() names.Tag {
    57  	return fa.Tag
    58  }
    59  
    60  // HasPermission returns true if the logged in user is admin or has a name equal to
    61  // the pre-set admin tag.
    62  func (fa FakeAuthorizer) HasPermission(operation permission.Access, target names.Tag) (bool, error) {
    63  	if fa.Tag.Kind() == names.UserTagKind {
    64  		ut := fa.Tag.(names.UserTag)
    65  		emptyTag := names.UserTag{}
    66  		if fa.AdminTag != emptyTag && ut == fa.AdminTag {
    67  			return true, nil
    68  		}
    69  		if ut == fa.HasWriteTag && (operation == permission.WriteAccess || operation == permission.ReadAccess) {
    70  			return true, nil
    71  		}
    72  
    73  		uTag := fa.Tag.(names.UserTag)
    74  		return nameBasedHasPermission(uTag.Name(), operation, target), nil
    75  	}
    76  	return false, nil
    77  }
    78  
    79  // nameBasedHasPermission provides a way for tests to fake the expected outcomes of the
    80  // authentication.
    81  // setting permissionname as the name that user will always have the given permission.
    82  // setting permissionnamemodeltagstring as the name will make that user have the given
    83  // permission only in that model.
    84  func nameBasedHasPermission(name string, operation permission.Access, target names.Tag) bool {
    85  	var perm permission.Access
    86  	switch {
    87  	case strings.HasPrefix(name, string(permission.SuperuserAccess)):
    88  		return operation == permission.SuperuserAccess
    89  	case strings.HasPrefix(name, string(permission.AddModelAccess)):
    90  		return operation == permission.AddModelAccess
    91  	case strings.HasPrefix(name, string(permission.LoginAccess)):
    92  		return operation == permission.LoginAccess
    93  	case strings.HasPrefix(name, string(permission.AdminAccess)):
    94  		perm = permission.AdminAccess
    95  	case strings.HasPrefix(name, string(permission.WriteAccess)):
    96  		perm = permission.WriteAccess
    97  	case strings.HasPrefix(name, string(permission.ConsumeAccess)):
    98  		perm = permission.ConsumeAccess
    99  	case strings.HasPrefix(name, string(permission.ReadAccess)):
   100  		perm = permission.ReadAccess
   101  	default:
   102  		return false
   103  	}
   104  	name = name[len(perm):]
   105  	if len(name) == 0 && perm == permission.AdminAccess {
   106  		return true
   107  	}
   108  	if len(name) == 0 {
   109  		return operation == perm
   110  	}
   111  	if name[0] == '-' {
   112  		name = name[1:]
   113  	}
   114  	targetTag, err := names.ParseTag(name)
   115  	if err != nil {
   116  		return false
   117  	}
   118  	return operation == perm && targetTag.String() == target.String()
   119  }
   120  
   121  // ConnectedModel returns the UUID of the model the current client is
   122  // connected to.
   123  func (fa FakeAuthorizer) ConnectedModel() string {
   124  	return fa.ModelUUID
   125  }
   126  
   127  // UserHasPermission returns true if the passed user is admin or has a name equal to
   128  // the pre-set admin tag.
   129  func (fa FakeAuthorizer) UserHasPermission(user names.UserTag, operation permission.Access, target names.Tag) (bool, error) {
   130  	if user.Name() == "admin" {
   131  		return true, nil
   132  	}
   133  	emptyTag := names.UserTag{}
   134  	if fa.AdminTag != emptyTag && user == fa.AdminTag {
   135  		return true, nil
   136  	}
   137  	ut := fa.Tag.(names.UserTag)
   138  	if ut == user {
   139  		return true, nil
   140  	}
   141  	return false, nil
   142  }