From 456d32dd0d13670f5649a3b59876318f723ad66e Mon Sep 17 00:00:00 2001 From: Fabi <38692350+fgerschwiler@users.noreply.github.com> Date: Tue, 18 Jan 2022 08:46:31 +0100 Subject: [PATCH] fix: show registration overview (#3002) * fix: show registration overview * fix: render error page to avoid possible loop --- .../login/handler/external_login_handler.go | 103 ++++++++++++++++-- internal/ui/login/handler/jwt_handler.go | 2 +- internal/ui/login/handler/renderer.go | 2 +- internal/ui/login/static/i18n/de.yaml | 2 +- internal/ui/login/static/i18n/en.yaml | 2 +- internal/ui/login/static/i18n/it.yaml | 2 +- .../templates/external_not_found_option.html | 54 +++++++++ 7 files changed, 152 insertions(+), 15 deletions(-) diff --git a/internal/ui/login/handler/external_login_handler.go b/internal/ui/login/handler/external_login_handler.go index eadbabf272..0c25992e6d 100644 --- a/internal/ui/login/handler/external_login_handler.go +++ b/internal/ui/login/handler/external_login_handler.go @@ -35,6 +35,7 @@ type externalIDPCallbackData struct { } type externalNotFoundOptionFormData struct { + externalRegisterFormData Link bool `schema:"linkbutton"` AutoRegister bool `schema:"autoregisterbutton"` ResetLinking bool `schema:"resetlinking"` @@ -43,6 +44,16 @@ type externalNotFoundOptionFormData struct { type externalNotFoundOptionData struct { baseData + externalNotFoundOptionFormData + ExternalIDPID string + ExternalIDPUserID string + ExternalIDPUserDisplayName string + ShowUsername bool + OrgRegister bool + ExternalEmail string + ExternalEmailVerified bool + ExternalPhone string + ExternalPhoneVerified bool } func (l *Login) handleExternalLoginStep(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, selectedIDPConfigID string) { @@ -186,18 +197,38 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R l.renderError(w, r, authReq, err) return } + err = l.authRepo.CheckExternalUserLogin(r.Context(), authReq.ID, userAgentID, externalUser, domain.BrowserInfoFromRequest(r)) if err != nil { if errors.IsNotFound(err) { err = nil } + iam, err := l.authRepo.GetIAM(r.Context()) + if err != nil { + l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) + return + } + + resourceOwner := iam.GlobalOrgID + + if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != iam.GlobalOrgID { + resourceOwner = authReq.RequestedOrgID + } + + orgIAMPolicy, err := l.getOrgIamPolicy(r, resourceOwner) + if err != nil { + l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) + return + } + + human, idpLinking, _ := l.mapExternalUserToLoginUser(orgIAMPolicy, externalUser, idpConfig) if !idpConfig.AutoRegister { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, iam, orgIAMPolicy, human, idpLinking, err) return } authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, userAgentID) if err != nil { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, iam, orgIAMPolicy, human, idpLinking, err) return } l.handleAutoRegister(w, r, authReq) @@ -217,13 +248,65 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R l.renderNextStep(w, r, authReq) } -func (l *Login) renderExternalNotFoundOption(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) { +func (l *Login) renderExternalNotFoundOption(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, iam *iam_model.IAM, orgIAMPolicy *query.OrgIAMPolicy, human *domain.Human, externalIDP *domain.UserIDPLink, err error) { var errID, errMessage string if err != nil { errID, errMessage = l.getErrorMessage(r, err) } + if orgIAMPolicy == nil { + iam, err = l.authRepo.GetIAM(r.Context()) + if err != nil { + l.renderError(w, r, authReq, err) + return + } + resourceOwner := iam.GlobalOrgID + + if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != iam.GlobalOrgID { + resourceOwner = authReq.RequestedOrgID + } + + orgIAMPolicy, err = l.getOrgIamPolicy(r, resourceOwner) + if err != nil { + l.renderError(w, r, authReq, err) + return + } + + } + + if human == nil || externalIDP == nil { + idpConfig, err := l.authRepo.GetIDPConfigByID(r.Context(), authReq.SelectedIDPConfigID) + if err != nil { + l.renderError(w, r, authReq, err) + return + } + linkingUser := authReq.LinkingUsers[len(authReq.LinkingUsers)-1] + human, externalIDP, _ = l.mapExternalUserToLoginUser(orgIAMPolicy, linkingUser, idpConfig) + } + data := externalNotFoundOptionData{ baseData: l.getBaseData(r, authReq, "ExternalNotFoundOption", errID, errMessage), + externalNotFoundOptionFormData: externalNotFoundOptionFormData{ + externalRegisterFormData: externalRegisterFormData{ + Email: human.EmailAddress, + Username: human.Username, + Firstname: human.FirstName, + Lastname: human.LastName, + Nickname: human.NickName, + Language: human.PreferredLanguage.String(), + }, + }, + ExternalIDPID: externalIDP.IDPConfigID, + ExternalIDPUserID: externalIDP.ExternalUserID, + ExternalIDPUserDisplayName: externalIDP.DisplayName, + ExternalEmail: human.EmailAddress, + ExternalEmailVerified: human.IsEmailVerified, + ShowUsername: orgIAMPolicy.UserLoginMustBeDomain, + OrgRegister: orgIAMPolicy.UserLoginMustBeDomain, + } + if human.Phone != nil { + data.Phone = human.PhoneNumber + data.ExternalPhone = human.PhoneNumber + data.ExternalPhoneVerified = human.IsPhoneVerified } translator := l.getTranslator(authReq) l.renderer.RenderTemplate(w, r, translator, l.renderer.Templates[tmplExternalNotFoundOption], data, nil) @@ -233,7 +316,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http data := new(externalNotFoundOptionFormData) authReq, err := l.getAuthRequestAndParseData(r, data) if err != nil { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) return } if data.Link { @@ -243,7 +326,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context()) err = l.authRepo.ResetLinkingUsers(r.Context(), authReq.ID, userAgentID) if err != nil { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) } l.handleLogin(w, r) return @@ -254,7 +337,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest) { iam, err := l.authRepo.GetIAM(r.Context()) if err != nil { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) return } @@ -268,13 +351,13 @@ func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authR orgIamPolicy, err := l.getOrgIamPolicy(r, resourceOwner) if err != nil { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) return } idpConfig, err := l.authRepo.GetIDPConfigByID(r.Context(), authReq.SelectedIDPConfigID) if err != nil { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, iam, orgIamPolicy, nil, nil, err) return } @@ -287,12 +370,12 @@ func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authR user, externalIDP, metadata := l.mapExternalUserToLoginUser(orgIamPolicy, linkingUser, idpConfig) user, metadata, err = l.customExternalUserToLoginUserMapping(user, nil, authReq, idpConfig, metadata, resourceOwner) if err != nil { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, iam, orgIamPolicy, nil, nil, err) return } err = l.authRepo.AutoRegisterExternalUser(setContext(r.Context(), resourceOwner), user, externalIDP, memberRoles, authReq.ID, userAgentID, resourceOwner, metadata, domain.BrowserInfoFromRequest(r)) if err != nil { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, iam, orgIamPolicy, user, externalIDP, err) return } authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID) diff --git a/internal/ui/login/handler/jwt_handler.go b/internal/ui/login/handler/jwt_handler.go index 8e57e71354..3e7ef78551 100644 --- a/internal/ui/login/handler/jwt_handler.go +++ b/internal/ui/login/handler/jwt_handler.go @@ -112,7 +112,7 @@ func (l *Login) jwtExtractionUserNotFound(w http.ResponseWriter, r *http.Request err = nil } if !idpConfig.AutoRegister { - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) return } authReq, err = l.authRepo.AuthRequestByID(r.Context(), authReq.ID, authReq.AgentID) diff --git a/internal/ui/login/handler/renderer.go b/internal/ui/login/handler/renderer.go index b8b7cbddf2..2e7d01d1e4 100644 --- a/internal/ui/login/handler/renderer.go +++ b/internal/ui/login/handler/renderer.go @@ -294,7 +294,7 @@ func (l *Login) chooseNextStep(w http.ResponseWriter, r *http.Request, authReq * case *domain.LinkUsersStep: l.linkUsers(w, r, authReq, err) case *domain.ExternalNotFoundOptionStep: - l.renderExternalNotFoundOption(w, r, authReq, err) + l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) case *domain.ExternalLoginStep: l.handleExternalLoginStep(w, r, authReq, step.SelectedIDPConfigID) case *domain.GrantRequiredStep: diff --git a/internal/ui/login/static/i18n/de.yaml b/internal/ui/login/static/i18n/de.yaml index fa099d191c..98f13e307a 100644 --- a/internal/ui/login/static/i18n/de.yaml +++ b/internal/ui/login/static/i18n/de.yaml @@ -280,7 +280,7 @@ ExternalNotFoundOption: Title: Externer Benutzer Description: Externer Benutzer konnte nicht gefunden werden. Willst du deinen Benutzer mit einem bestehenden verlinken oder diesen als neuen Benutzer registrieren. LinkButtonText: Verlinken - AutoRegisterButtonText: Automatisches registrieren + AutoRegisterButtonText: registrieren TosAndPrivacyLabel: Allgemeine Geschäftsbedingungen und Datenschutz TosConfirm: Ich akzeptiere die TosLinkText: AGBs diff --git a/internal/ui/login/static/i18n/en.yaml b/internal/ui/login/static/i18n/en.yaml index 96c62c0b8c..2719669df6 100644 --- a/internal/ui/login/static/i18n/en.yaml +++ b/internal/ui/login/static/i18n/en.yaml @@ -281,7 +281,7 @@ ExternalNotFoundOption: Title: External User Description: External user not found. Do you want to link your user or auto register a new one. LinkButtonText: Link - AutoRegisterButtonText: Auto register + AutoRegisterButtonText: register TosAndPrivacyLabel: Terms and conditions TosConfirm: I accept the TosLinkText: TOS diff --git a/internal/ui/login/static/i18n/it.yaml b/internal/ui/login/static/i18n/it.yaml index 3f13e28c60..fb4c9a04b2 100644 --- a/internal/ui/login/static/i18n/it.yaml +++ b/internal/ui/login/static/i18n/it.yaml @@ -281,7 +281,7 @@ ExternalNotFoundOption: Title: Utente esterno Description: Utente esterno non trovato. Vuoi collegare il tuo utente o registrarne uno nuovo automaticamente. LinkButtonText: Link - AutoRegisterButtonText: Registra automaticamente + AutoRegisterButtonText: Registra TosAndPrivacyLabel: Termini di servizio TosConfirm: Accetto i TosLinkText: Termini di servizio diff --git a/internal/ui/login/static/templates/external_not_found_option.html b/internal/ui/login/static/templates/external_not_found_option.html index 16910d3a0a..a76c33da31 100644 --- a/internal/ui/login/static/templates/external_not_found_option.html +++ b/internal/ui/login/static/templates/external_not_found_option.html @@ -12,8 +12,62 @@ {{ .CSRF }} + + + + + + +
+
+
+ + +
+
+ + +
+
+ +
+ +
+ + {{if .DisplayLoginNameSuffix}} + @{{.PrimaryDomain}} + {{end}} +
+
+ +
+ + +
+ +
+ + +
+ +
+
+ + +
+
+ {{ if or .TOSLink .PrivacyLink }}