diff --git a/internal/api/ui/login/external_provider_handler.go b/internal/api/ui/login/external_provider_handler.go index 1f835c855f..15046d25e8 100644 --- a/internal/api/ui/login/external_provider_handler.go +++ b/internal/api/ui/login/external_provider_handler.go @@ -525,12 +525,7 @@ func (l *Login) autoLinkUser(w http.ResponseWriter, r *http.Request, authReq *do // - creation by user // - linking to existing user func (l *Login) externalUserNotExisting(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, provider *query.IDPTemplate, externalUser *domain.ExternalUser, changed bool) { - resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID() - - if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner { - resourceOwner = authReq.RequestedOrgID - } - + resourceOwner := determineResourceOwner(r.Context(), authReq) orgIAMPolicy, err := l.getOrgDomainPolicy(r, resourceOwner) if err != nil { l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, err) @@ -587,35 +582,21 @@ func (l *Login) renderExternalNotFoundOption(w http.ResponseWriter, r *http.Requ if err != nil { errID, errMessage = l.getErrorMessage(r, err) } + resourceOwner := determineResourceOwner(r.Context(), authReq) if orgIAMPolicy == nil { - resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID() - - if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner { - resourceOwner = authReq.RequestedOrgID - } - orgIAMPolicy, err = l.getOrgDomainPolicy(r, resourceOwner) if err != nil { l.renderError(w, r, authReq, err) return } - } if human == nil || idpLink == nil { - // TODO (LS): how do we get multiple and why do we use the last of them (taken as is)? linkingUser := authReq.LinkingUsers[len(authReq.LinkingUsers)-1] human, idpLink, _ = mapExternalUserToLoginUser(linkingUser, orgIAMPolicy.UserLoginMustBeDomain) } - var resourceOwner string - if authReq != nil { - resourceOwner = authReq.RequestedOrgID - } - if resourceOwner == "" { - resourceOwner = authz.GetInstance(r.Context()).DefaultOrganisationID() - } labelPolicy, err := l.getLabelPolicy(r, resourceOwner) if err != nil { l.renderError(w, r, authReq, err) @@ -718,11 +699,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http // // it is called from either the [autoCreateExternalUser] or [handleExternalNotFoundOptionCheck] func (l *Login) registerExternalUser(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, externalUser *domain.ExternalUser) { - resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID() - - if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner { - resourceOwner = authReq.RequestedOrgID - } + resourceOwner := determineResourceOwner(r.Context(), authReq) orgIamPolicy, err := l.getOrgDomainPolicy(r, resourceOwner) if err != nil { diff --git a/internal/api/ui/login/register_handler.go b/internal/api/ui/login/register_handler.go index d487903a85..89e0eec7b3 100644 --- a/internal/api/ui/login/register_handler.go +++ b/internal/api/ui/login/register_handler.go @@ -1,6 +1,7 @@ package login import ( + "context" "net/http" "golang.org/x/text/language" @@ -40,6 +41,13 @@ type registerData struct { OrgRegister bool } +func determineResourceOwner(ctx context.Context, authRequest *domain.AuthRequest) string { + if authRequest != nil && authRequest.RequestedOrgID != "" { + return authRequest.RequestedOrgID + } + return authz.GetInstance(ctx).DefaultOrganisationID() +} + func (l *Login) handleRegister(w http.ResponseWriter, r *http.Request) { data := new(registerFormData) authRequest, err := l.getAuthRequestAndParseData(r, data) @@ -47,9 +55,30 @@ func (l *Login) handleRegister(w http.ResponseWriter, r *http.Request) { l.renderError(w, r, authRequest, err) return } + if err := l.checkRegistrationAllowed(r, determineResourceOwner(r.Context(), authRequest), authRequest); err != nil { + l.renderError(w, r, authRequest, err) + return + } l.renderRegister(w, r, authRequest, data, nil) } +func (l *Login) checkRegistrationAllowed(r *http.Request, orgID string, authReq *domain.AuthRequest) error { + if authReq != nil { + if registrationAllowed(authReq) { + return nil + } + return zerrors.ThrowPreconditionFailed(nil, "VIEW-RRGRXz4kGw", "Errors.Org.LoginPolicy.RegistrationNotAllowed") + } + loginPolicy, err := l.getLoginPolicy(r, orgID) + if err != nil { + return err + } + if loginPolicy.AllowRegister && loginPolicy.AllowUsernamePassword { + return nil + } + return zerrors.ThrowPreconditionFailed(nil, "VIEW-Vq3bduAacD", "Errors.Org.LoginPolicy.RegistrationNotAllowed") +} + func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) { data := new(registerFormData) authRequest, err := l.getAuthRequestAndParseData(r, data) @@ -57,17 +86,16 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) { l.renderError(w, r, authRequest, err) return } + resourceOwner := determineResourceOwner(r.Context(), authRequest) + if err := l.checkRegistrationAllowed(r, resourceOwner, authRequest); err != nil { + l.renderError(w, r, authRequest, err) + return + } if data.Password != data.Password2 { err := zerrors.ThrowInvalidArgument(nil, "VIEW-KaGue", "Errors.User.Password.ConfirmationWrong") l.renderRegister(w, r, authRequest, data, err) return } - - resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID() - - if authRequest != nil && authRequest.RequestedOrgID != "" && authRequest.RequestedOrgID != resourceOwner { - resourceOwner = authRequest.RequestedOrgID - } // For consistency with the external authentication flow, // the setMetadata() function is provided on the pre creation hook, for now, // like for the ExternalAuthentication flow. @@ -126,15 +154,7 @@ func (l *Login) renderRegister(w http.ResponseWriter, r *http.Request, authReque formData.Language = l.renderer.ReqLang(translator, r).String() } - var resourceOwner string - if authRequest != nil { - resourceOwner = authRequest.RequestedOrgID - } - - if resourceOwner == "" { - resourceOwner = authz.GetInstance(r.Context()).DefaultOrganisationID() - } - + resourceOwner := determineResourceOwner(r.Context(), authRequest) data := registerData{ baseData: l.getBaseData(r, authRequest, translator, "RegistrationUser.Title", "RegistrationUser.Description", errID, errMessage), registerFormData: *formData,