91 lines
3.8 KiB
Go
91 lines
3.8 KiB
Go
package system
|
|
|
|
import (
|
|
"context"
|
|
"kra/internal/biz/system"
|
|
"testing"
|
|
)
|
|
|
|
func seedStrictUserTree(t *testing.T, data *Data) (actorID, childID, siblingID uint, users []userPO) {
|
|
t.Helper()
|
|
enableStrictAuthorityTestMode(data)
|
|
db := data.gormDB.WithContext(context.Background())
|
|
rootID := uint(888)
|
|
actorID, childID, siblingID = 8001, 8002, 9001
|
|
if err := db.Create(&[]authorityPO{
|
|
{AuthorityID: rootID, ParentID: authorityUintPointer(0)},
|
|
{AuthorityID: actorID, ParentID: &rootID},
|
|
{AuthorityID: childID, ParentID: &actorID},
|
|
{AuthorityID: siblingID, ParentID: &rootID},
|
|
}).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
users = []userPO{
|
|
{Username: "actor-user", Password: "hash", AuthorityID: actorID, Enable: 1},
|
|
{Username: "managed-user", Password: "hash", AuthorityID: childID, Enable: 1},
|
|
{Username: "outside-user", Password: "hash", AuthorityID: siblingID, Enable: 1},
|
|
}
|
|
if err := db.Create(&users).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return actorID, childID, siblingID, users
|
|
}
|
|
|
|
func TestStrictUserMutationsRejectOutsideTargetAndAllowSelfPassword(t *testing.T) {
|
|
data := newTransactionTestData(t)
|
|
actorID, _, _, users := seedStrictUserTree(t, data)
|
|
ctx := system.NewActorContext(context.Background(), system.Actor{UserID: users[0].ID, AuthorityID: actorID})
|
|
repo := &userRepo{data: data}
|
|
|
|
if err := repo.UpdateUser(ctx, &system.User{ID: users[2].ID, NickName: "changed"}); err == nil {
|
|
t.Fatal("UpdateUser() accepted an out-of-scope target")
|
|
}
|
|
if err := repo.DeleteUser(ctx, users[2].ID); err == nil {
|
|
t.Fatal("DeleteUser() accepted an out-of-scope target")
|
|
}
|
|
if err := repo.UpdatePassword(ctx, users[2].ID, "new-hash", false); err == nil {
|
|
t.Fatal("UpdatePassword() accepted an out-of-scope target")
|
|
}
|
|
if err := repo.UpdatePassword(ctx, users[0].ID, "self-hash", true); err != nil {
|
|
t.Fatalf("UpdatePassword() rejected the current user: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestStrictUserCreationAndRoleAssignmentRequireManagedAuthorities(t *testing.T) {
|
|
data := newTransactionTestData(t)
|
|
actorID, childID, siblingID, users := seedStrictUserTree(t, data)
|
|
ctx := system.NewActorContext(context.Background(), system.Actor{UserID: users[0].ID, AuthorityID: actorID})
|
|
repo := &userRepo{data: data}
|
|
|
|
if _, err := repo.CreateUserWithAuthorities(ctx, &system.User{Username: "outside-create", Password: "hash", AuthorityID: siblingID, Enable: 1}, nil); err == nil {
|
|
t.Fatal("CreateUserWithAuthorities() accepted an out-of-scope primary authority")
|
|
}
|
|
if _, err := repo.CreateUserWithAuthorities(ctx, &system.User{Username: "managed-create", Password: "hash", AuthorityID: childID, Enable: 1}, []uint{childID}); err != nil {
|
|
t.Fatalf("CreateUserWithAuthorities() rejected managed authorities: %v", err)
|
|
}
|
|
if err := repo.SetUserAuthorities(ctx, users[1].ID, []uint{siblingID}); err == nil {
|
|
t.Fatal("SetUserAuthorities() accepted an out-of-scope authority")
|
|
}
|
|
if err := repo.SetUserAuthorities(ctx, users[2].ID, []uint{childID}); err == nil {
|
|
t.Fatal("SetUserAuthorities() accepted an out-of-scope user target")
|
|
}
|
|
}
|
|
|
|
func TestStrictUserUpdateRejectsPrimaryAuthorityOutsideManagedTree(t *testing.T) {
|
|
data := newTransactionTestData(t)
|
|
actorID, childID, siblingID, users := seedStrictUserTree(t, data)
|
|
ctx := system.NewActorContext(context.Background(), system.Actor{UserID: users[0].ID, AuthorityID: actorID})
|
|
repo := &userRepo{data: data}
|
|
|
|
if err := repo.UpdateUser(ctx, &system.User{ID: users[1].ID, NickName: "changed", AuthorityID: siblingID}); err == nil {
|
|
t.Fatal("UpdateUser() accepted a primary authority outside the managed tree")
|
|
}
|
|
var stored userPO
|
|
if err := data.gormDB.WithContext(context.Background()).First(&stored, users[1].ID).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if stored.AuthorityID != childID || stored.NickName == "changed" {
|
|
t.Fatalf("rejected update changed user: %+v", stored)
|
|
}
|
|
}
|