github.com/avfs/avfs@v0.33.1-0.20240303173310-c6ba67c33eb7/test/test_idm.go (about) 1 // 2 // Copyright 2020 The AVFS authors 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 package test 18 19 import ( 20 "fmt" 21 "io/fs" 22 "math" 23 "math/rand" 24 "testing" 25 26 "github.com/avfs/avfs" 27 ) 28 29 // TestIdmAll runs all identity manager tests. 30 func (ts *Suite) TestIdmAll(t *testing.T) { 31 defer ts.setInitUser(t) 32 33 ts.TestAdminGroupUser(t) 34 ts.TestGroupAddDel(t) 35 ts.TestUserAddDel(t) 36 ts.TestLookup(t) 37 } 38 39 // TestAdminGroupUser tests AdminGroup and AdminUser. 40 func (ts *Suite) TestAdminGroupUser(t *testing.T) { 41 idm := ts.idm 42 43 if !idm.HasFeature(avfs.FeatIdentityMgr) { 44 wantGroup, wantUser := avfs.DefaultName, avfs.DefaultName 45 46 ag := idm.AdminGroup() 47 if ag.Name() != wantGroup { 48 t.Errorf("AdminGroup : want name to be %s, got %s", wantGroup, ag.Name()) 49 } 50 51 if ag.Gid() != math.MaxInt { 52 t.Errorf("AdminGroup : want Gid to be %d, got %d", math.MaxInt, ag.Gid()) 53 } 54 55 au := idm.AdminUser() 56 if au.Name() != wantUser { 57 t.Errorf("AdminUser : want name to be %s, got %s", wantUser, au.Name()) 58 } 59 60 if au.Uid() != math.MaxInt { 61 t.Errorf("AdminUser : want Uid to be %d, got %d", math.MaxInt, au.Uid()) 62 } 63 64 if au.Gid() != math.MaxInt { 65 t.Errorf("AdminUser : want Gid to be %d, got %d", math.MaxInt, au.Gid()) 66 } 67 68 if au.IsAdmin() { 69 t.Errorf("AdminUser : want IsAdmin to be false, got true") 70 } 71 72 return 73 } 74 75 t.Run("Admin", func(t *testing.T) { 76 wantGroupName := avfs.AdminGroupName(avfs.CurrentOSType()) 77 ag := idm.AdminGroup() 78 79 if ag.Name() != wantGroupName { 80 t.Errorf("AdminGroup : want name to be %s, got %s", wantGroupName, ag.Name()) 81 } 82 83 wantUserName := avfs.AdminUserName(avfs.CurrentOSType()) 84 au := idm.AdminUser() 85 86 if au.Name() != wantUserName { 87 t.Errorf("AdminUser : want name to be %s, got %s", wantUserName, au.Name()) 88 } 89 }) 90 } 91 92 // TestGroupAddDel tests GroupAdd and GroupDel functions. 93 func (ts *Suite) TestGroupAddDel(t *testing.T) { 94 idm := ts.idm 95 suffix := fmt.Sprintf("GroupAddDel%x", rand.Uint32()) 96 97 if !idm.HasFeature(avfs.FeatIdentityMgr) || idm.HasFeature(avfs.FeatReadOnlyIdm) { 98 groupName := "AGroup" + suffix 99 100 _, err := idm.GroupAdd(groupName) 101 if err != avfs.ErrPermDenied { 102 t.Errorf("GroupAdd : want error to be %v, got %v", avfs.ErrPermDenied, err) 103 } 104 105 err = idm.GroupDel(groupName) 106 if err != avfs.ErrPermDenied { 107 t.Errorf("GroupDel : want error to be %v, got %v", avfs.ErrPermDenied, err) 108 } 109 110 return 111 } 112 113 gis := GroupInfos() 114 prevGid := 0 115 116 t.Run("GroupAdd", func(t *testing.T) { 117 for _, gi := range gis { 118 groupName := gi.Name + suffix 119 wantGroupErr := avfs.UnknownGroupError(groupName) 120 121 _, err := idm.LookupGroup(groupName) 122 if err != wantGroupErr { 123 t.Errorf("LookupGroupName %s : want error to be %v, got %v", groupName, wantGroupErr, err) 124 } 125 126 g, err := idm.GroupAdd(groupName) 127 if !AssertNoError(t, err, "GroupAdd %s", groupName) { 128 continue 129 } 130 131 if g.Name() != groupName { 132 t.Errorf("GroupAdd %s : want Name to be %s, got %s", groupName, groupName, g.Name()) 133 } 134 135 if g.Gid() <= prevGid { 136 t.Errorf("GroupAdd %s : want gid to be > %d, got %d", groupName, prevGid, g.Gid()) 137 } else { 138 prevGid = g.Gid() 139 } 140 141 _, err = idm.LookupGroup(groupName) 142 RequireNoError(t, err, "LookupGroup %s", groupName) 143 144 _, err = idm.LookupGroupId(g.Gid()) 145 RequireNoError(t, err, "LookupGroupId %s", groupName) 146 } 147 }) 148 149 t.Run("GroupAddExists", func(t *testing.T) { 150 for _, gi := range gis { 151 groupName := gi.Name + suffix 152 153 _, err := idm.GroupAdd(groupName) 154 if err != avfs.AlreadyExistsGroupError(groupName) { 155 t.Errorf("GroupAdd %s : want error to be %v, got %v", 156 groupName, avfs.AlreadyExistsGroupError(groupName), err) 157 } 158 } 159 }) 160 161 t.Run("GroupDel", func(t *testing.T) { 162 for _, gi := range gis { 163 groupName := gi.Name + suffix 164 165 g, err := idm.LookupGroup(groupName) 166 RequireNoError(t, err, "LookupGroup %s", groupName) 167 168 err = idm.GroupDel(groupName) 169 RequireNoError(t, err, "GroupDel %s", groupName) 170 171 _, err = idm.LookupGroup(g.Name()) 172 wantGroupErr := avfs.UnknownGroupError(groupName) 173 174 if err != wantGroupErr { 175 t.Errorf("LookupGroup %s : want error to be %v, got %v", groupName, wantGroupErr, err) 176 } 177 178 _, err = idm.LookupGroupId(g.Gid()) 179 wantGroupIdErr := avfs.UnknownGroupIdError(g.Gid()) 180 181 if err != wantGroupIdErr { 182 t.Errorf("LookupGroupId %s : want error to be %v, got %v", groupName, wantGroupIdErr, err) 183 } 184 185 err = idm.GroupDel(groupName) 186 if err != wantGroupErr { 187 t.Errorf("GroupDel %s : want error to be %v, got %v", groupName, wantGroupErr, err) 188 } 189 } 190 }) 191 } 192 193 // TestUserAddDel tests UserAdd and UserDel functions. 194 func (ts *Suite) TestUserAddDel(t *testing.T) { 195 idm := ts.idm 196 suffix := fmt.Sprintf("UserAddDel%x", rand.Uint32()) 197 198 if !idm.HasFeature(avfs.FeatIdentityMgr) || idm.HasFeature(avfs.FeatReadOnlyIdm) { 199 groupName := "InvalidGroup" + suffix 200 userName := "InvalidUser" + suffix 201 202 _, err := idm.UserAdd(userName, groupName) 203 if err != avfs.ErrPermDenied { 204 t.Errorf("UserAdd : want error to be %v, got %v", avfs.ErrPermDenied, err) 205 } 206 207 err = idm.UserDel(userName) 208 if err != avfs.ErrPermDenied { 209 t.Errorf("UserDel : want error to be %v, got %v", avfs.ErrPermDenied, err) 210 } 211 212 return 213 } 214 215 ts.CreateGroups(t, suffix) 216 217 prevUid := 0 218 uis := UserInfos() 219 220 t.Run("UserAdd", func(t *testing.T) { 221 for _, ui := range uis { 222 groupName := ui.GroupName + suffix 223 224 g, err := idm.LookupGroup(groupName) 225 RequireNoError(t, err, "LookupGroup %s", groupName) 226 227 userName := ui.Name + suffix 228 wantUserErr := avfs.UnknownUserError(userName) 229 230 _, err = idm.LookupUser(userName) 231 if err != wantUserErr { 232 t.Errorf("LookupUser %s : want error to be %v, got %v", userName, wantUserErr, err) 233 } 234 235 u, err := idm.UserAdd(userName, groupName) 236 RequireNoError(t, err, "UserAdd %s", userName) 237 238 if u == nil { 239 t.Errorf("UserAdd %s : want user to be not nil, got nil", userName) 240 241 continue 242 } 243 244 if u.Name() != userName { 245 t.Errorf("UserAdd %s : want Name to be %s, got %s", userName, userName, u.Name()) 246 } 247 248 if u.Uid() <= prevUid { 249 t.Errorf("UserAdd %s : want uid to be > %d, got %d", userName, prevUid, u.Uid()) 250 } else { 251 prevUid = u.Uid() 252 } 253 254 if u.Gid() != g.Gid() { 255 t.Errorf("UserAdd %s : want gid to be %d, got %d", userName, g.Gid(), u.Gid()) 256 } 257 258 if u.IsAdmin() { 259 t.Errorf("IsAdmin %s : want IsAdmin to be false, got true", userName) 260 } 261 262 _, err = idm.LookupUser(userName) 263 RequireNoError(t, err, "LookupUser %s", userName) 264 265 _, err = idm.LookupUserId(u.Uid()) 266 RequireNoError(t, err, "LookupUserId %s", userName) 267 } 268 }) 269 270 t.Run("UserAddDelErrors", func(t *testing.T) { 271 for _, ui := range uis { 272 groupName := ui.GroupName + suffix 273 userName := ui.Name + suffix 274 275 _, err := idm.UserAdd(userName, groupName) 276 if err != avfs.AlreadyExistsUserError(userName) { 277 t.Errorf("UserAdd %s : want error to be %v, got %v", userName, 278 avfs.AlreadyExistsUserError(userName), err) 279 } 280 281 groupNameNotFound := ui.GroupName + "NotFound" 282 283 _, err = idm.UserAdd(userName, groupNameNotFound) 284 if err != avfs.UnknownGroupError(groupNameNotFound) { 285 t.Errorf("UserAdd %s : want error to be %v, got %v", userName, 286 avfs.UnknownGroupError(groupNameNotFound), err) 287 } 288 289 userNameNotFound := ui.Name + "NotFound" 290 291 err = idm.UserDel(userNameNotFound) 292 if err != avfs.UnknownUserError(userNameNotFound) { 293 t.Errorf("UserDel %s : want error to be %v, got %v", userName, 294 avfs.UnknownUserError(userNameNotFound), err) 295 } 296 } 297 }) 298 299 t.Run("UserDel", func(t *testing.T) { 300 for _, ui := range uis { 301 userName := ui.Name + suffix 302 303 u, err := idm.LookupUser(userName) 304 RequireNoError(t, err, "LookupUser %s", userName) 305 306 err = idm.UserDel(userName) 307 RequireNoError(t, err, "UserDel %s", userName) 308 309 _, err = idm.LookupUser(u.Name()) 310 wantUserErr := avfs.UnknownUserError(userName) 311 312 if err != wantUserErr { 313 t.Errorf("LookupUser %s : want error to be %v, got %v", userName, wantUserErr, err) 314 } 315 316 _, err = idm.LookupUserId(u.Uid()) 317 wantUserIdErr := avfs.UnknownUserIdError(u.Uid()) 318 319 if err != wantUserIdErr { 320 t.Errorf("LookupUserId %s : want error to be %v, got %v", userName, wantUserIdErr, err) 321 } 322 } 323 }) 324 } 325 326 // TestLookup tests Lookup* functions. 327 func (ts *Suite) TestLookup(t *testing.T) { 328 idm := ts.idm 329 suffix := fmt.Sprintf("Lookup%x", rand.Uint32()) 330 331 if !idm.HasFeature(avfs.FeatIdentityMgr) { 332 groupName := "InvalidGroup" + suffix 333 334 _, err := idm.LookupGroup(groupName) 335 if err != avfs.ErrPermDenied { 336 t.Errorf("LookupGroup : want error to be %v, got %v", avfs.ErrPermDenied, err) 337 } 338 339 _, err = idm.LookupGroupId(0) 340 if err != avfs.ErrPermDenied { 341 t.Errorf("LookupGroupId : want error to be %v, got %v", avfs.ErrPermDenied, err) 342 } 343 344 _, err = idm.LookupUser("") 345 if err != avfs.ErrPermDenied { 346 t.Errorf("LookupUser : want error to be %v, got %v", avfs.ErrPermDenied, err) 347 } 348 349 _, err = idm.LookupUserId(0) 350 if err != avfs.ErrPermDenied { 351 t.Errorf("LookupUserId : want error to be %v, got %v", avfs.ErrPermDenied, err) 352 } 353 354 return 355 } 356 357 if idm.HasFeature(avfs.FeatReadOnlyIdm) { 358 groupName := "InvalidGroup" + suffix 359 _, err := idm.LookupGroup(groupName) 360 361 wantGroupErr := avfs.UnknownGroupError(groupName) 362 if err != wantGroupErr { 363 t.Errorf("LookupGroup %s : want error to be %v, got %v", groupName, wantGroupErr, err) 364 } 365 } 366 367 groups := ts.CreateGroups(t, suffix) 368 users := ts.CreateUsers(t, suffix) 369 370 t.Run("LookupGroup", func(t *testing.T) { 371 for _, wantGroup := range groups { 372 groupName := wantGroup.Name() 373 wantErr := avfs.UnknownGroupError(groupName) 374 375 g, err := idm.LookupGroup(groupName) 376 if idm.HasFeature(avfs.FeatReadOnlyIdm) { 377 if err != wantErr { 378 t.Errorf("LookupGroup %s : want error to be %v, got %v", groupName, wantErr, err) 379 } 380 381 continue 382 } 383 384 if !AssertNoError(t, err, "LookupGroup %s", groupName) { 385 continue 386 } 387 388 if g.Name() != groupName { 389 t.Errorf("LookupGroup %s : want name to be %s, got %s", groupName, groupName, g.Name()) 390 } 391 392 if g.Gid() != wantGroup.Gid() { 393 t.Errorf("LookupGroup %s : want gid to be %d, got %d", groupName, wantGroup.Gid(), g.Gid()) 394 } 395 } 396 }) 397 398 t.Run("LookupUser", func(t *testing.T) { 399 for _, wantUser := range users { 400 userName := wantUser.Name() 401 wantErr := avfs.UnknownUserError(userName) 402 403 u, err := idm.LookupUser(userName) 404 if idm.HasFeature(avfs.FeatReadOnlyIdm) { 405 if err != wantErr { 406 t.Errorf("LookupUser %s : want error to be %v, got %v", userName, wantErr, err) 407 } 408 409 continue 410 } 411 412 if !AssertNoError(t, err, "LookupUser %s", userName) { 413 continue 414 } 415 416 if u.Name() != userName { 417 t.Errorf("LookupUser %s : want name to be %s, got %s", userName, userName, u.Name()) 418 } 419 420 if u.Uid() != wantUser.Uid() { 421 t.Errorf("LookupUser %s : want uid to be %d, got %d", userName, wantUser.Uid(), u.Uid()) 422 } 423 424 if u.Gid() != wantUser.Gid() { 425 t.Errorf("LookupUser %s : want gid to be %d, got %d", userName, wantUser.Gid(), u.Gid()) 426 } 427 428 if (u.Uid() != 0 && u.Gid() != 0) && u.IsAdmin() { 429 t.Errorf("LookupUser %s : want IsAdmin to be false, got true", userName) 430 } 431 } 432 }) 433 } 434 435 const ( 436 grpTest = "grpTest" // grpTest is the default group of the default test user UsrTest. 437 grpOther = "grpOther" // grpOther is the group to test users who are not members of grpTest. 438 grpEmpty = "grpEmpty" // grpEmpty is a group without users. 439 ) 440 441 // GroupInfo contains information to create a test group. 442 type GroupInfo struct { 443 Name string 444 } 445 446 // GroupInfos returns a GroupInfo slice describing the test groups. 447 func GroupInfos() []*GroupInfo { 448 gis := []*GroupInfo{ 449 {Name: grpTest}, 450 {Name: grpOther}, 451 {Name: grpEmpty}, 452 } 453 454 return gis 455 } 456 457 // CreateGroups creates and returns test groups with a suffix appended to each group. 458 // Errors are ignored if the group already exists. 459 func (ts *Suite) CreateGroups(tb testing.TB, suffix string) (groups []avfs.GroupReader) { 460 idm := ts.idm 461 if !idm.HasFeature(avfs.FeatIdentityMgr) || idm.HasFeature(avfs.FeatReadOnlyIdm) { 462 return nil 463 } 464 465 for _, group := range GroupInfos() { 466 groupName := group.Name + suffix 467 468 g, err := idm.GroupAdd(groupName) 469 if err != avfs.AlreadyExistsGroupError(groupName) { 470 RequireNoError(tb, err, "GroupAdd %s", groupName) 471 } 472 473 groups = append(groups, g) 474 } 475 476 return groups 477 } 478 479 const ( 480 UsrTest = "UsrTest" // UsrTest is used to test user access rights. 481 UsrGrp = "UsrGrp" // UsrGrp is a member of the group GrpTest used to test default group access rights. 482 UsrOth = "UsrOth" // UsrOth is a member of the group GrpOth used to test non-members access rights. 483 ) 484 485 // UserInfo contains information to create a test user. 486 type UserInfo struct { 487 Name string 488 GroupName string 489 } 490 491 // UserInfos returns a UserInfo slice describing the test users. 492 func UserInfos() []*UserInfo { 493 uis := []*UserInfo{ 494 {Name: UsrTest, GroupName: grpTest}, 495 {Name: UsrGrp, GroupName: grpTest}, 496 {Name: UsrOth, GroupName: grpOther}, 497 } 498 499 return uis 500 } 501 502 // CreateUsers creates and returns test users with a suffix appended to each user. 503 // Errors are ignored if the user or his home directory already exists. 504 func (ts *Suite) CreateUsers(tb testing.TB, suffix string) (users []avfs.UserReader) { 505 idm := ts.idm 506 if !idm.HasFeature(avfs.FeatIdentityMgr) || idm.HasFeature(avfs.FeatReadOnlyIdm) { 507 return nil 508 } 509 510 for _, ui := range UserInfos() { 511 userName := ui.Name + suffix 512 groupName := ui.GroupName + suffix 513 514 u, err := idm.UserAdd(userName, groupName) 515 if err != nil { 516 switch e := err.(type) { 517 case *fs.PathError: 518 if e.Op != "mkdir" || e.Err != avfs.ErrFileExists { 519 tb.Fatalf("UserAdd %s : want Mkdir error, got %v", userName, err) 520 } 521 default: 522 if err != avfs.AlreadyExistsUserError(userName) { 523 tb.Fatalf("UserAdd %s : want error to be nil, got %v", userName, err) 524 } 525 } 526 527 if u == nil { 528 u, err = idm.LookupUser(userName) 529 RequireNoError(tb, err, "LookupUser %s", userName) 530 } 531 } 532 533 users = append(users, u) 534 } 535 536 return users 537 }