From 35fb2403d6992795ce789644b85774676c785ed8 Mon Sep 17 00:00:00 2001 From: Silvan Date: Mon, 9 Aug 2021 08:55:48 +0200 Subject: [PATCH] fix(auth): read privacy policy from eventstore if not found (#2125) * fix(auth): read privacy policy from eventstore if not found * Update internal/auth/repository/eventsourcing/eventstore/auth_request.go Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> --- .../eventsourcing/eventstore/auth_request.go | 41 +++++++++++++------ .../eventsourcing/eventstore/key.go | 6 +-- .../eventsourcing/eventstore/org.go | 40 ++++++++++++++---- .../eventsourcing/handler/handler.go | 2 +- .../repository/eventsourcing/repository.go | 4 +- internal/command/key_pair.go | 3 +- .../eventsourcing/eventstore/org.go | 2 +- 7 files changed, 71 insertions(+), 27 deletions(-) diff --git a/internal/auth/repository/eventsourcing/eventstore/auth_request.go b/internal/auth/repository/eventsourcing/eventstore/auth_request.go index 0e73c4d88..98c335de4 100644 --- a/internal/auth/repository/eventsourcing/eventstore/auth_request.go +++ b/internal/auth/repository/eventsourcing/eventstore/auth_request.go @@ -4,25 +4,24 @@ import ( "context" "time" - "github.com/caos/zitadel/internal/command" - "github.com/caos/zitadel/internal/domain" - "github.com/caos/logging" "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view" "github.com/caos/zitadel/internal/auth_request/model" - auth_req_model "github.com/caos/zitadel/internal/auth_request/model" cache "github.com/caos/zitadel/internal/auth_request/repository" + "github.com/caos/zitadel/internal/command" + "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" + v1 "github.com/caos/zitadel/internal/eventstore/v1" es_models "github.com/caos/zitadel/internal/eventstore/v1/models" iam_model "github.com/caos/zitadel/internal/iam/model" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model" iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" "github.com/caos/zitadel/internal/id" org_model "github.com/caos/zitadel/internal/org/model" org_view_model "github.com/caos/zitadel/internal/org/repository/view/model" project_view_model "github.com/caos/zitadel/internal/project/repository/view/model" + "github.com/caos/zitadel/internal/repository/iam" "github.com/caos/zitadel/internal/telemetry/tracing" user_model "github.com/caos/zitadel/internal/user/model" es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" @@ -34,6 +33,7 @@ type AuthRequestRepo struct { Command *command.Commands AuthRequests cache.AuthRequestCache View *view.View + Eventstore v1.Eventstore UserSessionViewProvider userSessionViewProvider UserViewProvider userViewProvider @@ -664,7 +664,7 @@ func (repo *AuthRequestRepo) usersForUserSelection(request *domain.AuthRequest) LoginName: session.LoginName, ResourceOwner: session.ResourceOwner, AvatarKey: session.AvatarKey, - UserSessionState: auth_req_model.UserSessionStateToDomain(session.State), + UserSessionState: model.UserSessionStateToDomain(session.State), SelectionPossible: request.RequestedOrgID == "" || request.RequestedOrgID == session.ResourceOwner, } } @@ -709,7 +709,7 @@ func (repo *AuthRequestRepo) firstFactorChecked(request *domain.AuthRequest, use func (repo *AuthRequestRepo) mfaChecked(userSession *user_model.UserSessionView, request *domain.AuthRequest, user *user_model.UserView) (domain.NextStep, bool, error) { mfaLevel := request.MFALevel() allowedProviders, required := user.MFATypesAllowed(mfaLevel, request.LoginPolicy) - promptRequired := (auth_req_model.MFALevelToDomain(user.MFAMaxSetUp) < mfaLevel) || (len(allowedProviders) == 0 && required) + promptRequired := (model.MFALevelToDomain(user.MFAMaxSetUp) < mfaLevel) || (len(allowedProviders) == 0 && required) if promptRequired || !repo.mfaSkippedOrSetUp(user) { types := user.MFATypesSetupPossible(mfaLevel, request.LoginPolicy) if promptRequired && len(types) == 0 { @@ -733,14 +733,14 @@ func (repo *AuthRequestRepo) mfaChecked(userSession *user_model.UserSessionView, fallthrough case domain.MFALevelSecondFactor: if checkVerificationTimeMaxAge(userSession.SecondFactorVerification, repo.SecondFactorCheckLifeTime, request) { - request.MFAsVerified = append(request.MFAsVerified, auth_req_model.MFATypeToDomain(userSession.SecondFactorVerificationType)) + request.MFAsVerified = append(request.MFAsVerified, model.MFATypeToDomain(userSession.SecondFactorVerificationType)) request.AuthTime = userSession.SecondFactorVerification return nil, true, nil } fallthrough case domain.MFALevelMultiFactor: if checkVerificationTimeMaxAge(userSession.MultiFactorVerification, repo.MultiFactorCheckLifeTime, request) { - request.MFAsVerified = append(request.MFAsVerified, auth_req_model.MFATypeToDomain(userSession.MultiFactorVerificationType)) + request.MFAsVerified = append(request.MFAsVerified, model.MFATypeToDomain(userSession.MultiFactorVerificationType)) request.AuthTime = userSession.MultiFactorVerification return nil, true, nil } @@ -762,17 +762,32 @@ func (repo *AuthRequestRepo) getLoginPolicy(ctx context.Context, orgID string) ( if err != nil { return nil, err } - return iam_es_model.LoginPolicyViewToModel(policy), err + return iam_view_model.LoginPolicyViewToModel(policy), err } func (repo *AuthRequestRepo) getPrivacyPolicy(ctx context.Context, orgID string) (*domain.PrivacyPolicy, error) { policy, err := repo.View.PrivacyPolicyByAggregateID(orgID) if errors.IsNotFound(err) { policy, err = repo.View.PrivacyPolicyByAggregateID(repo.IAMID) - if err != nil { + if err != nil && !errors.IsNotFound(err) { return nil, err } + if err == nil { + return policy.ToDomain(), nil + } + policy = &iam_view_model.PrivacyPolicyView{} + events, err := repo.Eventstore.FilterEvents(ctx, es_models.NewSearchQuery(). + AggregateIDFilter(repo.IAMID). + AggregateTypeFilter(iam.AggregateType). + EventTypesFilter(es_models.EventType(iam.PrivacyPolicyAddedEventType), es_models.EventType(iam.PrivacyPolicyChangedEventType))) + if err != nil || len(events) == 0 { + return nil, errors.ThrowNotFound(err, "EVENT-GSRqg", "IAM.PrivacyPolicy.NotExisting") + } policy.Default = true + for _, event := range events { + policy.AppendEvent(event) + } + return policy.ToDomain(), nil } if err != nil { return nil, err @@ -825,13 +840,13 @@ func getLoginPolicyIDPProviders(provider idpProviderViewProvider, iamID, orgID s if err != nil { return nil, err } - return iam_es_model.IDPProviderViewsToModel(idpProviders), nil + return iam_view_model.IDPProviderViewsToModel(idpProviders), nil } idpProviders, err := provider.IDPProvidersByAggregateIDAndState(orgID, iam_model.IDPConfigStateActive) if err != nil { return nil, err } - return iam_es_model.IDPProviderViewsToModel(idpProviders), nil + return iam_view_model.IDPProviderViewsToModel(idpProviders), nil } func checkVerificationTimeMaxAge(verificationTime time.Time, lifetime time.Duration, request *domain.AuthRequest) bool { diff --git a/internal/auth/repository/eventsourcing/eventstore/key.go b/internal/auth/repository/eventsourcing/eventstore/key.go index ed0ff57e2..26d529e91 100644 --- a/internal/auth/repository/eventsourcing/eventstore/key.go +++ b/internal/auth/repository/eventsourcing/eventstore/key.go @@ -2,7 +2,6 @@ package eventstore import ( "context" - "github.com/caos/zitadel/internal/eventstore" "os" "time" @@ -13,6 +12,7 @@ import ( "github.com/caos/zitadel/internal/command" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/v1/spooler" "github.com/caos/zitadel/internal/id" "github.com/caos/zitadel/internal/key/model" @@ -50,9 +50,9 @@ func (k *KeyRepository) GetSigningKey(ctx context.Context, keyCh chan<- jose.Sig renewTimer = time.After(k.getRenewTimer(refreshed)) case <-renewTimer: key, err := k.latestSigningKey() - logging.Log("KEY-DAfh4").OnError(err).Error("could not check for latest signing key") + logging.Log("KEY-DAfh4-1").OnError(err).Error("could not check for latest signing key") refreshed, err := k.refreshSigningKey(ctx, key, keyCh, algorithm) - logging.Log("KEY-DAfh4").OnError(err).Error("could not refresh signing key when ensuring key") + logging.Log("KEY-DAfh4-2").OnError(err).Error("could not refresh signing key when ensuring key") renewTimer = time.After(k.getRenewTimer(refreshed)) } } diff --git a/internal/auth/repository/eventsourcing/eventstore/org.go b/internal/auth/repository/eventsourcing/eventstore/org.go index d42408f5d..da1d9ea2a 100644 --- a/internal/auth/repository/eventsourcing/eventstore/org.go +++ b/internal/auth/repository/eventsourcing/eventstore/org.go @@ -6,16 +6,18 @@ import ( "github.com/caos/logging" "github.com/caos/zitadel/internal/api/authz" + auth_view "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view" "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" + eventstore "github.com/caos/zitadel/internal/eventstore/v1" + "github.com/caos/zitadel/internal/eventstore/v1/models" iam_model "github.com/caos/zitadel/internal/iam/model" iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" - "github.com/caos/zitadel/internal/telemetry/tracing" - - auth_view "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view" org_model "github.com/caos/zitadel/internal/org/model" "github.com/caos/zitadel/internal/org/repository/view/model" + "github.com/caos/zitadel/internal/repository/iam" + "github.com/caos/zitadel/internal/telemetry/tracing" ) const ( @@ -25,6 +27,7 @@ const ( type OrgRepository struct { SearchLimit uint64 + Eventstore eventstore.Eventstore View *auth_view.View SystemDefaults systemdefaults.SystemDefaults } @@ -129,9 +132,32 @@ func (repo *OrgRepository) GetLoginText(ctx context.Context, orgID string) ([]*d } func (repo *OrgRepository) GetDefaultPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error) { - policy, err := repo.View.PrivacyPolicyByAggregateID(repo.SystemDefaults.IamID) - if err != nil { - return nil, err + policy, viewErr := repo.View.PrivacyPolicyByAggregateID(repo.SystemDefaults.IamID) + if viewErr != nil && !errors.IsNotFound(viewErr) { + return nil, viewErr } - return iam_view_model.PrivacyViewToModel(policy), nil + if errors.IsNotFound(viewErr) { + policy = new(iam_view_model.PrivacyPolicyView) + } + events, esErr := repo.getIAMEvents(ctx, policy.Sequence) + if errors.IsNotFound(viewErr) && len(events) == 0 { + return nil, errors.ThrowNotFound(nil, "EVENT-LPJMp", "Errors.IAM.PrivacyPolicy.NotFound") + } + if esErr != nil { + logging.Log("EVENT-1l7bf").WithError(esErr).Debug("error retrieving new events") + return iam_view_model.PrivacyViewToModel(policy), nil + } + policyCopy := *policy + for _, event := range events { + if err := policyCopy.AppendEvent(event); err != nil { + return iam_view_model.PrivacyViewToModel(policy), nil + } + } + result := iam_view_model.PrivacyViewToModel(policy) + result.Default = true + return result, nil +} + +func (p *OrgRepository) getIAMEvents(ctx context.Context, sequence uint64) ([]*models.Event, error) { + return p.Eventstore.FilterEvents(ctx, models.NewSearchQuery().AggregateIDFilter(p.SystemDefaults.IamID).AggregateTypeFilter(iam.AggregateType)) } diff --git a/internal/auth/repository/eventsourcing/handler/handler.go b/internal/auth/repository/eventsourcing/handler/handler.go index 2aa3b464c..c727b4a2f 100644 --- a/internal/auth/repository/eventsourcing/handler/handler.go +++ b/internal/auth/repository/eventsourcing/handler/handler.go @@ -1,12 +1,12 @@ package handler import ( - "github.com/caos/zitadel/internal/eventstore/v1" "time" "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view" sd "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/config/types" + v1 "github.com/caos/zitadel/internal/eventstore/v1" "github.com/caos/zitadel/internal/eventstore/v1/query" key_model "github.com/caos/zitadel/internal/key/model" ) diff --git a/internal/auth/repository/eventsourcing/repository.go b/internal/auth/repository/eventsourcing/repository.go index 4c75bc714..6f9eaad29 100644 --- a/internal/auth/repository/eventsourcing/repository.go +++ b/internal/auth/repository/eventsourcing/repository.go @@ -17,7 +17,7 @@ import ( "github.com/caos/zitadel/internal/config/types" "github.com/caos/zitadel/internal/crypto" es2 "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/v1" + v1 "github.com/caos/zitadel/internal/eventstore/v1" es_spol "github.com/caos/zitadel/internal/eventstore/v1/spooler" "github.com/caos/zitadel/internal/id" key_model "github.com/caos/zitadel/internal/key/model" @@ -101,6 +101,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co Command: command, AuthRequests: authReq, View: view, + Eventstore: es, UserSessionViewProvider: view, UserViewProvider: view, UserCommandProvider: command, @@ -156,6 +157,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co SearchLimit: conf.SearchLimit, View: view, SystemDefaults: systemDefaults, + Eventstore: es, }, eventstore.IAMRepository{ IAMID: systemDefaults.IamID, diff --git a/internal/command/key_pair.go b/internal/command/key_pair.go index eeb915b01..7f21690fb 100644 --- a/internal/command/key_pair.go +++ b/internal/command/key_pair.go @@ -2,11 +2,12 @@ package command import ( "context" + "time" + "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/domain" keypair "github.com/caos/zitadel/internal/repository/keypair" - "time" ) const ( diff --git a/internal/management/repository/eventsourcing/eventstore/org.go b/internal/management/repository/eventsourcing/eventstore/org.go index d4e5b8601..248885581 100644 --- a/internal/management/repository/eventsourcing/eventstore/org.go +++ b/internal/management/repository/eventsourcing/eventstore/org.go @@ -20,7 +20,7 @@ import ( "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1" + v1 "github.com/caos/zitadel/internal/eventstore/v1" "github.com/caos/zitadel/internal/eventstore/v1/models" "github.com/caos/zitadel/internal/i18n" iam_model "github.com/caos/zitadel/internal/iam/model"