Silvan 5abd5b0505
feat: split users into human and machine (#470)
* feat(management): service accounts

* chore: current go version

* init

* refactor: apis

* feat(internal): start impl of service account

* chore: start impl of machine/human users

* code compiles

* fix: tests

* fix: tests

* fix: add new event types to switches

* chore: add cases to event types

* fix(management): definitive proto messages

* fix: machine/human

* fix: add missing tables as todos

* fix: remove unused permissions

* fix: refactoring

* fix: refactor

* fix: human registered

* fix: user id

* fix: logid

* fix: proto remove //equal

* chore(management): remove no comment

* fix: human mfas

* fix: user subobjects

* chore: rename existing to better name

* fix: username in user (#634)

* fix: username in user

* fix: username

* fix remove unused code

* fix add validations

* fix: use new user in all apis

* fix: regexp for username in api

* fix: fill user data for human and machine (#638)

* fix: fill Display name grant/member handlers
fix: add description to grant/member objects in api
fix: check if user is human in login

* fix: remove description from member and grant

* chore: remove todos

* feat: machine keys

* fix: implement missing parts

* feat: machine key management view

* fix: remove keys from machine view

* fix: set default expiration date

* fix: get key by ids

* feat: add machine keys in proto

* feat: machine keys

* fix: add migration

* fix: mig

* fix: correct method name

* feat: user search

* feat: user search

* fix: log ids

* fix partial authconfig prompt, domain c perm

* membership read check

* contributor refresh trigger, observe org write

* fix: migrations

* fix(console): machine build (#660)

* frontend 1

* fix html bindings

* trailing comma

* user permissions, project deactivate

* fix(console): human view (#661)

* fix search user view, user detail form

* rm log

* feat(console): user services list and create (#663)

* fix search user view, user detail form

* rm log

* machine list

* generic table component

* create user service

* proove table for undefined values

* tmp disable user link if machine

* lint

* lint styles

* user table lint

* Update console/src/assets/i18n/de.json

Co-authored-by: Florian Forster <florian@caos.ch>

* feat(console): service user detail view, keys cr_d, fix search user autocomplete (#664)

* service users for sidenav, routing

* i18n

* back routes

* machine detail form

* update machine detail, fix svc user grants

* keys table

* add key dialog, timestamp creation

* check permission on create, delete, fix selection

* lint ts, scss

* Update console/src/assets/i18n/de.json

* Apply suggestions from code review

Co-authored-by: Florian Forster <florian@caos.ch>

* allow user grants for project.write

* management service

* fix mgmt service

* feat: Machine keys (#655)

* fix: memberships (#633)

* feat: add iam members to memberships

* fix: search project grants

* fix: rename

* feat: idp and login policy configurations (#619)

* feat: oidc config

* fix: oidc configurations

* feat: oidc idp config

* feat: add oidc config test

* fix: tests

* fix: tests

* feat: translate new events

* feat: idp eventstore

* feat: idp eventstore

* fix: tests

* feat: command side idp

* feat: query side idp

* feat: idp config on org

* fix: tests

* feat: authz idp on org

* feat: org idps

* feat: login policy

* feat: login policy

* feat: login policy

* feat: add idp func on login policy

* feat: add validation to loginpolicy and idp provider

* feat: add default login policy

* feat: login policy on org

* feat: login policy on org

* fix: id config handlers

* fix: id config handlers

* fix: create idp on org

* fix: create idp on org

* fix: not existing idp config

* fix: default login policy

* fix: add login policy on org

* fix: idp provider search on org

* fix: test

* fix: remove idp on org

* fix: test

* fix: test

* fix: remove admin idp

* fix: logo src as byte

* fix: migration

* fix: tests

* Update internal/iam/repository/eventsourcing/iam.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/iam_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/iam_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/model/login_policy.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/model/login_policy.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/org/repository/eventsourcing/org_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/model/login_policy_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/model/login_policy_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* fix: pr comments

* fix: tests

* Update types.go

* fix: merge request changes

* fix: reduce optimization

Co-authored-by: Silvan <silvan.reusser@gmail.com>
Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* fix: reread user mfas, preferred loginname as otp account name (#636)

* fix: reread user mfas

* fix: use preferred login name as otp account name

* fix: tests

* fix: reduce (#635)

* fix: management reduce optimization

* fix: reduce optimization

* fix: reduce optimization

* fix: merge master

* chore(deps): bump github.com/gorilla/schema from 1.1.0 to 1.2.0 (#627)

Bumps [github.com/gorilla/schema](https://github.com/gorilla/schema) from 1.1.0 to 1.2.0.
- [Release notes](https://github.com/gorilla/schema/releases)
- [Commits](https://github.com/gorilla/schema/compare/v1.1.0...v1.2.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump github.com/gorilla/mux from 1.7.4 to 1.8.0 (#624)

Bumps [github.com/gorilla/mux](https://github.com/gorilla/mux) from 1.7.4 to 1.8.0.
- [Release notes](https://github.com/gorilla/mux/releases)
- [Commits](https://github.com/gorilla/mux/compare/v1.7.4...v1.8.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump github.com/DATA-DOG/go-sqlmock from 1.4.1 to 1.5.0 (#591)

Bumps [github.com/DATA-DOG/go-sqlmock](https://github.com/DATA-DOG/go-sqlmock) from 1.4.1 to 1.5.0.
- [Release notes](https://github.com/DATA-DOG/go-sqlmock/releases)
- [Commits](https://github.com/DATA-DOG/go-sqlmock/compare/v1.4.1...v1.5.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore: auto assign issues and PR to ZTIADEL project board (#643)

* Create main.yml

* Update main.yml

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* fix(console): project grant members, update deps (#645)

* fix: searchprojectgrantmembers

* chore(deps-dev): bump @angular/cli from 10.0.6 to 10.0.7 in /console (#622)

Bumps [@angular/cli](https://github.com/angular/angular-cli) from 10.0.6 to 10.0.7.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/compare/v10.0.6...v10.0.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump @angular-devkit/build-angular in /console (#626)

Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1000.6 to 0.1000.7.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Peintner <max@caos.ch>

* chore(deps-dev): bump @types/jasmine from 3.5.12 to 3.5.13 in /console (#623)

Bumps [@types/jasmine](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jasmine) from 3.5.12 to 3.5.13.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jasmine)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump ts-node from 8.10.2 to 9.0.0 in /console (#629)

Bumps [ts-node](https://github.com/TypeStrong/ts-node) from 8.10.2 to 9.0.0.
- [Release notes](https://github.com/TypeStrong/ts-node/releases)
- [Commits](https://github.com/TypeStrong/ts-node/compare/v8.10.2...v9.0.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* update packlock

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore: delete main.yml (#648)

* fix: usergrant (#650)

* fix(console): mfa refresh after verification, member eventemitter (#651)

* refresh mfa

* fix: detail link from contributors

* lint

* feat: add domain verification notification (#649)

* fix: dont (re)generate client secret with auth type none

* fix(cors): allow Origin from request

* feat: add origin allow list and fix some core issues

* rename migration

* fix UserIDsByDomain

* feat: send email to users after domain claim

* username

* check origin on userinfo

* update oidc pkg

* fix: add migration 1.6

* change username

* change username

* remove unique email aggregate

* change username in mgmt

* search global user by login name

* fix test

* change user search in angular

* fix tests

* merge

* userview in angular

* fix merge

* Update pkg/grpc/management/proto/management.proto

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>

* Update internal/notification/static/i18n/de.yaml

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>

* fix

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>

* fix: translation (#647)

* fix: translation

* fix: translation

* fix: translation

* fix: remove unused code

* fix: log err

* fix: migration numbers (#652)

* chore: issue / feature templates (#642)

* feat: machine keys

* fix: implement missing parts

* feat: machine key management view

* fix: remove keys from machine view

* feat: global org read (#657)

* fix: set default expiration date

* fix: get key by ids

* feat: add machine keys in proto

* feat: machine keys

* fix: add migration

* fix: mig

* fix: correct method name

* feat: user search

* feat: user search

* fix: log ids

* fix: migrations

* fix(console): machine build (#660)

* frontend 1

* fix html bindings

* trailing comma

* fix(console): human view (#661)

* fix search user view, user detail form

* rm log

* feat(console): user services list and create (#663)

* fix search user view, user detail form

* rm log

* machine list

* generic table component

* create user service

* proove table for undefined values

* tmp disable user link if machine

* lint

* lint styles

* user table lint

* Update console/src/assets/i18n/de.json

Co-authored-by: Florian Forster <florian@caos.ch>

* feat(console): service user detail view, keys cr_d, fix search user autocomplete (#664)

* service users for sidenav, routing

* i18n

* back routes

* machine detail form

* update machine detail, fix svc user grants

* keys table

* add key dialog, timestamp creation

* check permission on create, delete, fix selection

* lint ts, scss

* Update console/src/assets/i18n/de.json

* Apply suggestions from code review

Co-authored-by: Florian Forster <florian@caos.ch>

* refactor: protos

* fix(management): key expiration date

* fix: check if user is human

* fix: marshal key details

* fix: correct generate login names

* fix: logid

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
Co-authored-by: Livio Amstutz <livio.a@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: Fabiennne <fabienne.gerschwiler@gmail.com>
Co-authored-by: Florian Forster <florian@caos.ch>

* fix: naming

* refactor: findings

* fix: username

* fix: mfa upper case

* fix: tests

* fix: add translations

* reactivatemyorg req typeö

* fix: projectType for console

* fix: user changes

* fix: translate events

* fix: event type translation

* fix: remove unused types

Co-authored-by: Fabiennne <fabienne.gerschwiler@gmail.com>
Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: Florian Forster <florian@caos.ch>
Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
Co-authored-by: Livio Amstutz <livio.a@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-08-31 17:48:01 +02:00

366 lines
13 KiB
Go

package eventsourcing
import (
"context"
"github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
)
func IAMByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) {
if id == "" {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-0soe4", "Errors.IAM.IDMissing")
}
return IAMQuery(latestSequence).
AggregateIDFilter(id), nil
}
func IAMQuery(latestSequence uint64) *es_models.SearchQuery {
return es_models.NewSearchQuery().
AggregateTypeFilter(model.IAMAggregate).
LatestSequenceFilter(latestSequence)
}
func IAMAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, iam *model.IAM) (*es_models.Aggregate, error) {
if iam == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-lo04e", "Errors.Internal")
}
return aggCreator.NewAggregate(ctx, iam.AggregateID, model.IAMAggregate, model.IAMVersion, iam.Sequence)
}
func IAMAggregateOverwriteContext(ctx context.Context, aggCreator *es_models.AggregateCreator, iam *model.IAM, resourceOwnerID string, userID string) (*es_models.Aggregate, error) {
if iam == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dis83", "Errors.Internal")
}
return aggCreator.NewAggregate(ctx, iam.AggregateID, model.IAMAggregate, model.IAMVersion, iam.Sequence, es_models.OverwriteResourceOwner(resourceOwnerID), es_models.OverwriteEditorUser(userID))
}
func IAMSetupStartedAggregate(aggCreator *es_models.AggregateCreator, iam *model.IAM) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := IAMAggregate(ctx, aggCreator, iam)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.IAMSetupStarted, nil)
}
}
func IAMSetupDoneAggregate(aggCreator *es_models.AggregateCreator, iam *model.IAM) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := IAMAggregate(ctx, aggCreator, iam)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.IAMSetupDone, nil)
}
}
func IAMSetGlobalOrgAggregate(aggCreator *es_models.AggregateCreator, iam *model.IAM, globalOrg string) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if globalOrg == "" {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-8siwa", "Errors.IAM.GlobalOrgMissing")
}
agg, err := IAMAggregate(ctx, aggCreator, iam)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.GlobalOrgSet, &model.IAM{GlobalOrgID: globalOrg})
}
}
func IAMSetIamProjectAggregate(aggCreator *es_models.AggregateCreator, iam *model.IAM, projectID string) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if projectID == "" {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sjuw3", "Errors.IAM.IamProjectIDMisisng")
}
agg, err := IAMAggregate(ctx, aggCreator, iam)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.IAMProjectSet, &model.IAM{IAMProjectID: projectID})
}
}
func IAMMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existingIAM *model.IAM, member *model.IAMMember) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if member == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-9sope", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existingIAM)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.IAMMemberAdded, member)
}
}
func IAMMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingIAM *model.IAM, member *model.IAMMember) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if member == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-38skf", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existingIAM)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.IAMMemberChanged, member)
}
}
func IAMMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existingIAM *model.IAM, member *model.IAMMember) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if member == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-90lsw", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existingIAM)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.IAMMemberRemoved, member)
}
}
func IDPConfigAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if idp == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-MSn7d", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
agg, err = agg.AppendEvent(model.IDPConfigAdded, idp)
if err != nil {
return nil, err
}
if idp.OIDCIDPConfig != nil {
return agg.AppendEvent(model.OIDCIDPConfigAdded, idp.OIDCIDPConfig)
}
return agg, nil
}
}
func IDPConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if idp == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Amc7s", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
var changes map[string]interface{}
for _, i := range existing.IDPs {
if i.IDPConfigID == idp.IDPConfigID {
changes = i.Changes(idp)
}
}
return agg.AppendEvent(model.IDPConfigChanged, changes)
}
}
func IDPConfigRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig, provider *model.IDPProvider) (*es_models.Aggregate, error) {
if idp == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-se23g", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
agg, err = agg.AppendEvent(model.IDPConfigRemoved, &model.IDPConfigID{IDPConfigID: idp.IDPConfigID})
if err != nil {
return nil, err
}
if provider != nil {
return agg.AppendEvent(model.LoginPolicyIDPProviderCascadeRemoved, &model.IDPConfigID{IDPConfigID: idp.IDPConfigID})
}
return agg, nil
}
func IDPConfigDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if idp == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slfi3", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.IDPConfigDeactivated, &model.IDPConfigID{IDPConfigID: idp.IDPConfigID})
}
}
func IDPConfigReactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if idp == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.IDPConfigReactivated, &model.IDPConfigID{IDPConfigID: idp.IDPConfigID})
}
}
func OIDCIDPConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, config *model.OIDCIDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if config == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
var changes map[string]interface{}
for _, idp := range existing.IDPs {
if idp.IDPConfigID == config.IDPConfigID && idp.OIDCIDPConfig != nil {
changes = idp.OIDCIDPConfig.Changes(config)
}
}
if len(changes) <= 1 {
return nil, errors.ThrowPreconditionFailedf(nil, "EVENT-Cml9s", "Errors.NoChangesFound")
}
return agg.AppendEvent(model.OIDCIDPConfigChanged, changes)
}
}
func LoginPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LoginPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if policy == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smla8", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
validationQuery := es_models.NewSearchQuery().
AggregateTypeFilter(model.IAMAggregate).
EventTypesFilter(model.LoginPolicyAdded).
AggregateIDFilter(existing.AggregateID)
validation := checkExistingLoginPolicyValidation()
agg.SetPrecondition(validationQuery, validation)
return agg.AppendEvent(model.LoginPolicyAdded, policy)
}
}
func LoginPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LoginPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if policy == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Mlco9", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
changes := existing.DefaultLoginPolicy.Changes(policy)
if len(changes) == 0 {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smk8d", "Errors.NoChangesFound")
}
return agg.AppendEvent(model.LoginPolicyChanged, changes)
}
}
func LoginPolicyIDPProviderAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, provider *model.IDPProvider) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if provider == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sml9d", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
validationQuery := es_models.NewSearchQuery().
AggregateTypeFilter(model.IAMAggregate).
AggregateIDFilter(existing.AggregateID)
validation := checkExistingLoginPolicyIDPProviderValidation(provider.IDPConfigID)
agg.SetPrecondition(validationQuery, validation)
return agg.AppendEvent(model.LoginPolicyIDPProviderAdded, provider)
}
}
func LoginPolicyIDPProviderRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, provider *model.IDPProviderID) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if provider == nil || existing == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sml9d", "Errors.Internal")
}
agg, err := IAMAggregate(ctx, aggCreator, existing)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.LoginPolicyIDPProviderRemoved, provider)
}
}
func checkExistingLoginPolicyValidation() func(...*es_models.Event) error {
return func(events ...*es_models.Event) error {
for _, event := range events {
switch event.Type {
case model.LoginPolicyAdded:
return errors.ThrowPreconditionFailed(nil, "EVENT-Ski9d", "Errors.IAM.LoginPolicy.AlreadyExists")
}
}
return nil
}
}
func checkExistingLoginPolicyIDPProviderValidation(idpConfigID string) func(...*es_models.Event) error {
return func(events ...*es_models.Event) error {
idpConfigs := make([]*model.IDPConfig, 0)
idps := make([]*model.IDPProvider, 0)
for _, event := range events {
switch event.Type {
case model.IDPConfigAdded:
config := new(model.IDPConfig)
config.SetData(event)
idpConfigs = append(idpConfigs, config)
case model.IDPConfigRemoved:
config := new(model.IDPConfig)
config.SetData(event)
for i, p := range idpConfigs {
if p.IDPConfigID == config.IDPConfigID {
idpConfigs[i] = idpConfigs[len(idpConfigs)-1]
idpConfigs[len(idpConfigs)-1] = nil
idpConfigs = idpConfigs[:len(idpConfigs)-1]
}
}
case model.LoginPolicyIDPProviderAdded:
idp := new(model.IDPProvider)
idp.SetData(event)
idps = append(idps, idp)
case model.LoginPolicyIDPProviderRemoved:
idp := new(model.IDPProvider)
idp.SetData(event)
for i, p := range idps {
if p.IDPConfigID == idp.IDPConfigID {
idps[i] = idps[len(idps)-1]
idps[len(idps)-1] = nil
idps = idps[:len(idps)-1]
}
}
}
}
exists := false
for _, p := range idpConfigs {
if p.IDPConfigID == idpConfigID {
exists = true
}
}
if !exists {
return errors.ThrowPreconditionFailed(nil, "EVENT-Djlo9", "Errors.IAM.IdpNotExisting")
}
for _, p := range idps {
if p.IDPConfigID == idpConfigID {
return errors.ThrowPreconditionFailed(nil, "EVENT-us5Zw", "Errors.IAM.LoginPolicy.IdpProviderAlreadyExisting")
}
}
return nil
}
}