mirror of
https://github.com/zitadel/zitadel.git
synced 2025-03-01 00:27:24 +00:00
refactor(changes): use queries.SearchEvents
(#5388)
* refactor(changes): use `queries.SearchEvents` --------- Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
parent
09abf06d4d
commit
a3b36a0138
@ -656,6 +656,8 @@ DefaultInstance:
|
||||
# # CallURL is called when a relative amount of the quota is used.
|
||||
# CallURL: "https://httpbin.org/post"
|
||||
|
||||
AuditLogRetention: 0s
|
||||
|
||||
InternalAuthZ:
|
||||
RolePermissionMappings:
|
||||
- Role: "IAM_OWNER"
|
||||
|
@ -235,7 +235,7 @@ func startAPIs(
|
||||
if err := apis.RegisterServer(ctx, system.CreateServer(commands, queries, adminRepo, config.Database.DatabaseName(), config.DefaultInstance, config.ExternalDomain)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := apis.RegisterServer(ctx, admin.CreateServer(config.Database.DatabaseName(), commands, queries, config.SystemDefaults, adminRepo, config.ExternalSecure, keys.User)); err != nil {
|
||||
if err := apis.RegisterServer(ctx, admin.CreateServer(config.Database.DatabaseName(), commands, queries, config.SystemDefaults, adminRepo, config.ExternalSecure, keys.User, config.AuditLogRetention)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := apis.RegisterServer(ctx, management.CreateServer(commands, queries, config.SystemDefaults, keys.User, config.ExternalSecure, config.AuditLogRetention)); err != nil {
|
||||
|
@ -17,7 +17,7 @@ func (s *Server) ListEvents(ctx context.Context, in *admin_pb.ListEventsRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
events, err := s.query.SearchEvents(ctx, filter)
|
||||
events, err := s.query.SearchEvents(ctx, filter, s.auditLogRetention)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/admin/repository"
|
||||
@ -24,13 +26,14 @@ var _ admin.AdminServiceServer = (*Server)(nil)
|
||||
|
||||
type Server struct {
|
||||
admin.UnimplementedAdminServiceServer
|
||||
database string
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
administrator repository.AdministratorRepository
|
||||
assetsAPIDomain func(context.Context) string
|
||||
userCodeAlg crypto.EncryptionAlgorithm
|
||||
passwordHashAlg crypto.HashAlgorithm
|
||||
database string
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
administrator repository.AdministratorRepository
|
||||
assetsAPIDomain func(context.Context) string
|
||||
userCodeAlg crypto.EncryptionAlgorithm
|
||||
passwordHashAlg crypto.HashAlgorithm
|
||||
auditLogRetention time.Duration
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
@ -45,15 +48,17 @@ func CreateServer(
|
||||
repo repository.Repository,
|
||||
externalSecure bool,
|
||||
userCodeAlg crypto.EncryptionAlgorithm,
|
||||
auditLogRetention time.Duration,
|
||||
) *Server {
|
||||
return &Server{
|
||||
database: database,
|
||||
command: command,
|
||||
query: query,
|
||||
administrator: repo,
|
||||
assetsAPIDomain: assets.AssetAPI(externalSecure),
|
||||
userCodeAlg: userCodeAlg,
|
||||
passwordHashAlg: crypto.NewBCrypt(sd.SecretGenerators.PasswordSaltCost),
|
||||
database: database,
|
||||
command: command,
|
||||
query: query,
|
||||
administrator: repo,
|
||||
assetsAPIDomain: assets.AssetAPI(externalSecure),
|
||||
userCodeAlg: userCodeAlg,
|
||||
passwordHashAlg: crypto.NewBCrypt(sd.SecretGenerators.PasswordSaltCost),
|
||||
auditLogRetention: auditLogRetention,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,10 @@ import (
|
||||
user_grpc "github.com/zitadel/zitadel/internal/api/grpc/user"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/repository/user"
|
||||
auth_pb "github.com/zitadel/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
@ -56,13 +58,38 @@ func (s *Server) RemoveMyUser(ctx context.Context, _ *auth_pb.RemoveMyUserReques
|
||||
}
|
||||
|
||||
func (s *Server) ListMyUserChanges(ctx context.Context, req *auth_pb.ListMyUserChangesRequest) (*auth_pb.ListMyUserChangesResponse, error) {
|
||||
sequence, limit, asc := change.ChangeQueryToQuery(req.Query)
|
||||
changes, err := s.query.UserChanges(ctx, authz.GetCtxData(ctx).UserID, sequence, limit, asc, s.auditLogRetention)
|
||||
var (
|
||||
limit uint64
|
||||
sequence uint64
|
||||
asc bool
|
||||
)
|
||||
if req.Query != nil {
|
||||
limit = uint64(req.Query.Limit)
|
||||
sequence = req.Query.Sequence
|
||||
asc = req.Query.Asc
|
||||
}
|
||||
|
||||
query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
AllowTimeTravel().
|
||||
Limit(limit).
|
||||
OrderDesc().
|
||||
ResourceOwner(authz.GetCtxData(ctx).ResourceOwner).
|
||||
AddQuery().
|
||||
SequenceGreater(sequence).
|
||||
AggregateTypes(user.AggregateType).
|
||||
AggregateIDs(authz.GetCtxData(ctx).UserID).
|
||||
Builder()
|
||||
if asc {
|
||||
query.OrderAsc()
|
||||
}
|
||||
|
||||
changes, err := s.query.SearchEvents(ctx, query, s.auditLogRetention)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &auth_pb.ListMyUserChangesResponse{
|
||||
Result: change.ChangesToPb(changes.Changes, s.assetsAPIDomain(ctx)),
|
||||
Result: change.EventsToChangesPb(changes, s.assetsAPIDomain(ctx)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -10,30 +10,23 @@ import (
|
||||
"github.com/zitadel/zitadel/pkg/grpc/message"
|
||||
)
|
||||
|
||||
func ChangeQueryToQuery(query *change_pb.ChangeQuery) (sequence uint64, limit uint64, asc bool) {
|
||||
if query == nil {
|
||||
return 0, 0, false
|
||||
}
|
||||
return query.Sequence, uint64(query.Limit), query.Asc
|
||||
}
|
||||
|
||||
func ChangesToPb(changes []*query.Change, assetAPIPrefix string) []*change_pb.Change {
|
||||
func EventsToChangesPb(changes []*query.Event, assetAPIPrefix string) []*change_pb.Change {
|
||||
c := make([]*change_pb.Change, len(changes))
|
||||
for i, change := range changes {
|
||||
c[i] = ChangeToPb(change, assetAPIPrefix)
|
||||
c[i] = EventToChangePb(change, assetAPIPrefix)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func ChangeToPb(change *query.Change, assetAPIPrefix string) *change_pb.Change {
|
||||
func EventToChangePb(change *query.Event, assetAPIPrefix string) *change_pb.Change {
|
||||
return &change_pb.Change{
|
||||
ChangeDate: timestamppb.New(change.ChangeDate),
|
||||
EventType: message.NewLocalizedEventType(change.EventType),
|
||||
ChangeDate: timestamppb.New(change.CreationDate),
|
||||
EventType: message.NewLocalizedEventType(change.Type),
|
||||
Sequence: change.Sequence,
|
||||
EditorId: change.ModifierId,
|
||||
EditorDisplayName: change.ModifierName,
|
||||
EditorPreferredLoginName: change.ModifierLoginName,
|
||||
EditorAvatarUrl: domain.AvatarURL(assetAPIPrefix, change.ModifierResourceOwner, change.ModifierAvatarKey),
|
||||
ResourceOwnerId: change.ResourceOwner,
|
||||
EditorId: change.Editor.ID,
|
||||
EditorDisplayName: change.Editor.DisplayName,
|
||||
EditorPreferredLoginName: change.Editor.PreferedLoginName,
|
||||
EditorAvatarUrl: domain.AvatarURL(assetAPIPrefix, change.Aggregate.ResourceOwner, change.Editor.AvatarKey),
|
||||
ResourceOwnerId: change.Aggregate.ResourceOwner,
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,10 @@ import (
|
||||
org_grpc "github.com/zitadel/zitadel/internal/api/grpc/org"
|
||||
policy_grpc "github.com/zitadel/zitadel/internal/api/grpc/policy"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/repository/org"
|
||||
mgmt_pb "github.com/zitadel/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
@ -35,13 +37,37 @@ func (s *Server) GetOrgByDomainGlobal(ctx context.Context, req *mgmt_pb.GetOrgBy
|
||||
}
|
||||
|
||||
func (s *Server) ListOrgChanges(ctx context.Context, req *mgmt_pb.ListOrgChangesRequest) (*mgmt_pb.ListOrgChangesResponse, error) {
|
||||
sequence, limit, asc := change_grpc.ChangeQueryToQuery(req.Query)
|
||||
response, err := s.query.OrgChanges(ctx, authz.GetCtxData(ctx).OrgID, sequence, limit, asc, s.auditLogRetention)
|
||||
var (
|
||||
limit uint64
|
||||
sequence uint64
|
||||
asc bool
|
||||
)
|
||||
if req.Query != nil {
|
||||
limit = uint64(req.Query.Limit)
|
||||
sequence = req.Query.Sequence
|
||||
asc = req.Query.Asc
|
||||
}
|
||||
|
||||
query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
AllowTimeTravel().
|
||||
Limit(limit).
|
||||
OrderDesc().
|
||||
ResourceOwner(authz.GetCtxData(ctx).OrgID).
|
||||
AddQuery().
|
||||
SequenceGreater(sequence).
|
||||
AggregateTypes(org.AggregateType).
|
||||
AggregateIDs(authz.GetCtxData(ctx).OrgID).
|
||||
Builder()
|
||||
if asc {
|
||||
query.OrderAsc()
|
||||
}
|
||||
|
||||
response, err := s.query.SearchEvents(ctx, query, s.auditLogRetention)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.ListOrgChangesResponse{
|
||||
Result: change_grpc.ChangesToPb(response.Changes, s.assetAPIPrefix(ctx)),
|
||||
Result: change_grpc.EventsToChangesPb(response, s.assetAPIPrefix(ctx)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,9 @@ import (
|
||||
member_grpc "github.com/zitadel/zitadel/internal/api/grpc/member"
|
||||
object_grpc "github.com/zitadel/zitadel/internal/api/grpc/object"
|
||||
project_grpc "github.com/zitadel/zitadel/internal/api/grpc/project"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/repository/project"
|
||||
mgmt_pb "github.com/zitadel/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
@ -56,13 +58,41 @@ func (s *Server) ListProjects(ctx context.Context, req *mgmt_pb.ListProjectsRequ
|
||||
}
|
||||
|
||||
func (s *Server) ListProjectGrantChanges(ctx context.Context, req *mgmt_pb.ListProjectGrantChangesRequest) (*mgmt_pb.ListProjectGrantChangesResponse, error) {
|
||||
sequence, limit, asc := change_grpc.ChangeQueryToQuery(req.Query)
|
||||
res, err := s.query.ProjectGrantChanges(ctx, req.ProjectId, req.GrantId, sequence, limit, asc, s.auditLogRetention)
|
||||
var (
|
||||
limit uint64
|
||||
sequence uint64
|
||||
asc bool
|
||||
)
|
||||
if req.Query != nil {
|
||||
limit = uint64(req.Query.Limit)
|
||||
sequence = req.Query.Sequence
|
||||
asc = req.Query.Asc
|
||||
}
|
||||
|
||||
query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
AllowTimeTravel().
|
||||
Limit(limit).
|
||||
OrderDesc().
|
||||
ResourceOwner(authz.GetCtxData(ctx).OrgID).
|
||||
AddQuery().
|
||||
SequenceGreater(sequence).
|
||||
AggregateTypes(project.AggregateType).
|
||||
AggregateIDs(req.ProjectId).
|
||||
EventData(map[string]interface{}{
|
||||
"grantId": req.GrantId,
|
||||
}).
|
||||
Builder()
|
||||
if asc {
|
||||
query.OrderAsc()
|
||||
}
|
||||
|
||||
changes, err := s.query.SearchEvents(ctx, query, s.auditLogRetention)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &mgmt_pb.ListProjectGrantChangesResponse{
|
||||
Result: change_grpc.ChangesToPb(res.Changes, s.assetAPIPrefix(ctx)),
|
||||
Result: change_grpc.EventsToChangesPb(changes, s.assetAPIPrefix(ctx)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -109,13 +139,38 @@ func (s *Server) ListGrantedProjectRoles(ctx context.Context, req *mgmt_pb.ListG
|
||||
}
|
||||
|
||||
func (s *Server) ListProjectChanges(ctx context.Context, req *mgmt_pb.ListProjectChangesRequest) (*mgmt_pb.ListProjectChangesResponse, error) {
|
||||
sequence, limit, asc := change_grpc.ChangeQueryToQuery(req.Query)
|
||||
res, err := s.query.ProjectChanges(ctx, req.ProjectId, sequence, limit, asc, s.auditLogRetention)
|
||||
var (
|
||||
limit uint64
|
||||
sequence uint64
|
||||
asc bool
|
||||
)
|
||||
if req.Query != nil {
|
||||
limit = uint64(req.Query.Limit)
|
||||
sequence = req.Query.Sequence
|
||||
asc = req.Query.Asc
|
||||
}
|
||||
|
||||
query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
AllowTimeTravel().
|
||||
Limit(limit).
|
||||
OrderDesc().
|
||||
ResourceOwner(authz.GetCtxData(ctx).OrgID).
|
||||
AddQuery().
|
||||
SequenceGreater(sequence).
|
||||
AggregateTypes(project.AggregateType).
|
||||
AggregateIDs(req.ProjectId).
|
||||
Builder()
|
||||
if asc {
|
||||
query.OrderAsc()
|
||||
}
|
||||
|
||||
changes, err := s.query.SearchEvents(ctx, query, s.auditLogRetention)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &mgmt_pb.ListProjectChangesResponse{
|
||||
Result: change_grpc.ChangesToPb(res.Changes, s.assetAPIPrefix(ctx)),
|
||||
Result: change_grpc.EventsToChangesPb(changes, s.assetAPIPrefix(ctx)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,9 @@ import (
|
||||
object_grpc "github.com/zitadel/zitadel/internal/api/grpc/object"
|
||||
project_grpc "github.com/zitadel/zitadel/internal/api/grpc/project"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/repository/project"
|
||||
mgmt_pb "github.com/zitadel/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
@ -39,13 +41,41 @@ func (s *Server) ListApps(ctx context.Context, req *mgmt_pb.ListAppsRequest) (*m
|
||||
}
|
||||
|
||||
func (s *Server) ListAppChanges(ctx context.Context, req *mgmt_pb.ListAppChangesRequest) (*mgmt_pb.ListAppChangesResponse, error) {
|
||||
sequence, limit, asc := change_grpc.ChangeQueryToQuery(req.Query)
|
||||
res, err := s.query.ApplicationChanges(ctx, req.ProjectId, req.AppId, sequence, limit, asc, s.auditLogRetention)
|
||||
var (
|
||||
limit uint64
|
||||
sequence uint64
|
||||
asc bool
|
||||
)
|
||||
if req.Query != nil {
|
||||
limit = uint64(req.Query.Limit)
|
||||
sequence = req.Query.Sequence
|
||||
asc = req.Query.Asc
|
||||
}
|
||||
|
||||
query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
AllowTimeTravel().
|
||||
Limit(limit).
|
||||
OrderDesc().
|
||||
ResourceOwner(authz.GetCtxData(ctx).OrgID).
|
||||
AddQuery().
|
||||
SequenceGreater(sequence).
|
||||
AggregateTypes(project.AggregateType).
|
||||
AggregateIDs(req.ProjectId).
|
||||
EventData(map[string]interface{}{
|
||||
"appId": req.AppId,
|
||||
}).
|
||||
Builder()
|
||||
if asc {
|
||||
query.OrderAsc()
|
||||
}
|
||||
|
||||
changes, err := s.query.SearchEvents(ctx, query, s.auditLogRetention)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &mgmt_pb.ListAppChangesResponse{
|
||||
Result: change_grpc.ChangesToPb(res.Changes, s.assetAPIPrefix(ctx)),
|
||||
Result: change_grpc.EventsToChangesPb(changes, s.assetAPIPrefix(ctx)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,9 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/api/ui/login"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/repository/user"
|
||||
mgmt_pb "github.com/zitadel/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
@ -73,13 +75,38 @@ func (s *Server) ListUsers(ctx context.Context, req *mgmt_pb.ListUsersRequest) (
|
||||
}
|
||||
|
||||
func (s *Server) ListUserChanges(ctx context.Context, req *mgmt_pb.ListUserChangesRequest) (*mgmt_pb.ListUserChangesResponse, error) {
|
||||
sequence, limit, asc := change_grpc.ChangeQueryToQuery(req.Query)
|
||||
res, err := s.query.UserChanges(ctx, req.UserId, sequence, limit, asc, s.auditLogRetention)
|
||||
var (
|
||||
limit uint64
|
||||
sequence uint64
|
||||
asc bool
|
||||
)
|
||||
if req.Query != nil {
|
||||
limit = uint64(req.Query.Limit)
|
||||
sequence = req.Query.Sequence
|
||||
asc = req.Query.Asc
|
||||
}
|
||||
|
||||
query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
AllowTimeTravel().
|
||||
Limit(limit).
|
||||
OrderDesc().
|
||||
ResourceOwner(authz.GetCtxData(ctx).OrgID).
|
||||
AddQuery().
|
||||
SequenceGreater(sequence).
|
||||
AggregateTypes(user.AggregateType).
|
||||
AggregateIDs(req.UserId).
|
||||
Builder()
|
||||
if asc {
|
||||
query.OrderAsc()
|
||||
}
|
||||
|
||||
changes, err := s.query.SearchEvents(ctx, query, s.auditLogRetention)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &mgmt_pb.ListUserChangesResponse{
|
||||
Result: change_grpc.ChangesToPb(res.Changes, s.assetAPIPrefix(ctx)),
|
||||
Result: change_grpc.EventsToChangesPb(changes, s.assetAPIPrefix(ctx)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -1,145 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/repository/org"
|
||||
"github.com/zitadel/zitadel/internal/repository/project"
|
||||
"github.com/zitadel/zitadel/internal/repository/user"
|
||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
|
||||
type Changes struct {
|
||||
Changes []*Change
|
||||
}
|
||||
|
||||
type Change struct {
|
||||
ChangeDate time.Time
|
||||
EventType string
|
||||
Sequence uint64
|
||||
ResourceOwner string
|
||||
ModifierId string
|
||||
ModifierName string
|
||||
ModifierLoginName string
|
||||
ModifierResourceOwner string
|
||||
ModifierAvatarKey string
|
||||
}
|
||||
|
||||
func (q *Queries) OrgChanges(ctx context.Context, orgID string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (_ *Changes, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query := func(query *eventstore.SearchQuery) {
|
||||
query.AggregateTypes(org.AggregateType).
|
||||
AggregateIDs(orgID)
|
||||
}
|
||||
return q.changes(ctx, query, lastSequence, limit, sortAscending, auditLogRetention)
|
||||
|
||||
}
|
||||
|
||||
func (q *Queries) ProjectChanges(ctx context.Context, projectID string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (_ *Changes, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query := func(query *eventstore.SearchQuery) {
|
||||
query.AggregateTypes(project.AggregateType).
|
||||
AggregateIDs(projectID)
|
||||
}
|
||||
return q.changes(ctx, query, lastSequence, limit, sortAscending, auditLogRetention)
|
||||
}
|
||||
|
||||
func (q *Queries) ProjectGrantChanges(ctx context.Context, projectID, grantID string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (_ *Changes, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query := func(query *eventstore.SearchQuery) {
|
||||
query.AggregateTypes(project.AggregateType).
|
||||
AggregateIDs(projectID).
|
||||
EventData(map[string]interface{}{
|
||||
"grantId": grantID,
|
||||
})
|
||||
}
|
||||
return q.changes(ctx, query, lastSequence, limit, sortAscending, auditLogRetention)
|
||||
}
|
||||
|
||||
func (q *Queries) ApplicationChanges(ctx context.Context, projectID, appID string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (_ *Changes, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query := func(query *eventstore.SearchQuery) {
|
||||
query.AggregateTypes(project.AggregateType).
|
||||
AggregateIDs(projectID).
|
||||
EventData(map[string]interface{}{
|
||||
"appId": appID,
|
||||
})
|
||||
}
|
||||
return q.changes(ctx, query, lastSequence, limit, sortAscending, auditLogRetention)
|
||||
}
|
||||
|
||||
func (q *Queries) UserChanges(ctx context.Context, userID string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (_ *Changes, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query := func(query *eventstore.SearchQuery) {
|
||||
query.AggregateTypes(user.AggregateType).
|
||||
AggregateIDs(userID)
|
||||
}
|
||||
return q.changes(ctx, query, lastSequence, limit, sortAscending, auditLogRetention)
|
||||
}
|
||||
|
||||
func (q *Queries) changes(ctx context.Context, query func(query *eventstore.SearchQuery), lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (*Changes, error) {
|
||||
builder := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).Limit(limit).AllowTimeTravel()
|
||||
if !sortAscending {
|
||||
builder.OrderDesc()
|
||||
}
|
||||
search := builder.AddQuery().SequenceGreater(lastSequence) //always use greater (less is done automatically by sorting desc)
|
||||
query(search)
|
||||
|
||||
events, err := q.eventstore.Filter(ctx, builder)
|
||||
if err != nil {
|
||||
logging.Log("QUERY-ZRffs").WithError(err).Warn("eventstore unavailable")
|
||||
return nil, errors.ThrowInternal(err, "QUERY-328b1", "Errors.Internal")
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "QUERY-FpQqK", "Errors.Changes.NotFound")
|
||||
}
|
||||
changes := make([]*Change, 0, len(events))
|
||||
for _, event := range events {
|
||||
if auditLogRetention != 0 && event.CreationDate().Before(time.Now().Add(-auditLogRetention)) {
|
||||
continue
|
||||
}
|
||||
change := &Change{
|
||||
ChangeDate: event.CreationDate(),
|
||||
EventType: string(event.Type()),
|
||||
Sequence: event.Sequence(),
|
||||
ResourceOwner: event.Aggregate().ResourceOwner,
|
||||
ModifierId: event.EditorUser(),
|
||||
ModifierName: event.EditorUser(),
|
||||
ModifierLoginName: event.EditorUser(),
|
||||
}
|
||||
editor, _ := q.GetUserByID(ctx, false, change.ModifierId, false)
|
||||
if editor != nil {
|
||||
change.ModifierLoginName = editor.PreferredLoginName
|
||||
change.ModifierResourceOwner = editor.ResourceOwner
|
||||
if editor.Human != nil {
|
||||
change.ModifierName = editor.Human.DisplayName
|
||||
change.ModifierAvatarKey = editor.Human.AvatarKey
|
||||
}
|
||||
if editor.Machine != nil {
|
||||
change.ModifierName = editor.Machine.Name
|
||||
}
|
||||
}
|
||||
changes = append(changes, change)
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "QUERY-DEGS2", "Errors.Changes.AuditRetention")
|
||||
}
|
||||
return &Changes{
|
||||
Changes: changes,
|
||||
}, nil
|
||||
}
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/call"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
@ -18,12 +19,14 @@ type Event struct {
|
||||
}
|
||||
|
||||
type EventEditor struct {
|
||||
ID string
|
||||
DisplayName string
|
||||
Service string
|
||||
ID string
|
||||
DisplayName string
|
||||
Service string
|
||||
PreferedLoginName string
|
||||
AvatarKey string
|
||||
}
|
||||
|
||||
func (q *Queries) SearchEvents(ctx context.Context, query *eventstore.SearchQueryBuilder) (_ []*Event, err error) {
|
||||
func (q *Queries) SearchEvents(ctx context.Context, query *eventstore.SearchQueryBuilder, auditLogRetention time.Duration) (_ []*Event, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
events, err := q.eventstore.Filter(ctx, query.AllowTimeTravel())
|
||||
@ -31,7 +34,18 @@ func (q *Queries) SearchEvents(ctx context.Context, query *eventstore.SearchQuer
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return q.convertEvents(ctx, events), nil
|
||||
callTime := call.FromContext(ctx)
|
||||
if callTime.IsZero() {
|
||||
callTime = time.Now()
|
||||
}
|
||||
for i, event := range events {
|
||||
if event.CreationDate().Before(callTime.Add(-auditLogRetention)) {
|
||||
events = events[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return q.convertEvents(ctx, events, auditLogRetention), nil
|
||||
}
|
||||
|
||||
func (q *Queries) SearchEventTypes(ctx context.Context) []string {
|
||||
@ -42,31 +56,33 @@ func (q *Queries) SearchAggregateTypes(ctx context.Context) []string {
|
||||
return q.eventstore.AggregateTypes()
|
||||
}
|
||||
|
||||
func (q *Queries) convertEvents(ctx context.Context, events []eventstore.Event) []*Event {
|
||||
func (q *Queries) convertEvents(ctx context.Context, events []eventstore.Event, auditLogRetention time.Duration) []*Event {
|
||||
result := make([]*Event, len(events))
|
||||
users := make(map[string]string)
|
||||
users := make(map[string]*EventEditor)
|
||||
for i, event := range events {
|
||||
result[i] = q.convertEvent(ctx, event, users)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (q *Queries) convertEvent(ctx context.Context, event eventstore.Event, users map[string]string) *Event {
|
||||
func (q *Queries) convertEvent(ctx context.Context, event eventstore.Event, users map[string]*EventEditor) *Event {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
var err error
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
displayName, ok := users[event.EditorUser()]
|
||||
editor, ok := users[event.EditorUser()]
|
||||
if !ok {
|
||||
displayName = q.editorUserByID(ctx, event.EditorUser())
|
||||
users[event.EditorUser()] = displayName
|
||||
editor = q.editorUserByID(ctx, event.EditorUser())
|
||||
users[event.EditorUser()] = editor
|
||||
}
|
||||
|
||||
return &Event{
|
||||
Editor: &EventEditor{
|
||||
ID: event.EditorUser(),
|
||||
Service: event.EditorService(),
|
||||
DisplayName: displayName,
|
||||
ID: event.EditorUser(),
|
||||
Service: event.EditorService(),
|
||||
DisplayName: editor.DisplayName,
|
||||
PreferedLoginName: editor.PreferedLoginName,
|
||||
AvatarKey: editor.AvatarKey,
|
||||
},
|
||||
Aggregate: event.Aggregate(),
|
||||
Sequence: event.Sequence(),
|
||||
@ -76,15 +92,25 @@ func (q *Queries) convertEvent(ctx context.Context, event eventstore.Event, user
|
||||
}
|
||||
}
|
||||
|
||||
func (q *Queries) editorUserByID(ctx context.Context, userID string) string {
|
||||
func (q *Queries) editorUserByID(ctx context.Context, userID string) *EventEditor {
|
||||
user, err := q.GetUserByID(ctx, false, userID, false)
|
||||
if err != nil {
|
||||
return userID
|
||||
return &EventEditor{ID: userID}
|
||||
}
|
||||
|
||||
if user.Human != nil {
|
||||
return user.Human.DisplayName
|
||||
return &EventEditor{
|
||||
ID: user.ID,
|
||||
DisplayName: user.Human.DisplayName,
|
||||
PreferedLoginName: user.PreferredLoginName,
|
||||
AvatarKey: user.Human.AvatarKey,
|
||||
}
|
||||
} else if user.Machine != nil {
|
||||
return user.Machine.Name
|
||||
return &EventEditor{
|
||||
ID: user.ID,
|
||||
DisplayName: user.Machine.Name,
|
||||
PreferedLoginName: user.PreferredLoginName,
|
||||
}
|
||||
}
|
||||
return userID
|
||||
return &EventEditor{ID: userID}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user