完善 API Key 能力范围可视化和维护

This commit is contained in:
2026-06-07 19:01:32 +08:00
parent dc14866210
commit f47132a653
19 changed files with 1165 additions and 49 deletions
+78
View File
@@ -622,6 +622,45 @@ func (s *Server) listUserGroups(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, map[string]any{"items": items})
}
// listCurrentUserGroups godoc
// @Summary 获取当前用户组策略
// @Description 返回当前用户关联的用户组及策略摘要,供个人中心使用。
// @Tags workspace
// @Produce json
// @Security BearerAuth
// @Success 200 {object} UserGroupListResponse
// @Failure 401 {object} ErrorEnvelope
// @Failure 500 {object} ErrorEnvelope
// @Router /api/workspace/user-groups [get]
func (s *Server) listCurrentUserGroups(w http.ResponseWriter, r *http.Request) {
user, _ := auth.UserFromContext(r.Context())
if user == nil {
writeError(w, http.StatusUnauthorized, "unauthorized")
return
}
groupIDs := compactAuthStrings(user.UserGroupID)
groupKeys := compactAuthStrings(user.UserGroupKey)
groupKeys = append(groupKeys, compactAuthStrings(user.UserGroupKeys...)...)
items, err := s.store.ListUserGroupsBySubject(r.Context(), groupIDs, groupKeys)
if err != nil {
s.logger.Error("list current user groups failed", "error", err)
writeError(w, http.StatusInternalServerError, "list current user groups failed")
return
}
writeJSON(w, http.StatusOK, map[string]any{"items": items})
}
func compactAuthStrings(values ...string) []string {
out := make([]string, 0, len(values))
for _, value := range values {
value = strings.TrimSpace(value)
if value != "" {
out = append(out, value)
}
}
return out
}
// listAPIKeys godoc
// @Summary 列出 API Key
// @Description 返回当前用户创建的 API Key 元数据,secret 只在创建时返回。
@@ -702,6 +741,45 @@ func (s *Server) createAPIKey(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusCreated, created)
}
// updateAPIKeyScopes godoc
// @Summary 更新 API Key 能力范围
// @Description 更新当前用户拥有的 API Key scopes,至少需要保留一个能力范围。
// @Tags api-keys
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param apiKeyID path string true "API Key ID"
// @Param input body store.UpdateAPIKeyScopesInput true "API Key scope 更新请求"
// @Success 200 {object} store.APIKey
// @Failure 400 {object} ErrorEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Failure 500 {object} ErrorEnvelope
// @Router /api/v1/api-keys/{apiKeyID}/scopes [patch]
func (s *Server) updateAPIKeyScopes(w http.ResponseWriter, r *http.Request) {
user, _ := auth.UserFromContext(r.Context())
var input store.UpdateAPIKeyScopesInput
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
writeError(w, http.StatusBadRequest, "invalid json body")
return
}
item, err := s.store.UpdateAPIKeyScopes(r.Context(), r.PathValue("apiKeyID"), input, user)
if err == nil {
writeJSON(w, http.StatusOK, item)
return
}
if errors.Is(err, store.ErrLocalUserRequired) || errors.Is(err, store.ErrInvalidAPIKeyScopes) {
writeError(w, http.StatusBadRequest, err.Error())
return
}
if store.IsNotFound(err) {
writeError(w, http.StatusNotFound, "api key not found")
return
}
s.logger.Error("update api key scopes failed", "error", err)
writeError(w, http.StatusInternalServerError, "update api key scopes failed")
}
// disableAPIKey godoc
// @Summary 禁用 API Key
// @Description 禁用当前用户拥有的 API Key,保留记录但不再允许调用。