feat(ECR-010): Ops-E 系统运营;修复登出解绑;P2 Complete
落地管理员 RBAC/封禁/推送任务 stub,logout 解绑 device 并统一各页 ensureAccount,同时收口 P2 生日生成与状态文档。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -38,6 +38,15 @@ func DeviceAuth(pool *pgxpool.Pool) gin.HandlerFunc {
|
||||
WHERE token=$1 AND revoked_at IS NULL AND expires_at > now()`, tok,
|
||||
).Scan(&uid)
|
||||
if err == nil {
|
||||
if banned, berr := userIsBanned(c.Request.Context(), pool, uid); berr != nil {
|
||||
response.Fail(c, http.StatusInternalServerError, 50001, "identity unavailable")
|
||||
c.Abort()
|
||||
return
|
||||
} else if banned {
|
||||
response.Fail(c, http.StatusForbidden, 40310, "账号已封禁")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
_, _ = pool.Exec(c.Request.Context(), `
|
||||
INSERT INTO device_identities(device_key, user_id)
|
||||
VALUES ($1,$2)
|
||||
@@ -56,6 +65,15 @@ func DeviceAuth(pool *pgxpool.Pool) gin.HandlerFunc {
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
if banned, berr := userIsBanned(c.Request.Context(), pool, userID); berr != nil {
|
||||
response.Fail(c, http.StatusInternalServerError, 50001, "identity unavailable")
|
||||
c.Abort()
|
||||
return
|
||||
} else if banned {
|
||||
response.Fail(c, http.StatusForbidden, 40310, "账号已封禁")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Set(string(UserIDKey), userID.String())
|
||||
c.Header(DeviceKeyHeader, key)
|
||||
c.Next()
|
||||
@@ -149,3 +167,16 @@ func newDeviceKey() string {
|
||||
_, _ = rand.Read(b)
|
||||
return "dev_" + hex.EncodeToString(b)
|
||||
}
|
||||
|
||||
func userIsBanned(ctx context.Context, pool *pgxpool.Pool, userID uuid.UUID) (bool, error) {
|
||||
var status string
|
||||
err := pool.QueryRow(ctx, `
|
||||
SELECT status FROM users WHERE id=$1 AND deleted_at IS NULL`, userID).Scan(&status)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return status == "banned", nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user