github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/facades/client/usermanager/usermanager_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 "fmt" 8 "sort" 9 "time" 10 11 "github.com/juju/errors" 12 "github.com/juju/names/v5" 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/apiserver/common" 17 commontesting "github.com/juju/juju/apiserver/common/testing" 18 apiservererrors "github.com/juju/juju/apiserver/errors" 19 "github.com/juju/juju/apiserver/facade/facadetest" 20 "github.com/juju/juju/apiserver/facades/client/controller" 21 "github.com/juju/juju/apiserver/facades/client/usermanager" 22 apiservertesting "github.com/juju/juju/apiserver/testing" 23 "github.com/juju/juju/core/permission" 24 jujutesting "github.com/juju/juju/juju/testing" 25 "github.com/juju/juju/rpc/params" 26 "github.com/juju/juju/state" 27 "github.com/juju/juju/testing/factory" 28 ) 29 30 type userManagerSuite struct { 31 jujutesting.JujuConnSuite 32 33 usermanager *usermanager.UserManagerAPI 34 authorizer apiservertesting.FakeAuthorizer 35 adminName string 36 resources *common.Resources 37 38 commontesting.BlockHelper 39 } 40 41 var _ = gc.Suite(&userManagerSuite{}) 42 43 func (s *userManagerSuite) SetUpTest(c *gc.C) { 44 s.JujuConnSuite.SetUpTest(c) 45 46 s.resources = common.NewResources() 47 adminTag := s.AdminUserTag(c) 48 s.adminName = adminTag.Name() 49 s.authorizer = apiservertesting.FakeAuthorizer{ 50 Tag: adminTag, 51 } 52 var err error 53 s.usermanager, err = usermanager.NewUserManagerAPI(facadetest.Context{ 54 StatePool_: s.StatePool, 55 State_: s.State, 56 Resources_: s.resources, 57 Auth_: s.authorizer, 58 }) 59 c.Assert(err, jc.ErrorIsNil) 60 61 s.BlockHelper = commontesting.NewBlockHelper(s.APIState) 62 s.AddCleanup(func(*gc.C) { s.BlockHelper.Close() }) 63 } 64 65 func (s *userManagerSuite) TestNewUserManagerAPIRefusesNonClient(c *gc.C) { 66 anAuthoriser := s.authorizer 67 anAuthoriser.Tag = names.NewMachineTag("1") 68 endPoint, err := usermanager.NewUserManagerAPI(facadetest.Context{ 69 State_: s.State, 70 Resources_: s.resources, 71 Auth_: anAuthoriser, 72 }) 73 c.Assert(endPoint, gc.IsNil) 74 c.Assert(err, gc.ErrorMatches, "permission denied") 75 } 76 77 func (s *userManagerSuite) assertAddUser(c *gc.C, access params.UserAccessPermission, sharedModelTags []string) { 78 sharedModelState := s.Factory.MakeModel(c, nil) 79 defer sharedModelState.Close() 80 81 args := params.AddUsers{ 82 Users: []params.AddUser{{ 83 Username: "foobar", 84 DisplayName: "Foo Bar", 85 Password: "password", 86 }}} 87 88 result, err := s.usermanager.AddUser(args) 89 // Check that the call is successful 90 c.Assert(err, jc.ErrorIsNil) 91 c.Assert(result.Results, gc.HasLen, 1) 92 foobarTag := names.NewLocalUserTag("foobar") 93 c.Assert(result.Results[0], gc.DeepEquals, params.AddUserResult{ 94 Tag: foobarTag.String()}) 95 // Check that the call results in a new user being created 96 user, err := s.State.User(foobarTag) 97 c.Assert(err, jc.ErrorIsNil) 98 c.Assert(user, gc.NotNil) 99 c.Assert(user.Name(), gc.Equals, "foobar") 100 c.Assert(user.DisplayName(), gc.Equals, "Foo Bar") 101 } 102 103 func (s *userManagerSuite) TestAddUser(c *gc.C) { 104 s.assertAddUser(c, params.UserAccessPermission(""), nil) 105 } 106 107 func (s *userManagerSuite) TestAddUserWithSecretKey(c *gc.C) { 108 args := params.AddUsers{ 109 Users: []params.AddUser{{ 110 Username: "foobar", 111 DisplayName: "Foo Bar", 112 Password: "", // assign secret key 113 }}} 114 115 result, err := s.usermanager.AddUser(args) 116 // Check that the call is successful 117 c.Assert(err, jc.ErrorIsNil) 118 c.Assert(result.Results, gc.HasLen, 1) 119 foobarTag := names.NewLocalUserTag("foobar") 120 121 // Check that the call results in a new user being created 122 user, err := s.State.User(foobarTag) 123 c.Assert(err, jc.ErrorIsNil) 124 c.Assert(user, gc.NotNil) 125 c.Assert(user.Name(), gc.Equals, "foobar") 126 c.Assert(user.DisplayName(), gc.Equals, "Foo Bar") 127 c.Assert(user.SecretKey(), gc.NotNil) 128 c.Assert(user.PasswordValid(""), jc.IsFalse) 129 130 // Check that the secret key returned by the API matches what 131 // is in state. 132 c.Assert(result.Results[0], gc.DeepEquals, params.AddUserResult{ 133 Tag: foobarTag.String(), 134 SecretKey: user.SecretKey(), 135 }) 136 } 137 138 func (s *userManagerSuite) TestBlockAddUser(c *gc.C) { 139 args := params.AddUsers{ 140 Users: []params.AddUser{{ 141 Username: "foobar", 142 DisplayName: "Foo Bar", 143 Password: "password", 144 }}} 145 146 s.BlockAllChanges(c, "TestBlockAddUser") 147 result, err := s.usermanager.AddUser(args) 148 // Check that the call is blocked. 149 s.AssertBlocked(c, err, "TestBlockAddUser") 150 // Check that there's no results. 151 c.Assert(result.Results, gc.HasLen, 0) 152 //check that user is not created. 153 foobarTag := names.NewLocalUserTag("foobar") 154 // Check that the call results in a new user being created. 155 _, err = s.State.User(foobarTag) 156 c.Assert(err, gc.ErrorMatches, `user "foobar" not found`) 157 } 158 159 func (s *userManagerSuite) TestAddUserAsNormalUser(c *gc.C) { 160 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 161 usermanager, err := usermanager.NewUserManagerAPI(facadetest.Context{ 162 State_: s.State, 163 Resources_: s.resources, 164 Auth_: apiservertesting.FakeAuthorizer{Tag: alex.Tag()}, 165 }) 166 c.Assert(err, jc.ErrorIsNil) 167 168 args := params.AddUsers{ 169 Users: []params.AddUser{{ 170 Username: "foobar", 171 DisplayName: "Foo Bar", 172 Password: "password", 173 }}} 174 175 _, err = usermanager.AddUser(args) 176 c.Assert(err, gc.ErrorMatches, "permission denied") 177 178 _, err = s.State.User(names.NewLocalUserTag("foobar")) 179 c.Assert(err, jc.Satisfies, errors.IsNotFound) 180 } 181 182 func (s *userManagerSuite) TestDisableUser(c *gc.C) { 183 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex"}) 184 barb := s.Factory.MakeUser(c, &factory.UserParams{Name: "barb", Disabled: true}) 185 186 args := params.Entities{ 187 Entities: []params.Entity{ 188 {alex.Tag().String()}, 189 {barb.Tag().String()}, 190 {names.NewLocalUserTag("ellie").String()}, 191 {names.NewUserTag("fred@remote").String()}, 192 {"not-a-tag"}, 193 }} 194 result, err := s.usermanager.DisableUser(args) 195 c.Assert(err, jc.ErrorIsNil) 196 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 197 Results: []params.ErrorResult{ 198 {Error: nil}, 199 {Error: nil}, 200 {Error: ¶ms.Error{ 201 Message: "permission denied", 202 Code: params.CodeUnauthorized, 203 }}, 204 {Error: ¶ms.Error{ 205 Message: "permission denied", 206 Code: params.CodeUnauthorized, 207 }}, 208 {Error: ¶ms.Error{ 209 Message: `"not-a-tag" is not a valid tag`, 210 }}, 211 }}) 212 err = alex.Refresh() 213 c.Assert(err, jc.ErrorIsNil) 214 c.Assert(alex.IsDisabled(), jc.IsTrue) 215 216 err = barb.Refresh() 217 c.Assert(err, jc.ErrorIsNil) 218 c.Assert(barb.IsDisabled(), jc.IsTrue) 219 } 220 221 func (s *userManagerSuite) TestBlockDisableUser(c *gc.C) { 222 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex"}) 223 barb := s.Factory.MakeUser(c, &factory.UserParams{Name: "barb", Disabled: true}) 224 225 args := params.Entities{ 226 Entities: []params.Entity{ 227 {alex.Tag().String()}, 228 {barb.Tag().String()}, 229 {names.NewLocalUserTag("ellie").String()}, 230 {names.NewUserTag("fred@remote").String()}, 231 {"not-a-tag"}, 232 }} 233 234 s.BlockAllChanges(c, "TestBlockDisableUser") 235 _, err := s.usermanager.DisableUser(args) 236 // Check that the call is blocked 237 s.AssertBlocked(c, err, "TestBlockDisableUser") 238 239 err = alex.Refresh() 240 c.Assert(err, jc.ErrorIsNil) 241 c.Assert(alex.IsDisabled(), jc.IsFalse) 242 243 err = barb.Refresh() 244 c.Assert(err, jc.ErrorIsNil) 245 c.Assert(barb.IsDisabled(), jc.IsTrue) 246 } 247 248 func (s *userManagerSuite) TestEnableUser(c *gc.C) { 249 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex"}) 250 barb := s.Factory.MakeUser(c, &factory.UserParams{Name: "barb", Disabled: true}) 251 252 args := params.Entities{ 253 Entities: []params.Entity{ 254 {alex.Tag().String()}, 255 {barb.Tag().String()}, 256 {names.NewLocalUserTag("ellie").String()}, 257 {names.NewUserTag("fred@remote").String()}, 258 {"not-a-tag"}, 259 }} 260 result, err := s.usermanager.EnableUser(args) 261 c.Assert(err, jc.ErrorIsNil) 262 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 263 Results: []params.ErrorResult{ 264 {Error: nil}, 265 {Error: nil}, 266 {Error: ¶ms.Error{ 267 Message: "permission denied", 268 Code: params.CodeUnauthorized, 269 }}, 270 {Error: ¶ms.Error{ 271 Message: "permission denied", 272 Code: params.CodeUnauthorized, 273 }}, 274 {Error: ¶ms.Error{ 275 Message: `"not-a-tag" is not a valid tag`, 276 }}, 277 }}) 278 err = alex.Refresh() 279 c.Assert(err, jc.ErrorIsNil) 280 c.Assert(alex.IsDisabled(), jc.IsFalse) 281 282 err = barb.Refresh() 283 c.Assert(err, jc.ErrorIsNil) 284 c.Assert(barb.IsDisabled(), jc.IsFalse) 285 } 286 287 func (s *userManagerSuite) TestBlockEnableUser(c *gc.C) { 288 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex"}) 289 barb := s.Factory.MakeUser(c, &factory.UserParams{Name: "barb", Disabled: true}) 290 291 args := params.Entities{ 292 Entities: []params.Entity{ 293 {alex.Tag().String()}, 294 {barb.Tag().String()}, 295 {names.NewLocalUserTag("ellie").String()}, 296 {names.NewUserTag("fred@remote").String()}, 297 {"not-a-tag"}, 298 }} 299 300 s.BlockAllChanges(c, "TestBlockEnableUser") 301 _, err := s.usermanager.EnableUser(args) 302 // Check that the call is blocked 303 s.AssertBlocked(c, err, "TestBlockEnableUser") 304 305 err = alex.Refresh() 306 c.Assert(err, jc.ErrorIsNil) 307 c.Assert(alex.IsDisabled(), jc.IsFalse) 308 309 err = barb.Refresh() 310 c.Assert(err, jc.ErrorIsNil) 311 c.Assert(barb.IsDisabled(), jc.IsTrue) 312 } 313 314 func (s *userManagerSuite) TestDisableUserAsNormalUser(c *gc.C) { 315 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 316 usermanager, err := usermanager.NewUserManagerAPI(facadetest.Context{ 317 State_: s.State, 318 Resources_: s.resources, 319 Auth_: apiservertesting.FakeAuthorizer{Tag: alex.Tag()}, 320 }) 321 c.Assert(err, jc.ErrorIsNil) 322 323 barb := s.Factory.MakeUser(c, &factory.UserParams{Name: "barb"}) 324 325 args := params.Entities{ 326 []params.Entity{{barb.Tag().String()}}, 327 } 328 _, err = usermanager.DisableUser(args) 329 c.Assert(err, gc.ErrorMatches, "permission denied") 330 331 err = barb.Refresh() 332 c.Assert(err, jc.ErrorIsNil) 333 c.Assert(barb.IsDisabled(), jc.IsFalse) 334 } 335 336 func (s *userManagerSuite) TestEnableUserAsNormalUser(c *gc.C) { 337 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 338 usermanager, err := usermanager.NewUserManagerAPI(facadetest.Context{ 339 State_: s.State, 340 Resources_: s.resources, 341 Auth_: apiservertesting.FakeAuthorizer{Tag: alex.Tag()}, 342 }) 343 c.Assert(err, jc.ErrorIsNil) 344 345 barb := s.Factory.MakeUser(c, &factory.UserParams{Name: "barb", Disabled: true}) 346 347 args := params.Entities{ 348 []params.Entity{{barb.Tag().String()}}, 349 } 350 _, err = usermanager.EnableUser(args) 351 c.Assert(err, gc.ErrorMatches, "permission denied") 352 353 err = barb.Refresh() 354 c.Assert(err, jc.ErrorIsNil) 355 c.Assert(barb.IsDisabled(), jc.IsTrue) 356 } 357 358 func (s *userManagerSuite) TestUserInfo(c *gc.C) { 359 userFoo := s.Factory.MakeUser(c, &factory.UserParams{Name: "foobar", DisplayName: "Foo Bar"}) 360 userBar := s.Factory.MakeUser(c, &factory.UserParams{Name: "barfoo", DisplayName: "Bar Foo", Disabled: true}) 361 err := controller.ChangeControllerAccess( 362 s.State, s.AdminUserTag(c), names.NewUserTag("fred@external"), 363 params.GrantControllerAccess, permission.SuperuserAccess) 364 c.Assert(err, jc.ErrorIsNil) 365 err = controller.ChangeControllerAccess( 366 s.State, s.AdminUserTag(c), names.NewUserTag("everyone@external"), 367 params.GrantControllerAccess, permission.SuperuserAccess) 368 c.Assert(err, jc.ErrorIsNil) 369 370 args := params.UserInfoRequest{ 371 Entities: []params.Entity{ 372 { 373 Tag: userFoo.Tag().String(), 374 }, { 375 Tag: userBar.Tag().String(), 376 }, { 377 Tag: names.NewLocalUserTag("ellie").String(), 378 }, { 379 Tag: names.NewUserTag("fred@external").String(), 380 }, { 381 Tag: names.NewUserTag("mary@external").String(), 382 }, { 383 Tag: "not-a-tag", 384 }, 385 }} 386 387 results, err := s.usermanager.UserInfo(args) 388 c.Assert(err, jc.ErrorIsNil) 389 var expected params.UserInfoResults 390 for _, r := range []struct { 391 user *state.User 392 info *params.UserInfo 393 err *params.Error 394 }{ 395 { 396 user: userFoo, 397 info: ¶ms.UserInfo{ 398 Username: "foobar", 399 DisplayName: "Foo Bar", 400 Access: "login", 401 }, 402 }, { 403 user: userBar, 404 info: ¶ms.UserInfo{ 405 Username: "barfoo", 406 DisplayName: "Bar Foo", 407 Access: "", 408 Disabled: true, 409 }, 410 }, { 411 err: ¶ms.Error{ 412 Message: "permission denied", 413 Code: params.CodeUnauthorized, 414 }, 415 }, { 416 info: ¶ms.UserInfo{ 417 Username: "fred@external", 418 Access: "superuser", 419 }, 420 }, { 421 info: ¶ms.UserInfo{ 422 Username: "mary@external", 423 Access: "superuser", 424 }, 425 }, { 426 err: ¶ms.Error{ 427 Message: `"not-a-tag" is not a valid tag`, 428 }, 429 }, 430 } { 431 if r.info != nil { 432 if names.NewUserTag(r.info.Username).IsLocal() { 433 r.info.DateCreated = r.user.DateCreated() 434 r.info.LastConnection = lastLoginPointer(c, r.user) 435 r.info.CreatedBy = s.adminName 436 } 437 } 438 expected.Results = append(expected.Results, params.UserInfoResult{Result: r.info, Error: r.err}) 439 } 440 441 c.Assert(results, jc.DeepEquals, expected) 442 } 443 444 func (s *userManagerSuite) TestUserInfoAll(c *gc.C) { 445 admin, err := s.State.User(s.AdminUserTag(c)) 446 c.Assert(err, jc.ErrorIsNil) 447 userFoo := s.Factory.MakeUser(c, &factory.UserParams{Name: "foobar", DisplayName: "Foo Bar"}) 448 userAardvark := s.Factory.MakeUser(c, &factory.UserParams{Name: "aardvark", DisplayName: "Aard Vark", Disabled: true}) 449 450 args := params.UserInfoRequest{IncludeDisabled: true} 451 results, err := s.usermanager.UserInfo(args) 452 c.Assert(err, jc.ErrorIsNil) 453 var expected params.UserInfoResults 454 for _, r := range []struct { 455 user *state.User 456 info *params.UserInfo 457 }{{ 458 user: userAardvark, 459 info: ¶ms.UserInfo{ 460 Username: "aardvark", 461 DisplayName: "Aard Vark", 462 Access: "", 463 Disabled: true, 464 }, 465 }, { 466 user: admin, 467 info: ¶ms.UserInfo{ 468 Username: s.adminName, 469 DisplayName: admin.DisplayName(), 470 Access: "superuser", 471 }, 472 }, { 473 user: userFoo, 474 info: ¶ms.UserInfo{ 475 Username: "foobar", 476 DisplayName: "Foo Bar", 477 Access: "login", 478 }, 479 }} { 480 r.info.CreatedBy = s.adminName 481 r.info.DateCreated = r.user.DateCreated() 482 r.info.LastConnection = lastLoginPointer(c, r.user) 483 expected.Results = append(expected.Results, params.UserInfoResult{Result: r.info}) 484 } 485 c.Assert(results, jc.DeepEquals, expected) 486 487 results, err = s.usermanager.UserInfo(params.UserInfoRequest{}) 488 c.Assert(err, jc.ErrorIsNil) 489 // Same results as before, but without the deactivated user 490 expected.Results = expected.Results[1:] 491 c.Assert(results, jc.DeepEquals, expected) 492 } 493 494 func (s *userManagerSuite) TestUserInfoNonControllerAdmin(c *gc.C) { 495 s.Factory.MakeUser(c, &factory.UserParams{Name: "foobar", DisplayName: "Foo Bar"}) 496 userAardvark := s.Factory.MakeUser(c, &factory.UserParams{Name: "aardvark", DisplayName: "Aard Vark"}) 497 498 authorizer := apiservertesting.FakeAuthorizer{ 499 Tag: userAardvark.Tag(), 500 } 501 usermanager, err := usermanager.NewUserManagerAPI(facadetest.Context{ 502 State_: s.State, 503 Resources_: s.resources, 504 Auth_: authorizer, 505 }) 506 c.Assert(err, jc.ErrorIsNil) 507 508 args := params.UserInfoRequest{Entities: []params.Entity{ 509 {Tag: userAardvark.Tag().String()}, 510 {Tag: names.NewUserTag("foobar").String()}, 511 }} 512 results, err := usermanager.UserInfo(args) 513 c.Assert(err, jc.ErrorIsNil) 514 // Non admin users can only see themselves. 515 c.Assert(results, jc.DeepEquals, params.UserInfoResults{ 516 Results: []params.UserInfoResult{ 517 { 518 Result: ¶ms.UserInfo{ 519 Username: "aardvark", 520 DisplayName: "Aard Vark", 521 Access: "login", 522 CreatedBy: s.adminName, 523 DateCreated: userAardvark.DateCreated(), 524 LastConnection: lastLoginPointer(c, userAardvark), 525 }, 526 }, { 527 Error: ¶ms.Error{ 528 Message: "permission denied", 529 Code: params.CodeUnauthorized, 530 }, 531 }, 532 }, 533 }) 534 } 535 536 func (s *userManagerSuite) TestUserInfoEveryonePermission(c *gc.C) { 537 _, err := s.State.AddControllerUser(state.UserAccessSpec{ 538 User: names.NewUserTag("everyone@external"), 539 Access: permission.SuperuserAccess, 540 CreatedBy: s.AdminUserTag(c), 541 }) 542 c.Assert(err, jc.ErrorIsNil) 543 _, err = s.State.AddControllerUser(state.UserAccessSpec{ 544 User: names.NewUserTag("aardvark@external"), 545 Access: permission.LoginAccess, 546 CreatedBy: s.AdminUserTag(c), 547 }) 548 c.Assert(err, jc.ErrorIsNil) 549 550 args := params.UserInfoRequest{Entities: []params.Entity{{Tag: names.NewUserTag("aardvark@external").String()}}} 551 results, err := s.usermanager.UserInfo(args) 552 c.Assert(err, jc.ErrorIsNil) 553 // Non admin users can only see themselves. 554 c.Assert(results, jc.DeepEquals, params.UserInfoResults{ 555 Results: []params.UserInfoResult{{Result: ¶ms.UserInfo{ 556 Username: "aardvark@external", 557 Access: "superuser", 558 }}}, 559 }) 560 } 561 562 func (s *userManagerSuite) makeLocalModelUser(c *gc.C, username, displayname string) permission.UserAccess { 563 // factory.MakeUser will create an ModelUser for a local user by default. 564 user := s.Factory.MakeUser(c, &factory.UserParams{Name: username, DisplayName: displayname}) 565 modelUser, err := s.State.UserAccess(user.UserTag(), s.Model.ModelTag()) 566 c.Assert(err, jc.ErrorIsNil) 567 return modelUser 568 } 569 570 func (s *userManagerSuite) TestModelUsersInfo(c *gc.C) { 571 testAdmin := s.AdminUserTag(c) 572 owner, err := s.State.UserAccess(testAdmin, s.Model.ModelTag()) 573 c.Assert(err, jc.ErrorIsNil) 574 575 localUser1 := s.makeLocalModelUser(c, "ralphdoe", "Ralph Doe") 576 localUser2 := s.makeLocalModelUser(c, "samsmith", "Sam Smith") 577 remoteUser1 := s.Factory.MakeModelUser(c, &factory.ModelUserParams{User: "bobjohns@ubuntuone", DisplayName: "Bob Johns", Access: permission.WriteAccess}) 578 remoteUser2 := s.Factory.MakeModelUser(c, &factory.ModelUserParams{User: "nicshaw@idprovider", DisplayName: "Nic Shaw", Access: permission.WriteAccess}) 579 580 results, err := s.usermanager.ModelUserInfo(params.Entities{Entities: []params.Entity{{ 581 Tag: s.Model.ModelTag().String(), 582 }}}) 583 c.Assert(err, jc.ErrorIsNil) 584 var expected params.ModelUserInfoResults 585 for _, r := range []struct { 586 user permission.UserAccess 587 info *params.ModelUserInfo 588 }{ 589 { 590 owner, 591 ¶ms.ModelUserInfo{ 592 ModelTag: s.Model.ModelTag().String(), 593 UserName: owner.UserName, 594 DisplayName: owner.DisplayName, 595 Access: "admin", 596 }, 597 }, { 598 localUser1, 599 ¶ms.ModelUserInfo{ 600 ModelTag: s.Model.ModelTag().String(), 601 UserName: "ralphdoe", 602 DisplayName: "Ralph Doe", 603 Access: "admin", 604 }, 605 }, { 606 localUser2, 607 ¶ms.ModelUserInfo{ 608 ModelTag: s.Model.ModelTag().String(), 609 UserName: "samsmith", 610 DisplayName: "Sam Smith", 611 Access: "admin", 612 }, 613 }, { 614 remoteUser1, 615 ¶ms.ModelUserInfo{ 616 ModelTag: s.Model.ModelTag().String(), 617 UserName: "bobjohns@ubuntuone", 618 DisplayName: "Bob Johns", 619 Access: "write", 620 }, 621 }, { 622 remoteUser2, 623 ¶ms.ModelUserInfo{ 624 ModelTag: s.Model.ModelTag().String(), 625 UserName: "nicshaw@idprovider", 626 DisplayName: "Nic Shaw", 627 Access: "write", 628 }, 629 }, 630 } { 631 r.info.LastConnection = lastConnPointer(c, r.user, s.State) 632 expected.Results = append(expected.Results, params.ModelUserInfoResult{Result: r.info}) 633 } 634 635 sort.Sort(ByUserName(expected.Results)) 636 sort.Sort(ByUserName(results.Results)) 637 c.Assert(results, jc.DeepEquals, expected) 638 } 639 640 func lastConnPointer(c *gc.C, modelUser permission.UserAccess, st *state.State) *time.Time { 641 model, err := st.Model() 642 if err != nil { 643 c.Fatal(err) 644 } 645 646 lastConn, err := model.LastModelConnection(modelUser.UserTag) 647 if err != nil { 648 if state.IsNeverConnectedError(err) { 649 return nil 650 } 651 c.Fatal(err) 652 } 653 return &lastConn 654 } 655 656 // ByUserName implements sort.Interface for []params.ModelUserInfoResult based on 657 // the UserName field. 658 type ByUserName []params.ModelUserInfoResult 659 660 func (a ByUserName) Len() int { return len(a) } 661 func (a ByUserName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 662 func (a ByUserName) Less(i, j int) bool { return a[i].Result.UserName < a[j].Result.UserName } 663 664 func lastLoginPointer(c *gc.C, user *state.User) *time.Time { 665 lastLogin, err := user.LastLogin() 666 if err != nil { 667 if state.IsNeverLoggedInError(err) { 668 return nil 669 } 670 c.Fatal(err) 671 } 672 return &lastLogin 673 } 674 675 func (s *userManagerSuite) TestSetPassword(c *gc.C) { 676 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 677 678 args := params.EntityPasswords{ 679 Changes: []params.EntityPassword{{ 680 Tag: alex.Tag().String(), 681 Password: "new-password", 682 }}} 683 results, err := s.usermanager.SetPassword(args) 684 c.Assert(err, jc.ErrorIsNil) 685 c.Assert(results.Results, gc.HasLen, 1) 686 c.Assert(results.Results[0], gc.DeepEquals, params.ErrorResult{Error: nil}) 687 688 err = alex.Refresh() 689 c.Assert(err, jc.ErrorIsNil) 690 691 c.Assert(alex.PasswordValid("new-password"), jc.IsTrue) 692 } 693 694 func (s *userManagerSuite) TestBlockSetPassword(c *gc.C) { 695 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 696 697 args := params.EntityPasswords{ 698 Changes: []params.EntityPassword{{ 699 Tag: alex.Tag().String(), 700 Password: "new-password", 701 }}} 702 703 s.BlockAllChanges(c, "TestBlockSetPassword") 704 _, err := s.usermanager.SetPassword(args) 705 // Check that the call is blocked 706 s.AssertBlocked(c, err, "TestBlockSetPassword") 707 708 err = alex.Refresh() 709 c.Assert(err, jc.ErrorIsNil) 710 711 c.Assert(alex.PasswordValid("new-password"), jc.IsFalse) 712 } 713 714 func (s *userManagerSuite) TestSetPasswordForSelf(c *gc.C) { 715 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 716 usermanager, err := usermanager.NewUserManagerAPI(facadetest.Context{ 717 State_: s.State, 718 Resources_: s.resources, 719 Auth_: apiservertesting.FakeAuthorizer{Tag: alex.Tag()}, 720 }) 721 c.Assert(err, jc.ErrorIsNil) 722 723 args := params.EntityPasswords{ 724 Changes: []params.EntityPassword{{ 725 Tag: alex.Tag().String(), 726 Password: "new-password", 727 }}} 728 results, err := usermanager.SetPassword(args) 729 c.Assert(err, jc.ErrorIsNil) 730 c.Assert(results.Results, gc.HasLen, 1) 731 c.Assert(results.Results[0], gc.DeepEquals, params.ErrorResult{Error: nil}) 732 733 err = alex.Refresh() 734 c.Assert(err, jc.ErrorIsNil) 735 736 c.Assert(alex.PasswordValid("new-password"), jc.IsTrue) 737 } 738 739 func (s *userManagerSuite) TestSetPasswordForOther(c *gc.C) { 740 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 741 barb := s.Factory.MakeUser(c, &factory.UserParams{Name: "barb", NoModelUser: true}) 742 usermanager, err := usermanager.NewUserManagerAPI(facadetest.Context{ 743 State_: s.State, 744 Resources_: s.resources, 745 Auth_: apiservertesting.FakeAuthorizer{Tag: alex.Tag()}, 746 }) 747 c.Assert(err, jc.ErrorIsNil) 748 749 args := params.EntityPasswords{ 750 Changes: []params.EntityPassword{{ 751 Tag: barb.Tag().String(), 752 Password: "new-password", 753 }}} 754 results, err := usermanager.SetPassword(args) 755 c.Assert(err, jc.ErrorIsNil) 756 c.Assert(results.Results, gc.HasLen, 1) 757 c.Assert(results.Results[0], gc.DeepEquals, params.ErrorResult{ 758 Error: ¶ms.Error{ 759 Message: "permission denied", 760 Code: params.CodeUnauthorized, 761 }}) 762 763 err = barb.Refresh() 764 c.Assert(err, jc.ErrorIsNil) 765 766 c.Assert(barb.PasswordValid("new-password"), jc.IsFalse) 767 } 768 769 func (s *userManagerSuite) TestRemoveUserBadTag(c *gc.C) { 770 tag := "not-a-tag" 771 got, err := s.usermanager.RemoveUser(params.Entities{ 772 Entities: []params.Entity{{Tag: tag}}}) 773 c.Assert(got.Results, gc.HasLen, 1) 774 c.Assert(err, gc.Equals, nil) 775 c.Check(got.Results[0].Error, jc.DeepEquals, ¶ms.Error{ 776 Message: "\"not-a-tag\" is not a valid tag", 777 }) 778 } 779 780 func (s *userManagerSuite) TestRemoveUserNonExistent(c *gc.C) { 781 tag := "user-harvey" 782 got, err := s.usermanager.RemoveUser(params.Entities{ 783 Entities: []params.Entity{{Tag: tag}}}) 784 c.Assert(got.Results, gc.HasLen, 1) 785 c.Assert(err, gc.Equals, nil) 786 c.Check(got.Results[0].Error, jc.DeepEquals, ¶ms.Error{ 787 Message: "failed to delete user \"harvey\": user \"harvey\" not found", 788 Code: "not found", 789 }) 790 } 791 792 func (s *userManagerSuite) TestRemoveUser(c *gc.C) { 793 // Create a user to delete. 794 jjam := s.Factory.MakeUser(c, &factory.UserParams{Name: "jimmyjam"}) 795 796 expectedError := fmt.Sprintf("failed to delete user %q: user %q is permanently deleted", jjam.Name(), jjam.Name()) 797 798 // Remove the user 799 got, err := s.usermanager.RemoveUser(params.Entities{ 800 Entities: []params.Entity{{Tag: jjam.Tag().String()}}}) 801 c.Assert(got.Results, gc.HasLen, 1) 802 803 c.Check(got.Results[0].Error, gc.IsNil) // Uses gc.IsNil as it's a typed nil. 804 c.Assert(err, jc.ErrorIsNil) 805 806 // Check if deleted. 807 err = jjam.Refresh() 808 c.Check(err, jc.ErrorIsNil) 809 c.Assert(jjam.IsDeleted(), jc.IsTrue) 810 811 // Try again and verify we get the expected error. 812 got, err = s.usermanager.RemoveUser(params.Entities{ 813 Entities: []params.Entity{{Tag: jjam.Tag().String()}}}) 814 c.Check(got.Results, gc.HasLen, 1) 815 c.Check(got.Results[0].Error, jc.DeepEquals, ¶ms.Error{ 816 Message: expectedError, 817 Code: "", 818 }) 819 c.Assert(err, jc.ErrorIsNil) 820 } 821 822 func (s *userManagerSuite) TestRemoveUserAsNormalUser(c *gc.C) { 823 // Create a user to delete. 824 jjam := s.Factory.MakeUser(c, &factory.UserParams{Name: "jimmyjam"}) 825 // Create a user to delete jjam. 826 chuck := s.Factory.MakeUser(c, &factory.UserParams{ 827 Name: "chuck", 828 NoModelUser: true, 829 }) 830 831 // Authenticate as chuck. 832 usermanager, err := usermanager.NewUserManagerAPI(facadetest.Context{ 833 State_: s.State, 834 Resources_: s.resources, 835 Auth_: apiservertesting.FakeAuthorizer{Tag: chuck.Tag()}, 836 }) 837 c.Assert(err, jc.ErrorIsNil) 838 839 // Make sure the user exists. 840 ui, err := s.usermanager.UserInfo(params.UserInfoRequest{ 841 Entities: []params.Entity{{Tag: jjam.Tag().String()}}, 842 }) 843 c.Check(err, jc.ErrorIsNil) 844 c.Check(ui.Results, gc.HasLen, 1) 845 c.Assert(ui.Results[0].Result.Username, gc.DeepEquals, jjam.Name()) 846 847 // Remove jjam as chuck and fail. 848 _, err = usermanager.RemoveUser(params.Entities{ 849 Entities: []params.Entity{{Tag: jjam.Tag().String()}}}) 850 c.Assert(err, gc.ErrorMatches, "permission denied") 851 852 // Make sure jjam is still around. 853 err = jjam.Refresh() 854 c.Assert(err, jc.ErrorIsNil) 855 } 856 857 func (s *userManagerSuite) TestRemoveUserSelfAsNormalUser(c *gc.C) { 858 // Create a user to delete. 859 jjam := s.Factory.MakeUser(c, &factory.UserParams{ 860 Name: "jimmyjam", 861 NoModelUser: true, 862 }) 863 usermanager, err := usermanager.NewUserManagerAPI(facadetest.Context{ 864 State_: s.State, 865 Resources_: s.resources, 866 Auth_: apiservertesting.FakeAuthorizer{Tag: jjam.Tag()}, 867 }) 868 c.Assert(err, jc.ErrorIsNil) 869 870 // Make sure the user exists. 871 ui, err := s.usermanager.UserInfo(params.UserInfoRequest{ 872 Entities: []params.Entity{{Tag: jjam.Tag().String()}}, 873 }) 874 c.Assert(err, jc.ErrorIsNil) 875 c.Check(ui.Results, gc.HasLen, 1) 876 c.Assert(ui.Results[0].Result.Username, gc.DeepEquals, jjam.Name()) 877 878 // Remove the user as the user 879 _, err = usermanager.RemoveUser(params.Entities{ 880 Entities: []params.Entity{{Tag: jjam.Tag().String()}}}) 881 c.Assert(err, gc.ErrorMatches, "permission denied") 882 883 // Check if deleted. 884 err = jjam.Refresh() 885 c.Assert(err, jc.ErrorIsNil) 886 } 887 888 func (s *userManagerSuite) TestRemoveUserAsSelfAdmin(c *gc.C) { 889 890 expectedError := "cannot delete controller owner \"admin\"" 891 892 // Remove admin as admin. 893 got, err := s.usermanager.RemoveUser(params.Entities{ 894 Entities: []params.Entity{{Tag: s.AdminUserTag(c).String()}}}) 895 c.Assert(got.Results, gc.HasLen, 1) 896 c.Check(got.Results[0].Error, jc.DeepEquals, ¶ms.Error{ 897 Message: expectedError, 898 }) 899 c.Assert(err, jc.ErrorIsNil) 900 901 // Try again to see if we succeeded. 902 got, err = s.usermanager.RemoveUser(params.Entities{ 903 Entities: []params.Entity{{Tag: s.AdminUserTag(c).String()}}}) 904 c.Assert(got.Results, gc.HasLen, 1) 905 c.Check(got.Results[0].Error, jc.DeepEquals, ¶ms.Error{ 906 Message: expectedError, 907 }) 908 c.Assert(err, jc.ErrorIsNil) 909 910 ui, err := s.usermanager.UserInfo(params.UserInfoRequest{}) 911 c.Check(err, jc.ErrorIsNil) 912 c.Assert(ui.Results, gc.HasLen, 1) 913 914 } 915 916 func (s *userManagerSuite) TestRemoveUserBulkSharedModels(c *gc.C) { 917 // Create users. 918 jjam := s.Factory.MakeUser(c, &factory.UserParams{ 919 Name: "jimmyjam", 920 }) 921 alice := s.Factory.MakeUser(c, &factory.UserParams{ 922 Name: "alice", 923 }) 924 bob := s.Factory.MakeUser(c, &factory.UserParams{ 925 Name: "bob", 926 }) 927 928 // Get a handle on the current model. 929 model, err := s.State.Model() 930 c.Assert(err, jc.ErrorIsNil) 931 users, err := model.Users() 932 c.Assert(err, jc.ErrorIsNil) 933 934 // Make sure the users exist. 935 var userNames []string 936 for _, u := range users { 937 userNames = append(userNames, u.UserTag.Name()) 938 } 939 c.Assert(userNames, jc.SameContents, []string{"admin", jjam.Name(), alice.Name(), bob.Name()}) 940 941 // Remove 2 users. 942 got, err := s.usermanager.RemoveUser(params.Entities{ 943 Entities: []params.Entity{ 944 {Tag: jjam.Tag().String()}, 945 {Tag: alice.Tag().String()}, 946 }}) 947 c.Check(got.Results, gc.HasLen, 2) 948 var paramErr *params.Error 949 c.Check(got.Results[0].Error, jc.DeepEquals, paramErr) 950 c.Check(got.Results[1].Error, jc.DeepEquals, paramErr) 951 c.Assert(err, jc.ErrorIsNil) 952 953 // Make sure users were deleted. 954 err = jjam.Refresh() 955 c.Assert(err, jc.ErrorIsNil) 956 c.Assert(jjam.IsDeleted(), jc.IsTrue) 957 err = alice.Refresh() 958 c.Assert(err, jc.ErrorIsNil) 959 c.Assert(alice.IsDeleted(), jc.IsTrue) 960 } 961 962 func (s *userManagerSuite) TestResetPassword(c *gc.C) { 963 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 964 c.Assert(alex.PasswordValid("password"), jc.IsTrue) 965 966 args := params.Entities{Entities: []params.Entity{{Tag: alex.Tag().String()}}} 967 results, err := s.usermanager.ResetPassword(args) 968 c.Assert(err, jc.ErrorIsNil) 969 c.Assert(results.Results, gc.HasLen, 1) 970 971 err = alex.Refresh() 972 c.Assert(err, jc.ErrorIsNil) 973 c.Assert(results.Results[0].Tag, gc.DeepEquals, alex.Tag().String()) 974 c.Assert(results.Results[0].SecretKey, gc.DeepEquals, alex.SecretKey()) 975 c.Assert(alex.PasswordValid("password"), jc.IsFalse) 976 } 977 978 func (s *userManagerSuite) TestResetPasswordMultiple(c *gc.C) { 979 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 980 barb := s.Factory.MakeUser(c, &factory.UserParams{Name: "barb", NoModelUser: true}) 981 c.Assert(alex.PasswordValid("password"), jc.IsTrue) 982 c.Assert(barb.PasswordValid("password"), jc.IsTrue) 983 984 args := params.Entities{Entities: []params.Entity{ 985 {Tag: alex.Tag().String()}, 986 {Tag: barb.Tag().String()}, 987 }} 988 results, err := s.usermanager.ResetPassword(args) 989 c.Assert(err, jc.ErrorIsNil) 990 err = alex.Refresh() 991 c.Assert(err, jc.ErrorIsNil) 992 err = barb.Refresh() 993 c.Assert(err, jc.ErrorIsNil) 994 c.Assert(results.Results, gc.DeepEquals, []params.AddUserResult{ 995 { 996 Tag: alex.Tag().String(), 997 SecretKey: alex.SecretKey(), 998 }, 999 { 1000 Tag: barb.Tag().String(), 1001 SecretKey: barb.SecretKey(), 1002 }, 1003 }) 1004 c.Assert(alex.PasswordValid("password"), jc.IsFalse) 1005 c.Assert(barb.PasswordValid("password"), jc.IsFalse) 1006 } 1007 1008 func (s *userManagerSuite) TestBlockResetPassword(c *gc.C) { 1009 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 1010 args := params.Entities{Entities: []params.Entity{{Tag: alex.Tag().String()}}} 1011 c.Assert(alex.PasswordValid("password"), jc.IsTrue) 1012 1013 s.BlockAllChanges(c, "TestBlockResetPassword") 1014 _, err := s.usermanager.ResetPassword(args) 1015 // Check that the call is blocked 1016 s.AssertBlocked(c, err, "TestBlockResetPassword") 1017 1018 err = alex.Refresh() 1019 c.Assert(err, jc.ErrorIsNil) 1020 c.Assert(alex.PasswordValid("password"), jc.IsTrue) 1021 } 1022 1023 func (s *userManagerSuite) TestResetPasswordControllerAdminForSelf(c *gc.C) { 1024 alex, err := s.State.User(s.AdminUserTag(c)) 1025 c.Assert(err, jc.ErrorIsNil) 1026 args := params.Entities{Entities: []params.Entity{{Tag: alex.Tag().String()}}} 1027 c.Assert(alex.PasswordValid("dummy-secret"), jc.IsTrue) 1028 1029 results, err := s.usermanager.ResetPassword(args) 1030 c.Assert(err, jc.ErrorIsNil) 1031 c.Assert(results.Results, gc.HasLen, 1) 1032 1033 err = alex.Refresh() 1034 c.Assert(err, jc.ErrorIsNil) 1035 c.Assert(results.Results, gc.DeepEquals, []params.AddUserResult{ 1036 { 1037 Tag: alex.Tag().String(), 1038 Error: apiservererrors.ServerError(apiservererrors.ErrPerm), 1039 }, 1040 }) 1041 c.Assert(alex.PasswordValid("dummy-secret"), jc.IsTrue) 1042 } 1043 1044 func (s *userManagerSuite) TestResetPasswordNotControllerAdmin(c *gc.C) { 1045 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 1046 c.Assert(alex.PasswordValid("password"), jc.IsTrue) 1047 barb := s.Factory.MakeUser(c, &factory.UserParams{Name: "barb", NoModelUser: true}) 1048 c.Assert(barb.PasswordValid("password"), jc.IsTrue) 1049 usermanager, err := usermanager.NewUserManagerAPI(facadetest.Context{ 1050 State_: s.State, 1051 Resources_: s.resources, 1052 Auth_: apiservertesting.FakeAuthorizer{Tag: alex.Tag()}, 1053 }) 1054 c.Assert(err, jc.ErrorIsNil) 1055 1056 args := params.Entities{Entities: []params.Entity{ 1057 {Tag: alex.Tag().String()}, 1058 {Tag: barb.Tag().String()}, 1059 }} 1060 results, err := usermanager.ResetPassword(args) 1061 c.Assert(err, jc.ErrorIsNil) 1062 1063 err = alex.Refresh() 1064 c.Assert(err, jc.ErrorIsNil) 1065 err = barb.Refresh() 1066 c.Assert(err, jc.ErrorIsNil) 1067 c.Assert(results.Results, gc.DeepEquals, []params.AddUserResult{ 1068 { 1069 Tag: alex.Tag().String(), 1070 Error: apiservererrors.ServerError(apiservererrors.ErrPerm), 1071 }, 1072 { 1073 Tag: barb.Tag().String(), 1074 Error: apiservererrors.ServerError(apiservererrors.ErrPerm), 1075 }, 1076 }) 1077 1078 c.Assert(alex.PasswordValid("password"), jc.IsTrue) 1079 c.Assert(barb.PasswordValid("password"), jc.IsTrue) 1080 } 1081 1082 func (s *userManagerSuite) TestResetPasswordFail(c *gc.C) { 1083 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true, Disabled: true}) 1084 args := params.Entities{Entities: []params.Entity{ 1085 {Tag: "user-invalid"}, 1086 {Tag: alex.Tag().String()}, 1087 }} 1088 1089 results, err := s.usermanager.ResetPassword(args) 1090 c.Assert(err, jc.ErrorIsNil) 1091 c.Assert(results.Results, gc.DeepEquals, []params.AddUserResult{ 1092 { 1093 Tag: "user-invalid", 1094 Error: apiservererrors.ServerError(apiservererrors.ErrPerm), 1095 }, 1096 { 1097 Tag: alex.Tag().String(), 1098 Error: apiservererrors.ServerError(fmt.Errorf("cannot reset password for user \"alex\": user deactivated")), 1099 }, 1100 }) 1101 } 1102 1103 func (s *userManagerSuite) TestResetPasswordMixedResult(c *gc.C) { 1104 alex := s.Factory.MakeUser(c, &factory.UserParams{Name: "alex", NoModelUser: true}) 1105 c.Assert(alex.PasswordValid("password"), jc.IsTrue) 1106 args := params.Entities{Entities: []params.Entity{ 1107 {Tag: "user-invalid"}, 1108 {Tag: alex.Tag().String()}, 1109 }} 1110 1111 results, err := s.usermanager.ResetPassword(args) 1112 c.Assert(err, jc.ErrorIsNil) 1113 err = alex.Refresh() 1114 c.Assert(err, jc.ErrorIsNil) 1115 c.Assert(results.Results, gc.DeepEquals, []params.AddUserResult{ 1116 { 1117 Tag: "user-invalid", 1118 Error: apiservererrors.ServerError(apiservererrors.ErrPerm), 1119 }, 1120 { 1121 Tag: alex.Tag().String(), 1122 SecretKey: alex.SecretKey(), 1123 }, 1124 }) 1125 c.Assert(alex.PasswordValid("password"), jc.IsFalse) 1126 } 1127 1128 func (s *userManagerSuite) TestResetPasswordEmpty(c *gc.C) { 1129 results, err := s.usermanager.ResetPassword(params.Entities{}) 1130 c.Assert(err, jc.ErrorIsNil) 1131 c.Assert(results.Results, gc.HasLen, 0) 1132 }