github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/user_test.go (about)

     1  // Copyright 2013, 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state_test
     5  
     6  import (
     7  	"regexp"
     8  	"time"
     9  
    10  	"github.com/juju/errors"
    11  	"github.com/juju/names"
    12  	jc "github.com/juju/testing/checkers"
    13  	"github.com/juju/utils"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/state"
    17  	"github.com/juju/juju/testing/factory"
    18  )
    19  
    20  type UserSuite struct {
    21  	ConnSuite
    22  }
    23  
    24  var _ = gc.Suite(&UserSuite{})
    25  
    26  func (s *UserSuite) TestAddInvalidNames(c *gc.C) {
    27  	for _, name := range []string{
    28  		"",
    29  		"a",
    30  		"b^b",
    31  		"a.",
    32  		"a-",
    33  		"user@local",
    34  		"@ubuntuone",
    35  	} {
    36  		c.Logf("check invalid name %q", name)
    37  		user, err := s.State.AddUser(name, "ignored", "ignored", "ignored")
    38  		c.Check(err, gc.ErrorMatches, `invalid user name "`+regexp.QuoteMeta(name)+`"`)
    39  		c.Check(user, gc.IsNil)
    40  	}
    41  }
    42  
    43  func (s *UserSuite) TestAddUser(c *gc.C) {
    44  	name := "f00-Bar.ram77"
    45  	displayName := "Display"
    46  	password := "password"
    47  	creator := "admin"
    48  
    49  	now := time.Now().Round(time.Second).UTC()
    50  
    51  	user, err := s.State.AddUser(name, displayName, password, creator)
    52  	c.Assert(err, jc.ErrorIsNil)
    53  	c.Assert(user, gc.NotNil)
    54  	c.Assert(user.Name(), gc.Equals, name)
    55  	c.Assert(user.DisplayName(), gc.Equals, displayName)
    56  	c.Assert(user.PasswordValid(password), jc.IsTrue)
    57  	c.Assert(user.CreatedBy(), gc.Equals, creator)
    58  	c.Assert(user.DateCreated().After(now) ||
    59  		user.DateCreated().Equal(now), jc.IsTrue)
    60  	lastLogin, err := user.LastLogin()
    61  	c.Assert(err, jc.Satisfies, state.IsNeverLoggedInError)
    62  	c.Assert(lastLogin, gc.DeepEquals, time.Time{})
    63  
    64  	user, err = s.State.User(user.UserTag())
    65  	c.Assert(err, jc.ErrorIsNil)
    66  	c.Assert(user, gc.NotNil)
    67  	c.Assert(user.Name(), gc.Equals, name)
    68  	c.Assert(user.DisplayName(), gc.Equals, displayName)
    69  	c.Assert(user.PasswordValid(password), jc.IsTrue)
    70  	c.Assert(user.CreatedBy(), gc.Equals, creator)
    71  	c.Assert(user.DateCreated().After(now) ||
    72  		user.DateCreated().Equal(now), jc.IsTrue)
    73  	lastLogin, err = user.LastLogin()
    74  	c.Assert(err, jc.Satisfies, state.IsNeverLoggedInError)
    75  	c.Assert(lastLogin, gc.DeepEquals, time.Time{})
    76  }
    77  
    78  func (s *UserSuite) TestCheckUserExists(c *gc.C) {
    79  	user := s.Factory.MakeUser(c, nil)
    80  	exists, err := state.CheckUserExists(s.State, user.Name())
    81  	c.Assert(err, jc.ErrorIsNil)
    82  	c.Assert(exists, jc.IsTrue)
    83  	exists, err = state.CheckUserExists(s.State, "notAUser")
    84  	c.Assert(err, jc.ErrorIsNil)
    85  	c.Assert(exists, jc.IsFalse)
    86  }
    87  
    88  func (s *UserSuite) TestString(c *gc.C) {
    89  	user := s.Factory.MakeUser(c, &factory.UserParams{Name: "foo"})
    90  	c.Assert(user.String(), gc.Equals, "foo@local")
    91  }
    92  
    93  func (s *UserSuite) TestUpdateLastLogin(c *gc.C) {
    94  	now := time.Now().Round(time.Second).UTC()
    95  	user := s.Factory.MakeUser(c, nil)
    96  	err := user.UpdateLastLogin()
    97  	c.Assert(err, jc.ErrorIsNil)
    98  	lastLogin, err := user.LastLogin()
    99  	c.Assert(err, jc.ErrorIsNil)
   100  	c.Assert(lastLogin.After(now) ||
   101  		lastLogin.Equal(now), jc.IsTrue)
   102  }
   103  
   104  func (s *UserSuite) TestSetPassword(c *gc.C) {
   105  	user := s.Factory.MakeUser(c, nil)
   106  	testSetPassword(c, func() (state.Authenticator, error) {
   107  		return s.State.User(user.UserTag())
   108  	})
   109  }
   110  
   111  func (s *UserSuite) TestAddUserSetsSalt(c *gc.C) {
   112  	user := s.Factory.MakeUser(c, &factory.UserParams{Password: "a-password"})
   113  	salt, hash := state.GetUserPasswordSaltAndHash(user)
   114  	c.Assert(hash, gc.Not(gc.Equals), "")
   115  	c.Assert(salt, gc.Not(gc.Equals), "")
   116  	c.Assert(utils.UserPasswordHash("a-password", salt), gc.Equals, hash)
   117  	c.Assert(user.PasswordValid("a-password"), jc.IsTrue)
   118  }
   119  
   120  func (s *UserSuite) TestSetPasswordChangesSalt(c *gc.C) {
   121  	user := s.Factory.MakeUser(c, nil)
   122  	origSalt, origHash := state.GetUserPasswordSaltAndHash(user)
   123  	c.Assert(origSalt, gc.Not(gc.Equals), "")
   124  	user.SetPassword("a-password")
   125  	newSalt, newHash := state.GetUserPasswordSaltAndHash(user)
   126  	c.Assert(newSalt, gc.Not(gc.Equals), "")
   127  	c.Assert(newSalt, gc.Not(gc.Equals), origSalt)
   128  	c.Assert(newHash, gc.Not(gc.Equals), origHash)
   129  	c.Assert(user.PasswordValid("a-password"), jc.IsTrue)
   130  }
   131  
   132  func (s *UserSuite) TestDisable(c *gc.C) {
   133  	user := s.Factory.MakeUser(c, &factory.UserParams{Password: "a-password"})
   134  	c.Assert(user.IsDisabled(), jc.IsFalse)
   135  
   136  	err := user.Disable()
   137  	c.Assert(err, jc.ErrorIsNil)
   138  	c.Assert(user.IsDisabled(), jc.IsTrue)
   139  	c.Assert(user.PasswordValid("a-password"), jc.IsFalse)
   140  
   141  	err = user.Enable()
   142  	c.Assert(err, jc.ErrorIsNil)
   143  	c.Assert(user.IsDisabled(), jc.IsFalse)
   144  	c.Assert(user.PasswordValid("a-password"), jc.IsTrue)
   145  }
   146  
   147  func (s *UserSuite) TestSetPasswordHash(c *gc.C) {
   148  	user := s.Factory.MakeUser(c, nil)
   149  
   150  	salt, err := utils.RandomSalt()
   151  	c.Assert(err, jc.ErrorIsNil)
   152  	err = user.SetPasswordHash(utils.UserPasswordHash("foo", salt), salt)
   153  	c.Assert(err, jc.ErrorIsNil)
   154  
   155  	c.Assert(user.PasswordValid("foo"), jc.IsTrue)
   156  	c.Assert(user.PasswordValid("bar"), jc.IsFalse)
   157  
   158  	// User passwords should *not* use the fast PasswordHash function
   159  	hash := utils.AgentPasswordHash("foo-12345678901234567890")
   160  	c.Assert(err, jc.ErrorIsNil)
   161  	err = user.SetPasswordHash(hash, "")
   162  	c.Assert(err, jc.ErrorIsNil)
   163  
   164  	c.Assert(user.PasswordValid("foo-12345678901234567890"), jc.IsFalse)
   165  }
   166  
   167  func (s *UserSuite) TestSetPasswordHashWithSalt(c *gc.C) {
   168  	user := s.Factory.MakeUser(c, nil)
   169  
   170  	err := user.SetPasswordHash(utils.UserPasswordHash("foo", "salted"), "salted")
   171  	c.Assert(err, jc.ErrorIsNil)
   172  
   173  	c.Assert(user.PasswordValid("foo"), jc.IsTrue)
   174  	salt, _ := state.GetUserPasswordSaltAndHash(user)
   175  	c.Assert(salt, gc.Equals, "salted")
   176  }
   177  
   178  func (s *UserSuite) TestCantDisableAdmin(c *gc.C) {
   179  	user, err := s.State.User(s.Owner)
   180  	c.Assert(err, jc.ErrorIsNil)
   181  	err = user.Disable()
   182  	c.Assert(err, gc.ErrorMatches, "cannot disable controller model owner")
   183  }
   184  
   185  func (s *UserSuite) TestCaseSensitiveUsersErrors(c *gc.C) {
   186  	s.Factory.MakeUser(c, &factory.UserParams{Name: "Bob"})
   187  
   188  	_, err := s.State.AddUser(
   189  		"boB", "ignored", "ignored", "ignored")
   190  	c.Assert(errors.IsAlreadyExists(err), jc.IsTrue)
   191  	c.Assert(err, gc.ErrorMatches, "user already exists")
   192  }
   193  
   194  func (s *UserSuite) TestCaseInsensitiveLookup(c *gc.C) {
   195  	expectedUser := s.Factory.MakeUser(c, &factory.UserParams{Name: "Bob"})
   196  
   197  	assertCaseInsensitiveLookup := func(name string) {
   198  		userTag := names.NewUserTag(name)
   199  		obtainedUser, err := s.State.User(userTag)
   200  		c.Assert(err, jc.ErrorIsNil)
   201  		c.Assert(obtainedUser, gc.DeepEquals, expectedUser)
   202  	}
   203  
   204  	assertCaseInsensitiveLookup("bob")
   205  	assertCaseInsensitiveLookup("bOb")
   206  	assertCaseInsensitiveLookup("boB")
   207  	assertCaseInsensitiveLookup("BOB")
   208  }
   209  
   210  func (s *UserSuite) TestAllUsers(c *gc.C) {
   211  	// Create in non-alphabetical order.
   212  	s.Factory.MakeUser(c, &factory.UserParams{Name: "conrad"})
   213  	s.Factory.MakeUser(c, &factory.UserParams{Name: "adam"})
   214  	s.Factory.MakeUser(c, &factory.UserParams{Name: "debbie", Disabled: true})
   215  	s.Factory.MakeUser(c, &factory.UserParams{Name: "barbara"})
   216  	s.Factory.MakeUser(c, &factory.UserParams{Name: "fred", Disabled: true})
   217  	s.Factory.MakeUser(c, &factory.UserParams{Name: "erica"})
   218  	// There is the existing controller owner called "test-admin"
   219  
   220  	includeDeactivated := false
   221  	users, err := s.State.AllUsers(includeDeactivated)
   222  	c.Assert(err, jc.ErrorIsNil)
   223  	c.Assert(users, gc.HasLen, 5)
   224  	c.Check(users[0].Name(), gc.Equals, "adam")
   225  	c.Check(users[1].Name(), gc.Equals, "barbara")
   226  	c.Check(users[2].Name(), gc.Equals, "conrad")
   227  	c.Check(users[3].Name(), gc.Equals, "erica")
   228  	c.Check(users[4].Name(), gc.Equals, "test-admin")
   229  
   230  	includeDeactivated = true
   231  	users, err = s.State.AllUsers(includeDeactivated)
   232  	c.Assert(err, jc.ErrorIsNil)
   233  	c.Assert(users, gc.HasLen, 7)
   234  	c.Check(users[0].Name(), gc.Equals, "adam")
   235  	c.Check(users[1].Name(), gc.Equals, "barbara")
   236  	c.Check(users[2].Name(), gc.Equals, "conrad")
   237  	c.Check(users[3].Name(), gc.Equals, "debbie")
   238  	c.Check(users[4].Name(), gc.Equals, "erica")
   239  	c.Check(users[5].Name(), gc.Equals, "fred")
   240  	c.Check(users[6].Name(), gc.Equals, "test-admin")
   241  }
   242  
   243  func (s *UserSuite) TestAddUserNoSecretKey(c *gc.C) {
   244  	u, err := s.State.AddUser("bob", "display", "pass", "admin")
   245  	c.Assert(err, jc.ErrorIsNil)
   246  	c.Assert(u.SecretKey(), gc.IsNil)
   247  }
   248  
   249  func (s *UserSuite) TestAddUserSecretKey(c *gc.C) {
   250  	u, err := s.State.AddUserWithSecretKey("bob", "display", "admin")
   251  	c.Assert(err, jc.ErrorIsNil)
   252  	c.Assert(u.SecretKey(), gc.HasLen, 32)
   253  	c.Assert(u.PasswordValid(""), jc.IsFalse)
   254  }
   255  
   256  func (s *UserSuite) TestSetPasswordClearsSecretKey(c *gc.C) {
   257  	u, err := s.State.AddUserWithSecretKey("bob", "display", "admin")
   258  	c.Assert(err, jc.ErrorIsNil)
   259  	c.Assert(u.SecretKey(), gc.HasLen, 32)
   260  	err = u.SetPassword("anything")
   261  	c.Assert(err, jc.ErrorIsNil)
   262  	c.Assert(u.SecretKey(), gc.IsNil)
   263  	err = u.Refresh()
   264  	c.Assert(err, jc.ErrorIsNil)
   265  	c.Assert(u.SecretKey(), gc.IsNil)
   266  }