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: &params.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: &params.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: &params.UserInfo{Username: "first"}},
   214  			{Result: &params.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: &params.Error{Message: "first error"}},
   244  			{Error: &params.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: &params.ModelUserInfo{UserName: "one"}},
   266  			{Result: &params.ModelUserInfo{UserName: "two"}},
   267  			{Result: &params.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: &params.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  }