github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/client/usermanager/client_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package usermanager_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names/v5" 9 jc "github.com/juju/testing/checkers" 10 "go.uber.org/mock/gomock" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/api/base/mocks" 14 "github.com/juju/juju/api/client/usermanager" 15 apiservererrors "github.com/juju/juju/apiserver/errors" 16 "github.com/juju/juju/rpc/params" 17 ) 18 19 type usermanagerSuite struct{} 20 21 var _ = gc.Suite(&usermanagerSuite{}) 22 23 func (s *usermanagerSuite) TestAddExistingUser(c *gc.C) { 24 ctrl := gomock.NewController(c) 25 defer ctrl.Finish() 26 27 args := params.AddUsers{ 28 Users: []params.AddUser{{Username: "foobar", DisplayName: "Foo Bar", Password: "password"}}, 29 } 30 31 result := new(params.AddUserResults) 32 results := params.AddUserResults{ 33 Results: []params.AddUserResult{ 34 { 35 Tag: "user-foobar", 36 SecretKey: []byte("passwedfdd"), 37 Error: apiservererrors.ServerError(errors.Annotate(errors.New("user foobar already exists"), "failed to create user")), 38 }, 39 }, 40 } 41 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 42 mockFacadeCaller.EXPECT().FacadeCall("AddUser", args, result).SetArg(2, results).Return(nil) 43 44 client := usermanager.NewClientFromCaller(mockFacadeCaller) 45 _, _, err := client.AddUser("foobar", "Foo Bar", "password") 46 c.Assert(err, gc.ErrorMatches, "failed to create user: user foobar already exists") 47 } 48 49 func (s *usermanagerSuite) TestAddUserResponseError(c *gc.C) { 50 ctrl := gomock.NewController(c) 51 defer ctrl.Finish() 52 53 args := params.AddUsers{ 54 Users: []params.AddUser{{Username: "foobar", DisplayName: "Foo Bar", Password: "password"}}, 55 } 56 57 result := new(params.AddUserResults) 58 results := params.AddUserResults{ 59 Results: make([]params.AddUserResult, len(args.Users)), 60 } 61 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 62 mockFacadeCaller.EXPECT().FacadeCall("AddUser", args, result).SetArg(2, results).Return(errors.New("call error")) 63 64 client := usermanager.NewClientFromCaller(mockFacadeCaller) 65 _, _, err := client.AddUser("foobar", "Foo Bar", "password") 66 c.Assert(err, gc.ErrorMatches, "call error") 67 } 68 69 func (s *usermanagerSuite) TestAddUserResultCount(c *gc.C) { 70 ctrl := gomock.NewController(c) 71 defer ctrl.Finish() 72 73 args := params.AddUsers{ 74 Users: []params.AddUser{{Username: "foobar", DisplayName: "Foo Bar", Password: "password"}}, 75 } 76 77 result := new(params.AddUserResults) 78 results := params.AddUserResults{ 79 Results: make([]params.AddUserResult, 2), 80 } 81 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 82 mockFacadeCaller.EXPECT().FacadeCall("AddUser", args, result).SetArg(2, results).Return(nil) 83 84 client := usermanager.NewClientFromCaller(mockFacadeCaller) 85 _, _, err := client.AddUser("foobar", "Foo Bar", "password") 86 c.Assert(err, gc.ErrorMatches, "expected 1 result, got 2") 87 } 88 89 func (s *usermanagerSuite) TestRemoveUser(c *gc.C) { 90 ctrl := gomock.NewController(c) 91 defer ctrl.Finish() 92 93 result := new(params.ErrorResults) 94 results := params.ErrorResults{ 95 make([]params.ErrorResult, 1), 96 } 97 arg := params.Entities{ 98 []params.Entity{{"user-jjam"}}, 99 } 100 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 101 mockFacadeCaller.EXPECT().FacadeCall("RemoveUser", arg, result).SetArg(2, results).Return(nil) 102 client := usermanager.NewClientFromCaller(mockFacadeCaller) 103 // Delete the user. 104 err := client.RemoveUser("jjam") 105 c.Assert(err, jc.ErrorIsNil) 106 } 107 108 func (s *usermanagerSuite) TestDisableUser(c *gc.C) { 109 ctrl := gomock.NewController(c) 110 defer ctrl.Finish() 111 112 user := names.NewUserTag("foobar") 113 args := params.Entities{ 114 []params.Entity{{"user-foobar"}}, 115 } 116 result := new(params.ErrorResults) 117 results := params.ErrorResults{ 118 Results: make([]params.ErrorResult, 1), 119 } 120 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 121 mockFacadeCaller.EXPECT().FacadeCall("DisableUser", args, result).SetArg(2, results).Return(nil) 122 123 client := usermanager.NewClientFromCaller(mockFacadeCaller) 124 err := client.DisableUser(user.Name()) 125 c.Assert(err, jc.ErrorIsNil) 126 } 127 128 func (s *usermanagerSuite) TestEnableUser(c *gc.C) { 129 ctrl := gomock.NewController(c) 130 defer ctrl.Finish() 131 132 user := names.NewUserTag("foobar") 133 args := params.Entities{Entities: []params.Entity{{user.String()}}} 134 result := new(params.ErrorResults) 135 results := params.ErrorResults{Results: make([]params.ErrorResult, 1)} 136 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 137 mockFacadeCaller.EXPECT().FacadeCall("EnableUser", args, result).SetArg(2, results).Return(nil) 138 client := usermanager.NewClientFromCaller(mockFacadeCaller) 139 err := client.EnableUser(user.Name()) 140 c.Assert(err, jc.ErrorIsNil) 141 } 142 143 func (s *usermanagerSuite) TestCantRemoveAdminUser(c *gc.C) { 144 ctrl := gomock.NewController(c) 145 defer ctrl.Finish() 146 147 admin := names.NewUserTag("admin") 148 args := params.Entities{ 149 []params.Entity{{"user-admin"}}, 150 } 151 result := new(params.ErrorResults) 152 results := params.ErrorResults{ 153 []params.ErrorResult{{Error: ¶ms.Error{Message: "failed to disable user: cannot disable controller model owner"}}}, 154 } 155 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 156 mockFacadeCaller.EXPECT().FacadeCall("DisableUser", args, result).SetArg(2, results).Return(nil) 157 158 client := usermanager.NewClientFromCaller(mockFacadeCaller) 159 err := client.DisableUser(admin.Name()) 160 c.Assert(err, gc.ErrorMatches, "failed to disable user: cannot disable controller model owner") 161 } 162 163 func (s *usermanagerSuite) TestUserInfo(c *gc.C) { 164 ctrl := gomock.NewController(c) 165 defer ctrl.Finish() 166 167 admin := names.NewUserTag("admin") 168 args := params.UserInfoRequest{ 169 Entities: []params.Entity{{Tag: "user-foobar"}}, 170 IncludeDisabled: true, 171 } 172 result := new(params.UserInfoResults) 173 results := params.UserInfoResults{ 174 Results: []params.UserInfoResult{ 175 { 176 Result: ¶ms.UserInfo{ 177 Access: "login", 178 Username: "foobar", 179 DisplayName: "Foo Bar", 180 CreatedBy: admin.Name(), 181 }, 182 }, 183 }, 184 } 185 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 186 mockFacadeCaller.EXPECT().FacadeCall("UserInfo", args, result).SetArg(2, results).Return(nil) 187 188 client := usermanager.NewClientFromCaller(mockFacadeCaller) 189 obtained, err := client.UserInfo([]string{"foobar"}, usermanager.AllUsers) 190 c.Assert(err, jc.ErrorIsNil) 191 expected := []params.UserInfo{ 192 { 193 Username: "foobar", 194 DisplayName: "Foo Bar", 195 Access: "login", 196 CreatedBy: "admin", 197 }, 198 } 199 200 c.Assert(obtained, jc.DeepEquals, expected) 201 } 202 203 func (s *usermanagerSuite) TestUserInfoMoreThanOneResult(c *gc.C) { 204 ctrl := gomock.NewController(c) 205 defer ctrl.Finish() 206 207 args := params.UserInfoRequest{ 208 IncludeDisabled: true, 209 } 210 result := new(params.UserInfoResults) 211 results := params.UserInfoResults{ 212 []params.UserInfoResult{ 213 {Result: ¶ms.UserInfo{Username: "first"}}, 214 {Result: ¶ms.UserInfo{Username: "second"}}, 215 }, 216 } 217 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 218 mockFacadeCaller.EXPECT().FacadeCall("UserInfo", args, result).SetArg(2, results).Return(nil) 219 220 client := usermanager.NewClientFromCaller(mockFacadeCaller) 221 obtained, err := client.UserInfo(nil, usermanager.AllUsers) 222 c.Assert(err, jc.ErrorIsNil) 223 224 expected := []params.UserInfo{ 225 {Username: "first"}, 226 {Username: "second"}, 227 } 228 229 c.Assert(obtained, jc.DeepEquals, expected) 230 } 231 232 func (s *usermanagerSuite) TestUserInfoMoreThanOneError(c *gc.C) { 233 ctrl := gomock.NewController(c) 234 defer ctrl.Finish() 235 236 args := params.UserInfoRequest{ 237 Entities: []params.Entity{{Tag: "user-foo"}, {Tag: "user-bar"}}, 238 IncludeDisabled: true, 239 } 240 result := new(params.UserInfoResults) 241 results := params.UserInfoResults{ 242 []params.UserInfoResult{ 243 {Error: ¶ms.Error{Message: "first error"}}, 244 {Error: ¶ms.Error{Message: "second error"}}, 245 }, 246 } 247 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 248 mockFacadeCaller.EXPECT().FacadeCall("UserInfo", args, result).SetArg(2, results).Return(nil) 249 250 client := usermanager.NewClientFromCaller(mockFacadeCaller) 251 _, err := client.UserInfo([]string{"foo", "bar"}, usermanager.AllUsers) 252 c.Assert(err, gc.ErrorMatches, "foo: first error, bar: second error") 253 } 254 255 func (s *usermanagerSuite) TestModelUserInfo(c *gc.C) { 256 ctrl := gomock.NewController(c) 257 defer ctrl.Finish() 258 259 args := params.Entities{ 260 []params.Entity{{Tag: names.NewModelTag("deadbeef-0bad-400d-8000-4b1d0d06f00d").String()}}, 261 } 262 result := new(params.ModelUserInfoResults) 263 results := params.ModelUserInfoResults{ 264 []params.ModelUserInfoResult{ 265 {Result: ¶ms.ModelUserInfo{UserName: "one"}}, 266 {Result: ¶ms.ModelUserInfo{UserName: "two"}}, 267 {Result: ¶ms.ModelUserInfo{UserName: "three"}}, 268 }, 269 } 270 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 271 mockFacadeCaller.EXPECT().FacadeCall("ModelUserInfo", args, result).SetArg(2, results).Return(nil) 272 273 client := usermanager.NewClientFromCaller(mockFacadeCaller) 274 obtained, err := client.ModelUserInfo("deadbeef-0bad-400d-8000-4b1d0d06f00d") 275 c.Assert(err, jc.ErrorIsNil) 276 c.Assert(obtained, jc.DeepEquals, []params.ModelUserInfo{ 277 {UserName: "one"}, 278 {UserName: "two"}, 279 {UserName: "three"}, 280 }) 281 } 282 283 func (s *usermanagerSuite) TestSetUserPassword(c *gc.C) { 284 ctrl := gomock.NewController(c) 285 defer ctrl.Finish() 286 287 tag := names.NewUserTag("admin") 288 args := params.EntityPasswords{ 289 []params.EntityPassword{{Tag: tag.String(), Password: "new-password"}}, 290 } 291 result := new(params.ErrorResults) 292 results := params.ErrorResults{Results: make([]params.ErrorResult, 1)} 293 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 294 mockFacadeCaller.EXPECT().FacadeCall("SetPassword", args, result).SetArg(2, results).Return(nil) 295 296 client := usermanager.NewClientFromCaller(mockFacadeCaller) 297 err := client.SetPassword(tag.Name(), "new-password") 298 c.Assert(err, jc.ErrorIsNil) 299 } 300 301 func (s *usermanagerSuite) TestSetUserPasswordCanonical(c *gc.C) { 302 ctrl := gomock.NewController(c) 303 defer ctrl.Finish() 304 305 tag := names.NewUserTag("admin") 306 args := params.EntityPasswords{[]params.EntityPassword{{Tag: tag.String(), Password: "new-password"}}} 307 result := new(params.ErrorResults) 308 results := params.ErrorResults{Results: make([]params.ErrorResult, 1)} 309 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 310 mockFacadeCaller.EXPECT().FacadeCall("SetPassword", args, result).SetArg(2, results).Return(nil) 311 312 client := usermanager.NewClientFromCaller(mockFacadeCaller) 313 err := client.SetPassword(tag.Id(), "new-password") 314 c.Assert(err, jc.ErrorIsNil) 315 } 316 317 func (s *usermanagerSuite) TestSetUserPasswordBadName(c *gc.C) { 318 ctrl := gomock.NewController(c) 319 defer ctrl.Finish() 320 321 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 322 323 client := usermanager.NewClientFromCaller(mockFacadeCaller) 324 err := client.SetPassword("not!good", "new-password") 325 c.Assert(err, gc.ErrorMatches, `"not!good" is not a valid username`) 326 } 327 328 func (s *usermanagerSuite) TestResetPasswordResponseError(c *gc.C) { 329 ctrl := gomock.NewController(c) 330 defer ctrl.Finish() 331 332 args := params.Entities{ 333 []params.Entity{{Tag: names.NewUserTag("foobar").String()}}, 334 } 335 result := new(params.AddUserResults) 336 results := params.AddUserResults{Results: []params.AddUserResult{{Error: ¶ms.Error{Message: "boom"}}}} 337 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 338 mockFacadeCaller.EXPECT().FacadeCall("ResetPassword", args, result).SetArg(2, results).Return(nil) 339 340 client := usermanager.NewClientFromCaller(mockFacadeCaller) 341 _, err := client.ResetPassword("foobar") 342 c.Assert(err, gc.ErrorMatches, "boom") 343 } 344 345 func (s *usermanagerSuite) TestResetPassword(c *gc.C) { 346 ctrl := gomock.NewController(c) 347 defer ctrl.Finish() 348 349 key := []byte("no cats or dragons here") 350 args := params.Entities{ 351 []params.Entity{{Tag: names.NewUserTag("foobar").String()}}, 352 } 353 result := new(params.AddUserResults) 354 results := params.AddUserResults{Results: []params.AddUserResult{{Tag: "user-foobar", SecretKey: key}}} 355 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 356 mockFacadeCaller.EXPECT().FacadeCall("ResetPassword", args, result).SetArg(2, results).Return(nil) 357 358 client := usermanager.NewClientFromCaller(mockFacadeCaller) 359 res, err := client.ResetPassword("foobar") 360 c.Assert(err, jc.ErrorIsNil) 361 c.Assert(res, gc.DeepEquals, key) 362 } 363 364 func (s *usermanagerSuite) TestResetPasswordInvalidUsername(c *gc.C) { 365 ctrl := gomock.NewController(c) 366 defer ctrl.Finish() 367 368 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 369 client := usermanager.NewClientFromCaller(mockFacadeCaller) 370 _, err := client.ResetPassword("not/valid") 371 c.Assert(err, gc.ErrorMatches, `invalid user name "not/valid"`) 372 } 373 374 func (s *usermanagerSuite) TestResetPasswordResultCount(c *gc.C) { 375 ctrl := gomock.NewController(c) 376 defer ctrl.Finish() 377 378 args := params.Entities{[]params.Entity{{Tag: names.NewUserTag("foobar").String()}}} 379 result := new(params.AddUserResults) 380 results := params.AddUserResults{Results: make([]params.AddUserResult, 2)} 381 mockFacadeCaller := mocks.NewMockFacadeCaller(ctrl) 382 mockFacadeCaller.EXPECT().FacadeCall("ResetPassword", args, result).SetArg(2, results).Return(nil) 383 384 client := usermanager.NewClientFromCaller(mockFacadeCaller) 385 _, err := client.ResetPassword("foobar") 386 c.Assert(err, gc.ErrorMatches, "expected 1 result, got 2") 387 }