feat: restrict permission roles

This commit is contained in:
Frudrax Cheng
2026-06-06 13:50:56 +08:00
parent a55f515930
commit 5edb25ac4e
17 changed files with 229 additions and 175 deletions
+29 -42
View File
@@ -18,13 +18,13 @@ func TestUsersService_Create_Success(t *testing.T) {
Email: "new@example.com",
Phone: "13800000001",
EmployeeNo: "users_create_ok",
Position: "技术员",
Role: "technician",
Position: "软件工程师",
Role: "software_engineer",
})
assert.NoError(t, err)
assert.NotNil(t, dto)
assert.Equal(t, "users_create_ok", dto.Username)
assert.Equal(t, "technician", dto.Role)
assert.Equal(t, "software_engineer", dto.Role)
assert.Equal(t, "13800000001", dto.Phone)
assert.Equal(t, "users_create_ok", dto.EmployeeNo)
assert.Len(t, dto.EmployeeSerials, 1)
@@ -33,35 +33,17 @@ func TestUsersService_Create_Success(t *testing.T) {
database.DB.Unscoped().Where("employee_name = ?", "新技术员").Delete(&models.EmployeeSerial{})
}
func TestUsersService_Create_EmployeeWithoutPasswordGeneratesSerial(t *testing.T) {
func TestUsersService_Create_BlocksEmployeeRole(t *testing.T) {
svc := UsersService{}
dto, err := svc.Create(models.CreateUserDTO{
_, err := svc.Create(models.CreateUserDTO{
Name: "普通员工",
Phone: "13800000002",
EmployeeNo: "employee_no_pwd",
Position: "生产员工",
Role: "employee",
})
assert.NoError(t, err)
assert.NotNil(t, dto)
assert.Equal(t, "employee", dto.Role)
assert.Len(t, dto.EmployeeSerials, 1)
var user models.User
assert.NoError(t, database.DB.Where("employee_no = ?", "employee_no_pwd").First(&user).Error)
assert.Empty(t, user.Password)
serialService := EmployeeSerialsService{}
serial, err := serialService.Query(dto.EmployeeSerials[0].SerialNumber)
assert.NoError(t, err)
assert.NotNil(t, serial.Employee)
assert.Equal(t, "普通员工", serial.Employee.Name)
assert.Equal(t, "13800000002", serial.Employee.Phone)
assert.Equal(t, "employee_no_pwd", serial.Employee.EmployeeNo)
assert.Equal(t, "生产员工", serial.Employee.Position)
database.DB.Unscoped().Where("employee_id = ?", user.ID).Delete(&models.EmployeeSerial{})
database.DB.Unscoped().Delete(&user)
assert.Error(t, err)
assert.Contains(t, err.Error(), "权限管理只能创建")
}
func TestUsersService_Create_BackendRoleRequiresPassword(t *testing.T) {
@@ -70,8 +52,8 @@ func TestUsersService_Create_BackendRoleRequiresPassword(t *testing.T) {
Name: "无密码技术员",
Phone: "13800000003",
EmployeeNo: "tech_no_pwd",
Position: "技术员",
Role: "technician",
Position: "软件工程师",
Role: "software_engineer",
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "必须设置")
@@ -82,7 +64,7 @@ func TestUsersService_Create_DuplicateUsername(t *testing.T) {
Username: "users_create_dup",
Password: "x",
Name: "existing",
Role: "technician",
Role: "software_engineer",
}
database.DB.Create(&user)
defer database.DB.Unscoped().Delete(&user)
@@ -94,8 +76,8 @@ func TestUsersService_Create_DuplicateUsername(t *testing.T) {
Name: "duplicate",
Phone: "13800000004",
EmployeeNo: "users_create_dup_2",
Position: "技术员",
Role: "technician",
Position: "软件工程师",
Role: "software_engineer",
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "用户名已存在")
@@ -113,10 +95,10 @@ func TestUsersService_Update_BlocksSelfDemotion(t *testing.T) {
svc := UsersService{}
_, err := svc.Update(admin.ID, models.UpdateUserDTO{
Role: "technician",
Role: "software_engineer",
}, admin.ID)
assert.Error(t, err)
assert.Contains(t, err.Error(), "不能修改自己的管理员角色")
assert.Contains(t, err.Error(), "不能通过权限管理修改管理员角色")
}
func TestUsersService_Update_AllowsRoleChangeForOthers(t *testing.T) {
@@ -130,7 +112,7 @@ func TestUsersService_Update_AllowsRoleChangeForOthers(t *testing.T) {
Username: "users_update_target",
Password: "x",
Name: "target",
Role: "technician",
Role: "software_engineer",
}
database.DB.Create(&currentAdmin)
database.DB.Create(&target)
@@ -140,11 +122,11 @@ func TestUsersService_Update_AllowsRoleChangeForOthers(t *testing.T) {
svc := UsersService{}
updated, err := svc.Update(target.ID, models.UpdateUserDTO{
Name: "新名字",
Role: "admin",
Role: "project_manager",
}, currentAdmin.ID)
assert.NoError(t, err)
assert.Equal(t, "新名字", updated.Name)
assert.Equal(t, "admin", updated.Role)
assert.Equal(t, "project_manager", updated.Role)
}
func TestUsersService_ResetPassword_ChangesHash(t *testing.T) {
@@ -153,7 +135,7 @@ func TestUsersService_ResetPassword_ChangesHash(t *testing.T) {
Username: "users_reset_pwd",
Password: string(hashed),
Name: "reset",
Role: "technician",
Role: "software_engineer",
}
database.DB.Create(&user)
defer database.DB.Unscoped().Delete(&user)
@@ -214,15 +196,18 @@ func TestUsersService_Delete_BlocksLastAdmin(t *testing.T) {
database.DB.Unscoped().Delete(&last)
}
func TestUsersService_FindAssignable_ReturnsAdminAndTechnician(t *testing.T) {
func TestUsersService_FindAssignable_ReturnsWorkOrderRoles(t *testing.T) {
a := models.User{Username: "assignable_admin", Password: "x", Name: "A", Role: "admin"}
tech := models.User{Username: "assignable_tech", Password: "x", Name: "T", Role: "technician"}
software := models.User{Username: "assignable_software", Password: "x", Name: "S", Role: "software_engineer"}
plain := models.User{Username: "assignable_user", Password: "x", Name: "U", Role: "employee"}
database.DB.Create(&a)
database.DB.Create(&tech)
database.DB.Create(&software)
database.DB.Create(&plain)
defer database.DB.Unscoped().Delete(&a)
defer database.DB.Unscoped().Delete(&tech)
defer database.DB.Unscoped().Delete(&software)
defer database.DB.Unscoped().Delete(&plain)
svc := UsersService{}
@@ -233,15 +218,17 @@ func TestUsersService_FindAssignable_ReturnsAdminAndTechnician(t *testing.T) {
for _, u := range users {
usernames[u.Username] = u.Role
}
assert.Equal(t, "admin", usernames["assignable_admin"])
assert.Equal(t, "technician", usernames["assignable_tech"])
assert.Equal(t, "software_engineer", usernames["assignable_software"])
_, hasAdmin := usernames["assignable_admin"]
assert.False(t, hasAdmin, "admin should not be assignable")
_, hasPlain := usernames["assignable_user"]
assert.False(t, hasPlain, "plain user should not be assignable")
}
func TestUsersService_FindAll_FilterByRole(t *testing.T) {
tech1 := models.User{Username: "findall_tech1", Password: "x", Name: "T1", Role: "technician"}
tech2 := models.User{Username: "findall_tech2", Password: "x", Name: "T2", Role: "technician"}
tech1 := models.User{Username: "findall_tech1", Password: "x", Name: "T1", Role: "software_engineer"}
tech2 := models.User{Username: "findall_tech2", Password: "x", Name: "T2", Role: "software_engineer"}
user1 := models.User{Username: "findall_user1", Password: "x", Name: "U1", Role: "employee"}
database.DB.Create(&tech1)
database.DB.Create(&tech2)
@@ -251,9 +238,9 @@ func TestUsersService_FindAll_FilterByRole(t *testing.T) {
defer database.DB.Unscoped().Delete(&user1)
svc := UsersService{}
results, _, _, err := svc.FindAll(1, 50, "technician", "")
results, _, _, err := svc.FindAll(1, 50, "software_engineer", "")
assert.NoError(t, err)
for _, u := range results {
assert.Equal(t, "technician", u.Role)
assert.Equal(t, "software_engineer", u.Role)
}
}