Files
sub2api/backend/internal/handler/admin/user_handler_get_deleted_test.go
T
shaw 35748d8c51 feat(security): gate admin role promotion behind step-up 2FA and harden admin TOTP verification
- 提升用户为管理员 / 创建管理员账号纳入敏感操作:handler 级 EnforceStepUp 门控
  (admin API key 拒绝、未启用 TOTP 拒绝、无 grant 返回 STEP_UP_REQUIRED),
  目标已是管理员的日常编辑不触发
- 管理员启用/停用 2FA 一律使用密码验证(默认通知邮箱常收不到验证码),
  verification-method 按用户角色返回;普通用户行为不变
- 用户编辑/创建弹窗接入 useStepUp:命中 STEP_UP_REQUIRED 弹 TOTP 验证并自动重试
- 审计日志清理入口与其他敏感操作对齐:未启用 2FA 时直接提示先启用 TOTP,
  不再弹出无法完成的验证码输入框(后端强制现场 TOTP 语义不变)
- 审计日志页重构:DataTable 布局、详情弹窗分区展示、时间范围改为 ops 同款
  下拉(预设窗口 + 自定义起止支持时分)
2026-07-16 16:49:08 +08:00

52 lines
1.4 KiB
Go

package admin
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/require"
)
type getByIDAdminStub struct {
service.AdminService
}
func (s *getByIDAdminStub) GetUser(_ context.Context, _ int64) (*service.User, error) {
return nil, service.ErrUserNotFound
}
func (s *getByIDAdminStub) GetUserIncludeDeleted(_ context.Context, id int64) (*service.User, error) {
return &service.User{ID: id, Email: "del@test.com"}, nil
}
func setupGetByIDRouter(svc service.AdminService) *gin.Engine {
gin.SetMode(gin.TestMode)
r := gin.New()
h := NewUserHandler(svc, nil, nil, nil, nil, nil)
r.GET("/admin/users/:id", h.GetByID)
return r
}
func TestAdminUserGetByID_IncludeDeleted(t *testing.T) {
svc := &getByIDAdminStub{AdminService: newStubAdminService()}
router := setupGetByIDRouter(svc)
t.Run("normal path returns 404 for deleted user", func(t *testing.T) {
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/admin/users/7", nil)
router.ServeHTTP(w, req)
require.Equal(t, http.StatusNotFound, w.Code)
})
t.Run("include_deleted=true returns 200", func(t *testing.T) {
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/admin/users/7?include_deleted=true", nil)
router.ServeHTTP(w, req)
require.Equal(t, http.StatusOK, w.Code)
})
}