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 }