mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:37:32 +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:
@@ -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
|
||||
}
|
Reference in New Issue
Block a user