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>
This commit is contained in:
Silvan 2021-08-09 08:55:48 +02:00 committed by GitHub
parent 7451ed58f2
commit 35fb2403d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 71 additions and 27 deletions

View File

@ -4,25 +4,24 @@ import (
"context" "context"
"time" "time"
"github.com/caos/zitadel/internal/command"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/logging" "github.com/caos/logging"
"github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view" "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
"github.com/caos/zitadel/internal/auth_request/model" "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" 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" "github.com/caos/zitadel/internal/errors"
v1 "github.com/caos/zitadel/internal/eventstore/v1"
es_models "github.com/caos/zitadel/internal/eventstore/v1/models" es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
iam_model "github.com/caos/zitadel/internal/iam/model" 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" iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
"github.com/caos/zitadel/internal/id" "github.com/caos/zitadel/internal/id"
org_model "github.com/caos/zitadel/internal/org/model" org_model "github.com/caos/zitadel/internal/org/model"
org_view_model "github.com/caos/zitadel/internal/org/repository/view/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" 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" "github.com/caos/zitadel/internal/telemetry/tracing"
user_model "github.com/caos/zitadel/internal/user/model" user_model "github.com/caos/zitadel/internal/user/model"
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
@ -34,6 +33,7 @@ type AuthRequestRepo struct {
Command *command.Commands Command *command.Commands
AuthRequests cache.AuthRequestCache AuthRequests cache.AuthRequestCache
View *view.View View *view.View
Eventstore v1.Eventstore
UserSessionViewProvider userSessionViewProvider UserSessionViewProvider userSessionViewProvider
UserViewProvider userViewProvider UserViewProvider userViewProvider
@ -664,7 +664,7 @@ func (repo *AuthRequestRepo) usersForUserSelection(request *domain.AuthRequest)
LoginName: session.LoginName, LoginName: session.LoginName,
ResourceOwner: session.ResourceOwner, ResourceOwner: session.ResourceOwner,
AvatarKey: session.AvatarKey, AvatarKey: session.AvatarKey,
UserSessionState: auth_req_model.UserSessionStateToDomain(session.State), UserSessionState: model.UserSessionStateToDomain(session.State),
SelectionPossible: request.RequestedOrgID == "" || request.RequestedOrgID == session.ResourceOwner, 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) { func (repo *AuthRequestRepo) mfaChecked(userSession *user_model.UserSessionView, request *domain.AuthRequest, user *user_model.UserView) (domain.NextStep, bool, error) {
mfaLevel := request.MFALevel() mfaLevel := request.MFALevel()
allowedProviders, required := user.MFATypesAllowed(mfaLevel, request.LoginPolicy) 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) { if promptRequired || !repo.mfaSkippedOrSetUp(user) {
types := user.MFATypesSetupPossible(mfaLevel, request.LoginPolicy) types := user.MFATypesSetupPossible(mfaLevel, request.LoginPolicy)
if promptRequired && len(types) == 0 { if promptRequired && len(types) == 0 {
@ -733,14 +733,14 @@ func (repo *AuthRequestRepo) mfaChecked(userSession *user_model.UserSessionView,
fallthrough fallthrough
case domain.MFALevelSecondFactor: case domain.MFALevelSecondFactor:
if checkVerificationTimeMaxAge(userSession.SecondFactorVerification, repo.SecondFactorCheckLifeTime, request) { 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 request.AuthTime = userSession.SecondFactorVerification
return nil, true, nil return nil, true, nil
} }
fallthrough fallthrough
case domain.MFALevelMultiFactor: case domain.MFALevelMultiFactor:
if checkVerificationTimeMaxAge(userSession.MultiFactorVerification, repo.MultiFactorCheckLifeTime, request) { 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 request.AuthTime = userSession.MultiFactorVerification
return nil, true, nil return nil, true, nil
} }
@ -762,17 +762,32 @@ func (repo *AuthRequestRepo) getLoginPolicy(ctx context.Context, orgID string) (
if err != nil { if err != nil {
return nil, err 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) { func (repo *AuthRequestRepo) getPrivacyPolicy(ctx context.Context, orgID string) (*domain.PrivacyPolicy, error) {
policy, err := repo.View.PrivacyPolicyByAggregateID(orgID) policy, err := repo.View.PrivacyPolicyByAggregateID(orgID)
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
policy, err = repo.View.PrivacyPolicyByAggregateID(repo.IAMID) policy, err = repo.View.PrivacyPolicyByAggregateID(repo.IAMID)
if err != nil { if err != nil && !errors.IsNotFound(err) {
return nil, 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 policy.Default = true
for _, event := range events {
policy.AppendEvent(event)
}
return policy.ToDomain(), nil
} }
if err != nil { if err != nil {
return nil, err return nil, err
@ -825,13 +840,13 @@ func getLoginPolicyIDPProviders(provider idpProviderViewProvider, iamID, orgID s
if err != nil { if err != nil {
return nil, err 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) idpProviders, err := provider.IDPProvidersByAggregateIDAndState(orgID, iam_model.IDPConfigStateActive)
if err != nil { if err != nil {
return nil, err 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 { func checkVerificationTimeMaxAge(verificationTime time.Time, lifetime time.Duration, request *domain.AuthRequest) bool {

View File

@ -2,7 +2,6 @@ package eventstore
import ( import (
"context" "context"
"github.com/caos/zitadel/internal/eventstore"
"os" "os"
"time" "time"
@ -13,6 +12,7 @@ import (
"github.com/caos/zitadel/internal/command" "github.com/caos/zitadel/internal/command"
"github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/errors" "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/eventstore/v1/spooler"
"github.com/caos/zitadel/internal/id" "github.com/caos/zitadel/internal/id"
"github.com/caos/zitadel/internal/key/model" "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)) renewTimer = time.After(k.getRenewTimer(refreshed))
case <-renewTimer: case <-renewTimer:
key, err := k.latestSigningKey() 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) 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)) renewTimer = time.After(k.getRenewTimer(refreshed))
} }
} }

View File

@ -6,16 +6,18 @@ import (
"github.com/caos/logging" "github.com/caos/logging"
"github.com/caos/zitadel/internal/api/authz" "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/config/systemdefaults"
"github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/errors" "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_model "github.com/caos/zitadel/internal/iam/model"
iam_view_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/telemetry/tracing"
auth_view "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
org_model "github.com/caos/zitadel/internal/org/model" org_model "github.com/caos/zitadel/internal/org/model"
"github.com/caos/zitadel/internal/org/repository/view/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 ( const (
@ -25,6 +27,7 @@ const (
type OrgRepository struct { type OrgRepository struct {
SearchLimit uint64 SearchLimit uint64
Eventstore eventstore.Eventstore
View *auth_view.View View *auth_view.View
SystemDefaults systemdefaults.SystemDefaults 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) { func (repo *OrgRepository) GetDefaultPrivacyPolicy(ctx context.Context) (*iam_model.PrivacyPolicyView, error) {
policy, err := repo.View.PrivacyPolicyByAggregateID(repo.SystemDefaults.IamID) policy, viewErr := repo.View.PrivacyPolicyByAggregateID(repo.SystemDefaults.IamID)
if err != nil { if viewErr != nil && !errors.IsNotFound(viewErr) {
return nil, err 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))
} }

View File

@ -1,12 +1,12 @@
package handler package handler
import ( import (
"github.com/caos/zitadel/internal/eventstore/v1"
"time" "time"
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view" "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
sd "github.com/caos/zitadel/internal/config/systemdefaults" sd "github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/config/types" "github.com/caos/zitadel/internal/config/types"
v1 "github.com/caos/zitadel/internal/eventstore/v1"
"github.com/caos/zitadel/internal/eventstore/v1/query" "github.com/caos/zitadel/internal/eventstore/v1/query"
key_model "github.com/caos/zitadel/internal/key/model" key_model "github.com/caos/zitadel/internal/key/model"
) )

View File

@ -17,7 +17,7 @@ import (
"github.com/caos/zitadel/internal/config/types" "github.com/caos/zitadel/internal/config/types"
"github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/crypto"
es2 "github.com/caos/zitadel/internal/eventstore" 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" es_spol "github.com/caos/zitadel/internal/eventstore/v1/spooler"
"github.com/caos/zitadel/internal/id" "github.com/caos/zitadel/internal/id"
key_model "github.com/caos/zitadel/internal/key/model" 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, Command: command,
AuthRequests: authReq, AuthRequests: authReq,
View: view, View: view,
Eventstore: es,
UserSessionViewProvider: view, UserSessionViewProvider: view,
UserViewProvider: view, UserViewProvider: view,
UserCommandProvider: command, UserCommandProvider: command,
@ -156,6 +157,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
SearchLimit: conf.SearchLimit, SearchLimit: conf.SearchLimit,
View: view, View: view,
SystemDefaults: systemDefaults, SystemDefaults: systemDefaults,
Eventstore: es,
}, },
eventstore.IAMRepository{ eventstore.IAMRepository{
IAMID: systemDefaults.IamID, IAMID: systemDefaults.IamID,

View File

@ -2,11 +2,12 @@ package command
import ( import (
"context" "context"
"time"
"github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/domain"
keypair "github.com/caos/zitadel/internal/repository/keypair" keypair "github.com/caos/zitadel/internal/repository/keypair"
"time"
) )
const ( const (

View File

@ -20,7 +20,7 @@ import (
"github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/errors" "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/eventstore/v1/models"
"github.com/caos/zitadel/internal/i18n" "github.com/caos/zitadel/internal/i18n"
iam_model "github.com/caos/zitadel/internal/iam/model" iam_model "github.com/caos/zitadel/internal/iam/model"