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 } hadUnexpectedLookupError := false for _, userID := range userIDs { user, err := s.userRepo.GetByID(ctx, userID) if err != nil { if isUserNotFoundError(err) { continue } hadUnexpectedLookupError = true log.Printf("auth: resolve auth capabilities failed while loading admin user: user_id=%d err=%v", userID, err) continue } if user != nil && user.Status == domain.UserStatusActive { return false } } if hadUnexpectedLookupError { return false } return true }