fix(auth): restore self role lookup and lock regression coverage
This commit is contained in:
@@ -1211,7 +1211,7 @@
|
||||
- 密码登录:启用
|
||||
- 邮箱验证码登录:仅在 SMTP 配置完整时启用
|
||||
- 短信验证码登录:仅在阿里云或腾讯云短信配置完整时启用
|
||||
- 账号绑定与解绑:邮箱 / 手机号 / 社交账号产品闭环已完成;邮箱与短信绑定分别依赖对应验证码通道配置
|
||||
- 账号绑定与解绑:邮箱/手机号仅在对应验证码通道启用时可发起;社交账号绑定依赖已配置的 OAuth provider。未配置时前端不会暴露可绑定 provider,后端绑定接口 fail-closed 返回 `503`,不能宣称该链路已默认产品闭环
|
||||
- 密码重置:仅在 SMTP 配置完整时启用
|
||||
- 首登管理员初始化:当系统不存在激活管理员时,`/login` 与 `/register` 会基于 `GET /api/v1/auth/capabilities` 暴露 `/bootstrap-admin` 入口;初始化成功后会直接进入后台,且该入口自动关闭
|
||||
- TOTP:启用
|
||||
|
||||
@@ -757,18 +757,48 @@ func TestUserHandler_UpdateUserStatus_RequiresAdmin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserHandler_GetUserRoles_ForbiddenForRegularUser(t *testing.T) {
|
||||
func TestUserHandler_GetUserRoles_SelfCanView(t *testing.T) {
|
||||
server, cleanup := setupHandlerTestServer(t)
|
||||
defer cleanup()
|
||||
|
||||
registerUser(server.URL, "rolesuser", "rolesuser@test.com", "UserPass123!")
|
||||
token := getToken(server.URL, "rolesuser", "UserPass123!")
|
||||
|
||||
resp, _ := doGet(server.URL+"/api/v1/users/1/roles", token)
|
||||
resp, body := doGet(server.URL+"/api/v1/users/1/roles", token)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Errorf("expected status %d for self role lookup, got %d, body: %s", http.StatusOK, resp.StatusCode, body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserHandler_GetUserRoles_ForbiddenForOtherRegularUser(t *testing.T) {
|
||||
server, cleanup := setupHandlerTestServer(t)
|
||||
defer cleanup()
|
||||
|
||||
registerUser(server.URL, "rolesuser", "rolesuser@test.com", "UserPass123!")
|
||||
registerUser(server.URL, "otherrolesuser", "otherrolesuser@test.com", "UserPass123!")
|
||||
token := getToken(server.URL, "rolesuser", "UserPass123!")
|
||||
|
||||
resp, _ := doGet(server.URL+"/api/v1/users/2/roles", token)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusForbidden {
|
||||
t.Errorf("expected status %d for non-admin user, got %d", http.StatusForbidden, resp.StatusCode)
|
||||
t.Errorf("expected status %d for viewing another user's roles, got %d", http.StatusForbidden, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserHandler_GetUserRoles_UnauthorizedWithoutToken(t *testing.T) {
|
||||
server, cleanup := setupHandlerTestServer(t)
|
||||
defer cleanup()
|
||||
|
||||
registerUser(server.URL, "rolesuser", "rolesuser@test.com", "UserPass123!")
|
||||
|
||||
resp, _ := doGet(server.URL+"/api/v1/users/1/roles", "")
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusUnauthorized {
|
||||
t.Errorf("expected status %d without token, got %d", http.StatusUnauthorized, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,6 +820,23 @@ func TestUserHandler_GetUserRoles_AdminCanViewOther(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserHandler_GetUserRoles_AdminGetsNotFoundForMissingUser(t *testing.T) {
|
||||
server, cleanup := setupHandlerTestServer(t)
|
||||
defer cleanup()
|
||||
|
||||
token := bootstrapAdminToken(server.URL, "rolesbootstrap", "rolesbootstrap@test.com", "AdminPass123!")
|
||||
if token == "" {
|
||||
t.Fatal("bootstrap admin token should succeed")
|
||||
}
|
||||
|
||||
resp, _ := doGet(server.URL+"/api/v1/users/99999/roles", token)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusNotFound {
|
||||
t.Errorf("expected status %d for missing user, got %d", http.StatusNotFound, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserHandler_AssignRoles_RequiresAdmin(t *testing.T) {
|
||||
server, cleanup := setupHandlerTestServer(t)
|
||||
defer cleanup()
|
||||
|
||||
@@ -212,7 +212,7 @@ func (r *Router) Setup() *gin.Engine {
|
||||
users.DELETE("/:id", middleware.RequirePermission("user:delete"), r.userHandler.DeleteUser)
|
||||
users.PUT("/:id/password", r.userHandler.UpdatePassword)
|
||||
users.PUT("/:id/status", middleware.RequirePermission("user:manage"), r.userHandler.UpdateUserStatus)
|
||||
users.GET("/:id/roles", middleware.RequirePermission("user:manage"), r.userHandler.GetUserRoles)
|
||||
users.GET("/:id/roles", r.userHandler.GetUserRoles)
|
||||
users.PUT("/:id/roles", middleware.RequirePermission("user:manage"), r.userHandler.AssignRoles)
|
||||
users.PUT("/batch/status", middleware.RequirePermission("user:manage"), r.userHandler.BatchUpdateStatus)
|
||||
users.DELETE("/batch", middleware.RequirePermission("user:delete"), r.userHandler.BatchDelete)
|
||||
|
||||
Reference in New Issue
Block a user