123 lines
3.4 KiB
Go

package externaladmin
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"
"hyapp-admin-server/internal/appctx"
"hyapp-admin-server/internal/modules/shared"
"hyapp-admin-server/internal/response"
"github.com/gin-gonic/gin"
)
// optionalPermissionSelection preserves the JSON distinction required by account
// creation: omitted keeps the legacy full snapshot, while an explicit [] creates a
// valid account with no business permissions. JSON null is rejected as ambiguous.
type optionalPermissionSelection struct {
Value []string
Set bool
}
func (selection *optionalPermissionSelection) UnmarshalJSON(body []byte) error {
selection.Set = true
body = bytes.TrimSpace(body)
if bytes.Equal(body, []byte("null")) {
return errors.New("permissions must be an array")
}
var permissions []string
if err := json.Unmarshal(body, &permissions); err != nil {
return err
}
selection.Value = permissions
return nil
}
type updatePermissionsRequest struct {
Permissions optionalPermissionSelection `json:"permissions"`
ExpectedRevision uint64 `json:"expectedRevision"`
}
func (h *Handler) ListPermissionCatalog(c *gin.Context) {
items := PermissionCatalog()
response.OK(c, gin.H{"items": items, "total": len(items)})
}
func (h *Handler) GetAccountPermissions(c *gin.Context) {
id, ok := parseUint64Param(c, "id")
if !ok {
return
}
permissions, err := h.service.GetAccountPermissions(c.Request.Context(), appctx.FromContext(c.Request.Context()), id)
if errors.Is(err, ErrAccountNotFound) {
response.NotFound(c, "外管用户不存在")
return
}
if errors.Is(err, ErrInvalidInput) {
response.BadRequest(c, "外管用户参数不正确")
return
}
if err != nil {
response.ServerError(c, "获取外管用户权限失败")
return
}
response.OK(c, permissions)
}
func (h *Handler) UpdateAccountPermissions(c *gin.Context) {
id, ok := parseUint64Param(c, "id")
if !ok {
return
}
var request updatePermissionsRequest
if err := c.ShouldBindJSON(&request); err != nil || !request.Permissions.Set || request.ExpectedRevision == 0 {
response.BadRequest(c, "权限参数不正确")
return
}
result, err := h.service.UpdateAccountPermissions(c.Request.Context(), appctx.FromContext(c.Request.Context()), id, UpdatePermissionsInput{
Permissions: request.Permissions.Value, ExpectedRevision: request.ExpectedRevision,
})
if errors.Is(err, ErrInvalidPermissions) {
response.BadRequest(c, permissionValidationMessage(err))
return
}
if errors.Is(err, ErrInvalidInput) {
response.BadRequest(c, "外管用户参数不正确")
return
}
if errors.Is(err, ErrAccountNotFound) {
response.NotFound(c, "外管用户不存在")
return
}
if errors.Is(err, ErrPermissionConflict) {
response.Conflict(c, "外管用户权限已被其他管理员修改,请刷新后重试")
return
}
if err != nil {
response.ServerError(c, "更新外管用户权限失败")
return
}
shared.OperationLogWithResourceID(
c,
h.audit,
"update-external-admin-user-permissions",
"external_admin_accounts",
strconv.FormatUint(id, 10),
"success",
fmt.Sprintf(
"app_code=%s previous_permissions=%s permissions=%s revision=%d changed=%t sessions_revoked=%t",
result.Account.AppCode,
strings.Join(result.PreviousPermissions, ","),
strings.Join(result.Account.Permissions, ","),
result.Account.PermissionRevision,
result.Changed,
result.SessionsRevoked,
),
)
response.OK(c, result.Account)
}