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>
This commit is contained in:
Silvan
2020-08-31 17:48:01 +02:00
committed by GitHub
parent c1c85e632b
commit 5abd5b0505
207 changed files with 52837 additions and 26745 deletions

View File

@@ -82,7 +82,10 @@ func (m *IamMember) processIamMember(event *models.Event) (err error) {
func (m *IamMember) processUser(event *models.Event) (err error) {
switch event.Type {
case usr_es_model.UserProfileChanged,
usr_es_model.UserEmailChanged:
usr_es_model.UserEmailChanged,
usr_es_model.HumanProfileChanged,
usr_es_model.HumanEmailChanged,
usr_es_model.MachineChanged:
members, err := m.view.IAMMembersByUserID(event.AggregateID)
if err != nil {
return err
@@ -115,10 +118,15 @@ func (m *IamMember) fillData(member *iam_model.IAMMemberView) (err error) {
func (m *IamMember) fillUserData(member *iam_model.IAMMemberView, user *usr_model.User) {
member.UserName = user.UserName
member.FirstName = user.FirstName
member.LastName = user.LastName
member.Email = user.EmailAddress
member.DisplayName = user.DisplayName
if user.Human != nil {
member.FirstName = user.FirstName
member.LastName = user.LastName
member.DisplayName = user.FirstName + " " + user.LastName
member.Email = user.EmailAddress
}
if user.Machine != nil {
member.DisplayName = user.Machine.Name
}
}
func (m *IamMember) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-Ld9ow", "id", event.AggregateID).WithError(err).Warn("something went wrong in iammember handler")

View File

@@ -55,7 +55,10 @@ func (u *User) ProcessUser(event *models.Event) (err error) {
user := new(view_model.UserView)
switch event.Type {
case es_model.UserAdded,
es_model.UserRegistered:
es_model.UserRegistered,
es_model.HumanRegistered,
es_model.MachineAdded,
es_model.HumanAdded:
err = user.AppendEvent(event)
if err != nil {
return err
@@ -72,9 +75,20 @@ func (u *User) ProcessUser(event *models.Event) (err error) {
es_model.UserReactivated,
es_model.UserLocked,
es_model.UserUnlocked,
es_model.MfaOtpAdded,
es_model.MfaOtpVerified,
es_model.MfaOtpRemoved:
es_model.MFAOTPAdded,
es_model.MFAOTPVerified,
es_model.MFAOTPRemoved,
es_model.HumanProfileChanged,
es_model.HumanEmailChanged,
es_model.HumanEmailVerified,
es_model.HumanPhoneChanged,
es_model.HumanPhoneVerified,
es_model.HumanPhoneRemoved,
es_model.HumanAddressChanged,
es_model.HumanMFAOTPAdded,
es_model.HumanMFAOTPVerified,
es_model.HumanMFAOTPRemoved,
es_model.MachineChanged:
user, err = u.view.UserByID(event.AggregateID)
if err != nil {
return err
@@ -173,6 +187,6 @@ func (u *User) fillLoginNames(user *view_model.UserView) (err error) {
}
func (u *User) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-is8wa", "id", event.AggregateID).WithError(err).Warn("something went wrong in user handler")
logging.LogWithFields("SPOOL-vLmwQ", "id", event.AggregateID).WithError(err).Warn("something went wrong in user handler")
return spooler.HandleError(event, err, u.view.GetLatestUserFailedEvent, u.view.ProcessedUserFailedEvent, u.view.ProcessedUserSequence, u.errorCountUntilSkip)
}

View File

@@ -59,9 +59,9 @@ func addRoleContextIDToPerm(perm, roleContextID string) string {
return perm
}
func ExistsPerm(existing []string, perm string) bool {
for _, e := range existing {
if e == perm {
func ExistsPerm(existingPermissions []string, perm string) bool {
for _, existingPermission := range existingPermissions {
if existingPermission == perm {
return true
}
}

View File

@@ -419,8 +419,8 @@ func Test_AddRoleContextIDToPerm(t *testing.T) {
func Test_ExistisPerm(t *testing.T) {
type args struct {
existing []string
perm string
existingPermissions []string
perm string
}
tests := []struct {
name string
@@ -430,23 +430,23 @@ func Test_ExistisPerm(t *testing.T) {
{
name: "not existing perm",
args: args{
existing: []string{"perm1", "perm2", "perm3"},
perm: "perm4",
existingPermissions: []string{"perm1", "perm2", "perm3"},
perm: "perm4",
},
result: false,
},
{
name: "existing perm",
args: args{
existing: []string{"perm1", "perm2", "perm3"},
perm: "perm2",
existingPermissions: []string{"perm1", "perm2", "perm3"},
perm: "perm2",
},
result: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ExistsPerm(tt.args.existing, tt.args.perm)
result := ExistsPerm(tt.args.existingPermissions, tt.args.perm)
if result != tt.result {
t.Errorf("got wrong result, expecting: %v, actual: %v ", tt.result, result)
}

View File

@@ -3,7 +3,6 @@ package admin
import (
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
"golang.org/x/text/language"
admin_model "github.com/caos/zitadel/internal/admin/model"
"github.com/caos/zitadel/internal/eventstore/models"
@@ -32,39 +31,6 @@ func orgCreateRequestToModel(org *admin.CreateOrgRequest) *org_model.Org {
return o
}
func userCreateRequestToModel(user *admin.CreateUserRequest) *usr_model.User {
preferredLanguage, err := language.Parse(user.PreferredLanguage)
logging.Log("GRPC-30hwz").OnError(err).Debug("unable to parse language")
result := &usr_model.User{
Profile: &usr_model.Profile{
UserName: user.UserName,
FirstName: user.FirstName,
LastName: user.LastName,
NickName: user.NickName,
PreferredLanguage: preferredLanguage,
Gender: genderToModel(user.Gender),
},
Password: &usr_model.Password{
SecretString: user.Password,
},
Email: &usr_model.Email{
EmailAddress: user.Email,
IsEmailVerified: user.IsEmailVerified,
},
Address: &usr_model.Address{
Country: user.Country,
Locality: user.Locality,
PostalCode: user.PostalCode,
Region: user.Region,
StreetAddress: user.StreetAddress,
},
}
if user.Phone != "" {
result.Phone = &usr_model.Phone{PhoneNumber: user.Phone, IsPhoneVerified: user.IsPhoneVerified}
}
return result
}
func setUpOrgResponseFromModel(setUp *admin_model.SetupOrg) *admin.OrgSetUpResponse {
return &admin.OrgSetUpResponse{
Org: orgFromModel(setUp.Org),
@@ -126,45 +92,6 @@ func orgViewFromModel(org *org_model.OrgView) *admin.Org {
}
}
func userFromModel(user *usr_model.User) *admin.User {
creationDate, err := ptypes.TimestampProto(user.CreationDate)
logging.Log("GRPC-8duwe").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(user.ChangeDate)
logging.Log("GRPC-ckoe3d").OnError(err).Debug("unable to parse timestamp")
converted := &admin.User{
Id: user.AggregateID,
State: userStateFromModel(user.State),
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: user.Sequence,
UserName: user.UserName,
FirstName: user.FirstName,
LastName: user.LastName,
DisplayName: user.DisplayName,
NickName: user.NickName,
PreferredLanguage: user.PreferredLanguage.String(),
Gender: genderFromModel(user.Gender),
}
if user.Email != nil {
converted.Email = user.EmailAddress
converted.IsEmailVerified = user.IsEmailVerified
}
if user.Phone != nil {
converted.Phone = user.PhoneNumber
converted.IsPhoneVerified = user.IsPhoneVerified
}
if user.Address != nil {
converted.Country = user.Country
converted.Locality = user.Locality
converted.PostalCode = user.PostalCode
converted.Region = user.Region
converted.StreetAddress = user.StreetAddress
}
return converted
}
func orgStateFromModel(state org_model.OrgState) admin.OrgState {
switch state {
case org_model.OrgStateActive:
@@ -247,7 +174,7 @@ func orgQueryKeyToModel(key admin.OrgSearchKey) org_model.OrgSearchKey {
switch key {
case admin.OrgSearchKey_ORGSEARCHKEY_DOMAIN:
return org_model.OrgSearchKeyOrgDomain
case admin.OrgSearchKey_ORGSEARCHKEY_ORG_NAME:
case admin.OrgSearchKey_ORGSEARCHKEY_NAME:
return org_model.OrgSearchKeyOrgName
case admin.OrgSearchKey_ORGSEARCHKEY_STATE:
return org_model.OrgSearchKeyState

View File

@@ -0,0 +1,128 @@
package admin
import (
"github.com/caos/logging"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes"
"golang.org/x/text/language"
)
func userCreateRequestToModel(user *admin.CreateUserRequest) *usr_model.User {
var human *usr_model.Human
var machine *usr_model.Machine
if h := user.GetHuman(); h != nil {
human = humanCreateToModel(h)
}
if m := user.GetMachine(); m != nil {
machine = machineCreateToModel(m)
}
return &usr_model.User{
UserName: user.UserName,
Human: human,
Machine: machine,
}
}
func humanCreateToModel(u *admin.CreateHumanRequest) *usr_model.Human {
preferredLanguage, err := language.Parse(u.PreferredLanguage)
logging.Log("GRPC-1ouQc").OnError(err).Debug("language malformed")
human := &usr_model.Human{
Profile: &usr_model.Profile{
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
PreferredLanguage: preferredLanguage,
Gender: genderToModel(u.Gender),
},
Email: &usr_model.Email{
EmailAddress: u.Email,
IsEmailVerified: u.IsEmailVerified,
},
Address: &usr_model.Address{
Country: u.Country,
Locality: u.Locality,
PostalCode: u.PostalCode,
Region: u.Region,
StreetAddress: u.StreetAddress,
},
}
if u.Password != "" {
human.Password = &usr_model.Password{SecretString: u.Password}
}
if u.Phone != "" {
human.Phone = &usr_model.Phone{PhoneNumber: u.Phone, IsPhoneVerified: u.IsPhoneVerified}
}
return human
}
func machineCreateToModel(machine *admin.CreateMachineRequest) *usr_model.Machine {
return &usr_model.Machine{
Name: machine.Name,
Description: machine.Description,
}
}
func userFromModel(user *usr_model.User) *admin.UserResponse {
creationDate, err := ptypes.TimestampProto(user.CreationDate)
logging.Log("GRPC-yo0FW").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(user.ChangeDate)
logging.Log("GRPC-jxoQr").OnError(err).Debug("unable to parse timestamp")
userResp := &admin.UserResponse{
Id: user.AggregateID,
State: userStateFromModel(user.State),
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: user.Sequence,
UserName: user.UserName,
}
if user.Machine != nil {
userResp.User = &admin.UserResponse_Machine{Machine: machineFromModel(user.Machine)}
}
if user.Human != nil {
userResp.User = &admin.UserResponse_Human{Human: humanFromModel(user.Human)}
}
return userResp
}
func machineFromModel(account *usr_model.Machine) *admin.MachineResponse {
return &admin.MachineResponse{
Name: account.Name,
Description: account.Description,
}
}
func humanFromModel(user *usr_model.Human) *admin.HumanResponse {
human := &admin.HumanResponse{
FirstName: user.FirstName,
LastName: user.LastName,
DisplayName: user.DisplayName,
NickName: user.NickName,
PreferredLanguage: user.PreferredLanguage.String(),
Gender: genderFromModel(user.Gender),
}
if user.Email != nil {
human.Email = user.EmailAddress
human.IsEmailVerified = user.IsEmailVerified
}
if user.Phone != nil {
human.Phone = user.PhoneNumber
human.IsPhoneVerified = user.IsPhoneVerified
}
if user.Address != nil {
human.Country = user.Country
human.Locality = user.Locality
human.PostalCode = user.PostalCode
human.Region = user.Region
human.StreetAddress = user.StreetAddress
}
return human
}

View File

@@ -27,37 +27,28 @@ func userViewFromModel(user *usr_model.UserView) *auth.UserView {
lastLogin, err := ptypes.TimestampProto(user.LastLogin)
logging.Log("GRPC-Gteh2").OnError(err).Debug("unable to parse timestamp")
passwordChanged, err := ptypes.TimestampProto(user.PasswordChanged)
logging.Log("GRPC-fgQFT").OnError(err).Debug("unable to parse timestamp")
return &auth.UserView{
userView := &auth.UserView{
Id: user.ID,
State: userStateFromModel(user.State),
CreationDate: creationDate,
ChangeDate: changeDate,
LastLogin: lastLogin,
PasswordChanged: passwordChanged,
UserName: user.UserName,
FirstName: user.FirstName,
LastName: user.LastName,
DisplayName: user.DisplayName,
NickName: user.NickName,
PreferredLanguage: user.PreferredLanguage,
Gender: genderFromModel(user.Gender),
Email: user.Email,
IsEmailVerified: user.IsEmailVerified,
Phone: user.Phone,
IsPhoneVerified: user.IsPhoneVerified,
Country: user.Country,
Locality: user.Locality,
PostalCode: user.PostalCode,
Region: user.Region,
StreetAddress: user.StreetAddress,
Sequence: user.Sequence,
ResourceOwner: user.ResourceOwner,
LoginNames: user.LoginNames,
PreferredLoginName: user.PreferredLoginName,
}
if user.HumanView != nil {
userView.User = &auth.UserView_Human{Human: humanViewFromModel(user.HumanView)}
}
if user.MachineView != nil {
userView.User = &auth.UserView_Machine{Machine: machineViewFromModel(user.MachineView)}
}
return userView
}
func profileFromModel(profile *usr_model.Profile) *auth.UserProfile {
@@ -72,7 +63,6 @@ func profileFromModel(profile *usr_model.Profile) *auth.UserProfile {
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: profile.Sequence,
UserName: profile.UserName,
FirstName: profile.FirstName,
LastName: profile.LastName,
DisplayName: profile.DisplayName,
@@ -94,7 +84,6 @@ func profileViewFromModel(profile *usr_model.Profile) *auth.UserProfileView {
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: profile.Sequence,
UserName: profile.UserName,
FirstName: profile.FirstName,
LastName: profile.LastName,
DisplayName: profile.DisplayName,
@@ -366,7 +355,7 @@ func userChangesToAPI(changes *usr_model.UserChanges) (_ []*auth.Change) {
EventType: message.NewLocalizedEventType(change.EventType),
Sequence: change.Sequence,
Data: data,
EditorId: change.ModifierId,
EditorId: change.ModifierID,
Editor: change.ModifierName,
}
}

View File

@@ -0,0 +1,32 @@
package auth
import (
"github.com/caos/logging"
usr_model "github.com/caos/zitadel/internal/user/model"
auth "github.com/caos/zitadel/pkg/grpc/auth"
"github.com/golang/protobuf/ptypes"
)
func humanViewFromModel(user *usr_model.HumanView) *auth.HumanView {
passwordChanged, err := ptypes.TimestampProto(user.PasswordChanged)
logging.Log("MANAG-h4ByY").OnError(err).Debug("unable to parse date")
return &auth.HumanView{
FirstName: user.FirstName,
LastName: user.LastName,
DisplayName: user.DisplayName,
NickName: user.NickName,
PreferredLanguage: user.PreferredLanguage,
Gender: genderFromModel(user.Gender),
Email: user.Email,
IsEmailVerified: user.IsEmailVerified,
Phone: user.Phone,
IsPhoneVerified: user.IsPhoneVerified,
Country: user.Country,
Locality: user.Locality,
PostalCode: user.PostalCode,
Region: user.Region,
StreetAddress: user.StreetAddress,
PasswordChanged: passwordChanged,
}
}

View File

@@ -0,0 +1,51 @@
package auth
import (
"github.com/caos/logging"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/pkg/grpc/auth"
"github.com/golang/protobuf/ptypes"
)
func machineViewFromModel(machine *usr_model.MachineView) *auth.MachineView {
lastKeyAdded, err := ptypes.TimestampProto(machine.LastKeyAdded)
logging.Log("MANAG-wGcAQ").OnError(err).Debug("unable to parse date")
return &auth.MachineView{
Description: machine.Description,
Name: machine.Name,
LastKeyAdded: lastKeyAdded,
}
}
func machineKeyViewsFromModel(keys ...*usr_model.MachineKeyView) []*auth.MachineKeyView {
keyViews := make([]*auth.MachineKeyView, len(keys))
for i, key := range keys {
keyViews[i] = machineKeyViewFromModel(key)
}
return keyViews
}
func machineKeyViewFromModel(key *usr_model.MachineKeyView) *auth.MachineKeyView {
creationDate, err := ptypes.TimestampProto(key.CreationDate)
logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp")
expirationDate, err := ptypes.TimestampProto(key.CreationDate)
logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp")
return &auth.MachineKeyView{
Id: key.ID,
CreationDate: creationDate,
ExpirationDate: expirationDate,
Sequence: key.Sequence,
Type: machineKeyTypeFromModel(key.Type),
}
}
func machineKeyTypeFromModel(typ usr_model.MachineKeyType) auth.MachineKeyType {
switch typ {
case usr_model.MachineKeyTypeJSON:
return auth.MachineKeyType_MACHINEKEY_JSON
default:
return auth.MachineKeyType_MACHINEKEY_UNSPECIFIED
}
}

View File

@@ -3,11 +3,10 @@ package management
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetUserByID(ctx context.Context, id *management.UserID) (*management.UserView, error) {
@@ -52,7 +51,7 @@ func (s *Server) IsUserUnique(ctx context.Context, request *management.UniqueUse
return &management.UniqueUserResponse{IsUnique: unique}, nil
}
func (s *Server) CreateUser(ctx context.Context, in *management.CreateUserRequest) (*management.User, error) {
func (s *Server) CreateUser(ctx context.Context, in *management.CreateUserRequest) (*management.UserResponse, error) {
user, err := s.user.CreateUser(ctx, userCreateToModel(in))
if err != nil {
return nil, err
@@ -60,7 +59,7 @@ func (s *Server) CreateUser(ctx context.Context, in *management.CreateUserReques
return userFromModel(user), nil
}
func (s *Server) DeactivateUser(ctx context.Context, in *management.UserID) (*management.User, error) {
func (s *Server) DeactivateUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
user, err := s.user.DeactivateUser(ctx, in.Id)
if err != nil {
return nil, err
@@ -68,7 +67,7 @@ func (s *Server) DeactivateUser(ctx context.Context, in *management.UserID) (*ma
return userFromModel(user), nil
}
func (s *Server) ReactivateUser(ctx context.Context, in *management.UserID) (*management.User, error) {
func (s *Server) ReactivateUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
user, err := s.user.ReactivateUser(ctx, in.Id)
if err != nil {
return nil, err
@@ -76,7 +75,7 @@ func (s *Server) ReactivateUser(ctx context.Context, in *management.UserID) (*ma
return userFromModel(user), nil
}
func (s *Server) LockUser(ctx context.Context, in *management.UserID) (*management.User, error) {
func (s *Server) LockUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
user, err := s.user.LockUser(ctx, in.Id)
if err != nil {
return nil, err
@@ -84,7 +83,7 @@ func (s *Server) LockUser(ctx context.Context, in *management.UserID) (*manageme
return userFromModel(user), nil
}
func (s *Server) UnlockUser(ctx context.Context, in *management.UserID) (*management.User, error) {
func (s *Server) UnlockUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
user, err := s.user.UnlockUser(ctx, in.Id)
if err != nil {
return nil, err
@@ -96,6 +95,14 @@ func (s *Server) DeleteUser(ctx context.Context, in *management.UserID) (*empty.
return nil, errors.ThrowUnimplemented(nil, "GRPC-as4fg", "Not implemented")
}
func (s *Server) UpdateUserMachine(ctx context.Context, in *management.UpdateMachineRequest) (*management.MachineResponse, error) {
machine, err := s.user.ChangeMachine(ctx, updateMachineToModel(in))
if err != nil {
return nil, err
}
return machineFromModel(machine), nil
}
func (s *Server) GetUserProfile(ctx context.Context, in *management.UserID) (*management.UserProfileView, error) {
profile, err := s.user.ProfileByID(ctx, in.Id)
if err != nil {

View File

@@ -15,77 +15,48 @@ import (
"github.com/caos/zitadel/pkg/grpc/message"
)
func userFromModel(user *usr_model.User) *management.User {
func userFromModel(user *usr_model.User) *management.UserResponse {
creationDate, err := ptypes.TimestampProto(user.CreationDate)
logging.Log("GRPC-8duwe").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(user.ChangeDate)
logging.Log("GRPC-ckoe3d").OnError(err).Debug("unable to parse timestamp")
converted := &management.User{
Id: user.AggregateID,
State: userStateFromModel(user.State),
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: user.Sequence,
UserName: user.UserName,
FirstName: user.FirstName,
LastName: user.LastName,
DisplayName: user.DisplayName,
NickName: user.NickName,
PreferredLanguage: user.PreferredLanguage.String(),
Gender: genderFromModel(user.Gender),
userResp := &management.UserResponse{
Id: user.AggregateID,
State: userStateFromModel(user.State),
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: user.Sequence,
UserName: user.UserName,
}
if user.Email != nil {
converted.Email = user.EmailAddress
converted.IsEmailVerified = user.IsEmailVerified
if user.Machine != nil {
userResp.User = &management.UserResponse_Machine{Machine: machineFromModel(user.Machine)}
}
if user.Phone != nil {
converted.Phone = user.PhoneNumber
converted.IsPhoneVerified = user.IsPhoneVerified
if user.Human != nil {
userResp.User = &management.UserResponse_Human{Human: humanFromModel(user.Human)}
}
if user.Address != nil {
converted.Country = user.Country
converted.Locality = user.Locality
converted.PostalCode = user.PostalCode
converted.Region = user.Region
converted.StreetAddress = user.StreetAddress
}
return converted
return userResp
}
func userCreateToModel(u *management.CreateUserRequest) *usr_model.User {
preferredLanguage, err := language.Parse(u.PreferredLanguage)
logging.Log("GRPC-cK5k2").OnError(err).Debug("language malformed")
func userCreateToModel(user *management.CreateUserRequest) *usr_model.User {
var human *usr_model.Human
var machine *usr_model.Machine
user := &usr_model.User{
Profile: &usr_model.Profile{
UserName: u.UserName,
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
PreferredLanguage: preferredLanguage,
Gender: genderToModel(u.Gender),
},
Email: &usr_model.Email{
EmailAddress: u.Email,
IsEmailVerified: u.IsEmailVerified,
},
Address: &usr_model.Address{
Country: u.Country,
Locality: u.Locality,
PostalCode: u.PostalCode,
Region: u.Region,
StreetAddress: u.StreetAddress,
},
if h := user.GetHuman(); h != nil {
human = humanCreateToModel(h)
}
if u.Password != "" {
user.Password = &usr_model.Password{SecretString: u.Password}
if m := user.GetMachine(); m != nil {
machine = machineCreateToModel(m)
}
if u.Phone != "" {
user.Phone = &usr_model.Phone{PhoneNumber: u.Phone, IsPhoneVerified: u.IsPhoneVerified}
return &usr_model.User{
UserName: user.UserName,
Human: human,
Machine: machine,
}
return user
}
func passwordRequestToModel(r *management.PasswordRequest) *usr_model.Password {
@@ -135,6 +106,8 @@ func userSearchKeyToModel(key management.UserSearchKey) usr_model.UserSearchKey
return usr_model.UserSearchKeyEmail
case management.UserSearchKey_USERSEARCHKEY_STATE:
return usr_model.UserSearchKeyState
case management.UserSearchKey_USERSEARCHKEY_TYPE:
return usr_model.UserSearchKeyType
default:
return usr_model.UserSearchKeyUnspecified
}
@@ -187,7 +160,6 @@ func profileFromModel(profile *usr_model.Profile) *management.UserProfile {
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: profile.Sequence,
UserName: profile.UserName,
FirstName: profile.FirstName,
LastName: profile.LastName,
DisplayName: profile.DisplayName,
@@ -209,7 +181,6 @@ func profileViewFromModel(profile *usr_model.Profile) *management.UserProfileVie
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: profile.Sequence,
UserName: profile.UserName,
FirstName: profile.FirstName,
LastName: profile.LastName,
DisplayName: profile.DisplayName,
@@ -400,37 +371,26 @@ func userViewFromModel(user *usr_model.UserView) *management.UserView {
lastLogin, err := ptypes.TimestampProto(user.LastLogin)
logging.Log("GRPC-dksi3").OnError(err).Debug("unable to parse timestamp")
passwordChanged, err := ptypes.TimestampProto(user.PasswordChanged)
logging.Log("GRPC-dl9ws").OnError(err).Debug("unable to parse timestamp")
return &management.UserView{
userView := &management.UserView{
Id: user.ID,
State: userStateFromModel(user.State),
CreationDate: creationDate,
ChangeDate: changeDate,
LastLogin: lastLogin,
PasswordChanged: passwordChanged,
UserName: user.UserName,
FirstName: user.FirstName,
LastName: user.LastName,
DisplayName: user.DisplayName,
NickName: user.NickName,
PreferredLanguage: user.PreferredLanguage,
Gender: genderFromModel(user.Gender),
Email: user.Email,
IsEmailVerified: user.IsEmailVerified,
Phone: user.Phone,
IsPhoneVerified: user.IsPhoneVerified,
Country: user.Country,
Locality: user.Locality,
PostalCode: user.PostalCode,
Region: user.Region,
StreetAddress: user.StreetAddress,
Sequence: user.Sequence,
ResourceOwner: user.ResourceOwner,
LoginNames: user.LoginNames,
PreferredLoginName: user.PreferredLoginName,
UserName: user.UserName,
}
if user.HumanView != nil {
userView.User = &management.UserView_Human{Human: humanViewFromModel(user.HumanView)}
}
if user.MachineView != nil {
userView.User = &management.UserView_Machine{Machine: machineViewFromModel(user.MachineView)}
}
return userView
}
func userMembershipSearchResponseFromModel(response *usr_model.UserMembershipSearchResponse) *management.UserMembershipSearchResponse {
@@ -603,7 +563,7 @@ func userChangesToMgtAPI(changes *usr_model.UserChanges) (_ []*management.Change
EventType: message.NewLocalizedEventType(change.EventType),
Sequence: change.Sequence,
Data: data,
EditorId: change.ModifierId,
EditorId: change.ModifierID,
Editor: change.ModifierName,
}
}

View File

@@ -28,14 +28,6 @@ func usergrantFromModel(grant *grant_model.UserGrant) *management.UserGrant {
}
}
func userGrantCreateBulkToModel(u *management.UserGrantCreateBulk) []*grant_model.UserGrant {
grants := make([]*grant_model.UserGrant, len(u.UserGrants))
for i, grant := range u.UserGrants {
grants[i] = userGrantCreateToModel(grant)
}
return grants
}
func userGrantCreateToModel(u *management.UserGrantCreate) *grant_model.UserGrant {
return &grant_model.UserGrant{
ObjectRoot: models.ObjectRoot{AggregateID: u.UserId},
@@ -46,14 +38,6 @@ func userGrantCreateToModel(u *management.UserGrantCreate) *grant_model.UserGran
}
}
func userGrantUpdateBulkToModel(u *management.UserGrantUpdateBulk) []*grant_model.UserGrant {
grants := make([]*grant_model.UserGrant, len(u.UserGrants))
for i, grant := range u.UserGrants {
grants[i] = userGrantUpdateToModel(grant)
}
return grants
}
func userGrantUpdateToModel(u *management.UserGrantUpdate) *grant_model.UserGrant {
return &grant_model.UserGrant{
ObjectRoot: models.ObjectRoot{AggregateID: u.Id},
@@ -171,19 +155,3 @@ func usergrantStateFromModel(state grant_model.UserGrantState) management.UserGr
return management.UserGrantState_USERGRANTSTATE_UNSPECIFIED
}
}
func projectUserGrantSearchRequestsToModel(project *management.ProjectUserGrantSearchRequest) *grant_model.UserGrantSearchRequest {
return &grant_model.UserGrantSearchRequest{
Offset: project.Offset,
Limit: project.Limit,
Queries: userGrantSearchQueriesToModel(project.Queries),
}
}
func projectGrantUserGrantSearchRequestsToModel(project *management.ProjectGrantUserGrantSearchRequest) *grant_model.UserGrantSearchRequest {
return &grant_model.UserGrantSearchRequest{
Offset: project.Offset,
Limit: project.Limit,
Queries: userGrantSearchQueriesToModel(project.Queries),
}
}

View File

@@ -0,0 +1,94 @@
package management
import (
"github.com/caos/logging"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes"
"golang.org/x/text/language"
)
func humanFromModel(user *usr_model.Human) *management.HumanResponse {
human := &management.HumanResponse{
FirstName: user.FirstName,
LastName: user.LastName,
DisplayName: user.DisplayName,
NickName: user.NickName,
PreferredLanguage: user.PreferredLanguage.String(),
Gender: genderFromModel(user.Gender),
}
if user.Email != nil {
human.Email = user.EmailAddress
human.IsEmailVerified = user.IsEmailVerified
}
if user.Phone != nil {
human.Phone = user.PhoneNumber
human.IsPhoneVerified = user.IsPhoneVerified
}
if user.Address != nil {
human.Country = user.Country
human.Locality = user.Locality
human.PostalCode = user.PostalCode
human.Region = user.Region
human.StreetAddress = user.StreetAddress
}
return human
}
func humanViewFromModel(user *usr_model.HumanView) *management.HumanView {
passwordChanged, err := ptypes.TimestampProto(user.PasswordChanged)
logging.Log("MANAG-h4ByY").OnError(err).Debug("unable to parse date")
return &management.HumanView{
FirstName: user.FirstName,
LastName: user.LastName,
DisplayName: user.DisplayName,
NickName: user.NickName,
PreferredLanguage: user.PreferredLanguage,
Gender: genderFromModel(user.Gender),
Email: user.Email,
IsEmailVerified: user.IsEmailVerified,
Phone: user.Phone,
IsPhoneVerified: user.IsPhoneVerified,
Country: user.Country,
Locality: user.Locality,
PostalCode: user.PostalCode,
Region: user.Region,
StreetAddress: user.StreetAddress,
PasswordChanged: passwordChanged,
}
}
func humanCreateToModel(u *management.CreateHumanRequest) *usr_model.Human {
preferredLanguage, err := language.Parse(u.PreferredLanguage)
logging.Log("GRPC-cK5k2").OnError(err).Debug("language malformed")
human := &usr_model.Human{
Profile: &usr_model.Profile{
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
PreferredLanguage: preferredLanguage,
Gender: genderToModel(u.Gender),
},
Email: &usr_model.Email{
EmailAddress: u.Email,
IsEmailVerified: u.IsEmailVerified,
},
Address: &usr_model.Address{
Country: u.Country,
Locality: u.Locality,
PostalCode: u.PostalCode,
Region: u.Region,
StreetAddress: u.StreetAddress,
},
}
if u.Password != "" {
human.Password = &usr_model.Password{SecretString: u.Password}
}
if u.Phone != "" {
human.Phone = &usr_model.Phone{PhoneNumber: u.Phone, IsPhoneVerified: u.IsPhoneVerified}
}
return human
}

View File

@@ -0,0 +1,37 @@
package management
import (
"context"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) AddMachineKey(ctx context.Context, req *management.AddMachineKeyRequest) (*management.AddMachineKeyResponse, error) {
key, err := s.user.AddMachineKey(ctx, addMachineKeyToModel(req))
if err != nil {
return nil, err
}
return addMachineKeyFromModel(key), nil
}
func (s *Server) DeleteMachineKey(ctx context.Context, req *management.MachineKeyIDRequest) (*empty.Empty, error) {
err := s.user.RemoveMachineKey(ctx, req.UserId, req.KeyId)
return &empty.Empty{}, err
}
func (s *Server) GetMachineKey(ctx context.Context, req *management.MachineKeyIDRequest) (*management.MachineKeyView, error) {
key, err := s.user.GetMachineKey(ctx, req.UserId, req.KeyId)
if err != nil {
return nil, err
}
return machineKeyViewFromModel(key), nil
}
func (s *Server) SearchMachineKeys(ctx context.Context, req *management.MachineKeySearchRequest) (*management.MachineKeySearchResponse, error) {
result, err := s.user.SearchMachineKeys(ctx, machineKeySearchRequestToModel(req))
if err != nil {
return nil, err
}
return machineKeySearchResponseFromModel(result), nil
}

View File

@@ -0,0 +1,160 @@
package management
import (
"encoding/json"
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/model"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes"
)
func machineCreateToModel(machine *management.CreateMachineRequest) *usr_model.Machine {
return &usr_model.Machine{
Name: machine.Name,
Description: machine.Description,
}
}
func updateMachineToModel(machine *management.UpdateMachineRequest) *usr_model.Machine {
return &usr_model.Machine{
ObjectRoot: models.ObjectRoot{AggregateID: machine.Id},
Description: machine.Description,
}
}
func machineFromModel(account *usr_model.Machine) *management.MachineResponse {
return &management.MachineResponse{
Name: account.Name,
Description: account.Description,
}
}
func machineViewFromModel(machine *usr_model.MachineView) *management.MachineView {
lastKeyAdded, err := ptypes.TimestampProto(machine.LastKeyAdded)
logging.Log("MANAG-wGcAQ").OnError(err).Debug("unable to parse date")
return &management.MachineView{
Description: machine.Description,
Name: machine.Name,
LastKeyAdded: lastKeyAdded,
}
}
func machineKeyViewsFromModel(keys ...*usr_model.MachineKeyView) []*management.MachineKeyView {
keyViews := make([]*management.MachineKeyView, len(keys))
for i, key := range keys {
keyViews[i] = machineKeyViewFromModel(key)
}
return keyViews
}
func machineKeyViewFromModel(key *usr_model.MachineKeyView) *management.MachineKeyView {
creationDate, err := ptypes.TimestampProto(key.CreationDate)
logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp")
expirationDate, err := ptypes.TimestampProto(key.ExpirationDate)
logging.Log("MANAG-gluk7").OnError(err).Debug("unable to parse timestamp")
return &management.MachineKeyView{
Id: key.ID,
CreationDate: creationDate,
ExpirationDate: expirationDate,
Sequence: key.Sequence,
Type: machineKeyTypeFromModel(key.Type),
}
}
func addMachineKeyToModel(key *management.AddMachineKeyRequest) *usr_model.MachineKey {
expirationDate := time.Time{}
if key.ExpirationDate != nil {
var err error
expirationDate, err = ptypes.Timestamp(key.ExpirationDate)
logging.Log("MANAG-iNshR").OnError(err).Debug("unable to parse expiration date")
}
return &usr_model.MachineKey{
ExpirationDate: expirationDate,
Type: machineKeyTypeToModel(key.Type),
ObjectRoot: models.ObjectRoot{AggregateID: key.UserId},
}
}
func addMachineKeyFromModel(key *usr_model.MachineKey) *management.AddMachineKeyResponse {
creationDate, err := ptypes.TimestampProto(key.CreationDate)
logging.Log("MANAG-dlb8m").OnError(err).Debug("unable to parse cretaion date")
expirationDate, err := ptypes.TimestampProto(key.ExpirationDate)
logging.Log("MANAG-dlb8m").OnError(err).Debug("unable to parse cretaion date")
detail, err := json.Marshal(struct {
Type string `json:"type"`
KeyID string `json:"keyId"`
Key []byte `json:"key"`
UserID string `json:"userId"`
}{
Type: "serviceaccount",
KeyID: key.KeyID,
Key: key.PrivateKey,
UserID: key.AggregateID,
})
logging.Log("MANAG-lFQ2g").OnError(err).Warn("unable to marshall key")
return &management.AddMachineKeyResponse{
Id: key.KeyID,
CreationDate: creationDate,
ExpirationDate: expirationDate,
Sequence: key.Sequence,
KeyDetails: detail,
Type: machineKeyTypeFromModel(key.Type),
}
}
func machineKeyTypeToModel(typ management.MachineKeyType) usr_model.MachineKeyType {
switch typ {
case management.MachineKeyType_MACHINEKEY_JSON:
return usr_model.MachineKeyTypeJSON
default:
return usr_model.MachineKeyTypeNONE
}
}
func machineKeyTypeFromModel(typ usr_model.MachineKeyType) management.MachineKeyType {
switch typ {
case usr_model.MachineKeyTypeJSON:
return management.MachineKeyType_MACHINEKEY_JSON
default:
return management.MachineKeyType_MACHINEKEY_UNSPECIFIED
}
}
func machineKeySearchRequestToModel(req *management.MachineKeySearchRequest) *usr_model.MachineKeySearchRequest {
return &usr_model.MachineKeySearchRequest{
Offset: req.Offset,
Limit: req.Limit,
Asc: req.Asc,
Queries: []*usr_model.MachineKeySearchQuery{
{
Key: usr_model.MachineKeyKeyUserID,
Method: model.SearchMethodEquals,
Value: req.UserId,
},
},
}
}
func machineKeySearchResponseFromModel(req *usr_model.MachineKeySearchResponse) *management.MachineKeySearchResponse {
viewTimestamp, err := ptypes.TimestampProto(req.Timestamp)
logging.Log("MANAG-Sk9ds").OnError(err).Debug("unable to parse cretaion date")
return &management.MachineKeySearchResponse{
Offset: req.Offset,
Limit: req.Limit,
TotalResult: req.TotalResult,
ProcessedSequence: req.Sequence,
ViewTimestamp: viewTimestamp,
Result: machineKeyViewsFromModel(req.Result...),
}
}

View File

@@ -0,0 +1,31 @@
package middleware
import (
"context"
"google.golang.org/grpc"
_ "github.com/caos/zitadel/internal/statik"
)
func ValidationHandler() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
return validate(ctx, req, info, handler)
}
}
type validator interface {
Validate() error
}
func validate(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
validate, ok := req.(validator)
if !ok {
return handler(ctx, req)
}
err := validate.Validate()
if err != nil {
return nil, err
}
return handler(ctx, req)
}

View File

@@ -33,6 +33,7 @@ func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, lang l
middleware.ErrorHandler(),
middleware.AuthorizationInterceptor(verifier, authConfig),
middleware.TranslationHandler(lang),
middleware.ValidationHandler(),
),
),
)

View File

@@ -356,7 +356,12 @@ func userSessionByIDs(ctx context.Context, provider userSessionViewProvider, eve
es_model.MfaOtpCheckFailed,
es_model.SignedOut,
es_model.UserLocked,
es_model.UserDeactivated:
es_model.UserDeactivated,
es_model.HumanPasswordCheckSucceeded,
es_model.HumanPasswordCheckFailed,
es_model.HumanMfaOtpCheckSucceeded,
es_model.HumanMfaOtpCheckFailed,
es_model.HumanSignedOut:
eventData, err := user_view_model.UserSessionFromEvent(event)
if err != nil {
logging.Log("EVENT-sdgT3").WithError(err).Debug("error getting event data")
@@ -378,6 +383,11 @@ func activeUserByID(ctx context.Context, userViewProvider userViewProvider, user
if err != nil {
return nil, err
}
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Lm69x", "Errors.User.NotHuman")
}
if user.State == user_model.UserStateLocked || user.State == user_model.UserStateSuspend {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-FJ262", "Errors.User.Locked")
}

View File

@@ -106,14 +106,18 @@ type mockViewUser struct {
func (m *mockViewUser) UserByID(string) (*user_view_model.UserView, error) {
return &user_view_model.UserView{
InitRequired: m.InitRequired,
PasswordSet: m.PasswordSet,
PasswordChangeRequired: m.PasswordChangeRequired,
IsEmailVerified: m.IsEmailVerified,
OTPState: m.OTPState,
MfaMaxSetUp: m.MfaMaxSetUp,
MfaInitSkipped: m.MfaInitSkipped,
State: int32(user_model.UserStateActive),
State: int32(user_model.UserStateActive),
UserName: "schofseckel",
HumanView: &user_view_model.HumanView{
FirstName: "schof",
InitRequired: m.InitRequired,
PasswordSet: m.PasswordSet,
PasswordChangeRequired: m.PasswordChangeRequired,
IsEmailVerified: m.IsEmailVerified,
OTPState: m.OTPState,
MfaMaxSetUp: m.MfaMaxSetUp,
MfaInitSkipped: m.MfaInitSkipped,
},
}, nil
}
@@ -564,7 +568,9 @@ func TestAuthRequestRepo_mfaChecked(t *testing.T) {
args{
request: &model.AuthRequest{},
user: &user_model.UserView{
MfaMaxSetUp: model.MfaLevelNotSetUp,
HumanView: &user_model.HumanView{
MfaMaxSetUp: model.MfaLevelNotSetUp,
},
},
},
&model.MfaPromptStep{
@@ -582,8 +588,10 @@ func TestAuthRequestRepo_mfaChecked(t *testing.T) {
args{
request: &model.AuthRequest{},
user: &user_model.UserView{
MfaMaxSetUp: model.MfaLevelNotSetUp,
MfaInitSkipped: time.Now().UTC(),
HumanView: &user_model.HumanView{
MfaMaxSetUp: model.MfaLevelNotSetUp,
MfaInitSkipped: time.Now().UTC(),
},
},
},
nil,
@@ -597,8 +605,10 @@ func TestAuthRequestRepo_mfaChecked(t *testing.T) {
args{
request: &model.AuthRequest{},
user: &user_model.UserView{
MfaMaxSetUp: model.MfaLevelSoftware,
OTPState: user_model.MfaStateReady,
HumanView: &user_model.HumanView{
MfaMaxSetUp: model.MfaLevelSoftware,
OTPState: user_model.MfaStateReady,
},
},
userSession: &user_model.UserSessionView{MfaSoftwareVerification: time.Now().UTC().Add(-5 * time.Hour)},
},
@@ -613,8 +623,10 @@ func TestAuthRequestRepo_mfaChecked(t *testing.T) {
args{
request: &model.AuthRequest{},
user: &user_model.UserView{
MfaMaxSetUp: model.MfaLevelSoftware,
OTPState: user_model.MfaStateReady,
HumanView: &user_model.HumanView{
MfaMaxSetUp: model.MfaLevelSoftware,
OTPState: user_model.MfaStateReady,
},
},
userSession: &user_model.UserSessionView{},
},
@@ -658,7 +670,9 @@ func TestAuthRequestRepo_mfaSkippedOrSetUp(t *testing.T) {
"mfa set up, true",
fields{},
args{&user_model.UserView{
MfaMaxSetUp: model.MfaLevelSoftware,
HumanView: &user_model.HumanView{
MfaMaxSetUp: model.MfaLevelSoftware,
},
}},
true,
},
@@ -668,8 +682,10 @@ func TestAuthRequestRepo_mfaSkippedOrSetUp(t *testing.T) {
MfaInitSkippedLifeTime: 30 * 24 * time.Hour,
},
args{&user_model.UserView{
MfaMaxSetUp: -1,
MfaInitSkipped: time.Now().UTC().Add(-10 * time.Hour),
HumanView: &user_model.HumanView{
MfaMaxSetUp: -1,
MfaInitSkipped: time.Now().UTC().Add(-10 * time.Hour),
},
}},
true,
},
@@ -679,8 +695,10 @@ func TestAuthRequestRepo_mfaSkippedOrSetUp(t *testing.T) {
MfaInitSkippedLifeTime: 30 * 24 * time.Hour,
},
args{&user_model.UserView{
MfaMaxSetUp: -1,
MfaInitSkipped: time.Now().UTC().Add(-40 * 24 * time.Hour),
HumanView: &user_model.HumanView{
MfaMaxSetUp: -1,
MfaInitSkipped: time.Now().UTC().Add(-40 * 24 * time.Hour),
},
}},
false,
},
@@ -735,7 +753,7 @@ func Test_userSessionByIDs(t *testing.T) {
userProvider: &mockViewUserSession{
PasswordVerification: time.Now().UTC().Round(1 * time.Second),
},
user: &user_model.UserView{ID: "id"},
user: &user_model.UserView{ID: "id", HumanView: &user_model.HumanView{FirstName: "schof"}},
eventProvider: &mockEventErrUser{},
},
&user_model.UserSessionView{
@@ -752,7 +770,7 @@ func Test_userSessionByIDs(t *testing.T) {
PasswordVerification: time.Now().UTC().Round(1 * time.Second),
},
agentID: "agentID",
user: &user_model.UserView{ID: "id"},
user: &user_model.UserView{ID: "id", HumanView: &user_model.HumanView{FirstName: "schof"}},
eventProvider: &mockEventUser{
&es_models.Event{
AggregateType: user_es_model.UserAggregate,
@@ -802,7 +820,7 @@ func Test_userSessionByIDs(t *testing.T) {
PasswordVerification: time.Now().UTC().Round(1 * time.Second),
},
agentID: "agentID",
user: &user_model.UserView{ID: "id"},
user: &user_model.UserView{ID: "id", HumanView: &user_model.HumanView{FirstName: "schof"}},
eventProvider: &mockEventUser{
&es_models.Event{
AggregateType: user_es_model.UserAggregate,
@@ -884,8 +902,12 @@ func Test_userByID(t *testing.T) {
eventProvider: &mockEventErrUser{},
},
&user_model.UserView{
PasswordChangeRequired: true,
State: user_model.UserStateActive,
State: user_model.UserStateActive,
UserName: "schofseckel",
HumanView: &user_model.HumanView{
PasswordChangeRequired: true,
FirstName: "schof",
},
},
nil,
},
@@ -905,8 +927,12 @@ func Test_userByID(t *testing.T) {
},
},
&user_model.UserView{
PasswordChangeRequired: true,
State: user_model.UserStateActive,
State: user_model.UserStateActive,
UserName: "schofseckel",
HumanView: &user_model.HumanView{
PasswordChangeRequired: true,
FirstName: "schof",
},
},
nil,
},
@@ -929,10 +955,14 @@ func Test_userByID(t *testing.T) {
},
},
&user_model.UserView{
PasswordChangeRequired: false,
ChangeDate: time.Now().UTC().Round(1 * time.Second),
State: user_model.UserStateActive,
PasswordChanged: time.Now().UTC().Round(1 * time.Second),
ChangeDate: time.Now().UTC().Round(1 * time.Second),
State: user_model.UserStateActive,
UserName: "schofseckel",
HumanView: &user_model.HumanView{
PasswordChangeRequired: false,
PasswordChanged: time.Now().UTC().Round(1 * time.Second),
FirstName: "schof",
},
},
nil,
},

View File

@@ -74,7 +74,10 @@ func (repo *UserRepo) MyProfile(ctx context.Context) (*model.Profile, error) {
if err != nil {
return nil, err
}
return user.GetProfile(), nil
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-H2JIT", "Errors.User.NotHuman")
}
return user.GetProfile()
}
func (repo *UserRepo) ChangeMyProfile(ctx context.Context, profile *model.Profile) (*model.Profile, error) {
@@ -89,7 +92,10 @@ func (repo *UserRepo) MyEmail(ctx context.Context) (*model.Email, error) {
if err != nil {
return nil, err
}
return user.GetEmail(), nil
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-oGRpc", "Errors.User.NotHuman")
}
return user.GetEmail()
}
func (repo *UserRepo) ChangeMyEmail(ctx context.Context, email *model.Email) (*model.Email, error) {
@@ -120,7 +126,10 @@ func (repo *UserRepo) MyPhone(ctx context.Context) (*model.Phone, error) {
if err != nil {
return nil, err
}
return user.GetPhone(), nil
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-DTWJb", "Errors.User.NotHuman")
}
return user.GetPhone()
}
func (repo *UserRepo) ChangeMyPhone(ctx context.Context, phone *model.Phone) (*model.Phone, error) {
@@ -147,7 +156,10 @@ func (repo *UserRepo) MyAddress(ctx context.Context) (*model.Address, error) {
if err != nil {
return nil, err
}
return user.GetAddress(), nil
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Ok9nI", "Errors.User.NotHuman")
}
return user.GetAddress()
}
func (repo *UserRepo) ChangeMyAddress(ctx context.Context, address *model.Address) (*model.Address, error) {
@@ -190,7 +202,7 @@ func (repo *UserRepo) AddMfaOTP(ctx context.Context, userID string) (*model.OTP,
accountName := ""
user, err := repo.UserByID(ctx, userID)
if err != nil {
logging.Log("EVENT-Fk93s").OnError(err).Debug("unable to get user for loginname")
logging.Log("EVENT-Fk93s").WithError(err).Debug("unable to get user for loginname")
} else {
accountName = user.PreferredLoginName
}
@@ -201,7 +213,7 @@ func (repo *UserRepo) AddMyMfaOTP(ctx context.Context) (*model.OTP, error) {
accountName := ""
user, err := repo.UserByID(ctx, authz.GetCtxData(ctx).UserID)
if err != nil {
logging.Log("EVENT-Ml0sd").OnError(err).Debug("unable to get user for loginname")
logging.Log("EVENT-Ml0sd").WithError(err).Debug("unable to get user for loginname")
} else {
accountName = user.PreferredLoginName
}
@@ -298,8 +310,8 @@ func (repo *UserRepo) MyUserChanges(ctx context.Context, lastSequence uint64, li
return nil, err
}
for _, change := range changes.Changes {
change.ModifierName = change.ModifierId
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierId)
change.ModifierName = change.ModifierID
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierID)
if user != nil {
change.ModifierName = user.DisplayName
}

View File

@@ -3,10 +3,8 @@ package handler
import (
"context"
"encoding/json"
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
es_models "github.com/caos/zitadel/internal/eventstore/models"
@@ -14,6 +12,7 @@ import (
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
project_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
user_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
)
type Token struct {
@@ -44,7 +43,8 @@ func (u *Token) EventQuery() (*models.SearchQuery, error) {
func (u *Token) Reduce(event *models.Event) (err error) {
switch event.Type {
case user_es_model.UserProfileChanged:
case user_es_model.UserProfileChanged,
user_es_model.HumanProfileChanged:
user := new(view_model.UserView)
user.AppendEvent(event)
tokens, err := u.view.TokensByUserID(event.AggregateID)
@@ -55,7 +55,8 @@ func (u *Token) Reduce(event *models.Event) (err error) {
token.PreferredLanguage = user.PreferredLanguage
}
return u.view.PutTokens(tokens, event.Sequence)
case user_es_model.SignedOut:
case user_es_model.SignedOut,
user_es_model.HumanSignedOut:
id, err := agentIDFromSession(event)
if err != nil {
return err
@@ -86,7 +87,6 @@ func (u *Token) Reduce(event *models.Event) (err error) {
default:
return u.view.ProcessedTokenSequence(event.Sequence)
}
return nil
}
func (u *Token) OnError(event *models.Event, err error) error {

View File

@@ -56,7 +56,10 @@ func (u *User) ProcessUser(event *models.Event) (err error) {
user := new(view_model.UserView)
switch event.Type {
case es_model.UserAdded,
es_model.UserRegistered:
es_model.MachineAdded,
es_model.HumanAdded,
es_model.UserRegistered,
es_model.HumanRegistered:
err = user.AppendEvent(event)
if err != nil {
return err
@@ -73,11 +76,24 @@ func (u *User) ProcessUser(event *models.Event) (err error) {
es_model.UserReactivated,
es_model.UserLocked,
es_model.UserUnlocked,
es_model.MfaOtpAdded,
es_model.MfaOtpVerified,
es_model.MfaOtpRemoved,
es_model.MfaInitSkipped,
es_model.UserPasswordChanged:
es_model.MFAOTPAdded,
es_model.MFAOTPVerified,
es_model.MFAOTPRemoved,
es_model.MFAInitSkipped,
es_model.UserPasswordChanged,
es_model.HumanProfileChanged,
es_model.HumanEmailChanged,
es_model.HumanEmailVerified,
es_model.HumanPhoneChanged,
es_model.HumanPhoneVerified,
es_model.HumanPhoneRemoved,
es_model.HumanAddressChanged,
es_model.HumanMFAOTPAdded,
es_model.HumanMFAOTPVerified,
es_model.HumanMFAOTPRemoved,
es_model.HumanMfaInitSkipped,
es_model.MachineChanged,
es_model.HumanPasswordChanged:
user, err = u.view.UserByID(event.AggregateID)
if err != nil {
return err
@@ -176,6 +192,6 @@ func (u *User) fillPreferredLoginNamesOnOrgUsers(event *models.Event) error {
}
func (u *User) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-is8wa", "id", event.AggregateID).WithError(err).Warn("something went wrong in user handler")
logging.LogWithFields("SPOOL-is8aAWima", "id", event.AggregateID).WithError(err).Warn("something went wrong in user handler")
return spooler.HandleError(event, err, u.view.GetLatestUserFailedEvent, u.view.ProcessedUserFailedEvent, u.view.ProcessedUserSequence, u.errorCountUntilSkip)
}

View File

@@ -110,7 +110,10 @@ func (u *UserGrant) processUserGrant(event *models.Event) (err error) {
func (u *UserGrant) processUser(event *models.Event) (err error) {
switch event.Type {
case usr_es_model.UserProfileChanged,
usr_es_model.UserEmailChanged:
usr_es_model.UserEmailChanged,
usr_es_model.HumanProfileChanged,
usr_es_model.HumanEmailChanged,
usr_es_model.MachineChanged:
grants, err := u.view.UserGrantsByUserID(event.AggregateID)
if err != nil {
return err
@@ -276,13 +279,13 @@ func suffixRoles(suffix string, roles []string) []string {
func mergeExistingRoles(rolePrefix, suffix string, existingRoles, newRoles []string) []string {
mergedRoles := make([]string, 0)
for _, existing := range existingRoles {
if !strings.HasPrefix(existing, rolePrefix) {
mergedRoles = append(mergedRoles, existing)
for _, existingRole := range existingRoles {
if !strings.HasPrefix(existingRole, rolePrefix) {
mergedRoles = append(mergedRoles, existingRole)
continue
}
if suffix != "" && !strings.HasSuffix(existing, suffix) {
mergedRoles = append(mergedRoles, existing)
if suffix != "" && !strings.HasSuffix(existingRole, suffix) {
mergedRoles = append(mergedRoles, existingRole)
}
}
return append(mergedRoles, newRoles...)
@@ -325,9 +328,15 @@ func (u *UserGrant) fillData(grant *view_model.UserGrantView, resourceOwner stri
func (u *UserGrant) fillUserData(grant *view_model.UserGrantView, user *usr_model.User) {
grant.UserName = user.UserName
grant.FirstName = user.FirstName
grant.LastName = user.LastName
grant.Email = user.EmailAddress
if user.Human != nil {
grant.FirstName = user.FirstName
grant.LastName = user.LastName
grant.DisplayName = user.FirstName + " " + user.LastName
grant.Email = user.EmailAddress
}
if user.Machine != nil {
grant.DisplayName = user.Machine.Name
}
}
func (u *UserGrant) fillProjectData(grant *view_model.UserGrantView, project *proj_model.Project) {

View File

@@ -42,7 +42,12 @@ func (u *UserSession) Reduce(event *models.Event) (err error) {
es_model.UserPasswordCheckFailed,
es_model.MfaOtpCheckSucceeded,
es_model.MfaOtpCheckFailed,
es_model.SignedOut:
es_model.SignedOut,
es_model.HumanPasswordCheckSucceeded,
es_model.HumanPasswordCheckFailed,
es_model.HumanMfaOtpCheckSucceeded,
es_model.HumanMfaOtpCheckFailed,
es_model.HumanSignedOut:
eventData, err := view_model.UserSessionFromEvent(event)
if err != nil {
return err
@@ -62,10 +67,13 @@ func (u *UserSession) Reduce(event *models.Event) (err error) {
}
return u.updateSession(session, event)
case es_model.UserPasswordChanged,
es_model.MfaOtpRemoved,
es_model.MFAOTPRemoved,
es_model.UserProfileChanged,
es_model.UserLocked,
es_model.UserDeactivated,
es_model.HumanPasswordChanged,
es_model.HumanMFAOTPRemoved,
es_model.HumanProfileChanged,
es_model.DomainClaimed,
es_model.UserUserNameChanged:
sessions, err := u.view.UserSessionsByUserID(event.AggregateID)

View File

@@ -76,7 +76,6 @@ func (u *UserGrant) processProject(event *models.Event) (err error) {
default:
return u.view.ProcessedUserGrantSequence(event.Sequence)
}
return nil
}
func (u *UserGrant) processOrg(event *models.Event) (err error) {
@@ -88,7 +87,6 @@ func (u *UserGrant) processOrg(event *models.Event) (err error) {
default:
return u.view.ProcessedUserGrantSequence(event.Sequence)
}
return nil
}
func (u *UserGrant) processIamMember(event *models.Event, rolePrefix string, suffix bool) error {
@@ -194,13 +192,13 @@ func suffixRoles(suffix string, roles []string) []string {
func mergeExistingRoles(rolePrefix, suffix string, existingRoles, newRoles []string) []string {
mergedRoles := make([]string, 0)
for _, existing := range existingRoles {
if !strings.HasPrefix(existing, rolePrefix) {
mergedRoles = append(mergedRoles, existing)
for _, existingRole := range existingRoles {
if !strings.HasPrefix(existingRole, rolePrefix) {
mergedRoles = append(mergedRoles, existingRole)
continue
}
if suffix != "" && !strings.HasSuffix(existing, suffix) {
mergedRoles = append(mergedRoles, existing)
if suffix != "" && !strings.HasSuffix(existingRole, suffix) {
mergedRoles = append(mergedRoles, existingRole)
}
}
return append(mergedRoles, newRoles...)

View File

@@ -40,6 +40,7 @@ type SecretGenerators struct {
EmailVerificationCode crypto.GeneratorConfig
PhoneVerificationCode crypto.GeneratorConfig
PasswordVerificationCode crypto.GeneratorConfig
MachineKeySize uint32
}
type MultifactorConfig struct {

View File

@@ -86,9 +86,6 @@ func (a *Aggregate) Validate() error {
return errors.ThrowPreconditionFailed(nil, "MODEL-eBYUW", "resource owner not set")
}
if a.Precondition != nil && (a.Precondition.Query == nil || a.Precondition.Validation == nil) {
if err := a.Precondition.Query.Validate(); err != nil {
return err
}
return errors.ThrowPreconditionFailed(nil, "MODEL-EEUvA", "invalid precondition")
}

View File

@@ -90,7 +90,7 @@ func (s *spooledHandler) awaitError(cancel func(), errs chan error, workerID str
select {
case err := <-errs:
cancel()
logging.Log("SPOOL-K2lst").OnError(err).WithField("view", s.ViewModel()).WithField("worker", workerID).Debug("load canceled")
logging.Log("SPOOL-OT8di").OnError(err).WithField("view", s.ViewModel()).WithField("worker", workerID).Debug("load canceled")
}
}
@@ -164,7 +164,7 @@ func (s *spooledHandler) lock(ctx context.Context, errs chan<- error, workerID s
case <-renewTimer:
logging.Log("SPOOL-K2lst").WithField("view", s.ViewModel()).WithField("worker", workerID).Debug("renew")
err := s.locker.Renew(workerID, s.ViewModel(), s.MinimumCycleDuration()*2)
logging.Log("SPOOL-K2lst").WithField("view", s.ViewModel()).WithField("worker", workerID).WithError(err).Debug("renew done")
logging.Log("SPOOL-u4j6k").WithField("view", s.ViewModel()).WithField("worker", workerID).WithError(err).Debug("renew done")
if err == nil {
locked <- true
renewTimer = time.After(renewDuration)

View File

@@ -1,8 +1,9 @@
package model
import (
"github.com/caos/zitadel/internal/model"
"time"
"github.com/caos/zitadel/internal/model"
)
type IAMMemberView struct {

View File

@@ -2,6 +2,7 @@ package eventsourcing
import (
"context"
"github.com/caos/zitadel/internal/cache/config"
sd "github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/crypto"
@@ -190,12 +191,12 @@ func (es *IAMEventstore) RemoveIAMMember(ctx context.Context, member *iam_model.
if _, m := existing.GetMember(member.UserID); m == nil {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-29skr", "Errors.IAM.MemberNotExisting")
}
repoIam := model.IAMFromModel(existing)
repoIAM := model.IAMFromModel(existing)
repoMember := model.IAMMemberFromModel(member)
projectAggregate := IAMMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMember)
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, projectAggregate)
es.iamCache.cacheIAM(repoIam)
projectAggregate := IAMMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoIAM, repoMember)
err = es_sdk.Push(ctx, es.PushAggregates, repoIAM.AppendEvents, projectAggregate)
es.iamCache.cacheIAM(repoIAM)
return err
}

View File

@@ -554,10 +554,10 @@ func TestChangeIamMember(t *testing.T) {
func TestRemoveIamMember(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {
es *IAMEventstore
ctx context.Context
existing *model.IAM
member *iam_model.IAMMember
es *IAMEventstore
ctx context.Context
existingIAM *model.IAM
member *iam_model.IAMMember
}
type res struct {
result *iam_model.IAMMember
@@ -573,7 +573,7 @@ func TestRemoveIamMember(t *testing.T) {
args: args{
es: GetMockManipulateIamWithMember(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.IAM{
existingIAM: &model.IAM{
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1},
Members: []*model.IAMMember{{UserID: "UserID", Roles: []string{"Roles"}}},
},
@@ -588,7 +588,7 @@ func TestRemoveIamMember(t *testing.T) {
args: args{
es: GetMockManipulateIam(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.IAM{
existingIAM: &model.IAM{
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1},
Members: []*model.IAMMember{{UserID: "UserID", Roles: []string{"Roles"}}},
},
@@ -603,7 +603,7 @@ func TestRemoveIamMember(t *testing.T) {
args: args{
es: GetMockManipulateIam(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.IAM{
existingIAM: &model.IAM{
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1},
},
member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}},

View File

@@ -2,6 +2,7 @@ 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"
@@ -83,12 +84,12 @@ func IAMSetIamProjectAggregate(aggCreator *es_models.AggregateCreator, iam *mode
}
}
func IAMMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, member *model.IAMMember) func(ctx context.Context) (*es_models.Aggregate, error) {
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, existing)
agg, err := IAMAggregate(ctx, aggCreator, existingIAM)
if err != nil {
return nil, err
}
@@ -96,13 +97,13 @@ func IAMMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existing *m
}
}
func IAMMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, member *model.IAMMember) func(ctx context.Context) (*es_models.Aggregate, error) {
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, existing)
agg, err := IAMAggregate(ctx, aggCreator, existingIAM)
if err != nil {
return nil, err
}
@@ -110,12 +111,12 @@ func IAMMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existing
}
}
func IAMMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, member *model.IAMMember) func(ctx context.Context) (*es_models.Aggregate, error) {
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, existing)
agg, err := IAMAggregate(ctx, aggCreator, existingIAM)
if err != nil {
return nil, err
}

File diff suppressed because it is too large Load Diff

View File

@@ -64,6 +64,7 @@ func (es *KeyEventstore) GenerateKeyPair(ctx context.Context, usage key_model.Ke
},
})
}
func (es *KeyEventstore) CreateKeyPair(ctx context.Context, pair *key_model.KeyPair) (*key_model.KeyPair, error) {
if !pair.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-G34ga", "Name is required")

View File

@@ -501,8 +501,8 @@ func (repo *ProjectRepo) ChangeProjectGrant(ctx context.Context, grant *proj_mod
ProjectID: grant.ProjectID,
UserID: grant.UserID,
}
existing := changed.RemoveRoleKeysIfExisting(removedRoles)
if existing {
roleDeleted := changed.RemoveRoleKeysIfExisting(removedRoles)
if roleDeleted {
_, agg, err := repo.UserGrantEvents.PrepareChangeUserGrant(ctx, changed, true)
if err != nil {
return nil, err

View File

@@ -2,20 +2,20 @@ package eventstore
import (
"context"
"github.com/caos/zitadel/internal/config/systemdefaults"
caos_errs "github.com/caos/zitadel/internal/errors"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/errors"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/management/repository/eventsourcing/view"
global_model "github.com/caos/zitadel/internal/model"
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
policy_event "github.com/caos/zitadel/internal/policy/repository/eventsourcing"
usr_model "github.com/caos/zitadel/internal/user/model"
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
"github.com/caos/zitadel/internal/user/repository/view/model"
"github.com/caos/zitadel/internal/view/repository"
)
type UserRepo struct {
@@ -123,8 +123,8 @@ func (repo *UserRepo) UserChanges(ctx context.Context, id string, lastSequence u
return nil, err
}
for _, change := range changes.Changes {
change.ModifierName = change.ModifierId
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierId)
change.ModifierName = change.ModifierID
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierID)
if user != nil {
change.ModifierName = user.DisplayName
}
@@ -149,6 +149,9 @@ func (repo *UserRepo) UserMfas(ctx context.Context, userID string) ([]*usr_model
if err != nil {
return nil, err
}
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-xx0hV", "Errors.User.NotHuman")
}
if user.OTPState == usr_model.MfaStateUnspecified {
return []*usr_model.MultiFactor{}, nil
}
@@ -172,7 +175,51 @@ func (repo *UserRepo) ProfileByID(ctx context.Context, userID string) (*usr_mode
if err != nil {
return nil, err
}
return user.GetProfile(), nil
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-gDFC2", "Errors.User.NotHuman")
}
return user.GetProfile()
}
func (repo *UserRepo) ChangeMachine(ctx context.Context, machine *usr_model.Machine) (*usr_model.Machine, error) {
return repo.UserEvents.ChangeMachine(ctx, machine)
}
func (repo *UserRepo) GetMachineKey(ctx context.Context, userID, keyID string) (*usr_model.MachineKeyView, error) {
key, err := repo.View.MachineKeyByIDs(userID, keyID)
if err != nil {
return nil, err
}
return model.MachineKeyToModel(key), nil
}
func (repo *UserRepo) SearchMachineKeys(ctx context.Context, request *usr_model.MachineKeySearchRequest) (*usr_model.MachineKeySearchResponse, error) {
request.EnsureLimit(repo.SearchLimit)
sequence, seqErr := repo.View.GetLatestMachineKeySequence()
logging.Log("EVENT-Sk8fs").OnError(seqErr).Warn("could not read latest user sequence")
keys, count, err := repo.View.SearchMachineKeys(request)
if err != nil {
return nil, err
}
result := &usr_model.MachineKeySearchResponse{
Offset: request.Offset,
Limit: request.Limit,
TotalResult: count,
Result: model.MachineKeysToModel(keys),
}
if seqErr == nil {
result.Sequence = sequence.CurrentSequence
result.Timestamp = sequence.CurrentTimestamp
}
return result, nil
}
func (repo *UserRepo) AddMachineKey(ctx context.Context, key *usr_model.MachineKey) (*usr_model.MachineKey, error) {
return repo.UserEvents.AddMachineKey(ctx, key)
}
func (repo *UserRepo) RemoveMachineKey(ctx context.Context, userID, keyID string) error {
return repo.UserEvents.RemoveMachineKey(ctx, userID, keyID)
}
func (repo *UserRepo) ChangeProfile(ctx context.Context, profile *usr_model.Profile) (*usr_model.Profile, error) {
@@ -192,7 +239,10 @@ func (repo *UserRepo) EmailByID(ctx context.Context, userID string) (*usr_model.
if err != nil {
return nil, err
}
return user.GetEmail(), nil
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-pt7HY", "Errors.User.NotHuman")
}
return user.GetEmail()
}
func (repo *UserRepo) ChangeEmail(ctx context.Context, email *usr_model.Email) (*usr_model.Email, error) {
@@ -208,7 +258,10 @@ func (repo *UserRepo) PhoneByID(ctx context.Context, userID string) (*usr_model.
if err != nil {
return nil, err
}
return user.GetPhone(), nil
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-hliQl", "Errors.User.NotHuman")
}
return user.GetPhone()
}
func (repo *UserRepo) ChangePhone(ctx context.Context, email *usr_model.Phone) (*usr_model.Phone, error) {
@@ -228,7 +281,10 @@ func (repo *UserRepo) AddressByID(ctx context.Context, userID string) (*usr_mode
if err != nil {
return nil, err
}
return user.GetAddress(), nil
if user.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-LQh4I", "Errors.User.NotHuman")
}
return user.GetAddress()
}
func (repo *UserRepo) ChangeAddress(ctx context.Context, address *usr_model.Address) (*usr_model.Address, error) {

View File

@@ -1,13 +1,13 @@
package handler
import (
"github.com/caos/zitadel/internal/config/systemdefaults"
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
"time"
"github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/config/types"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/eventstore/query"
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
"github.com/caos/zitadel/internal/management/repository/eventsourcing/view"
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
@@ -48,6 +48,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, ev
&OrgMember{handler: handler{view, bulkLimit, configs.cycleDuration("OrgMember"), errorCount}, userEvents: repos.UserEvents},
&OrgDomain{handler: handler{view, bulkLimit, configs.cycleDuration("OrgDomain"), errorCount}},
&UserMembership{handler: handler{view, bulkLimit, configs.cycleDuration("UserMembership"), errorCount}, orgEvents: repos.OrgEvents, projectEvents: repos.ProjectEvents},
&MachineKeys{handler: handler{view, bulkLimit, configs.cycleDuration("MachineKeys"), errorCount}},
&IDPConfig{handler: handler{view, bulkLimit, configs.cycleDuration("IDPConfig"), errorCount}},
&LoginPolicy{handler: handler{view, bulkLimit, configs.cycleDuration("LoginPolicy"), errorCount}},
&IDPProvider{handler: handler{view, bulkLimit, configs.cycleDuration("IDPProvider"), errorCount}, systemDefaults: defaults, iamEvents: repos.IamEvents, orgEvents: repos.OrgEvents},

View File

@@ -0,0 +1,73 @@
package handler
import (
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/eventstore/models"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/eventstore/spooler"
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
usr_model "github.com/caos/zitadel/internal/user/repository/view/model"
)
type MachineKeys struct {
handler
}
const (
machineKeysTable = "management.machine_keys"
)
func (d *MachineKeys) ViewModel() string {
return machineKeysTable
}
func (d *MachineKeys) EventQuery() (*models.SearchQuery, error) {
sequence, err := d.view.GetLatestMachineKeySequence()
if err != nil {
return nil, err
}
return es_models.NewSearchQuery().
AggregateTypeFilter(model.UserAggregate).
LatestSequenceFilter(sequence.CurrentSequence), nil
}
func (d *MachineKeys) Reduce(event *models.Event) (err error) {
switch event.AggregateType {
case model.UserAggregate:
err = d.processMachineKeys(event)
}
return err
}
func (d *MachineKeys) processMachineKeys(event *models.Event) (err error) {
key := new(usr_model.MachineKeyView)
switch event.Type {
case model.MachineKeyAdded:
err = key.AppendEvent(event)
if key.ExpirationDate.Before(time.Now()) {
return d.view.ProcessedMachineKeySequence(event.Sequence)
}
case model.MachineKeyRemoved:
err = key.SetData(event)
if err != nil {
return err
}
return d.view.DeleteMachineKey(key.ID, event.Sequence)
case model.UserRemoved:
return d.view.DeleteMachineKeysByUserID(event.AggregateID, event.Sequence)
default:
return d.view.ProcessedMachineKeySequence(event.Sequence)
}
if err != nil {
return err
}
return d.view.PutMachineKey(key, key.Sequence)
}
func (d *MachineKeys) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-S9fe", "id", event.AggregateID).WithError(err).Warn("something went wrong in machine key handler")
return spooler.HandleError(event, err, d.view.GetLatestMachineKeyFailedEvent, d.view.ProcessedMachineKeyFailedEvent, d.view.ProcessedMachineKeySequence, d.errorCountUntilSkip)
}

View File

@@ -69,8 +69,8 @@ func (d *OrgDomain) processOrgDomain(event *models.Event) (err error) {
if err != nil {
return err
}
for _, existing := range existingDomains {
existing.Primary = false
for _, existingDomain := range existingDomains {
existingDomain.Primary = false
}
err = d.view.PutOrgDomains(existingDomains, 0)
if err != nil {

View File

@@ -85,7 +85,10 @@ func (m *OrgMember) processOrgMember(event *models.Event) (err error) {
func (m *OrgMember) processUser(event *models.Event) (err error) {
switch event.Type {
case usr_es_model.UserProfileChanged,
usr_es_model.UserEmailChanged:
usr_es_model.UserEmailChanged,
usr_es_model.HumanProfileChanged,
usr_es_model.HumanEmailChanged,
usr_es_model.MachineChanged:
members, err := m.view.OrgMembersByUserID(event.AggregateID)
if err != nil {
return err
@@ -118,10 +121,15 @@ func (m *OrgMember) fillData(member *org_model.OrgMemberView) (err error) {
func (m *OrgMember) fillUserData(member *org_model.OrgMemberView, user *usr_model.User) {
member.UserName = user.UserName
member.FirstName = user.FirstName
member.LastName = user.LastName
member.Email = user.EmailAddress
member.DisplayName = user.DisplayName
if user.Human != nil {
member.FirstName = user.FirstName
member.LastName = user.LastName
member.DisplayName = user.FirstName + " " + user.LastName
member.Email = user.EmailAddress
}
if user.Machine != nil {
member.DisplayName = user.Machine.Name
}
}
func (m *OrgMember) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-u73es", "id", event.AggregateID).WithError(err).Warn("something went wrong in orgmember handler")

View File

@@ -111,13 +111,13 @@ func (p *ProjectGrant) updateExistingProjects(project *view_model.ProjectView, s
if err != nil {
logging.LogWithFields("SPOOL-los03", "id", project.ProjectID).WithError(err).Warn("could not update existing projects")
}
for _, existing := range projectGrants {
existing.Name = project.Name
for _, existingGrant := range projectGrants {
existingGrant.Name = project.Name
}
return p.view.PutProjectGrants(projectGrants, sequence)
}
func (p *ProjectGrant) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-is8wa", "id", event.AggregateID).WithError(err).Warn("something went wrong in granted projecthandler")
logging.LogWithFields("SPOOL-sQqOg", "id", event.AggregateID).WithError(err).Warn("something went wrong in granted projecthandler")
return spooler.HandleError(event, err, p.view.GetLatestProjectGrantFailedEvent, p.view.ProcessedProjectGrantFailedEvent, p.view.ProcessedProjectGrantSequence, p.errorCountUntilSkip)
}

View File

@@ -87,7 +87,10 @@ func (p *ProjectGrantMember) processProjectGrantMember(event *models.Event) (err
func (p *ProjectGrantMember) processUser(event *models.Event) (err error) {
switch event.Type {
case usr_es_model.UserProfileChanged,
usr_es_model.UserEmailChanged:
usr_es_model.UserEmailChanged,
usr_es_model.HumanProfileChanged,
usr_es_model.HumanEmailChanged,
usr_es_model.MachineChanged:
members, err := p.view.ProjectGrantMembersByUserID(event.AggregateID)
if err != nil {
return err
@@ -120,10 +123,15 @@ func (p *ProjectGrantMember) fillData(member *view_model.ProjectGrantMemberView)
func (p *ProjectGrantMember) fillUserData(member *view_model.ProjectGrantMemberView, user *usr_model.User) {
member.UserName = user.UserName
member.FirstName = user.FirstName
member.LastName = user.LastName
member.Email = user.EmailAddress
member.DisplayName = user.DisplayName
if user.Human != nil {
member.FirstName = user.FirstName
member.LastName = user.LastName
member.DisplayName = user.FirstName + " " + user.LastName
member.Email = user.EmailAddress
}
if user.Machine != nil {
member.DisplayName = user.Machine.Name
}
}
func (p *ProjectGrantMember) OnError(event *models.Event, err error) error {

View File

@@ -87,7 +87,10 @@ func (p *ProjectMember) processProjectMember(event *models.Event) (err error) {
func (p *ProjectMember) processUser(event *models.Event) (err error) {
switch event.Type {
case usr_es_model.UserProfileChanged,
usr_es_model.UserEmailChanged:
usr_es_model.UserEmailChanged,
usr_es_model.HumanProfileChanged,
usr_es_model.HumanEmailChanged,
usr_es_model.MachineChanged:
members, err := p.view.ProjectMembersByUserID(event.AggregateID)
if err != nil {
return err
@@ -120,10 +123,15 @@ func (p *ProjectMember) fillData(member *view_model.ProjectMemberView) (err erro
func (p *ProjectMember) fillUserData(member *view_model.ProjectMemberView, user *usr_model.User) {
member.UserName = user.UserName
member.FirstName = user.FirstName
member.LastName = user.LastName
member.Email = user.EmailAddress
member.DisplayName = user.DisplayName
if user.Human != nil {
member.FirstName = user.FirstName
member.LastName = user.LastName
member.Email = user.EmailAddress
member.DisplayName = user.FirstName + " " + user.LastName
}
if user.Machine != nil {
member.DisplayName = user.Machine.Name
}
}
func (p *ProjectMember) OnError(event *models.Event, err error) error {
logging.LogWithFields("SPOOL-u73es", "id", event.AggregateID).WithError(err).Warn("something went wrong in projectmember handler")

View File

@@ -55,7 +55,10 @@ func (u *User) ProcessUser(event *models.Event) (err error) {
user := new(view_model.UserView)
switch event.Type {
case es_model.UserAdded,
es_model.UserRegistered:
es_model.UserRegistered,
es_model.HumanRegistered,
es_model.MachineAdded,
es_model.HumanAdded:
err = user.AppendEvent(event)
if err != nil {
return err
@@ -72,9 +75,20 @@ func (u *User) ProcessUser(event *models.Event) (err error) {
es_model.UserReactivated,
es_model.UserLocked,
es_model.UserUnlocked,
es_model.MfaOtpAdded,
es_model.MfaOtpVerified,
es_model.MfaOtpRemoved:
es_model.MFAOTPAdded,
es_model.MFAOTPVerified,
es_model.MFAOTPRemoved,
es_model.HumanProfileChanged,
es_model.HumanEmailChanged,
es_model.HumanEmailVerified,
es_model.HumanPhoneChanged,
es_model.HumanPhoneVerified,
es_model.HumanPhoneRemoved,
es_model.HumanAddressChanged,
es_model.HumanMFAOTPAdded,
es_model.HumanMFAOTPVerified,
es_model.HumanMFAOTPRemoved,
es_model.MachineChanged:
user, err = u.view.UserByID(event.AggregateID)
if err != nil {
return err

View File

@@ -92,7 +92,10 @@ func (u *UserGrant) processUserGrant(event *models.Event) (err error) {
func (u *UserGrant) processUser(event *models.Event) (err error) {
switch event.Type {
case usr_es_model.UserProfileChanged,
usr_es_model.UserEmailChanged:
usr_es_model.UserEmailChanged,
usr_es_model.HumanProfileChanged,
usr_es_model.HumanEmailChanged,
usr_es_model.MachineChanged:
grants, err := u.view.UserGrantsByUserID(event.AggregateID)
if err != nil {
return err
@@ -160,10 +163,15 @@ func (u *UserGrant) fillData(grant *view_model.UserGrantView, resourceOwner stri
func (u *UserGrant) fillUserData(grant *view_model.UserGrantView, user *usr_model.User) {
grant.UserName = user.UserName
grant.FirstName = user.FirstName
grant.LastName = user.LastName
grant.DisplayName = user.DisplayName
grant.Email = user.EmailAddress
if user.Human != nil {
grant.FirstName = user.FirstName
grant.LastName = user.LastName
grant.DisplayName = user.FirstName + " " + user.LastName
grant.Email = user.EmailAddress
}
if user.Machine != nil {
grant.DisplayName = user.Machine.Name
}
}
func (u *UserGrant) fillProjectData(grant *view_model.UserGrantView, project *proj_model.Project) {

View File

@@ -3,12 +3,11 @@ package eventsourcing
import (
"context"
es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
sd "github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/config/types"
es_int "github.com/caos/zitadel/internal/eventstore"
es_spol "github.com/caos/zitadel/internal/eventstore/spooler"
es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
"github.com/caos/zitadel/internal/management/repository/eventsourcing/eventstore"
"github.com/caos/zitadel/internal/management/repository/eventsourcing/handler"
"github.com/caos/zitadel/internal/management/repository/eventsourcing/spooler"

View File

@@ -0,0 +1,67 @@
package view
import (
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/internal/user/repository/view"
"github.com/caos/zitadel/internal/user/repository/view/model"
"github.com/caos/zitadel/internal/view/repository"
)
const (
machineKeyTable = "management.machine_keys"
)
func (v *View) MachineKeyByIDs(userID, keyID string) (*model.MachineKeyView, error) {
return view.MachineKeyByIDs(v.Db, machineKeyTable, userID, keyID)
}
func (v *View) MachineKeysByUserID(userID string) ([]*model.MachineKeyView, error) {
return view.MachineKeysByUserID(v.Db, machineKeyTable, userID)
}
func (v *View) SearchMachineKeys(request *usr_model.MachineKeySearchRequest) ([]*model.MachineKeyView, uint64, error) {
return view.SearchMachineKeys(v.Db, machineKeyTable, request)
}
func (v *View) PutMachineKey(org *model.MachineKeyView, sequence uint64) error {
err := view.PutMachineKey(v.Db, machineKeyTable, org)
if err != nil {
return err
}
if sequence != 0 {
return v.ProcessedMachineKeySequence(sequence)
}
return nil
}
func (v *View) DeleteMachineKey(keyID string, eventSequence uint64) error {
err := view.DeleteMachineKey(v.Db, machineKeyTable, keyID)
if err != nil {
return nil
}
return v.ProcessedMachineKeySequence(eventSequence)
}
func (v *View) DeleteMachineKeysByUserID(userID string, eventSequence uint64) error {
err := view.DeleteMachineKey(v.Db, machineKeyTable, userID)
if err != nil {
return nil
}
return v.ProcessedMachineKeySequence(eventSequence)
}
func (v *View) GetLatestMachineKeySequence() (*repository.CurrentSequence, error) {
return v.latestSequence(machineKeyTable)
}
func (v *View) ProcessedMachineKeySequence(eventSequence uint64) error {
return v.saveCurrentSequence(machineKeyTable, eventSequence)
}
func (v *View) GetLatestMachineKeyFailedEvent(sequence uint64) (*repository.FailedEvent, error) {
return v.latestFailedEvent(machineKeyTable, sequence)
}
func (v *View) ProcessedMachineKeyFailedEvent(failedEvent *repository.FailedEvent) error {
return v.saveFailedEvent(failedEvent)
}

View File

@@ -15,10 +15,13 @@ type UserRepository interface {
LockUser(ctx context.Context, id string) (*model.User, error)
UnlockUser(ctx context.Context, id string) (*model.User, error)
SearchUsers(ctx context.Context, request *model.UserSearchRequest) (*model.UserSearchResponse, error)
UserChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*model.UserChanges, error)
GetUserByLoginNameGlobal(ctx context.Context, email string) (*model.UserView, error)
IsUserUnique(ctx context.Context, userName, email string) (bool, error)
UserMfas(ctx context.Context, userID string) ([]*model.MultiFactor, error)
UserChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*model.UserChanges, error)
ChangeUsername(ctx context.Context, id, username string) error
SetOneTimePassword(ctx context.Context, password *model.Password) (*model.Password, error)
RequestSetPassword(ctx context.Context, id string, notifyType model.NotificationType) error
@@ -26,7 +29,13 @@ type UserRepository interface {
ProfileByID(ctx context.Context, userID string) (*model.Profile, error)
ChangeProfile(ctx context.Context, profile *model.Profile) (*model.Profile, error)
ChangeUsername(ctx context.Context, id, username string) error
UserMfas(ctx context.Context, userID string) ([]*model.MultiFactor, error)
SearchMachineKeys(ctx context.Context, request *model.MachineKeySearchRequest) (*model.MachineKeySearchResponse, error)
GetMachineKey(ctx context.Context, userID, keyID string) (*model.MachineKeyView, error)
ChangeMachine(ctx context.Context, machine *model.Machine) (*model.Machine, error)
AddMachineKey(ctx context.Context, key *model.MachineKey) (*model.MachineKey, error)
RemoveMachineKey(ctx context.Context, userID, keyID string) error
EmailByID(ctx context.Context, userID string) (*model.Email, error)
ChangeEmail(ctx context.Context, email *model.Email) (*model.Email, error)

View File

@@ -50,13 +50,17 @@ func (n *Notification) EventQuery() (*models.SearchQuery, error) {
func (n *Notification) Reduce(event *models.Event) (err error) {
switch event.Type {
case es_model.InitializedUserCodeAdded:
case es_model.InitializedUserCodeAdded,
es_model.InitializedHumanCodeAdded:
err = n.handleInitUserCode(event)
case es_model.UserEmailCodeAdded:
case es_model.UserEmailCodeAdded,
es_model.HumanEmailCodeAdded:
err = n.handleEmailVerificationCode(event)
case es_model.UserPhoneCodeAdded:
case es_model.UserPhoneCodeAdded,
es_model.HumanPhoneCodeAdded:
err = n.handlePhoneVerificationCode(event)
case es_model.UserPasswordCodeAdded:
case es_model.UserPasswordCodeAdded,
es_model.HumanPasswordCodeAdded:
err = n.handlePasswordCode(event)
case es_model.DomainClaimed:
err = n.handleDomainClaimed(event)

View File

@@ -55,7 +55,9 @@ func (u *NotifyUser) ProcessUser(event *models.Event) (err error) {
user := new(view_model.NotifyUser)
switch event.Type {
case es_model.UserAdded,
es_model.UserRegistered:
es_model.UserRegistered,
es_model.HumanRegistered,
es_model.HumanAdded:
user.AppendEvent(event)
u.fillLoginNames(user)
case es_model.UserProfileChanged,
@@ -63,7 +65,14 @@ func (u *NotifyUser) ProcessUser(event *models.Event) (err error) {
es_model.UserEmailVerified,
es_model.UserPhoneChanged,
es_model.UserPhoneVerified,
es_model.UserPhoneRemoved:
es_model.UserPhoneRemoved,
es_model.HumanProfileChanged,
es_model.HumanEmailChanged,
es_model.HumanEmailVerified,
es_model.HumanPhoneChanged,
es_model.HumanPhoneVerified,
es_model.HumanPhoneRemoved,
es_model.MachineChanged:
user, err = u.view.NotifyUserByID(event.AggregateID)
if err != nil {
return err
@@ -104,10 +113,6 @@ func (u *NotifyUser) ProcessOrg(event *models.Event) (err error) {
default:
return u.view.ProcessedNotifyUserSequence(event.Sequence)
}
if err != nil {
return err
}
return nil
}
func (u *NotifyUser) fillLoginNamesOnOrgUsers(event *models.Event) error {

View File

@@ -3,12 +3,8 @@ package eventsourcing
import (
"context"
"encoding/json"
iam_model "github.com/caos/zitadel/internal/iam/model"
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
http_utils "github.com/caos/zitadel/internal/api/http"
"github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/crypto"
@@ -16,9 +12,12 @@ import (
"github.com/caos/zitadel/internal/eventstore"
es_models "github.com/caos/zitadel/internal/eventstore/models"
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
iam_model "github.com/caos/zitadel/internal/iam/model"
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
"github.com/caos/zitadel/internal/id"
org_model "github.com/caos/zitadel/internal/org/model"
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
"github.com/golang/protobuf/ptypes"
)
type OrgEventstore struct {
@@ -174,11 +173,11 @@ func (es *OrgEventstore) AddOrgDomain(ctx context.Context, domain *org_model.Org
if domain == nil || !domain.IsValid() {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-8sFJW", "Errors.Org.InvalidDomain")
}
existing, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
if err != nil {
return nil, err
}
repoOrg := model.OrgFromModel(existing)
repoOrg := model.OrgFromModel(existingOrg)
repoDomain := model.OrgDomainFromModel(domain)
aggregate := OrgDomainAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoDomain)
@@ -201,11 +200,11 @@ func (es *OrgEventstore) GenerateOrgDomainValidation(ctx context.Context, domain
if !ok {
return "", "", errors.ThrowPreconditionFailed(nil, "EVENT-Gsw31", "Errors.Org.DomainVerificationTypeInvalid")
}
existing, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
if err != nil {
return "", "", err
}
_, d := existing.GetDomain(domain)
_, d := existingOrg.GetDomain(domain)
if d == nil {
return "", "", errors.ThrowPreconditionFailed(nil, "EVENT-AGD31", "Errors.Org.DomainNotOnOrg")
}
@@ -221,7 +220,7 @@ func (es *OrgEventstore) GenerateOrgDomainValidation(ctx context.Context, domain
return "", "", errors.ThrowPreconditionFailed(err, "EVENT-Bae21", "Errors.Org.DomainVerificationTypeInvalid")
}
repoOrg := model.OrgFromModel(existing)
repoOrg := model.OrgFromModel(existingOrg)
repoDomain := model.OrgDomainFromModel(domain)
aggregate := OrgDomainValidationGeneratedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoDomain)
@@ -236,28 +235,28 @@ func (es *OrgEventstore) ValidateOrgDomain(ctx context.Context, domain *org_mode
if domain == nil || !domain.IsValid() {
return errors.ThrowPreconditionFailed(nil, "EVENT-R24hb", "Errors.Org.InvalidDomain")
}
existing, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
if err != nil {
return err
}
_, d := existing.GetDomain(domain)
if d == nil {
_, existingDomain := existingOrg.GetDomain(domain)
if existingDomain == nil {
return errors.ThrowPreconditionFailed(nil, "EVENT-Sjdi3", "Errors.Org.DomainNotOnOrg")
}
if d.Verified {
if existingDomain.Verified {
return errors.ThrowPreconditionFailed(nil, "EVENT-4gT342", "Errors.Org.DomainAlreadyVerified")
}
if d.ValidationCode == nil || d.ValidationType == org_model.OrgDomainValidationTypeUnspecified {
if existingDomain.ValidationCode == nil || existingDomain.ValidationType == org_model.OrgDomainValidationTypeUnspecified {
return errors.ThrowPreconditionFailed(nil, "EVENT-SFBB3", "Errors.Org.DomainVerificationMissing")
}
validationCode, err := crypto.DecryptString(d.ValidationCode, es.verificationAlgorithm)
validationCode, err := crypto.DecryptString(existingDomain.ValidationCode, es.verificationAlgorithm)
if err != nil {
return err
}
repoOrg := model.OrgFromModel(existing)
repoOrg := model.OrgFromModel(existingOrg)
repoDomain := model.OrgDomainFromModel(domain)
checkType, _ := d.ValidationType.CheckType()
err = es.verificationValidator(d.Domain, validationCode, validationCode, checkType)
checkType, _ := existingDomain.ValidationType.CheckType()
err = es.verificationValidator(existingDomain.Domain, validationCode, validationCode, checkType)
if err == nil {
orgAggregates, err := OrgDomainVerifiedAggregate(ctx, es.Eventstore.AggregateCreator(), repoOrg, repoDomain, users)
if err != nil {
@@ -275,18 +274,18 @@ func (es *OrgEventstore) SetPrimaryOrgDomain(ctx context.Context, domain *org_mo
if domain == nil || !domain.IsValid() {
return errors.ThrowPreconditionFailed(nil, "EVENT-SsDG2", "Errors.Org.InvalidDomain")
}
existing, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
if err != nil {
return err
}
_, d := existing.GetDomain(domain)
if d == nil {
_, existingDomain := existingOrg.GetDomain(domain)
if existingDomain == nil {
return errors.ThrowPreconditionFailed(nil, "EVENT-GDfA3", "Errors.Org.DomainNotOnOrg")
}
if !d.Verified {
if !existingDomain.Verified {
return errors.ThrowPreconditionFailed(nil, "EVENT-Ggd32", "Errors.Org.DomainNotVerified")
}
repoOrg := model.OrgFromModel(existing)
repoOrg := model.OrgFromModel(existingOrg)
repoDomain := model.OrgDomainFromModel(domain)
if err := es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, OrgDomainSetPrimaryAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoDomain)); err != nil {
return err
@@ -298,18 +297,18 @@ func (es *OrgEventstore) RemoveOrgDomain(ctx context.Context, domain *org_model.
if domain.Domain == "" {
return errors.ThrowPreconditionFailed(nil, "EVENT-SJsK3", "Errors.Org.DomainMissing")
}
existing, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID))
if err != nil {
return err
}
_, d := existing.GetDomain(domain)
if d == nil {
_, existingDomain := existingOrg.GetDomain(domain)
if existingDomain == nil {
return errors.ThrowPreconditionFailed(nil, "EVENT-Sjdi3", "Errors.Org.DomainNotOnOrg")
}
if d.Primary {
if existingDomain.Primary {
return errors.ThrowPreconditionFailed(nil, "EVENT-Sjdi3", "Errors.Org.PrimaryDomainNotDeletable")
}
repoOrg := model.OrgFromModel(existing)
repoOrg := model.OrgFromModel(existingOrg)
repoDomain := model.OrgDomainFromModel(domain)
orgAggregates, err := OrgDomainRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoOrg, repoDomain)
if err != nil {
@@ -400,7 +399,7 @@ func (es *OrgEventstore) OrgMemberByIDs(ctx context.Context, member *org_model.O
func (es *OrgEventstore) PrepareAddOrgMember(ctx context.Context, member *org_model.OrgMember, resourceOwner string) (*model.OrgMember, *es_models.Aggregate, error) {
if member == nil || !member.IsValid() {
return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.Org.InvalidMember")
return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-jRFLz", "Errors.Org.InvalidMember")
}
repoMember := model.OrgMemberFromModel(member)
@@ -424,7 +423,7 @@ func (es *OrgEventstore) AddOrgMember(ctx context.Context, member *org_model.Org
func (es *OrgEventstore) ChangeOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) {
if member == nil || !member.IsValid() {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.Org.InvalidMember")
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ara6l", "Errors.Org.InvalidMember")
}
existingMember, err := es.OrgMemberByIDs(ctx, member)
@@ -466,25 +465,25 @@ func (es *OrgEventstore) RemoveOrgMember(ctx context.Context, member *org_model.
}
func (es *OrgEventstore) GetOrgIAMPolicy(ctx context.Context, orgID string) (*org_model.OrgIAMPolicy, error) {
existing, err := es.OrgByID(ctx, org_model.NewOrg(orgID))
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(orgID))
if err != nil && !errors.IsNotFound(err) {
return nil, err
}
if existing != nil && existing.OrgIamPolicy != nil {
return existing.OrgIamPolicy, nil
if existingOrg != nil && existingOrg.OrgIamPolicy != nil {
return existingOrg.OrgIamPolicy, nil
}
return es.defaultOrgIamPolicy, nil
}
func (es *OrgEventstore) AddOrgIAMPolicy(ctx context.Context, policy *org_model.OrgIAMPolicy) (*org_model.OrgIAMPolicy, error) {
existing, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID))
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID))
if err != nil {
return nil, err
}
if existing.OrgIamPolicy != nil {
if existingOrg.OrgIamPolicy != nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-7Usj3", "Errors.Org.PolicyAlreadyExists")
}
repoOrg := model.OrgFromModel(existing)
repoOrg := model.OrgFromModel(existingOrg)
repoPolicy := model.OrgIAMPolicyFromModel(policy)
orgAggregate := OrgIAMPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPolicy)
if err != nil {
@@ -499,14 +498,14 @@ func (es *OrgEventstore) AddOrgIAMPolicy(ctx context.Context, policy *org_model.
}
func (es *OrgEventstore) ChangeOrgIAMPolicy(ctx context.Context, policy *org_model.OrgIAMPolicy) (*org_model.OrgIAMPolicy, error) {
existing, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID))
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID))
if err != nil {
return nil, err
}
if existing.OrgIamPolicy == nil {
if existingOrg.OrgIamPolicy == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-8juSd", "Errors.Org.PolicyNotExisting")
}
repoOrg := model.OrgFromModel(existing)
repoOrg := model.OrgFromModel(existingOrg)
repoPolicy := model.OrgIAMPolicyFromModel(policy)
orgAggregate := OrgIAMPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPolicy)
if err != nil {
@@ -521,14 +520,14 @@ func (es *OrgEventstore) ChangeOrgIAMPolicy(ctx context.Context, policy *org_mod
}
func (es *OrgEventstore) RemoveOrgIAMPolicy(ctx context.Context, orgID string) error {
existing, err := es.OrgByID(ctx, org_model.NewOrg(orgID))
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(orgID))
if err != nil {
return err
}
if existing.OrgIamPolicy == nil {
if existingOrg.OrgIamPolicy == nil {
return errors.ThrowPreconditionFailed(nil, "EVENT-z6Dse", "Errors.Org.PolicyNotExisting")
}
repoOrg := model.OrgFromModel(existing)
repoOrg := model.OrgFromModel(existingOrg)
orgAggregate := OrgIamPolicyRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg)
if err != nil {
return err

View File

@@ -117,8 +117,8 @@ func TestAppendEvent(t *testing.T) {
func TestChanges(t *testing.T) {
type args struct {
existing *Org
new *Org
existingOrg *Org
newOrg *Org
}
type res struct {
changesLen int
@@ -131,8 +131,8 @@ func TestChanges(t *testing.T) {
{
name: "org name changes",
args: args{
existing: &Org{Name: "Name"},
new: &Org{Name: "NameChanged"},
existingOrg: &Org{Name: "Name"},
newOrg: &Org{Name: "NameChanged"},
},
res: res{
changesLen: 1,
@@ -141,8 +141,8 @@ func TestChanges(t *testing.T) {
{
name: "no changes",
args: args{
existing: &Org{Name: "Name"},
new: &Org{Name: "Name"},
existingOrg: &Org{Name: "Name"},
newOrg: &Org{Name: "Name"},
},
res: res{
changesLen: 0,
@@ -151,7 +151,7 @@ func TestChanges(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
changes := tt.args.existing.Changes(tt.args.new)
changes := tt.args.existingOrg.Changes(tt.args.newOrg)
if len(changes) != tt.res.changesLen {
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
}

View File

@@ -93,14 +93,14 @@ func addDomainAggregateAndEvents(ctx context.Context, aggCreator *es_models.Aggr
return aggregates, nil
}
func OrgUpdateAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.Org, updated *model.Org) ([]*es_models.Aggregate, error) {
if existing == nil {
func OrgUpdateAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, existingOrg *model.Org, updatedOrg *model.Org) ([]*es_models.Aggregate, error) {
if existingOrg == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dk83d", "Errors.Internal")
}
if updated == nil {
if updatedOrg == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "Errors.Internal")
}
changes := existing.Changes(updated)
changes := existingOrg.Changes(updatedOrg)
if len(changes) == 0 {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-E0hc5", "Errors.NoChangesFound")
}
@@ -113,14 +113,14 @@ func OrgUpdateAggregates(ctx context.Context, aggCreator *es_models.AggregateCre
return nil, err
}
aggregates = append(aggregates, nameAggregate)
nameReleasedAggregate, err := releasedUniqueNameAggregate(ctx, aggCreator, "", existing.Name)
nameReleasedAggregate, err := releasedUniqueNameAggregate(ctx, aggCreator, "", existingOrg.Name)
if err != nil {
return nil, err
}
aggregates = append(aggregates, nameReleasedAggregate)
}
orgAggregate, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
orgAggregate, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence)
if err != nil {
return nil, err
}
@@ -231,12 +231,12 @@ func releasedUniqueNameAggregate(ctx context.Context, aggCreator *es_models.Aggr
return aggregate.SetPrecondition(OrgNameUniqueQuery(name), isEventValidation(aggregate, model.OrgNameReleased)), nil
}
func OrgDomainAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) {
func OrgDomainAddedAggregate(aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if domain == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-OSid3", "Errors.Internal")
}
agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence)
if err != nil {
return nil, err
}
@@ -244,12 +244,12 @@ func OrgDomainAddedAggregate(aggCreator *es_models.AggregateCreator, existing *m
}
}
func OrgDomainValidationGeneratedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) {
func OrgDomainValidationGeneratedAggregate(aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if domain == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-GD2gq", "Errors.Internal")
}
agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence)
if err != nil {
return nil, err
}
@@ -257,12 +257,12 @@ func OrgDomainValidationGeneratedAggregate(aggCreator *es_models.AggregateCreato
}
}
func OrgDomainValidationFailedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) {
func OrgDomainValidationFailedAggregate(aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if domain == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-BHF52", "Errors.Internal")
}
agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence)
if err != nil {
return nil, err
}
@@ -270,28 +270,28 @@ func OrgDomainValidationFailedAggregate(aggCreator *es_models.AggregateCreator,
}
}
func OrgDomainVerifiedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.Org, domain *model.OrgDomain, users func(context.Context, string) ([]*es_models.Aggregate, error)) ([]*es_models.Aggregate, error) {
func OrgDomainVerifiedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain, users func(context.Context, string) ([]*es_models.Aggregate, error)) ([]*es_models.Aggregate, error) {
if domain == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-DHs7s", "Errors.Internal")
}
agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence)
if err != nil {
return nil, err
}
aggregates, err := orgDomainVerified(ctx, aggCreator, agg, existing, domain, users)
aggregates, err := orgDomainVerified(ctx, aggCreator, agg, existingOrg, domain, users)
if err != nil {
return nil, err
}
return append(aggregates, agg), nil
}
func orgDomainVerified(ctx context.Context, aggCreator *es_models.AggregateCreator, agg *es_models.Aggregate, existing *model.Org, domain *model.OrgDomain, users func(context.Context, string) ([]*es_models.Aggregate, error)) ([]*es_models.Aggregate, error) {
func orgDomainVerified(ctx context.Context, aggCreator *es_models.AggregateCreator, agg *es_models.Aggregate, existingOrg *model.Org, domain *model.OrgDomain, users func(context.Context, string) ([]*es_models.Aggregate, error)) ([]*es_models.Aggregate, error) {
agg, err := agg.AppendEvent(model.OrgDomainVerified, domain)
if err != nil {
return nil, err
}
domainAgregate, err := reservedUniqueDomainAggregate(ctx, aggCreator, existing.AggregateID, domain.Domain)
domainAgregate, err := reservedUniqueDomainAggregate(ctx, aggCreator, existingOrg.AggregateID, domain.Domain)
if err != nil {
return nil, err
}
@@ -306,12 +306,12 @@ func orgDomainVerified(ctx context.Context, aggCreator *es_models.AggregateCreat
return aggregates, nil
}
func OrgDomainSetPrimaryAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) {
func OrgDomainSetPrimaryAggregate(aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if domain == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-PSw3j", "Errors.Internal")
}
agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence)
if err != nil {
return nil, err
}
@@ -319,12 +319,12 @@ func OrgDomainSetPrimaryAggregate(aggCreator *es_models.AggregateCreator, existi
}
}
func OrgDomainRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.Org, domain *model.OrgDomain) ([]*es_models.Aggregate, error) {
func OrgDomainRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) ([]*es_models.Aggregate, error) {
if domain == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-si8dW", "Errors.Internal")
}
aggregates := make([]*es_models.Aggregate, 0, 2)
agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence)
if err != nil {
return nil, err
}
@@ -333,7 +333,7 @@ func OrgDomainRemovedAggregate(ctx context.Context, aggCreator *es_models.Aggreg
return nil, err
}
aggregates = append(aggregates, agg)
domainAgregate, err := releasedUniqueDomainAggregate(ctx, aggCreator, existing.AggregateID, domain.Domain)
domainAgregate, err := releasedUniqueDomainAggregate(ctx, aggCreator, existingOrg.AggregateID, domain.Domain)
if err != nil {
return nil, err
}

View File

@@ -2,17 +2,18 @@ package eventsourcing
import (
"context"
"github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
)
func OrgIAMPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *model.OrgIAMPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
func OrgIAMPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, policy *model.OrgIAMPolicy) 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-i9sJS", "Errors.Internal")
}
agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence)
if err != nil {
return nil, err
}
@@ -20,16 +21,16 @@ func OrgIAMPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing
}
}
func OrgIAMPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *model.OrgIAMPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
func OrgIAMPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, policy *model.OrgIAMPolicy) 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-9Ksie", "Errors.Internal")
}
agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence)
if err != nil {
return nil, err
}
changes := existing.OrgIamPolicy.Changes(policy)
changes := org.OrgIamPolicy.Changes(policy)
if len(changes) == 0 {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Js6Vs", "Errors.NoChangesFound")
}
@@ -37,9 +38,9 @@ func OrgIAMPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existi
}
}
func OrgIamPolicyRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) {
func OrgIamPolicyRemovedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence)
if err != nil {
return nil, err
}

View File

@@ -367,10 +367,10 @@ func TestOrgUpdateAggregates(t *testing.T) {
isErr func(error) bool
}
type args struct {
ctx context.Context
aggCreator *es_models.AggregateCreator
existing *model.Org
updated *model.Org
ctx context.Context
aggCreator *es_models.AggregateCreator
existingOrg *model.Org
updated *model.Org
}
tests := []struct {
name string
@@ -380,10 +380,10 @@ func TestOrgUpdateAggregates(t *testing.T) {
{
name: "no existing org error",
args: args{
ctx: authz.NewMockContext("org", "user"),
aggCreator: es_models.NewAggregateCreator("test"),
existing: nil,
updated: &model.Org{},
ctx: authz.NewMockContext("org", "user"),
aggCreator: es_models.NewAggregateCreator("test"),
existingOrg: nil,
updated: &model.Org{},
},
res: res{
aggregateCount: 0,
@@ -393,10 +393,10 @@ func TestOrgUpdateAggregates(t *testing.T) {
{
name: "no updated org error",
args: args{
ctx: authz.NewMockContext("org", "user"),
aggCreator: es_models.NewAggregateCreator("test"),
existing: &model.Org{},
updated: nil,
ctx: authz.NewMockContext("org", "user"),
aggCreator: es_models.NewAggregateCreator("test"),
existingOrg: &model.Org{},
updated: nil,
},
res: res{
aggregateCount: 0,
@@ -406,10 +406,10 @@ func TestOrgUpdateAggregates(t *testing.T) {
{
name: "no changes",
args: args{
ctx: authz.NewMockContext("org", "user"),
aggCreator: es_models.NewAggregateCreator("test"),
existing: &model.Org{},
updated: &model.Org{},
ctx: authz.NewMockContext("org", "user"),
aggCreator: es_models.NewAggregateCreator("test"),
existingOrg: &model.Org{},
updated: &model.Org{},
},
res: res{
aggregateCount: 0,
@@ -421,7 +421,7 @@ func TestOrgUpdateAggregates(t *testing.T) {
args: args{
ctx: authz.NewMockContext("org", "user"),
aggCreator: es_models.NewAggregateCreator("test"),
existing: &model.Org{
existingOrg: &model.Org{
ObjectRoot: es_models.ObjectRoot{
AggregateID: "sdaf",
Sequence: 5,
@@ -444,7 +444,7 @@ func TestOrgUpdateAggregates(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := OrgUpdateAggregates(tt.args.ctx, tt.args.aggCreator, tt.args.existing, tt.args.updated)
got, err := OrgUpdateAggregates(tt.args.ctx, tt.args.aggCreator, tt.args.existingOrg, tt.args.updated)
if tt.res.isErr == nil && err != nil {
t.Errorf("no error expected got: %v", err)
}

View File

@@ -2,9 +2,10 @@ package model
import (
"encoding/json"
es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
"time"
es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
@@ -36,22 +37,6 @@ type OrgMemberView struct {
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
}
func OrgMemberViewFromModel(member *model.OrgMemberView) *OrgMemberView {
return &OrgMemberView{
UserID: member.UserID,
OrgID: member.OrgID,
UserName: member.UserName,
Email: member.Email,
FirstName: member.FirstName,
LastName: member.LastName,
DisplayName: member.DisplayName,
Roles: member.Roles,
Sequence: member.Sequence,
CreationDate: member.CreationDate,
ChangeDate: member.ChangeDate,
}
}
func OrgMemberToModel(member *OrgMemberView) *model.OrgMemberView {
return &model.OrgMemberView{
UserID: member.UserID,

View File

@@ -36,16 +36,16 @@ func PasswordAgePolicyCreateAggregate(aggCreator *es_models.AggregateCreator, po
}
}
func PasswordAgePolicyUpdateAggregate(aggCreator *es_models.AggregateCreator, existing *PasswordAgePolicy, new *PasswordAgePolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
func PasswordAgePolicyUpdateAggregate(aggCreator *es_models.AggregateCreator, existingPolicy *PasswordAgePolicy, newPolicy *PasswordAgePolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if new == nil {
if newPolicy == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "Errors.Internal")
}
agg, err := PasswordAgePolicyAggregate(ctx, aggCreator, existing)
agg, err := PasswordAgePolicyAggregate(ctx, aggCreator, existingPolicy)
if err != nil {
return nil, err
}
changes := existing.AgeChanges(new)
changes := existingPolicy.AgeChanges(newPolicy)
return agg.AppendEvent(model.PasswordAgePolicyChanged, changes)
}
}

View File

@@ -188,10 +188,10 @@ func TestPasswordAgePolicyCreateAggregate(t *testing.T) {
func TestPasswordAgePolicyUpdateAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *PasswordAgePolicy
new *PasswordAgePolicy
aggCreator *models.AggregateCreator
ctx context.Context
existingPolicy *PasswordAgePolicy
newPolicy *PasswordAgePolicy
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
@@ -207,10 +207,10 @@ func TestPasswordAgePolicyUpdateAggregate(t *testing.T) {
{
name: "policy update aggregate ok",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &PasswordAgePolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName", State: int32(policy_model.PolicyStateActive)},
new: &PasswordAgePolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName_Changed", State: int32(policy_model.PolicyStateActive)},
aggCreator: models.NewAggregateCreator("Test"),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &PasswordAgePolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName", State: int32(policy_model.PolicyStateActive)},
newPolicy: &PasswordAgePolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName_Changed", State: int32(policy_model.PolicyStateActive)},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
@@ -220,9 +220,9 @@ func TestPasswordAgePolicyUpdateAggregate(t *testing.T) {
{
name: "existing policy nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
@@ -234,10 +234,10 @@ func TestPasswordAgePolicyUpdateAggregate(t *testing.T) {
{
name: "new policy nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &PasswordAgePolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "ProjectName", State: int32(policy_model.PolicyStateActive)},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &PasswordAgePolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "ProjectName", State: int32(policy_model.PolicyStateActive)},
newPolicy: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
@@ -249,7 +249,7 @@ func TestPasswordAgePolicyUpdateAggregate(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := PasswordAgePolicyUpdateAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx)
agg, err := PasswordAgePolicyUpdateAggregate(tt.args.aggCreator, tt.args.existingPolicy, tt.args.newPolicy)(tt.args.ctx)
if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))

View File

@@ -37,16 +37,16 @@ func PasswordComplexityPolicyCreateAggregate(aggCreator *es_models.AggregateCrea
}
}
func PasswordComplexityPolicyUpdateAggregate(aggCreator *es_models.AggregateCreator, existing *PasswordComplexityPolicy, new *PasswordComplexityPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
func PasswordComplexityPolicyUpdateAggregate(aggCreator *es_models.AggregateCreator, existingPolicy *PasswordComplexityPolicy, newPolicy *PasswordComplexityPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if new == nil {
if newPolicy == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "Errors.Internal")
}
agg, err := PasswordComplexityPolicyAggregate(ctx, aggCreator, existing)
agg, err := PasswordComplexityPolicyAggregate(ctx, aggCreator, existingPolicy)
if err != nil {
return nil, err
}
changes := existing.ComplexityChanges(new)
changes := existingPolicy.ComplexityChanges(newPolicy)
return agg.AppendEvent(model.PasswordComplexityPolicyChanged, changes)
}
}

View File

@@ -188,10 +188,10 @@ func TestPasswordComplexityPolicyCreateAggregate(t *testing.T) {
func TestPasswordComplexityPolicyUpdateAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *PasswordComplexityPolicy
new *PasswordComplexityPolicy
aggCreator *models.AggregateCreator
ctx context.Context
existingPolicy *PasswordComplexityPolicy
newPolicy *PasswordComplexityPolicy
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
@@ -207,10 +207,10 @@ func TestPasswordComplexityPolicyUpdateAggregate(t *testing.T) {
{
name: "policy update aggregate ok",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &PasswordComplexityPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName", State: int32(policy_model.PolicyStateActive)},
new: &PasswordComplexityPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName_Changed", State: int32(policy_model.PolicyStateActive)},
aggCreator: models.NewAggregateCreator("Test"),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &PasswordComplexityPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName", State: int32(policy_model.PolicyStateActive)},
newPolicy: &PasswordComplexityPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName_Changed", State: int32(policy_model.PolicyStateActive)},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
@@ -220,9 +220,9 @@ func TestPasswordComplexityPolicyUpdateAggregate(t *testing.T) {
{
name: "existing policy nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
@@ -234,10 +234,10 @@ func TestPasswordComplexityPolicyUpdateAggregate(t *testing.T) {
{
name: "new policy nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &PasswordComplexityPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "ProjectName", State: int32(policy_model.PolicyStateActive)},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &PasswordComplexityPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "ProjectName", State: int32(policy_model.PolicyStateActive)},
newPolicy: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
@@ -249,7 +249,7 @@ func TestPasswordComplexityPolicyUpdateAggregate(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := PasswordComplexityPolicyUpdateAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx)
agg, err := PasswordComplexityPolicyUpdateAggregate(tt.args.aggCreator, tt.args.existingPolicy, tt.args.newPolicy)(tt.args.ctx)
if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))

View File

@@ -38,16 +38,16 @@ func PasswordLockoutPolicyCreateAggregate(aggCreator *es_models.AggregateCreator
}
}
func PasswordLockoutPolicyUpdateAggregate(aggCreator *es_models.AggregateCreator, existing *PasswordLockoutPolicy, new *PasswordLockoutPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
func PasswordLockoutPolicyUpdateAggregate(aggCreator *es_models.AggregateCreator, existingPolicy *PasswordLockoutPolicy, newPolicy *PasswordLockoutPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if new == nil {
if newPolicy == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "Errors.Internal")
}
agg, err := PasswordLockoutPolicyAggregate(ctx, aggCreator, existing)
agg, err := PasswordLockoutPolicyAggregate(ctx, aggCreator, existingPolicy)
if err != nil {
return nil, err
}
changes := existing.LockoutChanges(new)
changes := existingPolicy.LockoutChanges(newPolicy)
return agg.AppendEvent(model.PasswordLockoutPolicyChanged, changes)
}
}

View File

@@ -125,7 +125,7 @@ func TestPasswordLockoutPolicyAggregate(t *testing.T) {
func TestPasswordLockoutPolicyCreateAggregate(t *testing.T) {
type args struct {
ctx context.Context
new *PasswordLockoutPolicy
newPolicy *PasswordLockoutPolicy
aggCreator *models.AggregateCreator
}
type res struct {
@@ -143,7 +143,7 @@ func TestPasswordLockoutPolicyCreateAggregate(t *testing.T) {
name: "policy update aggregate ok",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
new: &PasswordLockoutPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName", State: int32(policy_model.PolicyStateActive)},
newPolicy: &PasswordLockoutPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName", State: int32(policy_model.PolicyStateActive)},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
@@ -155,7 +155,7 @@ func TestPasswordLockoutPolicyCreateAggregate(t *testing.T) {
name: "new policy nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
new: nil,
newPolicy: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
@@ -168,7 +168,7 @@ func TestPasswordLockoutPolicyCreateAggregate(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := PasswordLockoutPolicyCreateAggregate(tt.args.aggCreator, tt.args.new)(tt.args.ctx)
agg, err := PasswordLockoutPolicyCreateAggregate(tt.args.aggCreator, tt.args.newPolicy)(tt.args.ctx)
if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
@@ -188,10 +188,10 @@ func TestPasswordLockoutPolicyCreateAggregate(t *testing.T) {
func TestPasswordLockoutPolicyUpdateAggregate(t *testing.T) {
type args struct {
ctx context.Context
existing *PasswordLockoutPolicy
new *PasswordLockoutPolicy
aggCreator *models.AggregateCreator
ctx context.Context
existingPolicy *PasswordLockoutPolicy
newPolicy *PasswordLockoutPolicy
aggCreator *models.AggregateCreator
}
type res struct {
eventLen int
@@ -207,10 +207,10 @@ func TestPasswordLockoutPolicyUpdateAggregate(t *testing.T) {
{
name: "policy update aggregate ok",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &PasswordLockoutPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName", State: int32(policy_model.PolicyStateActive)},
new: &PasswordLockoutPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName_Changed", State: int32(policy_model.PolicyStateActive)},
aggCreator: models.NewAggregateCreator("Test"),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &PasswordLockoutPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName", State: int32(policy_model.PolicyStateActive)},
newPolicy: &PasswordLockoutPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "PolicyName_Changed", State: int32(policy_model.PolicyStateActive)},
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
@@ -220,9 +220,9 @@ func TestPasswordLockoutPolicyUpdateAggregate(t *testing.T) {
{
name: "existing policy nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: nil,
aggCreator: models.NewAggregateCreator("Test"),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
@@ -234,10 +234,10 @@ func TestPasswordLockoutPolicyUpdateAggregate(t *testing.T) {
{
name: "new policy nil",
args: args{
ctx: authz.NewMockContext("orgID", "userID"),
existing: &PasswordLockoutPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "ProjectName", State: int32(policy_model.PolicyStateActive)},
new: nil,
aggCreator: models.NewAggregateCreator("Test"),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &PasswordLockoutPolicy{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Description: "ProjectName", State: int32(policy_model.PolicyStateActive)},
newPolicy: nil,
aggCreator: models.NewAggregateCreator("Test"),
},
res: res{
eventLen: 1,
@@ -249,7 +249,7 @@ func TestPasswordLockoutPolicyUpdateAggregate(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
agg, err := PasswordLockoutPolicyUpdateAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx)
agg, err := PasswordLockoutPolicyUpdateAggregate(tt.args.aggCreator, tt.args.existingPolicy, tt.args.newPolicy)(tt.args.ctx)
if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen {
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))

View File

@@ -1,8 +1,9 @@
package model
import (
"github.com/caos/zitadel/internal/model"
"time"
"github.com/caos/zitadel/internal/model"
)
type ProjectMemberView struct {

View File

@@ -80,7 +80,7 @@ func (es *ProjectEventstore) ProjectEventsByID(ctx context.Context, id string, s
func (es *ProjectEventstore) CreateProject(ctx context.Context, project *proj_model.Project) (*proj_model.Project, error) {
if !project.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.Project.Invalid")
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-IOVCC", "Errors.Project.Invalid")
}
id, err := es.idGenerator.Next()
if err != nil {
@@ -106,7 +106,7 @@ func (es *ProjectEventstore) CreateProject(ctx context.Context, project *proj_mo
func (es *ProjectEventstore) UpdateProject(ctx context.Context, project *proj_model.Project) (*proj_model.Project, error) {
if !project.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.Project.Invalid")
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7eBD6", "Errors.Project.Invalid")
}
existingProject, err := es.ProjectByID(ctx, project.AggregateID)
if err != nil {
@@ -126,15 +126,15 @@ func (es *ProjectEventstore) UpdateProject(ctx context.Context, project *proj_mo
}
func (es *ProjectEventstore) DeactivateProject(ctx context.Context, id string) (*proj_model.Project, error) {
existing, err := es.ProjectByID(ctx, id)
existingProject, err := es.ProjectByID(ctx, id)
if err != nil {
return nil, err
}
if !existing.IsActive() {
if !existingProject.IsActive() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die45", "Errors.Project.NotActive")
}
repoExisting := model.ProjectFromModel(existing)
repoExisting := model.ProjectFromModel(existingProject)
aggregate := ProjectDeactivateAggregate(es.AggregateCreator(), repoExisting)
err = es_sdk.Push(ctx, es.PushAggregates, repoExisting.AppendEvents, aggregate)
if err != nil {
@@ -145,15 +145,15 @@ func (es *ProjectEventstore) DeactivateProject(ctx context.Context, id string) (
}
func (es *ProjectEventstore) ReactivateProject(ctx context.Context, id string) (*proj_model.Project, error) {
existing, err := es.ProjectByID(ctx, id)
existingProject, err := es.ProjectByID(ctx, id)
if err != nil {
return nil, err
}
if existing.IsActive() {
if existingProject.IsActive() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die45", "Errors.Project.NotInactive")
}
repoExisting := model.ProjectFromModel(existing)
repoExisting := model.ProjectFromModel(existingProject)
aggregate := ProjectReactivateAggregate(es.AggregateCreator(), repoExisting)
err = es_sdk.Push(ctx, es.PushAggregates, repoExisting.AppendEvents, aggregate)
if err != nil {
@@ -180,11 +180,11 @@ func (es *ProjectEventstore) PrepareRemoveProject(ctx context.Context, proj *pro
if proj.AggregateID == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Akbov", "Errors.ProjectInvalid")
}
existing, err := es.ProjectByID(ctx, proj.AggregateID)
existingProject, err := es.ProjectByID(ctx, proj.AggregateID)
if err != nil {
return nil, nil, err
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
projectAggregate, err := ProjectRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoProject)
if err != nil {
return nil, nil, err
@@ -209,16 +209,16 @@ func (es *ProjectEventstore) ProjectMemberByIDs(ctx context.Context, member *pro
func (es *ProjectEventstore) AddProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) {
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.Project.MemberInvalid")
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-2OWkC", "Errors.Project.MemberInvalid")
}
existing, err := es.ProjectByID(ctx, member.AggregateID)
existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil {
return nil, err
}
if _, m := existing.GetMember(member.UserID); m != nil {
if _, m := existingProject.GetMember(member.UserID); m != nil {
return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-idke6", "Errors.Project.MemberAlreadyExists")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoMember := model.ProjectMemberFromModel(member)
addAggregate := ProjectMemberAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember)
@@ -236,16 +236,16 @@ func (es *ProjectEventstore) AddProjectMember(ctx context.Context, member *proj_
func (es *ProjectEventstore) ChangeProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) {
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.Project.MemberInvalid")
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Buh04", "Errors.Project.MemberInvalid")
}
existing, err := es.ProjectByID(ctx, member.AggregateID)
existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil {
return nil, err
}
if _, m := existing.GetMember(member.UserID); m == nil {
if _, m := existingProject.GetMember(member.UserID); m == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-oe39f", "Errors.Project.MemberNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoMember := model.ProjectMemberFromModel(member)
projectAggregate := ProjectMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember)
@@ -265,14 +265,14 @@ func (es *ProjectEventstore) RemoveProjectMember(ctx context.Context, member *pr
if member.UserID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-d43fs", "Errors.Project.MemberInvalid")
}
existing, err := es.ProjectByID(ctx, member.AggregateID)
existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil {
return err
}
if _, m := existing.GetMember(member.UserID); m == nil {
if _, m := existingProject.GetMember(member.UserID); m == nil {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-swf34", "Errors.Project.MemberNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoMember := model.ProjectMemberFromModel(member)
projectAggregate := ProjectMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember)
@@ -288,14 +288,14 @@ func (es *ProjectEventstore) PrepareRemoveProjectMember(ctx context.Context, mem
if member.UserID == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-tCXHE", "Errors.Project.MemberInvalid")
}
existing, err := es.ProjectByID(ctx, member.AggregateID)
existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil {
return nil, nil, err
}
if _, m := existing.GetMember(member.UserID); m == nil {
if _, m := existingProject.GetMember(member.UserID); m == nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-wPcg5", "Errors.Project.MemberNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoMember := model.ProjectMemberFromModel(member)
projectAggregate := ProjectMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember)
@@ -316,17 +316,17 @@ func (es *ProjectEventstore) AddProjectRoles(ctx context.Context, roles ...*proj
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-idue3", "Errors.Project.MemberInvalid")
}
}
existing, err := es.ProjectByID(ctx, roles[0].AggregateID)
existingProject, err := es.ProjectByID(ctx, roles[0].AggregateID)
if err != nil {
return nil, err
}
for _, role := range roles {
if existing.ContainsRole(role) {
if existingProject.ContainsRole(role) {
return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-sk35t", "Errors.Project.RoleAlreadyExists")
}
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoRoles := model.ProjectRolesFromModel(roles)
projectAggregate := ProjectRoleAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoRoles...)
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
@@ -347,14 +347,14 @@ func (es *ProjectEventstore) ChangeProjectRole(ctx context.Context, role *proj_m
if !role.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9die3", "Errors.Project.RoleInvalid")
}
existing, err := es.ProjectByID(ctx, role.AggregateID)
existingProject, err := es.ProjectByID(ctx, role.AggregateID)
if err != nil {
return nil, err
}
if !existing.ContainsRole(role) {
if !existingProject.ContainsRole(role) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die34", "Errors.Project.RoleNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoRole := model.ProjectRoleFromModel(role)
projectAggregate := ProjectRoleChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoRole)
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
@@ -374,14 +374,14 @@ func (es *ProjectEventstore) PrepareRemoveProjectRole(ctx context.Context, role
if role.Key == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-id823", "Errors.Project.RoleInvalid")
}
existing, err := es.ProjectByID(ctx, role.AggregateID)
existingProject, err := es.ProjectByID(ctx, role.AggregateID)
if err != nil {
return nil, nil, err
}
if !existing.ContainsRole(role) {
if !existingProject.ContainsRole(role) {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-oe823", "Errors.Project.RoleNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoRole := model.ProjectRoleFromModel(role)
grants := es.RemoveRoleFromGrants(repoProject, role.Key)
projectAggregate, err := ProjectRoleRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoProject, repoRole, grants)
@@ -391,9 +391,9 @@ func (es *ProjectEventstore) PrepareRemoveProjectRole(ctx context.Context, role
return repoProject, projectAggregate, nil
}
func (es *ProjectEventstore) RemoveRoleFromGrants(existing *model.Project, roleKey string) []*model.ProjectGrant {
grants := make([]*model.ProjectGrant, len(existing.Grants))
for i, grant := range existing.Grants {
func (es *ProjectEventstore) RemoveRoleFromGrants(existingProject *model.Project, roleKey string) []*model.ProjectGrant {
grants := make([]*model.ProjectGrant, len(existingProject.Grants))
for i, grant := range existingProject.Grants {
newGrant := *grant
roles := make([]string, 0)
for _, role := range newGrant.RoleKeys {
@@ -468,7 +468,7 @@ func (es *ProjectEventstore) ProjectChanges(ctx context.Context, id string, last
}, nil
}
func ChangesQuery(projID string, latestSequence, limit uint64, sortAscending bool) *es_models.SearchQuery {
func ChangesQuery(projectID string, latestSequence, limit uint64, sortAscending bool) *es_models.SearchQuery {
query := es_models.NewSearchQuery().
AggregateTypeFilter(model.ProjectAggregate)
if !sortAscending {
@@ -476,7 +476,7 @@ func ChangesQuery(projID string, latestSequence, limit uint64, sortAscending boo
}
query.LatestSequenceFilter(latestSequence).
AggregateIDFilter(projID).
AggregateIDFilter(projectID).
SetLimit(limit)
return query
}
@@ -500,7 +500,7 @@ func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model
if app == nil || !app.IsValid(true) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9eidw", "Errors.Project.AppInvalid")
}
existing, err := es.ProjectByID(ctx, app.AggregateID)
existingProject, err := es.ProjectByID(ctx, app.AggregateID)
if err != nil {
return nil, err
}
@@ -513,7 +513,7 @@ func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model
var stringPw string
if app.OIDCConfig != nil {
app.OIDCConfig.AppID = id
err := app.OIDCConfig.GenerateNewClientID(es.idGenerator, existing)
err := app.OIDCConfig.GenerateNewClientID(es.idGenerator, existingProject)
if err != nil {
return nil, err
}
@@ -522,7 +522,7 @@ func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model
return nil, err
}
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoApp := model.AppFromModel(app)
addAggregate := ApplicationAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp)
@@ -544,14 +544,14 @@ func (es *ProjectEventstore) ChangeApplication(ctx context.Context, app *proj_mo
if app == nil || !app.IsValid(false) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dieuw", "Errors.Project.AppInvalid")
}
existing, err := es.ProjectByID(ctx, app.AggregateID)
existingProject, err := es.ProjectByID(ctx, app.AggregateID)
if err != nil {
return nil, err
}
if _, app := existing.GetApp(app.AppID); app == nil {
if _, app := existingProject.GetApp(app.AppID); app == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die83", "Errors.Project.AppNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoApp := model.AppFromModel(app)
projectAggregate := ApplicationChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp)
@@ -570,14 +570,14 @@ func (es *ProjectEventstore) RemoveApplication(ctx context.Context, app *proj_mo
if app.AppID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-id832", "Errors.Project.IDMissing")
}
existing, err := es.ProjectByID(ctx, app.AggregateID)
existingProject, err := es.ProjectByID(ctx, app.AggregateID)
if err != nil {
return err
}
if _, app := existing.GetApp(app.AppID); app == nil {
if _, app := existingProject.GetApp(app.AppID); app == nil {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83s", "Errors.Project.AppNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
appRepo := model.AppFromModel(app)
projectAggregate := ApplicationRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, appRepo)
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
@@ -592,14 +592,14 @@ func (es *ProjectEventstore) PrepareRemoveApplication(ctx context.Context, app *
if app.AppID == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-xu0Wy", "Errors.Project.IDMissing")
}
existing, err := es.ProjectByID(ctx, app.AggregateID)
existingProject, err := es.ProjectByID(ctx, app.AggregateID)
if err != nil {
return nil, nil, err
}
if _, app := existing.GetApp(app.AppID); app == nil {
if _, app := existingProject.GetApp(app.AppID); app == nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-gaOD2", "Errors.Project.AppNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
appRepo := model.AppFromModel(app)
projectAggregate := ApplicationRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, appRepo)
agg, err := projectAggregate(ctx)
@@ -659,15 +659,15 @@ func (es *ProjectEventstore) DeactivateApplication(ctx context.Context, projectI
if appID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dlp9e", "Errors.Project.IDMissing")
}
existing, err := es.ProjectByID(ctx, projectID)
existingProject, err := es.ProjectByID(ctx, projectID)
if err != nil {
return nil, err
}
app := &proj_model.Application{AppID: appID}
if _, app := existing.GetApp(app.AppID); app == nil {
if _, app := existingProject.GetApp(app.AppID); app == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-slpe9", "Errors.Project.AppNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoApp := model.AppFromModel(app)
projectAggregate := ApplicationDeactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp)
@@ -686,15 +686,15 @@ func (es *ProjectEventstore) ReactivateApplication(ctx context.Context, projectI
if appID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0odi2", "Errors.Project.IDMissing")
}
existing, err := es.ProjectByID(ctx, projectID)
existingProject, err := es.ProjectByID(ctx, projectID)
if err != nil {
return nil, err
}
app := &proj_model.Application{AppID: appID}
if _, app := existing.GetApp(app.AppID); app == nil {
if _, app := existingProject.GetApp(app.AppID); app == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld92d", "Errors.Project.AppNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoApp := model.AppFromModel(app)
projectAggregate := ApplicationReactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp)
@@ -713,18 +713,18 @@ func (es *ProjectEventstore) ChangeOIDCConfig(ctx context.Context, config *proj_
if config == nil || !config.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-du834", "Errors.Project.OIDCConfigInvalid")
}
existing, err := es.ProjectByID(ctx, config.AggregateID)
existingProject, err := es.ProjectByID(ctx, config.AggregateID)
if err != nil {
return nil, err
}
var app *proj_model.Application
if _, app = existing.GetApp(config.AppID); app == nil {
if _, app = existingProject.GetApp(config.AppID); app == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dkso8", "Errors.Project.AppNoExisting")
}
if app.Type != proj_model.AppTypeOIDC {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-98uje", "Errors.Project.AppIsNotOIDC")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoConfig := model.OIDCConfigFromModel(config)
projectAggregate := OIDCConfigChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoConfig)
@@ -743,12 +743,12 @@ func (es *ProjectEventstore) ChangeOIDCConfigSecret(ctx context.Context, project
if appID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7ue34", "Errors.Project.OIDCConfigInvalid")
}
existing, err := es.ProjectByID(ctx, projectID)
existingProject, err := es.ProjectByID(ctx, projectID)
if err != nil {
return nil, err
}
var app *proj_model.Application
if _, app = existing.GetApp(appID); app == nil {
if _, app = existingProject.GetApp(appID); app == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9odi4", "Errors.Project.AppNotExisting")
}
if app.Type != proj_model.AppTypeOIDC {
@@ -757,7 +757,7 @@ func (es *ProjectEventstore) ChangeOIDCConfigSecret(ctx context.Context, project
if app.OIDCConfig.AuthMethodType == proj_model.OIDCAuthMethodTypeNone {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-GDrg2", "Errors.Project.OIDCAuthMethodNoneSecret")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
stringPw, err := app.OIDCConfig.GenerateNewClientSecret(es.pwGenerator)
if err != nil {
@@ -784,12 +784,12 @@ func (es *ProjectEventstore) VerifyOIDCClientSecret(ctx context.Context, project
if appID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-H3RT2", "Errors.Project.RequiredFieldsMissing")
}
existing, err := es.ProjectByID(ctx, projectID)
existingProject, err := es.ProjectByID(ctx, projectID)
if err != nil {
return err
}
var app *proj_model.Application
if _, app = existing.GetApp(appID); app == nil {
if _, app = existingProject.GetApp(appID); app == nil {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-D6hba", "Errors.Project.AppNoExisting")
}
if app.Type != proj_model.AppTypeOIDC {
@@ -797,9 +797,9 @@ func (es *ProjectEventstore) VerifyOIDCClientSecret(ctx context.Context, project
}
if err := crypto.CompareHash(app.OIDCConfig.ClientSecret, []byte(secret), es.passwordAlg); err == nil {
return es.setOIDCClientSecretCheckResult(ctx, existing, app.AppID, OIDCClientSecretCheckSucceededAggregate)
return es.setOIDCClientSecretCheckResult(ctx, existingProject, app.AppID, OIDCClientSecretCheckSucceededAggregate)
}
if err := es.setOIDCClientSecretCheckResult(ctx, existing, app.AppID, OIDCClientSecretCheckFailedAggregate); err != nil {
if err := es.setOIDCClientSecretCheckResult(ctx, existingProject, app.AppID, OIDCClientSecretCheckFailedAggregate); err != nil {
return err
}
return caos_errs.ThrowInvalidArgument(nil, "EVENT-wg24q", "Errors.Internal")
@@ -834,14 +834,14 @@ func (es *ProjectEventstore) AddProjectGrant(ctx context.Context, grant *proj_mo
if grant == nil || !grant.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-37dhs", "Errors.Project.GrantInvalid")
}
existing, err := es.ProjectByID(ctx, grant.AggregateID)
existingProject, err := es.ProjectByID(ctx, grant.AggregateID)
if err != nil {
return nil, err
}
if existing.ContainsGrantForOrg(grant.GrantedOrgID) {
if existingProject.ContainsGrantForOrg(grant.GrantedOrgID) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7ug4g", "Errors.Project.GrantAlreadyExists")
}
if !existing.ContainsRoles(grant.RoleKeys) {
if !existingProject.ContainsRoles(grant.RoleKeys) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83d", "Errors.Project.GrantHasNotExistingRole")
}
id, err := es.idGenerator.Next()
@@ -850,7 +850,7 @@ func (es *ProjectEventstore) AddProjectGrant(ctx context.Context, grant *proj_mo
}
grant.GrantID = id
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoGrant := model.GrantFromModel(grant)
addAggregate := ProjectGrantAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoGrant)
@@ -868,19 +868,19 @@ func (es *ProjectEventstore) PrepareChangeProjectGrant(ctx context.Context, gran
if grant == nil && grant.GrantID == "" {
return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8sie3", "Errors.Project.GrantInvalid")
}
existing, err := es.ProjectByID(ctx, grant.AggregateID)
existingProject, err := es.ProjectByID(ctx, grant.AggregateID)
if err != nil {
return nil, nil, nil, err
}
_, existingGrant := existing.GetGrant(grant.GrantID)
_, existingGrant := existingProject.GetGrant(grant.GrantID)
if existingGrant == nil {
return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die83", "Errors.Project.GrantNotExisting")
}
if !existing.ContainsRoles(grant.RoleKeys) {
if !existingProject.ContainsRoles(grant.RoleKeys) {
return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83d", "Error.Project.GrantHasNotExistingRole")
}
removedRoles := existingGrant.GetRemovedRoles(grant.RoleKeys)
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoGrant := model.GrantFromModel(grant)
projectAggregate := ProjectGrantChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoGrant)
@@ -920,14 +920,14 @@ func (es *ProjectEventstore) PrepareRemoveProjectGrant(ctx context.Context, gran
if grant.GrantID == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8eud6", "Errors.Project.IDMissing")
}
existing, err := es.ProjectByID(ctx, grant.AggregateID)
existingProject, err := es.ProjectByID(ctx, grant.AggregateID)
if err != nil {
return nil, nil, err
}
if _, g := existing.GetGrant(grant.GrantID); g == nil {
if _, g := existingProject.GetGrant(grant.GrantID); g == nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9ie3s", "Errors.Project.GrantNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
grantRepo := model.GrantFromModel(grant)
projectAggregate := ProjectGrantRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, grantRepo)
return repoProject, projectAggregate, nil
@@ -937,15 +937,15 @@ func (es *ProjectEventstore) DeactivateProjectGrant(ctx context.Context, project
if grantID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7due2", "Errors.Project.IDMissing")
}
existing, err := es.ProjectByID(ctx, projectID)
existingProject, err := es.ProjectByID(ctx, projectID)
if err != nil {
return nil, err
}
grant := &proj_model.ProjectGrant{GrantID: grantID}
if _, g := existing.GetGrant(grant.GrantID); g == nil {
if _, g := existingProject.GetGrant(grant.GrantID); g == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-slpe9", "Errors.Project.GrantNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoGrant := model.GrantFromModel(grant)
projectAggregate := ProjectGrantDeactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoGrant)
@@ -964,15 +964,15 @@ func (es *ProjectEventstore) ReactivateProjectGrant(ctx context.Context, project
if grantID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-d7suw", "Errors.Project.IDMissing")
}
existing, err := es.ProjectByID(ctx, projectID)
existingProject, err := es.ProjectByID(ctx, projectID)
if err != nil {
return nil, err
}
grant := &proj_model.ProjectGrant{GrantID: grantID}
if _, g := existing.GetGrant(grant.GrantID); g == nil {
if _, g := existingProject.GetGrant(grant.GrantID); g == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0spew", "Errors.Project.GrantNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoGrant := model.GrantFromModel(grant)
projectAggregate := ProjectGrantReactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoGrant)
@@ -1008,14 +1008,14 @@ func (es *ProjectEventstore) AddProjectGrantMember(ctx context.Context, member *
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0dor4", "Errors.Project.MemberInvalid")
}
existing, err := es.ProjectByID(ctx, member.AggregateID)
existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil {
return nil, err
}
if existing.ContainsGrantMember(member) {
if existingProject.ContainsGrantMember(member) {
return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-8die3", "Errors.Project.MemberAlreadyExists")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoMember := model.GrantMemberFromModel(member)
addAggregate := ProjectGrantMemberAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember)
@@ -1036,14 +1036,14 @@ func (es *ProjectEventstore) ChangeProjectGrantMember(ctx context.Context, membe
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dkw35", "Errors.Project.MemberInvalid")
}
existing, err := es.ProjectByID(ctx, member.AggregateID)
existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil {
return nil, err
}
if !existing.ContainsGrantMember(member) {
if !existingProject.ContainsGrantMember(member) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8dj4s", "Errors.Project.MemberNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoMember := model.GrantMemberFromModel(member)
projectAggregate := ProjectGrantMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember)
@@ -1064,14 +1064,14 @@ func (es *ProjectEventstore) RemoveProjectGrantMember(ctx context.Context, membe
if member.UserID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-8su4r", "Errors.Project.MemberInvalid")
}
existing, err := es.ProjectByID(ctx, member.AggregateID)
existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil {
return err
}
if !existing.ContainsGrantMember(member) {
if !existingProject.ContainsGrantMember(member) {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-9ode4", "Errors.Project.MemberNotExisting")
}
repoProject := model.ProjectFromModel(existing)
repoProject := model.ProjectFromModel(existingProject)
repoMember := model.GrantMemberFromModel(member)
projectAggregate := ProjectGrantMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember)

View File

@@ -207,10 +207,10 @@ func TestUpdateProject(t *testing.T) {
func TestDeactivateProject(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {
es *ProjectEventstore
ctx context.Context
existing *model.Project
new *model.Project
es *ProjectEventstore
ctx context.Context
existingProject *model.Project
newProject *model.Project
}
type res struct {
project *model.Project
@@ -225,9 +225,9 @@ func TestDeactivateProject(t *testing.T) {
{
name: "deactivate project, ok",
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive},
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existingProject: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive},
},
res: res{
project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "NameNew", State: model.ProjectStateInactive},
@@ -236,9 +236,9 @@ func TestDeactivateProject(t *testing.T) {
{
name: "deactivate project with inactive state",
args: args{
es: GetMockManipulateInactiveProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateInactive},
es: GetMockManipulateInactiveProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existingProject: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateInactive},
},
res: res{
wantErr: true,
@@ -248,9 +248,9 @@ func TestDeactivateProject(t *testing.T) {
{
name: "existing not found",
args: args{
es: GetMockManipulateProjectNoEvents(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive},
es: GetMockManipulateProjectNoEvents(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existingProject: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive},
},
res: res{
wantErr: true,
@@ -260,7 +260,7 @@ func TestDeactivateProject(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := tt.args.es.DeactivateProject(tt.args.ctx, tt.args.existing.AggregateID)
result, err := tt.args.es.DeactivateProject(tt.args.ctx, tt.args.existingProject.AggregateID)
if !tt.res.wantErr && result.AggregateID == "" {
t.Errorf("result has no id")
@@ -278,10 +278,10 @@ func TestDeactivateProject(t *testing.T) {
func TestReactivateProject(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {
es *ProjectEventstore
ctx context.Context
existing *model.Project
new *model.Project
es *ProjectEventstore
ctx context.Context
existingPolicy *model.Project
newPolicy *model.Project
}
type res struct {
project *model.Project
@@ -296,9 +296,9 @@ func TestReactivateProject(t *testing.T) {
{
name: "reactivate project, ok",
args: args{
es: GetMockManipulateInactiveProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateInactive},
es: GetMockManipulateInactiveProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateInactive},
},
res: res{
project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "NameNew", State: model.ProjectStateActive},
@@ -307,9 +307,9 @@ func TestReactivateProject(t *testing.T) {
{
name: "reactivate project with inactive state",
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive},
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive},
},
res: res{
wantErr: true,
@@ -319,9 +319,9 @@ func TestReactivateProject(t *testing.T) {
{
name: "existing not found",
args: args{
es: GetMockManipulateProjectNoEvents(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive},
es: GetMockManipulateProjectNoEvents(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive},
},
res: res{
wantErr: true,
@@ -331,7 +331,7 @@ func TestReactivateProject(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := tt.args.es.ReactivateProject(tt.args.ctx, tt.args.existing.AggregateID)
result, err := tt.args.es.ReactivateProject(tt.args.ctx, tt.args.existingPolicy.AggregateID)
if !tt.res.wantErr && result.AggregateID == "" {
t.Errorf("result has no id")
@@ -349,9 +349,9 @@ func TestReactivateProject(t *testing.T) {
func TestRemoveProject(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {
es *ProjectEventstore
ctx context.Context
existing *model.Project
es *ProjectEventstore
ctx context.Context
existingPolicy *model.Project
}
type res struct {
result *model.Project
@@ -368,10 +368,12 @@ func TestRemoveProject(t *testing.T) {
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{
existingPolicy: &model.Project{
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1},
Name: "Name",
Members: []*model.ProjectMember{&model.ProjectMember{UserID: "UserID", Roles: []string{"Roles"}}},
Members: []*model.ProjectMember{
{UserID: "UserID", Roles: []string{"Roles"}},
},
},
},
res: res{
@@ -383,10 +385,12 @@ func TestRemoveProject(t *testing.T) {
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{
existingPolicy: &model.Project{
ObjectRoot: es_models.ObjectRoot{Sequence: 1},
Name: "Name",
Members: []*model.ProjectMember{&model.ProjectMember{UserID: "UserID", Roles: []string{"Roles"}}},
Members: []*model.ProjectMember{
{UserID: "UserID", Roles: []string{"Roles"}},
},
},
},
res: res{
@@ -397,9 +401,9 @@ func TestRemoveProject(t *testing.T) {
{
name: "project not existing",
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{},
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &model.Project{},
},
res: res{
wantErr: true,
@@ -409,9 +413,9 @@ func TestRemoveProject(t *testing.T) {
{
name: "existing not found",
args: args{
es: GetMockManipulateProjectNoEvents(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "OtherAggregateID", Sequence: 1}},
es: GetMockManipulateProjectNoEvents(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existingPolicy: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "OtherAggregateID", Sequence: 1}},
},
res: res{
wantErr: true,
@@ -421,7 +425,7 @@ func TestRemoveProject(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.args.es.RemoveProject(tt.args.ctx, tt.args.existing)
err := tt.args.es.RemoveProject(tt.args.ctx, tt.args.existingPolicy)
if !tt.res.wantErr && err != nil {
t.Errorf("should not get err")
@@ -700,10 +704,10 @@ func TestChangeProjectMember(t *testing.T) {
func TestRemoveProjectMember(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {
es *ProjectEventstore
ctx context.Context
existing *model.Project
member *model.ProjectMember
es *ProjectEventstore
ctx context.Context
existingProject *model.Project
member *model.ProjectMember
}
type res struct {
result *model.ProjectMember
@@ -720,10 +724,12 @@ func TestRemoveProjectMember(t *testing.T) {
args: args{
es: GetMockManipulateProjectWithMember(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{
existingProject: &model.Project{
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1},
Name: "Name",
Members: []*model.ProjectMember{&model.ProjectMember{UserID: "UserID", Roles: []string{"Roles"}}},
Members: []*model.ProjectMember{
{UserID: "UserID", Roles: []string{"Roles"}},
},
},
member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID"},
},
@@ -736,10 +742,12 @@ func TestRemoveProjectMember(t *testing.T) {
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{
existingProject: &model.Project{
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1},
Name: "Name",
Members: []*model.ProjectMember{&model.ProjectMember{UserID: "UserID", Roles: []string{"Roles"}}},
Members: []*model.ProjectMember{
{UserID: "UserID", Roles: []string{"Roles"}},
},
},
member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Roles: []string{"ChangeRoles"}},
},
@@ -753,7 +761,7 @@ func TestRemoveProjectMember(t *testing.T) {
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
existing: &model.Project{
existingProject: &model.Project{
ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1},
Name: "Name",
},
@@ -811,9 +819,11 @@ func TestAddProjectRole(t *testing.T) {
{
name: "add project role, ok",
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
roles: []*model.ProjectRole{&model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}},
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
roles: []*model.ProjectRole{
{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"},
},
},
res: res{
result: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"},
@@ -822,9 +832,11 @@ func TestAddProjectRole(t *testing.T) {
{
name: "no key",
args: args{
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
roles: []*model.ProjectRole{&model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, DisplayName: "DisplayName", Group: "Group"}},
es: GetMockManipulateProject(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
roles: []*model.ProjectRole{
{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, DisplayName: "DisplayName", Group: "Group"},
},
},
res: res{
wantErr: true,
@@ -834,9 +846,11 @@ func TestAddProjectRole(t *testing.T) {
{
name: "role already existing",
args: args{
es: GetMockManipulateProjectWithRole(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
roles: []*model.ProjectRole{&model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}},
es: GetMockManipulateProjectWithRole(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
roles: []*model.ProjectRole{
{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"},
},
},
res: res{
wantErr: true,
@@ -846,9 +860,11 @@ func TestAddProjectRole(t *testing.T) {
{
name: "existing project not found",
args: args{
es: GetMockManipulateProjectNoEvents(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
roles: []*model.ProjectRole{&model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}},
es: GetMockManipulateProjectNoEvents(ctrl),
ctx: authz.NewMockContext("orgID", "userID"),
roles: []*model.ProjectRole{
{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"},
},
},
res: res{
wantErr: true,
@@ -2733,7 +2749,12 @@ func TestChangesProject(t *testing.T) {
limit: 0,
},
res: res{
changes: &model.ProjectChanges{Changes: []*model.ProjectChange{&model.ProjectChange{EventType: "", Sequence: 1, ModifierId: ""}}, LastSequence: 1},
changes: &model.ProjectChanges{
Changes: []*model.ProjectChange{
{EventType: "", Sequence: 1, ModifierId: ""},
},
LastSequence: 1,
},
project: &model.Project{Name: "MusterProject"},
},
},
@@ -2777,7 +2798,7 @@ func TestChangesApplication(t *testing.T) {
type args struct {
es *ProjectEventstore
id string
secId string
secID string
lastSequence uint64
limit uint64
}
@@ -2797,13 +2818,18 @@ func TestChangesApplication(t *testing.T) {
args: args{
es: GetMockChangesApplicationOK(ctrl),
id: "1",
secId: "AppId",
secID: "AppId",
lastSequence: 0,
limit: 0,
},
res: res{
changes: &model.ApplicationChanges{Changes: []*model.ApplicationChange{&model.ApplicationChange{EventType: "", Sequence: 1, ModifierId: ""}}, LastSequence: 1},
app: &model.Application{Name: "MusterApp", AppID: "AppId", Type: 3},
changes: &model.ApplicationChanges{
Changes: []*model.ApplicationChange{
{EventType: "", Sequence: 1, ModifierId: ""},
},
LastSequence: 1,
},
app: &model.Application{Name: "MusterApp", AppID: "AppId", Type: 3},
},
},
{
@@ -2811,7 +2837,7 @@ func TestChangesApplication(t *testing.T) {
args: args{
es: GetMockChangesApplicationNoEvents(ctrl),
id: "2",
secId: "2",
secID: "2",
lastSequence: 0,
limit: 0,
},
@@ -2823,7 +2849,7 @@ func TestChangesApplication(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := tt.args.es.ApplicationChanges(nil, tt.args.id, tt.args.secId, tt.args.lastSequence, tt.args.limit, false)
result, err := tt.args.es.ApplicationChanges(nil, tt.args.id, tt.args.secID, tt.args.lastSequence, tt.args.limit, false)
app := &model.Application{}
if result != nil && len(result.Changes) > 0 {

View File

@@ -2,15 +2,16 @@ package model
import (
"encoding/json"
"testing"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/project/model"
"testing"
)
func TestApplicationChanges(t *testing.T) {
type args struct {
existing *Application
new *Application
existingProject *Application
newProject *Application
}
type res struct {
changesLen int
@@ -23,8 +24,8 @@ func TestApplicationChanges(t *testing.T) {
{
name: "application name changes",
args: args{
existing: &Application{AppID: "AppID", Name: "Name"},
new: &Application{AppID: "AppID", Name: "NameChanged"},
existingProject: &Application{AppID: "AppID", Name: "Name"},
newProject: &Application{AppID: "AppID", Name: "NameChanged"},
},
res: res{
changesLen: 2,
@@ -33,8 +34,8 @@ func TestApplicationChanges(t *testing.T) {
{
name: "no changes",
args: args{
existing: &Application{AppID: "AppID", Name: "Name"},
new: &Application{AppID: "AppID", Name: "Name"},
existingProject: &Application{AppID: "AppID", Name: "Name"},
newProject: &Application{AppID: "AppID", Name: "Name"},
},
res: res{
changesLen: 1,
@@ -43,7 +44,7 @@ func TestApplicationChanges(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
changes := tt.args.existing.Changes(tt.args.new)
changes := tt.args.existingProject.Changes(tt.args.newProject)
if len(changes) != tt.res.changesLen {
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
}
@@ -69,7 +70,11 @@ func TestAppendAddAppEvent(t *testing.T) {
app: &Application{Name: "Application"},
event: &es_models.Event{},
},
result: &Project{Applications: []*Application{&Application{Name: "Application"}}},
result: &Project{
Applications: []*Application{
{Name: "Application"},
},
},
},
}
for _, tt := range tests {
@@ -103,11 +108,19 @@ func TestAppendChangeAppEvent(t *testing.T) {
{
name: "append change application event",
args: args{
project: &Project{Applications: []*Application{&Application{Name: "Application"}}},
app: &Application{Name: "Application Change"},
event: &es_models.Event{},
project: &Project{
Applications: []*Application{
{Name: "Application"},
},
},
app: &Application{Name: "Application Change"},
event: &es_models.Event{},
},
result: &Project{
Applications: []*Application{
{Name: "Application Change"},
},
},
result: &Project{Applications: []*Application{&Application{Name: "Application Change"}}},
},
}
for _, tt := range tests {
@@ -141,9 +154,13 @@ func TestAppendRemoveAppEvent(t *testing.T) {
{
name: "append remove application event",
args: args{
project: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application"}}},
app: &Application{AppID: "AppID", Name: "Application"},
event: &es_models.Event{},
project: &Project{
Applications: []*Application{
{AppID: "AppID", Name: "Application"},
},
},
app: &Application{AppID: "AppID", Name: "Application"},
event: &es_models.Event{},
},
result: &Project{Applications: []*Application{}},
},
@@ -177,22 +194,38 @@ func TestAppendAppStateEvent(t *testing.T) {
{
name: "append deactivate application event",
args: args{
project: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application", State: int32(model.AppStateActive)}}},
app: &ApplicationID{AppID: "AppID"},
event: &es_models.Event{},
state: model.AppStateInactive,
project: &Project{
Applications: []*Application{
{AppID: "AppID", Name: "Application", State: int32(model.AppStateActive)},
},
},
app: &ApplicationID{AppID: "AppID"},
event: &es_models.Event{},
state: model.AppStateInactive,
},
result: &Project{
Applications: []*Application{
{AppID: "AppID", Name: "Application", State: int32(model.AppStateInactive)},
},
},
result: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application", State: int32(model.AppStateInactive)}}},
},
{
name: "append reactivate application event",
args: args{
project: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application", State: int32(model.AppStateInactive)}}},
app: &ApplicationID{AppID: "AppID"},
event: &es_models.Event{},
state: model.AppStateActive,
project: &Project{
Applications: []*Application{
{AppID: "AppID", Name: "Application", State: int32(model.AppStateInactive)},
},
},
app: &ApplicationID{AppID: "AppID"},
event: &es_models.Event{},
state: model.AppStateActive,
},
result: &Project{
Applications: []*Application{
{AppID: "AppID", Name: "Application", State: int32(model.AppStateActive)},
},
},
result: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application", State: int32(model.AppStateActive)}}},
},
}
for _, tt := range tests {

View File

@@ -2,14 +2,15 @@ package model
import (
"encoding/json"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"testing"
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
func TestOIDCConfigChanges(t *testing.T) {
type args struct {
existing *OIDCConfig
new *OIDCConfig
existingConfig *OIDCConfig
newConfig *OIDCConfig
}
type res struct {
changesLen int
@@ -22,7 +23,7 @@ func TestOIDCConfigChanges(t *testing.T) {
{
name: "all possible values change",
args: args{
existing: &OIDCConfig{
existingConfig: &OIDCConfig{
AppID: "AppID",
RedirectUris: []string{"RedirectUris"},
ResponseTypes: []int32{1},
@@ -31,7 +32,7 @@ func TestOIDCConfigChanges(t *testing.T) {
AuthMethodType: 1,
PostLogoutRedirectUris: []string{"PostLogoutRedirectUris"},
},
new: &OIDCConfig{
newConfig: &OIDCConfig{
AppID: "AppID",
RedirectUris: []string{"RedirectUrisChanged"},
ResponseTypes: []int32{2},
@@ -48,7 +49,7 @@ func TestOIDCConfigChanges(t *testing.T) {
{
name: "no changes",
args: args{
existing: &OIDCConfig{
existingConfig: &OIDCConfig{
AppID: "AppID",
RedirectUris: []string{"RedirectUris"},
ResponseTypes: []int32{1},
@@ -57,7 +58,7 @@ func TestOIDCConfigChanges(t *testing.T) {
AuthMethodType: 1,
PostLogoutRedirectUris: []string{"PostLogoutRedirectUris"},
},
new: &OIDCConfig{
newConfig: &OIDCConfig{
AppID: "AppID",
RedirectUris: []string{"RedirectUris"},
ResponseTypes: []int32{1},
@@ -74,11 +75,11 @@ func TestOIDCConfigChanges(t *testing.T) {
{
name: "change not changeable attributes",
args: args{
existing: &OIDCConfig{
existingConfig: &OIDCConfig{
AppID: "AppID",
ClientID: "ClientID",
},
new: &OIDCConfig{
newConfig: &OIDCConfig{
AppID: "AppIDChange",
ClientID: "ClientIDChange",
},
@@ -90,7 +91,7 @@ func TestOIDCConfigChanges(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
changes := tt.args.existing.Changes(tt.args.new)
changes := tt.args.existingConfig.Changes(tt.args.newConfig)
if len(changes) != tt.res.changesLen {
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
}
@@ -112,11 +113,19 @@ func TestAppendAddOIDCConfigEvent(t *testing.T) {
{
name: "append add application event",
args: args{
project: &Project{Applications: []*Application{&Application{AppID: "AppID"}}},
config: &OIDCConfig{AppID: "AppID", ClientID: "ClientID"},
event: &es_models.Event{},
project: &Project{
Applications: []*Application{
{AppID: "AppID"},
},
},
config: &OIDCConfig{AppID: "AppID", ClientID: "ClientID"},
event: &es_models.Event{},
},
result: &Project{
Applications: []*Application{
{AppID: "AppID", OIDCConfig: &OIDCConfig{AppID: "AppID", ClientID: "ClientID"}},
},
},
result: &Project{Applications: []*Application{&Application{AppID: "AppID", OIDCConfig: &OIDCConfig{AppID: "AppID", ClientID: "ClientID"}}}},
},
}
for _, tt := range tests {
@@ -153,11 +162,19 @@ func TestAppendChangeOIDCConfigEvent(t *testing.T) {
{
name: "append change application event",
args: args{
project: &Project{Applications: []*Application{&Application{AppID: "AppID", OIDCConfig: &OIDCConfig{AppID: "AppID", ClientID: "ClientID"}}}},
config: &OIDCConfig{AppID: "AppID", ClientID: "ClientID Changed"},
event: &es_models.Event{},
project: &Project{
Applications: []*Application{
{AppID: "AppID", OIDCConfig: &OIDCConfig{AppID: "AppID", ClientID: "ClientID"}},
},
},
config: &OIDCConfig{AppID: "AppID", ClientID: "ClientID Changed"},
event: &es_models.Event{},
},
result: &Project{
Applications: []*Application{
{AppID: "AppID", OIDCConfig: &OIDCConfig{AppID: "AppID", ClientID: "ClientID Changed"}},
},
},
result: &Project{Applications: []*Application{&Application{AppID: "AppID", OIDCConfig: &OIDCConfig{AppID: "AppID", ClientID: "ClientID Changed"}}}},
},
}
for _, tt := range tests {

View File

@@ -2,15 +2,16 @@ package model
import (
"encoding/json"
"testing"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/project/model"
"testing"
)
func TestProjectChanges(t *testing.T) {
type args struct {
existing *Project
new *Project
existingProject *Project
newProject *Project
}
type res struct {
changesLen int
@@ -23,8 +24,8 @@ func TestProjectChanges(t *testing.T) {
{
name: "project name changes",
args: args{
existing: &Project{Name: "Name"},
new: &Project{Name: "NameChanged"},
existingProject: &Project{Name: "Name"},
newProject: &Project{Name: "NameChanged"},
},
res: res{
changesLen: 1,
@@ -33,8 +34,8 @@ func TestProjectChanges(t *testing.T) {
{
name: "no changes",
args: args{
existing: &Project{Name: "Name"},
new: &Project{Name: "Name"},
existingProject: &Project{Name: "Name"},
newProject: &Project{Name: "Name"},
},
res: res{
changesLen: 0,
@@ -43,7 +44,7 @@ func TestProjectChanges(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
changes := tt.args.existing.Changes(tt.args.new)
changes := tt.args.existingProject.Changes(tt.args.newProject)
if len(changes) != tt.res.changesLen {
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
}
@@ -65,7 +66,7 @@ func TestProjectFromEvents(t *testing.T) {
name: "project from events, ok",
args: args{
event: []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: ProjectAdded},
{AggregateID: "AggregateID", Sequence: 1, Type: ProjectAdded},
},
project: &Project{Name: "ProjectName"},
},
@@ -75,7 +76,7 @@ func TestProjectFromEvents(t *testing.T) {
name: "project from events, nil project",
args: args{
event: []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: ProjectAdded},
{AggregateID: "AggregateID", Sequence: 1, Type: ProjectAdded},
},
project: nil,
},

View File

@@ -2,6 +2,7 @@ package eventsourcing
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/crypto"
@@ -59,25 +60,25 @@ func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *mod
}
}
func ProjectUpdateAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, new *model.Project) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectUpdateAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, newProject *model.Project) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if new == nil {
if newProject == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
changes := existing.Changes(new)
changes := existingProject.Changes(newProject)
if len(changes) == 0 {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-9soPE", "Errors.NoChangesFound")
}
if existing.Name != new.Name {
if existingProject.Name != newProject.Name {
validationQuery := es_models.NewSearchQuery().
AggregateTypeFilter(model.ProjectAggregate).
EventTypesFilter(model.ProjectAdded, model.ProjectChanged, model.ProjectRemoved)
validation := addProjectValidation(new.Name)
validation := addProjectValidation(newProject.Name)
agg.SetPrecondition(validationQuery, validation)
}
return agg.AppendEvent(model.ProjectChanged, changes)
@@ -102,23 +103,23 @@ func projectStateAggregate(aggCreator *es_models.AggregateCreator, project *mode
}
}
func ProjectRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.Project) (*es_models.Aggregate, error) {
if existing == nil {
func ProjectRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existingProject *model.Project) (*es_models.Aggregate, error) {
if existingProject == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Cj7lb", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.ProjectRemoved, existing)
return agg.AppendEvent(model.ProjectRemoved, existingProject)
}
func ProjectMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectMember) 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-ie34f", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -131,13 +132,13 @@ func ProjectMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existin
}
}
func ProjectMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectMember) 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-d34fs", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -145,12 +146,12 @@ func ProjectMemberChangedAggregate(aggCreator *es_models.AggregateCreator, exist
}
}
func ProjectMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectMember) 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-dieu7", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -158,12 +159,12 @@ func ProjectMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, exist
}
}
func ProjectRoleAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, roles ...*model.ProjectRole) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectRoleAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, roles ...*model.ProjectRole) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if roles == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sleo9", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -177,12 +178,12 @@ func ProjectRoleAddedAggregate(aggCreator *es_models.AggregateCreator, existing
}
}
func ProjectRoleChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, role *model.ProjectRole) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectRoleChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, role *model.ProjectRole) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if role == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-oe8sf", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -190,11 +191,11 @@ func ProjectRoleChangedAggregate(aggCreator *es_models.AggregateCreator, existin
}
}
func ProjectRoleRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.Project, role *model.ProjectRole, grants []*model.ProjectGrant) (*es_models.Aggregate, error) {
func ProjectRoleRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existingProject *model.Project, role *model.ProjectRole, grants []*model.ProjectGrant) (*es_models.Aggregate, error) {
if role == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d8eis", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -204,7 +205,7 @@ func ProjectRoleRemovedAggregate(ctx context.Context, aggCreator *es_models.Aggr
}
for _, grant := range grants {
var changes map[string]interface{}
if _, g := model.GetProjectGrant(existing.Grants, grant.GrantID); grant != nil {
if _, g := model.GetProjectGrant(existingProject.Grants, grant.GrantID); grant != nil {
changes = g.Changes(grant)
agg, err = agg.AppendEvent(model.ProjectGrantCascadeChanged, changes)
if err != nil {
@@ -215,12 +216,12 @@ func ProjectRoleRemovedAggregate(ctx context.Context, aggCreator *es_models.Aggr
return agg, nil
}
func ApplicationAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
func ApplicationAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if app == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-09du7", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -232,17 +233,17 @@ func ApplicationAddedAggregate(aggCreator *es_models.AggregateCreator, existing
}
}
func ApplicationChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
func ApplicationChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if app == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sleo9", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
var changes map[string]interface{}
for _, a := range existing.Applications {
for _, a := range existingProject.Applications {
if a.AppID == app.AppID {
changes = a.Changes(app)
}
@@ -253,12 +254,12 @@ func ApplicationChangedAggregate(aggCreator *es_models.AggregateCreator, existin
}
}
func ApplicationRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
func ApplicationRemovedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if app == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-se23g", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -268,12 +269,12 @@ func ApplicationRemovedAggregate(aggCreator *es_models.AggregateCreator, existin
}
}
func ApplicationDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
func ApplicationDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if app == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slfi3", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -283,12 +284,12 @@ func ApplicationDeactivatedAggregate(aggCreator *es_models.AggregateCreator, exi
}
}
func ApplicationReactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
func ApplicationReactivatedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if app == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -298,17 +299,17 @@ func ApplicationReactivatedAggregate(aggCreator *es_models.AggregateCreator, exi
}
}
func OIDCConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, config *model.OIDCConfig) func(ctx context.Context) (*es_models.Aggregate, error) {
func OIDCConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, config *model.OIDCConfig) 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 := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
var changes map[string]interface{}
for _, a := range existing.Applications {
for _, a := range existingProject.Applications {
if a.AppID == config.AppID {
if a.OIDCConfig != nil {
changes = a.OIDCConfig.Changes(config)
@@ -321,9 +322,9 @@ func OIDCConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing
}
}
func OIDCConfigSecretChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, appID string, secret *crypto.CryptoValue) func(ctx context.Context) (*es_models.Aggregate, error) {
func OIDCConfigSecretChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, appID string, secret *crypto.CryptoValue) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -337,9 +338,9 @@ func OIDCConfigSecretChangedAggregate(aggCreator *es_models.AggregateCreator, ex
}
}
func OIDCClientSecretCheckSucceededAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, appID string) es_sdk.AggregateFunc {
func OIDCClientSecretCheckSucceededAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, appID string) es_sdk.AggregateFunc {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -352,9 +353,9 @@ func OIDCClientSecretCheckSucceededAggregate(aggCreator *es_models.AggregateCrea
}
}
func OIDCClientSecretCheckFailedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, appID string) es_sdk.AggregateFunc {
func OIDCClientSecretCheckFailedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, appID string) es_sdk.AggregateFunc {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -367,12 +368,12 @@ func OIDCClientSecretCheckFailedAggregate(aggCreator *es_models.AggregateCreator
}
}
func ProjectGrantAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectGrantAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if grant == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kd89w", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -386,17 +387,17 @@ func ProjectGrantAddedAggregate(aggCreator *es_models.AggregateCreator, existing
}
}
func ProjectGrantChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectGrantChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if grant == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d9ie2", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
var changes map[string]interface{}
for _, g := range existing.Grants {
for _, g := range existingProject.Grants {
if g.GrantID == grant.GrantID {
changes = g.Changes(grant)
}
@@ -407,12 +408,12 @@ func ProjectGrantChangedAggregate(aggCreator *es_models.AggregateCreator, existi
}
}
func ProjectGrantRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectGrantRemovedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if grant == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kci8d", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -422,12 +423,12 @@ func ProjectGrantRemovedAggregate(aggCreator *es_models.AggregateCreator, existi
}
}
func ProjectGrantDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectGrantDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if grant == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-id832", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -437,12 +438,12 @@ func ProjectGrantDeactivatedAggregate(aggCreator *es_models.AggregateCreator, ex
}
}
func ProjectGrantReactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectGrantReactivatedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if grant == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-8diw2", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -450,12 +451,12 @@ func ProjectGrantReactivatedAggregate(aggCreator *es_models.AggregateCreator, ex
}
}
func ProjectGrantMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, member *model.ProjectGrantMember) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectGrantMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectGrantMember) 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-4ufh6", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -468,13 +469,13 @@ func ProjectGrantMemberAddedAggregate(aggCreator *es_models.AggregateCreator, ex
}
}
func ProjectGrantMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, member *model.ProjectGrantMember) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectGrantMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectGrantMember) 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-d8i4h", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -487,12 +488,12 @@ func ProjectGrantMemberChangedAggregate(aggCreator *es_models.AggregateCreator,
}
}
func ProjectGrantMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Project, member *model.ProjectGrantMember) func(ctx context.Context) (*es_models.Aggregate, error) {
func ProjectGrantMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectGrantMember) 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-slp0r", "Errors.Internal")
}
agg, err := ProjectAggregate(ctx, aggCreator, existing)
agg, err := ProjectAggregate(ctx, aggCreator, existingProject)
if err != nil {
return nil, err
}
@@ -570,7 +571,7 @@ func checkExistsUser(events ...*es_models.Event) error {
switch event.AggregateType {
case usr_model.UserAggregate:
switch event.Type {
case usr_model.UserAdded, usr_model.UserRegistered:
case usr_model.UserAdded, usr_model.UserRegistered, usr_model.HumanRegistered, usr_model.MachineAdded, usr_model.HumanAdded:
existsUser = true
case usr_model.UserRemoved:
existsUser = false

File diff suppressed because it is too large Load Diff

View File

@@ -38,23 +38,6 @@ type ProjectGrantMemberView struct {
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
}
func ProjectGrantMemberViewFromModel(member *model.ProjectGrantMemberView) *ProjectGrantMemberView {
return &ProjectGrantMemberView{
UserID: member.UserID,
GrantID: member.GrantID,
ProjectID: member.ProjectID,
UserName: member.UserName,
Email: member.Email,
FirstName: member.FirstName,
LastName: member.LastName,
DisplayName: member.DisplayName,
Roles: member.Roles,
Sequence: member.Sequence,
CreationDate: member.CreationDate,
ChangeDate: member.ChangeDate,
}
}
func ProjectGrantMemberToModel(member *ProjectGrantMemberView) *model.ProjectGrantMemberView {
return &model.ProjectGrantMemberView{
UserID: member.UserID,

View File

@@ -2,13 +2,14 @@ package model
import (
"encoding/json"
"time"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/project/model"
es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
"github.com/lib/pq"
"time"
)
const (
@@ -35,22 +36,6 @@ type ProjectMemberView struct {
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
}
func ProjectMemberViewFromModel(member *model.ProjectMemberView) *ProjectMemberView {
return &ProjectMemberView{
UserID: member.UserID,
ProjectID: member.ProjectID,
UserName: member.UserName,
Email: member.Email,
FirstName: member.FirstName,
LastName: member.LastName,
DisplayName: member.DisplayName,
Roles: member.Roles,
Sequence: member.Sequence,
CreationDate: member.CreationDate,
ChangeDate: member.ChangeDate,
}
}
func ProjectMemberToModel(member *ProjectMemberView) *model.ProjectMemberView {
return &model.ProjectMemberView{
UserID: member.UserID,

View File

@@ -26,7 +26,7 @@ var templateFuncs = map[string]interface{}{
}
func RegisterTmplFunc(name string, f interface{}) {
if _, existing := templateFuncs[name]; existing {
if _, found := templateFuncs[name]; found {
panic(fmt.Sprintf("func with name %v is already registered", name))
}

View File

@@ -320,17 +320,19 @@ func (setUp *initializer) users(ctx context.Context, users []User, orgPolicy *or
func (setUp *initializer) user(ctx context.Context, user User, orgPolicy *org_model.OrgIAMPolicy) (*usr_model.User, error) {
createUser := &usr_model.User{
Profile: &usr_model.Profile{
UserName: user.UserName,
FirstName: user.FirstName,
LastName: user.LastName,
},
Email: &usr_model.Email{
EmailAddress: user.Email,
IsEmailVerified: true,
},
Password: &usr_model.Password{
SecretString: user.Password,
UserName: user.UserName,
Human: &usr_model.Human{
Profile: &usr_model.Profile{
FirstName: user.FirstName,
LastName: user.LastName,
},
Email: &usr_model.Email{
EmailAddress: user.Email,
IsEmailVerified: true,
},
Password: &usr_model.Password{
SecretString: user.Password,
},
},
}
return setUp.UserEvents.CreateUser(ctx, createUser, setUp.pwComplexityPolicy, orgPolicy)

View File

@@ -24,6 +24,8 @@ Errors:
PhoneInvalid: Telefonnummer ist ungültig
PhoneAlreadyVerified: Telefonnummer bereits verifiziert
AddressNotFound: Addresse nicht gefunden
NotHuman: Der Benutzer muss eine Person sein
NotMachine: Der Benutzer muss technisch sein
Code:
Empty: Code ist leer
NotFound: Code konnte nicht gefunden werden
@@ -144,6 +146,8 @@ Errors:
NotFound: Token konnte nicht gefunden werden
UserSession:
NotFound: Benutzer Sitzung konnte nicht gefunden werden
Key:
ExpireBeforeNow: Das Ablaufdatum liegt in der Vergangenheit
EventTypes:
user:
added: Benutzer hinzugefügt
@@ -168,6 +172,66 @@ EventTypes:
code:
added: E-Mail Code generiert
sent: E-Mail Code gesendet
machine:
machine:
added: Technischer Benutzer hinzugefügt
changed: Technischer Benutzer geändert
key:
added: Key added
removed: Key removed
human:
added: Benutzer hinzugefügt
selfregistered: Benutzer hat sich selbst registriert
initialization:
code:
added: Initialisierungscode generiert
sent: Initialiseriungscode versendet
check:
succeeded: Benutzerinitialisierung erfolgreich
failed: Benutzerinitialisierung fehlgeschlagen
username:
reserved: Benutzername reserviert
released: Benutzername freigegeben
email:
changed: E-Mail-Adresse geändert
verified: E-Mail-Adresse verifiziert
verification:
failed: Verifikation der E-Mail-Adresse fehlgeschlagen
code:
added: E-Mail Code generiert
sent: E-Mail Code gesendet
password:
changed: Passwort geändert
code:
added: Passwort Code generiert
sent: Passwort Code versendet
check:
succeeded: Passwortvalidierung erfolgreich
failed: Passwortvalidierung fehlgeschlagen
phone:
changed: Telefonnummer geändert
verified: Telefonnummer verifiziert
verification:
failed: Verifikation der Telefonnummer fehlgeschlagen
code:
added: Telefon Code hinzugefügt
sent: Telefon Code versendet
profile:
changed: Benutzerprofil geändert
address:
changed: Adresse des Benutzers geändert
mfa:
otp:
added: Multifaktor OTP hinzugefügt
verified: Multifaktor OTP verifiziert
removed: Multifaktor OTP entfernt
check:
succeeded: Multifaktor OTP Verifikation erfolgreich
failed: Multifaktor OTP Verifikation fehlgeschlagen
init:
skipped: Multifaktor Initialisierung übersprungen
signed:
out: Benutzer erfolgreich abgemeldet
locked: Benutzer gesperrt
unlocked: Benutzer entsperrt
deactivated: Benutzer deaktiviert

View File

@@ -24,6 +24,8 @@ Errors:
PhoneInvalid: Phone is invalid
PhoneAlreadyVerified: Phone already verified
AddressNotFound: Address not found
NotHuman: The User must be personal
NotMachine: The User must be technical
Code:
Empty: Code is empty
NotFound: Code not found
@@ -144,6 +146,8 @@ Errors:
NotFound: Token not found
UserSession:
NotFound: UserSession not found
Key:
ExpireBeforeNow: The expiration date is in the past
EventTypes:
user:
added: User added
@@ -168,6 +172,66 @@ EventTypes:
code:
added: Email address verification code generated
sent: Email address verification code sent
machine:
machine:
added: Technical user added
changed: Technical user changed
key:
added: Key added
removed: Key removed
human:
added: Person added
selfregistered: Person registered himself
initialization:
code:
added: Initialisation code generated
sent: Initialisation code sent
check:
succeeded: Initialisation check succeded
failed: Initialisation check failed
username:
reserved: Username reserved
released: Username released
email:
changed: Email address changed
verified: Email address verified
verification:
failed: Email address verification failed
code:
added: Email address verification code generated
sent: Email address verification code sent
password:
changed: Password changed
code:
added: Password code generated
sent: Password code sent
check:
succeeded: Password check succeeded
failed: Password check failed
phone:
changed: Phone number changed
verified: Phone number verified
verification:
failed: Phone number verification failed
code:
added: Phone number code generated
sent: Phone number code sent
profile:
changed: User profile changed
address:
changed: User address changed
mfa:
otp:
added: Multifactor OTP added
verified: Multifactor OTP verified
removed: Multifactor OTP removed
check:
succeeded: Multifactor OTP check succeeded
failed: Multifactor OTP check failed
init:
skipped: Multifactor initialisation skipped
signed:
out: User signed out
locked: User locked
unlocked: User unlocked
deactivated: User deactivated

View File

@@ -139,17 +139,19 @@ func (l *Login) renderRegister(w http.ResponseWriter, r *http.Request, authReque
func (d registerFormData) toUserModel() *usr_model.User {
return &usr_model.User{
Profile: &usr_model.Profile{
FirstName: d.Firstname,
LastName: d.Lastname,
PreferredLanguage: language.Make(d.Language),
Gender: usr_model.Gender(d.Gender),
},
Password: &usr_model.Password{
SecretString: d.Password,
},
Email: &usr_model.Email{
EmailAddress: d.Email,
Human: &usr_model.Human{
Profile: &usr_model.Profile{
FirstName: d.Firstname,
LastName: d.Lastname,
PreferredLanguage: language.Make(d.Language),
Gender: usr_model.Gender(d.Gender),
},
Password: &usr_model.Password{
SecretString: d.Password,
},
Email: &usr_model.Email{
EmailAddress: d.Email,
},
},
}
}

View File

@@ -1,9 +1,10 @@
package handler
import (
auth_model "github.com/caos/zitadel/internal/auth/model"
"net/http"
auth_model "github.com/caos/zitadel/internal/auth/model"
"github.com/caos/zitadel/internal/auth_request/model"
caos_errs "github.com/caos/zitadel/internal/errors"
org_model "github.com/caos/zitadel/internal/org/model"
@@ -122,22 +123,24 @@ func (d registerOrgFormData) toUserModel() *usr_model.User {
d.Username = d.Email
}
return &usr_model.User{
Profile: &usr_model.Profile{
UserName: d.Username,
FirstName: d.Firstname,
LastName: d.Lastname,
},
Password: &usr_model.Password{
SecretString: d.Password,
},
Email: &usr_model.Email{
EmailAddress: d.Email,
UserName: d.Username,
Human: &usr_model.Human{
Profile: &usr_model.Profile{
FirstName: d.Firstname,
LastName: d.Lastname,
},
Password: &usr_model.Password{
SecretString: d.Password,
},
Email: &usr_model.Email{
EmailAddress: d.Email,
},
},
}
}
func (d registerOrgFormData) toOrgModel() *org_model.Org {
return &org_model.Org{
Name: d.OrgName,
Name: d.OrgName,
}
}

View File

@@ -0,0 +1,53 @@
package model
import (
"time"
"github.com/caos/zitadel/internal/model"
)
type MachineKeyView struct {
ID string
UserID string
Type MachineKeyType
Sequence uint64
CreationDate time.Time
ExpirationDate time.Time
}
type MachineKeySearchRequest struct {
Offset uint64
Limit uint64
SortingColumn MachineKeySearchKey
Asc bool
Queries []*MachineKeySearchQuery
}
type MachineKeySearchKey int32
const (
MachineKeyKeyUnspecified MachineKeySearchKey = iota
MachineKeyKeyID
MachineKeyKeyUserID
)
type MachineKeySearchQuery struct {
Key MachineKeySearchKey
Method model.SearchMethod
Value interface{}
}
type MachineKeySearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*MachineKeyView
Sequence uint64
Timestamp time.Time
}
func (r *MachineKeySearchRequest) EnsureLimit(limit uint64) {
if r.Limit == 0 || r.Limit > limit {
r.Limit = limit
}
}

View File

@@ -8,7 +8,6 @@ import (
type Profile struct {
es_models.ObjectRoot
UserName string
FirstName string
LastName string
NickName string

View File

@@ -1,51 +1,21 @@
package model
import (
caos_errors "github.com/caos/zitadel/internal/errors"
org_model "github.com/caos/zitadel/internal/org/model"
policy_model "github.com/caos/zitadel/internal/policy/model"
"github.com/golang/protobuf/ptypes/timestamp"
"strings"
"time"
"github.com/caos/zitadel/internal/crypto"
caos_errors "github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
org_model "github.com/caos/zitadel/internal/org/model"
"github.com/golang/protobuf/ptypes/timestamp"
)
type User struct {
es_models.ObjectRoot
State UserState
UserName string
State UserState
*Password
*Profile
*Email
*Phone
*Address
InitCode *InitUserCode
EmailCode *EmailCode
PhoneCode *PhoneCode
PasswordCode *PasswordCode
OTP *OTP
}
type UserChanges struct {
Changes []*UserChange
LastSequence uint64
}
type UserChange struct {
ChangeDate *timestamp.Timestamp `json:"changeDate,omitempty"`
EventType string `json:"eventType,omitempty"`
Sequence uint64 `json:"sequence,omitempty"`
ModifierId string `json:"modifierUser,omitempty"`
ModifierName string `json:"-"`
Data interface{} `json:"data,omitempty"`
}
type InitUserCode struct {
es_models.ObjectRoot
Code *crypto.CryptoValue
Expiry time.Duration
*Human
*Machine
}
type UserState int32
@@ -60,15 +30,6 @@ const (
UserStateInitial
)
type Gender int32
const (
GenderUnspecified Gender = iota
GenderFemale
GenderMale
GenderDiverse
)
func (u *User) CheckOrgIAMPolicy(policy *org_model.OrgIAMPolicy) error {
if policy == nil {
return caos_errors.ThrowPreconditionFailed(nil, "MODEL-zSH7j", "Errors.Users.OrgIamPolicyNil")
@@ -88,12 +49,18 @@ func (u *User) SetNamesAsDisplayname() {
}
}
func (u *User) IsValid() bool {
return u.Profile != nil && u.FirstName != "" && u.LastName != "" && u.UserName != "" && u.Email != nil && u.Email.IsValid() && u.Phone == nil || (u.Phone != nil && u.Phone.IsValid())
type UserChanges struct {
Changes []*UserChange
LastSequence uint64
}
func (u *User) IsInitialState() bool {
return u.Email == nil || !u.IsEmailVerified || u.Password == nil || u.SecretString == ""
type UserChange struct {
ChangeDate *timestamp.Timestamp `json:"changeDate,omitempty"`
EventType string `json:"eventType,omitempty"`
Sequence uint64 `json:"sequence,omitempty"`
ModifierID string `json:"modifierUser,omitempty"`
ModifierName string `json:"-"`
Data interface{} `json:"data,omitempty"`
}
func (u *User) IsActive() bool {
@@ -112,47 +79,25 @@ func (u *User) IsLocked() bool {
return u.State == UserStateLocked
}
func (u *User) IsOTPReady() bool {
return u.OTP != nil && u.OTP.State == MfaStateReady
func (u *User) IsValid() bool {
if u.Human == nil && u.Machine == nil || u.UserName == "" {
return false
}
if u.Human != nil {
return u.Human.IsValid()
}
return u.Machine.IsValid()
}
func (u *User) HashPasswordIfExisting(policy *policy_model.PasswordComplexityPolicy, passwordAlg crypto.HashAlgorithm, onetime bool) error {
if u.Password != nil {
return u.Password.HashPasswordIfExisting(policy, passwordAlg, onetime)
func (u *User) CheckOrgIamPolicy(policy *org_model.OrgIAMPolicy) error {
if policy == nil {
return caos_errors.ThrowPreconditionFailed(nil, "MODEL-zSH7j", "Errors.Users.OrgIamPolicyNil")
}
if policy.UserLoginMustBeDomain && strings.Contains(u.UserName, "@") {
return caos_errors.ThrowPreconditionFailed(nil, "MODEL-se4sJ", "Errors.User.EmailAsUsernameNotAllowed")
}
if !policy.UserLoginMustBeDomain && u.Profile != nil && u.UserName == "" && u.Email != nil {
u.UserName = u.EmailAddress
}
return nil
}
func (u *User) GenerateInitCodeIfNeeded(initGenerator crypto.Generator) error {
if !u.IsInitialState() {
return nil
}
u.InitCode = new(InitUserCode)
return u.InitCode.GenerateInitUserCode(initGenerator)
}
func (u *User) GeneratePhoneCodeIfNeeded(phoneGenerator crypto.Generator) error {
if u.Phone == nil || u.IsPhoneVerified {
return nil
}
u.PhoneCode = new(PhoneCode)
return u.PhoneCode.GeneratePhoneCode(phoneGenerator)
}
func (u *User) GenerateEmailCodeIfNeeded(emailGenerator crypto.Generator) error {
if u.Email == nil || u.IsEmailVerified {
return nil
}
u.EmailCode = new(EmailCode)
return u.EmailCode.GenerateEmailCode(emailGenerator)
}
func (init *InitUserCode) GenerateInitUserCode(generator crypto.Generator) error {
initCodeCrypto, _, err := crypto.NewCode(generator)
if err != nil {
return err
}
init.Code = initCodeCrypto
init.Expiry = generator.Expiry()
return nil
}

View File

@@ -0,0 +1,98 @@
package model
import (
"time"
policy_model "github.com/caos/zitadel/internal/policy/model"
"github.com/caos/zitadel/internal/crypto"
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
type Human struct {
*Password
*Profile
*Email
*Phone
*Address
InitCode *InitUserCode
EmailCode *EmailCode
PhoneCode *PhoneCode
PasswordCode *PasswordCode
OTP *OTP
}
type InitUserCode struct {
es_models.ObjectRoot
Code *crypto.CryptoValue
Expiry time.Duration
}
type Gender int32
const (
GenderUnspecified Gender = iota
GenderFemale
GenderMale
GenderDiverse
)
func (u *Human) SetNamesAsDisplayname() {
if u.Profile != nil && u.DisplayName == "" && u.FirstName != "" && u.LastName != "" {
u.DisplayName = u.FirstName + " " + u.LastName
}
}
func (u *Human) IsValid() bool {
return u.Profile != nil && u.FirstName != "" && u.LastName != "" && u.Email != nil && u.Email.IsValid() && u.Phone == nil || (u.Phone != nil && u.Phone.IsValid())
}
func (u *Human) IsInitialState() bool {
return u.Email == nil || !u.IsEmailVerified || u.Password == nil || u.SecretString == ""
}
func (u *Human) IsOTPReady() bool {
return u.OTP != nil && u.OTP.State == MfaStateReady
}
func (u *Human) HashPasswordIfExisting(policy *policy_model.PasswordComplexityPolicy, passwordAlg crypto.HashAlgorithm, onetime bool) error {
if u.Password != nil {
return u.Password.HashPasswordIfExisting(policy, passwordAlg, onetime)
}
return nil
}
func (u *Human) GenerateInitCodeIfNeeded(initGenerator crypto.Generator) error {
if !u.IsInitialState() {
return nil
}
u.InitCode = new(InitUserCode)
return u.InitCode.GenerateInitUserCode(initGenerator)
}
func (u *Human) GeneratePhoneCodeIfNeeded(phoneGenerator crypto.Generator) error {
if u.Phone == nil || u.IsPhoneVerified {
return nil
}
u.PhoneCode = new(PhoneCode)
return u.PhoneCode.GeneratePhoneCode(phoneGenerator)
}
func (u *Human) GenerateEmailCodeIfNeeded(emailGenerator crypto.Generator) error {
if u.Email == nil || u.IsEmailVerified {
return nil
}
u.EmailCode = new(EmailCode)
return u.EmailCode.GenerateEmailCode(emailGenerator)
}
func (init *InitUserCode) GenerateInitUserCode(generator crypto.Generator) error {
initCodeCrypto, _, err := crypto.NewCode(generator)
if err != nil {
return err
}
init.Code = initCodeCrypto
init.Expiry = generator.Expiry()
return nil
}

View File

@@ -6,7 +6,7 @@ import (
func TestIsUserValid(t *testing.T) {
type args struct {
user *User
user *Human
}
tests := []struct {
name string
@@ -17,9 +17,8 @@ func TestIsUserValid(t *testing.T) {
{
name: "user with minimal data",
args: args{
user: &User{
user: &Human{
Profile: &Profile{
UserName: "UserName",
FirstName: "FirstName",
LastName: "LastName",
},
@@ -33,9 +32,8 @@ func TestIsUserValid(t *testing.T) {
{
name: "user with phone data",
args: args{
user: &User{
user: &Human{
Profile: &Profile{
UserName: "UserName",
FirstName: "FirstName",
LastName: "LastName",
},
@@ -52,9 +50,8 @@ func TestIsUserValid(t *testing.T) {
{
name: "user with address data",
args: args{
user: &User{
user: &Human{
Profile: &Profile{
UserName: "UserName",
FirstName: "FirstName",
LastName: "LastName",
},
@@ -74,9 +71,8 @@ func TestIsUserValid(t *testing.T) {
{
name: "user with all data",
args: args{
user: &User{
user: &Human{
Profile: &Profile{
UserName: "UserName",
FirstName: "FirstName",
LastName: "LastName",
},

View File

@@ -0,0 +1,34 @@
package model
import (
"time"
"github.com/caos/zitadel/internal/eventstore/models"
)
type Machine struct {
models.ObjectRoot
Name string
Description string
}
func (sa *Machine) IsValid() bool {
return sa.Name != ""
}
type MachineKey struct {
models.ObjectRoot
KeyID string
Type MachineKeyType
ExpirationDate time.Time
PrivateKey []byte
}
type MachineKeyType int32
const (
MachineKeyTypeNONE = iota
MachineKeyTypeJSON
)

View File

@@ -3,28 +3,33 @@ package model
import (
"time"
"golang.org/x/text/language"
"github.com/caos/zitadel/internal/eventstore/models"
req_model "github.com/caos/zitadel/internal/auth_request/model"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/model"
"golang.org/x/text/language"
)
type UserView struct {
ID string
CreationDate time.Time
ChangeDate time.Time
State UserState
ResourceOwner string
ID string
UserName string
CreationDate time.Time
ChangeDate time.Time
State UserState
Sequence uint64
ResourceOwner string
LastLogin time.Time
PreferredLoginName string
LoginNames []string
*MachineView
*HumanView
}
type HumanView struct {
PasswordSet bool
PasswordChangeRequired bool
UsernameChangeRequired bool
PasswordChanged time.Time
LastLogin time.Time
UserName string
PreferredLoginName string
LoginNames []string
FirstName string
LastName string
NickName string
@@ -44,7 +49,12 @@ type UserView struct {
MfaMaxSetUp req_model.MfaLevel
MfaInitSkipped time.Time
InitRequired bool
Sequence uint64
}
type MachineView struct {
LastKeyAdded time.Time
Name string
Description string
}
type UserSearchRequest struct {
@@ -69,6 +79,7 @@ const (
UserSearchKeyState
UserSearchKeyResourceOwner
UserSearchKeyLoginNames
UserSearchKeyType
)
type UserSearchQuery struct {
@@ -130,7 +141,10 @@ func (u *UserView) MfaTypesAllowed(level req_model.MfaLevel) []req_model.MfaType
return types
}
func (u *UserView) GetProfile() *Profile {
func (u *UserView) GetProfile() (*Profile, error) {
if u.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "MODEL-WLTce", "Errors.User.NotHuman")
}
return &Profile{
ObjectRoot: models.ObjectRoot{
AggregateID: u.ID,
@@ -139,7 +153,6 @@ func (u *UserView) GetProfile() *Profile {
CreationDate: u.CreationDate,
ChangeDate: u.ChangeDate,
},
UserName: u.UserName,
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
@@ -148,10 +161,13 @@ func (u *UserView) GetProfile() *Profile {
Gender: u.Gender,
PreferredLoginName: u.PreferredLoginName,
LoginNames: u.LoginNames,
}
}, nil
}
func (u *UserView) GetPhone() *Phone {
func (u *UserView) GetPhone() (*Phone, error) {
if u.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "MODEL-him4a", "Errors.User.NotHuman")
}
return &Phone{
ObjectRoot: models.ObjectRoot{
AggregateID: u.ID,
@@ -162,10 +178,13 @@ func (u *UserView) GetPhone() *Phone {
},
PhoneNumber: u.Phone,
IsPhoneVerified: u.IsPhoneVerified,
}
}, nil
}
func (u *UserView) GetEmail() *Email {
func (u *UserView) GetEmail() (*Email, error) {
if u.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "MODEL-PWd6K", "Errors.User.NotHuman")
}
return &Email{
ObjectRoot: models.ObjectRoot{
AggregateID: u.ID,
@@ -176,10 +195,13 @@ func (u *UserView) GetEmail() *Email {
},
EmailAddress: u.Email,
IsEmailVerified: u.IsEmailVerified,
}
}, nil
}
func (u *UserView) GetAddress() *Address {
func (u *UserView) GetAddress() (*Address, error) {
if u.HumanView == nil {
return nil, errors.ThrowPreconditionFailed(nil, "MODEL-DN61m", "Errors.User.NotHuman")
}
return &Address{
ObjectRoot: models.ObjectRoot{
AggregateID: u.ID,
@@ -193,5 +215,5 @@ func (u *UserView) GetAddress() *Address {
PostalCode: u.PostalCode,
Region: u.Region,
StreetAddress: u.StreetAddress,
}
}, nil
}

View File

@@ -19,9 +19,9 @@ func StartCache(conf *config.CacheConfig) (*UserCache, error) {
return &UserCache{userCache: userCache}, nil
}
func (c *UserCache) getUser(ID string) *model.User {
user := &model.User{ObjectRoot: models.ObjectRoot{AggregateID: ID}}
if err := c.userCache.Get(ID, user); err != nil {
func (c *UserCache) getUser(id string) *model.User {
user := &model.User{ObjectRoot: models.ObjectRoot{AggregateID: id}}
if err := c.userCache.Get(id, user); err != nil {
logging.Log("EVENT-AtS0S").WithError(err).Debug("error in getting cache")
}
return user

File diff suppressed because it is too large Load Diff

View File

@@ -69,7 +69,7 @@ func GetMockPwGenerator(ctrl *gomock.Controller) crypto.Generator {
func GetMockUserByIDOK(ctrl *gomock.Controller, user model.User) *UserEventstore {
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -85,13 +85,16 @@ func GetMockUserByIDNoEvents(ctrl *gomock.Controller) *UserEventstore {
func GetMockManipulateUser(ctrl *gomock.Controller) *UserEventstore {
user := model.User{
Profile: &model.Profile{
UserName: "UserName",
UserName: "UserName",
Human: &model.Human{
Profile: &model.Profile{
DisplayName: "DisplayName",
},
},
}
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -101,9 +104,9 @@ func GetMockManipulateUser(ctrl *gomock.Controller) *UserEventstore {
}
func GetMockManipulateUserWithPWGenerator(ctrl *gomock.Controller, init, email, phone, password bool) *UserEventstore {
user := model.User{
user := model.Human{
Profile: &model.Profile{
UserName: "UserName",
DisplayName: "DisplayName",
},
Email: &model.Email{
EmailAddress: "EmailAddress",
@@ -114,7 +117,7 @@ func GetMockManipulateUserWithPWGenerator(ctrl *gomock.Controller, init, email,
}
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -126,7 +129,7 @@ func GetMockManipulateUserWithPWGenerator(ctrl *gomock.Controller, init, email,
func GetMockManipulateUserWithInitCodeGen(ctrl *gomock.Controller, user model.User) *UserEventstore {
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -138,7 +141,7 @@ func GetMockManipulateUserWithInitCodeGen(ctrl *gomock.Controller, user model.Us
func GetMockManipulateUserWithPasswordInitCodeGen(ctrl *gomock.Controller, user model.User) *UserEventstore {
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
&es_models.Event{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -150,7 +153,7 @@ func GetMockManipulateUserWithPasswordInitCodeGen(ctrl *gomock.Controller, user
func GetMockManipulateUserWithPasswordAndEmailCodeGen(ctrl *gomock.Controller, user model.User) *UserEventstore {
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -162,7 +165,7 @@ func GetMockManipulateUserWithPasswordAndEmailCodeGen(ctrl *gomock.Controller, u
func GetMockManipulateUserWithEmailCodeGen(ctrl *gomock.Controller, user model.User) *UserEventstore {
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -174,7 +177,7 @@ func GetMockManipulateUserWithEmailCodeGen(ctrl *gomock.Controller, user model.U
func GetMockManipulateUserWithPhoneCodeGen(ctrl *gomock.Controller, user model.User) *UserEventstore {
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -187,8 +190,8 @@ func GetMockManipulateUserWithPasswordCodeGen(ctrl *gomock.Controller, user mode
data, _ := json.Marshal(user)
code, _ := json.Marshal(user.PasswordCode)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserPasswordCodeAdded, Data: code},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserPasswordCodeAdded, Data: code},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -199,13 +202,16 @@ func GetMockManipulateUserWithPasswordCodeGen(ctrl *gomock.Controller, user mode
func GetMockManipulateUserWithOTPGen(ctrl *gomock.Controller) *UserEventstore {
user := model.User{
Profile: &model.Profile{
UserName: "UserName",
UserName: "UserName",
Human: &model.Human{
Profile: &model.Profile{
DisplayName: "DisplayName",
},
},
}
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -224,15 +230,15 @@ func GetMockManipulateUserWithOTPGen(ctrl *gomock.Controller) *UserEventstore {
}
func GetMockManipulateInactiveUser(ctrl *gomock.Controller) *UserEventstore {
user := model.User{
user := model.Human{
Profile: &model.Profile{
UserName: "UserName",
DisplayName: "DisplayName",
},
}
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
&es_models.Event{AggregateID: "AggregateID", Sequence: 2, Type: model.UserDeactivated},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 2, Type: model.UserDeactivated},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -242,15 +248,15 @@ func GetMockManipulateInactiveUser(ctrl *gomock.Controller) *UserEventstore {
}
func GetMockManipulateLockedUser(ctrl *gomock.Controller) *UserEventstore {
user := model.User{
user := model.Human{
Profile: &model.Profile{
UserName: "UserName",
DisplayName: "DisplayName",
},
}
data, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: data},
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserLocked},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserLocked},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -269,8 +275,8 @@ func GetMockManipulateUserWithInitCode(ctrl *gomock.Controller, user model.User)
dataUser, _ := json.Marshal(user)
dataCode, _ := json.Marshal(code)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: dataUser},
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.InitializedUserCodeAdded, Data: dataCode},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.InitializedUserCodeAdded, Data: dataCode},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -280,9 +286,9 @@ func GetMockManipulateUserWithInitCode(ctrl *gomock.Controller, user model.User)
}
func GetMockManipulateUserWithEmailCode(ctrl *gomock.Controller) *UserEventstore {
user := model.User{
user := model.Human{
Profile: &model.Profile{
UserName: "UserName",
DisplayName: "DisplayName",
},
Email: &model.Email{
EmailAddress: "EmailAddress",
@@ -297,8 +303,8 @@ func GetMockManipulateUserWithEmailCode(ctrl *gomock.Controller) *UserEventstore
dataUser, _ := json.Marshal(user)
dataCode, _ := json.Marshal(code)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: dataUser},
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserEmailCodeAdded, Data: dataCode},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserEmailCodeAdded, Data: dataCode},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -307,9 +313,9 @@ func GetMockManipulateUserWithEmailCode(ctrl *gomock.Controller) *UserEventstore
return GetMockedEventstoreWithPw(ctrl, mockEs, false, true, false, false)
}
func GetMockManipulateUserVerifiedEmail(ctrl *gomock.Controller) *UserEventstore {
user := model.User{
user := model.Human{
Profile: &model.Profile{
UserName: "UserName",
DisplayName: "DisplayName",
},
Email: &model.Email{
EmailAddress: "EmailAddress",
@@ -317,8 +323,8 @@ func GetMockManipulateUserVerifiedEmail(ctrl *gomock.Controller) *UserEventstore
}
dataUser, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: dataUser},
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserEmailVerified},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserEmailVerified},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -328,9 +334,9 @@ func GetMockManipulateUserVerifiedEmail(ctrl *gomock.Controller) *UserEventstore
}
func GetMockManipulateUserWithPhoneCode(ctrl *gomock.Controller) *UserEventstore {
user := model.User{
user := model.Human{
Profile: &model.Profile{
UserName: "UserName",
DisplayName: "DisplayName",
},
Phone: &model.Phone{
PhoneNumber: "PhoneNumber",
@@ -345,8 +351,8 @@ func GetMockManipulateUserWithPhoneCode(ctrl *gomock.Controller) *UserEventstore
dataUser, _ := json.Marshal(user)
dataCode, _ := json.Marshal(code)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: dataUser},
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserPhoneCodeAdded, Data: dataCode},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserPhoneCodeAdded, Data: dataCode},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -356,9 +362,9 @@ func GetMockManipulateUserWithPhoneCode(ctrl *gomock.Controller) *UserEventstore
}
func GetMockManipulateUserVerifiedPhone(ctrl *gomock.Controller) *UserEventstore {
user := model.User{
user := model.Human{
Profile: &model.Profile{
UserName: "UserName",
DisplayName: "DisplayName",
},
Phone: &model.Phone{
PhoneNumber: "PhoneNumber",
@@ -366,8 +372,8 @@ func GetMockManipulateUserVerifiedPhone(ctrl *gomock.Controller) *UserEventstore
}
dataUser, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: dataUser},
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserPhoneVerified},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserPhoneVerified},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -377,11 +383,11 @@ func GetMockManipulateUserVerifiedPhone(ctrl *gomock.Controller) *UserEventstore
}
func GetMockManipulateUserFull(ctrl *gomock.Controller) *UserEventstore {
user := model.User{
user := model.Human{
Profile: &model.Profile{
UserName: "UserName",
FirstName: "FirstName",
LastName: "LastName",
DisplayName: "DisplayName",
FirstName: "FirstName",
LastName: "LastName",
},
Password: &model.Password{
Secret: &crypto.CryptoValue{Algorithm: "bcrypt", KeyID: "KeyID"},
@@ -399,7 +405,7 @@ func GetMockManipulateUserFull(ctrl *gomock.Controller) *UserEventstore {
}
dataUser, _ := json.Marshal(user)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: dataUser},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -409,9 +415,9 @@ func GetMockManipulateUserFull(ctrl *gomock.Controller) *UserEventstore {
}
func GetMockManipulateUserWithOTP(ctrl *gomock.Controller, decrypt, verified bool) *UserEventstore {
user := model.User{
user := model.Human{
Profile: &model.Profile{
UserName: "UserName",
DisplayName: "DisplayName",
},
}
otp := model.OTP{
@@ -425,11 +431,11 @@ func GetMockManipulateUserWithOTP(ctrl *gomock.Controller, decrypt, verified boo
dataUser, _ := json.Marshal(user)
dataOtp, _ := json.Marshal(otp)
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserAdded, Data: dataUser},
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MfaOtpAdded, Data: dataOtp},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.MFAOTPAdded, Data: dataOtp},
}
if verified {
events = append(events, &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MfaOtpVerified})
events = append(events, &es_models.Event{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.MFAOTPVerified})
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
@@ -478,16 +484,16 @@ func GetMockedEventstoreComplexity(ctrl *gomock.Controller, mockEs *mock.MockEve
func GetMockChangesUserOK(ctrl *gomock.Controller) *UserEventstore {
user := model.Profile{
FirstName: "Hans",
LastName: "Muster",
UserName: "HansMuster",
FirstName: "Hans",
LastName: "Muster",
DisplayName: "DisplayName",
}
data, err := json.Marshal(user)
if err != nil {
}
events := []*es_models.Event{
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, AggregateType: model.UserAggregate, Data: data},
{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, AggregateType: model.UserAggregate, Data: data},
}
mockEs := mock.NewMockEventstore(ctrl)
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@ package model
import (
"encoding/json"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
@@ -60,7 +61,7 @@ func AddressToModel(address *Address) *model.Address {
}
}
func (u *User) appendUserAddressChangedEvent(event *es_models.Event) error {
func (u *Human) appendUserAddressChangedEvent(event *es_models.Event) error {
if u.Address == nil {
u.Address = new(Address)
}

View File

@@ -2,14 +2,15 @@ package model
import (
"encoding/json"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"testing"
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
func TestAddressChanges(t *testing.T) {
type args struct {
existing *Address
new *Address
existingAddress *Address
newAddress *Address
}
type res struct {
changesLen int
@@ -22,8 +23,8 @@ func TestAddressChanges(t *testing.T) {
{
name: "all fields changed",
args: args{
existing: &Address{Country: "Country", Locality: "Locality", PostalCode: "PostalCode", Region: "Region", StreetAddress: "StreetAddress"},
new: &Address{Country: "CountryChanged", Locality: "LocalityChanged", PostalCode: "PostalCodeChanged", Region: "RegionChanged", StreetAddress: "StreetAddressChanged"},
existingAddress: &Address{Country: "Country", Locality: "Locality", PostalCode: "PostalCode", Region: "Region", StreetAddress: "StreetAddress"},
newAddress: &Address{Country: "CountryChanged", Locality: "LocalityChanged", PostalCode: "PostalCodeChanged", Region: "RegionChanged", StreetAddress: "StreetAddressChanged"},
},
res: res{
changesLen: 5,
@@ -32,8 +33,8 @@ func TestAddressChanges(t *testing.T) {
{
name: "no fields changed",
args: args{
existing: &Address{Country: "Country", Locality: "Locality", PostalCode: "PostalCode", Region: "Region", StreetAddress: "StreetAddress"},
new: &Address{Country: "Country", Locality: "Locality", PostalCode: "PostalCode", Region: "Region", StreetAddress: "StreetAddress"},
existingAddress: &Address{Country: "Country", Locality: "Locality", PostalCode: "PostalCode", Region: "Region", StreetAddress: "StreetAddress"},
newAddress: &Address{Country: "Country", Locality: "Locality", PostalCode: "PostalCode", Region: "Region", StreetAddress: "StreetAddress"},
},
res: res{
changesLen: 0,
@@ -42,7 +43,7 @@ func TestAddressChanges(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
changes := tt.args.existing.Changes(tt.args.new)
changes := tt.args.existingAddress.Changes(tt.args.newAddress)
if len(changes) != tt.res.changesLen {
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
}
@@ -52,23 +53,23 @@ func TestAddressChanges(t *testing.T) {
func TestAppendUserAddressChangedEvent(t *testing.T) {
type args struct {
user *User
user *Human
address *Address
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append user address event",
args: args{
user: &User{Address: &Address{Locality: "Locality", Country: "Country"}},
user: &Human{Address: &Address{Locality: "Locality", Country: "Country"}},
address: &Address{Locality: "LocalityChanged", PostalCode: "PostalCode"},
event: &es_models.Event{},
},
result: &User{Address: &Address{Locality: "LocalityChanged", Country: "Country", PostalCode: "PostalCode"}},
result: &Human{Address: &Address{Locality: "LocalityChanged", Country: "Country", PostalCode: "PostalCode"}},
},
}
for _, tt := range tests {

View File

@@ -2,12 +2,13 @@ package model
import (
"encoding/json"
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/crypto"
caos_errs "github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/user/model"
"time"
)
type Email struct {
@@ -69,17 +70,17 @@ func EmailCodeToModel(code *EmailCode) *model.EmailCode {
}
}
func (u *User) appendUserEmailChangedEvent(event *es_models.Event) error {
func (u *Human) appendUserEmailChangedEvent(event *es_models.Event) error {
u.Email = new(Email)
return u.Email.setData(event)
}
func (u *User) appendUserEmailCodeAddedEvent(event *es_models.Event) error {
func (u *Human) appendUserEmailCodeAddedEvent(event *es_models.Event) error {
u.EmailCode = new(EmailCode)
return u.EmailCode.SetData(event)
}
func (u *User) appendUserEmailVerifiedEvent() {
func (u *Human) appendUserEmailVerifiedEvent() {
u.IsEmailVerified = true
}

View File

@@ -2,15 +2,16 @@ package model
import (
"encoding/json"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"testing"
"time"
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
func TestEmailChanges(t *testing.T) {
type args struct {
existing *Email
new *Email
existingEmail *Email
new *Email
}
type res struct {
changesLen int
@@ -23,8 +24,8 @@ func TestEmailChanges(t *testing.T) {
{
name: "all fields changed",
args: args{
existing: &Email{EmailAddress: "Email", IsEmailVerified: true},
new: &Email{EmailAddress: "EmailChanged", IsEmailVerified: false},
existingEmail: &Email{EmailAddress: "Email", IsEmailVerified: true},
new: &Email{EmailAddress: "EmailChanged", IsEmailVerified: false},
},
res: res{
changesLen: 1,
@@ -33,8 +34,8 @@ func TestEmailChanges(t *testing.T) {
{
name: "no fields changed",
args: args{
existing: &Email{EmailAddress: "Email", IsEmailVerified: true},
new: &Email{EmailAddress: "Email", IsEmailVerified: false},
existingEmail: &Email{EmailAddress: "Email", IsEmailVerified: true},
new: &Email{EmailAddress: "Email", IsEmailVerified: false},
},
res: res{
changesLen: 0,
@@ -43,7 +44,7 @@ func TestEmailChanges(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
changes := tt.args.existing.Changes(tt.args.new)
changes := tt.args.existingEmail.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))
}
@@ -53,23 +54,23 @@ func TestEmailChanges(t *testing.T) {
func TestAppendUserEmailChangedEvent(t *testing.T) {
type args struct {
user *User
user *Human
email *Email
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append user email event",
args: args{
user: &User{Email: &Email{EmailAddress: "EmailAddress"}},
user: &Human{Email: &Email{EmailAddress: "EmailAddress"}},
email: &Email{EmailAddress: "EmailAddressChanged"},
event: &es_models.Event{},
},
result: &User{Email: &Email{EmailAddress: "EmailAddressChanged"}},
result: &Human{Email: &Email{EmailAddress: "EmailAddressChanged"}},
},
}
for _, tt := range tests {
@@ -88,23 +89,23 @@ func TestAppendUserEmailChangedEvent(t *testing.T) {
func TestAppendUserEmailCodeAddedEvent(t *testing.T) {
type args struct {
user *User
user *Human
code *EmailCode
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append user email code added event",
args: args{
user: &User{Email: &Email{EmailAddress: "EmailAddress"}},
user: &Human{Email: &Email{EmailAddress: "EmailAddress"}},
code: &EmailCode{Expiry: time.Hour * 1},
event: &es_models.Event{},
},
result: &User{EmailCode: &EmailCode{Expiry: time.Hour * 1}},
result: &Human{EmailCode: &EmailCode{Expiry: time.Hour * 1}},
},
}
for _, tt := range tests {
@@ -123,21 +124,21 @@ func TestAppendUserEmailCodeAddedEvent(t *testing.T) {
func TestAppendUserEmailVerifiedEvent(t *testing.T) {
type args struct {
user *User
user *Human
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append user email event",
args: args{
user: &User{Email: &Email{EmailAddress: "EmailAddress"}},
user: &Human{Email: &Email{EmailAddress: "EmailAddress"}},
event: &es_models.Event{},
},
result: &User{Email: &Email{EmailAddress: "EmailAddress", IsEmailVerified: true}},
result: &Human{Email: &Email{EmailAddress: "EmailAddress", IsEmailVerified: true}},
},
}
for _, tt := range tests {

View File

@@ -2,6 +2,7 @@ package model
import (
"encoding/json"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/crypto"
caos_errs "github.com/caos/zitadel/internal/errors"
@@ -32,18 +33,18 @@ func OTPToModel(otp *OTP) *model.OTP {
}
}
func (u *User) appendOtpAddedEvent(event *es_models.Event) error {
func (u *Human) appendOTPAddedEvent(event *es_models.Event) error {
u.OTP = &OTP{
State: int32(model.MfaStateNotReady),
}
return u.OTP.setData(event)
}
func (u *User) appendOtpVerifiedEvent() {
func (u *Human) appendOTPVerifiedEvent() {
u.OTP.State = int32(model.MfaStateReady)
}
func (u *User) appendOtpRemovedEvent() {
func (u *Human) appendOTPRemovedEvent() {
u.OTP = nil
}

View File

@@ -2,31 +2,32 @@ package model
import (
"encoding/json"
"testing"
"github.com/caos/zitadel/internal/crypto"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/user/model"
"testing"
)
func TestAppendMfaOTPAddedEvent(t *testing.T) {
type args struct {
user *User
user *Human
otp *OTP
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append user otp event",
args: args{
user: &User{},
user: &Human{},
otp: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}},
event: &es_models.Event{},
},
result: &User{OTP: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}, State: int32(model.MfaStateNotReady)}},
result: &Human{OTP: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}, State: int32(model.MfaStateNotReady)}},
},
}
for _, tt := range tests {
@@ -35,7 +36,7 @@ func TestAppendMfaOTPAddedEvent(t *testing.T) {
data, _ := json.Marshal(tt.args.otp)
tt.args.event.Data = data
}
tt.args.user.appendOtpAddedEvent(tt.args.event)
tt.args.user.appendOTPAddedEvent(tt.args.event)
if tt.args.user.OTP.State != tt.result.OTP.State {
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.OTP.State, tt.args.user.OTP.State)
}
@@ -45,23 +46,23 @@ func TestAppendMfaOTPAddedEvent(t *testing.T) {
func TestAppendMfaOTPVerifyEvent(t *testing.T) {
type args struct {
user *User
user *Human
otp *OTP
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append otp verify event",
args: args{
user: &User{OTP: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}}},
user: &Human{OTP: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}}},
otp: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}},
event: &es_models.Event{},
},
result: &User{OTP: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}, State: int32(model.MfaStateReady)}},
result: &Human{OTP: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}, State: int32(model.MfaStateReady)}},
},
}
for _, tt := range tests {
@@ -70,7 +71,7 @@ func TestAppendMfaOTPVerifyEvent(t *testing.T) {
data, _ := json.Marshal(tt.args.otp)
tt.args.event.Data = data
}
tt.args.user.appendOtpVerifiedEvent()
tt.args.user.appendOTPVerifiedEvent()
if tt.args.user.OTP.State != tt.result.OTP.State {
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.OTP.State, tt.args.user.OTP.State)
}
@@ -80,27 +81,27 @@ func TestAppendMfaOTPVerifyEvent(t *testing.T) {
func TestAppendMfaOTPRemoveEvent(t *testing.T) {
type args struct {
user *User
user *Human
otp *OTP
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append otp verify event",
args: args{
user: &User{OTP: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}}},
user: &Human{OTP: &OTP{Secret: &crypto.CryptoValue{KeyID: "KeyID"}}},
event: &es_models.Event{},
},
result: &User{},
result: &Human{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.args.user.appendOtpRemovedEvent()
tt.args.user.appendOTPRemovedEvent()
if tt.args.user.OTP != nil {
t.Errorf("got wrong result: actual: %v ", tt.result.OTP)
}

View File

@@ -2,12 +2,13 @@ package model
import (
"encoding/json"
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/crypto"
caos_errs "github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/user/model"
"time"
)
type Password struct {
@@ -50,7 +51,7 @@ func PasswordCodeToModel(code *PasswordCode) *model.PasswordCode {
}
}
func (u *User) appendUserPasswordChangedEvent(event *es_models.Event) error {
func (u *Human) appendUserPasswordChangedEvent(event *es_models.Event) error {
u.Password = new(Password)
err := u.Password.setData(event)
if err != nil {
@@ -60,7 +61,7 @@ func (u *User) appendUserPasswordChangedEvent(event *es_models.Event) error {
return nil
}
func (u *User) appendPasswordSetRequestedEvent(event *es_models.Event) error {
func (u *Human) appendPasswordSetRequestedEvent(event *es_models.Event) error {
u.PasswordCode = new(PasswordCode)
return u.PasswordCode.SetData(event)
}

View File

@@ -2,30 +2,31 @@ package model
import (
"encoding/json"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"testing"
"time"
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
func TestAppendUserPasswordChangedEvent(t *testing.T) {
type args struct {
user *User
user *Human
pw *Password
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append init user code event",
args: args{
user: &User{},
user: &Human{},
pw: &Password{ChangeRequired: true},
event: &es_models.Event{},
},
result: &User{Password: &Password{ChangeRequired: true}},
result: &Human{Password: &Password{ChangeRequired: true}},
},
}
for _, tt := range tests {
@@ -44,23 +45,23 @@ func TestAppendUserPasswordChangedEvent(t *testing.T) {
func TestAppendPasswordSetRequestedEvent(t *testing.T) {
type args struct {
user *User
user *Human
code *PasswordCode
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append user phone code added event",
args: args{
user: &User{Phone: &Phone{PhoneNumber: "PhoneNumber"}},
user: &Human{Phone: &Phone{PhoneNumber: "PhoneNumber"}},
code: &PasswordCode{Expiry: time.Hour * 1},
event: &es_models.Event{},
},
result: &User{PasswordCode: &PasswordCode{Expiry: time.Hour * 1}},
result: &Human{PasswordCode: &PasswordCode{Expiry: time.Hour * 1}},
},
}
for _, tt := range tests {

View File

@@ -2,12 +2,13 @@ package model
import (
"encoding/json"
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/crypto"
caos_errs "github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/user/model"
"time"
)
type Phone struct {
@@ -67,21 +68,21 @@ func PhoneCodeToModel(code *PhoneCode) *model.PhoneCode {
}
}
func (u *User) appendUserPhoneChangedEvent(event *es_models.Event) error {
func (u *Human) appendUserPhoneChangedEvent(event *es_models.Event) error {
u.Phone = new(Phone)
return u.Phone.setData(event)
}
func (u *User) appendUserPhoneCodeAddedEvent(event *es_models.Event) error {
func (u *Human) appendUserPhoneCodeAddedEvent(event *es_models.Event) error {
u.PhoneCode = new(PhoneCode)
return u.PhoneCode.SetData(event)
}
func (u *User) appendUserPhoneVerifiedEvent() {
func (u *Human) appendUserPhoneVerifiedEvent() {
u.IsPhoneVerified = true
}
func (u *User) appendUserPhoneRemovedEvent() {
func (u *Human) appendUserPhoneRemovedEvent() {
u.Phone = nil
u.PhoneCode = nil
}

View File

@@ -2,15 +2,16 @@ package model
import (
"encoding/json"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"testing"
"time"
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
func TestPhoneChanges(t *testing.T) {
type args struct {
existing *Phone
new *Phone
existingPhone *Phone
newPhone *Phone
}
type res struct {
changesLen int
@@ -23,8 +24,8 @@ func TestPhoneChanges(t *testing.T) {
{
name: "all fields changed",
args: args{
existing: &Phone{PhoneNumber: "Phone", IsPhoneVerified: true},
new: &Phone{PhoneNumber: "PhoneChanged", IsPhoneVerified: false},
existingPhone: &Phone{PhoneNumber: "Phone", IsPhoneVerified: true},
newPhone: &Phone{PhoneNumber: "PhoneChanged", IsPhoneVerified: false},
},
res: res{
changesLen: 1,
@@ -33,8 +34,8 @@ func TestPhoneChanges(t *testing.T) {
{
name: "no fields changed",
args: args{
existing: &Phone{PhoneNumber: "Phone", IsPhoneVerified: true},
new: &Phone{PhoneNumber: "Phone", IsPhoneVerified: false},
existingPhone: &Phone{PhoneNumber: "Phone", IsPhoneVerified: true},
newPhone: &Phone{PhoneNumber: "Phone", IsPhoneVerified: false},
},
res: res{
changesLen: 0,
@@ -43,7 +44,7 @@ func TestPhoneChanges(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
changes := tt.args.existing.Changes(tt.args.new)
changes := tt.args.existingPhone.Changes(tt.args.newPhone)
if len(changes) != tt.res.changesLen {
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
}
@@ -53,23 +54,23 @@ func TestPhoneChanges(t *testing.T) {
func TestAppendUserPhoneChangedEvent(t *testing.T) {
type args struct {
user *User
user *Human
phone *Phone
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append user phone event",
args: args{
user: &User{Phone: &Phone{PhoneNumber: "PhoneNumber"}},
user: &Human{Phone: &Phone{PhoneNumber: "PhoneNumber"}},
phone: &Phone{PhoneNumber: "PhoneNumberChanged"},
event: &es_models.Event{},
},
result: &User{Phone: &Phone{PhoneNumber: "PhoneNumberChanged"}},
result: &Human{Phone: &Phone{PhoneNumber: "PhoneNumberChanged"}},
},
}
for _, tt := range tests {
@@ -88,23 +89,23 @@ func TestAppendUserPhoneChangedEvent(t *testing.T) {
func TestAppendUserPhoneCodeAddedEvent(t *testing.T) {
type args struct {
user *User
user *Human
code *PhoneCode
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append user phone code added event",
args: args{
user: &User{Phone: &Phone{PhoneNumber: "PhoneNumber"}},
user: &Human{Phone: &Phone{PhoneNumber: "PhoneNumber"}},
code: &PhoneCode{Expiry: time.Hour * 1},
event: &es_models.Event{},
},
result: &User{PhoneCode: &PhoneCode{Expiry: time.Hour * 1}},
result: &Human{PhoneCode: &PhoneCode{Expiry: time.Hour * 1}},
},
}
for _, tt := range tests {
@@ -123,21 +124,21 @@ func TestAppendUserPhoneCodeAddedEvent(t *testing.T) {
func TestAppendUserPhoneVerifiedEvent(t *testing.T) {
type args struct {
user *User
user *Human
event *es_models.Event
}
tests := []struct {
name string
args args
result *User
result *Human
}{
{
name: "append user phone event",
args: args{
user: &User{Phone: &Phone{PhoneNumber: "PhoneNumber"}},
user: &Human{Phone: &Phone{PhoneNumber: "PhoneNumber"}},
event: &es_models.Event{},
},
result: &User{Phone: &Phone{PhoneNumber: "PhoneNumber", IsPhoneVerified: true}},
result: &Human{Phone: &Phone{PhoneNumber: "PhoneNumber", IsPhoneVerified: true}},
},
}
for _, tt := range tests {

View File

@@ -10,7 +10,6 @@ import (
type Profile struct {
es_models.ObjectRoot
UserName string `json:"userName,omitempty"`
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
NickName string `json:"nickName,omitempty"`
@@ -18,7 +17,7 @@ type Profile struct {
PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"`
Gender int32 `json:"gender,omitempty"`
isUserNameUnique bool `json:"-"`
isUserNameUnique bool
}
func (p *Profile) Changes(changed *Profile) map[string]interface{} {
@@ -47,7 +46,6 @@ func (p *Profile) Changes(changed *Profile) map[string]interface{} {
func ProfileFromModel(profile *model.Profile) *Profile {
return &Profile{
ObjectRoot: profile.ObjectRoot,
UserName: profile.UserName,
FirstName: profile.FirstName,
LastName: profile.LastName,
NickName: profile.NickName,
@@ -60,7 +58,6 @@ func ProfileFromModel(profile *model.Profile) *Profile {
func ProfileToModel(profile *Profile) *model.Profile {
return &model.Profile{
ObjectRoot: profile.ObjectRoot,
UserName: profile.UserName,
FirstName: profile.FirstName,
LastName: profile.LastName,
NickName: profile.NickName,

Some files were not shown because too many files have changed in this diff Show More