github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/permissions_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common_test 5 6 import ( 7 "github.com/juju/errors" 8 jc "github.com/juju/testing/checkers" 9 gc "gopkg.in/check.v1" 10 "gopkg.in/juju/names.v2" 11 12 "github.com/juju/juju/apiserver/common" 13 "github.com/juju/juju/permission" 14 "github.com/juju/juju/testing" 15 ) 16 17 type PermissionSuite struct { 18 testing.BaseSuite 19 } 20 21 var _ = gc.Suite(&PermissionSuite{}) 22 23 type fakeUserAccess struct { 24 subjects []names.UserTag 25 objects []names.Tag 26 access permission.Access 27 err error 28 } 29 30 func (f *fakeUserAccess) call(subject names.UserTag, object names.Tag) (permission.Access, error) { 31 f.subjects = append(f.subjects, subject) 32 f.objects = append(f.objects, object) 33 return f.access, f.err 34 } 35 36 func (r *PermissionSuite) TestNoUserTagLacksPermission(c *gc.C) { 37 nonUser := names.NewModelTag("beef1beef1-0000-0000-000011112222") 38 target := names.NewModelTag("beef1beef2-0000-0000-000011112222") 39 hasPermission, err := common.HasPermission((&fakeUserAccess{}).call, nonUser, permission.ReadAccess, target) 40 c.Assert(hasPermission, jc.IsFalse) 41 c.Assert(err, jc.ErrorIsNil) 42 } 43 44 func (r *PermissionSuite) TestHasPermission(c *gc.C) { 45 testCases := []struct { 46 title string 47 userGetterAccess permission.Access 48 user names.UserTag 49 target names.Tag 50 access permission.Access 51 expected bool 52 }{ 53 { 54 title: "user has lesser permissions than required", 55 userGetterAccess: permission.ReadAccess, 56 user: names.NewUserTag("validuser"), 57 target: names.NewModelTag("beef1beef2-0000-0000-000011112222"), 58 access: permission.WriteAccess, 59 expected: false, 60 }, 61 { 62 title: "user has equal permission than required", 63 userGetterAccess: permission.WriteAccess, 64 user: names.NewUserTag("validuser"), 65 target: names.NewModelTag("beef1beef2-0000-0000-000011112222"), 66 access: permission.WriteAccess, 67 expected: true, 68 }, 69 { 70 title: "user has greater permission than required", 71 userGetterAccess: permission.AdminAccess, 72 user: names.NewUserTag("validuser"), 73 target: names.NewModelTag("beef1beef2-0000-0000-000011112222"), 74 access: permission.WriteAccess, 75 expected: true, 76 }, 77 { 78 title: "user requests model permission on controller", 79 userGetterAccess: permission.AdminAccess, 80 user: names.NewUserTag("validuser"), 81 target: names.NewModelTag("beef1beef2-0000-0000-000011112222"), 82 access: permission.AddModelAccess, 83 expected: false, 84 }, 85 { 86 title: "user requests controller permission on model", 87 userGetterAccess: permission.AdminAccess, 88 user: names.NewUserTag("validuser"), 89 target: names.NewControllerTag("beef1beef2-0000-0000-000011112222"), 90 access: permission.AdminAccess, // notice user has this permission for model. 91 expected: false, 92 }, 93 { 94 title: "controller permissions also work", 95 userGetterAccess: permission.SuperuserAccess, 96 user: names.NewUserTag("validuser"), 97 target: names.NewControllerTag("beef1beef2-0000-0000-000011112222"), 98 access: permission.SuperuserAccess, 99 expected: true, 100 }, 101 { 102 title: "cloud permissions work", 103 userGetterAccess: permission.AddModelAccess, 104 user: names.NewUserTag("validuser"), 105 target: names.NewCloudTag("mycloud"), 106 access: permission.AddModelAccess, 107 expected: true, 108 }, 109 { 110 title: "user has lesser cloud permissions than required", 111 userGetterAccess: permission.NoAccess, 112 user: names.NewUserTag("validuser"), 113 target: names.NewCloudTag("mycloud"), 114 access: permission.AddModelAccess, 115 expected: false, 116 }, 117 { 118 title: "user has lesser offer permissions than required", 119 userGetterAccess: permission.ReadAccess, 120 user: names.NewUserTag("validuser"), 121 target: names.NewApplicationOfferTag("hosted-mysql"), 122 access: permission.WriteAccess, 123 expected: false, 124 }, 125 { 126 title: "user has equal offer permission than required", 127 userGetterAccess: permission.ConsumeAccess, 128 user: names.NewUserTag("validuser"), 129 target: names.NewApplicationOfferTag("hosted-mysql"), 130 access: permission.ConsumeAccess, 131 expected: true, 132 }, 133 { 134 title: "user has greater offer permission than required", 135 userGetterAccess: permission.AdminAccess, 136 user: names.NewUserTag("validuser"), 137 target: names.NewApplicationOfferTag("hosted-mysql"), 138 access: permission.ConsumeAccess, 139 expected: true, 140 }, 141 { 142 title: "user requests controller permission on offer", 143 userGetterAccess: permission.ReadAccess, 144 user: names.NewUserTag("validuser"), 145 target: names.NewApplicationOfferTag("hosted-mysql"), 146 access: permission.AddModelAccess, 147 expected: false, 148 }, 149 } 150 for i, t := range testCases { 151 userGetter := &fakeUserAccess{ 152 access: t.userGetterAccess, 153 } 154 c.Logf("HasPermission test n %d: %s", i, t.title) 155 hasPermission, err := common.HasPermission(userGetter.call, t.user, t.access, t.target) 156 c.Assert(hasPermission, gc.Equals, t.expected) 157 c.Assert(err, jc.ErrorIsNil) 158 } 159 160 } 161 162 func (r *PermissionSuite) TestUserGetterErrorReturns(c *gc.C) { 163 user := names.NewUserTag("validuser") 164 target := names.NewModelTag("beef1beef2-0000-0000-000011112222") 165 userGetter := &fakeUserAccess{ 166 access: permission.NoAccess, 167 err: errors.NotFoundf("a user"), 168 } 169 hasPermission, err := common.HasPermission(userGetter.call, user, permission.ReadAccess, target) 170 c.Assert(err, jc.ErrorIsNil) 171 c.Assert(hasPermission, jc.IsFalse) 172 c.Assert(userGetter.subjects, gc.HasLen, 1) 173 c.Assert(userGetter.subjects[0], gc.DeepEquals, user) 174 c.Assert(userGetter.objects, gc.HasLen, 1) 175 c.Assert(userGetter.objects[0], gc.DeepEquals, target) 176 } 177 178 type fakeEveryoneUserAccess struct { 179 user permission.Access 180 everyone permission.Access 181 } 182 183 func (f *fakeEveryoneUserAccess) call(subject names.UserTag, object names.Tag) (permission.Access, error) { 184 if subject.Id() == common.EveryoneTagName { 185 return f.everyone, nil 186 } 187 return f.user, nil 188 } 189 190 func (r *PermissionSuite) TestEveryoneAtExternal(c *gc.C) { 191 testCases := []struct { 192 title string 193 userGetterAccess permission.Access 194 everyoneAccess permission.Access 195 user names.UserTag 196 target names.Tag 197 access permission.Access 198 expected bool 199 }{ 200 { 201 title: "user has lesser permissions than everyone", 202 userGetterAccess: permission.LoginAccess, 203 everyoneAccess: permission.SuperuserAccess, 204 user: names.NewUserTag("validuser@external"), 205 target: names.NewControllerTag("beef1beef2-0000-0000-000011112222"), 206 access: permission.SuperuserAccess, 207 expected: true, 208 }, 209 { 210 title: "user has greater permissions than everyone", 211 userGetterAccess: permission.SuperuserAccess, 212 everyoneAccess: permission.LoginAccess, 213 user: names.NewUserTag("validuser@external"), 214 target: names.NewControllerTag("beef1beef2-0000-0000-000011112222"), 215 access: permission.SuperuserAccess, 216 expected: true, 217 }, 218 { 219 title: "everibody not considered if user is local", 220 userGetterAccess: permission.LoginAccess, 221 everyoneAccess: permission.SuperuserAccess, 222 user: names.NewUserTag("validuser"), 223 target: names.NewControllerTag("beef1beef2-0000-0000-000011112222"), 224 access: permission.SuperuserAccess, 225 expected: false, 226 }, 227 } 228 229 for i, t := range testCases { 230 userGetter := &fakeEveryoneUserAccess{ 231 user: t.userGetterAccess, 232 everyone: t.everyoneAccess, 233 } 234 c.Logf(`HasPermission "everyone" test n %d: %s`, i, t.title) 235 hasPermission, err := common.HasPermission(userGetter.call, t.user, t.access, t.target) 236 c.Assert(err, jc.ErrorIsNil) 237 c.Assert(hasPermission, gc.Equals, t.expected) 238 } 239 }