Files
user-system/internal/service/auth_capabilities.go
long-agent 2a18a6fb47 fix(n+1): 批量查询替代循环单查
- IsAdminBootstrapRequired: userRepo.GetByID 循环 → GetByIDs 批量
- AssignRoles: roleRepo.GetByID 循环 → GetByIDs 批量
- 在 userRepositoryInterface 补充 GetByIDs 方法签名
2026-05-08 08:05:26 +08:00

91 lines
2.5 KiB
Go

package service
import (
"context"
"errors"
"log"
"github.com/user-management-system/internal/auth"
"github.com/user-management-system/internal/domain"
"gorm.io/gorm"
)
const adminRoleCode = "admin"
type AuthCapabilities struct {
Password bool `json:"password"`
EmailActivation bool `json:"email_activation"`
EmailCode bool `json:"email_code"`
SMSCode bool `json:"sms_code"`
PasswordReset bool `json:"password_reset"`
AdminBootstrapRequired bool `json:"admin_bootstrap_required"`
OAuthProviders []auth.OAuthProviderInfo `json:"oauth_providers"`
}
func (s *AuthService) SupportsEmailActivation() bool {
return s != nil && s.emailActivationSvc != nil
}
func (s *AuthService) SupportsEmailCodeLogin() bool {
return s != nil && s.emailCodeSvc != nil
}
func (s *AuthService) SupportsSMSCodeLogin() bool {
return s != nil && s.smsCodeSvc != nil
}
func (s *AuthService) GetAuthCapabilities(ctx context.Context) AuthCapabilities {
if ctx == nil {
ctx = context.Background()
}
return AuthCapabilities{
Password: true,
EmailActivation: s.SupportsEmailActivation(),
EmailCode: s.SupportsEmailCodeLogin(),
SMSCode: s.SupportsSMSCodeLogin(),
AdminBootstrapRequired: s.IsAdminBootstrapRequired(ctx),
OAuthProviders: s.GetEnabledOAuthProviders(),
}
}
func (s *AuthService) IsAdminBootstrapRequired(ctx context.Context) bool {
if s == nil || s.userRepo == nil || s.roleRepo == nil || s.userRoleRepo == nil {
return false
}
if ctx == nil {
ctx = context.Background()
}
adminRole, err := s.roleRepo.GetByCode(ctx, adminRoleCode)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return true
}
log.Printf("auth: resolve auth capabilities failed while loading admin role: %v", err)
return false
}
userIDs, err := s.userRoleRepo.GetUserIDByRoleID(ctx, adminRole.ID)
if err != nil {
log.Printf("auth: resolve auth capabilities failed while loading admin users: role_id=%d err=%v", adminRole.ID, err)
return false
}
if len(userIDs) == 0 {
return true
}
users, err := s.userRepo.GetByIDs(ctx, userIDs)
if err != nil {
log.Printf("auth: resolve auth capabilities failed while loading admin users: err=%v", err)
return false
}
for _, user := range users {
if user.Status == domain.UserStatusActive {
return false
}
}
return true
}