| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- package service
- import (
- "context"
- infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
- "github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
- )
- type userManagementActorKey struct{}
- // WithUserManagementActor carries the server-authenticated actor to the final
- // repository transaction. It is never populated from request JSON.
- func WithUserManagementActor(ctx context.Context, actorID int64) context.Context {
- return context.WithValue(ctx, userManagementActorKey{}, actorID)
- }
- func UserManagementActor(ctx context.Context) (int64, bool) {
- id, ok := ctx.Value(userManagementActorKey{}).(int64)
- return id, ok
- }
- func (s *adminServiceImpl) authorizeManagedUserResource(ctx context.Context, targetID int64) error {
- actorID, managed := UserManagementActor(ctx)
- if !managed {
- return nil
- } // Non-HTTP internal callers retain their own authority.
- if s.userRepo == nil || actorID <= 0 {
- return infraerrors.Forbidden("USER_RESOURCE_FORBIDDEN", "User resource authorization unavailable")
- }
- actor, err := s.userRepo.GetByID(ctx, actorID)
- if err != nil {
- return err
- }
- target, err := s.userRepo.GetByID(ctx, targetID)
- if err != nil {
- return err
- }
- if !actor.IsActive() || !actor.IsAdmin() || (target.IsAdmin() && !actor.IsSuperAdmin()) {
- return infraerrors.Forbidden("SUPER_ADMIN_REQUIRED", "只有超级管理员可以管理管理员账号的密钥和订阅")
- }
- return nil
- }
- // Only a live super administrator may grant roles or change another
- // administrator. Actor identity comes from authenticated server context.
- func (s *adminServiceImpl) authorizeUserRoleChange(ctx context.Context, actorID int64, target *User, requestedRole string) error {
- roleChange := target == nil && IsAdminRole(requestedRole) || target != nil && requestedRole != "" && requestedRole != target.Role
- protectedTarget := target != nil && target.IsAdmin()
- if !roleChange && !protectedTarget {
- return nil
- }
- if actorID <= 0 {
- return infraerrors.Forbidden("SUPER_ADMIN_REQUIRED", "只有超级管理员可以修改角色或管理管理员账号")
- }
- actor, err := s.userRepo.GetByID(ctx, actorID)
- if err != nil {
- return err
- }
- if !actor.IsActive() || !actor.IsSuperAdmin() {
- return infraerrors.Forbidden("SUPER_ADMIN_REQUIRED", "只有超级管理员可以修改角色或管理管理员账号")
- }
- if target != nil && target.ID == actorID && requestedRole != "" && requestedRole != actor.Role {
- return infraerrors.Forbidden("SELF_DEMOTION_FORBIDDEN", "不能修改自己的管理员角色")
- }
- return nil
- }
- func (s *adminServiceImpl) ensureNotLastSuperAdmin(ctx context.Context) error {
- noSubs := false
- _, result, err := s.userRepo.ListWithFilters(ctx, pagination.PaginationParams{Page: 1, PageSize: 1}, UserListFilters{Role: RoleSuperAdmin, IncludeSubscriptions: &noSubs})
- if err != nil {
- return err
- }
- if result == nil || result.Total <= 1 {
- return infraerrors.Forbidden("LAST_SUPER_ADMIN", "不能降级最后一个超级管理员")
- }
- return nil
- }
|