100 lines
2.7 KiB
Go
100 lines
2.7 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
|
|
}
|
|
|
|
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
|
|
}
|