mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-12 02:54:20 +00:00
feat: Iam projection (#3074)
* feat: implement projection for iam and clean up code * feat: add migration * fix: remove unused tests * fix: handler
This commit is contained in:
parent
44d78df4d4
commit
b363ddd707
@ -2,6 +2,7 @@ package spooler
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/caos/zitadel/internal/command"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
|
@ -73,7 +73,6 @@ func Create(config Config, authZ authz.Config, q *query.Queries, authZRepo *auth
|
||||
}
|
||||
|
||||
api.verifier = authz.Start(&repo)
|
||||
api.health = authZRepo
|
||||
api.auth = authRepo
|
||||
api.admin = adminRepo
|
||||
api.grpcServer = server.CreateServer(api.verifier, authZ, sd.DefaultLanguage)
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/config/types"
|
||||
v1 "github.com/caos/zitadel/internal/eventstore/v1"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||
query2 "github.com/caos/zitadel/internal/query"
|
||||
)
|
||||
|
||||
type Configs map[string]*Config
|
||||
@ -29,11 +30,11 @@ func (h *handler) Eventstore() v1.Eventstore {
|
||||
return h.es
|
||||
}
|
||||
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, systemDefaults sd.SystemDefaults) []query.Handler {
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, systemDefaults sd.SystemDefaults, queries *query2.Queries) []query.Handler {
|
||||
return []query.Handler{
|
||||
newUser(
|
||||
handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es},
|
||||
systemDefaults.IamID),
|
||||
systemDefaults.IamID, queries),
|
||||
newUserSession(
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserSession"), errorCount, es}),
|
||||
newToken(
|
||||
@ -45,10 +46,10 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
handler{view, bulkLimit, configs.cycleDuration("IDPConfig"), errorCount, es}),
|
||||
newIDPProvider(
|
||||
handler{view, bulkLimit, configs.cycleDuration("IDPProvider"), errorCount, es},
|
||||
systemDefaults),
|
||||
systemDefaults, queries),
|
||||
newExternalIDP(
|
||||
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
||||
systemDefaults),
|
||||
systemDefaults, queries),
|
||||
newRefreshToken(handler{view, bulkLimit, configs.cycleDuration("RefreshToken"), errorCount, es}),
|
||||
newOrgProjectMapping(handler{view, bulkLimit, configs.cycleDuration("OrgProjectMapping"), errorCount, es}),
|
||||
}
|
||||
|
@ -2,13 +2,10 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
query2 "github.com/caos/zitadel/internal/query"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
@ -30,15 +27,18 @@ type IDPProvider struct {
|
||||
handler
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
subscription *v1.Subscription
|
||||
queries *query2.Queries
|
||||
}
|
||||
|
||||
func newIDPProvider(
|
||||
h handler,
|
||||
defaults systemdefaults.SystemDefaults,
|
||||
queries *query2.Queries,
|
||||
) *IDPProvider {
|
||||
idpProvider := &IDPProvider{
|
||||
handler: h,
|
||||
systemDefaults: defaults,
|
||||
queries: queries,
|
||||
}
|
||||
|
||||
idpProvider.subscribe()
|
||||
@ -120,7 +120,7 @@ func (i *IDPProvider) processIdpProvider(event *es_models.Event) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config := new(iam_model.IDPConfig)
|
||||
config := new(query2.IDP)
|
||||
if event.AggregateID == i.systemDefaults.IamID {
|
||||
config, err = i.getDefaultIDPConfig(context.TODO(), esConfig.IDPConfigID)
|
||||
} else {
|
||||
@ -145,7 +145,7 @@ func (i *IDPProvider) processIdpProvider(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (i *IDPProvider) fillData(provider *iam_view_model.IDPProviderView) (err error) {
|
||||
var config *iam_model.IDPConfig
|
||||
var config *query2.IDP
|
||||
if provider.IDPProviderType == int32(iam_model.IDPProviderTypeSystem) {
|
||||
config, err = i.getDefaultIDPConfig(context.Background(), provider.IDPConfigID)
|
||||
} else {
|
||||
@ -158,10 +158,14 @@ func (i *IDPProvider) fillData(provider *iam_view_model.IDPProviderView) (err er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IDPProvider) fillConfigData(provider *iam_view_model.IDPProviderView, config *iam_model.IDPConfig) {
|
||||
func (i *IDPProvider) fillConfigData(provider *iam_view_model.IDPProviderView, config *query2.IDP) {
|
||||
provider.Name = config.Name
|
||||
provider.StylingType = int32(config.StylingType)
|
||||
provider.IDPConfigType = int32(config.Type)
|
||||
if config.OIDCIDP != nil {
|
||||
provider.IDPConfigType = int32(domain.IDPConfigTypeOIDC)
|
||||
} else if config.JWTIDP != nil {
|
||||
provider.IDPConfigType = int32(domain.IDPConfigTypeJWT)
|
||||
}
|
||||
provider.IDPState = int32(config.State)
|
||||
}
|
||||
|
||||
@ -174,63 +178,10 @@ func (i *IDPProvider) OnSuccess() error {
|
||||
return spooler.HandleSuccess(i.view.UpdateIDPProviderSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (i *IDPProvider) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := i.getOrgByID(ctx, aggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, i := existing.GetIDP(idpConfigID); i != nil {
|
||||
return i, nil
|
||||
}
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-2m9fS", "Errors.IDP.NotExisting")
|
||||
func (i *IDPProvider) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*query2.IDP, error) {
|
||||
return i.queries.IDPByIDAndResourceOwner(ctx, idpConfigID, aggregateID)
|
||||
}
|
||||
|
||||
func (i *IDPProvider) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-6m0fS", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *IDPProvider) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *IDPProvider) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil {
|
||||
return existingIDP, nil
|
||||
}
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-49O0f", "Errors.IDP.NotExisting")
|
||||
func (u *IDPProvider) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*query2.IDP, error) {
|
||||
return u.queries.IDPByIDAndResourceOwner(ctx, idpConfigID, domain.IAMID)
|
||||
}
|
||||
|
@ -2,20 +2,18 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
query2 "github.com/caos/zitadel/internal/query"
|
||||
user_repo "github.com/caos/zitadel/internal/repository/user"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@ -29,15 +27,18 @@ type User struct {
|
||||
handler
|
||||
iamID string
|
||||
subscription *v1.Subscription
|
||||
queries *query2.Queries
|
||||
}
|
||||
|
||||
func newUser(
|
||||
handler handler,
|
||||
iamID string,
|
||||
queries *query2.Queries,
|
||||
) *User {
|
||||
h := &User{
|
||||
handler: handler,
|
||||
iamID: iamID,
|
||||
queries: queries,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -178,7 +179,7 @@ func (u *User) fillLoginNames(user *view_model.UserView) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
@ -210,7 +211,7 @@ func (u *User) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
@ -232,7 +233,7 @@ func (u *User) fillPreferredLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
@ -283,30 +284,6 @@ func (u *User) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, er
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *User) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *User) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3m9fs", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
func (u *User) getDefaultOrgIAMPolicy(ctx context.Context) (*query2.OrgIAMPolicy, error) {
|
||||
return u.queries.DefaultOrgIAMPolicy(ctx)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
@ -9,15 +10,12 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
query2 "github.com/caos/zitadel/internal/query"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
@ -30,15 +28,18 @@ type ExternalIDP struct {
|
||||
handler
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
subscription *v1.Subscription
|
||||
queries *query2.Queries
|
||||
}
|
||||
|
||||
func newExternalIDP(
|
||||
handler handler,
|
||||
defaults systemdefaults.SystemDefaults,
|
||||
queries *query2.Queries,
|
||||
) *ExternalIDP {
|
||||
h := &ExternalIDP{
|
||||
handler: handler,
|
||||
systemDefaults: defaults,
|
||||
queries: queries,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -125,7 +126,7 @@ func (i *ExternalIDP) processIdpConfig(event *es_models.Event) (err error) {
|
||||
switch event.Type {
|
||||
case iam_es_model.IDPConfigChanged, org_es_model.IDPConfigChanged:
|
||||
configView := new(iam_view_model.IDPConfigView)
|
||||
config := new(iam_model.IDPConfig)
|
||||
config := new(query2.IDP)
|
||||
if event.Type == iam_es_model.IDPConfigChanged {
|
||||
configView.AppendEvent(iam_model.IDPProviderTypeSystem, event)
|
||||
} else {
|
||||
@ -165,7 +166,7 @@ func (i *ExternalIDP) fillData(externalIDP *usr_view_model.ExternalIDPView) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) fillConfigData(externalIDP *usr_view_model.ExternalIDPView, config *iam_model.IDPConfig) {
|
||||
func (i *ExternalIDP) fillConfigData(externalIDP *usr_view_model.ExternalIDPView, config *query2.IDP) {
|
||||
externalIDP.IDPName = config.Name
|
||||
}
|
||||
|
||||
@ -178,63 +179,10 @@ func (i *ExternalIDP) OnSuccess() error {
|
||||
return spooler.HandleSuccess(i.view.UpdateExternalIDPSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := i.getOrgByID(ctx, aggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, i := existing.GetIDP(idpConfigID); i != nil {
|
||||
return i, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2m9fS", "Errors.Org.IdpNotExisting")
|
||||
func (i *ExternalIDP) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*query2.IDP, error) {
|
||||
return i.queries.IDPByIDAndResourceOwner(ctx, idpConfigID, aggregateID)
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-6m0fS", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *ExternalIDP) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *ExternalIDP) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil {
|
||||
return existingIDP, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-mmk5d", "Errors.IAM.IdpNotExisting")
|
||||
func (i *ExternalIDP) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*query2.IDP, error) {
|
||||
return i.queries.IDPByIDAndResourceOwner(ctx, idpConfigID, domain.IAMID)
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
|
||||
statikLoginFS, err := fs.NewWithNamespace("login")
|
||||
logging.Log("CONFI-20opp").OnError(err).Panic("unable to start login statik dir")
|
||||
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults)
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults, queries)
|
||||
|
||||
userRepo := eventstore.UserRepo{
|
||||
SearchLimit: conf.SearchLimit,
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"database/sql"
|
||||
|
||||
v1 "github.com/caos/zitadel/internal/eventstore/v1"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/handler"
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
@ -18,12 +19,12 @@ type SpoolerConfig struct {
|
||||
Handlers handler.Configs
|
||||
}
|
||||
|
||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, client *sql.DB, systemDefaults sd.SystemDefaults) *spooler.Spooler {
|
||||
func StartSpooler(c SpoolerConfig, es v1.Eventstore, view *view.View, client *sql.DB, systemDefaults sd.SystemDefaults, queries *query.Queries) *spooler.Spooler {
|
||||
spoolerConfig := spooler.Config{
|
||||
Eventstore: es,
|
||||
Locker: &locker{dbClient: client},
|
||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, systemDefaults),
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, systemDefaults, queries),
|
||||
}
|
||||
spool := spoolerConfig.New()
|
||||
spool.Start()
|
||||
|
@ -1,22 +0,0 @@
|
||||
package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
type IamRepo struct {
|
||||
IAMID string
|
||||
|
||||
IAMV2Query *query.Queries
|
||||
}
|
||||
|
||||
func (repo *IamRepo) Health(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *IamRepo) IamByID(ctx context.Context) (*model.IAM, error) {
|
||||
return repo.IAMV2Query.IAMByID(ctx, repo.IAMID)
|
||||
}
|
@ -27,7 +27,6 @@ type Config struct {
|
||||
type EsRepository struct {
|
||||
spooler *es_spol.Spooler
|
||||
eventstore.UserGrantRepo
|
||||
eventstore.IamRepo
|
||||
eventstore.TokenVerifierRepo
|
||||
}
|
||||
|
||||
@ -63,10 +62,6 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, qu
|
||||
Auth: authZ,
|
||||
Eventstore: es,
|
||||
},
|
||||
eventstore.IamRepo{
|
||||
IAMID: systemDefaults.IamID,
|
||||
IAMV2Query: queries,
|
||||
},
|
||||
eventstore.TokenVerifierRepo{
|
||||
TokenVerificationKey: keyAlgorithm,
|
||||
Eventstore: es,
|
||||
|
@ -1,11 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
type IAMRepository interface {
|
||||
Health(ctx context.Context) error
|
||||
IAMByID(ctx context.Context, id string) (*model.IAM, error)
|
||||
}
|
@ -7,5 +7,4 @@ import (
|
||||
type Repository interface {
|
||||
Health(context.Context) error
|
||||
UserGrantRepository
|
||||
IAMRepository
|
||||
}
|
||||
|
@ -24,45 +24,9 @@ const (
|
||||
|
||||
type IAM struct {
|
||||
es_models.ObjectRoot
|
||||
GlobalOrgID string
|
||||
IAMProjectID string
|
||||
SetUpDone domain.Step
|
||||
SetUpStarted domain.Step
|
||||
Members []*IAMMember
|
||||
IDPs []*IDPConfig
|
||||
DefaultLoginPolicy *LoginPolicy
|
||||
DefaultLabelPolicy *LabelPolicy
|
||||
DefaultOrgIAMPolicy *OrgIAMPolicy
|
||||
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy
|
||||
DefaultPasswordAgePolicy *PasswordAgePolicy
|
||||
DefaultLockoutPolicy *LockoutPolicy
|
||||
DefaultMailTemplate *MailTemplate
|
||||
DefaultMailTexts []*MailText
|
||||
}
|
||||
|
||||
func (iam *IAM) GetMember(userID string) (int, *IAMMember) {
|
||||
for i, m := range iam.Members {
|
||||
if m.UserID == userID {
|
||||
return i, m
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (iam *IAM) GetIDP(idpID string) (int, *IDPConfig) {
|
||||
for i, idp := range iam.IDPs {
|
||||
if idp.IDPConfigID == idpID {
|
||||
return i, idp
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (iam *IAM) GetDefaultMailText(mailTextType string, language string) (int, *MailText) {
|
||||
for i, m := range iam.DefaultMailTexts {
|
||||
if m.MailTextType == mailTextType && m.Language == language {
|
||||
return i, m
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
GlobalOrgID string
|
||||
IAMProjectID string
|
||||
SetUpDone domain.Step
|
||||
SetUpStarted domain.Step
|
||||
Members []*IAMMember
|
||||
}
|
||||
|
@ -24,53 +24,19 @@ const (
|
||||
|
||||
type IAM struct {
|
||||
es_models.ObjectRoot
|
||||
SetUpStarted Step `json:"-"`
|
||||
SetUpDone Step `json:"-"`
|
||||
GlobalOrgID string `json:"globalOrgId,omitempty"`
|
||||
IAMProjectID string `json:"iamProjectId,omitempty"`
|
||||
Members []*IAMMember `json:"-"`
|
||||
IDPs []*IDPConfig `json:"-"`
|
||||
DefaultLoginPolicy *LoginPolicy `json:"-"`
|
||||
DefaultLabelPolicy *LabelPolicy `json:"-"`
|
||||
DefaultMailTemplate *MailTemplate `json:"-"`
|
||||
DefaultOrgIAMPolicy *OrgIAMPolicy `json:"-"`
|
||||
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy `json:"-"`
|
||||
DefaultPasswordAgePolicy *PasswordAgePolicy `json:"-"`
|
||||
DefaultLockoutPolicy *LockoutPolicy `json:"-"`
|
||||
SetUpStarted Step `json:"-"`
|
||||
SetUpDone Step `json:"-"`
|
||||
GlobalOrgID string `json:"globalOrgId,omitempty"`
|
||||
IAMProjectID string `json:"iamProjectId,omitempty"`
|
||||
}
|
||||
|
||||
func IAMToModel(iam *IAM) *model.IAM {
|
||||
members := IAMMembersToModel(iam.Members)
|
||||
idps := IDPConfigsToModel(iam.IDPs)
|
||||
converted := &model.IAM{
|
||||
ObjectRoot: iam.ObjectRoot,
|
||||
SetUpStarted: domain.Step(iam.SetUpStarted),
|
||||
SetUpDone: domain.Step(iam.SetUpDone),
|
||||
GlobalOrgID: iam.GlobalOrgID,
|
||||
IAMProjectID: iam.IAMProjectID,
|
||||
Members: members,
|
||||
IDPs: idps,
|
||||
}
|
||||
if iam.DefaultLoginPolicy != nil {
|
||||
converted.DefaultLoginPolicy = LoginPolicyToModel(iam.DefaultLoginPolicy)
|
||||
}
|
||||
if iam.DefaultLabelPolicy != nil {
|
||||
converted.DefaultLabelPolicy = LabelPolicyToModel(iam.DefaultLabelPolicy)
|
||||
}
|
||||
if iam.DefaultMailTemplate != nil {
|
||||
converted.DefaultMailTemplate = MailTemplateToModel(iam.DefaultMailTemplate)
|
||||
}
|
||||
if iam.DefaultPasswordComplexityPolicy != nil {
|
||||
converted.DefaultPasswordComplexityPolicy = PasswordComplexityPolicyToModel(iam.DefaultPasswordComplexityPolicy)
|
||||
}
|
||||
if iam.DefaultPasswordAgePolicy != nil {
|
||||
converted.DefaultPasswordAgePolicy = PasswordAgePolicyToModel(iam.DefaultPasswordAgePolicy)
|
||||
}
|
||||
if iam.DefaultLockoutPolicy != nil {
|
||||
converted.DefaultLockoutPolicy = LockoutPolicyToModel(iam.DefaultLockoutPolicy)
|
||||
}
|
||||
if iam.DefaultOrgIAMPolicy != nil {
|
||||
converted.DefaultOrgIAMPolicy = OrgIAMPolicyToModel(iam.DefaultOrgIAMPolicy)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
@ -112,68 +78,6 @@ func (i *IAM) AppendEvent(event *es_models.Event) (err error) {
|
||||
case IAMProjectSet,
|
||||
GlobalOrgSet:
|
||||
err = i.SetData(event)
|
||||
case IAMMemberAdded:
|
||||
err = i.appendAddMemberEvent(event)
|
||||
case IAMMemberChanged:
|
||||
err = i.appendChangeMemberEvent(event)
|
||||
case IAMMemberRemoved:
|
||||
err = i.appendRemoveMemberEvent(event)
|
||||
case IAMMemberCascadeRemoved:
|
||||
err = i.appendRemoveMemberEvent(event)
|
||||
case IDPConfigAdded:
|
||||
return i.appendAddIDPConfigEvent(event)
|
||||
case IDPConfigChanged:
|
||||
return i.appendChangeIDPConfigEvent(event)
|
||||
case IDPConfigRemoved:
|
||||
return i.appendRemoveIDPConfigEvent(event)
|
||||
case IDPConfigDeactivated:
|
||||
return i.appendIDPConfigStateEvent(event, model.IDPConfigStateInactive)
|
||||
case IDPConfigReactivated:
|
||||
return i.appendIDPConfigStateEvent(event, model.IDPConfigStateActive)
|
||||
case OIDCIDPConfigAdded:
|
||||
return i.appendAddOIDCIDPConfigEvent(event)
|
||||
case OIDCIDPConfigChanged:
|
||||
return i.appendChangeOIDCIDPConfigEvent(event)
|
||||
case LoginPolicyAdded:
|
||||
return i.appendAddLoginPolicyEvent(event)
|
||||
case LoginPolicyChanged:
|
||||
return i.appendChangeLoginPolicyEvent(event)
|
||||
case LoginPolicyIDPProviderAdded:
|
||||
return i.appendAddIDPProviderToLoginPolicyEvent(event)
|
||||
case LoginPolicyIDPProviderRemoved:
|
||||
return i.appendRemoveIDPProviderFromLoginPolicyEvent(event)
|
||||
case LoginPolicySecondFactorAdded:
|
||||
return i.appendAddSecondFactorToLoginPolicyEvent(event)
|
||||
case LoginPolicySecondFactorRemoved:
|
||||
return i.appendRemoveSecondFactorFromLoginPolicyEvent(event)
|
||||
case LoginPolicyMultiFactorAdded:
|
||||
return i.appendAddMultiFactorToLoginPolicyEvent(event)
|
||||
case LoginPolicyMultiFactorRemoved:
|
||||
return i.appendRemoveMultiFactorFromLoginPolicyEvent(event)
|
||||
case LabelPolicyAdded:
|
||||
return i.appendAddLabelPolicyEvent(event)
|
||||
case LabelPolicyChanged:
|
||||
return i.appendChangeLabelPolicyEvent(event)
|
||||
case MailTemplateAdded:
|
||||
return i.appendAddMailTemplateEvent(event)
|
||||
case MailTemplateChanged:
|
||||
return i.appendChangeMailTemplateEvent(event)
|
||||
case PasswordComplexityPolicyAdded:
|
||||
return i.appendAddPasswordComplexityPolicyEvent(event)
|
||||
case PasswordComplexityPolicyChanged:
|
||||
return i.appendChangePasswordComplexityPolicyEvent(event)
|
||||
case PasswordAgePolicyAdded:
|
||||
return i.appendAddPasswordAgePolicyEvent(event)
|
||||
case PasswordAgePolicyChanged:
|
||||
return i.appendChangePasswordAgePolicyEvent(event)
|
||||
case LockoutPolicyAdded:
|
||||
return i.appendAddLockoutPolicyEvent(event)
|
||||
case LockoutPolicyChanged:
|
||||
return i.appendChangeLockoutPolicyEvent(event)
|
||||
case OrgIAMPolicyAdded:
|
||||
return i.appendAddOrgIAMPolicyEvent(event)
|
||||
case OrgIAMPolicyChanged:
|
||||
return i.appendChangeOrgIAMPolicyEvent(event)
|
||||
}
|
||||
|
||||
return err
|
||||
|
@ -2,9 +2,9 @@ package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/logging"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
type IAMMember struct {
|
||||
@ -13,84 +13,6 @@ type IAMMember struct {
|
||||
Roles []string `json:"roles,omitempty"`
|
||||
}
|
||||
|
||||
func GetIAMMember(members []*IAMMember, id string) (int, *IAMMember) {
|
||||
for i, m := range members {
|
||||
if m.UserID == id {
|
||||
return i, m
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func IAMMembersToModel(members []*IAMMember) []*model.IAMMember {
|
||||
convertedMembers := make([]*model.IAMMember, len(members))
|
||||
for i, m := range members {
|
||||
convertedMembers[i] = IAMMemberToModel(m)
|
||||
}
|
||||
return convertedMembers
|
||||
}
|
||||
|
||||
func IAMMembersFromModel(members []*model.IAMMember) []*IAMMember {
|
||||
convertedMembers := make([]*IAMMember, len(members))
|
||||
for i, m := range members {
|
||||
convertedMembers[i] = IAMMemberFromModel(m)
|
||||
}
|
||||
return convertedMembers
|
||||
}
|
||||
|
||||
func IAMMemberFromModel(member *model.IAMMember) *IAMMember {
|
||||
return &IAMMember{
|
||||
ObjectRoot: member.ObjectRoot,
|
||||
UserID: member.UserID,
|
||||
Roles: member.Roles,
|
||||
}
|
||||
}
|
||||
|
||||
func IAMMemberToModel(member *IAMMember) *model.IAMMember {
|
||||
return &model.IAMMember{
|
||||
ObjectRoot: member.ObjectRoot,
|
||||
UserID: member.UserID,
|
||||
Roles: member.Roles,
|
||||
}
|
||||
}
|
||||
|
||||
func (iam *IAM) appendAddMemberEvent(event *es_models.Event) error {
|
||||
member := &IAMMember{}
|
||||
err := member.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
member.ObjectRoot.CreationDate = event.CreationDate
|
||||
iam.Members = append(iam.Members, member)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendChangeMemberEvent(event *es_models.Event) error {
|
||||
member := &IAMMember{}
|
||||
err := member.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i, m := GetIAMMember(iam.Members, member.UserID); m != nil {
|
||||
iam.Members[i] = member
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendRemoveMemberEvent(event *es_models.Event) error {
|
||||
member := &IAMMember{}
|
||||
err := member.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i, m := GetIAMMember(iam.Members, member.UserID); m != nil {
|
||||
iam.Members[i] = iam.Members[len(iam.Members)-1]
|
||||
iam.Members[len(iam.Members)-1] = nil
|
||||
iam.Members = iam.Members[:len(iam.Members)-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IAMMember) SetData(event *es_models.Event) error {
|
||||
m.ObjectRoot.AppendEvent(event)
|
||||
if err := json.Unmarshal(event.Data, m); err != nil {
|
||||
|
@ -1,118 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAppendAddMemberEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
member *IAMMember
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add member event",
|
||||
args: args{
|
||||
iam: &IAM{},
|
||||
member: &IAMMember{UserID: "UserID", Roles: []string{"Role"}},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{Members: []*IAMMember{&IAMMember{UserID: "UserID", Roles: []string{"Role"}}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.member != nil {
|
||||
data, _ := json.Marshal(tt.args.member)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddMemberEvent(tt.args.event)
|
||||
if len(tt.args.iam.Members) != 1 {
|
||||
t.Errorf("got wrong result should have one member actual: %v ", len(tt.args.iam.Members))
|
||||
}
|
||||
if tt.args.iam.Members[0] == tt.result.Members[0] {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Members[0], tt.args.iam.Members[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangeMemberEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
member *IAMMember
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change member event",
|
||||
args: args{
|
||||
iam: &IAM{Members: []*IAMMember{&IAMMember{UserID: "UserID", Roles: []string{"Role"}}}},
|
||||
member: &IAMMember{UserID: "UserID", Roles: []string{"ChangedRole"}},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{Members: []*IAMMember{&IAMMember{UserID: "UserID", Roles: []string{"ChangedRole"}}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.member != nil {
|
||||
data, _ := json.Marshal(tt.args.member)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangeMemberEvent(tt.args.event)
|
||||
if len(tt.args.iam.Members) != 1 {
|
||||
t.Errorf("got wrong result should have one member actual: %v ", len(tt.args.iam.Members))
|
||||
}
|
||||
if tt.args.iam.Members[0] == tt.result.Members[0] {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Members[0], tt.args.iam.Members[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendRemoveMemberEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
member *IAMMember
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append remove member event",
|
||||
args: args{
|
||||
iam: &IAM{Members: []*IAMMember{&IAMMember{UserID: "UserID", Roles: []string{"Role"}}}},
|
||||
member: &IAMMember{UserID: "UserID"},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{Members: []*IAMMember{}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.member != nil {
|
||||
data, _ := json.Marshal(tt.args.member)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendRemoveMemberEvent(tt.args.event)
|
||||
if len(tt.args.iam.Members) != 0 {
|
||||
t.Errorf("got wrong result should have no member actual: %v ", len(tt.args.iam.Members))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/logging"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
@ -52,29 +53,6 @@ func IDPConfigsToModel(idps []*IDPConfig) []*model.IDPConfig {
|
||||
return convertedIDPConfigs
|
||||
}
|
||||
|
||||
func IDPConfigsFromModel(idps []*model.IDPConfig) []*IDPConfig {
|
||||
convertedIDPConfigs := make([]*IDPConfig, len(idps))
|
||||
for i, idp := range idps {
|
||||
convertedIDPConfigs[i] = IDPConfigFromModel(idp)
|
||||
}
|
||||
return convertedIDPConfigs
|
||||
}
|
||||
|
||||
func IDPConfigFromModel(idp *model.IDPConfig) *IDPConfig {
|
||||
converted := &IDPConfig{
|
||||
ObjectRoot: idp.ObjectRoot,
|
||||
IDPConfigID: idp.IDPConfigID,
|
||||
Name: idp.Name,
|
||||
State: int32(idp.State),
|
||||
Type: int32(idp.Type),
|
||||
StylingType: int32(idp.StylingType),
|
||||
}
|
||||
if idp.OIDCConfig != nil {
|
||||
converted.OIDCIDPConfig = OIDCIDPConfigFromModel(idp.OIDCConfig)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func IDPConfigToModel(idp *IDPConfig) *model.IDPConfig {
|
||||
converted := &model.IDPConfig{
|
||||
ObjectRoot: idp.ObjectRoot,
|
||||
@ -90,57 +68,6 @@ func IDPConfigToModel(idp *IDPConfig) *model.IDPConfig {
|
||||
return converted
|
||||
}
|
||||
|
||||
func (iam *IAM) appendAddIDPConfigEvent(event *es_models.Event) error {
|
||||
idp := new(IDPConfig)
|
||||
err := idp.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
idp.ObjectRoot.CreationDate = event.CreationDate
|
||||
iam.IDPs = append(iam.IDPs, idp)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendChangeIDPConfigEvent(event *es_models.Event) error {
|
||||
idp := new(IDPConfig)
|
||||
err := idp.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i, idpConfig := GetIDPConfig(iam.IDPs, idp.IDPConfigID); idpConfig != nil {
|
||||
iam.IDPs[i].SetData(event)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendRemoveIDPConfigEvent(event *es_models.Event) error {
|
||||
idp := new(IDPConfig)
|
||||
err := idp.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i, idpConfig := GetIDPConfig(iam.IDPs, idp.IDPConfigID); idpConfig != nil {
|
||||
iam.IDPs[i] = iam.IDPs[len(iam.IDPs)-1]
|
||||
iam.IDPs[len(iam.IDPs)-1] = nil
|
||||
iam.IDPs = iam.IDPs[:len(iam.IDPs)-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendIDPConfigStateEvent(event *es_models.Event, state model.IDPConfigState) error {
|
||||
idp := new(IDPConfig)
|
||||
err := idp.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if i, idpConfig := GetIDPConfig(iam.IDPs, idp.IDPConfigID); idpConfig != nil {
|
||||
idpConfig.State = int32(state)
|
||||
iam.IDPs[i] = idpConfig
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *IDPConfig) SetData(event *es_models.Event) error {
|
||||
c.ObjectRoot.AppendEvent(event)
|
||||
if err := json.Unmarshal(event.Data, c); err != nil {
|
||||
|
@ -1,9 +1,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -50,164 +47,3 @@ func TestIdpConfigChanges(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddIdpConfigEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
idp *IDPConfig
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add idp config event",
|
||||
args: args{
|
||||
iam: &IAM{},
|
||||
idp: &IDPConfig{Name: "IDPConfig"},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{IDPs: []*IDPConfig{&IDPConfig{Name: "IDPConfig"}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.idp != nil {
|
||||
data, _ := json.Marshal(tt.args.idp)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddIDPConfigEvent(tt.args.event)
|
||||
if len(tt.args.iam.IDPs) != 1 {
|
||||
t.Errorf("got wrong result should have one idpConfig actual: %v ", len(tt.args.iam.IDPs))
|
||||
}
|
||||
if tt.args.iam.IDPs[0] == tt.result.IDPs[0] {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.IDPs[0], tt.args.iam.IDPs[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangeIdpConfigEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
idpConfig *IDPConfig
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change idp config event",
|
||||
args: args{
|
||||
iam: &IAM{IDPs: []*IDPConfig{&IDPConfig{Name: "IDPConfig"}}},
|
||||
idpConfig: &IDPConfig{Name: "IDPConfig Change"},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{IDPs: []*IDPConfig{&IDPConfig{Name: "IDPConfig Change"}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.idpConfig != nil {
|
||||
data, _ := json.Marshal(tt.args.idpConfig)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangeIDPConfigEvent(tt.args.event)
|
||||
if len(tt.args.iam.IDPs) != 1 {
|
||||
t.Errorf("got wrong result should have one idpConfig actual: %v ", len(tt.args.iam.IDPs))
|
||||
}
|
||||
if tt.args.iam.IDPs[0] == tt.result.IDPs[0] {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.IDPs[0], tt.args.iam.IDPs[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendRemoveIDPEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
idp *IDPConfig
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append remove idp config event",
|
||||
args: args{
|
||||
iam: &IAM{IDPs: []*IDPConfig{&IDPConfig{IDPConfigID: "IDPConfigID", Name: "IDPConfig"}}},
|
||||
idp: &IDPConfig{IDPConfigID: "IDPConfigID", Name: "IDPConfig"},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{IDPs: []*IDPConfig{}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.idp != nil {
|
||||
data, _ := json.Marshal(tt.args.idp)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendRemoveIDPConfigEvent(tt.args.event)
|
||||
if len(tt.args.iam.IDPs) != 0 {
|
||||
t.Errorf("got wrong result should have no apps actual: %v ", len(tt.args.iam.IDPs))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAppStateEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
idp *IDPConfig
|
||||
event *es_models.Event
|
||||
state model.IDPConfigState
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append deactivate application event",
|
||||
args: args{
|
||||
iam: &IAM{IDPs: []*IDPConfig{&IDPConfig{IDPConfigID: "IDPConfigID", Name: "IDPConfig", State: int32(model.IDPConfigStateActive)}}},
|
||||
idp: &IDPConfig{IDPConfigID: "IDPConfigID"},
|
||||
event: &es_models.Event{},
|
||||
state: model.IDPConfigStateInactive,
|
||||
},
|
||||
result: &IAM{IDPs: []*IDPConfig{&IDPConfig{IDPConfigID: "IDPConfigID", Name: "IDPConfig", State: int32(model.IDPConfigStateInactive)}}},
|
||||
},
|
||||
{
|
||||
name: "append reactivate application event",
|
||||
args: args{
|
||||
iam: &IAM{IDPs: []*IDPConfig{&IDPConfig{IDPConfigID: "IDPConfigID", Name: "IDPConfig", State: int32(model.IDPConfigStateInactive)}}},
|
||||
idp: &IDPConfig{IDPConfigID: "IDPConfigID"},
|
||||
event: &es_models.Event{},
|
||||
state: model.IDPConfigStateActive,
|
||||
},
|
||||
result: &IAM{IDPs: []*IDPConfig{&IDPConfig{IDPConfigID: "IDPConfigID", Name: "IDPConfig", State: int32(model.IDPConfigStateActive)}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.idp != nil {
|
||||
data, _ := json.Marshal(tt.args.idp)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendIDPConfigStateEvent(tt.args.event, tt.args.state)
|
||||
if len(tt.args.iam.IDPs) != 1 {
|
||||
t.Errorf("got wrong result should have one idpConfig actual: %v ", len(tt.args.iam.IDPs))
|
||||
}
|
||||
if tt.args.iam.IDPs[0] == tt.result.IDPs[0] {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.IDPs[0], tt.args.iam.IDPs[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -38,20 +38,6 @@ func LabelPolicyToModel(policy *LabelPolicy) *iam_model.LabelPolicy {
|
||||
}
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddLabelPolicyEvent(event *es_models.Event) error {
|
||||
i.DefaultLabelPolicy = new(LabelPolicy)
|
||||
err := i.DefaultLabelPolicy.SetDataLabel(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultLabelPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangeLabelPolicyEvent(event *es_models.Event) error {
|
||||
return i.DefaultLabelPolicy.SetDataLabel(event)
|
||||
}
|
||||
|
||||
func (p *LabelPolicy) SetDataLabel(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
|
@ -1,88 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
)
|
||||
|
||||
func TestAppendAddLabelPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *LabelPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add label policy event",
|
||||
args: args{
|
||||
iam: new(IAM),
|
||||
policy: &LabelPolicy{PrimaryColor: "000000", BackgroundColor: "FFFFFF"},
|
||||
event: new(es_models.Event),
|
||||
},
|
||||
result: &IAM{DefaultLabelPolicy: &LabelPolicy{PrimaryColor: "000000", BackgroundColor: "FFFFFF"}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddLabelPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLabelPolicy.PrimaryColor != tt.args.iam.DefaultLabelPolicy.PrimaryColor {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLabelPolicy.PrimaryColor, tt.args.iam.DefaultLabelPolicy.PrimaryColor)
|
||||
}
|
||||
if tt.result.DefaultLabelPolicy.BackgroundColor != tt.args.iam.DefaultLabelPolicy.BackgroundColor {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLabelPolicy.BackgroundColor, tt.args.iam.DefaultLabelPolicy.BackgroundColor)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangeLabelPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *LabelPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change label policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultLabelPolicy: &LabelPolicy{
|
||||
PrimaryColor: "000001", BackgroundColor: "FFFFF0",
|
||||
}},
|
||||
policy: &LabelPolicy{PrimaryColor: "000000", BackgroundColor: "FFFFFF"},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultLabelPolicy: &LabelPolicy{
|
||||
PrimaryColor: "000000", BackgroundColor: "FFFFFF",
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangeLabelPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLabelPolicy.PrimaryColor != tt.args.iam.DefaultLabelPolicy.PrimaryColor {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLabelPolicy.PrimaryColor, tt.args.iam.DefaultLabelPolicy.PrimaryColor)
|
||||
}
|
||||
if tt.result.DefaultLabelPolicy.BackgroundColor != tt.args.iam.DefaultLabelPolicy.BackgroundColor {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLabelPolicy.BackgroundColor, tt.args.iam.DefaultLabelPolicy.BackgroundColor)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -37,20 +37,6 @@ func (p *LockoutPolicy) Changes(changed *LockoutPolicy) map[string]interface{} {
|
||||
return changes
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddLockoutPolicyEvent(event *es_models.Event) error {
|
||||
i.DefaultLockoutPolicy = new(LockoutPolicy)
|
||||
err := i.DefaultLockoutPolicy.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultLockoutPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangeLockoutPolicyEvent(event *es_models.Event) error {
|
||||
return i.DefaultLockoutPolicy.SetData(event)
|
||||
}
|
||||
|
||||
func (p *LockoutPolicy) SetData(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
|
@ -1,8 +1,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -49,80 +47,3 @@ func TestPasswordLockoutPolicyChanges(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddPasswordLockoutPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *LockoutPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add password lockout policy event",
|
||||
args: args{
|
||||
iam: new(IAM),
|
||||
policy: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true},
|
||||
event: new(es_models.Event),
|
||||
},
|
||||
result: &IAM{DefaultLockoutPolicy: &LockoutPolicy{MaxPasswordAttempts: 10, ShowLockOutFailures: true}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLockoutPolicy.MaxPasswordAttempts != tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLockoutPolicy.MaxPasswordAttempts, tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts)
|
||||
}
|
||||
if tt.result.DefaultLockoutPolicy.ShowLockOutFailures != tt.args.iam.DefaultLockoutPolicy.ShowLockOutFailures {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLockoutPolicy.ShowLockOutFailures, tt.args.iam.DefaultLockoutPolicy.ShowLockOutFailures)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangePasswordLockoutPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *LockoutPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change password lockout policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultLockoutPolicy: &LockoutPolicy{
|
||||
MaxPasswordAttempts: 10,
|
||||
}},
|
||||
policy: &LockoutPolicy{MaxPasswordAttempts: 5},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultLockoutPolicy: &LockoutPolicy{
|
||||
MaxPasswordAttempts: 5,
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangeLockoutPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLockoutPolicy.MaxPasswordAttempts != tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLockoutPolicy.MaxPasswordAttempts, tt.args.iam.DefaultLockoutPolicy.MaxPasswordAttempts)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -79,14 +79,6 @@ func IDPProvidersToModel(members []*IDPProvider) []*iam_model.IDPProvider {
|
||||
return convertedProviders
|
||||
}
|
||||
|
||||
func IDOProvidersFromModel(members []*iam_model.IDPProvider) []*IDPProvider {
|
||||
convertedProviders := make([]*IDPProvider, len(members))
|
||||
for i, m := range members {
|
||||
convertedProviders[i] = IDPProviderFromModel(m)
|
||||
}
|
||||
return convertedProviders
|
||||
}
|
||||
|
||||
func IDPProviderToModel(provider *IDPProvider) *iam_model.IDPProvider {
|
||||
return &iam_model.IDPProvider{
|
||||
ObjectRoot: provider.ObjectRoot,
|
||||
@ -95,26 +87,6 @@ func IDPProviderToModel(provider *IDPProvider) *iam_model.IDPProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func IDPProviderFromModel(provider *iam_model.IDPProvider) *IDPProvider {
|
||||
return &IDPProvider{
|
||||
ObjectRoot: provider.ObjectRoot,
|
||||
Type: int32(provider.Type),
|
||||
IDPConfigID: provider.IDPConfigID,
|
||||
}
|
||||
}
|
||||
|
||||
func SecondFactorsFromModel(mfas []domain.SecondFactorType) []int32 {
|
||||
convertedMFAs := make([]int32, len(mfas))
|
||||
for i, mfa := range mfas {
|
||||
convertedMFAs[i] = int32(mfa)
|
||||
}
|
||||
return convertedMFAs
|
||||
}
|
||||
|
||||
func SecondFactorFromModel(mfa domain.SecondFactorType) *MFA {
|
||||
return &MFA{MFAType: int32(mfa)}
|
||||
}
|
||||
|
||||
func SecondFactorsToModel(mfas []int32) []domain.SecondFactorType {
|
||||
convertedMFAs := make([]domain.SecondFactorType, len(mfas))
|
||||
for i, mfa := range mfas {
|
||||
@ -123,18 +95,6 @@ func SecondFactorsToModel(mfas []int32) []domain.SecondFactorType {
|
||||
return convertedMFAs
|
||||
}
|
||||
|
||||
func MultiFactorsFromModel(mfas []iam_model.MultiFactorType) []int32 {
|
||||
convertedMFAs := make([]int32, len(mfas))
|
||||
for i, mfa := range mfas {
|
||||
convertedMFAs[i] = int32(mfa)
|
||||
}
|
||||
return convertedMFAs
|
||||
}
|
||||
|
||||
func MultiFactorFromModel(mfa iam_model.MultiFactorType) *MFA {
|
||||
return &MFA{MFAType: int32(mfa)}
|
||||
}
|
||||
|
||||
func MultiFactorsToModel(mfas []int32) []domain.MultiFactorType {
|
||||
convertedMFAs := make([]domain.MultiFactorType, len(mfas))
|
||||
for i, mfa := range mfas {
|
||||
@ -164,96 +124,6 @@ func (p *LoginPolicy) Changes(changed *LoginPolicy) map[string]interface{} {
|
||||
return changes
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddLoginPolicyEvent(event *es_models.Event) error {
|
||||
i.DefaultLoginPolicy = new(LoginPolicy)
|
||||
err := i.DefaultLoginPolicy.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultLoginPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangeLoginPolicyEvent(event *es_models.Event) error {
|
||||
return i.DefaultLoginPolicy.SetData(event)
|
||||
}
|
||||
|
||||
func (iam *IAM) appendAddIDPProviderToLoginPolicyEvent(event *es_models.Event) error {
|
||||
provider := new(IDPProvider)
|
||||
err := provider.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
provider.ObjectRoot.CreationDate = event.CreationDate
|
||||
iam.DefaultLoginPolicy.IDPProviders = append(iam.DefaultLoginPolicy.IDPProviders, provider)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendRemoveIDPProviderFromLoginPolicyEvent(event *es_models.Event) error {
|
||||
provider := new(IDPProvider)
|
||||
err := provider.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i, m := GetIDPProvider(iam.DefaultLoginPolicy.IDPProviders, provider.IDPConfigID); m != nil {
|
||||
iam.DefaultLoginPolicy.IDPProviders[i] = iam.DefaultLoginPolicy.IDPProviders[len(iam.DefaultLoginPolicy.IDPProviders)-1]
|
||||
iam.DefaultLoginPolicy.IDPProviders[len(iam.DefaultLoginPolicy.IDPProviders)-1] = nil
|
||||
iam.DefaultLoginPolicy.IDPProviders = iam.DefaultLoginPolicy.IDPProviders[:len(iam.DefaultLoginPolicy.IDPProviders)-1]
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendAddSecondFactorToLoginPolicyEvent(event *es_models.Event) error {
|
||||
mfa := new(MFA)
|
||||
err := mfa.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iam.DefaultLoginPolicy.SecondFactors = append(iam.DefaultLoginPolicy.SecondFactors, mfa.MFAType)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendRemoveSecondFactorFromLoginPolicyEvent(event *es_models.Event) error {
|
||||
mfa := new(MFA)
|
||||
err := mfa.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i, m := GetMFA(iam.DefaultLoginPolicy.SecondFactors, mfa.MFAType); m != 0 {
|
||||
iam.DefaultLoginPolicy.SecondFactors[i] = iam.DefaultLoginPolicy.SecondFactors[len(iam.DefaultLoginPolicy.SecondFactors)-1]
|
||||
iam.DefaultLoginPolicy.SecondFactors[len(iam.DefaultLoginPolicy.SecondFactors)-1] = 0
|
||||
iam.DefaultLoginPolicy.SecondFactors = iam.DefaultLoginPolicy.SecondFactors[:len(iam.DefaultLoginPolicy.SecondFactors)-1]
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendAddMultiFactorToLoginPolicyEvent(event *es_models.Event) error {
|
||||
mfa := new(MFA)
|
||||
err := mfa.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iam.DefaultLoginPolicy.MultiFactors = append(iam.DefaultLoginPolicy.MultiFactors, mfa.MFAType)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendRemoveMultiFactorFromLoginPolicyEvent(event *es_models.Event) error {
|
||||
mfa := new(MFA)
|
||||
err := mfa.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i, m := GetMFA(iam.DefaultLoginPolicy.MultiFactors, mfa.MFAType); m != 0 {
|
||||
iam.DefaultLoginPolicy.MultiFactors[i] = iam.DefaultLoginPolicy.MultiFactors[len(iam.DefaultLoginPolicy.MultiFactors)-1]
|
||||
iam.DefaultLoginPolicy.MultiFactors[len(iam.DefaultLoginPolicy.MultiFactors)-1] = 0
|
||||
iam.DefaultLoginPolicy.MultiFactors = iam.DefaultLoginPolicy.MultiFactors[:len(iam.DefaultLoginPolicy.MultiFactors)-1]
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *LoginPolicy) SetData(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
|
@ -1,431 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
func TestLoginPolicyChanges(t *testing.T) {
|
||||
type args struct {
|
||||
existing *LoginPolicy
|
||||
new *LoginPolicy
|
||||
}
|
||||
type res struct {
|
||||
changesLen int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "loginpolicy all attributes change",
|
||||
args: args{
|
||||
existing: &LoginPolicy{AllowUsernamePassword: false, AllowRegister: false, AllowExternalIdp: false, ForceMFA: false},
|
||||
new: &LoginPolicy{AllowUsernamePassword: true, AllowRegister: true, AllowExternalIdp: true, ForceMFA: true},
|
||||
},
|
||||
res: res{
|
||||
changesLen: 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no changes",
|
||||
args: args{
|
||||
existing: &LoginPolicy{AllowUsernamePassword: false, AllowRegister: false, AllowExternalIdp: false, ForceMFA: false},
|
||||
new: &LoginPolicy{AllowUsernamePassword: false, AllowRegister: false, AllowExternalIdp: false, ForceMFA: false},
|
||||
},
|
||||
res: res{
|
||||
changesLen: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
changes := tt.args.existing.Changes(tt.args.new)
|
||||
if len(changes) != tt.res.changesLen {
|
||||
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddLoginPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *LoginPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add login policy event",
|
||||
args: args{
|
||||
iam: new(IAM),
|
||||
policy: &LoginPolicy{AllowUsernamePassword: true, AllowRegister: true, AllowExternalIdp: true, ForceMFA: true},
|
||||
event: new(es_models.Event),
|
||||
},
|
||||
result: &IAM{DefaultLoginPolicy: &LoginPolicy{AllowUsernamePassword: true, AllowRegister: true, AllowExternalIdp: true, ForceMFA: true}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddLoginPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLoginPolicy.AllowUsernamePassword != tt.args.iam.DefaultLoginPolicy.AllowUsernamePassword {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowUsernamePassword, tt.args.iam.DefaultLoginPolicy.AllowUsernamePassword)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.AllowRegister != tt.args.iam.DefaultLoginPolicy.AllowRegister {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowRegister, tt.args.iam.DefaultLoginPolicy.AllowRegister)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.AllowExternalIdp != tt.args.iam.DefaultLoginPolicy.AllowExternalIdp {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowExternalIdp, tt.args.iam.DefaultLoginPolicy.AllowExternalIdp)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.ForceMFA != tt.args.iam.DefaultLoginPolicy.ForceMFA {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.ForceMFA, tt.args.iam.DefaultLoginPolicy.ForceMFA)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangeLoginPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *LoginPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change login policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultLoginPolicy: &LoginPolicy{
|
||||
AllowExternalIdp: false,
|
||||
AllowRegister: false,
|
||||
AllowUsernamePassword: false,
|
||||
ForceMFA: false,
|
||||
}},
|
||||
policy: &LoginPolicy{AllowUsernamePassword: true, AllowRegister: true, AllowExternalIdp: true, ForceMFA: true},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultLoginPolicy: &LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
ForceMFA: true,
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangeLoginPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLoginPolicy.AllowUsernamePassword != tt.args.iam.DefaultLoginPolicy.AllowUsernamePassword {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowUsernamePassword, tt.args.iam.DefaultLoginPolicy.AllowUsernamePassword)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.AllowRegister != tt.args.iam.DefaultLoginPolicy.AllowRegister {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowRegister, tt.args.iam.DefaultLoginPolicy.AllowRegister)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.AllowExternalIdp != tt.args.iam.DefaultLoginPolicy.AllowExternalIdp {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowExternalIdp, tt.args.iam.DefaultLoginPolicy.AllowExternalIdp)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.ForceMFA != tt.args.iam.DefaultLoginPolicy.ForceMFA {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.ForceMFA, tt.args.iam.DefaultLoginPolicy.ForceMFA)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddIdpToPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
provider *IDPProvider
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add idp to login policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultLoginPolicy: &LoginPolicy{AllowExternalIdp: true, AllowRegister: true, AllowUsernamePassword: true}},
|
||||
provider: &IDPProvider{Type: int32(model.IDPProviderTypeSystem), IDPConfigID: "IDPConfigID"},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultLoginPolicy: &LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
IDPProviders: []*IDPProvider{
|
||||
{IDPConfigID: "IDPConfigID", Type: int32(model.IDPProviderTypeSystem)},
|
||||
}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.provider != nil {
|
||||
data, _ := json.Marshal(tt.args.provider)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddIDPProviderToLoginPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLoginPolicy.AllowUsernamePassword != tt.args.iam.DefaultLoginPolicy.AllowUsernamePassword {
|
||||
t.Errorf("got wrong result AllowUsernamePassword: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowUsernamePassword, tt.args.iam.DefaultLoginPolicy.AllowUsernamePassword)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.AllowRegister != tt.args.iam.DefaultLoginPolicy.AllowRegister {
|
||||
t.Errorf("got wrong result AllowRegister: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowRegister, tt.args.iam.DefaultLoginPolicy.AllowRegister)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.AllowExternalIdp != tt.args.iam.DefaultLoginPolicy.AllowExternalIdp {
|
||||
t.Errorf("got wrong result AllowExternalIDP: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowExternalIdp, tt.args.iam.DefaultLoginPolicy.AllowExternalIdp)
|
||||
}
|
||||
if len(tt.result.DefaultLoginPolicy.IDPProviders) != len(tt.args.iam.DefaultLoginPolicy.IDPProviders) {
|
||||
t.Errorf("got wrong idp provider len: expected: %v, actual: %v ", len(tt.result.DefaultLoginPolicy.IDPProviders), len(tt.args.iam.DefaultLoginPolicy.IDPProviders))
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.IDPProviders[0].Type != tt.args.provider.Type {
|
||||
t.Errorf("got wrong idp provider type: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.IDPProviders[0].Type, tt.args.provider.Type)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.IDPProviders[0].IDPConfigID != tt.args.provider.IDPConfigID {
|
||||
t.Errorf("got wrong idp provider idpconfigid: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.IDPProviders[0].IDPConfigID, tt.args.provider.IDPConfigID)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveIdpToPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
provider *IDPProvider
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add idp to login policy event",
|
||||
args: args{
|
||||
iam: &IAM{
|
||||
DefaultLoginPolicy: &LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
IDPProviders: []*IDPProvider{
|
||||
{IDPConfigID: "IDPConfigID", Type: int32(model.IDPProviderTypeSystem)},
|
||||
}}},
|
||||
provider: &IDPProvider{Type: int32(model.IDPProviderTypeSystem), IDPConfigID: "IDPConfigID"},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultLoginPolicy: &LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
IDPProviders: []*IDPProvider{}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.provider != nil {
|
||||
data, _ := json.Marshal(tt.args.provider)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendRemoveIDPProviderFromLoginPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultLoginPolicy.AllowUsernamePassword != tt.args.iam.DefaultLoginPolicy.AllowUsernamePassword {
|
||||
t.Errorf("got wrong result AllowUsernamePassword: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowUsernamePassword, tt.args.iam.DefaultLoginPolicy.AllowUsernamePassword)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.AllowRegister != tt.args.iam.DefaultLoginPolicy.AllowRegister {
|
||||
t.Errorf("got wrong result AllowRegister: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowRegister, tt.args.iam.DefaultLoginPolicy.AllowRegister)
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.AllowExternalIdp != tt.args.iam.DefaultLoginPolicy.AllowExternalIdp {
|
||||
t.Errorf("got wrong result AllowExternalIDP: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.AllowExternalIdp, tt.args.iam.DefaultLoginPolicy.AllowExternalIdp)
|
||||
}
|
||||
if len(tt.result.DefaultLoginPolicy.IDPProviders) != len(tt.args.iam.DefaultLoginPolicy.IDPProviders) {
|
||||
t.Errorf("got wrong idp provider len: expected: %v, actual: %v ", len(tt.result.DefaultLoginPolicy.IDPProviders), len(tt.args.iam.DefaultLoginPolicy.IDPProviders))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddSecondFactorToPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
mfa *MFA
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add second factor to login policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultLoginPolicy: &LoginPolicy{AllowExternalIdp: true, AllowRegister: true, AllowUsernamePassword: true}},
|
||||
mfa: &MFA{MFAType: int32(domain.SecondFactorTypeOTP)},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultLoginPolicy: &LoginPolicy{
|
||||
SecondFactors: []int32{
|
||||
int32(domain.SecondFactorTypeOTP),
|
||||
}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.mfa != nil {
|
||||
data, _ := json.Marshal(tt.args.mfa)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddSecondFactorToLoginPolicyEvent(tt.args.event)
|
||||
if len(tt.result.DefaultLoginPolicy.SecondFactors) != len(tt.args.iam.DefaultLoginPolicy.SecondFactors) {
|
||||
t.Errorf("got wrong second factors len: expected: %v, actual: %v ", len(tt.result.DefaultLoginPolicy.SecondFactors), len(tt.args.iam.DefaultLoginPolicy.SecondFactors))
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.SecondFactors[0] != tt.args.mfa.MFAType {
|
||||
t.Errorf("got wrong second factor: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.SecondFactors[0], tt.args.mfa)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveSecondFactorToPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
mfa *MFA
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append remove second factor to login policy event",
|
||||
args: args{
|
||||
iam: &IAM{
|
||||
DefaultLoginPolicy: &LoginPolicy{
|
||||
SecondFactors: []int32{
|
||||
int32(domain.SecondFactorTypeOTP),
|
||||
}}},
|
||||
mfa: &MFA{MFAType: int32(domain.SecondFactorTypeOTP)},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultLoginPolicy: &LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
SecondFactors: []int32{}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.mfa != nil {
|
||||
data, _ := json.Marshal(tt.args.mfa)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendRemoveSecondFactorFromLoginPolicyEvent(tt.args.event)
|
||||
if len(tt.result.DefaultLoginPolicy.SecondFactors) != len(tt.args.iam.DefaultLoginPolicy.SecondFactors) {
|
||||
t.Errorf("got wrong second factor len: expected: %v, actual: %v ", len(tt.result.DefaultLoginPolicy.SecondFactors), len(tt.args.iam.DefaultLoginPolicy.SecondFactors))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddMultiFactorToPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
mfa *MFA
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add mfa to login policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultLoginPolicy: &LoginPolicy{AllowExternalIdp: true, AllowRegister: true, AllowUsernamePassword: true}},
|
||||
mfa: &MFA{MFAType: int32(model.MultiFactorTypeU2FWithPIN)},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultLoginPolicy: &LoginPolicy{
|
||||
MultiFactors: []int32{
|
||||
int32(model.MultiFactorTypeU2FWithPIN),
|
||||
}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.mfa != nil {
|
||||
data, _ := json.Marshal(tt.args.mfa)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddMultiFactorToLoginPolicyEvent(tt.args.event)
|
||||
if len(tt.result.DefaultLoginPolicy.MultiFactors) != len(tt.args.iam.DefaultLoginPolicy.MultiFactors) {
|
||||
t.Errorf("got wrong mfas len: expected: %v, actual: %v ", len(tt.result.DefaultLoginPolicy.MultiFactors), len(tt.args.iam.DefaultLoginPolicy.MultiFactors))
|
||||
}
|
||||
if tt.result.DefaultLoginPolicy.MultiFactors[0] != tt.args.mfa.MFAType {
|
||||
t.Errorf("got wrong mfa: expected: %v, actual: %v ", tt.result.DefaultLoginPolicy.MultiFactors[0], tt.args.mfa)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveMultiFactorToPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
mfa *MFA
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append remove mfa to login policy event",
|
||||
args: args{
|
||||
iam: &IAM{
|
||||
DefaultLoginPolicy: &LoginPolicy{
|
||||
MultiFactors: []int32{
|
||||
int32(model.MultiFactorTypeU2FWithPIN),
|
||||
}}},
|
||||
mfa: &MFA{MFAType: int32(model.MultiFactorTypeU2FWithPIN)},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultLoginPolicy: &LoginPolicy{
|
||||
AllowExternalIdp: true,
|
||||
AllowRegister: true,
|
||||
AllowUsernamePassword: true,
|
||||
MultiFactors: []int32{}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.mfa != nil {
|
||||
data, _ := json.Marshal(tt.args.mfa)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendRemoveMultiFactorFromLoginPolicyEvent(tt.args.event)
|
||||
if len(tt.result.DefaultLoginPolicy.MultiFactors) != len(tt.args.iam.DefaultLoginPolicy.MultiFactors) {
|
||||
t.Errorf("got wrong mfa len: expected: %v, actual: %v ", len(tt.result.DefaultLoginPolicy.MultiFactors), len(tt.args.iam.DefaultLoginPolicy.MultiFactors))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -23,14 +23,6 @@ func MailTemplateToModel(template *MailTemplate) *iam_model.MailTemplate {
|
||||
}
|
||||
}
|
||||
|
||||
func MailTemplateFromModel(template *iam_model.MailTemplate) *MailTemplate {
|
||||
return &MailTemplate{
|
||||
ObjectRoot: template.ObjectRoot,
|
||||
State: int32(template.State),
|
||||
Template: template.Template,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *MailTemplate) Changes(changed *MailTemplate) map[string]interface{} {
|
||||
changes := make(map[string]interface{}, 1)
|
||||
if b64.StdEncoding.EncodeToString(changed.Template) != b64.StdEncoding.EncodeToString(p.Template) {
|
||||
@ -40,20 +32,6 @@ func (p *MailTemplate) Changes(changed *MailTemplate) map[string]interface{} {
|
||||
return changes
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddMailTemplateEvent(event *es_models.Event) error {
|
||||
i.DefaultMailTemplate = new(MailTemplate)
|
||||
err := i.DefaultMailTemplate.SetDataLabel(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultMailTemplate.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangeMailTemplateEvent(event *es_models.Event) error {
|
||||
return i.DefaultMailTemplate.SetDataLabel(event)
|
||||
}
|
||||
|
||||
func (p *MailTemplate) SetDataLabel(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
|
@ -1,10 +1,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
)
|
||||
|
||||
func TestMailTemplateChanges(t *testing.T) {
|
||||
@ -50,77 +47,3 @@ func TestMailTemplateChanges(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddMailTemplateEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *MailTemplate
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add label policy event",
|
||||
args: args{
|
||||
iam: new(IAM),
|
||||
policy: &MailTemplate{Template: []byte("<!doctype html>")},
|
||||
event: new(es_models.Event),
|
||||
},
|
||||
result: &IAM{DefaultMailTemplate: &MailTemplate{Template: []byte("<!doctype html>")}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddMailTemplateEvent(tt.args.event)
|
||||
if string(tt.result.DefaultMailTemplate.Template) != string(tt.args.iam.DefaultMailTemplate.Template) {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTemplate.Template, tt.args.iam.DefaultMailTemplate.Template)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangeMailTemplateEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *MailTemplate
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change label policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultMailTemplate: &MailTemplate{
|
||||
Template: []byte("<doctype html>"),
|
||||
}},
|
||||
policy: &MailTemplate{Template: []byte("<!doctype html>")},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultMailTemplate: &MailTemplate{
|
||||
Template: []byte("<!doctype html>"),
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangeMailTemplateEvent(tt.args.event)
|
||||
if string(tt.result.DefaultMailTemplate.Template) != string(tt.args.iam.DefaultMailTemplate.Template) {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultMailTemplate.Template, tt.args.iam.DefaultMailTemplate.Template)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,13 @@ package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/lib/pq"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type OIDCIDPConfig struct {
|
||||
@ -45,19 +46,6 @@ func (c *OIDCIDPConfig) Changes(changed *OIDCIDPConfig) map[string]interface{} {
|
||||
return changes
|
||||
}
|
||||
|
||||
func OIDCIDPConfigFromModel(config *model.OIDCIDPConfig) *OIDCIDPConfig {
|
||||
return &OIDCIDPConfig{
|
||||
ObjectRoot: config.ObjectRoot,
|
||||
IDPConfigID: config.IDPConfigID,
|
||||
ClientID: config.ClientID,
|
||||
ClientSecret: config.ClientSecret,
|
||||
Issuer: config.Issuer,
|
||||
Scopes: config.Scopes,
|
||||
IDPDisplayNameMapping: int32(config.IDPDisplayNameMapping),
|
||||
UsernameMapping: int32(config.UsernameMapping),
|
||||
}
|
||||
}
|
||||
|
||||
func OIDCIDPConfigToModel(config *OIDCIDPConfig) *model.OIDCIDPConfig {
|
||||
return &model.OIDCIDPConfig{
|
||||
ObjectRoot: config.ObjectRoot,
|
||||
@ -71,33 +59,6 @@ func OIDCIDPConfigToModel(config *OIDCIDPConfig) *model.OIDCIDPConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func (iam *IAM) appendAddOIDCIDPConfigEvent(event *es_models.Event) error {
|
||||
config := new(OIDCIDPConfig)
|
||||
err := config.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.ObjectRoot.CreationDate = event.CreationDate
|
||||
if i, idpConfig := GetIDPConfig(iam.IDPs, config.IDPConfigID); idpConfig != nil {
|
||||
iam.IDPs[i].Type = int32(model.IDPConfigTypeOIDC)
|
||||
iam.IDPs[i].OIDCIDPConfig = config
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (iam *IAM) appendChangeOIDCIDPConfigEvent(event *es_models.Event) error {
|
||||
config := new(OIDCIDPConfig)
|
||||
err := config.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if i, idpConfig := GetIDPConfig(iam.IDPs, config.IDPConfigID); idpConfig != nil {
|
||||
iam.IDPs[i].OIDCIDPConfig.SetData(event)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OIDCIDPConfig) SetData(event *es_models.Event) error {
|
||||
o.ObjectRoot.AppendEvent(event)
|
||||
if err := json.Unmarshal(event.Data, o); err != nil {
|
||||
|
@ -1,10 +1,9 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
)
|
||||
|
||||
func TestOIDCIdpConfigChanges(t *testing.T) {
|
||||
@ -72,85 +71,3 @@ func TestOIDCIdpConfigChanges(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddOIDCIdpConfigEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
config *OIDCIDPConfig
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add oidc idp config event",
|
||||
args: args{
|
||||
iam: &IAM{IDPs: []*IDPConfig{&IDPConfig{IDPConfigID: "IDPConfigID"}}},
|
||||
config: &OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{IDPs: []*IDPConfig{&IDPConfig{IDPConfigID: "IDPConfigID", OIDCIDPConfig: &OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.config != nil {
|
||||
data, _ := json.Marshal(tt.args.config)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddOIDCIDPConfigEvent(tt.args.event)
|
||||
if len(tt.args.iam.IDPs) != 1 {
|
||||
t.Errorf("got wrong result should have one idpConfig actual: %v ", len(tt.args.iam.IDPs))
|
||||
}
|
||||
if tt.args.iam.IDPs[0].OIDCIDPConfig == nil {
|
||||
t.Errorf("got wrong result should have oidc config actual: %v ", tt.args.iam.IDPs[0].OIDCIDPConfig)
|
||||
}
|
||||
if tt.args.iam.IDPs[0] == tt.result.IDPs[0] {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.IDPs[0], tt.args.iam.IDPs[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangeOIDCIdpConfigEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
config *OIDCIDPConfig
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change oidc idp config event",
|
||||
args: args{
|
||||
iam: &IAM{IDPs: []*IDPConfig{&IDPConfig{IDPConfigID: "IDPConfigID", OIDCIDPConfig: &OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}}}},
|
||||
config: &OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID Changed"},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{IDPs: []*IDPConfig{&IDPConfig{IDPConfigID: "IDPConfigID", OIDCIDPConfig: &OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID Changed"}}}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.config != nil {
|
||||
data, _ := json.Marshal(tt.args.config)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangeOIDCIDPConfigEvent(tt.args.event)
|
||||
if len(tt.args.iam.IDPs) != 1 {
|
||||
t.Errorf("got wrong result should have one idpConfig actual: %v ", len(tt.args.iam.IDPs))
|
||||
}
|
||||
if tt.args.iam.IDPs[0].OIDCIDPConfig == nil {
|
||||
t.Errorf("got wrong result should have oidc config actual: %v ", tt.args.iam.IDPs[0].OIDCIDPConfig)
|
||||
}
|
||||
if tt.args.iam.IDPs[0] == tt.result.IDPs[0] {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.IDPs[0], tt.args.iam.IDPs[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -32,20 +32,6 @@ func (p *OrgIAMPolicy) Changes(changed *OrgIAMPolicy) map[string]interface{} {
|
||||
return changes
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddOrgIAMPolicyEvent(event *es_models.Event) error {
|
||||
i.DefaultOrgIAMPolicy = new(OrgIAMPolicy)
|
||||
err := i.DefaultOrgIAMPolicy.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultOrgIAMPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangeOrgIAMPolicyEvent(event *es_models.Event) error {
|
||||
return i.DefaultOrgIAMPolicy.SetData(event)
|
||||
}
|
||||
|
||||
func (p *OrgIAMPolicy) SetData(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
|
@ -1,10 +1,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
)
|
||||
|
||||
func TestOrgIAMPolicyChanges(t *testing.T) {
|
||||
@ -50,77 +47,3 @@ func TestOrgIAMPolicyChanges(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddOrgIAMPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *OrgIAMPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add org iam policy event",
|
||||
args: args{
|
||||
iam: new(IAM),
|
||||
policy: &OrgIAMPolicy{UserLoginMustBeDomain: true},
|
||||
event: new(es_models.Event),
|
||||
},
|
||||
result: &IAM{DefaultOrgIAMPolicy: &OrgIAMPolicy{UserLoginMustBeDomain: true}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddOrgIAMPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultOrgIAMPolicy.UserLoginMustBeDomain != tt.args.iam.DefaultOrgIAMPolicy.UserLoginMustBeDomain {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultOrgIAMPolicy.UserLoginMustBeDomain, tt.args.iam.DefaultOrgIAMPolicy.UserLoginMustBeDomain)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangeOrgIAMPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *OrgIAMPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change org iam policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultOrgIAMPolicy: &OrgIAMPolicy{
|
||||
UserLoginMustBeDomain: true,
|
||||
}},
|
||||
policy: &OrgIAMPolicy{UserLoginMustBeDomain: false},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultOrgIAMPolicy: &OrgIAMPolicy{
|
||||
UserLoginMustBeDomain: false,
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangeOrgIAMPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultOrgIAMPolicy.UserLoginMustBeDomain != tt.args.iam.DefaultOrgIAMPolicy.UserLoginMustBeDomain {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultOrgIAMPolicy.UserLoginMustBeDomain, tt.args.iam.DefaultOrgIAMPolicy.UserLoginMustBeDomain)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -37,20 +37,6 @@ func (p *PasswordAgePolicy) Changes(changed *PasswordAgePolicy) map[string]inter
|
||||
return changes
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddPasswordAgePolicyEvent(event *es_models.Event) error {
|
||||
i.DefaultPasswordAgePolicy = new(PasswordAgePolicy)
|
||||
err := i.DefaultPasswordAgePolicy.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultPasswordAgePolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangePasswordAgePolicyEvent(event *es_models.Event) error {
|
||||
return i.DefaultPasswordAgePolicy.SetData(event)
|
||||
}
|
||||
|
||||
func (p *PasswordAgePolicy) SetData(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
|
@ -1,8 +1,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -49,80 +47,3 @@ func TestPasswordAgePolicyChanges(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendAddPasswordAgePolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *PasswordAgePolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add password age policy event",
|
||||
args: args{
|
||||
iam: new(IAM),
|
||||
policy: &PasswordAgePolicy{MaxAgeDays: 10, ExpireWarnDays: 10},
|
||||
event: new(es_models.Event),
|
||||
},
|
||||
result: &IAM{DefaultPasswordAgePolicy: &PasswordAgePolicy{MaxAgeDays: 10, ExpireWarnDays: 10}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddPasswordAgePolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultPasswordAgePolicy.MaxAgeDays != tt.args.iam.DefaultPasswordAgePolicy.MaxAgeDays {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordAgePolicy.MaxAgeDays, tt.args.iam.DefaultPasswordAgePolicy.MaxAgeDays)
|
||||
}
|
||||
if tt.result.DefaultPasswordAgePolicy.ExpireWarnDays != tt.args.iam.DefaultPasswordAgePolicy.ExpireWarnDays {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordAgePolicy.ExpireWarnDays, tt.args.iam.DefaultPasswordAgePolicy.ExpireWarnDays)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangePasswordAgePolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *PasswordAgePolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change password age policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultPasswordAgePolicy: &PasswordAgePolicy{
|
||||
MaxAgeDays: 10,
|
||||
}},
|
||||
policy: &PasswordAgePolicy{MaxAgeDays: 5},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultPasswordAgePolicy: &PasswordAgePolicy{
|
||||
MaxAgeDays: 5,
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangePasswordAgePolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultPasswordAgePolicy.MaxAgeDays != tt.args.iam.DefaultPasswordAgePolicy.MaxAgeDays {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordAgePolicy.MaxAgeDays, tt.args.iam.DefaultPasswordAgePolicy.MaxAgeDays)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -31,20 +31,6 @@ func PasswordComplexityPolicyToModel(policy *PasswordComplexityPolicy) *iam_mode
|
||||
}
|
||||
}
|
||||
|
||||
func (i *IAM) appendAddPasswordComplexityPolicyEvent(event *es_models.Event) error {
|
||||
i.DefaultPasswordComplexityPolicy = new(PasswordComplexityPolicy)
|
||||
err := i.DefaultPasswordComplexityPolicy.SetData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.DefaultPasswordComplexityPolicy.ObjectRoot.CreationDate = event.CreationDate
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IAM) appendChangePasswordComplexityPolicyEvent(event *es_models.Event) error {
|
||||
return i.DefaultPasswordComplexityPolicy.SetData(event)
|
||||
}
|
||||
|
||||
func (p *PasswordComplexityPolicy) SetData(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, p)
|
||||
if err != nil {
|
||||
|
@ -1,94 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
)
|
||||
|
||||
func TestAppendAddPasswordComplexityPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *PasswordComplexityPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append add password complexity policy event",
|
||||
args: args{
|
||||
iam: new(IAM),
|
||||
policy: &PasswordComplexityPolicy{MinLength: 10, HasUppercase: true, HasLowercase: true, HasNumber: true, HasSymbol: true},
|
||||
event: new(es_models.Event),
|
||||
},
|
||||
result: &IAM{DefaultPasswordComplexityPolicy: &PasswordComplexityPolicy{MinLength: 10, HasUppercase: true, HasLowercase: true, HasNumber: true, HasSymbol: true}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendAddPasswordComplexityPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultPasswordComplexityPolicy.MinLength != tt.args.iam.DefaultPasswordComplexityPolicy.MinLength {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordComplexityPolicy.MinLength, tt.args.iam.DefaultPasswordComplexityPolicy.MinLength)
|
||||
}
|
||||
if tt.result.DefaultPasswordComplexityPolicy.HasUppercase != tt.args.iam.DefaultPasswordComplexityPolicy.HasUppercase {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordComplexityPolicy.HasUppercase, tt.args.iam.DefaultPasswordComplexityPolicy.HasUppercase)
|
||||
}
|
||||
if tt.result.DefaultPasswordComplexityPolicy.HasLowercase != tt.args.iam.DefaultPasswordComplexityPolicy.HasLowercase {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordComplexityPolicy.HasLowercase, tt.args.iam.DefaultPasswordComplexityPolicy.HasLowercase)
|
||||
}
|
||||
if tt.result.DefaultPasswordComplexityPolicy.HasNumber != tt.args.iam.DefaultPasswordComplexityPolicy.HasNumber {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordComplexityPolicy.HasNumber, tt.args.iam.DefaultPasswordComplexityPolicy.HasNumber)
|
||||
}
|
||||
if tt.result.DefaultPasswordComplexityPolicy.HasSymbol != tt.args.iam.DefaultPasswordComplexityPolicy.HasSymbol {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordComplexityPolicy.HasSymbol, tt.args.iam.DefaultPasswordComplexityPolicy.HasSymbol)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendChangePasswordComplexityPolicyEvent(t *testing.T) {
|
||||
type args struct {
|
||||
iam *IAM
|
||||
policy *PasswordComplexityPolicy
|
||||
event *es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *IAM
|
||||
}{
|
||||
{
|
||||
name: "append change password complexity policy event",
|
||||
args: args{
|
||||
iam: &IAM{DefaultPasswordComplexityPolicy: &PasswordComplexityPolicy{
|
||||
MinLength: 10,
|
||||
}},
|
||||
policy: &PasswordComplexityPolicy{MinLength: 5},
|
||||
event: &es_models.Event{},
|
||||
},
|
||||
result: &IAM{DefaultPasswordComplexityPolicy: &PasswordComplexityPolicy{
|
||||
MinLength: 5,
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.policy != nil {
|
||||
data, _ := json.Marshal(tt.args.policy)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
tt.args.iam.appendChangePasswordComplexityPolicyEvent(tt.args.event)
|
||||
if tt.result.DefaultPasswordComplexityPolicy.MinLength != tt.args.iam.DefaultPasswordComplexityPolicy.MinLength {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultPasswordComplexityPolicy.MinLength, tt.args.iam.DefaultPasswordComplexityPolicy.MinLength)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -44,6 +44,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
newNotifyUser(
|
||||
handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es},
|
||||
systemDefaults.IamID,
|
||||
queries,
|
||||
),
|
||||
newNotification(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Notification"), errorCount, es},
|
||||
|
@ -3,14 +3,11 @@ package handler
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
query2 "github.com/caos/zitadel/internal/query"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
@ -31,15 +28,18 @@ type NotifyUser struct {
|
||||
handler
|
||||
iamID string
|
||||
subscription *v1.Subscription
|
||||
queries *query2.Queries
|
||||
}
|
||||
|
||||
func newNotifyUser(
|
||||
handler handler,
|
||||
iamID string,
|
||||
queries *query2.Queries,
|
||||
) *NotifyUser {
|
||||
h := &NotifyUser{
|
||||
handler: handler,
|
||||
iamID: iamID,
|
||||
queries: queries,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -170,7 +170,7 @@ func (u *NotifyUser) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
@ -196,7 +196,7 @@ func (u *NotifyUser) fillPreferredLoginNamesOnOrgUsers(event *es_models.Event) e
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
@ -225,7 +225,7 @@ func (u *NotifyUser) fillLoginNames(user *view_model.NotifyUser) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
policy := new(query2.OrgIAMPolicy)
|
||||
if policy == nil {
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
@ -268,30 +268,6 @@ func (u *NotifyUser) getOrgByID(ctx context.Context, orgID string) (*org_model.O
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *NotifyUser) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *NotifyUser) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2Fj8s", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
func (u *NotifyUser) getDefaultOrgIAMPolicy(ctx context.Context) (*query2.OrgIAMPolicy, error) {
|
||||
return u.queries.DefaultOrgIAMPolicy(ctx)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
@ -9,177 +8,11 @@ import (
|
||||
|
||||
func readModelToIAM(readModel *ReadModel) *model.IAM {
|
||||
return &model.IAM{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel),
|
||||
GlobalOrgID: readModel.GlobalOrgID,
|
||||
IAMProjectID: readModel.ProjectID,
|
||||
SetUpDone: readModel.SetUpDone,
|
||||
SetUpStarted: readModel.SetUpStarted,
|
||||
Members: readModelToMembers(&readModel.Members),
|
||||
DefaultLabelPolicy: readModelToLabelPolicy(&readModel.DefaultLabelPolicy),
|
||||
DefaultLoginPolicy: readModelToLoginPolicy(&readModel.DefaultLoginPolicy),
|
||||
DefaultOrgIAMPolicy: readModelToOrgIAMPolicy(&readModel.DefaultOrgIAMPolicy),
|
||||
DefaultPasswordAgePolicy: readModelToPasswordAgePolicy(&readModel.DefaultPasswordAgePolicy),
|
||||
DefaultPasswordComplexityPolicy: readModelToPasswordComplexityPolicy(&readModel.DefaultPasswordComplexityPolicy),
|
||||
DefaultLockoutPolicy: readModelToPasswordLockoutPolicy(&readModel.DefaultPasswordLockoutPolicy),
|
||||
IDPs: readModelToIDPConfigs(&readModel.IDPs),
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToIDPConfigView(rm *IAMIDPConfigReadModel) *domain.IDPConfigView {
|
||||
converted := &domain.IDPConfigView{
|
||||
AggregateID: rm.AggregateID,
|
||||
ChangeDate: rm.ChangeDate,
|
||||
CreationDate: rm.CreationDate,
|
||||
IDPConfigID: rm.ConfigID,
|
||||
IDPProviderType: rm.ProviderType,
|
||||
IsOIDC: rm.OIDCConfig != nil,
|
||||
Name: rm.Name,
|
||||
Sequence: rm.ProcessedSequence,
|
||||
State: rm.State,
|
||||
StylingType: rm.StylingType,
|
||||
}
|
||||
if rm.OIDCConfig != nil {
|
||||
converted.OIDCClientID = rm.OIDCConfig.ClientID
|
||||
converted.OIDCClientSecret = rm.OIDCConfig.ClientSecret
|
||||
converted.OIDCIDPDisplayNameMapping = rm.OIDCConfig.IDPDisplayNameMapping
|
||||
converted.OIDCIssuer = rm.OIDCConfig.Issuer
|
||||
converted.OIDCScopes = rm.OIDCConfig.Scopes
|
||||
converted.OIDCUsernameMapping = rm.OIDCConfig.UserNameMapping
|
||||
converted.OAuthAuthorizationEndpoint = rm.OIDCConfig.AuthorizationEndpoint
|
||||
converted.OAuthTokenEndpoint = rm.OIDCConfig.TokenEndpoint
|
||||
}
|
||||
if rm.JWTConfig != nil {
|
||||
converted.JWTEndpoint = rm.JWTConfig.JWTEndpoint
|
||||
converted.JWTIssuer = rm.JWTConfig.Issuer
|
||||
converted.JWTKeysEndpoint = rm.JWTConfig.KeysEndpoint
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func readModelToMember(readModel *MemberReadModel) *model.IAMMember {
|
||||
return &model.IAMMember{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel),
|
||||
Roles: readModel.Roles,
|
||||
UserID: readModel.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToMembers(readModel *IAMMembersReadModel) []*model.IAMMember {
|
||||
members := make([]*model.IAMMember, len(readModel.Members))
|
||||
|
||||
for i, member := range readModel.Members {
|
||||
members[i] = &model.IAMMember{
|
||||
ObjectRoot: readModelToObjectRoot(member.ReadModel),
|
||||
Roles: member.Roles,
|
||||
UserID: member.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
return members
|
||||
}
|
||||
|
||||
func readModelToLabelPolicy(readModel *IAMLabelPolicyReadModel) *model.LabelPolicy {
|
||||
return &model.LabelPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.LabelPolicyReadModel.ReadModel),
|
||||
PrimaryColor: readModel.PrimaryColor,
|
||||
BackgroundColor: readModel.BackgroundColor,
|
||||
WarnColor: readModel.WarnColor,
|
||||
FontColor: readModel.FontColor,
|
||||
PrimaryColorDark: readModel.PrimaryColorDark,
|
||||
BackgroundColorDark: readModel.BackgroundColorDark,
|
||||
WarnColorDark: readModel.WarnColorDark,
|
||||
FontColorDark: readModel.FontColorDark,
|
||||
Default: true,
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToLoginPolicy(readModel *IAMLoginPolicyReadModel) *model.LoginPolicy {
|
||||
return &model.LoginPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.LoginPolicyReadModel.ReadModel),
|
||||
AllowExternalIdp: readModel.AllowExternalIDP,
|
||||
AllowRegister: readModel.AllowRegister,
|
||||
AllowUsernamePassword: readModel.AllowUserNamePassword,
|
||||
Default: true,
|
||||
}
|
||||
}
|
||||
func readModelToOrgIAMPolicy(readModel *IAMOrgIAMPolicyReadModel) *model.OrgIAMPolicy {
|
||||
return &model.OrgIAMPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.OrgIAMPolicyReadModel.ReadModel),
|
||||
UserLoginMustBeDomain: readModel.UserLoginMustBeDomain,
|
||||
Default: true,
|
||||
}
|
||||
}
|
||||
func readModelToPasswordAgePolicy(readModel *IAMPasswordAgePolicyReadModel) *model.PasswordAgePolicy {
|
||||
return &model.PasswordAgePolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.PasswordAgePolicyReadModel.ReadModel),
|
||||
ExpireWarnDays: readModel.ExpireWarnDays,
|
||||
MaxAgeDays: readModel.MaxAgeDays,
|
||||
}
|
||||
}
|
||||
func readModelToPasswordComplexityPolicy(readModel *IAMPasswordComplexityPolicyReadModel) *model.PasswordComplexityPolicy {
|
||||
return &model.PasswordComplexityPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.PasswordComplexityPolicyReadModel.ReadModel),
|
||||
HasLowercase: readModel.HasLowercase,
|
||||
HasNumber: readModel.HasNumber,
|
||||
HasSymbol: readModel.HasSymbol,
|
||||
HasUppercase: readModel.HasUpperCase,
|
||||
MinLength: readModel.MinLength,
|
||||
}
|
||||
}
|
||||
func readModelToPasswordLockoutPolicy(readModel *IAMLockoutPolicyReadModel) *model.LockoutPolicy {
|
||||
return &model.LockoutPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.LockoutPolicyReadModel.ReadModel),
|
||||
MaxPasswordAttempts: readModel.MaxAttempts,
|
||||
ShowLockOutFailures: readModel.ShowLockOutFailures,
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToIDPConfigs(rm *IAMIDPConfigsReadModel) []*model.IDPConfig {
|
||||
configs := make([]*model.IDPConfig, len(rm.Configs))
|
||||
for i, config := range rm.Configs {
|
||||
configs[i] = readModelToIDPConfig(&IAMIDPConfigReadModel{IDPConfigReadModel: *config})
|
||||
}
|
||||
return configs
|
||||
}
|
||||
|
||||
func readModelToIDPConfig(rm *IAMIDPConfigReadModel) *model.IDPConfig {
|
||||
config := &model.IDPConfig{
|
||||
ObjectRoot: readModelToObjectRoot(rm.ReadModel),
|
||||
IDPConfigID: rm.ConfigID,
|
||||
Name: rm.Name,
|
||||
State: model.IDPConfigState(rm.State),
|
||||
StylingType: model.IDPStylingType(rm.StylingType),
|
||||
}
|
||||
if rm.OIDCConfig != nil {
|
||||
config.OIDCConfig = readModelToIDPOIDCConfig(rm.OIDCConfig)
|
||||
}
|
||||
if rm.JWTConfig != nil {
|
||||
config.JWTIDPConfig = readModelToIDPJWTConfig(rm.JWTConfig)
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
func readModelToIDPOIDCConfig(rm *OIDCConfigReadModel) *model.OIDCIDPConfig {
|
||||
return &model.OIDCIDPConfig{
|
||||
ObjectRoot: readModelToObjectRoot(rm.ReadModel),
|
||||
ClientID: rm.ClientID,
|
||||
ClientSecret: rm.ClientSecret,
|
||||
ClientSecretString: string(rm.ClientSecret.Crypted),
|
||||
IDPConfigID: rm.IDPConfigID,
|
||||
IDPDisplayNameMapping: model.OIDCMappingField(rm.IDPDisplayNameMapping),
|
||||
Issuer: rm.Issuer,
|
||||
Scopes: rm.Scopes,
|
||||
UsernameMapping: model.OIDCMappingField(rm.UserNameMapping),
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToIDPJWTConfig(rm *JWTConfigReadModel) *model.JWTIDPConfig {
|
||||
return &model.JWTIDPConfig{
|
||||
ObjectRoot: readModelToObjectRoot(rm.ReadModel),
|
||||
IDPConfigID: rm.IDPConfigID,
|
||||
JWTEndpoint: rm.JWTEndpoint,
|
||||
Issuer: rm.Issuer,
|
||||
KeysEndpoint: rm.KeysEndpoint,
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel),
|
||||
GlobalOrgID: readModel.GlobalOrgID,
|
||||
IAMProjectID: readModel.ProjectID,
|
||||
SetUpDone: readModel.SetUpDone,
|
||||
SetUpStarted: readModel.SetUpStarted,
|
||||
}
|
||||
}
|
||||
|
||||
|
122
internal/query/projection/iam.go
Normal file
122
internal/query/projection/iam.go
Normal file
@ -0,0 +1,122 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/handler"
|
||||
"github.com/caos/zitadel/internal/eventstore/handler/crdb"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
)
|
||||
|
||||
type IAMProjection struct {
|
||||
crdb.StatementHandler
|
||||
}
|
||||
|
||||
const (
|
||||
IAMProjectionTable = "zitadel.projections.iam"
|
||||
)
|
||||
|
||||
func NewIAMProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IAMProjection {
|
||||
p := &IAMProjection{}
|
||||
config.ProjectionName = IAMProjectionTable
|
||||
config.Reducers = p.reducers()
|
||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *IAMProjection) reducers() []handler.AggregateReducer {
|
||||
return []handler.AggregateReducer{
|
||||
{
|
||||
Aggregate: iam.AggregateType,
|
||||
EventRedusers: []handler.EventReducer{
|
||||
{
|
||||
Event: iam.GlobalOrgSetEventType,
|
||||
Reduce: p.reduceGlobalOrgSet,
|
||||
},
|
||||
{
|
||||
Event: iam.ProjectSetEventType,
|
||||
Reduce: p.reduceIAMProjectSet,
|
||||
},
|
||||
{
|
||||
Event: iam.SetupStartedEventType,
|
||||
Reduce: p.reduceSetupEvent,
|
||||
},
|
||||
{
|
||||
Event: iam.SetupDoneEventType,
|
||||
Reduce: p.reduceSetupEvent,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type IAMColumn string
|
||||
|
||||
const (
|
||||
IAMColumnID = "id"
|
||||
IAMColumnChangeDate = "change_date"
|
||||
IAMColumnGlobalOrgID = "global_org_id"
|
||||
IAMColumnProjectID = "iam_project_id"
|
||||
IAMColumnSequence = "sequence"
|
||||
IAMColumnSetUpStarted = "setup_started"
|
||||
IAMColumnSetUpDone = "setup_done"
|
||||
)
|
||||
|
||||
func (p *IAMProjection) reduceGlobalOrgSet(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*iam.GlobalOrgSetEvent)
|
||||
if !ok {
|
||||
logging.LogWithFields("HANDL-3n89fs", "seq", event.Sequence(), "expectedType", iam.GlobalOrgSetEventType).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-2n9f2", "reduce.wrong.event.type")
|
||||
}
|
||||
return crdb.NewUpsertStatement(
|
||||
e,
|
||||
[]handler.Column{
|
||||
handler.NewCol(IAMColumnID, e.Aggregate().ID),
|
||||
handler.NewCol(IAMColumnChangeDate, e.CreationDate()),
|
||||
handler.NewCol(IAMColumnSequence, e.Sequence()),
|
||||
handler.NewCol(IAMColumnGlobalOrgID, e.OrgID),
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IAMProjection) reduceIAMProjectSet(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*iam.ProjectSetEvent)
|
||||
if !ok {
|
||||
logging.LogWithFields("HANDL-2j9fw", "seq", event.Sequence(), "expectedType", iam.ProjectSetEventType).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-30o0e", "reduce.wrong.event.type")
|
||||
}
|
||||
return crdb.NewUpsertStatement(
|
||||
e,
|
||||
[]handler.Column{
|
||||
handler.NewCol(IAMColumnID, e.Aggregate().ID),
|
||||
handler.NewCol(IAMColumnChangeDate, e.CreationDate()),
|
||||
handler.NewCol(IAMColumnSequence, e.Sequence()),
|
||||
handler.NewCol(IAMColumnProjectID, e.ProjectID),
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IAMProjection) reduceSetupEvent(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*iam.SetupStepEvent)
|
||||
if !ok {
|
||||
logging.LogWithFields("HANDL-39fjw", "seq", event.Sequence(), "expectedTypes", []eventstore.EventType{iam.SetupDoneEventType, iam.SetupStartedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-d9nfw", "reduce.wrong.event.type")
|
||||
}
|
||||
columns := []handler.Column{
|
||||
handler.NewCol(IAMColumnID, e.Aggregate().ID),
|
||||
handler.NewCol(IAMColumnChangeDate, e.CreationDate()),
|
||||
handler.NewCol(IAMColumnSequence, e.Sequence()),
|
||||
}
|
||||
if e.EventType == iam.SetupStartedEventType {
|
||||
columns = append(columns, handler.NewCol(IAMColumnSetUpStarted, e.Step))
|
||||
} else {
|
||||
columns = append(columns, handler.NewCol(IAMColumnSetUpDone, e.Step))
|
||||
}
|
||||
return crdb.NewUpsertStatement(
|
||||
e,
|
||||
columns,
|
||||
), nil
|
||||
}
|
158
internal/query/projection/iam_test.go
Normal file
158
internal/query/projection/iam_test.go
Normal file
@ -0,0 +1,158 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/handler"
|
||||
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
)
|
||||
|
||||
func TestIAMProjection_reduces(t *testing.T) {
|
||||
type args struct {
|
||||
event func(t *testing.T) eventstore.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
reduce func(event eventstore.Event) (*handler.Statement, error)
|
||||
want wantReduce
|
||||
}{
|
||||
{
|
||||
name: "reduceGlobalOrgSet",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.GlobalOrgSetEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{"globalOrgId": "orgid"}`),
|
||||
), iam.GlobalOrgSetMapper),
|
||||
},
|
||||
reduce: (&IAMProjection{}).reduceGlobalOrgSet,
|
||||
want: wantReduce{
|
||||
projection: IAMProjectionTable,
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPSERT INTO zitadel.projections.iam (id, change_date, sequence, global_org_id) VALUES ($1, $2, $3, $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"orgid",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "reduceGlobalOrgSet",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.ProjectSetEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{"iamProjectId": "project-id"}`),
|
||||
), iam.ProjectSetMapper),
|
||||
},
|
||||
reduce: (&IAMProjection{}).reduceIAMProjectSet,
|
||||
want: wantReduce{
|
||||
projection: IAMProjectionTable,
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPSERT INTO zitadel.projections.iam (id, change_date, sequence, iam_project_id) VALUES ($1, $2, $3, $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"project-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "reduceSetupStarted",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.SetupStartedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{"Step": 1}`),
|
||||
), iam.SetupStepMapper),
|
||||
},
|
||||
reduce: (&IAMProjection{}).reduceSetupEvent,
|
||||
want: wantReduce{
|
||||
projection: IAMProjectionTable,
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPSERT INTO zitadel.projections.iam (id, change_date, sequence, setup_started) VALUES ($1, $2, $3, $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
domain.Step1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "reduceSetupDone",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.SetupDoneEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{"Step": 1}`),
|
||||
), iam.SetupStepMapper),
|
||||
},
|
||||
reduce: (&IAMProjection{}).reduceSetupEvent,
|
||||
want: wantReduce{
|
||||
projection: IAMProjectionTable,
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPSERT INTO zitadel.projections.iam (id, change_date, sequence, setup_done) VALUES ($1, $2, $3, $4)",
|
||||
expectedArgs: []interface{}{
|
||||
"agg-id",
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
domain.Step1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
event := baseEvent(t)
|
||||
got, err := tt.reduce(event)
|
||||
if _, ok := err.(errors.InvalidArgument); !ok {
|
||||
t.Errorf("no wrong event mapping: %v, got: %v", err, got)
|
||||
}
|
||||
|
||||
event = tt.args.event(t)
|
||||
got, err = tt.reduce(event)
|
||||
assertReduce(t, got, err, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
@ -67,6 +67,7 @@ func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, co
|
||||
NewUserGrantProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["user_grants"]))
|
||||
NewUserMetadataProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["user_metadata"]))
|
||||
NewUserAuthMethodProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["user_auth_method"]))
|
||||
NewIAMProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["iam"]))
|
||||
_, err := NewKeyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["keys"]), defaults.KeyConfig, keyChan)
|
||||
|
||||
return err
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/lib/pq"
|
||||
@ -99,7 +99,7 @@ func (u *NotifyUser) GenerateLoginName(domain string, appendDomain bool) string
|
||||
return u.UserName + "@" + domain
|
||||
}
|
||||
|
||||
func (u *NotifyUser) SetLoginNames(policy *iam_model.OrgIAMPolicy, domains []*org_model.OrgDomain) {
|
||||
func (u *NotifyUser) SetLoginNames(policy *query.OrgIAMPolicy, domains []*org_model.OrgDomain) {
|
||||
loginNames := make([]string, 0)
|
||||
for _, d := range domains {
|
||||
if d.Verified {
|
||||
|
@ -6,13 +6,13 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
"github.com/lib/pq"
|
||||
|
||||
req_model "github.com/caos/zitadel/internal/auth_request/model"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
user_repo "github.com/caos/zitadel/internal/repository/user"
|
||||
"github.com/caos/zitadel/internal/user/model"
|
||||
@ -227,7 +227,7 @@ func (u *UserView) GenerateLoginName(domain string, appendDomain bool) string {
|
||||
return u.UserName + "@" + domain
|
||||
}
|
||||
|
||||
func (u *UserView) SetLoginNames(policy *iam_model.OrgIAMPolicy, domains []*org_model.OrgDomain) {
|
||||
func (u *UserView) SetLoginNames(policy *query.OrgIAMPolicy, domains []*org_model.OrgDomain) {
|
||||
loginNames := make([]string, 0)
|
||||
for _, d := range domains {
|
||||
if d.Verified {
|
||||
|
12
migrations/cockroach/V1.108__iam.sql
Normal file
12
migrations/cockroach/V1.108__iam.sql
Normal file
@ -0,0 +1,12 @@
|
||||
CREATE TABLE zitadel.projections.iam (
|
||||
id STRING NOT NULL
|
||||
, change_date TIMESTAMPTZ NOT NULL
|
||||
, sequence INT8 NOT NULL
|
||||
|
||||
, global_org_id STRING DEFAULT ''
|
||||
, iam_project_id STRING DEFAULT ''
|
||||
, setup_started SMALLINT DEFAULT 0
|
||||
, setup_done SMALLINT DEFAULT 0
|
||||
|
||||
, PRIMARY KEY (id)
|
||||
);
|
Loading…
Reference in New Issue
Block a user