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 }