mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-05 22:52:46 +00:00
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:
parent
7451ed58f2
commit
35fb2403d6
@ -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 {
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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,
|
||||||
|
@ -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 (
|
||||||
|
@ -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"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user