fix: add allowRegister check for register handling in login (#8782)

# Which Problems Are Solved

There is currently the possibility that you can jump to the register
path, even if register is disallowed through the settings.

# How the Problems Are Solved

Check before handling the HTTP requests if register is allowed.

# Additional Changes

Function to determine the resourceowner for all register related
functionality in the login.

# Additional Context

closes #8123
This commit is contained in:
Stefan Benz 2024-10-16 15:09:32 +02:00 committed by GitHub
parent 4ebc23aa1f
commit c21e171519
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 41 deletions

View File

@ -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 {

View File

@ -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,