template-monorepo/internal/logic/auth/federated_callback_helper.go

85 lines
2.2 KiB
Go

package auth
import (
"context"
"strings"
"gateway/internal/library/zitadel"
authmetaenum "gateway/internal/model/auth/domain/enum"
dommember "gateway/internal/model/member/domain/usecase"
"gateway/internal/svc"
)
func federatedEmailAllowed(claims *zitadel.IDTokenClaims, provider string, trustSocial bool) error {
if claims == nil {
return errb.SvcThirdParty("empty id token claims")
}
if claims.EmailVerified || trustSocial {
return nil
}
if strings.EqualFold(strings.TrimSpace(provider), "ldap") {
return nil
}
return errb.AuthForbidden("social email is not verified")
}
// resolveMemberForFederatedLogin loads an existing member or provisions on first LDAP login.
func resolveMemberForFederatedLogin(
ctx context.Context,
sc *svc.ServiceContext,
tenantID string,
claims *zitadel.IDTokenClaims,
provider string,
) (*dommember.MemberDTO, error) {
if sc.MemberProfile == nil {
return nil, errb.SysNotImplemented("member profile not configured")
}
member, err := sc.MemberProfile.GetByZitadelUserID(ctx, tenantID, claims.Sub)
if err == nil {
if err := ensureLoginEligible(member.Status); err != nil {
return nil, err
}
return member, nil
}
if !isMemberNotFound(err) {
return nil, err
}
provider = strings.ToLower(strings.TrimSpace(provider))
if provider == "google" {
return nil, errb.ResNotFound("account not found, please register first").WithCause(err)
}
if sc.MemberProvisioning == nil {
return nil, err
}
switch provider {
case "ldap":
return sc.MemberProvisioning.EnsureFromLDAP(ctx, &dommember.EnsureFromLDAPRequest{
TenantID: tenantID,
ZitadelSub: claims.Sub,
ExternalID: claims.Sub,
Email: claims.Email,
DisplayName: claims.Name,
})
default:
return sc.MemberProvisioning.EnsureFromOIDC(ctx, &dommember.EnsureFromOIDCRequest{
TenantID: tenantID,
ZitadelSub: claims.Sub,
Email: claims.Email,
EmailVerified: claims.EmailVerified,
DisplayName: claims.Name,
Locale: claims.Locale,
})
}
}
func registrationChannelForProvider(provider string) authmetaenum.RegistrationChannel {
switch strings.ToLower(strings.TrimSpace(provider)) {
case "ldap":
return authmetaenum.RegistrationChannelLDAP
default:
return authmetaenum.RegistrationChannelGoogle
}
}