mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 20:37:23 +00:00
fix: commandside queries (#1313)
* fix: move user by id to query side * fix: move get passwordless to query side # Conflicts: # internal/user/repository/eventsourcing/eventstore.go * fix: move get passwordless to query side * remove user eventstore * remove unused models * org changes * org changes * fix: move org queries to query side * fix: remove org eventstore * fix: remove org eventstore * fix: remove org eventstore * remove project from es v1 * project cleanup * project cleanup * fix: remove org eventstore * fix: remove iam eventstore Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
parent
2ba56595b1
commit
428ef4acdb
@ -1,11 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
)
|
||||
|
||||
type SetupOrg struct {
|
||||
*org_model.Org
|
||||
*usr_model.User
|
||||
}
|
@ -2,7 +2,11 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"strings"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
@ -11,19 +15,14 @@ import (
|
||||
admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_es "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type IAMRepository struct {
|
||||
SearchLimit uint64
|
||||
*iam_es.IAMEventstore
|
||||
OrgEvents *org_es.OrgEventstore
|
||||
UserEvents *usr_es.UserEventstore
|
||||
Eventstore eventstore.Eventstore
|
||||
SearchLimit uint64
|
||||
View *admin_view.View
|
||||
SystemDefaults systemdefaults.SystemDefaults
|
||||
Roles []string
|
||||
@ -130,7 +129,7 @@ func (repo *IAMRepository) GetDefaultLoginPolicy(ctx context.Context) (*iam_mode
|
||||
if caos_errs.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.LoginPolicyView)
|
||||
}
|
||||
events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-cmO9s", "Errors.IAM.LoginPolicy.NotFound")
|
||||
}
|
||||
@ -199,7 +198,7 @@ func (repo *IAMRepository) GetDefaultPasswordComplexityPolicy(ctx context.Contex
|
||||
if caos_errs.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordComplexityPolicyView)
|
||||
}
|
||||
events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-1Mc0s", "Errors.IAM.PasswordComplexityPolicy.NotFound")
|
||||
}
|
||||
@ -224,7 +223,7 @@ func (repo *IAMRepository) GetDefaultPasswordAgePolicy(ctx context.Context) (*ia
|
||||
if caos_errs.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordAgePolicyView)
|
||||
}
|
||||
events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-vMyS3", "Errors.IAM.PasswordAgePolicy.NotFound")
|
||||
}
|
||||
@ -249,7 +248,7 @@ func (repo *IAMRepository) GetDefaultPasswordLockoutPolicy(ctx context.Context)
|
||||
if caos_errs.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordLockoutPolicyView)
|
||||
}
|
||||
events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2M9oP", "Errors.IAM.PasswordLockoutPolicy.NotFound")
|
||||
}
|
||||
@ -274,7 +273,7 @@ func (repo *IAMRepository) GetOrgIAMPolicy(ctx context.Context) (*iam_model.OrgI
|
||||
if caos_errs.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.OrgIAMPolicyView)
|
||||
}
|
||||
events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-MkoL0", "Errors.IAM.OrgIAMPolicy.NotFound")
|
||||
}
|
||||
@ -344,3 +343,11 @@ func (repo *IAMRepository) GetDefaultMailText(ctx context.Context, textType stri
|
||||
text.Default = true
|
||||
return iam_es_model.MailTextViewToModel(text), err
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) getIAMEvents(ctx context.Context, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
@ -2,9 +2,12 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"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"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
|
||||
"github.com/caos/logging"
|
||||
@ -13,15 +16,11 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type OrgRepo struct {
|
||||
Eventstore eventstore.Eventstore
|
||||
OrgEventstore *org_es.OrgEventstore
|
||||
UserEventstore *usr_es.UserEventstore
|
||||
Eventstore eventstore.Eventstore
|
||||
|
||||
View *admin_view.View
|
||||
|
||||
@ -29,8 +28,29 @@ type OrgRepo struct {
|
||||
SystemDefaults systemdefaults.SystemDefaults
|
||||
}
|
||||
|
||||
func (repo *OrgRepo) OrgByID(ctx context.Context, id string) (*org_model.Org, error) {
|
||||
return repo.OrgEventstore.OrgByID(ctx, org_model.NewOrg(id))
|
||||
func (repo *OrgRepo) OrgByID(ctx context.Context, id string) (*org_model.OrgView, error) {
|
||||
org, viewErr := repo.View.OrgByID(id)
|
||||
if viewErr != nil && !errors.IsNotFound(viewErr) {
|
||||
return nil, viewErr
|
||||
}
|
||||
if errors.IsNotFound(viewErr) {
|
||||
org = new(model.OrgView)
|
||||
}
|
||||
events, esErr := repo.getOrgEvents(ctx, id, org.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-Lsoj7", "Errors.Org.NotFound")
|
||||
}
|
||||
if esErr != nil {
|
||||
logging.Log("EVENT-PSoc3").WithError(esErr).Debug("error retrieving new events")
|
||||
return model.OrgToModel(org), nil
|
||||
}
|
||||
orgCopy := *org
|
||||
for _, event := range events {
|
||||
if err := orgCopy.AppendEvent(event); err != nil {
|
||||
return model.OrgToModel(&orgCopy), nil
|
||||
}
|
||||
}
|
||||
return model.OrgToModel(&orgCopy), nil
|
||||
}
|
||||
|
||||
func (repo *OrgRepo) SearchOrgs(ctx context.Context, query *org_model.OrgSearchRequest) (*org_model.OrgSearchResult, error) {
|
||||
@ -55,7 +75,18 @@ func (repo *OrgRepo) SearchOrgs(ctx context.Context, query *org_model.OrgSearchR
|
||||
}
|
||||
|
||||
func (repo *OrgRepo) IsOrgUnique(ctx context.Context, name, domain string) (isUnique bool, err error) {
|
||||
return repo.OrgEventstore.IsOrgUnique(ctx, name, domain)
|
||||
var found bool
|
||||
err = es_sdk.Filter(ctx, repo.Eventstore.FilterEvents, isUniqueValidation(&found), view.OrgNameUniqueQuery(name))
|
||||
if (err != nil && !errors.IsNotFound(err)) || found {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = es_sdk.Filter(ctx, repo.Eventstore.FilterEvents, isUniqueValidation(&found), view.OrgDomainUniqueQuery(domain))
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return !found, nil
|
||||
}
|
||||
|
||||
func (repo *OrgRepo) GetOrgIAMPolicyByID(ctx context.Context, id string) (*iam_model.OrgIAMPolicyView, error) {
|
||||
@ -77,3 +108,22 @@ func (repo *OrgRepo) GetDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.Org
|
||||
policy.Default = true
|
||||
return iam_es_model.OrgIAMViewToModel(policy), err
|
||||
}
|
||||
|
||||
func (repo *OrgRepo) getOrgEvents(ctx context.Context, orgID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func isUniqueValidation(unique *bool) func(events ...*models.Event) error {
|
||||
return func(events ...*models.Event) error {
|
||||
if len(events) == 0 {
|
||||
return nil
|
||||
}
|
||||
*unique = *unique || events[0].Type == org_es_model.OrgDomainReserved || events[0].Type == org_es_model.OrgNameReserved
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
package eventstore
|
||||
|
||||
import (
|
||||
admin_model "github.com/caos/zitadel/internal/admin/model"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
type Setup struct {
|
||||
*model.Org
|
||||
*usr_es.User
|
||||
}
|
||||
|
||||
func (s *Setup) AppendEvents(events ...*es_models.Event) error {
|
||||
for _, event := range events {
|
||||
var err error
|
||||
switch event.AggregateType {
|
||||
case model.OrgAggregate:
|
||||
err = s.Org.AppendEvent(event)
|
||||
case usr_es.UserAggregate:
|
||||
err = s.User.AppendEvent(event)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetupToModel(setup *Setup) *admin_model.SetupOrg {
|
||||
return &admin_model.SetupOrg{
|
||||
Org: model.OrgToModel(setup.Org),
|
||||
User: usr_es.UserToModel(setup.User),
|
||||
}
|
||||
}
|
@ -8,9 +8,6 @@ import (
|
||||
"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"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Configs map[string]*Config
|
||||
@ -32,19 +29,12 @@ func (h *handler) Eventstore() eventstore.Eventstore {
|
||||
return h.es
|
||||
}
|
||||
|
||||
type EventstoreRepos struct {
|
||||
UserEvents *usr_event.UserEventstore
|
||||
IamEvents *iam_event.IAMEventstore
|
||||
OrgEvents *org_event.OrgEventstore
|
||||
}
|
||||
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, repos EventstoreRepos, defaults systemdefaults.SystemDefaults) []query.Handler {
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, defaults systemdefaults.SystemDefaults) []query.Handler {
|
||||
return []query.Handler{
|
||||
newOrg(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Org"), errorCount, es}),
|
||||
newIAMMember(
|
||||
handler{view, bulkLimit, configs.cycleDuration("IamMember"), errorCount, es},
|
||||
repos.UserEvents),
|
||||
handler{view, bulkLimit, configs.cycleDuration("IamMember"), errorCount, es}),
|
||||
newIDPConfig(
|
||||
handler{view, bulkLimit, configs.cycleDuration("IDPConfig"), errorCount, es}),
|
||||
newLabelPolicy(
|
||||
@ -53,13 +43,9 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
handler{view, bulkLimit, configs.cycleDuration("LoginPolicy"), errorCount, es}),
|
||||
newIDPProvider(
|
||||
handler{view, bulkLimit, configs.cycleDuration("IDPProvider"), errorCount, es},
|
||||
defaults,
|
||||
repos.IamEvents,
|
||||
repos.OrgEvents),
|
||||
defaults),
|
||||
newUser(
|
||||
handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es},
|
||||
repos.OrgEvents,
|
||||
repos.IamEvents,
|
||||
defaults),
|
||||
newPasswordComplexityPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("PasswordComplexityPolicy"), errorCount, es}),
|
||||
@ -71,9 +57,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
handler{view, bulkLimit, configs.cycleDuration("OrgIAMPolicy"), errorCount, es}),
|
||||
newExternalIDP(
|
||||
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
||||
defaults,
|
||||
repos.IamEvents,
|
||||
repos.OrgEvents),
|
||||
defaults),
|
||||
newMailTemplate(
|
||||
handler{view, bulkLimit, configs.cycleDuration("MailTemplate"), errorCount, es}),
|
||||
newMailText(
|
||||
|
@ -2,16 +2,19 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
@ -21,14 +24,12 @@ const (
|
||||
|
||||
type IAMMember struct {
|
||||
handler
|
||||
userEvents *usr_event.UserEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newIAMMember(handler handler, userEvents *usr_event.UserEventstore) *IAMMember {
|
||||
func newIAMMember(handler handler) *IAMMember {
|
||||
iamMember := &IAMMember{
|
||||
handler: handler,
|
||||
userEvents: userEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
iamMember.subscribe()
|
||||
@ -129,7 +130,7 @@ func (m *IAMMember) processUser(event *es_models.Event) (err error) {
|
||||
if len(members) == 0 {
|
||||
return m.view.ProcessedIAMMemberSequence(event)
|
||||
}
|
||||
user, err := m.userEvents.UserByID(context.Background(), event.AggregateID)
|
||||
user, err := m.getUserByID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -145,7 +146,7 @@ func (m *IAMMember) processUser(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *IAMMember) fillData(member *iam_model.IAMMemberView) (err error) {
|
||||
user, err := m.userEvents.UserByID(context.Background(), member.UserID)
|
||||
user, err := m.getUserByID(member.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -153,16 +154,16 @@ func (m *IAMMember) fillData(member *iam_model.IAMMemberView) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *IAMMember) fillUserData(member *iam_model.IAMMemberView, user *usr_model.User) {
|
||||
func (m *IAMMember) fillUserData(member *iam_model.IAMMemberView, user *view_model.UserView) {
|
||||
member.UserName = user.UserName
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
member.FirstName = user.FirstName
|
||||
member.LastName = user.LastName
|
||||
member.DisplayName = user.FirstName + " " + user.LastName
|
||||
member.Email = user.EmailAddress
|
||||
member.Email = user.Email
|
||||
}
|
||||
if user.Machine != nil {
|
||||
member.DisplayName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
member.DisplayName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
func (m *IAMMember) OnError(event *es_models.Event, err error) error {
|
||||
@ -173,3 +174,36 @@ func (m *IAMMember) OnError(event *es_models.Event, err error) error {
|
||||
func (m *IAMMember) OnSuccess() error {
|
||||
return spooler.HandleSuccess(m.view.UpdateIAMMemberSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (m *IAMMember) getUserByID(userID string) (*view_model.UserView, error) {
|
||||
user, usrErr := m.view.UserByID(userID)
|
||||
if usrErr != nil && !caos_errs.IsNotFound(usrErr) {
|
||||
return nil, usrErr
|
||||
}
|
||||
if user == nil {
|
||||
user = &view_model.UserView{}
|
||||
}
|
||||
events, err := m.getUserEvents(userID, user.Sequence)
|
||||
if err != nil {
|
||||
return user, usrErr
|
||||
}
|
||||
userCopy := *user
|
||||
for _, event := range events {
|
||||
if err := userCopy.AppendEvent(event); err != nil {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
if userCopy.State == int32(usr_model.UserStateDeleted) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "HANDLER-4n9fs", "Errors.User.NotFound")
|
||||
}
|
||||
return &userCopy, nil
|
||||
}
|
||||
|
||||
func (m *IAMMember) getUserEvents(userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
@ -2,6 +2,12 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
@ -10,10 +16,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
@ -24,22 +28,16 @@ const (
|
||||
type IDPProvider struct {
|
||||
handler
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
iamEvents *eventsourcing.IAMEventstore
|
||||
orgEvents *org_events.OrgEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newIDPProvider(
|
||||
handler handler,
|
||||
systemDefaults systemdefaults.SystemDefaults,
|
||||
iamEvents *eventsourcing.IAMEventstore,
|
||||
orgEvents *org_events.OrgEventstore,
|
||||
) *IDPProvider {
|
||||
h := &IDPProvider{
|
||||
handler: handler,
|
||||
systemDefaults: systemDefaults,
|
||||
iamEvents: iamEvents,
|
||||
orgEvents: orgEvents,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -117,7 +115,7 @@ func (i *IDPProvider) processIdpProvider(event *es_models.Event) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := i.iamEvents.GetIDPConfig(context.Background(), event.AggregateID, esConfig.IDPConfigID)
|
||||
config, err := i.getDefaultIDPConfig(context.Background(), esConfig.IDPConfigID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -137,9 +135,9 @@ func (i *IDPProvider) processIdpProvider(event *es_models.Event) (err error) {
|
||||
func (i *IDPProvider) fillData(provider *iam_view_model.IDPProviderView) (err error) {
|
||||
var config *iam_model.IDPConfig
|
||||
if provider.IDPProviderType == int32(iam_model.IDPProviderTypeSystem) {
|
||||
config, err = i.iamEvents.GetIDPConfig(context.Background(), i.systemDefaults.IamID, provider.IDPConfigID)
|
||||
config, err = i.getDefaultIDPConfig(context.Background(), provider.IDPConfigID)
|
||||
} else {
|
||||
config, err = i.orgEvents.GetIDPConfig(context.Background(), provider.AggregateID, provider.IDPConfigID)
|
||||
config, err = i.getOrgIDPConfig(context.Background(), provider.AggregateID, provider.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -163,3 +161,64 @@ func (i *IDPProvider) OnError(event *es_models.Event, err error) error {
|
||||
func (i *IDPProvider) OnSuccess() error {
|
||||
return spooler.HandleSuccess(i.view.UpdateIDPProviderSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (i *IDPProvider) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := i.getOrgByID(ctx, aggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, i := existing.GetIDP(idpConfigID); i != nil {
|
||||
return i, nil
|
||||
}
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-4m0fs", "Errors.Org.IdpNotExisting")
|
||||
}
|
||||
|
||||
func (i *IDPProvider) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-4m9gs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *IDPProvider) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *IDPProvider) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil {
|
||||
return existingIDP, nil
|
||||
}
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-4M=Fs", "Errors.IAM.IdpNotExisting")
|
||||
}
|
||||
|
@ -2,12 +2,12 @@ package handler
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
)
|
||||
@ -53,7 +53,7 @@ func (o *Org) EventQuery() (*es_models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eventsourcing.OrgQuery(sequence.CurrentSequence), nil
|
||||
return view.OrgQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (o *Org) CurrentSequence() (uint64, error) {
|
||||
|
@ -2,9 +2,15 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
iam_es "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
@ -14,7 +20,6 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@ -27,22 +32,16 @@ const (
|
||||
type User struct {
|
||||
handler
|
||||
eventstore eventstore.Eventstore
|
||||
orgEvents *org_events.OrgEventstore
|
||||
iamEvents *iam_es.IAMEventstore
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newUser(
|
||||
handler handler,
|
||||
orgEvents *org_events.OrgEventstore,
|
||||
iamEvents *iam_es.IAMEventstore,
|
||||
systemDefaults systemdefaults.SystemDefaults,
|
||||
) *User {
|
||||
h := &User{
|
||||
handler: handler,
|
||||
orgEvents: orgEvents,
|
||||
iamEvents: iamEvents,
|
||||
systemDefaults: systemDefaults,
|
||||
}
|
||||
|
||||
@ -184,13 +183,13 @@ func (u *User) ProcessOrg(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (u *User) fillLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.systemDefaults.IamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -206,13 +205,13 @@ func (u *User) fillLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
}
|
||||
|
||||
func (u *User) fillPreferredLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.systemDefaults.IamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -231,17 +230,18 @@ func (u *User) fillPreferredLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
}
|
||||
|
||||
func (u *User) fillLoginNames(user *view_model.UserView) (err error) {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(user.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.systemDefaults.IamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
user.SetLoginNames(policy, org.Domains)
|
||||
user.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain)
|
||||
return nil
|
||||
@ -255,3 +255,53 @@ func (u *User) OnError(event *models.Event, err error) error {
|
||||
func (u *User) OnSuccess() error {
|
||||
return spooler.HandleSuccess(u.view.UpdateUserSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *User) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.eventstore.FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-kVLb2", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *User) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.eventstore.FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *User) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2Fj8s", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
}
|
||||
|
@ -2,24 +2,25 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -29,22 +30,16 @@ const (
|
||||
type ExternalIDP struct {
|
||||
handler
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
iamEvents *eventsourcing.IAMEventstore
|
||||
orgEvents *org_es.OrgEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newExternalIDP(
|
||||
handler handler,
|
||||
systemDefaults systemdefaults.SystemDefaults,
|
||||
iamEvents *eventsourcing.IAMEventstore,
|
||||
orgEvents *org_es.OrgEventstore,
|
||||
) *ExternalIDP {
|
||||
h := &ExternalIDP{
|
||||
handler: handler,
|
||||
systemDefaults: systemDefaults,
|
||||
iamEvents: iamEvents,
|
||||
orgEvents: orgEvents,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -138,9 +133,9 @@ func (i *ExternalIDP) processIdpConfig(event *models.Event) (err error) {
|
||||
return err
|
||||
}
|
||||
if event.AggregateType == iam_es_model.IAMAggregate {
|
||||
config, err = i.iamEvents.GetIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID)
|
||||
config, err = i.getDefaultIDPConfig(context.Background(), configView.IDPConfigID)
|
||||
} else {
|
||||
config, err = i.orgEvents.GetIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID)
|
||||
config, err = i.getOrgIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -155,9 +150,9 @@ func (i *ExternalIDP) processIdpConfig(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) fillData(externalIDP *usr_view_model.ExternalIDPView) error {
|
||||
config, err := i.orgEvents.GetIDPConfig(context.Background(), externalIDP.ResourceOwner, externalIDP.IDPConfigID)
|
||||
config, err := i.getOrgIDPConfig(context.Background(), externalIDP.ResourceOwner, externalIDP.IDPConfigID)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
config, err = i.iamEvents.GetIDPConfig(context.Background(), i.systemDefaults.IamID, externalIDP.IDPConfigID)
|
||||
config, err = i.getDefaultIDPConfig(context.Background(), externalIDP.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -178,3 +173,64 @@ func (i *ExternalIDP) OnError(event *models.Event, err error) error {
|
||||
func (i *ExternalIDP) OnSuccess() error {
|
||||
return spooler.HandleSuccess(i.view.UpdateExternalIDPSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := i.getOrgByID(ctx, aggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, i := existing.GetIDP(idpConfigID); i != nil {
|
||||
return i, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2n8Fh", "Errors.Org.IdpNotExisting")
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-MOFMs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *ExternalIDP) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *ExternalIDP) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil {
|
||||
return existingIDP, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-49O0f", "Errors.IAM.IdpNotExisting")
|
||||
}
|
||||
|
@ -3,16 +3,12 @@ package eventsourcing
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/eventstore"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/handler"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/spooler"
|
||||
admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
|
||||
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"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -35,23 +31,6 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam, err := es_iam.StartIAM(es_iam.IAMConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults)
|
||||
|
||||
user, err := es_usr.StartUser(es_usr.UserConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sqlClient, err := conf.View.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -61,22 +40,18 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, handler.EventstoreRepos{UserEvents: user, OrgEvents: org, IamEvents: iam}, systemDefaults)
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults)
|
||||
|
||||
return &EsRepository{
|
||||
spooler: spool,
|
||||
OrgRepo: eventstore.OrgRepo{
|
||||
Eventstore: es,
|
||||
OrgEventstore: org,
|
||||
UserEventstore: user,
|
||||
View: view,
|
||||
SearchLimit: conf.SearchLimit,
|
||||
SystemDefaults: systemDefaults,
|
||||
},
|
||||
IAMRepository: eventstore.IAMRepository{
|
||||
IAMEventstore: iam,
|
||||
OrgEvents: org,
|
||||
UserEvents: user,
|
||||
Eventstore: es,
|
||||
View: view,
|
||||
SystemDefaults: systemDefaults,
|
||||
SearchLimit: conf.SearchLimit,
|
||||
@ -89,13 +64,5 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
||||
}
|
||||
|
||||
func (repo *EsRepository) Health(ctx context.Context) error {
|
||||
err := repo.Eventstore.Health(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = repo.UserEventstore.Health(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return repo.OrgEventstore.Health(ctx)
|
||||
return nil
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ type SpoolerConfig struct {
|
||||
Handlers handler.Configs
|
||||
}
|
||||
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, repos handler.EventstoreRepos, defaults systemdefaults.SystemDefaults) *spooler.Spooler {
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, defaults systemdefaults.SystemDefaults) *spooler.Spooler {
|
||||
spoolerConfig := spooler.Config{
|
||||
Eventstore: es,
|
||||
Locker: &locker{dbClient: sql},
|
||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, repos, defaults),
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, defaults),
|
||||
}
|
||||
spool := spoolerConfig.New()
|
||||
spool.Start()
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
|
||||
type OrgRepository interface {
|
||||
IsOrgUnique(ctx context.Context, name, domain string) (bool, error)
|
||||
OrgByID(ctx context.Context, id string) (*org_model.Org, error)
|
||||
OrgByID(ctx context.Context, id string) (*org_model.OrgView, error)
|
||||
SearchOrgs(ctx context.Context, query *org_model.OrgSearchRequest) (*org_model.OrgSearchResult, error)
|
||||
|
||||
GetOrgIAMPolicyByID(ctx context.Context, id string) (*iam_model.OrgIAMPolicyView, error)
|
||||
|
@ -14,7 +14,7 @@ func (s *Server) GetOrgByID(ctx context.Context, orgID *admin.OrgID) (_ *admin.O
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orgFromModel(org), nil
|
||||
return orgViewFromModel(org), nil
|
||||
}
|
||||
|
||||
func (s *Server) SearchOrgs(ctx context.Context, request *admin.OrgSearchRequest) (_ *admin.OrgSearchResponse, err error) {
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
|
||||
admin_model "github.com/caos/zitadel/internal/admin/model"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
@ -28,13 +27,6 @@ func orgCreateRequestToDomain(org *admin.CreateOrgRequest) *domain.Org {
|
||||
return o
|
||||
}
|
||||
|
||||
func setUpOrgResponseFromModel(setUp *admin_model.SetupOrg) *admin.OrgSetUpResponse {
|
||||
return &admin.OrgSetUpResponse{
|
||||
Org: orgFromModel(setUp.Org),
|
||||
User: userFromModel(setUp.User),
|
||||
}
|
||||
}
|
||||
|
||||
func orgSearchResponseFromModel(request *org_model.OrgSearchResult) *admin.OrgSearchResponse {
|
||||
timestamp, err := ptypes.TimestampProto(request.Timestamp)
|
||||
logging.Log("GRPC-shu7s").OnError(err).Debug("unable to get timestamp from time")
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/pkg/grpc/admin"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
@ -77,125 +76,6 @@ func machineCreateToDomain(machine *admin.CreateMachineRequest) *domain.Machine
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func externalIDPViewsToDomain(idps []*usr_model.ExternalIDPView) []*domain.ExternalIDP {
|
||||
externalIDPs := make([]*domain.ExternalIDP, len(idps))
|
||||
for i, idp := range idps {
|
||||
|
@ -438,7 +438,7 @@ func verifyWebAuthNFromDomain(u2f *domain.WebAuthNToken) *auth.WebAuthNResponse
|
||||
}
|
||||
}
|
||||
|
||||
func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNToken) *auth.WebAuthNTokens {
|
||||
func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNView) *auth.WebAuthNTokens {
|
||||
result := make([]*auth.WebAuthNToken, len(tokens))
|
||||
for i, token := range tokens {
|
||||
result[i] = webAuthNTokenFromModel(token)
|
||||
@ -446,10 +446,10 @@ func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNToken) *auth.WebAuthNTo
|
||||
return &auth.WebAuthNTokens{Tokens: result}
|
||||
}
|
||||
|
||||
func webAuthNTokenFromModel(token *usr_model.WebAuthNToken) *auth.WebAuthNToken {
|
||||
func webAuthNTokenFromModel(token *usr_model.WebAuthNView) *auth.WebAuthNToken {
|
||||
return &auth.WebAuthNToken{
|
||||
Id: token.WebAuthNTokenID,
|
||||
Name: token.WebAuthNTokenName,
|
||||
Id: token.TokenID,
|
||||
Name: token.Name,
|
||||
State: auth.MFAState(token.State),
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func (s *Server) GetIam(ctx context.Context, _ *empty.Empty) (*management.Iam, error) {
|
||||
iam, err := s.iam.IAMByID(ctx, s.systemDefaults.IamID)
|
||||
iam, err := s.project.GetIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -624,7 +624,7 @@ func userChangesToMgtAPI(changes *usr_model.UserChanges) (_ []*management.Change
|
||||
return result
|
||||
}
|
||||
|
||||
func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNToken) *management.WebAuthNTokens {
|
||||
func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNView) *management.WebAuthNTokens {
|
||||
result := make([]*management.WebAuthNToken, len(tokens))
|
||||
for i, token := range tokens {
|
||||
result[i] = webAuthNTokenFromModel(token)
|
||||
@ -632,10 +632,10 @@ func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNToken) *management.WebA
|
||||
return &management.WebAuthNTokens{Tokens: result}
|
||||
}
|
||||
|
||||
func webAuthNTokenFromModel(token *usr_model.WebAuthNToken) *management.WebAuthNToken {
|
||||
func webAuthNTokenFromModel(token *usr_model.WebAuthNView) *management.WebAuthNToken {
|
||||
return &management.WebAuthNToken{
|
||||
Id: token.WebAuthNTokenID,
|
||||
Name: token.WebAuthNTokenName,
|
||||
Id: token.TokenID,
|
||||
Name: token.Name,
|
||||
State: mfaStateFromModel(token.State),
|
||||
}
|
||||
}
|
||||
|
@ -37,35 +37,6 @@ func humanFromDomain(user *domain.Human) *management.HumanResponse {
|
||||
return human
|
||||
}
|
||||
|
||||
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(),
|
||||
//TODO: User Converter
|
||||
Gender: management.Gender(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")
|
||||
|
@ -1,11 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
)
|
||||
|
||||
type RegisterOrg struct {
|
||||
*org_model.Org
|
||||
*usr_model.User
|
||||
}
|
@ -5,16 +5,14 @@ import (
|
||||
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/project/model"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
)
|
||||
|
||||
type ApplicationRepo struct {
|
||||
Commands *command.CommandSide
|
||||
View *view.View
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
Commands *command.CommandSide
|
||||
View *view.View
|
||||
}
|
||||
|
||||
func (a *ApplicationRepo) ApplicationByClientID(ctx context.Context, clientID string) (*model.ApplicationView, error) {
|
||||
|
@ -20,12 +20,10 @@ import (
|
||||
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/id"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_view_model "github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
project_view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
user_model "github.com/caos/zitadel/internal/user/model"
|
||||
user_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
user_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
grant_view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||
@ -33,8 +31,6 @@ import (
|
||||
|
||||
type AuthRequestRepo struct {
|
||||
Command *command.CommandSide
|
||||
UserEvents *user_event.UserEventstore
|
||||
OrgEvents *org_event.OrgEventstore
|
||||
AuthRequests cache.AuthRequestCache
|
||||
View *view.View
|
||||
|
||||
@ -93,9 +89,6 @@ type userGrantProvider interface {
|
||||
}
|
||||
|
||||
func (repo *AuthRequestRepo) Health(ctx context.Context) error {
|
||||
if err := repo.UserEvents.Health(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return repo.AuthRequests.Health(ctx)
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
org_view_model "github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
proj_view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
user_model "github.com/caos/zitadel/internal/user/model"
|
||||
user_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
user_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
user_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
grant_view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||
@ -198,7 +197,6 @@ func (m *mockUserGrants) UserGrantsByProjectAndUserID(s string, s2 string) ([]*g
|
||||
|
||||
func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
type fields struct {
|
||||
UserEvents *user_event.UserEventstore
|
||||
AuthRequests *cache.AuthRequestCache
|
||||
View *view.View
|
||||
userSessionViewProvider userSessionViewProvider
|
||||
@ -958,7 +956,6 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
repo := &AuthRequestRepo{
|
||||
UserEvents: tt.fields.UserEvents,
|
||||
AuthRequests: tt.fields.AuthRequests,
|
||||
View: tt.fields.View,
|
||||
UserSessionViewProvider: tt.fields.userSessionViewProvider,
|
||||
|
@ -14,9 +14,7 @@ import (
|
||||
|
||||
auth_view "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -24,9 +22,7 @@ const (
|
||||
)
|
||||
|
||||
type OrgRepository struct {
|
||||
SearchLimit uint64
|
||||
OrgEventstore *org_es.OrgEventstore
|
||||
UserEventstore *usr_es.UserEventstore
|
||||
SearchLimit uint64
|
||||
|
||||
View *auth_view.View
|
||||
SystemDefaults systemdefaults.SystemDefaults
|
||||
|
@ -3,13 +3,11 @@ package eventstore
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/project/model"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
)
|
||||
|
||||
type ProjectRepo struct {
|
||||
View *view.View
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
View *view.View
|
||||
}
|
||||
|
||||
func (a *ApplicationRepo) ProjectRolesByProjectID(projectID string) ([]*model.ProjectRoleView, error) {
|
||||
|
@ -1,36 +0,0 @@
|
||||
package eventstore
|
||||
|
||||
import (
|
||||
auth_model "github.com/caos/zitadel/internal/auth/model"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
type Register struct {
|
||||
*model.Org
|
||||
*usr_es.User
|
||||
}
|
||||
|
||||
func (r *Register) AppendEvents(events ...*es_models.Event) error {
|
||||
for _, event := range events {
|
||||
var err error
|
||||
switch event.AggregateType {
|
||||
case model.OrgAggregate:
|
||||
err = r.Org.AppendEvent(event)
|
||||
case usr_es.UserAggregate:
|
||||
err = r.User.AppendEvent(event)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RegisterToModel(register *Register) *auth_model.RegisterOrg {
|
||||
return &auth_model.RegisterOrg{
|
||||
Org: model.OrgToModel(register.Org),
|
||||
User: usr_es.UserToModel(register.User),
|
||||
}
|
||||
}
|
@ -4,21 +4,22 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
usr_view "github.com/caos/zitadel/internal/user/repository/view"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
user_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
type TokenRepo struct {
|
||||
UserEvents *user_event.UserEventstore
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
View *view.View
|
||||
Eventstore eventstore.Eventstore
|
||||
View *view.View
|
||||
}
|
||||
|
||||
func (repo *TokenRepo) IsTokenValid(ctx context.Context, userID, tokenID string) (bool, error) {
|
||||
@ -43,7 +44,7 @@ func (repo *TokenRepo) TokenByID(ctx context.Context, userID, tokenID string) (*
|
||||
token.UserID = userID
|
||||
}
|
||||
|
||||
events, esErr := repo.UserEvents.UserEventsByID(ctx, userID, token.Sequence)
|
||||
events, esErr := repo.getUserEvents(ctx, userID, token.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-4T90g", "Errors.Token.NotFound")
|
||||
}
|
||||
@ -65,11 +66,10 @@ func (repo *TokenRepo) TokenByID(ctx context.Context, userID, tokenID string) (*
|
||||
return model.TokenViewToModel(token), nil
|
||||
}
|
||||
|
||||
func AppendAudIfNotExisting(aud string, existingAud []string) []string {
|
||||
for _, a := range existingAud {
|
||||
if a == aud {
|
||||
return existingAud
|
||||
}
|
||||
func (r *TokenRepo) getUserEvents(ctx context.Context, userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := usr_view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append(existingAud, aud)
|
||||
return r.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
key_model "github.com/caos/zitadel/internal/key/model"
|
||||
@ -12,25 +14,23 @@ import (
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
key_view_model "github.com/caos/zitadel/internal/key/repository/view/model"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
"github.com/caos/zitadel/internal/user/model"
|
||||
user_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_view "github.com/caos/zitadel/internal/user/repository/view"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
type UserRepo struct {
|
||||
SearchLimit uint64
|
||||
Eventstore eventstore.Eventstore
|
||||
UserEvents *user_event.UserEventstore
|
||||
OrgEvents *org_event.OrgEventstore
|
||||
View *view.View
|
||||
SystemDefaults systemdefaults.SystemDefaults
|
||||
}
|
||||
|
||||
func (repo *UserRepo) Health(ctx context.Context) error {
|
||||
return repo.UserEvents.Health(ctx)
|
||||
return repo.Eventstore.Health(ctx)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) MyUser(ctx context.Context) (*model.UserView, error) {
|
||||
@ -118,12 +118,15 @@ func (repo *UserRepo) MyUserMFAs(ctx context.Context) ([]*model.MultiFactor, err
|
||||
return mfas, nil
|
||||
}
|
||||
|
||||
func (repo *UserRepo) GetPasswordless(ctx context.Context, userID string) ([]*model.WebAuthNToken, error) {
|
||||
return repo.UserEvents.GetPasswordless(ctx, userID)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) GetMyPasswordless(ctx context.Context) ([]*model.WebAuthNToken, error) {
|
||||
return repo.UserEvents.GetPasswordless(ctx, authz.GetCtxData(ctx).UserID)
|
||||
func (repo *UserRepo) GetMyPasswordless(ctx context.Context) ([]*model.WebAuthNView, error) {
|
||||
user, err := repo.UserByID(ctx, authz.GetCtxData(ctx).UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user.HumanView == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "USER-9kF98", "Errors.User.NotHuman")
|
||||
}
|
||||
return user.HumanView.PasswordlessTokens, nil
|
||||
}
|
||||
|
||||
func (repo *UserRepo) UserSessionUserIDsByAgentID(ctx context.Context, agentID string) ([]string, error) {
|
||||
@ -143,7 +146,7 @@ func (repo *UserRepo) UserByID(ctx context.Context, id string) (*model.UserView,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
events, err := repo.UserEvents.UserEventsByID(ctx, id, user.Sequence)
|
||||
events, err := repo.getUserEvents(ctx, id, user.Sequence)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-PSoc3").WithError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("error retrieving new events")
|
||||
return usr_view_model.UserToModel(user), nil
|
||||
@ -160,12 +163,16 @@ func (repo *UserRepo) UserByID(ctx context.Context, id string) (*model.UserView,
|
||||
return usr_view_model.UserToModel(&userCopy), nil
|
||||
}
|
||||
|
||||
func (repo *UserRepo) UserEventsByID(ctx context.Context, id string, sequence uint64) ([]*es_models.Event, error) {
|
||||
return repo.getUserEvents(ctx, id, sequence)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) UserByLoginName(ctx context.Context, loginname string) (*model.UserView, error) {
|
||||
user, err := repo.View.UserByLoginName(loginname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
events, err := repo.UserEvents.UserEventsByID(ctx, user.ID, user.Sequence)
|
||||
events, err := repo.getUserEvents(ctx, user.ID, user.Sequence)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-PSoc3").WithError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("error retrieving new events")
|
||||
return usr_view_model.UserToModel(user), nil
|
||||
@ -182,19 +189,19 @@ func (repo *UserRepo) UserByLoginName(ctx context.Context, loginname string) (*m
|
||||
return usr_view_model.UserToModel(&userCopy), nil
|
||||
}
|
||||
func (repo *UserRepo) MyUserChanges(ctx context.Context, lastSequence uint64, limit uint64, sortAscending bool) (*model.UserChanges, error) {
|
||||
changes, err := repo.UserEvents.UserChanges(ctx, authz.GetCtxData(ctx).UserID, lastSequence, limit, sortAscending)
|
||||
changes, err := repo.getUserChanges(ctx, authz.GetCtxData(ctx).UserID, lastSequence, limit, sortAscending)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, change := range changes.Changes {
|
||||
change.ModifierName = change.ModifierID
|
||||
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierID)
|
||||
user, _ := repo.UserByID(ctx, change.ModifierID)
|
||||
if user != nil {
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
change.ModifierName = user.DisplayName
|
||||
}
|
||||
if user.Machine != nil {
|
||||
change.ModifierName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
change.ModifierName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -208,3 +215,55 @@ func (repo *UserRepo) MachineKeyByID(ctx context.Context, keyID string) (*key_mo
|
||||
}
|
||||
return key_view_model.AuthNKeyToModel(key), nil
|
||||
}
|
||||
|
||||
func (r *UserRepo) getUserChanges(ctx context.Context, userID string, lastSequence uint64, limit uint64, sortAscending bool) (*model.UserChanges, error) {
|
||||
query := usr_view.ChangesQuery(userID, lastSequence, limit, sortAscending)
|
||||
|
||||
events, err := r.Eventstore.FilterEvents(ctx, query)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-g9HCv").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, errors.ThrowInternal(err, "EVENT-htuG9", "Errors.Internal")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-6cAxe", "Errors.User.NoChanges")
|
||||
}
|
||||
|
||||
result := make([]*model.UserChange, len(events))
|
||||
|
||||
for i, event := range events {
|
||||
creationDate, err := ptypes.TimestampProto(event.CreationDate)
|
||||
logging.Log("EVENT-8GTGS").OnError(err).Debug("unable to parse timestamp")
|
||||
change := &model.UserChange{
|
||||
ChangeDate: creationDate,
|
||||
EventType: event.Type.String(),
|
||||
ModifierID: event.EditorUser,
|
||||
Sequence: event.Sequence,
|
||||
}
|
||||
|
||||
//TODO: now all types should be unmarshalled, e.g. password
|
||||
// if len(event.Data) != 0 {
|
||||
// user := new(model.User)
|
||||
// err := json.Unmarshal(event.Data, user)
|
||||
// logging.Log("EVENT-Rkg7X").OnError(err).Debug("unable to unmarshal data")
|
||||
// change.Data = user
|
||||
// }
|
||||
|
||||
result[i] = change
|
||||
if lastSequence < event.Sequence {
|
||||
lastSequence = event.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
return &model.UserChanges{
|
||||
Changes: result,
|
||||
LastSequence: lastSequence,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *UserRepo) getUserEvents(ctx context.Context, userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := usr_view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
@ -5,13 +5,15 @@ import (
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
)
|
||||
|
||||
@ -21,14 +23,12 @@ const (
|
||||
|
||||
type Application struct {
|
||||
handler
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newApplication(handler handler, projectEvents *proj_event.ProjectEventstore) *Application {
|
||||
func newApplication(handler handler) *Application {
|
||||
h := &Application{
|
||||
handler: handler,
|
||||
projectEvents: projectEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -66,14 +66,14 @@ func (a *Application) EventQuery() (*models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eventsourcing.ProjectQuery(sequence.CurrentSequence), nil
|
||||
return proj_view.ProjectQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (a *Application) Reduce(event *models.Event) (err error) {
|
||||
app := new(view_model.ApplicationView)
|
||||
switch event.Type {
|
||||
case es_model.ApplicationAdded:
|
||||
project, err := a.projectEvents.ProjectByID(context.Background(), event.AggregateID)
|
||||
project, err := a.getProjectByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -139,3 +139,24 @@ func (a *Application) OnError(event *models.Event, spoolerError error) error {
|
||||
func (a *Application) OnSuccess() error {
|
||||
return spooler.HandleSuccess(a.view.UpdateApplicationSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (a *Application) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(projID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esProject := &es_model.Project{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: projID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, a.Eventstore().FilterEvents, esProject.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esProject.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-DBf32", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return es_model.ProjectToModel(esProject), nil
|
||||
}
|
||||
|
@ -3,16 +3,11 @@ package handler
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
sd "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_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/config/types"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Configs map[string]*Config
|
||||
@ -34,42 +29,24 @@ func (h *handler) Eventstore() eventstore.Eventstore {
|
||||
return h.es
|
||||
}
|
||||
|
||||
type EventstoreRepos struct {
|
||||
UserEvents *usr_event.UserEventstore
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
OrgEvents *org_events.OrgEventstore
|
||||
IamEvents *iam_events.IAMEventstore
|
||||
}
|
||||
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, repos EventstoreRepos, systemDefaults sd.SystemDefaults) []query.Handler {
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, systemDefaults sd.SystemDefaults) []query.Handler {
|
||||
return []query.Handler{
|
||||
newUser(
|
||||
handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es},
|
||||
repos.OrgEvents,
|
||||
repos.IamEvents,
|
||||
systemDefaults.IamID),
|
||||
newUserSession(
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserSession"), errorCount, es},
|
||||
repos.UserEvents),
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserSession"), errorCount, es}),
|
||||
newUserMembership(
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserMembership"), errorCount, es},
|
||||
repos.OrgEvents,
|
||||
repos.ProjectEvents),
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserMembership"), errorCount, es}),
|
||||
newToken(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Token"), errorCount, es},
|
||||
repos.ProjectEvents),
|
||||
handler{view, bulkLimit, configs.cycleDuration("Token"), errorCount, es}),
|
||||
newKey(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Key"), errorCount, es}),
|
||||
newApplication(handler{view, bulkLimit, configs.cycleDuration("Application"), errorCount, es},
|
||||
repos.ProjectEvents),
|
||||
newApplication(handler{view, bulkLimit, configs.cycleDuration("Application"), errorCount, es}),
|
||||
newOrg(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Org"), errorCount, es}),
|
||||
newUserGrant(
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserGrant"), errorCount, es},
|
||||
repos.ProjectEvents,
|
||||
repos.UserEvents,
|
||||
repos.OrgEvents,
|
||||
repos.IamEvents,
|
||||
systemDefaults.IamID),
|
||||
newAuthNKeys(
|
||||
handler{view, bulkLimit, configs.cycleDuration("MachineKey"), errorCount, es}),
|
||||
@ -79,20 +56,15 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
handler{view, bulkLimit, configs.cycleDuration("IDPConfig"), errorCount, es}),
|
||||
newIDPProvider(
|
||||
handler{view, bulkLimit, configs.cycleDuration("IDPProvider"), errorCount, es},
|
||||
systemDefaults,
|
||||
repos.IamEvents,
|
||||
repos.OrgEvents),
|
||||
systemDefaults),
|
||||
newExternalIDP(
|
||||
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
||||
systemDefaults,
|
||||
repos.IamEvents,
|
||||
repos.OrgEvents),
|
||||
systemDefaults),
|
||||
newPasswordComplexityPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("PasswordComplexityPolicy"), errorCount, es}),
|
||||
newOrgIAMPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("OrgIAMPolicy"), errorCount, es}),
|
||||
newProjectRole(handler{view, bulkLimit, configs.cycleDuration("ProjectRole"), errorCount, es},
|
||||
repos.ProjectEvents),
|
||||
newProjectRole(handler{view, bulkLimit, configs.cycleDuration("ProjectRole"), errorCount, es}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,16 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
@ -26,22 +30,16 @@ const (
|
||||
type IDPProvider struct {
|
||||
handler
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
iamEvents *eventsourcing.IAMEventstore
|
||||
orgEvents *org_es.OrgEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newIDPProvider(
|
||||
h handler,
|
||||
defaults systemdefaults.SystemDefaults,
|
||||
iamEvents *eventsourcing.IAMEventstore,
|
||||
orgEvents *org_es.OrgEventstore,
|
||||
) *IDPProvider {
|
||||
idpProvider := &IDPProvider{
|
||||
handler: h,
|
||||
systemDefaults: defaults,
|
||||
iamEvents: iamEvents,
|
||||
orgEvents: orgEvents,
|
||||
}
|
||||
|
||||
idpProvider.subscribe()
|
||||
@ -121,9 +119,9 @@ func (i *IDPProvider) processIdpProvider(event *models.Event) (err error) {
|
||||
}
|
||||
config := new(iam_model.IDPConfig)
|
||||
if event.AggregateID == i.systemDefaults.IamID {
|
||||
config, err = i.iamEvents.GetIDPConfig(context.Background(), event.AggregateID, esConfig.IDPConfigID)
|
||||
config, err = i.getDefaultIDPConfig(context.TODO(), esConfig.IDPConfigID)
|
||||
} else {
|
||||
config, err = i.orgEvents.GetIDPConfig(context.Background(), event.AggregateID, esConfig.IDPConfigID)
|
||||
config, err = i.getOrgIDPConfig(context.TODO(), event.AggregateID, esConfig.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -146,9 +144,9 @@ func (i *IDPProvider) processIdpProvider(event *models.Event) (err error) {
|
||||
func (i *IDPProvider) fillData(provider *iam_view_model.IDPProviderView) (err error) {
|
||||
var config *iam_model.IDPConfig
|
||||
if provider.IDPProviderType == int32(iam_model.IDPProviderTypeSystem) {
|
||||
config, err = i.iamEvents.GetIDPConfig(context.Background(), i.systemDefaults.IamID, provider.IDPConfigID)
|
||||
config, err = i.getDefaultIDPConfig(context.Background(), provider.IDPConfigID)
|
||||
} else {
|
||||
config, err = i.orgEvents.GetIDPConfig(context.Background(), provider.AggregateID, provider.IDPConfigID)
|
||||
config, err = i.getOrgIDPConfig(context.Background(), provider.AggregateID, provider.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -172,3 +170,64 @@ func (i *IDPProvider) OnError(event *models.Event, err error) error {
|
||||
func (i *IDPProvider) OnSuccess() error {
|
||||
return spooler.HandleSuccess(i.view.UpdateIDPProviderSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (i *IDPProvider) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := i.getOrgByID(ctx, aggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, i := existing.GetIDP(idpConfigID); i != nil {
|
||||
return i, nil
|
||||
}
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-2m9fS", "Errors.Org.IdpNotExisting")
|
||||
}
|
||||
|
||||
func (i *IDPProvider) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-6m0fS", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *IDPProvider) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *IDPProvider) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil {
|
||||
return existingIDP, nil
|
||||
}
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-49O0f", "Errors.IAM.IdpNotExisting")
|
||||
}
|
||||
|
@ -2,12 +2,12 @@ package handler
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
)
|
||||
@ -61,7 +61,7 @@ func (o *Org) EventQuery() (*es_models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eventsourcing.OrgQuery(sequence.CurrentSequence), nil
|
||||
return view.OrgQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (o *Org) Reduce(event *es_models.Event) (err error) {
|
||||
|
@ -7,9 +7,8 @@ import (
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_events "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
)
|
||||
|
||||
@ -19,17 +18,14 @@ const (
|
||||
|
||||
type ProjectRole struct {
|
||||
handler
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newProjectRole(
|
||||
handler handler,
|
||||
projectEvents *proj_events.ProjectEventstore,
|
||||
) *ProjectRole {
|
||||
h := &ProjectRole{
|
||||
handler: handler,
|
||||
projectEvents: projectEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -67,7 +63,7 @@ func (p *ProjectRole) EventQuery() (*es_models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proj_events.ProjectQuery(sequence.CurrentSequence), nil
|
||||
return proj_view.ProjectQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (p *ProjectRole) Reduce(event *es_models.Event) (err error) {
|
||||
|
@ -5,15 +5,18 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
project_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
user_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
@ -24,17 +27,14 @@ const (
|
||||
|
||||
type Token struct {
|
||||
handler
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newToken(
|
||||
handler handler,
|
||||
projectEvents *proj_event.ProjectEventstore,
|
||||
) *Token {
|
||||
h := &Token{
|
||||
handler: handler,
|
||||
ProjectEvents: projectEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -118,7 +118,7 @@ func (t *Token) Reduce(event *models.Event) (err error) {
|
||||
return t.view.DeleteApplicationTokens(event, application.AppID)
|
||||
case project_es_model.ProjectDeactivated,
|
||||
project_es_model.ProjectRemoved:
|
||||
project, err := t.ProjectEvents.ProjectByID(context.Background(), event.AggregateID)
|
||||
project, err := t.getProjectByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -158,3 +158,24 @@ func applicationFromSession(event *models.Event) (*project_es_model.Application,
|
||||
func (t *Token) OnSuccess() error {
|
||||
return spooler.HandleSuccess(t.view.UpdateTokenSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (t *Token) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(projID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esProject := &project_es_model.Project{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: projID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, t.Eventstore().FilterEvents, esProject.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esProject.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-Dsdw2", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return project_es_model.ProjectToModel(esProject), nil
|
||||
}
|
||||
|
@ -2,19 +2,23 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_es "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -23,23 +27,17 @@ const (
|
||||
|
||||
type User struct {
|
||||
handler
|
||||
orgEvents *org_events.OrgEventstore
|
||||
iamEvents *iam_es.IAMEventstore
|
||||
iamID string
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newUser(
|
||||
handler handler,
|
||||
orgEvents *org_events.OrgEventstore,
|
||||
iamEvents *iam_es.IAMEventstore,
|
||||
iamID string,
|
||||
) *User {
|
||||
h := &User{
|
||||
handler: handler,
|
||||
orgEvents: orgEvents,
|
||||
iamEvents: iamEvents,
|
||||
iamID: iamID,
|
||||
handler: handler,
|
||||
iamID: iamID,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -169,13 +167,13 @@ func (u *User) ProcessUser(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (u *User) fillLoginNames(user *view_model.UserView) (err error) {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(user.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.iamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -201,13 +199,13 @@ func (u *User) ProcessOrg(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (u *User) fillLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.iamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -223,13 +221,13 @@ func (u *User) fillLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
}
|
||||
|
||||
func (u *User) fillPreferredLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.iamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -255,3 +253,53 @@ func (u *User) OnError(event *models.Event, err error) error {
|
||||
func (u *User) OnSuccess() error {
|
||||
return spooler.HandleSuccess(u.view.UpdateUserSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *User) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3m9vs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *User) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *User) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3m9fs", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
@ -10,15 +9,18 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -28,22 +30,16 @@ const (
|
||||
type ExternalIDP struct {
|
||||
handler
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
iamEvents *eventsourcing.IAMEventstore
|
||||
orgEvents *org_es.OrgEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newExternalIDP(
|
||||
handler handler,
|
||||
defaults systemdefaults.SystemDefaults,
|
||||
iamEvents *eventsourcing.IAMEventstore,
|
||||
orgEvents *org_es.OrgEventstore,
|
||||
) *ExternalIDP {
|
||||
h := &ExternalIDP{
|
||||
handler: handler,
|
||||
systemDefaults: defaults,
|
||||
iamEvents: iamEvents,
|
||||
orgEvents: orgEvents,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -137,9 +133,9 @@ func (i *ExternalIDP) processIdpConfig(event *models.Event) (err error) {
|
||||
return err
|
||||
}
|
||||
if event.AggregateType == iam_es_model.IAMAggregate {
|
||||
config, err = i.iamEvents.GetIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID)
|
||||
config, err = i.getDefaultIDPConfig(context.Background(), configView.IDPConfigID)
|
||||
} else {
|
||||
config, err = i.orgEvents.GetIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID)
|
||||
config, err = i.getOrgIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -155,9 +151,9 @@ func (i *ExternalIDP) processIdpConfig(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) fillData(externalIDP *usr_view_model.ExternalIDPView) error {
|
||||
config, err := i.orgEvents.GetIDPConfig(context.Background(), externalIDP.ResourceOwner, externalIDP.IDPConfigID)
|
||||
config, err := i.getOrgIDPConfig(context.Background(), externalIDP.ResourceOwner, externalIDP.IDPConfigID)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
config, err = i.iamEvents.GetIDPConfig(context.Background(), i.systemDefaults.IamID, externalIDP.IDPConfigID)
|
||||
config, err = i.getDefaultIDPConfig(context.Background(), externalIDP.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -178,3 +174,64 @@ func (i *ExternalIDP) OnError(event *models.Event, err error) error {
|
||||
func (i *ExternalIDP) OnSuccess() error {
|
||||
return spooler.HandleSuccess(i.view.UpdateExternalIDPSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := i.getOrgByID(ctx, aggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, i := existing.GetIDP(idpConfigID); i != nil {
|
||||
return i, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2m9fS", "Errors.Org.IdpNotExisting")
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-6m0fS", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *ExternalIDP) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *ExternalIDP) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil {
|
||||
return existingIDP, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-mmk5d", "Errors.IAM.IdpNotExisting")
|
||||
}
|
||||
|
@ -2,8 +2,16 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"strings"
|
||||
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
@ -13,16 +21,12 @@ import (
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_events "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
grant_es_model "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||
@ -35,30 +39,18 @@ const (
|
||||
|
||||
type UserGrant struct {
|
||||
handler
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
userEvents *usr_events.UserEventstore
|
||||
orgEvents *org_events.OrgEventstore
|
||||
iamEvents *iam_events.IAMEventstore
|
||||
iamID string
|
||||
iamProjectID string
|
||||
subscription *eventstore.Subscription
|
||||
iamID string
|
||||
iamProjectID string
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newUserGrant(
|
||||
handler handler,
|
||||
projectEvents *proj_event.ProjectEventstore,
|
||||
userEvents *usr_events.UserEventstore,
|
||||
orgEvents *org_events.OrgEventstore,
|
||||
iamEvents *iam_events.IAMEventstore,
|
||||
iamID string,
|
||||
) *UserGrant {
|
||||
h := &UserGrant{
|
||||
handler: handler,
|
||||
projectEvents: projectEvents,
|
||||
userEvents: userEvents,
|
||||
orgEvents: orgEvents,
|
||||
iamEvents: iamEvents,
|
||||
iamID: iamID,
|
||||
handler: handler,
|
||||
iamID: iamID,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -166,7 +158,7 @@ func (u *UserGrant) processUser(event *models.Event) (err error) {
|
||||
if len(grants) == 0 {
|
||||
return u.view.ProcessedUserGrantSequence(event)
|
||||
}
|
||||
user, err := u.userEvents.UserByID(context.Background(), event.AggregateID)
|
||||
user, err := u.getUserByID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -186,7 +178,7 @@ func (u *UserGrant) processProject(event *models.Event) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
project, err := u.projectEvents.ProjectByID(context.Background(), event.AggregateID)
|
||||
project, err := u.getProjectByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -348,7 +340,7 @@ func (u *UserGrant) setIamProjectID() error {
|
||||
if u.iamProjectID != "" {
|
||||
return nil
|
||||
}
|
||||
iam, err := u.iamEvents.IAMByID(context.Background(), u.iamID)
|
||||
iam, err := u.getIAMByID(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -361,18 +353,18 @@ func (u *UserGrant) setIamProjectID() error {
|
||||
}
|
||||
|
||||
func (u *UserGrant) fillData(grant *view_model.UserGrantView, resourceOwner string) (err error) {
|
||||
user, err := u.userEvents.UserByID(context.Background(), grant.UserID)
|
||||
user, err := u.getUserByID(grant.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.fillUserData(grant, user)
|
||||
project, err := u.projectEvents.ProjectByID(context.Background(), grant.ProjectID)
|
||||
project, err := u.getProjectByID(context.Background(), grant.ProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.fillProjectData(grant, project)
|
||||
|
||||
org, err := u.orgEvents.OrgByID(context.TODO(), org_model.NewOrg(resourceOwner))
|
||||
org, err := u.getOrgByID(context.TODO(), resourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -380,16 +372,16 @@ func (u *UserGrant) fillData(grant *view_model.UserGrantView, resourceOwner stri
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserGrant) fillUserData(grant *view_model.UserGrantView, user *usr_model.User) {
|
||||
func (u *UserGrant) fillUserData(grant *view_model.UserGrantView, user *model.UserView) {
|
||||
grant.UserName = user.UserName
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
grant.FirstName = user.FirstName
|
||||
grant.LastName = user.LastName
|
||||
grant.DisplayName = user.FirstName + " " + user.LastName
|
||||
grant.Email = user.EmailAddress
|
||||
grant.Email = user.Email
|
||||
}
|
||||
if user.Machine != nil {
|
||||
grant.DisplayName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
grant.DisplayName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
|
||||
@ -416,3 +408,96 @@ func (u *UserGrant) OnError(event *models.Event, err error) error {
|
||||
func (u *UserGrant) OnSuccess() error {
|
||||
return spooler.HandleSuccess(u.view.UpdateUserGrantSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *UserGrant) getUserByID(userID string) (*model.UserView, error) {
|
||||
user, usrErr := u.view.UserByID(userID)
|
||||
if usrErr != nil && !caos_errs.IsNotFound(usrErr) {
|
||||
return nil, usrErr
|
||||
}
|
||||
if user == nil {
|
||||
user = &model.UserView{}
|
||||
}
|
||||
events, err := u.getUserEvents(userID, user.Sequence)
|
||||
if err != nil {
|
||||
return user, usrErr
|
||||
}
|
||||
userCopy := *user
|
||||
for _, event := range events {
|
||||
if err := userCopy.AppendEvent(event); err != nil {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
if userCopy.State == int32(usr_model.UserStateDeleted) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "HANDLER-m9dos", "Errors.User.NotFound")
|
||||
}
|
||||
return &userCopy, nil
|
||||
}
|
||||
|
||||
func (u *UserGrant) getUserEvents(userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return u.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
||||
func (u *UserGrant) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3m9vs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *UserGrant) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(projID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esProject := &proj_es_model.Project{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: projID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esProject.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esProject.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-DAfng", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return proj_es_model.ProjectToModel(esProject), nil
|
||||
}
|
||||
|
||||
func (u *UserGrant) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
@ -4,17 +4,21 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@ -26,20 +30,14 @@ const (
|
||||
|
||||
type UserMembership struct {
|
||||
handler
|
||||
orgEvents *org_event.OrgEventstore
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newUserMembership(
|
||||
handler handler,
|
||||
orgEvents *org_event.OrgEventstore,
|
||||
projectEvents *proj_event.ProjectEventstore,
|
||||
) *UserMembership {
|
||||
h := &UserMembership{
|
||||
handler: handler,
|
||||
orgEvents: orgEvents,
|
||||
projectEvents: projectEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -156,7 +154,7 @@ func (m *UserMembership) processOrg(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *UserMembership) fillOrgName(member *usr_es_model.UserMembershipView) (err error) {
|
||||
org, err := m.orgEvents.OrgByID(context.Background(), org_model.NewOrg(member.ResourceOwner))
|
||||
org, err := m.getOrgByID(context.Background(), member.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -168,7 +166,7 @@ func (m *UserMembership) fillOrgName(member *usr_es_model.UserMembershipView) (e
|
||||
}
|
||||
|
||||
func (m *UserMembership) updateOrgName(event *models.Event) error {
|
||||
org, err := m.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.AggregateID))
|
||||
org, err := m.getOrgByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -231,7 +229,7 @@ func (m *UserMembership) processProject(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembershipView) (err error) {
|
||||
project, err := m.projectEvents.ProjectByID(context.Background(), member.AggregateID)
|
||||
project, err := m.getProjectByID(context.Background(), member.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -240,7 +238,7 @@ func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembers
|
||||
}
|
||||
|
||||
func (m *UserMembership) updateProjectDisplayName(event *models.Event) error {
|
||||
project, err := m.projectEvents.ProjectByID(context.Background(), event.AggregateID)
|
||||
project, err := m.getProjectByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -272,3 +270,45 @@ func (m *UserMembership) OnError(event *models.Event, err error) error {
|
||||
func (m *UserMembership) OnSuccess() error {
|
||||
return spooler.HandleSuccess(m.view.UpdateUserMembershipSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *UserMembership) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3m9vs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *UserMembership) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(projID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esProject := &proj_es_model.Project{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: projID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esProject.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esProject.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-Dbfw2", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return proj_es_model.ProjectToModel(esProject), nil
|
||||
}
|
||||
|
@ -8,9 +8,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
user_events "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
@ -20,17 +19,14 @@ const (
|
||||
|
||||
type UserSession struct {
|
||||
handler
|
||||
userEvents *user_events.UserEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newUserSession(
|
||||
handler handler,
|
||||
userEvents *user_events.UserEventstore,
|
||||
) *UserSession {
|
||||
h := &UserSession{
|
||||
handler: handler,
|
||||
userEvents: userEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -68,7 +64,7 @@ func (u *UserSession) EventQuery() (*models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eventsourcing.UserQuery(sequence.CurrentSequence), nil
|
||||
return view.UserQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (u *UserSession) Reduce(event *models.Event) (err error) {
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/eventstore"
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/handler"
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing/spooler"
|
||||
auth_view "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/auth_request/repository/cache"
|
||||
@ -15,11 +14,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
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/id"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_user "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
)
|
||||
@ -34,7 +29,8 @@ type Config struct {
|
||||
}
|
||||
|
||||
type EsRepository struct {
|
||||
spooler *es_spol.Spooler
|
||||
spooler *es_spol.Spooler
|
||||
Eventstore es_int.Eventstore
|
||||
eventstore.UserRepo
|
||||
eventstore.AuthRequestRepo
|
||||
eventstore.TokenRepo
|
||||
@ -69,73 +65,36 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, err := es_user.StartUser(
|
||||
es_user.UserConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
},
|
||||
systemDefaults,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authReq, err := cache.Start(conf.AuthRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iam, err := es_iam.StartIAM(
|
||||
es_iam.IAMConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
},
|
||||
systemDefaults,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
project, err := es_proj.StartProject(
|
||||
es_proj.ProjectConfig{
|
||||
Cache: conf.Eventstore.Cache,
|
||||
Eventstore: es,
|
||||
},
|
||||
systemDefaults,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamV2Query, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults)
|
||||
|
||||
repos := handler.EventstoreRepos{UserEvents: user, ProjectEvents: project, OrgEvents: org, IamEvents: iam}
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, repos, systemDefaults)
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults)
|
||||
|
||||
userRepo := eventstore.UserRepo{
|
||||
SearchLimit: conf.SearchLimit,
|
||||
Eventstore: es,
|
||||
View: view,
|
||||
SystemDefaults: systemDefaults,
|
||||
}
|
||||
return &EsRepository{
|
||||
spool,
|
||||
eventstore.UserRepo{
|
||||
SearchLimit: conf.SearchLimit,
|
||||
Eventstore: es,
|
||||
UserEvents: user,
|
||||
OrgEvents: org,
|
||||
View: view,
|
||||
SystemDefaults: systemDefaults,
|
||||
},
|
||||
es,
|
||||
userRepo,
|
||||
eventstore.AuthRequestRepo{
|
||||
Command: command,
|
||||
UserEvents: user,
|
||||
OrgEvents: org,
|
||||
AuthRequests: authReq,
|
||||
View: view,
|
||||
UserSessionViewProvider: view,
|
||||
UserViewProvider: view,
|
||||
UserCommandProvider: command,
|
||||
UserEventProvider: user,
|
||||
UserEventProvider: &userRepo,
|
||||
OrgViewProvider: view,
|
||||
IDPProviderViewProvider: view,
|
||||
LoginPolicyViewProvider: view,
|
||||
@ -149,18 +108,16 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
|
||||
IAMID: systemDefaults.IamID,
|
||||
},
|
||||
eventstore.TokenRepo{
|
||||
UserEvents: user,
|
||||
ProjectEvents: project,
|
||||
View: view,
|
||||
Eventstore: es,
|
||||
View: view,
|
||||
},
|
||||
eventstore.KeyRepository{
|
||||
View: view,
|
||||
SigningKeyRotation: systemDefaults.KeyConfig.SigningKeyRotation.Duration,
|
||||
},
|
||||
eventstore.ApplicationRepo{
|
||||
Commands: command,
|
||||
View: view,
|
||||
ProjectEvents: project,
|
||||
Commands: command,
|
||||
View: view,
|
||||
},
|
||||
|
||||
eventstore.UserSessionRepo{
|
||||
@ -176,8 +133,6 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co
|
||||
eventstore.OrgRepository{
|
||||
SearchLimit: conf.SearchLimit,
|
||||
View: view,
|
||||
OrgEventstore: org,
|
||||
UserEventstore: user,
|
||||
SystemDefaults: systemDefaults,
|
||||
},
|
||||
eventstore.IAMRepository{
|
||||
|
@ -19,12 +19,12 @@ type SpoolerConfig struct {
|
||||
Handlers handler.Configs
|
||||
}
|
||||
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, client *sql.DB, repos handler.EventstoreRepos, systemDefaults sd.SystemDefaults) *spooler.Spooler {
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, client *sql.DB, systemDefaults sd.SystemDefaults) *spooler.Spooler {
|
||||
spoolerConfig := spooler.Config{
|
||||
Eventstore: es,
|
||||
Locker: &locker{dbClient: client},
|
||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, repos, systemDefaults),
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, systemDefaults),
|
||||
}
|
||||
spool := spoolerConfig.New()
|
||||
spool.Start()
|
||||
|
@ -11,8 +11,6 @@ import (
|
||||
type UserRepository interface {
|
||||
myUserRepo
|
||||
|
||||
GetPasswordless(ctx context.Context, id string) ([]*model.WebAuthNToken, error)
|
||||
|
||||
UserSessionUserIDsByAgentID(ctx context.Context, agentID string) ([]string, error)
|
||||
|
||||
UserByID(ctx context.Context, userID string) (*model.UserView, error)
|
||||
@ -36,7 +34,7 @@ type myUserRepo interface {
|
||||
|
||||
MyUserMFAs(ctx context.Context) ([]*model.MultiFactor, error)
|
||||
|
||||
GetMyPasswordless(ctx context.Context) ([]*model.WebAuthNToken, error)
|
||||
GetMyPasswordless(ctx context.Context) ([]*model.WebAuthNView, error)
|
||||
|
||||
MyUserChanges(ctx context.Context, lastSequence uint64, limit uint64, sortAscending bool) (*model.UserChanges, error)
|
||||
|
||||
|
@ -5,18 +5,16 @@ import (
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type IamRepo struct {
|
||||
IAMID string
|
||||
IAMEvents *iam_event.IAMEventstore
|
||||
IAMID string
|
||||
|
||||
IAMV2Query *query.QuerySide
|
||||
}
|
||||
|
||||
func (repo *IamRepo) Health(ctx context.Context) error {
|
||||
return repo.IAMEvents.Health(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *IamRepo) IamByID(ctx context.Context) (*model.IAM, error) {
|
||||
|
@ -2,28 +2,33 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
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"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
usr_view "github.com/caos/zitadel/internal/user/repository/view"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/view"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
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"
|
||||
)
|
||||
|
||||
type TokenVerifierRepo struct {
|
||||
TokenVerificationKey [32]byte
|
||||
IAMID string
|
||||
IAMEvents *iam_event.IAMEventstore
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
UserEvents *usr_event.UserEventstore
|
||||
Eventstore eventstore.Eventstore
|
||||
View *view.View
|
||||
}
|
||||
|
||||
@ -38,7 +43,7 @@ func (repo *TokenVerifierRepo) TokenByID(ctx context.Context, tokenID, userID st
|
||||
token.UserID = userID
|
||||
}
|
||||
|
||||
events, esErr := repo.UserEvents.UserEventsByID(ctx, userID, token.Sequence)
|
||||
events, esErr := repo.getUserEvents(ctx, userID, token.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-4T90g", "Errors.Token.NotFound")
|
||||
}
|
||||
@ -110,7 +115,7 @@ func (repo *TokenVerifierRepo) VerifierClientID(ctx context.Context, appName str
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
iam, err := repo.IAMEvents.IAMByID(ctx, repo.IAMID)
|
||||
iam, err := repo.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -120,3 +125,28 @@ func (repo *TokenVerifierRepo) VerifierClientID(ctx context.Context, appName str
|
||||
}
|
||||
return app.OIDCClientID, nil
|
||||
}
|
||||
|
||||
func (r *TokenVerifierRepo) getUserEvents(ctx context.Context, userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := usr_view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (u *TokenVerifierRepo) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore.FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
@ -2,11 +2,17 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"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"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/view"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
global_model "github.com/caos/zitadel/internal/model"
|
||||
user_model "github.com/caos/zitadel/internal/user/model"
|
||||
user_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@ -19,7 +25,7 @@ type UserGrantRepo struct {
|
||||
IamID string
|
||||
IamProjectID string
|
||||
Auth authz.Config
|
||||
IamEvents *iam_event.IAMEventstore
|
||||
Eventstore eventstore.Eventstore
|
||||
}
|
||||
|
||||
func (repo *UserGrantRepo) Health() error {
|
||||
@ -94,7 +100,7 @@ func (repo *UserGrantRepo) FillIamProjectID(ctx context.Context) error {
|
||||
if repo.IamProjectID != "" {
|
||||
return nil
|
||||
}
|
||||
iam, err := repo.IamEvents.IAMByID(ctx, repo.IamID)
|
||||
iam, err := repo.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -118,6 +124,23 @@ func (repo *UserGrantRepo) mapRoleToPermission(permissions *grant_model.Permissi
|
||||
return permissions
|
||||
}
|
||||
|
||||
func (u *UserGrantRepo) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore.FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func userMembershipToMembership(membership *user_view_model.UserMembershipView) *authz.Membership {
|
||||
return &authz.Membership{
|
||||
MemberType: authz.MemberType(membership.MemberType),
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/project/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
)
|
||||
|
||||
@ -61,7 +61,7 @@ func (a *Application) EventQuery() (*models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eventsourcing.ProjectQuery(sequence.CurrentSequence), nil
|
||||
return view.ProjectQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (a *Application) Reduce(event *models.Event) (err error) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/view"
|
||||
@ -9,8 +8,6 @@ import (
|
||||
"github.com/caos/zitadel/internal/config/types"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
project_events "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Configs map[string]*Config
|
||||
@ -32,22 +29,13 @@ func (h *handler) Eventstore() eventstore.Eventstore {
|
||||
return h.es
|
||||
}
|
||||
|
||||
type EventstoreRepos struct {
|
||||
IAMEvents *eventsourcing.IAMEventstore
|
||||
OrgEvents *org_events.OrgEventstore
|
||||
ProjectEvents *project_events.ProjectEventstore
|
||||
}
|
||||
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, repos EventstoreRepos, systemDefaults sd.SystemDefaults) []query.Handler {
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, systemDefaults sd.SystemDefaults) []query.Handler {
|
||||
return []query.Handler{
|
||||
newUserGrant(
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserGrants"), errorCount, es},
|
||||
repos.IAMEvents,
|
||||
systemDefaults.IamID),
|
||||
newUserMembership(
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserMemberships"), errorCount, es},
|
||||
repos.OrgEvents,
|
||||
repos.ProjectEvents),
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserMemberships"), errorCount, es}),
|
||||
newApplication(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Application"), errorCount, es}),
|
||||
newOrg(
|
||||
|
@ -2,12 +2,12 @@ package handler
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
)
|
||||
@ -61,7 +61,7 @@ func (o *Org) EventQuery() (*es_models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eventsourcing.OrgQuery(sequence.CurrentSequence), nil
|
||||
return view.OrgQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (o *Org) Reduce(event *es_models.Event) error {
|
||||
|
@ -2,6 +2,9 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"strings"
|
||||
|
||||
"github.com/caos/logging"
|
||||
@ -13,7 +16,6 @@ import (
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
@ -27,7 +29,6 @@ const (
|
||||
|
||||
type UserGrant struct {
|
||||
handler
|
||||
iamEvents *iam_events.IAMEventstore
|
||||
iamID string
|
||||
iamProjectID string
|
||||
subscription *eventstore.Subscription
|
||||
@ -35,13 +36,11 @@ type UserGrant struct {
|
||||
|
||||
func newUserGrant(
|
||||
handler handler,
|
||||
iamEvents *iam_events.IAMEventstore,
|
||||
iamID string,
|
||||
) *UserGrant {
|
||||
h := &UserGrant{
|
||||
handler: handler,
|
||||
iamEvents: iamEvents,
|
||||
iamID: iamID,
|
||||
handler: handler,
|
||||
iamID: iamID,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -258,7 +257,7 @@ func (u *UserGrant) setIamProjectID() error {
|
||||
if u.iamProjectID != "" {
|
||||
return nil
|
||||
}
|
||||
iam, err := u.iamEvents.IAMByID(context.Background(), u.iamID)
|
||||
iam, err := u.getIAMByID(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -277,3 +276,20 @@ func (u *UserGrant) OnError(event *models.Event, err error) error {
|
||||
func (u *UserGrant) OnSuccess() error {
|
||||
return spooler.HandleSuccess(u.view.UpdateUserGrantSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *UserGrant) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
@ -4,17 +4,21 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@ -26,20 +30,14 @@ const (
|
||||
|
||||
type UserMembership struct {
|
||||
handler
|
||||
orgEvents *org_event.OrgEventstore
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newUserMembership(
|
||||
handler handler,
|
||||
orgEvents *org_event.OrgEventstore,
|
||||
projectEvents *proj_event.ProjectEventstore,
|
||||
) *UserMembership {
|
||||
h := &UserMembership{
|
||||
handler: handler,
|
||||
orgEvents: orgEvents,
|
||||
projectEvents: projectEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -156,7 +154,7 @@ func (m *UserMembership) processOrg(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *UserMembership) fillOrgName(member *usr_es_model.UserMembershipView) (err error) {
|
||||
org, err := m.orgEvents.OrgByID(context.Background(), org_model.NewOrg(member.ResourceOwner))
|
||||
org, err := m.getOrgByID(context.Background(), member.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -168,7 +166,7 @@ func (m *UserMembership) fillOrgName(member *usr_es_model.UserMembershipView) (e
|
||||
}
|
||||
|
||||
func (m *UserMembership) updateOrgName(event *models.Event) error {
|
||||
org, err := m.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.AggregateID))
|
||||
org, err := m.getOrgByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -231,7 +229,7 @@ func (m *UserMembership) processProject(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembershipView) (err error) {
|
||||
project, err := m.projectEvents.ProjectByID(context.Background(), member.AggregateID)
|
||||
project, err := m.getProjectByID(context.Background(), member.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -240,7 +238,7 @@ func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembers
|
||||
}
|
||||
|
||||
func (m *UserMembership) updateProjectDisplayName(event *models.Event) error {
|
||||
project, err := m.projectEvents.ProjectByID(context.Background(), event.AggregateID)
|
||||
project, err := m.getProjectByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -272,3 +270,42 @@ func (m *UserMembership) OnError(event *models.Event, err error) error {
|
||||
func (m *UserMembership) OnSuccess() error {
|
||||
return spooler.HandleSuccess(m.view.UpdateUserMembershipSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *UserMembership) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var esOrg *org_es_model.Org
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3m9vs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *UserMembership) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(projID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esProject := &proj_es_model.Project{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: projID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esProject.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esProject.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-Dfrt2", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return proj_es_model.ProjectToModel(esProject), nil
|
||||
}
|
||||
|
@ -2,24 +2,19 @@ package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
|
||||
es_user "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/auth_request/repository/cache"
|
||||
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/eventstore"
|
||||
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/handler"
|
||||
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/spooler"
|
||||
authz_view "github.com/caos/zitadel/internal/authz/repository/eventsourcing/view"
|
||||
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/id"
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -55,60 +50,30 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (*
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iam, err := es_iam.StartIAM(es_iam.IAMConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults)
|
||||
|
||||
project, err := es_proj.StartProject(es_proj.ProjectConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user, err := es_user.StartUser(
|
||||
es_user.UserConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
},
|
||||
systemDefaults,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iamV2, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos := handler.EventstoreRepos{IAMEvents: iam, OrgEvents: org, ProjectEvents: project}
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, repos, systemDefaults)
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults)
|
||||
|
||||
return &EsRepository{
|
||||
spool,
|
||||
eventstore.UserGrantRepo{
|
||||
View: view,
|
||||
IamID: systemDefaults.IamID,
|
||||
Auth: authZ,
|
||||
IamEvents: iam,
|
||||
View: view,
|
||||
IamID: systemDefaults.IamID,
|
||||
Auth: authZ,
|
||||
Eventstore: es,
|
||||
},
|
||||
eventstore.IamRepo{
|
||||
IAMID: systemDefaults.IamID,
|
||||
IAMEvents: iam,
|
||||
IAMV2Query: iamV2,
|
||||
},
|
||||
eventstore.TokenVerifierRepo{
|
||||
//TODO: Add Token Verification Key
|
||||
IAMID: systemDefaults.IamID,
|
||||
IAMEvents: iam,
|
||||
ProjectEvents: project,
|
||||
UserEvents: user,
|
||||
View: view,
|
||||
Eventstore: es,
|
||||
IAMID: systemDefaults.IamID,
|
||||
View: view,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ type SpoolerConfig struct {
|
||||
Handlers handler.Configs
|
||||
}
|
||||
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, repos handler.EventstoreRepos, systemDefaults sd.SystemDefaults) *spooler.Spooler {
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, systemDefaults sd.SystemDefaults) *spooler.Spooler {
|
||||
spoolerConfig := spooler.Config{
|
||||
Eventstore: es,
|
||||
Locker: &locker{dbClient: sql},
|
||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, repos, systemDefaults),
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, systemDefaults),
|
||||
}
|
||||
spool := spoolerConfig.New()
|
||||
spool.Start()
|
||||
|
@ -1,85 +1,11 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/cache/config"
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_int "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"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
|
||||
type IAMEventstore struct {
|
||||
es_int.Eventstore
|
||||
iamCache *IAMCache
|
||||
}
|
||||
|
||||
type IAMConfig struct {
|
||||
es_int.Eventstore
|
||||
Cache *config.CacheConfig
|
||||
}
|
||||
|
||||
func StartIAM(conf IAMConfig, systemDefaults sd.SystemDefaults) (*IAMEventstore, error) {
|
||||
iamCache, err := StartCache(conf.Cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &IAMEventstore{
|
||||
Eventstore: conf.Eventstore,
|
||||
iamCache: iamCache,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) IAMByID(ctx context.Context, id string) (_ *iam_model.IAM, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
iam := es.iamCache.getIAM(id)
|
||||
|
||||
query, err := IAMByIDQuery(iam.AggregateID, iam.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = es_sdk.Filter(ctx, es.FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
es.iamCache.cacheIAM(iam)
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) IAMEventsByID(ctx context.Context, id string, sequence uint64) ([]*es_models.Event, error) {
|
||||
query, err := IAMByIDQuery(id, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return es.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) GetIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := es.IAMByID(ctx, aggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil {
|
||||
return existingIDP, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-Scj8s", "Errors.IAM.IdpNotExisting")
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) GetOrgIAMPolicy(ctx context.Context, iamID string) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := es.IAMByID(ctx, iamID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2Fj8s", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
}
|
||||
|
21
internal/iam/repository/view/query.go
Normal file
21
internal/iam/repository/view/query.go
Normal file
@ -0,0 +1,21 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
func IAMByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) {
|
||||
if id == "" {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4ng8sd", "id should be filled")
|
||||
}
|
||||
return IAMQuery(latestSequence).
|
||||
AggregateIDFilter(id), nil
|
||||
}
|
||||
|
||||
func IAMQuery(latestSequence uint64) *es_models.SearchQuery {
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(iam_es_model.IAMAggregate).
|
||||
LatestSequenceFilter(latestSequence)
|
||||
}
|
@ -2,11 +2,17 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"strings"
|
||||
|
||||
iam_es "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
@ -17,10 +23,10 @@ import (
|
||||
mgmt_view "github.com/caos/zitadel/internal/management/repository/eventsourcing/view"
|
||||
global_model "github.com/caos/zitadel/internal/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -28,10 +34,8 @@ const (
|
||||
)
|
||||
|
||||
type OrgRepository struct {
|
||||
SearchLimit uint64
|
||||
*org_es.OrgEventstore
|
||||
UserEvents *usr_es.UserEventstore
|
||||
IAMEventstore *iam_es.IAMEventstore
|
||||
SearchLimit uint64
|
||||
Eventstore eventstore.Eventstore
|
||||
View *mgmt_view.View
|
||||
Roles []string
|
||||
SystemDefaults systemdefaults.SystemDefaults
|
||||
@ -91,19 +95,19 @@ func (repo *OrgRepository) SearchMyOrgDomains(ctx context.Context, request *org_
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) OrgChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*org_model.OrgChanges, error) {
|
||||
changes, err := repo.OrgEventstore.OrgChanges(ctx, id, lastSequence, limit, sortAscending)
|
||||
changes, err := repo.getOrgChanges(ctx, id, lastSequence, limit, sortAscending)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, change := range changes.Changes {
|
||||
change.ModifierName = change.ModifierId
|
||||
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierId)
|
||||
user, _ := repo.userByID(ctx, change.ModifierId)
|
||||
if user != nil {
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
change.ModifierName = user.DisplayName
|
||||
}
|
||||
if user.Machine != nil {
|
||||
change.ModifierName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
change.ModifierName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,7 +208,7 @@ func (repo *OrgRepository) GetLoginPolicy(ctx context.Context) (*iam_model.Login
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.LoginPolicyView)
|
||||
}
|
||||
events, esErr := repo.OrgEventstore.OrgEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getOrgEvents(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return repo.GetDefaultLoginPolicy(ctx)
|
||||
}
|
||||
@ -237,7 +241,7 @@ func (repo *OrgRepository) GetDefaultLoginPolicy(ctx context.Context) (*iam_mode
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.LoginPolicyView)
|
||||
}
|
||||
events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, domain.IAMID, policy.Sequence)
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-cmO9s", "Errors.IAM.LoginPolicy.NotFound")
|
||||
}
|
||||
@ -315,7 +319,7 @@ func (repo *OrgRepository) GetPasswordComplexityPolicy(ctx context.Context) (*ia
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordComplexityPolicyView)
|
||||
}
|
||||
events, esErr := repo.OrgEventstore.OrgEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getOrgEvents(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return repo.GetDefaultPasswordComplexityPolicy(ctx)
|
||||
}
|
||||
@ -340,7 +344,7 @@ func (repo *OrgRepository) GetDefaultPasswordComplexityPolicy(ctx context.Contex
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordComplexityPolicyView)
|
||||
}
|
||||
events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-cmO9s", "Errors.IAM.PasswordComplexityPolicy.NotFound")
|
||||
}
|
||||
@ -366,7 +370,7 @@ func (repo *OrgRepository) GetPasswordAgePolicy(ctx context.Context) (*iam_model
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordAgePolicyView)
|
||||
}
|
||||
events, esErr := repo.OrgEventstore.OrgEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getOrgEvents(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return repo.GetDefaultPasswordAgePolicy(ctx)
|
||||
}
|
||||
@ -391,7 +395,7 @@ func (repo *OrgRepository) GetDefaultPasswordAgePolicy(ctx context.Context) (*ia
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordAgePolicyView)
|
||||
}
|
||||
events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-cmO9s", "Errors.IAM.PasswordAgePolicy.NotFound")
|
||||
}
|
||||
@ -417,7 +421,7 @@ func (repo *OrgRepository) GetPasswordLockoutPolicy(ctx context.Context) (*iam_m
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordLockoutPolicyView)
|
||||
}
|
||||
events, esErr := repo.OrgEventstore.OrgEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getOrgEvents(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return repo.GetDefaultPasswordLockoutPolicy(ctx)
|
||||
}
|
||||
@ -442,7 +446,7 @@ func (repo *OrgRepository) GetDefaultPasswordLockoutPolicy(ctx context.Context)
|
||||
if errors.IsNotFound(viewErr) {
|
||||
policy = new(iam_es_model.PasswordLockoutPolicyView)
|
||||
}
|
||||
events, esErr := repo.IAMEventstore.IAMEventsByID(ctx, repo.SystemDefaults.IamID, policy.Sequence)
|
||||
events, esErr := repo.getIAMEvents(ctx, policy.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-cmO9s", "Errors.IAM.PasswordLockoutPolicy.NotFound")
|
||||
}
|
||||
@ -507,3 +511,99 @@ func (repo *OrgRepository) GetMailTexts(ctx context.Context) (*iam_model.MailTex
|
||||
}
|
||||
return iam_es_model.MailTextsViewToModel(texts, defaultIn), err
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) getOrgChanges(ctx context.Context, orgID string, lastSequence uint64, limit uint64, sortAscending bool) (*org_model.OrgChanges, error) {
|
||||
query := org_view.ChangesQuery(orgID, lastSequence, limit, sortAscending)
|
||||
|
||||
events, err := repo.Eventstore.FilterEvents(context.Background(), query)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-ZRffs").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, errors.ThrowInternal(err, "EVENT-328b1", "Errors.Org.NotFound")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-FpQqK", "Errors.Changes.NotFound")
|
||||
}
|
||||
|
||||
changes := make([]*org_model.OrgChange, len(events))
|
||||
|
||||
for i, event := range events {
|
||||
creationDate, err := ptypes.TimestampProto(event.CreationDate)
|
||||
logging.Log("EVENT-qxIR7").OnError(err).Debug("unable to parse timestamp")
|
||||
change := &org_model.OrgChange{
|
||||
ChangeDate: creationDate,
|
||||
EventType: event.Type.String(),
|
||||
ModifierId: event.EditorUser,
|
||||
Sequence: event.Sequence,
|
||||
}
|
||||
|
||||
if event.Data != nil {
|
||||
org := new(org_es_model.Org)
|
||||
err := json.Unmarshal(event.Data, org)
|
||||
logging.Log("EVENT-XCLEm").OnError(err).Debug("unable to unmarshal data")
|
||||
change.Data = org
|
||||
}
|
||||
|
||||
changes[i] = change
|
||||
if lastSequence < event.Sequence {
|
||||
lastSequence = event.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
return &org_model.OrgChanges{
|
||||
Changes: changes,
|
||||
LastSequence: lastSequence,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) userByID(ctx context.Context, id string) (*usr_model.UserView, error) {
|
||||
user, viewErr := repo.View.UserByID(id)
|
||||
if viewErr != nil && !errors.IsNotFound(viewErr) {
|
||||
return nil, viewErr
|
||||
}
|
||||
if errors.IsNotFound(viewErr) {
|
||||
user = new(usr_es_model.UserView)
|
||||
}
|
||||
events, esErr := repo.getUserEvents(ctx, id, user.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3nF8s", "Errors.User.NotFound")
|
||||
}
|
||||
if esErr != nil {
|
||||
logging.Log("EVENT-PSoc3").WithError(esErr).Debug("error retrieving new events")
|
||||
return usr_es_model.UserToModel(user), nil
|
||||
}
|
||||
userCopy := *user
|
||||
for _, event := range events {
|
||||
if err := userCopy.AppendEvent(event); err != nil {
|
||||
return usr_es_model.UserToModel(user), nil
|
||||
}
|
||||
}
|
||||
if userCopy.State == int32(usr_es_model.UserStateDeleted) {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3n8Fs", "Errors.User.NotFound")
|
||||
}
|
||||
return usr_es_model.UserToModel(&userCopy), nil
|
||||
}
|
||||
|
||||
func (r *OrgRepository) getUserEvents(ctx context.Context, userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (es *OrgRepository) getOrgEvents(ctx context.Context, id string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := org_view.OrgByIDQuery(id, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return es.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) getIAMEvents(ctx context.Context, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
@ -2,33 +2,40 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
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"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"strings"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
key_model "github.com/caos/zitadel/internal/key/model"
|
||||
key_view_model "github.com/caos/zitadel/internal/key/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/management/repository/eventsourcing/view"
|
||||
global_model "github.com/caos/zitadel/internal/model"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
"github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_view "github.com/caos/zitadel/internal/user/repository/view"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
type ProjectRepo struct {
|
||||
es_int.Eventstore
|
||||
SearchLimit uint64
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
UserEvents *usr_event.UserEventstore
|
||||
IAMEvents *iam_event.IAMEventstore
|
||||
View *view.View
|
||||
Roles []string
|
||||
IAMID string
|
||||
SearchLimit uint64
|
||||
View *view.View
|
||||
Roles []string
|
||||
IAMID string
|
||||
}
|
||||
|
||||
func (repo *ProjectRepo) ProjectByID(ctx context.Context, id string) (*proj_model.ProjectView, error) {
|
||||
@ -40,7 +47,7 @@ func (repo *ProjectRepo) ProjectByID(ctx context.Context, id string) (*proj_mode
|
||||
project = new(model.ProjectView)
|
||||
}
|
||||
|
||||
events, esErr := repo.ProjectEvents.ProjectEventsByID(ctx, id, project.Sequence)
|
||||
events, esErr := repo.getProjectEvents(ctx, id, project.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-8yfKu", "Errors.Project.NotFound")
|
||||
}
|
||||
@ -175,19 +182,19 @@ func (repo *ProjectRepo) SearchProjectRoles(ctx context.Context, projectID strin
|
||||
}
|
||||
|
||||
func (repo *ProjectRepo) ProjectChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*proj_model.ProjectChanges, error) {
|
||||
changes, err := repo.ProjectEvents.ProjectChanges(ctx, id, lastSequence, limit, sortAscending)
|
||||
changes, err := repo.getProjectChanges(ctx, id, lastSequence, limit, sortAscending)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, change := range changes.Changes {
|
||||
change.ModifierName = change.ModifierId
|
||||
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierId)
|
||||
user, _ := repo.userByID(ctx, change.ModifierId)
|
||||
if user != nil {
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
change.ModifierName = user.DisplayName
|
||||
}
|
||||
if user.Machine != nil {
|
||||
change.ModifierName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
change.ModifierName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,7 +211,7 @@ func (repo *ProjectRepo) ApplicationByID(ctx context.Context, projectID, appID s
|
||||
app.ID = appID
|
||||
}
|
||||
|
||||
events, esErr := repo.ProjectEvents.ProjectEventsByID(ctx, projectID, app.Sequence)
|
||||
events, esErr := repo.getProjectEvents(ctx, projectID, app.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-Fshu8", "Errors.Application.NotFound")
|
||||
}
|
||||
@ -249,19 +256,19 @@ func (repo *ProjectRepo) SearchApplications(ctx context.Context, request *proj_m
|
||||
}
|
||||
|
||||
func (repo *ProjectRepo) ApplicationChanges(ctx context.Context, id string, appId string, lastSequence uint64, limit uint64, sortAscending bool) (*proj_model.ApplicationChanges, error) {
|
||||
changes, err := repo.ProjectEvents.ApplicationChanges(ctx, id, appId, lastSequence, limit, sortAscending)
|
||||
changes, err := repo.getApplicationChanges(ctx, id, appId, lastSequence, limit, sortAscending)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, change := range changes.Changes {
|
||||
change.ModifierName = change.ModifierId
|
||||
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierId)
|
||||
user, _ := repo.userByID(ctx, change.ModifierId)
|
||||
if user != nil {
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
change.ModifierName = user.DisplayName
|
||||
}
|
||||
if user.Machine != nil {
|
||||
change.ModifierName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
change.ModifierName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -295,7 +302,7 @@ func (repo *ProjectRepo) GetClientKey(ctx context.Context, projectID, applicatio
|
||||
return nil, viewErr
|
||||
}
|
||||
|
||||
events, esErr := repo.ProjectEvents.ProjectEventsByID(ctx, projectID, key.Sequence)
|
||||
events, esErr := repo.getProjectEvents(ctx, projectID, key.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-SFf2g", "Errors.User.KeyNotFound")
|
||||
}
|
||||
@ -436,7 +443,7 @@ func (repo *ProjectRepo) SearchProjectGrantMembers(ctx context.Context, request
|
||||
}
|
||||
|
||||
func (repo *ProjectRepo) GetProjectMemberRoles(ctx context.Context) ([]string, error) {
|
||||
iam, err := repo.IAMEvents.IAMByID(ctx, repo.IAMID)
|
||||
iam, err := repo.GetIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -462,3 +469,158 @@ func (repo *ProjectRepo) GetProjectGrantMemberRoles() []string {
|
||||
}
|
||||
return roles
|
||||
}
|
||||
|
||||
func (repo *ProjectRepo) userByID(ctx context.Context, id string) (*usr_model.UserView, error) {
|
||||
user, viewErr := repo.View.UserByID(id)
|
||||
if viewErr != nil && !caos_errs.IsNotFound(viewErr) {
|
||||
return nil, viewErr
|
||||
}
|
||||
if caos_errs.IsNotFound(viewErr) {
|
||||
user = new(usr_es_model.UserView)
|
||||
}
|
||||
events, esErr := repo.getUserEvents(ctx, id, user.Sequence)
|
||||
if errors.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-4n8Fs", "Errors.User.NotFound")
|
||||
}
|
||||
if esErr != nil {
|
||||
logging.Log("EVENT-PSoc3").WithError(esErr).Debug("error retrieving new events")
|
||||
return usr_es_model.UserToModel(user), nil
|
||||
}
|
||||
userCopy := *user
|
||||
for _, event := range events {
|
||||
if err := userCopy.AppendEvent(event); err != nil {
|
||||
return usr_es_model.UserToModel(user), nil
|
||||
}
|
||||
}
|
||||
if userCopy.State == int32(usr_model.UserStateDeleted) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2m0Fs", "Errors.User.NotFound")
|
||||
}
|
||||
return usr_es_model.UserToModel(&userCopy), nil
|
||||
}
|
||||
|
||||
func (r *ProjectRepo) getUserEvents(ctx context.Context, userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := usr_view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (repo *ProjectRepo) getProjectChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*proj_model.ProjectChanges, error) {
|
||||
query := proj_view.ChangesQuery(id, lastSequence, limit, sortAscending)
|
||||
|
||||
events, err := repo.Eventstore.FilterEvents(context.Background(), query)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-ZRffs").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, caos_errs.ThrowInternal(err, "EVENT-328b1", "Errors.Internal")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-FpQqK", "Errors.Changes.NotFound")
|
||||
}
|
||||
|
||||
changes := make([]*proj_model.ProjectChange, len(events))
|
||||
|
||||
for i, event := range events {
|
||||
creationDate, err := ptypes.TimestampProto(event.CreationDate)
|
||||
logging.Log("EVENT-qxIR7").OnError(err).Debug("unable to parse timestamp")
|
||||
change := &proj_model.ProjectChange{
|
||||
ChangeDate: creationDate,
|
||||
EventType: event.Type.String(),
|
||||
ModifierId: event.EditorUser,
|
||||
Sequence: event.Sequence,
|
||||
}
|
||||
|
||||
if event.Data != nil {
|
||||
var data interface{}
|
||||
if strings.Contains(change.EventType, "application") {
|
||||
data = new(proj_model.Application)
|
||||
} else {
|
||||
data = new(proj_model.Project)
|
||||
}
|
||||
err = json.Unmarshal(event.Data, data)
|
||||
logging.Log("EVENT-NCkpN").OnError(err).Debug("unable to unmarshal data")
|
||||
change.Data = data
|
||||
}
|
||||
|
||||
changes[i] = change
|
||||
if lastSequence < event.Sequence {
|
||||
lastSequence = event.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
return &proj_model.ProjectChanges{
|
||||
Changes: changes,
|
||||
LastSequence: lastSequence,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (repo *ProjectRepo) getProjectEvents(ctx context.Context, id string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(id, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (repo *ProjectRepo) getApplicationChanges(ctx context.Context, projectID string, appID string, lastSequence uint64, limit uint64, sortAscending bool) (*proj_model.ApplicationChanges, error) {
|
||||
query := proj_view.ChangesQuery(projectID, lastSequence, limit, sortAscending)
|
||||
|
||||
events, err := repo.Eventstore.FilterEvents(ctx, query)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-ZRffs").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, caos_errs.ThrowInternal(err, "EVENT-sw6Ku", "Errors.Internal")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-9IHLP", "Errors.Changes.NotFound")
|
||||
}
|
||||
|
||||
result := make([]*proj_model.ApplicationChange, 0)
|
||||
for _, event := range events {
|
||||
if !strings.Contains(event.Type.String(), "application") || event.Data == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
app := new(proj_model.Application)
|
||||
err := json.Unmarshal(event.Data, app)
|
||||
logging.Log("EVENT-GIiKD").OnError(err).Debug("unable to unmarshal data")
|
||||
if app.AppID != appID {
|
||||
continue
|
||||
}
|
||||
|
||||
creationDate, err := ptypes.TimestampProto(event.CreationDate)
|
||||
logging.Log("EVENT-MJzeN").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
result = append(result, &proj_model.ApplicationChange{
|
||||
ChangeDate: creationDate,
|
||||
EventType: event.Type.String(),
|
||||
ModifierId: event.EditorUser,
|
||||
Sequence: event.Sequence,
|
||||
Data: app,
|
||||
})
|
||||
if lastSequence < event.Sequence {
|
||||
lastSequence = event.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
return &proj_model.ApplicationChanges{
|
||||
Changes: result,
|
||||
LastSequence: lastSequence,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (u *ProjectRepo) GetIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore.FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
usr_view "github.com/caos/zitadel/internal/user/repository/view"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
@ -14,9 +17,7 @@ import (
|
||||
key_view_model "github.com/caos/zitadel/internal/key/repository/view/model"
|
||||
"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"
|
||||
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"
|
||||
)
|
||||
@ -24,8 +25,6 @@ import (
|
||||
type UserRepo struct {
|
||||
es_int.Eventstore
|
||||
SearchLimit uint64
|
||||
UserEvents *usr_event.UserEventstore
|
||||
OrgEvents *org_event.OrgEventstore
|
||||
View *view.View
|
||||
SystemDefaults systemdefaults.SystemDefaults
|
||||
}
|
||||
@ -38,7 +37,7 @@ func (repo *UserRepo) UserByID(ctx context.Context, id string) (*usr_model.UserV
|
||||
if caos_errs.IsNotFound(viewErr) {
|
||||
user = new(model.UserView)
|
||||
}
|
||||
events, esErr := repo.UserEvents.UserEventsByID(ctx, id, user.Sequence)
|
||||
events, esErr := repo.getUserEvents(ctx, id, user.Sequence)
|
||||
if caos_errs.IsNotFound(viewErr) && len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-Lsoj7", "Errors.User.NotFound")
|
||||
}
|
||||
@ -84,19 +83,19 @@ func (repo *UserRepo) UserIDsByDomain(ctx context.Context, domain string) ([]str
|
||||
}
|
||||
|
||||
func (repo *UserRepo) UserChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*usr_model.UserChanges, error) {
|
||||
changes, err := repo.UserEvents.UserChanges(ctx, id, lastSequence, limit, sortAscending)
|
||||
changes, err := repo.getUserChanges(ctx, id, lastSequence, limit, sortAscending)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, change := range changes.Changes {
|
||||
change.ModifierName = change.ModifierID
|
||||
user, _ := repo.UserEvents.UserByID(ctx, change.ModifierID)
|
||||
user, _ := repo.UserByID(ctx, change.ModifierID)
|
||||
if user != nil {
|
||||
if user.Human != nil {
|
||||
change.ModifierName = user.Human.DisplayName
|
||||
if user.HumanView != nil {
|
||||
change.ModifierName = user.HumanView.DisplayName
|
||||
}
|
||||
if user.Machine != nil {
|
||||
change.ModifierName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
change.ModifierName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,8 +132,15 @@ func (repo *UserRepo) UserMFAs(ctx context.Context, userID string) ([]*usr_model
|
||||
return mfas, nil
|
||||
}
|
||||
|
||||
func (repo *UserRepo) GetPasswordless(ctx context.Context, userID string) ([]*usr_model.WebAuthNToken, error) {
|
||||
return repo.UserEvents.GetPasswordless(ctx, userID)
|
||||
func (repo *UserRepo) GetPasswordless(ctx context.Context, userID string) ([]*usr_model.WebAuthNView, error) {
|
||||
user, err := repo.UserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user.HumanView == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-9anf8", "Errors.User.NotHuman")
|
||||
}
|
||||
return user.HumanView.PasswordlessTokens, nil
|
||||
}
|
||||
|
||||
func (repo *UserRepo) ProfileByID(ctx context.Context, userID string) (*usr_model.Profile, error) {
|
||||
@ -274,6 +280,58 @@ func (repo *UserRepo) SearchUserMemberships(ctx context.Context, request *usr_mo
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *UserRepo) getUserChanges(ctx context.Context, userID string, lastSequence uint64, limit uint64, sortAscending bool) (*usr_model.UserChanges, error) {
|
||||
query := usr_view.ChangesQuery(userID, lastSequence, limit, sortAscending)
|
||||
|
||||
events, err := r.Eventstore.FilterEvents(ctx, query)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-g9HCv").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, errors.ThrowInternal(err, "EVENT-htuG9", "Errors.Internal")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-6cAxe", "Errors.User.NoChanges")
|
||||
}
|
||||
|
||||
result := make([]*usr_model.UserChange, len(events))
|
||||
|
||||
for i, event := range events {
|
||||
creationDate, err := ptypes.TimestampProto(event.CreationDate)
|
||||
logging.Log("EVENT-8GTGS").OnError(err).Debug("unable to parse timestamp")
|
||||
change := &usr_model.UserChange{
|
||||
ChangeDate: creationDate,
|
||||
EventType: event.Type.String(),
|
||||
ModifierID: event.EditorUser,
|
||||
Sequence: event.Sequence,
|
||||
}
|
||||
|
||||
//TODO: now all types should be unmarshalled, e.g. password
|
||||
// if len(event.Data) != 0 {
|
||||
// user := new(model.User)
|
||||
// err := json.Unmarshal(event.Data, user)
|
||||
// logging.Log("EVENT-Rkg7X").OnError(err).Debug("unable to unmarshal data")
|
||||
// change.Data = user
|
||||
// }
|
||||
|
||||
result[i] = change
|
||||
if lastSequence < event.Sequence {
|
||||
lastSequence = event.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
return &usr_model.UserChanges{
|
||||
Changes: result,
|
||||
LastSequence: lastSequence,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *UserRepo) getUserEvents(ctx context.Context, userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := usr_view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.Eventstore.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func handleSearchUserMembershipsPermissions(ctx context.Context, request *usr_model.UserMembershipSearchRequest, sequence *repository.CurrentSequence) *usr_model.UserMembershipSearchResponse {
|
||||
permissions := authz.GetAllPermissionsFromCtx(ctx)
|
||||
iamPerm := authz.HasGlobalExplicitPermission(permissions, iamMemberReadPerm)
|
||||
|
@ -5,13 +5,15 @@ import (
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
)
|
||||
|
||||
@ -21,17 +23,14 @@ const (
|
||||
|
||||
type Application struct {
|
||||
handler
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newApplication(
|
||||
handler handler,
|
||||
projectEvents *proj_event.ProjectEventstore,
|
||||
) *Application {
|
||||
h := &Application{
|
||||
handler: handler,
|
||||
projectEvents: projectEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -69,14 +68,14 @@ func (a *Application) EventQuery() (*models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eventsourcing.ProjectQuery(sequence.CurrentSequence), nil
|
||||
return proj_view.ProjectQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (a *Application) Reduce(event *models.Event) (err error) {
|
||||
app := new(view_model.ApplicationView)
|
||||
switch event.Type {
|
||||
case es_model.ApplicationAdded:
|
||||
project, err := a.projectEvents.ProjectByID(context.Background(), event.AggregateID)
|
||||
project, err := a.getProjectByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -139,3 +138,24 @@ func (a *Application) OnError(event *models.Event, spoolerError error) error {
|
||||
func (a *Application) OnSuccess() error {
|
||||
return spooler.HandleSuccess(a.view.UpdateApplicationSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (a *Application) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(projID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esProject := &es_model.Project{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: projID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, a.Eventstore().FilterEvents, esProject.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esProject.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-ADvfs", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return es_model.ProjectToModel(esProject), nil
|
||||
}
|
||||
|
@ -7,11 +7,7 @@ import (
|
||||
"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"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Configs map[string]*Config
|
||||
@ -33,48 +29,27 @@ func (h *handler) Eventstore() eventstore.Eventstore {
|
||||
return h.es
|
||||
}
|
||||
|
||||
type EventstoreRepos struct {
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
UserEvents *usr_event.UserEventstore
|
||||
OrgEvents *org_event.OrgEventstore
|
||||
IamEvents *iam_event.IAMEventstore
|
||||
}
|
||||
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, repos EventstoreRepos, defaults systemdefaults.SystemDefaults) []query.Handler {
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, defaults systemdefaults.SystemDefaults) []query.Handler {
|
||||
return []query.Handler{
|
||||
newProject(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Project"), errorCount, es}),
|
||||
newProjectGrant(
|
||||
handler{view, bulkLimit, configs.cycleDuration("ProjectGrant"), errorCount, es},
|
||||
repos.ProjectEvents,
|
||||
repos.OrgEvents),
|
||||
newProjectRole(handler{view, bulkLimit, configs.cycleDuration("ProjectRole"), errorCount, es},
|
||||
repos.ProjectEvents),
|
||||
newProjectMember(handler{view, bulkLimit, configs.cycleDuration("ProjectMember"), errorCount, es},
|
||||
repos.UserEvents),
|
||||
newProjectGrantMember(handler{view, bulkLimit, configs.cycleDuration("ProjectGrantMember"), errorCount, es},
|
||||
repos.UserEvents),
|
||||
newApplication(handler{view, bulkLimit, configs.cycleDuration("Application"), errorCount, es},
|
||||
repos.ProjectEvents),
|
||||
handler{view, bulkLimit, configs.cycleDuration("ProjectGrant"), errorCount, es}),
|
||||
newProjectRole(handler{view, bulkLimit, configs.cycleDuration("ProjectRole"), errorCount, es}),
|
||||
newProjectMember(handler{view, bulkLimit, configs.cycleDuration("ProjectMember"), errorCount, es}),
|
||||
newProjectGrantMember(handler{view, bulkLimit, configs.cycleDuration("ProjectGrantMember"), errorCount, es}),
|
||||
newApplication(handler{view, bulkLimit, configs.cycleDuration("Application"), errorCount, es}),
|
||||
newUser(handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es},
|
||||
repos.OrgEvents,
|
||||
repos.IamEvents,
|
||||
defaults.IamID),
|
||||
newUserGrant(handler{view, bulkLimit, configs.cycleDuration("UserGrant"), errorCount, es},
|
||||
repos.ProjectEvents,
|
||||
repos.UserEvents,
|
||||
repos.OrgEvents),
|
||||
newUserGrant(handler{view, bulkLimit, configs.cycleDuration("UserGrant"), errorCount, es}),
|
||||
newOrg(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Org"), errorCount, es}),
|
||||
newOrgMember(
|
||||
handler{view, bulkLimit, configs.cycleDuration("OrgMember"), errorCount, es},
|
||||
repos.UserEvents),
|
||||
handler{view, bulkLimit, configs.cycleDuration("OrgMember"), errorCount, es}),
|
||||
newOrgDomain(
|
||||
handler{view, bulkLimit, configs.cycleDuration("OrgDomain"), errorCount, es}),
|
||||
newUserMembership(
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserMembership"), errorCount, es},
|
||||
repos.OrgEvents,
|
||||
repos.ProjectEvents),
|
||||
handler{view, bulkLimit, configs.cycleDuration("UserMembership"), errorCount, es}),
|
||||
newAuthNKeys(
|
||||
handler{view, bulkLimit, configs.cycleDuration("MachineKeys"), errorCount, es}),
|
||||
newIDPConfig(
|
||||
@ -85,16 +60,10 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
handler{view, bulkLimit, configs.cycleDuration("LabelPolicy"), errorCount, es}),
|
||||
newIDPProvider(
|
||||
handler{view, bulkLimit, configs.cycleDuration("IDPProvider"), errorCount, es},
|
||||
|
||||
defaults,
|
||||
repos.IamEvents,
|
||||
repos.OrgEvents),
|
||||
defaults),
|
||||
newExternalIDP(
|
||||
handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es},
|
||||
|
||||
defaults,
|
||||
repos.IamEvents,
|
||||
repos.OrgEvents),
|
||||
defaults),
|
||||
newPasswordComplexityPolicy(
|
||||
handler{view, bulkLimit, configs.cycleDuration("PasswordComplexityPolicy"), errorCount, es}),
|
||||
newPasswordAgePolicy(
|
||||
|
@ -2,19 +2,22 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -24,22 +27,16 @@ const (
|
||||
type IDPProvider struct {
|
||||
handler
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
iamEvents *eventsourcing.IAMEventstore
|
||||
orgEvents *org_es.OrgEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newIDPProvider(
|
||||
handler handler,
|
||||
systemDefaults systemdefaults.SystemDefaults,
|
||||
iamEvents *eventsourcing.IAMEventstore,
|
||||
orgEvents *org_es.OrgEventstore,
|
||||
) *IDPProvider {
|
||||
h := &IDPProvider{
|
||||
handler: handler,
|
||||
systemDefaults: systemDefaults,
|
||||
iamEvents: iamEvents,
|
||||
orgEvents: orgEvents,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -119,9 +116,9 @@ func (m *IDPProvider) processIdpProvider(event *es_models.Event) (err error) {
|
||||
}
|
||||
config := new(iam_model.IDPConfig)
|
||||
if event.AggregateID == m.systemDefaults.IamID {
|
||||
config, err = m.iamEvents.GetIDPConfig(context.Background(), event.AggregateID, esConfig.IDPConfigID)
|
||||
config, err = m.getDefaultIDPConfig(context.Background(), esConfig.IDPConfigID)
|
||||
} else {
|
||||
config, err = m.orgEvents.GetIDPConfig(context.Background(), event.AggregateID, esConfig.IDPConfigID)
|
||||
config, err = m.getOrgIDPConfig(context.Background(), event.AggregateID, esConfig.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -144,9 +141,9 @@ func (m *IDPProvider) processIdpProvider(event *es_models.Event) (err error) {
|
||||
func (m *IDPProvider) fillData(provider *iam_view_model.IDPProviderView) (err error) {
|
||||
var config *iam_model.IDPConfig
|
||||
if provider.IDPProviderType == int32(iam_model.IDPProviderTypeSystem) {
|
||||
config, err = m.iamEvents.GetIDPConfig(context.Background(), m.systemDefaults.IamID, provider.IDPConfigID)
|
||||
config, err = m.getDefaultIDPConfig(context.Background(), provider.IDPConfigID)
|
||||
} else {
|
||||
config, err = m.orgEvents.GetIDPConfig(context.Background(), provider.AggregateID, provider.IDPConfigID)
|
||||
config, err = m.getOrgIDPConfig(context.Background(), provider.AggregateID, provider.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -170,3 +167,64 @@ func (m *IDPProvider) OnError(event *es_models.Event, err error) error {
|
||||
func (m *IDPProvider) OnSuccess() error {
|
||||
return spooler.HandleSuccess(m.view.UpdateIDPProviderSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (i *IDPProvider) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := i.getOrgByID(ctx, aggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, i := existing.GetIDP(idpConfigID); i != nil {
|
||||
return i, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2m9dS", "Errors.Org.IdpNotExisting")
|
||||
}
|
||||
|
||||
func (i *IDPProvider) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-4n9fs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *IDPProvider) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *IDPProvider) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil {
|
||||
return existingIDP, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-4M0fs", "Errors.IAM.IdpNotExisting")
|
||||
}
|
||||
|
@ -2,12 +2,12 @@ package handler
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
)
|
||||
@ -61,7 +61,7 @@ func (o *Org) EventQuery() (*es_models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eventsourcing.OrgQuery(sequence.CurrentSequence), nil
|
||||
return view.OrgQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (o *Org) Reduce(event *es_models.Event) (err error) {
|
||||
|
@ -2,6 +2,8 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
@ -12,8 +14,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/repository/view/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -22,17 +24,14 @@ const (
|
||||
|
||||
type OrgMember struct {
|
||||
handler
|
||||
userEvents *usr_event.UserEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newOrgMember(
|
||||
handler handler,
|
||||
userEvents *usr_event.UserEventstore,
|
||||
) *OrgMember {
|
||||
h := &OrgMember{
|
||||
handler: handler,
|
||||
userEvents: userEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -133,7 +132,7 @@ func (m *OrgMember) processUser(event *models.Event) (err error) {
|
||||
if len(members) == 0 {
|
||||
return m.view.ProcessedOrgMemberSequence(event)
|
||||
}
|
||||
user, err := m.userEvents.UserByID(context.Background(), event.AggregateID)
|
||||
user, err := m.getUserByID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -149,7 +148,7 @@ func (m *OrgMember) processUser(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *OrgMember) fillData(member *org_model.OrgMemberView) (err error) {
|
||||
user, err := m.userEvents.UserByID(context.Background(), member.UserID)
|
||||
user, err := m.getUserByID(member.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -157,16 +156,16 @@ func (m *OrgMember) fillData(member *org_model.OrgMemberView) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OrgMember) fillUserData(member *org_model.OrgMemberView, user *usr_model.User) {
|
||||
func (m *OrgMember) fillUserData(member *org_model.OrgMemberView, user *usr_view_model.UserView) {
|
||||
member.UserName = user.UserName
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
member.FirstName = user.FirstName
|
||||
member.LastName = user.LastName
|
||||
member.DisplayName = user.FirstName + " " + user.LastName
|
||||
member.Email = user.EmailAddress
|
||||
member.Email = user.Email
|
||||
}
|
||||
if user.Machine != nil {
|
||||
member.DisplayName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
member.DisplayName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
func (m *OrgMember) OnError(event *models.Event, err error) error {
|
||||
@ -177,3 +176,36 @@ func (m *OrgMember) OnError(event *models.Event, err error) error {
|
||||
func (o *OrgMember) OnSuccess() error {
|
||||
return spooler.HandleSuccess(o.view.UpdateOrgMemberSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *OrgMember) getUserByID(userID string) (*usr_view_model.UserView, error) {
|
||||
user, usrErr := u.view.UserByID(userID)
|
||||
if usrErr != nil && !caos_errs.IsNotFound(usrErr) {
|
||||
return nil, usrErr
|
||||
}
|
||||
if user == nil {
|
||||
user = &usr_view_model.UserView{}
|
||||
}
|
||||
events, err := u.getUserEvents(userID, user.Sequence)
|
||||
if err != nil {
|
||||
return user, usrErr
|
||||
}
|
||||
userCopy := *user
|
||||
for _, event := range events {
|
||||
if err := userCopy.AppendEvent(event); err != nil {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
if userCopy.State == int32(usr_model.UserStateDeleted) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "HANDLER-m9dos", "Errors.User.NotFound")
|
||||
}
|
||||
return &userCopy, nil
|
||||
}
|
||||
|
||||
func (u *OrgMember) getUserEvents(userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return u.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
)
|
||||
|
||||
@ -61,7 +61,7 @@ func (p *Project) EventQuery() (*models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proj_event.ProjectQuery(sequence.CurrentSequence), nil
|
||||
return proj_view.ProjectQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (p *Project) Reduce(event *models.Event) (err error) {
|
||||
|
@ -5,15 +5,18 @@ import (
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
)
|
||||
|
||||
@ -23,20 +26,14 @@ const (
|
||||
|
||||
type ProjectGrant struct {
|
||||
handler
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
orgEvents *org_event.OrgEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newProjectGrant(
|
||||
handler handler,
|
||||
projectEvents *proj_event.ProjectEventstore,
|
||||
orgEvents *org_event.OrgEventstore,
|
||||
) *ProjectGrant {
|
||||
h := &ProjectGrant{
|
||||
handler: handler,
|
||||
projectEvents: projectEvents,
|
||||
orgEvents: orgEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -74,7 +71,7 @@ func (p *ProjectGrant) EventQuery() (*models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proj_event.ProjectQuery(sequence.CurrentSequence), nil
|
||||
return proj_view.ProjectQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (p *ProjectGrant) Reduce(event *models.Event) (err error) {
|
||||
@ -97,11 +94,11 @@ func (p *ProjectGrant) Reduce(event *models.Event) (err error) {
|
||||
}
|
||||
grantedProject.Name = project.Name
|
||||
|
||||
org, err := p.orgEvents.OrgByID(context.TODO(), org_model.NewOrg(grantedProject.OrgID))
|
||||
org, err := p.getOrgByID(context.TODO(), grantedProject.OrgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resourceOwner, err := p.orgEvents.OrgByID(context.TODO(), org_model.NewOrg(grantedProject.ResourceOwner))
|
||||
resourceOwner, err := p.getOrgByID(context.TODO(), grantedProject.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -145,7 +142,7 @@ func (p *ProjectGrant) fillOrgData(grantedProject *view_model.ProjectGrantView,
|
||||
}
|
||||
|
||||
func (p *ProjectGrant) getProject(projectID string) (*proj_model.Project, error) {
|
||||
return p.projectEvents.ProjectByID(context.Background(), projectID)
|
||||
return p.getProjectByID(context.Background(), projectID)
|
||||
}
|
||||
|
||||
func (p *ProjectGrant) updateExistingProjects(project *view_model.ProjectView, event *models.Event) error {
|
||||
@ -167,3 +164,46 @@ func (p *ProjectGrant) OnError(event *models.Event, err error) error {
|
||||
func (p *ProjectGrant) OnSuccess() error {
|
||||
return spooler.HandleSuccess(p.view.UpdateProjectGrantSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *ProjectGrant) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3m9vs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *ProjectGrant) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(projID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esProject := &es_model.Project{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: projID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esProject.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esProject.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-NBrw2", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return es_model.ProjectToModel(esProject), nil
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
@ -13,7 +16,6 @@ import (
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
@ -23,17 +25,14 @@ const (
|
||||
|
||||
type ProjectGrantMember struct {
|
||||
handler
|
||||
userEvents *usr_event.UserEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newProjectGrantMember(
|
||||
handler handler,
|
||||
userEvents *usr_event.UserEventstore,
|
||||
) *ProjectGrantMember {
|
||||
h := &ProjectGrantMember{
|
||||
handler: handler,
|
||||
userEvents: userEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -140,7 +139,7 @@ func (p *ProjectGrantMember) processUser(event *models.Event) (err error) {
|
||||
if len(members) == 0 {
|
||||
return p.view.ProcessedProjectGrantMemberSequence(event)
|
||||
}
|
||||
user, err := p.userEvents.UserByID(context.Background(), event.AggregateID)
|
||||
user, err := p.getUserByID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -154,7 +153,7 @@ func (p *ProjectGrantMember) processUser(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (p *ProjectGrantMember) fillData(member *view_model.ProjectGrantMemberView) (err error) {
|
||||
user, err := p.userEvents.UserByID(context.Background(), member.UserID)
|
||||
user, err := p.getUserByID(member.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -162,16 +161,16 @@ func (p *ProjectGrantMember) fillData(member *view_model.ProjectGrantMemberView)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProjectGrantMember) fillUserData(member *view_model.ProjectGrantMemberView, user *usr_model.User) {
|
||||
func (p *ProjectGrantMember) fillUserData(member *view_model.ProjectGrantMemberView, user *usr_view_model.UserView) {
|
||||
member.UserName = user.UserName
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
member.FirstName = user.FirstName
|
||||
member.LastName = user.LastName
|
||||
member.DisplayName = user.FirstName + " " + user.LastName
|
||||
member.Email = user.EmailAddress
|
||||
member.Email = user.Email
|
||||
}
|
||||
if user.Machine != nil {
|
||||
member.DisplayName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
member.DisplayName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,3 +182,36 @@ func (p *ProjectGrantMember) OnError(event *models.Event, err error) error {
|
||||
func (p *ProjectGrantMember) OnSuccess() error {
|
||||
return spooler.HandleSuccess(p.view.UpdateProjectGrantMemberSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *ProjectGrantMember) getUserByID(userID string) (*usr_view_model.UserView, error) {
|
||||
user, usrErr := u.view.UserByID(userID)
|
||||
if usrErr != nil && !caos_errs.IsNotFound(usrErr) {
|
||||
return nil, usrErr
|
||||
}
|
||||
if user == nil {
|
||||
user = &usr_view_model.UserView{}
|
||||
}
|
||||
events, err := u.getUserEvents(userID, user.Sequence)
|
||||
if err != nil {
|
||||
return user, usrErr
|
||||
}
|
||||
userCopy := *user
|
||||
for _, event := range events {
|
||||
if err := userCopy.AppendEvent(event); err != nil {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
if userCopy.State == int32(usr_model.UserStateDeleted) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "HANDLER-m9dos", "Errors.User.NotFound")
|
||||
}
|
||||
return &userCopy, nil
|
||||
}
|
||||
|
||||
func (u *ProjectGrantMember) getUserEvents(userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return u.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
@ -13,8 +15,8 @@ import (
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -23,17 +25,14 @@ const (
|
||||
|
||||
type ProjectMember struct {
|
||||
handler
|
||||
userEvents *usr_event.UserEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newProjectMember(
|
||||
handler handler,
|
||||
userEvents *usr_event.UserEventstore,
|
||||
) *ProjectMember {
|
||||
h := &ProjectMember{
|
||||
handler: handler,
|
||||
userEvents: userEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -136,7 +135,7 @@ func (p *ProjectMember) processUser(event *models.Event) (err error) {
|
||||
if len(members) == 0 {
|
||||
return p.view.ProcessedProjectMemberSequence(event)
|
||||
}
|
||||
user, err := p.userEvents.UserByID(context.Background(), event.AggregateID)
|
||||
user, err := p.getUserByID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -151,7 +150,7 @@ func (p *ProjectMember) processUser(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (p *ProjectMember) fillData(member *view_model.ProjectMemberView) (err error) {
|
||||
user, err := p.userEvents.UserByID(context.Background(), member.UserID)
|
||||
user, err := p.getUserByID(member.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -159,16 +158,16 @@ func (p *ProjectMember) fillData(member *view_model.ProjectMemberView) (err erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProjectMember) fillUserData(member *view_model.ProjectMemberView, user *usr_model.User) {
|
||||
func (p *ProjectMember) fillUserData(member *view_model.ProjectMemberView, user *usr_view_model.UserView) {
|
||||
member.UserName = user.UserName
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
member.FirstName = user.FirstName
|
||||
member.LastName = user.LastName
|
||||
member.Email = user.EmailAddress
|
||||
member.Email = user.Email
|
||||
member.DisplayName = user.FirstName + " " + user.LastName
|
||||
}
|
||||
if user.Machine != nil {
|
||||
member.DisplayName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
member.DisplayName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
func (p *ProjectMember) OnError(event *models.Event, err error) error {
|
||||
@ -179,3 +178,36 @@ func (p *ProjectMember) OnError(event *models.Event, err error) error {
|
||||
func (p *ProjectMember) OnSuccess() error {
|
||||
return spooler.HandleSuccess(p.view.UpdateProjectMemberSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *ProjectMember) getUserByID(userID string) (*usr_view_model.UserView, error) {
|
||||
user, usrErr := u.view.UserByID(userID)
|
||||
if usrErr != nil && !caos_errs.IsNotFound(usrErr) {
|
||||
return nil, usrErr
|
||||
}
|
||||
if user == nil {
|
||||
user = &usr_view_model.UserView{}
|
||||
}
|
||||
events, err := u.getUserEvents(userID, user.Sequence)
|
||||
if err != nil {
|
||||
return user, usrErr
|
||||
}
|
||||
userCopy := *user
|
||||
for _, event := range events {
|
||||
if err := userCopy.AppendEvent(event); err != nil {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
if userCopy.State == int32(usr_model.UserStateDeleted) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "HANDLER-m9dos", "Errors.User.NotFound")
|
||||
}
|
||||
return &userCopy, nil
|
||||
}
|
||||
|
||||
func (u *ProjectMember) getUserEvents(userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return u.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
@ -7,9 +7,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
view_model "github.com/caos/zitadel/internal/project/repository/view/model"
|
||||
)
|
||||
|
||||
@ -19,17 +18,14 @@ const (
|
||||
|
||||
type ProjectRole struct {
|
||||
handler
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newProjectRole(
|
||||
handler handler,
|
||||
projectEvents *proj_event.ProjectEventstore,
|
||||
) *ProjectRole {
|
||||
h := &ProjectRole{
|
||||
handler: handler,
|
||||
projectEvents: projectEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -67,7 +63,7 @@ func (p *ProjectRole) EventQuery() (*models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eventsourcing.ProjectQuery(sequence.CurrentSequence), nil
|
||||
return proj_view.ProjectQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (p *ProjectRole) Reduce(event *models.Event) (err error) {
|
||||
|
@ -2,19 +2,23 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_es "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -23,23 +27,17 @@ const (
|
||||
|
||||
type User struct {
|
||||
handler
|
||||
orgEvents *org_events.OrgEventstore
|
||||
iamEvents *iam_es.IAMEventstore
|
||||
iamID string
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newUser(
|
||||
handler handler,
|
||||
orgEvents *org_events.OrgEventstore,
|
||||
iamEvents *iam_es.IAMEventstore,
|
||||
iamID string,
|
||||
) *User {
|
||||
h := &User{
|
||||
handler: handler,
|
||||
orgEvents: orgEvents,
|
||||
iamEvents: iamEvents,
|
||||
iamID: iamID,
|
||||
handler: handler,
|
||||
iamID: iamID,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -180,13 +178,13 @@ func (u *User) ProcessOrg(event *models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (u *User) fillLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.iamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -202,13 +200,13 @@ func (u *User) fillLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
}
|
||||
|
||||
func (u *User) fillPreferredLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.iamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -227,13 +225,13 @@ func (u *User) fillPreferredLoginNamesOnOrgUsers(event *models.Event) error {
|
||||
}
|
||||
|
||||
func (u *User) fillLoginNames(user *view_model.UserView) (err error) {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(user.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.iamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -251,3 +249,53 @@ func (u *User) OnError(event *models.Event, err error) error {
|
||||
func (u *User) OnSuccess() error {
|
||||
return spooler.HandleSuccess(u.view.UpdateUserSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *User) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-kVLb2", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *User) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *User) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2Fj8s", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
}
|
||||
|
@ -2,6 +2,11 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
"github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
@ -12,10 +17,8 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@ -28,22 +31,16 @@ const (
|
||||
type ExternalIDP struct {
|
||||
handler
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
iamEvents *eventsourcing.IAMEventstore
|
||||
orgEvents *org_es.OrgEventstore
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newExternalIDP(
|
||||
handler handler,
|
||||
systemDefaults systemdefaults.SystemDefaults,
|
||||
iamEvents *eventsourcing.IAMEventstore,
|
||||
orgEvents *org_es.OrgEventstore,
|
||||
) *ExternalIDP {
|
||||
h := &ExternalIDP{
|
||||
handler: handler,
|
||||
systemDefaults: systemDefaults,
|
||||
iamEvents: iamEvents,
|
||||
orgEvents: orgEvents,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -137,9 +134,9 @@ func (i *ExternalIDP) processIdpConfig(event *es_models.Event) (err error) {
|
||||
return err
|
||||
}
|
||||
if event.AggregateType == iam_es_model.IAMAggregate {
|
||||
config, err = i.iamEvents.GetIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID)
|
||||
config, err = i.getDefaultIDPConfig(context.Background(), configView.IDPConfigID)
|
||||
} else {
|
||||
config, err = i.orgEvents.GetIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID)
|
||||
config, err = i.getOrgIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -155,9 +152,9 @@ func (i *ExternalIDP) processIdpConfig(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) fillData(externalIDP *usr_view_model.ExternalIDPView) error {
|
||||
config, err := i.orgEvents.GetIDPConfig(context.Background(), externalIDP.ResourceOwner, externalIDP.IDPConfigID)
|
||||
config, err := i.getOrgIDPConfig(context.Background(), externalIDP.ResourceOwner, externalIDP.IDPConfigID)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
config, err = i.iamEvents.GetIDPConfig(context.Background(), i.systemDefaults.IamID, externalIDP.IDPConfigID)
|
||||
config, err = i.getDefaultIDPConfig(context.Background(), externalIDP.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -178,3 +175,64 @@ func (i *ExternalIDP) OnError(event *es_models.Event, err error) error {
|
||||
func (i *ExternalIDP) OnSuccess() error {
|
||||
return spooler.HandleSuccess(i.view.UpdateExternalIDPSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := i.getOrgByID(ctx, aggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, i := existing.GetIDP(idpConfigID); i != nil {
|
||||
return i, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-22n7G", "Errors.Org.IdpNotExisting")
|
||||
}
|
||||
|
||||
func (i *ExternalIDP) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-4m0fs", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *ExternalIDP) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &iam_es_model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *ExternalIDP) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil {
|
||||
return existingIDP, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-22Nv8", "Errors.IAM.IdpNotExisting")
|
||||
}
|
||||
|
@ -4,18 +4,25 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_events "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
grant_es_model "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||
@ -27,23 +34,14 @@ const (
|
||||
|
||||
type UserGrant struct {
|
||||
handler
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
userEvents *usr_events.UserEventstore
|
||||
orgEvents *org_events.OrgEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newUserGrant(
|
||||
handler handler,
|
||||
projectEvents *proj_event.ProjectEventstore,
|
||||
userEvents *usr_events.UserEventstore,
|
||||
orgEvents *org_events.OrgEventstore,
|
||||
) *UserGrant {
|
||||
h := &UserGrant{
|
||||
handler: handler,
|
||||
projectEvents: projectEvents,
|
||||
userEvents: userEvents,
|
||||
orgEvents: orgEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -141,7 +139,7 @@ func (u *UserGrant) processUser(event *es_models.Event) (err error) {
|
||||
if len(grants) == 0 {
|
||||
return u.view.ProcessedUserGrantSequence(event)
|
||||
}
|
||||
user, err := u.userEvents.UserByID(context.Background(), event.AggregateID)
|
||||
user, err := u.getUserByID(event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -164,7 +162,7 @@ func (u *UserGrant) processProject(event *es_models.Event) (err error) {
|
||||
if len(grants) == 0 {
|
||||
return u.view.ProcessedUserGrantSequence(event)
|
||||
}
|
||||
project, err := u.projectEvents.ProjectByID(context.Background(), event.AggregateID)
|
||||
project, err := u.getProjectByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -178,18 +176,18 @@ func (u *UserGrant) processProject(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (u *UserGrant) fillData(grant *view_model.UserGrantView, resourceOwner string) (err error) {
|
||||
user, err := u.userEvents.UserByID(context.Background(), grant.UserID)
|
||||
user, err := u.getUserByID(grant.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.fillUserData(grant, user)
|
||||
project, err := u.projectEvents.ProjectByID(context.Background(), grant.ProjectID)
|
||||
project, err := u.getProjectByID(context.Background(), grant.ProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.fillProjectData(grant, project)
|
||||
|
||||
org, err := u.orgEvents.OrgByID(context.TODO(), org_model.NewOrg(resourceOwner))
|
||||
org, err := u.getOrgByID(context.TODO(), resourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -197,16 +195,16 @@ func (u *UserGrant) fillData(grant *view_model.UserGrantView, resourceOwner stri
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserGrant) fillUserData(grant *view_model.UserGrantView, user *usr_model.User) {
|
||||
func (u *UserGrant) fillUserData(grant *view_model.UserGrantView, user *usr_view_model.UserView) {
|
||||
grant.UserName = user.UserName
|
||||
if user.Human != nil {
|
||||
if user.HumanView != nil {
|
||||
grant.FirstName = user.FirstName
|
||||
grant.LastName = user.LastName
|
||||
grant.DisplayName = user.FirstName + " " + user.LastName
|
||||
grant.Email = user.EmailAddress
|
||||
grant.Email = user.Email
|
||||
}
|
||||
if user.Machine != nil {
|
||||
grant.DisplayName = user.Machine.Name
|
||||
if user.MachineView != nil {
|
||||
grant.DisplayName = user.MachineView.Name
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,3 +231,79 @@ func (u *UserGrant) OnError(event *es_models.Event, err error) error {
|
||||
func (u *UserGrant) OnSuccess() error {
|
||||
return spooler.HandleSuccess(u.view.UpdateUserGrantSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *UserGrant) getUserByID(userID string) (*usr_view_model.UserView, error) {
|
||||
user, usrErr := u.view.UserByID(userID)
|
||||
if usrErr != nil && !caos_errs.IsNotFound(usrErr) {
|
||||
return nil, usrErr
|
||||
}
|
||||
if user == nil {
|
||||
user = &usr_view_model.UserView{}
|
||||
}
|
||||
events, err := u.getUserEvents(userID, user.Sequence)
|
||||
if err != nil {
|
||||
return user, usrErr
|
||||
}
|
||||
userCopy := *user
|
||||
for _, event := range events {
|
||||
if err := userCopy.AppendEvent(event); err != nil {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
if userCopy.State == int32(usr_model.UserStateDeleted) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "HANDLER-m9dos", "Errors.User.NotFound")
|
||||
}
|
||||
return &userCopy, nil
|
||||
}
|
||||
|
||||
func (u *UserGrant) getUserEvents(userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return u.es.FilterEvents(context.Background(), query)
|
||||
}
|
||||
|
||||
func (u *UserGrant) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-kVLb2", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *UserGrant) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(projID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esProject := &proj_es_model.Project{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: projID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esProject.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esProject.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-Dfb42", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return proj_es_model.ProjectToModel(esProject), nil
|
||||
}
|
||||
|
@ -3,6 +3,14 @@ package handler
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
proj_view "github.com/caos/zitadel/internal/project/repository/view"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
@ -11,9 +19,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
@ -26,20 +32,14 @@ const (
|
||||
|
||||
type UserMembership struct {
|
||||
handler
|
||||
orgEvents *org_event.OrgEventstore
|
||||
projectEvents *proj_event.ProjectEventstore
|
||||
subscription *eventstore.Subscription
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newUserMembership(
|
||||
handler handler,
|
||||
orgEvents *org_event.OrgEventstore,
|
||||
projectEvents *proj_event.ProjectEventstore,
|
||||
) *UserMembership {
|
||||
h := &UserMembership{
|
||||
handler: handler,
|
||||
orgEvents: orgEvents,
|
||||
projectEvents: projectEvents,
|
||||
handler: handler,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -155,7 +155,7 @@ func (m *UserMembership) processOrg(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *UserMembership) fillOrgDisplayName(member *usr_es_model.UserMembershipView) (err error) {
|
||||
org, err := m.orgEvents.OrgByID(context.Background(), org_model.NewOrg(member.AggregateID))
|
||||
org, err := m.getOrgByID(context.Background(), member.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -164,7 +164,7 @@ func (m *UserMembership) fillOrgDisplayName(member *usr_es_model.UserMembershipV
|
||||
}
|
||||
|
||||
func (m *UserMembership) updateOrgDisplayName(event *es_models.Event) error {
|
||||
org, err := m.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.AggregateID))
|
||||
org, err := m.getOrgByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -220,7 +220,7 @@ func (m *UserMembership) processProject(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembershipView) (err error) {
|
||||
project, err := m.projectEvents.ProjectByID(context.Background(), member.AggregateID)
|
||||
project, err := m.getProjectByID(context.Background(), member.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -229,7 +229,7 @@ func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembers
|
||||
}
|
||||
|
||||
func (m *UserMembership) updateProjectDisplayName(event *es_models.Event) error {
|
||||
project, err := m.projectEvents.ProjectByID(context.Background(), event.AggregateID)
|
||||
project, err := m.getProjectByID(context.Background(), event.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -261,3 +261,46 @@ func (m *UserMembership) OnError(event *es_models.Event, err error) error {
|
||||
func (m *UserMembership) OnSuccess() error {
|
||||
return spooler.HandleSuccess(m.view.UpdateUserMembershipSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *UserMembership) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := &org_es_model.Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-kVLb2", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *UserMembership) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) {
|
||||
query, err := proj_view.ProjectByIDQuery(projID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
esProject := &proj_es_model.Project{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: projID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esProject.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esProject.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-Bg32b", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return proj_es_model.ProjectToModel(esProject), nil
|
||||
}
|
||||
|
@ -1,22 +1,15 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
|
||||
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"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
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"
|
||||
mgmt_view "github.com/caos/zitadel/internal/management/repository/eventsourcing/view"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -34,6 +27,7 @@ type EsRepository struct {
|
||||
eventstore.UserRepo
|
||||
eventstore.UserGrantRepo
|
||||
eventstore.IAMRepository
|
||||
view *mgmt_view.View
|
||||
}
|
||||
|
||||
func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRepository, error) {
|
||||
@ -53,55 +47,25 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe
|
||||
return nil, err
|
||||
}
|
||||
|
||||
project, err := es_proj.StartProject(es_proj.ProjectConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user, err := es_usr.StartUser(es_usr.UserConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iamV2Query, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults)
|
||||
|
||||
iam, err := es_iam.StartIAM(es_iam.IAMConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eventstoreRepos := handler.EventstoreRepos{ProjectEvents: project, UserEvents: user, OrgEvents: org, IamEvents: iam}
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, eventstoreRepos, systemDefaults)
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults)
|
||||
|
||||
return &EsRepository{
|
||||
spooler: spool,
|
||||
OrgRepository: eventstore.OrgRepository{conf.SearchLimit, org, user, iam, view, roles, systemDefaults},
|
||||
ProjectRepo: eventstore.ProjectRepo{es, conf.SearchLimit, project, user, iam, view, roles, systemDefaults.IamID},
|
||||
UserRepo: eventstore.UserRepo{es, conf.SearchLimit, user, org, view, systemDefaults},
|
||||
OrgRepository: eventstore.OrgRepository{conf.SearchLimit, es, view, roles, systemDefaults},
|
||||
ProjectRepo: eventstore.ProjectRepo{es, conf.SearchLimit, view, roles, systemDefaults.IamID},
|
||||
UserRepo: eventstore.UserRepo{es, conf.SearchLimit, view, systemDefaults},
|
||||
UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, view},
|
||||
IAMRepository: eventstore.IAMRepository{
|
||||
IAMV2Query: iamV2Query,
|
||||
},
|
||||
view: view,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (repo *EsRepository) Health() error {
|
||||
return repo.ProjectEvents.Health(context.Background())
|
||||
}
|
||||
|
||||
func (repo *EsRepository) IAMByID(ctx context.Context, id string) (*iam_model.IAM, error) {
|
||||
return repo.IAMRepository.IAMByID(ctx, id)
|
||||
return repo.view.Health()
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ type SpoolerConfig struct {
|
||||
Handlers handler.Configs
|
||||
}
|
||||
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, eventstoreRepos handler.EventstoreRepos, defaults systemdefaults.SystemDefaults) *spooler.Spooler {
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, defaults systemdefaults.SystemDefaults) *spooler.Spooler {
|
||||
spoolerConfig := spooler.Config{
|
||||
Eventstore: es,
|
||||
Locker: &locker{dbClient: sql},
|
||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, eventstoreRepos, defaults),
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, defaults),
|
||||
}
|
||||
spool := spoolerConfig.New()
|
||||
spool.Start()
|
||||
|
@ -2,6 +2,7 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
|
||||
key_model "github.com/caos/zitadel/internal/key/model"
|
||||
"github.com/caos/zitadel/internal/project/model"
|
||||
@ -28,12 +29,12 @@ type ProjectRepository interface {
|
||||
ApplicationChanges(ctx context.Context, id string, secId string, lastSequence uint64, limit uint64, sortAscending bool) (*model.ApplicationChanges, error)
|
||||
SearchClientKeys(ctx context.Context, request *key_model.AuthNKeySearchRequest) (*key_model.AuthNKeySearchResponse, error)
|
||||
GetClientKey(ctx context.Context, projectID, applicationID, keyID string) (*key_model.AuthNKeyView, error)
|
||||
AddClientKey(ctx context.Context, key *model.ClientKey) (*model.ClientKey, error)
|
||||
RemoveClientKey(ctx context.Context, projectID, applicationID, keyID string) error
|
||||
|
||||
ProjectGrantByID(ctx context.Context, grantID string) (*model.ProjectGrantView, error)
|
||||
SearchProjectGrantMembers(ctx context.Context, request *model.ProjectGrantMemberSearchRequest) (*model.ProjectGrantMemberSearchResponse, error)
|
||||
|
||||
ProjectGrantMemberByID(ctx context.Context, projectID, userID string) (*model.ProjectGrantMemberView, error)
|
||||
GetProjectGrantMemberRoles() []string
|
||||
|
||||
GetIAMByID(ctx context.Context) (*iam_model.IAM, error)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ type UserRepository interface {
|
||||
|
||||
UserMFAs(ctx context.Context, userID string) ([]*model.MultiFactor, error)
|
||||
|
||||
GetPasswordless(ctx context.Context, userID string) ([]*model.WebAuthNToken, error)
|
||||
GetPasswordless(ctx context.Context, userID string) ([]*model.WebAuthNView, error)
|
||||
|
||||
SearchExternalIDPs(ctx context.Context, request *model.ExternalIDPSearchRequest) (*model.ExternalIDPSearchResponse, error)
|
||||
ExternalIDPsByIDPConfigID(ctx context.Context, idpConfigID string) ([]*model.ExternalIDPView, error)
|
||||
|
@ -12,10 +12,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
iam_es "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/notification/repository/eventsourcing/view"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Configs map[string]*Config
|
||||
@ -37,13 +34,7 @@ func (h *handler) Eventstore() eventstore.Eventstore {
|
||||
return h.es
|
||||
}
|
||||
|
||||
type EventstoreRepos struct {
|
||||
UserEvents *usr_event.UserEventstore
|
||||
OrgEvents *org_event.OrgEventstore
|
||||
IAMEvents *iam_es.IAMEventstore
|
||||
}
|
||||
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, command *command.CommandSide, repos EventstoreRepos, systemDefaults sd.SystemDefaults, i18n *i18n.Translator, dir http.FileSystem) []query.Handler {
|
||||
func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es eventstore.Eventstore, command *command.CommandSide, systemDefaults sd.SystemDefaults, i18n *i18n.Translator, dir http.FileSystem) []query.Handler {
|
||||
aesCrypto, err := crypto.NewAESCrypto(systemDefaults.UserVerificationKey)
|
||||
if err != nil {
|
||||
logging.Log("HANDL-s90ew").WithError(err).Debug("error create new aes crypto")
|
||||
@ -51,14 +42,11 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es
|
||||
return []query.Handler{
|
||||
newNotifyUser(
|
||||
handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es},
|
||||
repos.OrgEvents,
|
||||
repos.IAMEvents,
|
||||
systemDefaults.IamID,
|
||||
),
|
||||
newNotification(
|
||||
handler{view, bulkLimit, configs.cycleDuration("Notification"), errorCount, es},
|
||||
command,
|
||||
repos.UserEvents,
|
||||
systemDefaults,
|
||||
aesCrypto,
|
||||
i18n,
|
||||
|
@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/caos/zitadel/internal/user/repository/view"
|
||||
"github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
@ -24,7 +25,6 @@ import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/notification/types"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
@ -47,7 +47,6 @@ const (
|
||||
type Notification struct {
|
||||
handler
|
||||
command *command.CommandSide
|
||||
userEvents *usr_event.UserEventstore
|
||||
systemDefaults sd.SystemDefaults
|
||||
AesCrypto crypto.EncryptionAlgorithm
|
||||
i18n *i18n.Translator
|
||||
@ -58,7 +57,6 @@ type Notification struct {
|
||||
func newNotification(
|
||||
handler handler,
|
||||
command *command.CommandSide,
|
||||
userEvents *usr_event.UserEventstore,
|
||||
defaults sd.SystemDefaults,
|
||||
aesCrypto crypto.EncryptionAlgorithm,
|
||||
translator *i18n.Translator,
|
||||
@ -67,7 +65,6 @@ func newNotification(
|
||||
h := &Notification{
|
||||
handler: handler,
|
||||
command: command,
|
||||
userEvents: userEvents,
|
||||
systemDefaults: defaults,
|
||||
i18n: translator,
|
||||
statikDir: statikDir,
|
||||
@ -109,7 +106,7 @@ func (n *Notification) EventQuery() (*models.SearchQuery, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return usr_event.UserQuery(sequence.CurrentSequence), nil
|
||||
return view.UserQuery(sequence.CurrentSequence), nil
|
||||
}
|
||||
|
||||
func (n *Notification) Reduce(event *models.Event) (err error) {
|
||||
@ -331,7 +328,7 @@ func (n *Notification) checkIfAlreadyHandled(userID string, sequence uint64, eve
|
||||
}
|
||||
|
||||
func (n *Notification) getUserEvents(userID string, sequence uint64) ([]*models.Event, error) {
|
||||
query, err := usr_event.UserByIDQuery(userID, sequence)
|
||||
query, err := view.UserByIDQuery(userID, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2,15 +2,20 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
iam_view "github.com/caos/zitadel/internal/iam/repository/view"
|
||||
org_view "github.com/caos/zitadel/internal/org/repository/view"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/query"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_es "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_events "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/user/repository/view/model"
|
||||
@ -22,23 +27,17 @@ const (
|
||||
|
||||
type NotifyUser struct {
|
||||
handler
|
||||
orgEvents *org_events.OrgEventstore
|
||||
iamEvents *iam_es.IAMEventstore
|
||||
iamID string
|
||||
subscription *eventstore.Subscription
|
||||
}
|
||||
|
||||
func newNotifyUser(
|
||||
handler handler,
|
||||
orgEvents *org_events.OrgEventstore,
|
||||
iamEvents *iam_es.IAMEventstore,
|
||||
iamID string,
|
||||
) *NotifyUser {
|
||||
h := &NotifyUser{
|
||||
handler: handler,
|
||||
orgEvents: orgEvents,
|
||||
iamEvents: iamEvents,
|
||||
iamID: iamID,
|
||||
handler: handler,
|
||||
iamID: iamID,
|
||||
}
|
||||
|
||||
h.subscribe()
|
||||
@ -157,13 +156,13 @@ func (u *NotifyUser) ProcessOrg(event *es_models.Event) (err error) {
|
||||
}
|
||||
|
||||
func (u *NotifyUser) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.iamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -183,13 +182,13 @@ func (u *NotifyUser) fillLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
}
|
||||
|
||||
func (u *NotifyUser) fillPreferredLoginNamesOnOrgUsers(event *es_models.Event) error {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(event.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), event.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.iamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -212,13 +211,13 @@ func (u *NotifyUser) fillPreferredLoginNamesOnOrgUsers(event *es_models.Event) e
|
||||
}
|
||||
|
||||
func (u *NotifyUser) fillLoginNames(user *view_model.NotifyUser) (err error) {
|
||||
org, err := u.orgEvents.OrgByID(context.Background(), org_model.NewOrg(user.ResourceOwner))
|
||||
org, err := u.getOrgByID(context.Background(), user.ResourceOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policy := org.OrgIamPolicy
|
||||
if policy == nil {
|
||||
policy, err = u.iamEvents.GetOrgIAMPolicy(context.Background(), u.iamID)
|
||||
policy, err = u.getDefaultOrgIAMPolicy(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -236,3 +235,49 @@ func (p *NotifyUser) OnError(event *es_models.Event, err error) error {
|
||||
func (u *NotifyUser) OnSuccess() error {
|
||||
return spooler.HandleSuccess(u.view.UpdateNotifyUserSpoolerRunTimestamp)
|
||||
}
|
||||
|
||||
func (u *NotifyUser) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
query, err := org_view.OrgByIDQuery(orgID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var esOrg *org_es_model.Org
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-kVLb2", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return org_es_model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (u *NotifyUser) getIAMByID(ctx context.Context) (*iam_model.IAM, error) {
|
||||
query, err := iam_view.IAMByIDQuery(domain.IAMID, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam := &model.IAM{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: domain.IAMID,
|
||||
},
|
||||
}
|
||||
err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return model.IAMToModel(iam), nil
|
||||
}
|
||||
|
||||
func (u *NotifyUser) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingIAM, err := u.getIAMByID(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIAM.DefaultOrgIAMPolicy == nil {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-2Fj8s", "Errors.IAM.OrgIAMPolicy.NotExisting")
|
||||
}
|
||||
return existingIAM.DefaultOrgIAMPolicy, nil
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
"net/http"
|
||||
|
||||
@ -10,11 +9,8 @@ import (
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
es_spol "github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
"github.com/caos/zitadel/internal/i18n"
|
||||
"github.com/caos/zitadel/internal/notification/repository/eventsourcing/handler"
|
||||
"github.com/caos/zitadel/internal/notification/repository/eventsourcing/spooler"
|
||||
noti_view "github.com/caos/zitadel/internal/notification/repository/eventsourcing/view"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
@ -45,28 +41,11 @@ func Start(conf Config, dir http.FileSystem, systemDefaults sd.SystemDefaults, c
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, err := es_usr.StartUser(es_usr.UserConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: conf.Domain}, systemDefaults)
|
||||
|
||||
translator, err := i18n.NewTranslator(dir, i18n.TranslatorConfig{DefaultLanguage: conf.DefaultLanguage})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam, err := es_iam.StartIAM(es_iam.IAMConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eventstoreRepos := handler.EventstoreRepos{UserEvents: user, OrgEvents: org, IAMEvents: iam}
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, command, eventstoreRepos, systemDefaults, translator, dir)
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, command, systemDefaults, translator, dir)
|
||||
|
||||
return &EsRepository{
|
||||
spool,
|
||||
|
@ -20,12 +20,12 @@ type SpoolerConfig struct {
|
||||
Handlers handler.Configs
|
||||
}
|
||||
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, command *command.CommandSide, eventstoreRepos handler.EventstoreRepos, systemDefaults sd.SystemDefaults, i18n *i18n.Translator, dir http.FileSystem) *spooler.Spooler {
|
||||
func StartSpooler(c SpoolerConfig, es eventstore.Eventstore, view *view.View, sql *sql.DB, command *command.CommandSide, systemDefaults sd.SystemDefaults, i18n *i18n.Translator, dir http.FileSystem) *spooler.Spooler {
|
||||
spoolerConfig := spooler.Config{
|
||||
Eventstore: es,
|
||||
Locker: &locker{dbClient: sql},
|
||||
ConcurrentWorkers: c.ConcurrentWorkers,
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, command, eventstoreRepos, systemDefaults, i18n, dir),
|
||||
ViewHandlers: handler.Register(c.Handlers, c.BulkLimit, c.FailureCountUntilSkip, view, es, command, systemDefaults, i18n, dir),
|
||||
}
|
||||
spool := spoolerConfig.New()
|
||||
spool.Start()
|
||||
|
@ -1,191 +0,0 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/logging"
|
||||
http_utils "github.com/caos/zitadel/internal/api/http"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"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"
|
||||
"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 {
|
||||
eventstore.Eventstore
|
||||
IAMDomain string
|
||||
IamID string
|
||||
idGenerator id.Generator
|
||||
verificationAlgorithm crypto.EncryptionAlgorithm
|
||||
verificationGenerator crypto.Generator
|
||||
verificationValidator func(domain string, token string, verifier string, checkType http_utils.CheckType) error
|
||||
secretCrypto crypto.Crypto
|
||||
}
|
||||
|
||||
type OrgConfig struct {
|
||||
eventstore.Eventstore
|
||||
IAMDomain string
|
||||
VerificationConfig *crypto.KeyConfig
|
||||
}
|
||||
|
||||
func StartOrg(conf OrgConfig, defaults systemdefaults.SystemDefaults) *OrgEventstore {
|
||||
verificationAlg, err := crypto.NewAESCrypto(defaults.DomainVerification.VerificationKey)
|
||||
logging.Log("EVENT-aZ22d").OnError(err).Panic("cannot create verificationAlgorithm for domain verification")
|
||||
verificationGen := crypto.NewEncryptionGenerator(defaults.DomainVerification.VerificationGenerator, verificationAlg)
|
||||
|
||||
aesCrypto, err := crypto.NewAESCrypto(defaults.IDPConfigVerificationKey)
|
||||
logging.Log("EVENT-Sn8du").OnError(err).Panic("cannot create verificationAlgorithm for idp config verification")
|
||||
|
||||
return &OrgEventstore{
|
||||
Eventstore: conf.Eventstore,
|
||||
idGenerator: id.SonyFlakeGenerator,
|
||||
verificationAlgorithm: verificationAlg,
|
||||
verificationGenerator: verificationGen,
|
||||
verificationValidator: http_utils.ValidateDomain,
|
||||
IAMDomain: conf.IAMDomain,
|
||||
IamID: defaults.IamID,
|
||||
secretCrypto: aesCrypto,
|
||||
}
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) OrgByID(ctx context.Context, org *org_model.Org) (*org_model.Org, error) {
|
||||
if org == nil {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "EVENT-gQTYP", "Errors.Org.Empty")
|
||||
}
|
||||
query, err := OrgByIDQuery(org.AggregateID, org.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := model.OrgFromModel(org)
|
||||
err = es_sdk.Filter(ctx, es.FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-kVLb2", "Errors.Org.NotFound")
|
||||
}
|
||||
|
||||
return model.OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) OrgEventsByID(ctx context.Context, id string, sequence uint64) ([]*es_models.Event, error) {
|
||||
query, err := OrgByIDQuery(id, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return es.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) IsOrgUnique(ctx context.Context, name, domain string) (isUnique bool, err error) {
|
||||
var found bool
|
||||
err = es_sdk.Filter(ctx, es.FilterEvents, isUniqueValidation(&found), OrgNameUniqueQuery(name))
|
||||
if (err != nil && !errors.IsNotFound(err)) || found {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = es_sdk.Filter(ctx, es.FilterEvents, isUniqueValidation(&found), OrgDomainUniqueQuery(domain))
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return !found, nil
|
||||
}
|
||||
|
||||
func isUniqueValidation(unique *bool) func(events ...*es_models.Event) error {
|
||||
return func(events ...*es_models.Event) error {
|
||||
if len(events) == 0 {
|
||||
return nil
|
||||
}
|
||||
*unique = *unique || events[0].Type == model.OrgDomainReserved || events[0].Type == model.OrgNameReserved
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) OrgChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*org_model.OrgChanges, error) {
|
||||
query := ChangesQuery(id, lastSequence, limit, sortAscending)
|
||||
|
||||
events, err := es.Eventstore.FilterEvents(context.Background(), query)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-ZRffs").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, errors.ThrowInternal(err, "EVENT-328b1", "Errors.Org.NotFound")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-FpQqK", "Errors.Changes.NotFound")
|
||||
}
|
||||
|
||||
changes := make([]*org_model.OrgChange, len(events))
|
||||
|
||||
for i, event := range events {
|
||||
creationDate, err := ptypes.TimestampProto(event.CreationDate)
|
||||
logging.Log("EVENT-qxIR7").OnError(err).Debug("unable to parse timestamp")
|
||||
change := &org_model.OrgChange{
|
||||
ChangeDate: creationDate,
|
||||
EventType: event.Type.String(),
|
||||
ModifierId: event.EditorUser,
|
||||
Sequence: event.Sequence,
|
||||
}
|
||||
|
||||
if event.Data != nil {
|
||||
org := new(model.Org)
|
||||
err := json.Unmarshal(event.Data, org)
|
||||
logging.Log("EVENT-XCLEm").OnError(err).Debug("unable to unmarshal data")
|
||||
change.Data = org
|
||||
}
|
||||
|
||||
changes[i] = change
|
||||
if lastSequence < event.Sequence {
|
||||
lastSequence = event.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
return &org_model.OrgChanges{
|
||||
Changes: changes,
|
||||
LastSequence: lastSequence,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ChangesQuery(orgID string, latestSequence, limit uint64, sortAscending bool) *es_models.SearchQuery {
|
||||
query := es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.OrgAggregate)
|
||||
|
||||
if !sortAscending {
|
||||
query.OrderDesc()
|
||||
}
|
||||
|
||||
query.LatestSequenceFilter(latestSequence).
|
||||
AggregateIDFilter(orgID).
|
||||
SetLimit(limit)
|
||||
return query
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) GetOrgIAMPolicy(ctx context.Context, orgID string) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(orgID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingOrg.OrgIamPolicy == nil {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-3F9sf", "Errors.Org.OrgIAM.NotExisting")
|
||||
}
|
||||
return existingOrg.OrgIamPolicy, nil
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) GetIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
existing, err := es.OrgByID(ctx, org_model.NewOrg(aggregateID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, i := existing.GetIDP(idpConfigID); i != nil {
|
||||
return i, nil
|
||||
}
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-Qlo0d", "Errors.Org.IdpNotExisting")
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package repository
|
||||
|
||||
import es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
|
||||
type Org struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
Name string
|
||||
Domain string
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
package eventsourcing
|
||||
package view
|
||||
|
||||
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"
|
||||
@ -16,6 +14,12 @@ func OrgByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, err
|
||||
AggregateIDFilter(id), nil
|
||||
}
|
||||
|
||||
func OrgQuery(latestSequence uint64) *es_models.SearchQuery {
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.OrgAggregate).
|
||||
LatestSequenceFilter(latestSequence)
|
||||
}
|
||||
|
||||
func OrgDomainUniqueQuery(domain string) *es_models.SearchQuery {
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.OrgDomainAggregate).
|
||||
@ -32,12 +36,16 @@ func OrgNameUniqueQuery(name string) *es_models.SearchQuery {
|
||||
SetLimit(1)
|
||||
}
|
||||
|
||||
func OrgQuery(latestSequence uint64) *es_models.SearchQuery {
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.OrgAggregate).
|
||||
LatestSequenceFilter(latestSequence)
|
||||
}
|
||||
func ChangesQuery(orgID string, latestSequence, limit uint64, sortAscending bool) *es_models.SearchQuery {
|
||||
query := es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.OrgAggregate)
|
||||
|
||||
func OrgAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, id string, sequence uint64) (*es_models.Aggregate, error) {
|
||||
return aggCreator.NewAggregate(ctx, id, model.OrgAggregate, model.OrgVersion, sequence, es_models.OverwriteResourceOwner(id))
|
||||
if !sortAscending {
|
||||
query.OrderDesc()
|
||||
}
|
||||
|
||||
query.LatestSequenceFilter(latestSequence).
|
||||
AggregateIDFilter(orgID).
|
||||
SetLimit(limit)
|
||||
return query
|
||||
}
|
@ -1,206 +1,46 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
|
||||
"github.com/caos/zitadel/internal/cache/config"
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
"github.com/caos/zitadel/internal/id"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
"github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
const (
|
||||
projectOwnerRole = "PROJECT_OWNER"
|
||||
projectOwnerGlobalRole = "PROJECT_OWNER_GLOBAL"
|
||||
)
|
||||
|
||||
type ProjectEventstore struct {
|
||||
es_int.Eventstore
|
||||
projectCache *ProjectCache
|
||||
passwordAlg crypto.HashAlgorithm
|
||||
pwGenerator crypto.Generator
|
||||
idGenerator id.Generator
|
||||
ClientKeySize int
|
||||
}
|
||||
|
||||
type ProjectConfig struct {
|
||||
es_int.Eventstore
|
||||
Cache *config.CacheConfig
|
||||
}
|
||||
|
||||
func StartProject(conf ProjectConfig, systemDefaults sd.SystemDefaults) (*ProjectEventstore, error) {
|
||||
projectCache, err := StartCache(conf.Cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
passwordAlg := crypto.NewBCrypt(systemDefaults.SecretGenerators.PasswordSaltCost)
|
||||
pwGenerator := crypto.NewHashGenerator(systemDefaults.SecretGenerators.ClientSecretGenerator, passwordAlg)
|
||||
return &ProjectEventstore{
|
||||
Eventstore: conf.Eventstore,
|
||||
projectCache: projectCache,
|
||||
passwordAlg: passwordAlg,
|
||||
pwGenerator: pwGenerator,
|
||||
idGenerator: id.SonyFlakeGenerator,
|
||||
ClientKeySize: int(systemDefaults.SecretGenerators.ApplicationKeySize),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (es *ProjectEventstore) ProjectByID(ctx context.Context, id string) (*proj_model.Project, error) {
|
||||
project := es.projectCache.getProject(id)
|
||||
|
||||
query, err := ProjectByIDQuery(project.AggregateID, project.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = es_sdk.Filter(ctx, es.FilterEvents, project.AppendEvents, query)
|
||||
if err != nil && !(caos_errs.IsNotFound(err) && project.Sequence != 0) {
|
||||
return nil, err
|
||||
}
|
||||
if project.State == int32(proj_model.ProjectStateRemoved) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-dG8ie", "Errors.Project.NotFound")
|
||||
}
|
||||
es.projectCache.cacheProject(project)
|
||||
return model.ProjectToModel(project), nil
|
||||
}
|
||||
|
||||
func (es *ProjectEventstore) ProjectEventsByID(ctx context.Context, id string, sequence uint64) ([]*es_models.Event, error) {
|
||||
query, err := ProjectByIDQuery(id, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return es.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (es *ProjectEventstore) ProjectChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*proj_model.ProjectChanges, error) {
|
||||
query := ChangesQuery(id, lastSequence, limit, sortAscending)
|
||||
|
||||
events, err := es.Eventstore.FilterEvents(context.Background(), query)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-ZRffs").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, errors.ThrowInternal(err, "EVENT-328b1", "Errors.Internal")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-FpQqK", "Errors.Changes.NotFound")
|
||||
}
|
||||
|
||||
changes := make([]*proj_model.ProjectChange, len(events))
|
||||
|
||||
for i, event := range events {
|
||||
creationDate, err := ptypes.TimestampProto(event.CreationDate)
|
||||
logging.Log("EVENT-qxIR7").OnError(err).Debug("unable to parse timestamp")
|
||||
change := &proj_model.ProjectChange{
|
||||
ChangeDate: creationDate,
|
||||
EventType: event.Type.String(),
|
||||
ModifierId: event.EditorUser,
|
||||
Sequence: event.Sequence,
|
||||
}
|
||||
|
||||
if event.Data != nil {
|
||||
var data interface{}
|
||||
if strings.Contains(change.EventType, "application") {
|
||||
data = new(model.Application)
|
||||
} else {
|
||||
data = new(model.Project)
|
||||
}
|
||||
err = json.Unmarshal(event.Data, data)
|
||||
logging.Log("EVENT-NCkpN").OnError(err).Debug("unable to unmarshal data")
|
||||
change.Data = data
|
||||
}
|
||||
|
||||
changes[i] = change
|
||||
if lastSequence < event.Sequence {
|
||||
lastSequence = event.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
return &proj_model.ProjectChanges{
|
||||
Changes: changes,
|
||||
LastSequence: lastSequence,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ChangesQuery(projectID string, latestSequence, limit uint64, sortAscending bool) *es_models.SearchQuery {
|
||||
query := es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.ProjectAggregate)
|
||||
if !sortAscending {
|
||||
query.OrderDesc()
|
||||
}
|
||||
|
||||
query.LatestSequenceFilter(latestSequence).
|
||||
AggregateIDFilter(projectID).
|
||||
SetLimit(limit)
|
||||
return query
|
||||
}
|
||||
|
||||
func (es *ProjectEventstore) ApplicationByIDs(ctx context.Context, projectID, appID string) (*proj_model.Application, error) {
|
||||
if projectID == "" || appID == "" {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld93d", "Errors.Project.IDMissing")
|
||||
}
|
||||
project, err := es.ProjectByID(ctx, projectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, a := project.GetApp(appID); a != nil {
|
||||
return a, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-8ei2s", "Errors.Project.App.NotFound")
|
||||
}
|
||||
|
||||
func (es *ProjectEventstore) ApplicationChanges(ctx context.Context, projectID string, appID string, lastSequence uint64, limit uint64, sortAscending bool) (*proj_model.ApplicationChanges, error) {
|
||||
query := ChangesQuery(projectID, lastSequence, limit, sortAscending)
|
||||
|
||||
events, err := es.Eventstore.FilterEvents(ctx, query)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-ZRffs").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, errors.ThrowInternal(err, "EVENT-sw6Ku", "Errors.Internal")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-9IHLP", "Errors.Changes.NotFound")
|
||||
}
|
||||
|
||||
result := make([]*proj_model.ApplicationChange, 0)
|
||||
for _, event := range events {
|
||||
if !strings.Contains(event.Type.String(), "application") || event.Data == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
app := new(model.Application)
|
||||
err := json.Unmarshal(event.Data, app)
|
||||
logging.Log("EVENT-GIiKD").OnError(err).Debug("unable to unmarshal data")
|
||||
if app.AppID != appID {
|
||||
continue
|
||||
}
|
||||
|
||||
creationDate, err := ptypes.TimestampProto(event.CreationDate)
|
||||
logging.Log("EVENT-MJzeN").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
result = append(result, &proj_model.ApplicationChange{
|
||||
ChangeDate: creationDate,
|
||||
EventType: event.Type.String(),
|
||||
ModifierId: event.EditorUser,
|
||||
Sequence: event.Sequence,
|
||||
Data: app,
|
||||
})
|
||||
if lastSequence < event.Sequence {
|
||||
lastSequence = event.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
return &proj_model.ApplicationChanges{
|
||||
Changes: result,
|
||||
LastSequence: lastSequence,
|
||||
}, nil
|
||||
}
|
||||
//
|
||||
//import (
|
||||
// "github.com/caos/zitadel/internal/cache/config"
|
||||
// sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
// "github.com/caos/zitadel/internal/crypto"
|
||||
// es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
// "github.com/caos/zitadel/internal/id"
|
||||
//)
|
||||
//
|
||||
//const (
|
||||
// projectOwnerRole = "PROJECT_OWNER"
|
||||
// projectOwnerGlobalRole = "PROJECT_OWNER_GLOBAL"
|
||||
//)
|
||||
//
|
||||
//type ProjectEventstore struct {
|
||||
// es_int.Eventstore
|
||||
// projectCache *ProjectCache
|
||||
// passwordAlg crypto.HashAlgorithm
|
||||
// pwGenerator crypto.Generator
|
||||
// idGenerator id.Generator
|
||||
// ClientKeySize int
|
||||
//}
|
||||
//
|
||||
//type ProjectConfig struct {
|
||||
// es_int.Eventstore
|
||||
// Cache *config.CacheConfig
|
||||
//}
|
||||
//
|
||||
//func StartProject(conf ProjectConfig, systemDefaults sd.SystemDefaults) (*ProjectEventstore, error) {
|
||||
// projectCache, err := StartCache(conf.Cache)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// passwordAlg := crypto.NewBCrypt(systemDefaults.SecretGenerators.PasswordSaltCost)
|
||||
// pwGenerator := crypto.NewHashGenerator(systemDefaults.SecretGenerators.ClientSecretGenerator, passwordAlg)
|
||||
// return &ProjectEventstore{
|
||||
// Eventstore: conf.Eventstore,
|
||||
// projectCache: projectCache,
|
||||
// passwordAlg: passwordAlg,
|
||||
// pwGenerator: pwGenerator,
|
||||
// idGenerator: id.SonyFlakeGenerator,
|
||||
// ClientKeySize: int(systemDefaults.SecretGenerators.ApplicationKeySize),
|
||||
// }, nil
|
||||
//}
|
||||
|
@ -10,20 +10,6 @@ import (
|
||||
"github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
func ProjectByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) {
|
||||
if id == "" {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dke74", "Errors.Project.ProjectIDMissing")
|
||||
}
|
||||
return ProjectQuery(latestSequence).
|
||||
AggregateIDFilter(id), nil
|
||||
}
|
||||
|
||||
func ProjectQuery(latestSequence uint64) *es_models.SearchQuery {
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.ProjectAggregate).
|
||||
LatestSequenceFilter(latestSequence)
|
||||
}
|
||||
|
||||
func ProjectAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, project *model.Project) (*es_models.Aggregate, error) {
|
||||
if project == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-doe93", "Errors.Internal")
|
||||
|
34
internal/project/repository/view/query.go
Normal file
34
internal/project/repository/view/query.go
Normal file
@ -0,0 +1,34 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
func ProjectByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) {
|
||||
if id == "" {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dke74", "Errors.Project.ProjectIDMissing")
|
||||
}
|
||||
return ProjectQuery(latestSequence).
|
||||
AggregateIDFilter(id), nil
|
||||
}
|
||||
|
||||
func ProjectQuery(latestSequence uint64) *es_models.SearchQuery {
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.ProjectAggregate).
|
||||
LatestSequenceFilter(latestSequence)
|
||||
}
|
||||
|
||||
func ChangesQuery(projectID string, latestSequence, limit uint64, sortAscending bool) *es_models.SearchQuery {
|
||||
query := es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.ProjectAggregate)
|
||||
if !sortAscending {
|
||||
query.OrderDesc()
|
||||
}
|
||||
|
||||
query.LatestSequenceFilter(latestSequence).
|
||||
AggregateIDFilter(projectID).
|
||||
SetLimit(limit)
|
||||
return query
|
||||
}
|
@ -1,19 +1,5 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
)
|
||||
|
||||
type OTP struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
Secret *crypto.CryptoValue
|
||||
SecretString string
|
||||
Url string
|
||||
State MFAState
|
||||
}
|
||||
|
||||
type MFAState int32
|
||||
|
||||
const (
|
||||
|
@ -1,103 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"strings"
|
||||
|
||||
caos_errors "github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/golang/protobuf/ptypes/timestamp"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
es_models.ObjectRoot
|
||||
State UserState
|
||||
UserName string
|
||||
|
||||
*Human
|
||||
*Machine
|
||||
}
|
||||
|
||||
type UserState int32
|
||||
|
||||
const (
|
||||
UserStateUnspecified UserState = iota
|
||||
UserStateActive
|
||||
UserStateInactive
|
||||
UserStateDeleted
|
||||
UserStateLocked
|
||||
UserStateSuspend
|
||||
UserStateInitial
|
||||
)
|
||||
|
||||
func (u *User) CheckOrgIAMPolicy(policy *iam_model.OrgIAMPolicyView) 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) SetNamesAsDisplayname() {
|
||||
if u.Profile != nil && u.DisplayName == "" && u.FirstName != "" && u.LastName != "" {
|
||||
u.DisplayName = u.FirstName + " " + u.LastName
|
||||
}
|
||||
}
|
||||
|
||||
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"`
|
||||
}
|
||||
|
||||
func (u *User) IsActive() bool {
|
||||
return u.State == UserStateActive
|
||||
}
|
||||
|
||||
func (u *User) IsInitial() bool {
|
||||
return u.State == UserStateInitial
|
||||
}
|
||||
|
||||
func (u *User) IsInactive() bool {
|
||||
return u.State == UserStateInactive
|
||||
}
|
||||
|
||||
func (u *User) IsLocked() bool {
|
||||
return u.State == UserStateLocked
|
||||
}
|
||||
|
||||
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) CheckOrgIamPolicy(policy *iam_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
|
||||
}
|
19
internal/user/model/user_changes.go
Normal file
19
internal/user/model/user_changes.go
Normal file
@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/golang/protobuf/ptypes/timestamp"
|
||||
)
|
||||
|
||||
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"`
|
||||
}
|
@ -1,203 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
caos_errors "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
)
|
||||
|
||||
type Human struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
*Password
|
||||
*Profile
|
||||
*Email
|
||||
*Phone
|
||||
*Address
|
||||
ExternalIDPs []*ExternalIDP
|
||||
InitCode *InitUserCode
|
||||
EmailCode *EmailCode
|
||||
PhoneCode *PhoneCode
|
||||
PasswordCode *PasswordCode
|
||||
OTP *OTP
|
||||
U2FTokens []*WebAuthNToken
|
||||
PasswordlessTokens []*WebAuthNToken
|
||||
U2FLogins []*WebAuthNLogin
|
||||
PasswordlessLogins []*WebAuthNLogin
|
||||
}
|
||||
|
||||
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) CheckOrgIAMPolicy(userName string, policy *domain.OrgIAMPolicy) error {
|
||||
if policy == nil {
|
||||
return caos_errors.ThrowPreconditionFailed(nil, "MODEL-zSH7j", "Errors.Users.OrgIamPolicyNil")
|
||||
}
|
||||
if policy.UserLoginMustBeDomain && strings.Contains(userName, "@") {
|
||||
return caos_errors.ThrowPreconditionFailed(nil, "MODEL-se4sJ", "Errors.User.EmailAsUsernameNotAllowed")
|
||||
}
|
||||
if !policy.UserLoginMustBeDomain && u.Profile != nil && userName == "" && u.Email != nil {
|
||||
userName = u.EmailAddress
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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.PhoneNumber != "" && u.Phone.IsValid())
|
||||
}
|
||||
|
||||
func (u *Human) IsInitialState() bool {
|
||||
return u.Email == nil || !u.IsEmailVerified || (u.ExternalIDPs == nil || len(u.ExternalIDPs) == 0) && (u.Password == nil || u.SecretString == "")
|
||||
}
|
||||
|
||||
func (u *Human) IsOTPReady() bool {
|
||||
return u.OTP != nil && u.OTP.State == MFAStateReady
|
||||
}
|
||||
|
||||
func (u *Human) HashPasswordIfExisting(policy *iam_model.PasswordComplexityPolicyView, 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
|
||||
}
|
||||
|
||||
func (u *Human) GetExternalIDP(externalIDP *ExternalIDP) (int, *ExternalIDP) {
|
||||
for i, idp := range u.ExternalIDPs {
|
||||
if idp.UserID == externalIDP.UserID {
|
||||
return i, idp
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (u *Human) GetU2F(webAuthNTokenID string) (int, *WebAuthNToken) {
|
||||
for i, u2f := range u.U2FTokens {
|
||||
if u2f.WebAuthNTokenID == webAuthNTokenID {
|
||||
return i, u2f
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (u *Human) GetU2FByKeyID(keyID []byte) (int, *WebAuthNToken) {
|
||||
for i, u2f := range u.U2FTokens {
|
||||
if bytes.Compare(u2f.KeyID, keyID) == 0 {
|
||||
return i, u2f
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (u *Human) GetU2FToVerify() (int, *WebAuthNToken) {
|
||||
for i, u2f := range u.U2FTokens {
|
||||
if u2f.State == MFAStateNotReady {
|
||||
return i, u2f
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (u *Human) GetPasswordless(webAuthNTokenID string) (int, *WebAuthNToken) {
|
||||
for i, u2f := range u.PasswordlessTokens {
|
||||
if u2f.WebAuthNTokenID == webAuthNTokenID {
|
||||
return i, u2f
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (u *Human) GetPasswordlessByKeyID(keyID []byte) (int, *WebAuthNToken) {
|
||||
for i, pwl := range u.PasswordlessTokens {
|
||||
if bytes.Compare(pwl.KeyID, keyID) == 0 {
|
||||
return i, pwl
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (u *Human) GetPasswordlessToVerify() (int, *WebAuthNToken) {
|
||||
for i, u2f := range u.PasswordlessTokens {
|
||||
if u2f.State == MFAStateNotReady {
|
||||
return i, u2f
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (u *Human) GetU2FLogin(authReqID string) (int, *WebAuthNLogin) {
|
||||
for i, u2f := range u.U2FLogins {
|
||||
if u2f.AuthRequest.ID == authReqID {
|
||||
return i, u2f
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (u *Human) GetPasswordlessLogin(authReqID string) (int, *WebAuthNLogin) {
|
||||
for i, pw := range u.PasswordlessLogins {
|
||||
if pw.AuthRequest.ID == authReqID {
|
||||
return i, pw
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsUserValid(t *testing.T) {
|
||||
type args struct {
|
||||
user *Human
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result bool
|
||||
errFunc func(err error) bool
|
||||
}{
|
||||
{
|
||||
name: "user with minimal data",
|
||||
args: args{
|
||||
user: &Human{
|
||||
Profile: &Profile{
|
||||
FirstName: "FirstName",
|
||||
LastName: "LastName",
|
||||
},
|
||||
Email: &Email{
|
||||
EmailAddress: "Email",
|
||||
},
|
||||
},
|
||||
},
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "user with phone data",
|
||||
args: args{
|
||||
user: &Human{
|
||||
Profile: &Profile{
|
||||
FirstName: "FirstName",
|
||||
LastName: "LastName",
|
||||
},
|
||||
Email: &Email{
|
||||
EmailAddress: "Email",
|
||||
},
|
||||
Phone: &Phone{
|
||||
PhoneNumber: "+41711234569",
|
||||
},
|
||||
},
|
||||
},
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "user with address data",
|
||||
args: args{
|
||||
user: &Human{
|
||||
Profile: &Profile{
|
||||
FirstName: "FirstName",
|
||||
LastName: "LastName",
|
||||
},
|
||||
Email: &Email{
|
||||
EmailAddress: "Email",
|
||||
},
|
||||
Address: &Address{
|
||||
StreetAddress: "Teufenerstrasse 19",
|
||||
PostalCode: "9000",
|
||||
Locality: "St. Gallen",
|
||||
Country: "Switzerland",
|
||||
},
|
||||
},
|
||||
},
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "user with all data",
|
||||
args: args{
|
||||
user: &Human{
|
||||
Profile: &Profile{
|
||||
FirstName: "FirstName",
|
||||
LastName: "LastName",
|
||||
},
|
||||
Email: &Email{
|
||||
EmailAddress: "Email",
|
||||
},
|
||||
Phone: &Phone{
|
||||
PhoneNumber: "+41711234569",
|
||||
},
|
||||
Address: &Address{
|
||||
StreetAddress: "Teufenerstrasse 19",
|
||||
PostalCode: "9000",
|
||||
Locality: "St. Gallen",
|
||||
Country: "Switzerland",
|
||||
},
|
||||
},
|
||||
},
|
||||
result: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
isValid := tt.args.user.IsValid()
|
||||
|
||||
if tt.result != isValid {
|
||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result, isValid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
key_model "github.com/caos/zitadel/internal/key/model"
|
||||
)
|
||||
|
||||
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 key_model.AuthNKeyType
|
||||
ExpirationDate time.Time
|
||||
PrivateKey []byte
|
||||
}
|
@ -108,6 +108,27 @@ type UserSearchResponse struct {
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
type UserState int32
|
||||
|
||||
const (
|
||||
UserStateUnspecified UserState = iota
|
||||
UserStateActive
|
||||
UserStateInactive
|
||||
UserStateDeleted
|
||||
UserStateLocked
|
||||
UserStateSuspend
|
||||
UserStateInitial
|
||||
)
|
||||
|
||||
type Gender int32
|
||||
|
||||
const (
|
||||
GenderUnspecified Gender = iota
|
||||
GenderFemale
|
||||
GenderMale
|
||||
GenderDiverse
|
||||
)
|
||||
|
||||
func (r *UserSearchRequest) EnsureLimit(limit uint64) {
|
||||
if r.Limit == 0 || r.Limit > limit {
|
||||
r.Limit = limit
|
||||
|
@ -1,58 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/auth_request/model"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
)
|
||||
|
||||
type WebAuthNToken struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
WebAuthNTokenID string
|
||||
CredentialCreationData []byte
|
||||
State MFAState
|
||||
Challenge string
|
||||
AllowedCredentialIDs [][]byte
|
||||
UserVerification UserVerificationRequirement
|
||||
KeyID []byte
|
||||
PublicKey []byte
|
||||
AttestationType string
|
||||
AAGUID []byte
|
||||
SignCount uint32
|
||||
WebAuthNTokenName string
|
||||
}
|
||||
|
||||
type WebAuthNLogin struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
CredentialAssertionData []byte
|
||||
Challenge string
|
||||
AllowedCredentialIDs [][]byte
|
||||
UserVerification UserVerificationRequirement
|
||||
*model.AuthRequest
|
||||
}
|
||||
|
||||
type WebAuthNMethod int32
|
||||
|
||||
const (
|
||||
WebAuthNMethodUnspecified WebAuthNMethod = iota
|
||||
WebAuthNMethodU2F
|
||||
WebAuthNMethodPasswordless
|
||||
)
|
||||
|
||||
type UserVerificationRequirement int32
|
||||
|
||||
const (
|
||||
UserVerificationRequirementUnspecified UserVerificationRequirement = iota
|
||||
UserVerificationRequirementRequired
|
||||
UserVerificationRequirementPreferred
|
||||
UserVerificationRequirementDiscouraged
|
||||
)
|
||||
|
||||
type AuthenticatorAttachment int32
|
||||
|
||||
const (
|
||||
AuthenticatorAttachmentUnspecified AuthenticatorAttachment = iota
|
||||
AuthenticatorAttachmentPlattform
|
||||
AuthenticatorAttachmentCrossPlattform
|
||||
)
|
@ -1,35 +0,0 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/cache"
|
||||
"github.com/caos/zitadel/internal/cache/config"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
type UserCache struct {
|
||||
userCache cache.Cache
|
||||
}
|
||||
|
||||
func StartCache(conf *config.CacheConfig) (*UserCache, error) {
|
||||
userCache, err := conf.Config.NewCache()
|
||||
logging.Log("EVENT-vJG2j").OnError(err).Panic("unable to create user cache")
|
||||
|
||||
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 {
|
||||
logging.Log("EVENT-AtS0S").WithError(err).Debug("error in getting cache")
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
func (c *UserCache) cacheUser(user *model.User) {
|
||||
err := c.userCache.Set(user.AggregateID, user)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-0V2gX").WithError(err).Debug("error in setting project cache")
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/cache/config"
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
type UserEventstore struct {
|
||||
es_int.Eventstore
|
||||
userCache *UserCache
|
||||
}
|
||||
|
||||
type UserConfig struct {
|
||||
es_int.Eventstore
|
||||
Cache *config.CacheConfig
|
||||
PasswordSaltCost int
|
||||
}
|
||||
|
||||
func StartUser(conf UserConfig, systemDefaults sd.SystemDefaults) (*UserEventstore, error) {
|
||||
userCache, err := StartCache(conf.Cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &UserEventstore{
|
||||
Eventstore: conf.Eventstore,
|
||||
userCache: userCache,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) UserByID(ctx context.Context, id string) (*usr_model.User, error) {
|
||||
user := es.userCache.getUser(id)
|
||||
|
||||
query, err := UserByIDQuery(user.AggregateID, user.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = es_sdk.Filter(ctx, es.FilterEvents, user.AppendEvents, query)
|
||||
if err != nil && caos_errs.IsNotFound(err) && user.Sequence == 0 {
|
||||
return nil, err
|
||||
}
|
||||
if user.State == int32(usr_model.UserStateDeleted) {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-6hsK9", "Errors.User.NotFound")
|
||||
}
|
||||
es.userCache.cacheUser(user)
|
||||
return model.UserToModel(user), nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) HumanByID(ctx context.Context, userID string) (*usr_model.User, error) {
|
||||
if userID == "" {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-3M9sf", "Errors.User.UserIDMissing")
|
||||
}
|
||||
user, err := es.UserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user.Human == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-jLHYG", "Errors.User.NotHuman")
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) UserEventsByID(ctx context.Context, id string, sequence uint64) ([]*es_models.Event, error) {
|
||||
query, err := UserByIDQuery(id, sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return es.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (es *UserEventstore) UserChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*usr_model.UserChanges, error) {
|
||||
query := ChangesQuery(id, lastSequence, limit, sortAscending)
|
||||
|
||||
events, err := es.Eventstore.FilterEvents(ctx, query)
|
||||
if err != nil {
|
||||
logging.Log("EVENT-g9HCv").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, errors.ThrowInternal(err, "EVENT-htuG9", "Errors.Internal")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-6cAxe", "Errors.User.NoChanges")
|
||||
}
|
||||
|
||||
result := make([]*usr_model.UserChange, len(events))
|
||||
|
||||
for i, event := range events {
|
||||
creationDate, err := ptypes.TimestampProto(event.CreationDate)
|
||||
logging.Log("EVENT-8GTGS").OnError(err).Debug("unable to parse timestamp")
|
||||
change := &usr_model.UserChange{
|
||||
ChangeDate: creationDate,
|
||||
EventType: event.Type.String(),
|
||||
ModifierID: event.EditorUser,
|
||||
Sequence: event.Sequence,
|
||||
}
|
||||
|
||||
//TODO: now all types should be unmarshalled, e.g. password
|
||||
// if len(event.Data) != 0 {
|
||||
// user := new(model.User)
|
||||
// err := json.Unmarshal(event.Data, user)
|
||||
// logging.Log("EVENT-Rkg7X").OnError(err).Debug("unable to unmarshal data")
|
||||
// change.Data = user
|
||||
// }
|
||||
|
||||
result[i] = change
|
||||
if lastSequence < event.Sequence {
|
||||
lastSequence = event.Sequence
|
||||
}
|
||||
}
|
||||
|
||||
return &usr_model.UserChanges{
|
||||
Changes: result,
|
||||
LastSequence: lastSequence,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ChangesQuery(userID string, latestSequence, limit uint64, sortAscending bool) *es_models.SearchQuery {
|
||||
query := es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(model.UserAggregate)
|
||||
if !sortAscending {
|
||||
query.OrderDesc()
|
||||
}
|
||||
|
||||
query.LatestSequenceFilter(latestSequence).
|
||||
AggregateIDFilter(userID).
|
||||
SetLimit(limit)
|
||||
return query
|
||||
}
|
||||
|
||||
func (es *UserEventstore) GetPasswordless(ctx context.Context, userID string) ([]*usr_model.WebAuthNToken, error) {
|
||||
user, err := es.HumanByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return user.PasswordlessTokens, nil
|
||||
}
|
@ -21,22 +21,6 @@ type OTPVerified struct {
|
||||
UserAgentID string `json:"userAgentID,omitempty"`
|
||||
}
|
||||
|
||||
func OTPFromModel(otp *model.OTP) *OTP {
|
||||
return &OTP{
|
||||
ObjectRoot: otp.ObjectRoot,
|
||||
Secret: otp.Secret,
|
||||
State: int32(otp.State),
|
||||
}
|
||||
}
|
||||
|
||||
func OTPToModel(otp *OTP) *model.OTP {
|
||||
return &model.OTP{
|
||||
ObjectRoot: otp.ObjectRoot,
|
||||
Secret: otp.Secret,
|
||||
State: model.MFAState(otp.State),
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Human) appendOTPAddedEvent(event *es_models.Event) error {
|
||||
u.OTP = &OTP{
|
||||
State: int32(model.MFAStateNotReady),
|
||||
|
@ -24,42 +24,6 @@ type User struct {
|
||||
*Machine
|
||||
}
|
||||
|
||||
func UserFromModel(user *model.User) *User {
|
||||
var human *Human
|
||||
if user.Human != nil {
|
||||
human = HumanFromModel(user.Human)
|
||||
}
|
||||
var machine *Machine
|
||||
if user.Machine != nil {
|
||||
machine = MachineFromModel(user.Machine)
|
||||
}
|
||||
return &User{
|
||||
ObjectRoot: user.ObjectRoot,
|
||||
State: int32(user.State),
|
||||
UserName: user.UserName,
|
||||
Human: human,
|
||||
Machine: machine,
|
||||
}
|
||||
}
|
||||
|
||||
func UserToModel(user *User) *model.User {
|
||||
var human *model.Human
|
||||
if user.Human != nil {
|
||||
human = HumanToModel(user.Human)
|
||||
}
|
||||
var machine *model.Machine
|
||||
if user.Machine != nil {
|
||||
machine = MachineToModel(user.Machine)
|
||||
}
|
||||
return &model.User{
|
||||
ObjectRoot: user.ObjectRoot,
|
||||
State: model.UserState(user.State),
|
||||
UserName: user.UserName,
|
||||
Human: human,
|
||||
Machine: machine,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *User) AppendEvents(events ...*es_models.Event) error {
|
||||
for _, event := range events {
|
||||
if err := u.AppendEvent(event); err != nil {
|
||||
|
@ -37,113 +37,6 @@ type InitUserCode struct {
|
||||
Expiry time.Duration `json:"expiry,omitempty"`
|
||||
}
|
||||
|
||||
func HumanFromModel(user *model.Human) *Human {
|
||||
human := new(Human)
|
||||
if user.Password != nil {
|
||||
human.Password = PasswordFromModel(user.Password)
|
||||
}
|
||||
if user.Profile != nil {
|
||||
human.Profile = ProfileFromModel(user.Profile)
|
||||
}
|
||||
if user.Email != nil {
|
||||
human.Email = EmailFromModel(user.Email)
|
||||
}
|
||||
if user.Phone != nil {
|
||||
human.Phone = PhoneFromModel(user.Phone)
|
||||
}
|
||||
if user.Address != nil {
|
||||
human.Address = AddressFromModel(user.Address)
|
||||
}
|
||||
if user.OTP != nil {
|
||||
human.OTP = OTPFromModel(user.OTP)
|
||||
}
|
||||
if user.ExternalIDPs != nil {
|
||||
human.ExternalIDPs = ExternalIDPsFromModel(user.ExternalIDPs)
|
||||
}
|
||||
if user.U2FTokens != nil {
|
||||
human.U2FTokens = WebAuthNsFromModel(user.U2FTokens)
|
||||
}
|
||||
if user.PasswordlessTokens != nil {
|
||||
human.PasswordlessTokens = WebAuthNsFromModel(user.PasswordlessTokens)
|
||||
}
|
||||
if user.U2FLogins != nil {
|
||||
human.U2FLogins = WebAuthNLoginsFromModel(user.U2FLogins)
|
||||
}
|
||||
if user.PasswordlessLogins != nil {
|
||||
human.PasswordlessLogins = WebAuthNLoginsFromModel(user.PasswordlessLogins)
|
||||
}
|
||||
return human
|
||||
}
|
||||
|
||||
func HumanToModel(user *Human) *model.Human {
|
||||
human := new(model.Human)
|
||||
if user.Password != nil {
|
||||
human.Password = PasswordToModel(user.Password)
|
||||
}
|
||||
if user.Profile != nil {
|
||||
human.Profile = ProfileToModel(user.Profile)
|
||||
}
|
||||
if user.Email != nil {
|
||||
human.Email = EmailToModel(user.Email)
|
||||
}
|
||||
if user.Phone != nil {
|
||||
human.Phone = PhoneToModel(user.Phone)
|
||||
}
|
||||
if user.Address != nil {
|
||||
human.Address = AddressToModel(user.Address)
|
||||
}
|
||||
if user.ExternalIDPs != nil {
|
||||
human.ExternalIDPs = ExternalIDPsToModel(user.ExternalIDPs)
|
||||
}
|
||||
if user.InitCode != nil {
|
||||
human.InitCode = InitCodeToModel(user.InitCode)
|
||||
}
|
||||
if user.EmailCode != nil {
|
||||
human.EmailCode = EmailCodeToModel(user.EmailCode)
|
||||
}
|
||||
if user.PhoneCode != nil {
|
||||
human.PhoneCode = PhoneCodeToModel(user.PhoneCode)
|
||||
}
|
||||
if user.PasswordCode != nil {
|
||||
human.PasswordCode = PasswordCodeToModel(user.PasswordCode)
|
||||
}
|
||||
if user.OTP != nil {
|
||||
human.OTP = OTPToModel(user.OTP)
|
||||
}
|
||||
if user.U2FTokens != nil {
|
||||
human.U2FTokens = WebAuthNsToModel(user.U2FTokens)
|
||||
}
|
||||
if user.PasswordlessTokens != nil {
|
||||
human.PasswordlessTokens = WebAuthNsToModel(user.PasswordlessTokens)
|
||||
}
|
||||
if user.U2FLogins != nil {
|
||||
human.U2FLogins = WebAuthNLoginsToModel(user.U2FLogins)
|
||||
}
|
||||
if user.PasswordlessLogins != nil {
|
||||
human.PasswordlessLogins = WebAuthNLoginsToModel(user.PasswordlessLogins)
|
||||
}
|
||||
return human
|
||||
}
|
||||
|
||||
func InitCodeFromModel(code *model.InitUserCode) *InitUserCode {
|
||||
if code == nil {
|
||||
return nil
|
||||
}
|
||||
return &InitUserCode{
|
||||
ObjectRoot: code.ObjectRoot,
|
||||
Expiry: code.Expiry,
|
||||
Code: code.Code,
|
||||
}
|
||||
}
|
||||
|
||||
func InitCodeToModel(code *InitUserCode) *model.InitUserCode {
|
||||
return &model.InitUserCode{
|
||||
ObjectRoot: code.ObjectRoot,
|
||||
Expiry: code.Expiry,
|
||||
Code: code.Code,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Human) AppendEvents(events ...*es_models.Event) error {
|
||||
for _, event := range events {
|
||||
if err := p.AppendEvent(event); err != nil {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user