Add roles CRUD backed by system_roles tables, session list/revoke APIs, capabilities fallback for memory mode, and route all admin checks through AuthorizationService instead of hardcoded role-admin checks. Co-authored-by: Cursor <cursoragent@cursor.com>
72 lines
2.0 KiB
Go
72 lines
2.0 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"chat-agent-system/internal/auth"
|
|
)
|
|
|
|
type principalContextKey struct{}
|
|
|
|
// withPrincipal 将已认证用户写入请求 context。
|
|
func withPrincipal(ctx context.Context, user *auth.UserAccount) context.Context {
|
|
return context.WithValue(ctx, principalContextKey{}, user)
|
|
}
|
|
|
|
// principalFromContext 从 context 读取当前用户;未认证返回 nil。
|
|
func principalFromContext(ctx context.Context) *auth.UserAccount {
|
|
if ctx == nil {
|
|
return nil
|
|
}
|
|
user, _ := ctx.Value(principalContextKey{}).(*auth.UserAccount)
|
|
return user
|
|
}
|
|
|
|
// principalFromRequest 从 HTTP 请求 context 读取当前用户。
|
|
func (s *Server) principalFromRequest(r *http.Request) *auth.UserAccount {
|
|
return principalFromContext(r.Context())
|
|
}
|
|
|
|
// requirePrincipal 要求已认证用户,否则写入 401。
|
|
func (s *Server) requirePrincipal(w http.ResponseWriter, r *http.Request) (*auth.UserAccount, bool) {
|
|
user := s.principalFromRequest(r)
|
|
if user == nil {
|
|
writeJSONResponse(w, http.StatusUnauthorized, map[string]string{
|
|
"error_code": "ERR_UNAUTHENTICATED",
|
|
"message": "请先登录",
|
|
})
|
|
return nil, false
|
|
}
|
|
return user, true
|
|
}
|
|
|
|
// requireAdmin 要求系统管理员角色。
|
|
func (s *Server) requireAdmin(w http.ResponseWriter, r *http.Request) (*auth.UserAccount, bool) {
|
|
return s.requireSystemAdmin(w, r)
|
|
}
|
|
|
|
// requireSystemAdmin 通过 AuthorizationService 判定系统管理员。
|
|
func (s *Server) requireSystemAdmin(w http.ResponseWriter, r *http.Request) (*auth.UserAccount, bool) {
|
|
user, ok := s.requirePrincipal(w, r)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
admin, err := s.authzSvc.IsSystemAdmin(r.Context(), user.ID, user.RoleID)
|
|
if err != nil {
|
|
writeJSONResponse(w, http.StatusInternalServerError, map[string]string{
|
|
"error_code": "ERR_AUTHZ",
|
|
"message": "权限判定失败",
|
|
})
|
|
return nil, false
|
|
}
|
|
if !admin {
|
|
writeJSONResponse(w, http.StatusForbidden, map[string]string{
|
|
"error_code": "ERR_FORBIDDEN",
|
|
"message": "需要管理员权限",
|
|
})
|
|
return nil, false
|
|
}
|
|
return user, true
|
|
}
|