mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 23:37:23 +00:00
fix: idps (#777)
* fix: update client secret, skip passwordsteps only if login not if linking * fix: global policy for register * fix: scope handling * fix: back after error * fix: change org id scope to primary domain * fix: check if primarydomain empty * fix: local sh * fix: disable buttons on org login policy
This commit is contained in:
parent
3e1204524e
commit
83b0ac1fdb
@ -2,18 +2,19 @@
|
||||
[timestamp]="idpResult?.viewTimestamp" [selection]="selection">
|
||||
<ng-template appHasRole [appHasRole]="['iam.write']" actions>
|
||||
<button (click)="deactivateSelectedIdps()" matTooltip="{{'IDP.DEACTIVATE' | translate}}" class="icon-button"
|
||||
mat-icon-button *ngIf="selection.hasValue()" [disabled]="disabled">
|
||||
mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT" [disabled]="disabled">
|
||||
<mat-icon svgIcon="mdi_account_cancel"></mat-icon>
|
||||
</button>
|
||||
<button (click)="reactivateSelectedIdps()" matTooltip="{{'IDP.ACTIVATE' | translate}}" class="icon-button"
|
||||
mat-icon-button *ngIf="selection.hasValue()" [disabled]="disabled">
|
||||
mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT" [disabled]="disabled">
|
||||
<mat-icon svgIcon="mdi_account_check_outline"></mat-icon>
|
||||
</button>
|
||||
<button color="warn" (click)="removeSelectedIdps()" matTooltip="{{'IDP.DELETE' | translate}}"
|
||||
class="icon-button" mat-icon-button *ngIf="selection.hasValue()" [disabled]="disabled">
|
||||
class="icon-button" mat-icon-button *ngIf="selection.hasValue() && serviceType!=PolicyComponentServiceType.MGMT" [disabled]="disabled">
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
<a class="add-button" [routerLink]="createRouterLink" color="primary" mat-raised-button [disabled]="disabled">
|
||||
<a class="add-button" [routerLink]="createRouterLink" color="primary" mat-raised-button [disabled]="disabled"
|
||||
*ngIf="serviceType!=PolicyComponentServiceType.MGMT">
|
||||
<mat-icon class="icon">add</mat-icon>{{ 'ACTIONS.NEW' | translate }}
|
||||
</a>
|
||||
</ng-template>
|
||||
|
@ -1,10 +1,10 @@
|
||||
<app-detail-layout [backRouterLink]="backroutes" [title]="'ORG.POLICY.LOGIN_POLICY.TITLECREATE' | translate"
|
||||
[description]="'ORG.POLICY.LOGIN_POLICY.DESCRIPTIONCREATE' | translate">
|
||||
<ng-container *ngIf="(['policy.delete'] | hasRole | async) && serviceType == PolicyComponentServiceType.MGMT">
|
||||
<button matTooltip="{{'ORG.POLICY.DELETE' | translate}}" color="warn" (click)="deletePolicy()"
|
||||
<!--<button matTooltip="{{'ORG.POLICY.DELETE' | translate}}" color="warn" (click)="deletePolicy()"
|
||||
mat-stroked-button>
|
||||
{{'ORG.POLICY.DELETE' | translate}}
|
||||
</button>
|
||||
</button>-->
|
||||
</ng-container>
|
||||
|
||||
<div class="content" *ngIf="loginData">
|
||||
@ -12,19 +12,20 @@
|
||||
<span class="left-desc">{{'ORG.POLICY.DATA.ALLOWUSERNAMEPASSWORD' | translate}}</span>
|
||||
<span class="fill-space"></span>
|
||||
<mat-slide-toggle color="primary" name="hasNumber" ngDefaultControl
|
||||
[(ngModel)]="loginData.allowUsernamePassword">
|
||||
[(ngModel)]="loginData.allowUsernamePassword" [disabled]="serviceType==PolicyComponentServiceType.MGMT">
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="left-desc">{{'ORG.POLICY.DATA.ALLOWREGISTER' | translate}}</span>
|
||||
<span class="fill-space"></span>
|
||||
<mat-slide-toggle color="primary" name="hasNumber" ngDefaultControl [(ngModel)]="loginData.allowRegister">
|
||||
<mat-slide-toggle color="primary" name="hasNumber" ngDefaultControl [(ngModel)]="loginData.allowRegister"
|
||||
[disabled]="serviceType==PolicyComponentServiceType.MGMT">
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="left-desc">{{'ORG.POLICY.DATA.ALLOWEXTERNALIDP' | translate}}</span>
|
||||
<span class="fill-space"></span>
|
||||
<mat-slide-toggle color="primary" name="hasNumber" ngDefaultControl
|
||||
<mat-slide-toggle color="primary" name="hasNumber" ngDefaultControl [disabled]="serviceType==PolicyComponentServiceType.MGMT"
|
||||
[(ngModel)]="loginData.allowExternalIdp">
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
@ -34,18 +35,18 @@
|
||||
|
||||
<div class="idps">
|
||||
<div class="idp" *ngFor="let idp of idps">
|
||||
<mat-icon (click)="removeIdp(idp)" class="rm">remove_circle</mat-icon>
|
||||
<mat-icon *ngIf="serviceType!=PolicyComponentServiceType.MGMT" (click)="removeIdp(idp)" class="rm">remove_circle</mat-icon>
|
||||
<span>{{idp.name}}</span>
|
||||
<span class="meta">{{ 'IDP.TYPE' | translate }}: {{ 'IDP.TYPES.'+idp.type | translate }}</span>
|
||||
<span class="meta">{{ 'IDP.ID' | translate }}: {{idp.idpConfigId}}</span>
|
||||
</div>
|
||||
<div class="new-idp" (click)="openDialog()">
|
||||
<div *ngIf="serviceType!=PolicyComponentServiceType.MGMT" class="new-idp" (click)="openDialog()">
|
||||
<mat-icon>add</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-container">
|
||||
<button (click)="savePolicy()" color="primary" type="submit"
|
||||
<button (click)="savePolicy()" color="primary" type="submit" [disabled]="serviceType==PolicyComponentServiceType.MGMT"
|
||||
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||
</div>
|
||||
|
||||
|
@ -23,4 +23,6 @@ type AuthRequestRepository interface {
|
||||
VerifyMfaOTP(ctx context.Context, agentID, authRequestID, code, userAgentID string, info *model.BrowserInfo) error
|
||||
LinkExternalUsers(ctx context.Context, authReqID, userAgentID string) error
|
||||
AutoRegisterExternalUser(ctx context.Context, user *user_model.User, externalIDP *user_model.ExternalIDP, member *org_model.OrgMember, authReqID, userAgentID, resourceOwner string) error
|
||||
ResetLinkingUsers(ctx context.Context, authReqID, userAgentID string) error
|
||||
GetOrgByPrimaryDomain(primaryDomain string) (*org_model.OrgView, error)
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ type userEventProvider interface {
|
||||
|
||||
type orgViewProvider interface {
|
||||
OrgByID(string) (*org_view_model.OrgView, error)
|
||||
OrgByPrimaryDomain(string) (*org_view_model.OrgView, error)
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) Health(ctx context.Context) error {
|
||||
@ -231,6 +232,16 @@ func (repo *AuthRequestRepo) LinkExternalUsers(ctx context.Context, authReqID, u
|
||||
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) ResetLinkingUsers(ctx context.Context, authReqID, userAgentID string) error {
|
||||
request, err := repo.getAuthRequest(ctx, authReqID, userAgentID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
request.LinkingUsers = nil
|
||||
request.SelectedIDPConfigID = ""
|
||||
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) AutoRegisterExternalUser(ctx context.Context, registerUser *user_model.User, externalIDP *user_model.ExternalIDP, orgMember *org_model.OrgMember, authReqID, userAgentID, resourceOwner string) error {
|
||||
request, err := repo.getAuthRequest(ctx, authReqID, userAgentID)
|
||||
if err != nil {
|
||||
@ -317,7 +328,14 @@ func (repo *AuthRequestRepo) getLoginPolicyAndIDPProviders(ctx context.Context,
|
||||
func (repo *AuthRequestRepo) fillLoginPolicy(ctx context.Context, request *model.AuthRequest) error {
|
||||
orgID := request.UserOrgID
|
||||
if orgID == "" {
|
||||
orgID = request.GetScopeOrgID()
|
||||
primaryDomain := request.GetScopeOrgPrimaryDomain()
|
||||
if primaryDomain != "" {
|
||||
org, err := repo.GetOrgByPrimaryDomain(primaryDomain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
orgID = org.ID
|
||||
}
|
||||
}
|
||||
if orgID == "" {
|
||||
orgID = repo.IAMID
|
||||
@ -335,7 +353,16 @@ func (repo *AuthRequestRepo) fillLoginPolicy(ctx context.Context, request *model
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) checkLoginName(ctx context.Context, request *model.AuthRequest, loginName string) (err error) {
|
||||
orgID := request.GetScopeOrgID()
|
||||
primaryDomain := request.GetScopeOrgPrimaryDomain()
|
||||
orgID := ""
|
||||
if primaryDomain != "" {
|
||||
org, err := repo.GetOrgByPrimaryDomain(primaryDomain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
orgID = org.ID
|
||||
}
|
||||
|
||||
user := new(user_view_model.UserView)
|
||||
if orgID != "" {
|
||||
user, err = repo.View.UserByLoginNameAndResourceOwner(loginName, orgID)
|
||||
@ -356,6 +383,14 @@ func (repo *AuthRequestRepo) checkLoginName(ctx context.Context, request *model.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo AuthRequestRepo) GetOrgByPrimaryDomain(primaryDomain string) (*org_model.OrgView, error) {
|
||||
org, err := repo.OrgViewProvider.OrgByPrimaryDomain(primaryDomain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return org_view_model.OrgToModel(org), nil
|
||||
}
|
||||
|
||||
func (repo AuthRequestRepo) checkLoginPolicyWithResourceOwner(ctx context.Context, request *model.AuthRequest, user *user_view_model.UserView) error {
|
||||
loginPolicy, idpProviders, err := repo.getLoginPolicyAndIDPProviders(ctx, user.ResourceOwner)
|
||||
if err != nil {
|
||||
@ -386,10 +421,15 @@ func (repo *AuthRequestRepo) checkSelectedExternalIDP(request *model.AuthRequest
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) checkExternalUserLogin(request *model.AuthRequest, idpConfigID, externalUserID string) (err error) {
|
||||
orgID := request.GetScopeOrgID()
|
||||
primaryDomain := request.GetScopeOrgPrimaryDomain()
|
||||
externalIDP := new(user_view_model.ExternalIDPView)
|
||||
if orgID != "" {
|
||||
externalIDP, err = repo.View.ExternalIDPByExternalUserIDAndIDPConfigIDAndResourceOwner(externalUserID, idpConfigID, orgID)
|
||||
org := new(org_model.OrgView)
|
||||
if primaryDomain != "" {
|
||||
org, err = repo.GetOrgByPrimaryDomain(primaryDomain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
externalIDP, err = repo.View.ExternalIDPByExternalUserIDAndIDPConfigIDAndResourceOwner(externalUserID, idpConfigID, org.ID)
|
||||
} else {
|
||||
externalIDP, err = repo.View.ExternalIDPByExternalUserIDAndIDPConfigID(externalUserID, idpConfigID)
|
||||
}
|
||||
@ -435,7 +475,7 @@ func (repo *AuthRequestRepo) nextSteps(ctx context.Context, request *model.AuthR
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if request.SelectedIDPConfigID == "" {
|
||||
if request.SelectedIDPConfigID == "" || (request.SelectedIDPConfigID != "" && request.LinkingUsers != nil && len(request.LinkingUsers) > 0) {
|
||||
if user.InitRequired {
|
||||
return append(steps, &model.InitUserStep{PasswordSet: user.PasswordSet}), nil
|
||||
}
|
||||
|
@ -139,12 +139,22 @@ func (m *mockViewOrg) OrgByID(string) (*org_view_model.OrgView, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *mockViewOrg) OrgByPrimaryDomain(string) (*org_view_model.OrgView, error) {
|
||||
return &org_view_model.OrgView{
|
||||
State: int32(m.State),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type mockViewErrOrg struct{}
|
||||
|
||||
func (m *mockViewErrOrg) OrgByID(string) (*org_view_model.OrgView, error) {
|
||||
return nil, errors.ThrowInternal(nil, "id", "internal error")
|
||||
}
|
||||
|
||||
func (m *mockViewErrOrg) OrgByPrimaryDomain(string) (*org_view_model.OrgView, error) {
|
||||
return nil, errors.ThrowInternal(nil, "id", "internal error")
|
||||
}
|
||||
|
||||
func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
type fields struct {
|
||||
UserEvents *user_event.UserEventstore
|
||||
@ -582,7 +592,7 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"linking users, link users step",
|
||||
"linking users, password step",
|
||||
fields{
|
||||
userSessionViewProvider: &mockViewUserSession{
|
||||
MfaSoftwareVerification: time.Now().UTC().Add(-5 * time.Minute),
|
||||
@ -596,6 +606,32 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
MfaSoftwareCheckLifeTime: 18 * time.Hour,
|
||||
},
|
||||
args{
|
||||
&model.AuthRequest{
|
||||
UserID: "UserID",
|
||||
SelectedIDPConfigID: "IDPConfigID",
|
||||
LinkingUsers: []*model.ExternalUser{{IDPConfigID: "IDPConfigID", ExternalUserID: "UserID", DisplayName: "DisplayName"}},
|
||||
}, false},
|
||||
[]model.NextStep{&model.PasswordStep{}},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"linking users, linking step",
|
||||
fields{
|
||||
userSessionViewProvider: &mockViewUserSession{
|
||||
PasswordVerification: time.Now().UTC().Add(-5 * time.Minute),
|
||||
MfaSoftwareVerification: time.Now().UTC().Add(-5 * time.Minute),
|
||||
},
|
||||
userViewProvider: &mockViewUser{
|
||||
PasswordSet: true,
|
||||
IsEmailVerified: true,
|
||||
MfaMaxSetUp: int32(model.MfaLevelSoftware),
|
||||
},
|
||||
userEventProvider: &mockEventUser{},
|
||||
orgViewProvider: &mockViewOrg{State: org_model.OrgStateActive},
|
||||
MfaSoftwareCheckLifeTime: 18 * time.Hour,
|
||||
PasswordCheckLifeTime: 10 * 24 * time.Hour,
|
||||
},
|
||||
args{
|
||||
&model.AuthRequest{
|
||||
UserID: "UserID",
|
||||
|
@ -46,6 +46,17 @@ func (o *Org) Reduce(event *es_models.Event) (err error) {
|
||||
return err
|
||||
}
|
||||
err = org.AppendEvent(event)
|
||||
case model.OrgDomainPrimarySet:
|
||||
domain := new(org_model.OrgDomainView)
|
||||
err = domain.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
org, err = o.view.OrgByID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
org.Domain = domain.Domain
|
||||
default:
|
||||
return o.view.ProcessedOrgSequence(event.Sequence)
|
||||
}
|
||||
|
@ -15,6 +15,10 @@ func (v *View) OrgByID(orgID string) (*org_model.OrgView, error) {
|
||||
return org_view.OrgByID(v.Db, orgTable, orgID)
|
||||
}
|
||||
|
||||
func (v *View) OrgByPrimaryDomain(primaryDomain string) (*org_model.OrgView, error) {
|
||||
return org_view.OrgByPrimaryDomain(v.Db, orgTable, primaryDomain)
|
||||
}
|
||||
|
||||
func (v *View) SearchOrgs(req *model.OrgSearchRequest) ([]*org_model.OrgView, uint64, error) {
|
||||
return org_view.SearchOrgs(v.Db, orgTable, req)
|
||||
}
|
||||
|
@ -126,12 +126,12 @@ func (a *AuthRequest) SetUserInfo(userID, loginName, displayName, userOrgID stri
|
||||
a.UserOrgID = userOrgID
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetScopeOrgID() string {
|
||||
func (a *AuthRequest) GetScopeOrgPrimaryDomain() string {
|
||||
switch request := a.Request.(type) {
|
||||
case *AuthRequestOIDC:
|
||||
for _, scope := range request.Scopes {
|
||||
if strings.HasPrefix(scope, OrgIDScope) {
|
||||
strings.TrimPrefix(scope, OrgIDScope)
|
||||
if strings.HasPrefix(scope, OrgDomainPrimaryScope) {
|
||||
return strings.TrimPrefix(scope, OrgDomainPrimaryScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
OrgIDScope = "urn:zitadel:organisation:id:"
|
||||
OrgDomainPrimaryScope = "urn:zitadel:org:domain:primary:"
|
||||
)
|
||||
|
||||
type AuthRequestOIDC struct {
|
||||
|
@ -27,7 +27,7 @@ func (c *OIDCIDPConfig) Changes(changed *OIDCIDPConfig) map[string]interface{} {
|
||||
if c.ClientID != changed.ClientID {
|
||||
changes["clientId"] = changed.ClientID
|
||||
}
|
||||
if c.ClientSecret != nil && c.ClientSecret != changed.ClientSecret {
|
||||
if changed.ClientSecret != nil && c.ClientSecret != changed.ClientSecret {
|
||||
changes["clientSecret"] = changed.ClientSecret
|
||||
}
|
||||
if c.Issuer != changed.Issuer {
|
||||
|
@ -18,6 +18,16 @@ func OrgByID(db *gorm.DB, table, orgID string) (*model.OrgView, error) {
|
||||
return org, err
|
||||
}
|
||||
|
||||
func OrgByPrimaryDomain(db *gorm.DB, table, primaryDomain string) (*model.OrgView, error) {
|
||||
org := new(model.OrgView)
|
||||
query := repository.PrepareGetByKey(table, model.OrgSearchKey(org_model.OrgSearchKeyOrgDomain), primaryDomain)
|
||||
err := query(db, org)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "VIEW-GEwea", "Errors.Org.NotFound")
|
||||
}
|
||||
return org, err
|
||||
}
|
||||
|
||||
func SearchOrgs(db *gorm.DB, table string, req *org_model.OrgSearchRequest) ([]*model.OrgView, uint64, error) {
|
||||
orgs := make([]*model.OrgView, 0)
|
||||
query := repository.PrepareSearchQuery(table, model.OrgSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries})
|
||||
|
@ -33,6 +33,7 @@ type externalIDPCallbackData struct {
|
||||
type externalNotFoundOptionFormData struct {
|
||||
Link bool `schema:"link"`
|
||||
AutoRegister bool `schema:"autoregister"`
|
||||
ResetLinking bool `schema:"resetlinking"`
|
||||
}
|
||||
|
||||
type externalNotFoundOptionData struct {
|
||||
@ -139,35 +140,52 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http
|
||||
data := new(externalNotFoundOptionFormData)
|
||||
authReq, err := l.getAuthRequestAndParseData(r, data)
|
||||
if err != nil {
|
||||
l.renderError(w, r, authReq, err)
|
||||
l.renderExternalNotFoundOption(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
if data.Link {
|
||||
l.renderLogin(w, r, authReq, nil)
|
||||
return
|
||||
} else if data.ResetLinking {
|
||||
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.handleLogin(w, r)
|
||||
return
|
||||
}
|
||||
l.handleAutoRegister(w, r, authReq)
|
||||
}
|
||||
|
||||
func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest) {
|
||||
orgIamPolicy, err := l.getOrgIamPolicy(r, authReq.GetScopeOrgID())
|
||||
if err != nil {
|
||||
l.renderExternalNotFoundOption(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
iam, err := l.authRepo.GetIAM(r.Context())
|
||||
if err != nil {
|
||||
l.renderExternalNotFoundOption(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
|
||||
resourceOwner := iam.GlobalOrgID
|
||||
member := &org_model.OrgMember{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: iam.GlobalOrgID},
|
||||
Roles: []string{orgProjectCreatorRole},
|
||||
}
|
||||
if authReq.GetScopeOrgID() != iam.GlobalOrgID && authReq.GetScopeOrgID() != "" {
|
||||
member = nil
|
||||
resourceOwner = authReq.GetScopeOrgID()
|
||||
if authReq.GetScopeOrgPrimaryDomain() != "" {
|
||||
primaryDomain := authReq.GetScopeOrgPrimaryDomain()
|
||||
org, err := l.authRepo.GetOrgByPrimaryDomain(primaryDomain)
|
||||
if err != nil {
|
||||
l.renderExternalNotFoundOption(w, r, authReq, err)
|
||||
}
|
||||
if org.ID != iam.GlobalOrgID {
|
||||
member = nil
|
||||
resourceOwner = org.ID
|
||||
}
|
||||
}
|
||||
|
||||
orgIamPolicy, err := l.getOrgIamPolicy(r, resourceOwner)
|
||||
if err != nil {
|
||||
l.renderExternalNotFoundOption(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
|
||||
idpConfig, err := l.authRepo.GetIDPConfigByID(r.Context(), authReq.SelectedIDPConfigID)
|
||||
@ -216,7 +234,6 @@ func (l *Login) mapTokenToLoginUser(tokens *oidc.Tokens, idpConfig *iam_model.ID
|
||||
}
|
||||
return externalUser
|
||||
}
|
||||
|
||||
func (l *Login) mapExternalUserToLoginUser(orgIamPolicy *org_model.OrgIAMPolicy, linkingUser *model.ExternalUser, idpConfig *iam_model.IDPConfigView) (*usr_model.User, *usr_model.ExternalIDP) {
|
||||
username := linkingUser.PreferredUsername
|
||||
switch idpConfig.OIDCUsernameMapping {
|
||||
|
@ -71,11 +71,6 @@ func (l *Login) handleExternalRegisterCallback(w http.ResponseWriter, r *http.Re
|
||||
}
|
||||
|
||||
func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, idpConfig *iam_model.IDPConfigView, userAgentID string, tokens *oidc.Tokens) {
|
||||
orgIamPolicy, err := l.getOrgIamPolicy(r, authReq.GetScopeOrgID())
|
||||
if err != nil {
|
||||
l.renderRegisterOption(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
iam, err := l.authRepo.GetIAM(r.Context())
|
||||
if err != nil {
|
||||
l.renderRegisterOption(w, r, authReq, err)
|
||||
@ -86,11 +81,24 @@ func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Reques
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: iam.GlobalOrgID},
|
||||
Roles: []string{orgProjectCreatorRole},
|
||||
}
|
||||
if authReq.GetScopeOrgID() != iam.GlobalOrgID && authReq.GetScopeOrgID() != "" {
|
||||
member = nil
|
||||
resourceOwner = authReq.GetScopeOrgID()
|
||||
}
|
||||
|
||||
if authReq.GetScopeOrgPrimaryDomain() != "" {
|
||||
primaryDomain := authReq.GetScopeOrgPrimaryDomain()
|
||||
org, err := l.authRepo.GetOrgByPrimaryDomain(primaryDomain)
|
||||
if err != nil {
|
||||
l.renderRegisterOption(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
if org.ID != iam.GlobalOrgID {
|
||||
member = nil
|
||||
resourceOwner = org.ID
|
||||
}
|
||||
}
|
||||
orgIamPolicy, err := l.getOrgIamPolicy(r, resourceOwner)
|
||||
if err != nil {
|
||||
l.renderRegisterOption(w, r, authReq, err)
|
||||
return
|
||||
}
|
||||
user, externalIDP := l.mapTokenToLoginUserAndExternalIDP(orgIamPolicy, tokens, idpConfig)
|
||||
_, err = l.authRepo.RegisterExternalUser(setContext(r.Context(), resourceOwner), user, externalIDP, member, resourceOwner)
|
||||
if err != nil {
|
||||
|
@ -71,9 +71,17 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) {
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: iam.GlobalOrgID},
|
||||
Roles: []string{orgProjectCreatorRole},
|
||||
}
|
||||
if authRequest.GetScopeOrgID() != "" && authRequest.GetScopeOrgID() != iam.GlobalOrgID {
|
||||
member = nil
|
||||
resourceOwner = authRequest.GetScopeOrgID()
|
||||
if authRequest.GetScopeOrgPrimaryDomain() != "" {
|
||||
primaryDomain := authRequest.GetScopeOrgPrimaryDomain()
|
||||
org, err := l.authRepo.GetOrgByPrimaryDomain(primaryDomain)
|
||||
if err != nil {
|
||||
l.renderRegisterOption(w, r, authRequest, err)
|
||||
return
|
||||
}
|
||||
if org.ID != iam.GlobalOrgID {
|
||||
member = nil
|
||||
resourceOwner = org.ID
|
||||
}
|
||||
}
|
||||
user, err := l.authRepo.Register(setContext(r.Context(), resourceOwner), data.toUserModel(), member, resourceOwner)
|
||||
if err != nil {
|
||||
|
@ -292,7 +292,14 @@ func (l *Login) getOrgID(authReq *model.AuthRequest) string {
|
||||
if authReq.Request == nil {
|
||||
return ""
|
||||
}
|
||||
return authReq.GetScopeOrgID()
|
||||
primaryDomain := authReq.GetScopeOrgPrimaryDomain()
|
||||
if primaryDomain != "" {
|
||||
org, _ := l.authRepo.GetOrgByPrimaryDomain(primaryDomain)
|
||||
if org != nil {
|
||||
return org.ID
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getRequestID(authReq *model.AuthRequest, r *http.Request) string {
|
||||
|
@ -1,9 +1,7 @@
|
||||
{{ define "error-message" }}
|
||||
{{if .ErrMessage }}
|
||||
<div class="field">
|
||||
<div class="error">
|
||||
{{ if .ErrType }}{{ .ErrType }} - {{end}}{{ .ErrMessage }}
|
||||
</div>
|
||||
<div class="error">
|
||||
{{ if .ErrType }}{{ .ErrType }} - {{end}}{{ .ErrMessage }}
|
||||
</div>
|
||||
{{end}}
|
||||
{{ end }}
|
@ -15,9 +15,7 @@
|
||||
<div class="actions">
|
||||
<button class="secondary right" name="link" value="true" formnovalidate>{{t "ExternalNotFoundOption.Link"}}</button>
|
||||
<button class="secondary right" name="autoregister" value="true" formnovalidate>{{t "ExternalNotFoundOption.AutoRegister"}}</button>
|
||||
<a class="button secondary" href="{{ loginUrl .AuthReqID }}">
|
||||
{{t "Actions.Back"}}
|
||||
</a>
|
||||
<button class="secondary right" name="resetlinking" value="true" formnovalidate>{{t "Actions.Back"}}</button>
|
||||
</div>
|
||||
|
||||
{{template "error-message" .}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user