diff --git a/docs/docs/apis/proto/admin.md b/docs/docs/apis/proto/admin.md index 5c0f7b908a..ebefba59b3 100644 --- a/docs/docs/apis/proto/admin.md +++ b/docs/docs/apis/proto/admin.md @@ -3120,7 +3120,7 @@ at least one argument has to be provided | Field | Type | Description | Validation | | ----- | ---- | ----------- | ----------- | -| aggregate_types | repeated string | - | | +| aggregate_types | repeated zitadel.event.v1.AggregateType | - | | @@ -3137,7 +3137,7 @@ at least one argument has to be provided | Field | Type | Description | Validation | | ----- | ---- | ----------- | ----------- | -| event_types | repeated string | - | | +| event_types | repeated zitadel.event.v1.EventType | - | | @@ -3151,11 +3151,11 @@ at least one argument has to be provided | sequence | uint64 | sequence represents the order of events. It's always upcounting if asc is false sequence is used as less than filter if asc is true sequence is used as greater than filter if sequence is 0 the field is ignored | | | limit | uint32 | - | | | asc | bool | - | | -| editor_user_id | string | - | | -| event_types | repeated string | the types are or filtered and must match the type exatly | | -| aggregate_id | string | - | | -| aggregate_type | string | - | | -| resource_owner | string | - | | +| editor_user_id | string | - | string.min_len: 0
string.max_len: 200
| +| event_types | repeated string | the types are or filtered and must match the type exatly | repeated.max_items: 30
| +| aggregate_id | string | - | string.min_len: 0
string.max_len: 200
| +| aggregate_types | repeated string | - | repeated.max_items: 10
| +| resource_owner | string | - | string.min_len: 0
string.max_len: 200
| | creation_date | google.protobuf.Timestamp | if asc is false creation_date is used as less than filter if asc is true creation_date is used as greater than filter if creation_date is not set the field is ignored | | diff --git a/docs/docs/apis/proto/event.md b/docs/docs/apis/proto/event.md index 2bb1de3bad..1df23c2dfe 100644 --- a/docs/docs/apis/proto/event.md +++ b/docs/docs/apis/proto/event.md @@ -16,12 +16,24 @@ title: zitadel/event.proto | Field | Type | Description | Validation | | ----- | ---- | ----------- | ----------- | | id | string | - | | -| type | string | - | | +| type | AggregateType | - | | | resource_owner | string | - | | +### AggregateType + + + +| Field | Type | Description | Validation | +| ----- | ---- | ----------- | ----------- | +| type | string | - | | +| localized | zitadel.v1.LocalizedMessage | - | | + + + + ### Editor @@ -46,7 +58,19 @@ title: zitadel/event.proto | sequence | uint64 | - | | | creation_date | google.protobuf.Timestamp | The timestamp the event occurred | | | payload | google.protobuf.Struct | - | | +| type | EventType | - | | + + + + +### EventType + + + +| Field | Type | Description | Validation | +| ----- | ---- | ----------- | ----------- | | type | string | - | | +| localized | zitadel.v1.LocalizedMessage | - | | diff --git a/internal/api/grpc/admin/event.go b/internal/api/grpc/admin/event.go index 21bdfb6b02..28f9578c46 100644 --- a/internal/api/grpc/admin/event.go +++ b/internal/api/grpc/admin/event.go @@ -3,15 +3,13 @@ package admin import ( "context" - "google.golang.org/protobuf/types/known/structpb" - "google.golang.org/protobuf/types/known/timestamppb" - "github.com/zitadel/zitadel/internal/api/authz" - "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/eventstore" - "github.com/zitadel/zitadel/internal/query" admin_pb "github.com/zitadel/zitadel/pkg/grpc/admin" - event_pb "github.com/zitadel/zitadel/pkg/grpc/event" +) + +const ( + maxLimit = 1000 ) func (s *Server) ListEvents(ctx context.Context, in *admin_pb.ListEventsRequest) (*admin_pb.ListEventsResponse, error) { @@ -23,19 +21,18 @@ func (s *Server) ListEvents(ctx context.Context, in *admin_pb.ListEventsRequest) if err != nil { return nil, err } - return convertEventsToResponse(events) + + return admin_pb.EventsToPb(ctx, events) } func (s *Server) ListEventTypes(ctx context.Context, in *admin_pb.ListEventTypesRequest) (*admin_pb.ListEventTypesResponse, error) { - return &admin_pb.ListEventTypesResponse{ - EventTypes: s.query.SearchEventTypes(ctx), - }, nil + eventTypes := s.query.SearchEventTypes(ctx) + return admin_pb.EventTypesToPb(eventTypes), nil } func (s *Server) ListAggregateTypes(ctx context.Context, in *admin_pb.ListAggregateTypesRequest) (*admin_pb.ListAggregateTypesResponse, error) { - return &admin_pb.ListAggregateTypesResponse{ - AggregateTypes: s.query.SearchAggregateTypes(ctx), - }, nil + aggregateTypes := s.query.SearchAggregateTypes(ctx) + return admin_pb.AggregateTypesToPb(aggregateTypes), nil } func eventRequestToFilter(ctx context.Context, req *admin_pb.ListEventsRequest) (*eventstore.SearchQueryBuilder, error) { @@ -43,16 +40,28 @@ func eventRequestToFilter(ctx context.Context, req *admin_pb.ListEventsRequest) for i, eventType := range req.EventTypes { eventTypes[i] = eventstore.EventType(eventType) } + aggregateIDs := make([]string, 0, 1) + if req.AggregateId != "" { + aggregateIDs = append(aggregateIDs, req.AggregateId) + } + aggregateTypes := make([]eventstore.AggregateType, len(req.AggregateTypes)) + for i, aggregateType := range req.AggregateTypes { + aggregateTypes[i] = eventstore.AggregateType(aggregateType) + } + limit := uint64(req.Limit) + if limit == 0 || limit > maxLimit { + limit = maxLimit + } builder := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). OrderDesc(). InstanceID(authz.GetInstance(ctx).InstanceID()). - Limit(uint64(req.Limit)). + Limit(limit). ResourceOwner(req.ResourceOwner). EditorUser(req.EditorUserId). AddQuery(). - AggregateIDs(req.AggregateId). - AggregateTypes(eventstore.AggregateType(req.AggregateType)). + AggregateIDs(aggregateIDs...). + AggregateTypes(aggregateTypes...). EventTypes(eventTypes...). CreationDateAfter(req.CreationDate.AsTime()). SequenceGreater(req.Sequence). @@ -64,44 +73,3 @@ func eventRequestToFilter(ctx context.Context, req *admin_pb.ListEventsRequest) return builder, nil } - -func convertEventsToResponse(events []*query.Event) (response *admin_pb.ListEventsResponse, err error) { - response = &admin_pb.ListEventsResponse{ - Events: make([]*event_pb.Event, len(events)), - } - - for i, event := range events { - response.Events[i], err = convertEvent(event) - if err != nil { - return nil, err - } - } - - return response, nil -} - -func convertEvent(event *query.Event) (*event_pb.Event, error) { - var payload *structpb.Struct - if len(event.Payload) > 0 { - payload = new(structpb.Struct) - if err := payload.UnmarshalJSON(event.Payload); err != nil { - return nil, errors.ThrowInternal(err, "ADMIN-eaimD", "Errors.Internal") - } - } - return &event_pb.Event{ - Editor: &event_pb.Editor{ - UserId: event.Editor.ID, - DisplayName: event.Editor.DisplayName, - Service: event.Editor.Service, - }, - Aggregate: &event_pb.Aggregate{ - Id: event.Aggregate.ID, - Type: string(event.Aggregate.Type), - ResourceOwner: event.Aggregate.ResourceOwner, - }, - Sequence: event.Sequence, - CreationDate: timestamppb.New(event.CreationDate), - Payload: payload, - Type: event.Type, - }, nil -} diff --git a/internal/api/grpc/event/event.go b/internal/api/grpc/event/event.go new file mode 100644 index 0000000000..5e671e1e41 --- /dev/null +++ b/internal/api/grpc/event/event.go @@ -0,0 +1,64 @@ +package event + +import ( + structpb "github.com/golang/protobuf/ptypes/struct" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/query" + eventpb "github.com/zitadel/zitadel/pkg/grpc/event" + "github.com/zitadel/zitadel/pkg/grpc/message" +) + +func EventsToPb(events []*query.Event) (response []*eventpb.Event, err error) { + response = make([]*eventpb.Event, len(events)) + + for i, event := range events { + response[i], err = EventToPb(event) + if err != nil { + return nil, err + } + } + + return response, nil +} + +func EventToPb(event *query.Event) (response *eventpb.Event, err error) { + var payload *structpb.Struct + if len(event.Payload) > 0 { + payload = new(structpb.Struct) + if err := payload.UnmarshalJSON(event.Payload); err != nil { + return nil, errors.ThrowInternal(err, "ADMIN-eaimD", "Errors.Internal") + } + } + return &eventpb.Event{ + Editor: &eventpb.Editor{ + UserId: event.Editor.ID, + DisplayName: event.Editor.DisplayName, + Service: event.Editor.Service, + }, + Aggregate: &eventpb.Aggregate{ + Id: event.Aggregate.ID, + Type: AggregateTypeToPb(string(event.Aggregate.Type)), + ResourceOwner: event.Aggregate.ResourceOwner, + }, + Sequence: event.Sequence, + CreationDate: timestamppb.New(event.CreationDate), + Payload: payload, + Type: EventTypeToPb(event.Type), + }, nil +} + +func EventTypeToPb(typ string) *eventpb.EventType { + return &eventpb.EventType{ + Type: typ, + Localized: message.NewLocalizedEventType(typ), + } +} + +func AggregateTypeToPb(typ string) *eventpb.AggregateType { + return &eventpb.AggregateType{ + Type: typ, + Localized: message.NewLocalizedAggregateType(typ), + } +} diff --git a/internal/api/grpc/server/middleware/translation_interceptor.go b/internal/api/grpc/server/middleware/translation_interceptor.go index 7761e94b2c..996e80acc6 100644 --- a/internal/api/grpc/server/middleware/translation_interceptor.go +++ b/internal/api/grpc/server/middleware/translation_interceptor.go @@ -7,22 +7,30 @@ import ( "google.golang.org/grpc" "github.com/zitadel/zitadel/internal/api/authz" - _ "github.com/zitadel/zitadel/internal/statik" + "github.com/zitadel/zitadel/internal/telemetry/tracing" ) func TranslationHandler() func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { resp, err := handler(ctx, req) - translator, translatorError := newZitadelTranslator(authz.GetInstance(ctx).DefaultLanguage()) - if translatorError != nil { - logging.New().WithError(translatorError).Error("could not load translator") - return resp, err - } + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + if loc, ok := resp.(localizers); ok && resp != nil { + translator, translatorError := newZitadelTranslator(authz.GetInstance(ctx).DefaultLanguage()) + if translatorError != nil { + logging.New().WithError(translatorError).Error("could not load translator") + return resp, err + } translateFields(ctx, loc, translator) } if err != nil { + translator, translatorError := newZitadelTranslator(authz.GetInstance(ctx).DefaultLanguage()) + if translatorError != nil { + logging.New().WithError(translatorError).Error("could not load translator") + return resp, err + } err = translateError(ctx, err, translator) } return resp, err diff --git a/internal/eventstore/eventstore.go b/internal/eventstore/eventstore.go index 9451a28b63..6e9e47f8e4 100644 --- a/internal/eventstore/eventstore.go +++ b/internal/eventstore/eventstore.go @@ -254,7 +254,7 @@ func (es *Eventstore) RegisterFilterEventMapper(aggregateType AggregateType, eve func (es *Eventstore) appendEventType(typ EventType) { i := sort.SearchStrings(es.eventTypes, string(typ)) - if i > 0 && es.eventTypes[i-1] == string(typ) { + if i < len(es.eventTypes) && es.eventTypes[i] == string(typ) { return } es.eventTypes = append(es.eventTypes[:i], append([]string{string(typ)}, es.eventTypes[i:]...)...) diff --git a/internal/query/event.go b/internal/query/event.go index 761bd5759c..1b5d3a6ab1 100644 --- a/internal/query/event.go +++ b/internal/query/event.go @@ -5,6 +5,7 @@ import ( "time" "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/telemetry/tracing" ) type Event struct { @@ -22,7 +23,9 @@ type EventEditor struct { Service string } -func (q *Queries) SearchEvents(ctx context.Context, query *eventstore.SearchQueryBuilder) ([]*Event, error) { +func (q *Queries) SearchEvents(ctx context.Context, query *eventstore.SearchQueryBuilder) (_ []*Event, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() events, err := q.eventstore.Filter(ctx, query) if err != nil { return nil, err @@ -41,21 +44,22 @@ func (q *Queries) SearchAggregateTypes(ctx context.Context) []string { func (q *Queries) convertEvents(ctx context.Context, events []eventstore.Event) []*Event { result := make([]*Event, len(events)) + users := make(map[string]string) for i, event := range events { - result[i] = q.convertEvent(ctx, event) + result[i] = q.convertEvent(ctx, event, users) } return result } -func (q *Queries) convertEvent(ctx context.Context, event eventstore.Event) *Event { - displayName := event.EditorUser() - user, err := q.GetUserByID(ctx, false, event.EditorUser(), false) - if err == nil { - if user.Human != nil { - displayName = user.Human.DisplayName - } else if user.Machine != nil { - displayName = user.Machine.Name - } +func (q *Queries) convertEvent(ctx context.Context, event eventstore.Event, users map[string]string) *Event { + ctx, span := tracing.NewSpan(ctx) + var err error + defer func() { span.EndWithError(err) }() + + displayName, ok := users[event.EditorUser()] + if !ok { + displayName = q.editorUserByID(ctx, event.EditorUser()) + users[event.EditorUser()] = displayName } return &Event{ @@ -71,3 +75,16 @@ func (q *Queries) convertEvent(ctx context.Context, event eventstore.Event) *Eve Payload: event.DataAsBytes(), } } + +func (q *Queries) editorUserByID(ctx context.Context, userID string) string { + user, err := q.GetUserByID(ctx, false, userID, false) + if err != nil { + return userID + } + if user.Human != nil { + return user.Human.DisplayName + } else if user.Machine != nil { + return user.Machine.Name + } + return userID +} diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml index efe3a28a82..47b68a6ea3 100644 --- a/internal/static/i18n/de.yaml +++ b/internal/static/i18n/de.yaml @@ -188,8 +188,8 @@ Errors: RedirectURIInvalid: Default Redirect URI ist ungültig NotExisting: Login Policy existiert nicht auf dieser Organisation AlreadyExists: Login Policy existiert bereits - IdpProviderAlreadyExisting: Idp Provider existiert bereits - IdpProviderNotExisting: Idp Provider existiert nicht + IdpProviderAlreadyExisting: Identity Provider existiert bereits + IdpProviderNotExisting: Identity Provider existiert nicht RegistrationNotAllowed: Registrierung ist nicht erlaubt UsernamePasswordNotAllowed: Login mit Username / Passwort nicht erlaubt MFA: @@ -425,6 +425,16 @@ Errors: CloseRows: SQL Statement konnte nicht abgeschlossen werden SQLStatement: SQL Statement konnte nicht erstellt werden InvalidRequest: Anfrage ist ungültig + +AggregateTypes: + action: Action + instance: Instanz + key_pair: Schlüsselpaar + org: Organisation + project: Projekt + user: Benutzer + usergrant: Benutzerberechtigung + EventTypes: user: added: Benutzer hinzugefügt @@ -438,9 +448,11 @@ EventTypes: failed: Benutzerinitialisierung fehlgeschlagen token: added: Access Token ausgestellt + removed: Access Token gelöscht username: reserved: Benutzername reserviert released: Benutzername freigegeben + changed: Benutzername geändert email: reserved: E-Mail-Adresse reserviert released: E-Mail-Adresse freigegeben @@ -580,6 +592,7 @@ EventTypes: code: added: Telefon Code hinzugefügt sent: Telefon Code versendet + removed: Telefonnummer gelöscht profile: changed: Benutzerprofil geändert address: @@ -592,6 +605,8 @@ EventTypes: check: succeeded: Multifaktor OTP Verifikation erfolgreich failed: Multifaktor OTP Verifikation fehlgeschlagen + init: + skipped: Multifaktor OTP übersprungen init: skipped: Multifaktor Initialisierung übersprungen signed: @@ -607,10 +622,16 @@ EventTypes: cascade: removed: Berechtigung entfernt changed: Berechtigung geändert - metadata: - set: Benutzer Metadaten gesetzt - removed: Benutzer Metadaten gelöscht - removed.all: Alle Benutzer Metadaten gelöscht + metadata: + set: Benutzer Metadaten gesetzt + removed: Benutzer Metadaten gelöscht + removed.all: Alle Benutzer Metadaten gelöscht + domain: + claimed: Domain beansprucht + claimed.sent: Domain Beanspruchungs Information gesendet + pat: + added: Personal Access Token hinzugefügt + removed: Personal Access Token gelöscht org: added: Organisation hinzugefügt changed: Organisation geändert @@ -657,6 +678,10 @@ EventTypes: config: added: SAML IDP Konfiguration hinzugefügt changed: SAML IDP Konfiguration geändert + jwt: + config: + added: JWT IDP Konfiguration hinzugefügt + changed: JWT IDP Konfiguration geändert customtext: set: Kundenspezifischer Text wurde gesetzt removed: Kundenspezifischer Text wurde entfernt @@ -668,8 +693,10 @@ EventTypes: changed: Login Richtlinie geändert removed: Login Richtlinie gelöscht idpprovider: - added: Idp Provider zu Login Richtlinie hinzugefügt - removed: Idp Provider aus Login Richtlinie gelöscht + added: Identity Provider zu Login Richtlinie hinzugefügt + removed: Identity Provider aus Login Richtlinie gelöscht + cascade: + removed: Login Richtlinie kaskadiert gelöscht secondfactor: added: Zweitfaktor zu Login Richtlinie hinzugefügt removed: Zweitfaktor aus Login Richtlinie gelöscht @@ -715,12 +742,34 @@ EventTypes: added: Datenschutzbestimmung und AGB hinzugefügt changed: Datenschutzbestimmung und AGB geändert removed: Datenschutzbestimmung und AGB entfernt + domain: + added: Domain Richtlinie hinzugefügt + changed: Domain Richtlinie geändert + removed: Domain Richtlinie gelöscht + lockout: + added: Passwortaussperrrichtlinie hinzugefügt + changed: Passwortaussperrrichtlinie geändert + removed: Passwortaussperrrichtlinie gelöscht flow: trigger_actions: set: Aktionen festgelegt cascade: removed: Aktionen kaskadiert entfernt removed: Aktionen entfernt + cleared: Flow zurückgesetzt + mail: + template: + added: E-Mail Vorlage hinzugefügt + changed: E-Mail Vorlage geändert + removed: E-Mail Vorlage gelöscht + text: + added: E-Mail Text hinzugefügt + changed: E-Mail Text geändert + removed: E-Mail Text gelöscht + metadata: + removed: Metadaten gelöscht + removed.all: Alle Metadaten gelöscht + set: Metadaten gesetzt project: added: Projekt hinzugefügt changed: Project geändert @@ -821,6 +870,10 @@ EventTypes: config: added: SAML IDP Konfiguration hinzugefügt changed: SAML IDP Konfiguration geändert + jwt: + config: + added: JWT IDP Konfiguration hizugefügt + changed: JWT IDP Konfiguration geändert customtext: set: Text wurde gesetzt removed: Text wurde entfernt @@ -829,8 +882,8 @@ EventTypes: added: Default Login Policy hinzugefügt changed: Default Login Policy geändert idpprovider: - added: Idp Provider zu Default Login Policy hinzugefügt - removed: Idp Provider aus Default Login Policy gelöscht + added: Identity Provider zu Default Login Policy hinzugefügt + removed: Identity Provider aus Default Login Policy gelöscht label: added: Label Richtlinie hinzugefügt changed: Label Richtlinie geändert @@ -883,12 +936,140 @@ EventTypes: deactivated: Twilio SMS Provider deaktiviert key_pair: added: Schlüsselpaar hinzugefügt + certificate: + added: Zertifikat hinzugefügt action: added: Aktion hinzugefügt changed: Aktion geändert deactivated: Aktion deaktiviert reactivated: Aktion reaktiviert removed: Aktion gelöscht + instance: + added: Instanz hinzugefügt + changed: Instanz gelöscht + customtext: + removed: Kundenspezifischer Text gelöscht + set: Kundenspezifischer Text gelöscht + template: + removed: Kundenspezifische Textvorlage gelöscht + default: + language: + set: Standard Sprache gesetzt + org: + set: Standard Organisation gesetzt + domain: + added: Domain hinzugefügt + primary: + set: Primäre Domain gesetzt + removed: Domain gelöscht + iam: + console: + set: ZITADEL Console Applikation gesetzt + project: + set: ZITADEL Projekt gesetzt + mail: + template: + added: E-Mail Vorlage hinzugefügt + changed: E-Mail Vorlage geändert + text: + added: E-Mail Text hinzugefügt + changed: E-Mail Text geändert + member: + added: Instanzmitglied hinzugefügt + changed: Instanzmitglied geändert + removed: Instanzmitglied gelöscht + cascade: + removed: Instanzmitglied kaskadierend gelöscht + notification: + provider: + debug: + fileadded: Datei zu Debug Notification Provider hinzugefügt + filechanged: Datei von Debug Notification Provider geändert + fileremoved: Datei von Debug Notification Provider gelöscht + logadded: Log von Debug Notification Provider hinzugefügt + logchanged: Log von Debug Notification Provider geändert + logremoved: Log von Debug Notification Provider gelöscht + oidc: + settings: + added: OIDC Einstellung hinzugefügt + changed: OIDC Einstellung geändert + policy: + domain: + added: Domain Richtlinie hinzugefügt + changed: Domain Richtlinie geändert + label: + activated: Label Richtlinie aktiviert + added: Label Richtlinie hinzugefügt + assets: + removed: Assets von Label Richtlinie gelöscht + changed: Label Richtlinie geändert + font: + added: Schriftart zu Label Richtlinie hinzugefügt + removed: Schriftart von Label Richtlinie gelöscht + icon: + added: Icon zu Label Richtlinie hinzugefügt + removed: Icon von Label Richtlinie gelöscht + dark: + added: Icon (dunkler Modus) zu Label Richtlinie hinzugefügt + removed: Icon (dunkler Modus) von Label Richtlinie gelöscht + logo: + added: Logo zu Label Richtlinie hinzugefügt + removed: Logo von Label Richtlinie gelöscht + dark: + added: Logo (dunkler Modus) zu Label Richtlinie hinzugefügt + removed: Logo (dunkler Modus) von Label Richtlinie gelöscht + lockout: + added: Passwortaussperrrichtlinie hinzugefügt + changed: Passwortaussperrrichtlinie geändert + login: + added: Login Richtlinie hinzugefügt + changed: Login Richtlinie geändert + idpprovider: + added: Identity Provider zu Login Richtlinie hinzugefügt + cascade: + removed: Identity Provider kaskadierend von Login Richtlinie gelöscht + removed: Identity Provider von Login Richtlinie gelöscht + multifactor: + added: Multifaktor zu Login Richtlinie hinzugefügt + removed: Multifaktor zu Login Richtlinie gelöscht + secondfactor: + added: Zweitfaktor zu Login Richtlinie hinzugefügt + removed: Zweitfaktor von Login Richtlinie gelöscht + password: + age: + added: Passwort Alterungsrichtlinie hinzugefügt + changed: Passwort Alterungsrichtlinie geändert + complexity: + added: Passwort Komplexitätsrichtlinie hinzugefügt + changed: Passwort Komplexitätsrichtlinie geändert + privacy: + added: Datenschutzrichtlinie hinzugefügt + changed: Datenschutzrichtlinie geändert + security: + set: Sicherheitsrichtlinie gesetzt + + removed: Instanz gelöscht + secret: + generator: + added: Passwortgenerator hinzugefügt + changed: Passwortgenerator geändert + removed: Passwortgenerator gelöscht + sms: + configtwilio: + activated: Twilio SMS Konfiguration aktiviert + added: Twilio SMS Konfiguration hinzugefügt + changed: Twilio SMS Konfiguration geändert + deactivated: Twilio SMS Konfiguration deaktiviert + removed: Twilio SMS Konfiguration gelöscht + token: + changed: Token zu Twilio SMS Konfiguration hinzugefügt + smtp: + config: + added: SMTP Konfiguration hinzugefügt + changed: SMTP Konfiguration geändert + password: + changed: Passwort von SMTP Konfiguration geändert + removed: SMTP Konfiguration gelöscht Application: OIDC: diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml index 580f3b76e2..6dac00e54e 100644 --- a/internal/static/i18n/en.yaml +++ b/internal/static/i18n/en.yaml @@ -188,8 +188,8 @@ Errors: RedirectURIInvalid: Default Redirect URI is invalid NotExisting: Login Policy not existing AlreadyExists: Login Policy already exists - IdpProviderAlreadyExisting: Idp Provider already existing - IdpProviderNotExisting: Idp Provider not existing + IdpProviderAlreadyExisting: Identity Provider already existing + IdpProviderNotExisting: Identity Provider not existing RegistrationNotAllowed: Registration is not allowed UsernamePasswordNotAllowed: Login with Username / Password is not allowed MFA: @@ -295,7 +295,7 @@ Errors: IdpIsNotOIDC: IDP configuration is not of type oidc LoginPolicyInvalid: Login Policy is invalid LoginPolicyNotExisting: Login Policy doesn't exist - IdpProviderInvalid: Idp Provider is invalid + IdpProviderInvalid: Identity Provider is invalid LoginPolicy: NotFound: Default Login Policy not found NotChanged: Default Login Policy has not been changed @@ -425,6 +425,16 @@ Errors: CloseRows: SQL Statement could not be finished SQLStatement: SQL Statement could not be created InvalidRequest: Request is invalid + +AggregateTypes: + action: Action + instance: Instance + key_pair: Key Pair + org: Organization + project: Project + user: User + usergrant: User grant + EventTypes: user: added: User added @@ -438,13 +448,15 @@ EventTypes: failed: Initialization check failed token: added: Access Token created + removed: Access Token removed username: reserved: Username reserved released: Username released + changed: Username changed email: reserved: Email address reserved released: Email address released - changed: Email address changed + changed: Email address changed verified: Email address verified verification: failed: Email address verification failed @@ -474,7 +486,7 @@ EventTypes: reserved: Username reserved released: Username released email: - changed: Email address changed + changed: Email address changed verified: Email address verified verification: failed: Email address verification failed @@ -580,6 +592,7 @@ EventTypes: code: added: Phone number code generated sent: Phone number code sent + removed: Phone number removed profile: changed: User profile changed address: @@ -592,6 +605,8 @@ EventTypes: check: succeeded: Multifactor OTP check succeeded failed: Multifactor OTP check failed + init: + skipped: Multifactor OTP initialization skipped init: skipped: Multifactor initialization skipped signed: @@ -611,6 +626,12 @@ EventTypes: set: User metadata set removed: User metadata removed removed.all: All user metadata removed + domain: + claimed: Domain claimed + claimed.sent: Domain claimed notification sent + pat: + added: Personal Access Token added + removed: Personal Access Token removed org: added: Organization added changed: Organization changed @@ -636,7 +657,7 @@ EventTypes: changed: Organization member changed removed: Organization member removed cascade: - removeD: Organization member cascade removed + removed: Organization member cascade removed iam: policy: added: System policy added @@ -657,6 +678,10 @@ EventTypes: config: added: SAML IDP configuration added changed: SAML IDP configuration changed + jwt: + config: + added: JWT IDP configuration added + changed: JWT IDP configuration changed customtext: set: Custom text set removed: Custom text removed @@ -668,8 +693,10 @@ EventTypes: changed: Login Policy changed removed: Login Policy removed idpprovider: - added: Idp Provider added to Login Policy - removed: Idp Provider removed from Login Policy + added: Identity Provider added to Login Policy + removed: Identity Provider removed from Login Policy + cascade: + removed: Identity Provider cascade removed from Login Policy secondfactor: added: Second factor added to Login Policy removed: Second factor removed from Login Policy @@ -715,12 +742,34 @@ EventTypes: added: Privacy policy and TOS added changed: Privacy policy and TOS changed removed: Privacy policy and TOS removed + domain: + added: Domain policy added + changed: Domain policy changed + removed: Domain policy removed + lockout: + added: Lockout policy added + changed: Lockout policy changed + removed: Lockout policy removed flow: trigger_actions: set: Action set cascade: removed: Actions cascade removed removed: Actions removed + cleared: Flow cleared + mail: + template: + added: E-Mail template added + changed: E-Mail template changed + removed: E-Mail template removed + text: + added: E-Mail text added + changed: E-Mail text changed + removed: E-Mail text removed + metadata: + removed: Metadata removed + removed.all: All metadata removed + set: Metadata set project: added: Project added changed: Project changed @@ -750,7 +799,7 @@ EventTypes: changed: Management access member changed removed: Management access member removed cascade: - removeD: Management access cascade removed + removed: Management access cascade removed application: added: Application added changed: Application changed @@ -821,6 +870,10 @@ EventTypes: config: added: SAML IDP configuration added changed: SAML IDP configuration changed + jwt: + config: + added: JWT configuration to identity provider added + changed: JWT configuration from identity provider remvoed customtext: set: Text was set removed: Text was removed @@ -829,8 +882,8 @@ EventTypes: added: Default Login Policy added changed: Default Login Policy changed idpprovider: - added: Idp Provider added to Default Login Policy - removed: Idp Provider removed from Default Login Policy + added: Identity Provider added to Default Login Policy + removed: Identity Provider removed from Default Login Policy label: added: Label Policy added changed: Label Policy changed @@ -883,12 +936,140 @@ EventTypes: deactivated: Twilio SMS provider deactivated key_pair: added: Key pair added + certificate: + added: Certificate added action: added: Action added changed: Action changed deactivated: Action deactivated reactivated: Action reactivated removed: Action removed + instance: + added: Instance added + changed: Instance changed + customtext: + removed: Custom text removed + set: Custom text set + template: + removed: Template of custom text removed + default: + language: + set: Default language set + org: + set: Default organisation set + domain: + added: Domain added + primary: + set: Primary domain set + removed: Domain removed + iam: + console: + set: ZITADEL Console application set + project: + set: ZITADEL project set + mail: + template: + added: E-Mail template added + changed: E-Mail template changed + text: + added: E-Mail text added + changed: E-Mail text changed + member: + added: Instance member added + changed: Instance member changed + removed: Instance member removed + cascade: + removed: Instance member cascade removed + notification: + provider: + debug: + fileadded: File debug notification provider added + filechanged: File debug notification provider changed + fileremoved: File debug notification provider removed + logadded: Log debug notification provider added + logchanged: Log debug notification provider changed + logremoved: Log debug notification provider removed + oidc: + settings: + added: OIDC settings added + changed: OIDC settings changed + policy: + domain: + added: Domain policy added + changed: Domain policy changed + label: + activated: Label policy activated + added: Label policy added + assets: + removed: Asset from label policy removed + changed: Label policy changed + font: + added: Font added to label policy + removed: Font remvoed from label policy + icon: + added: Icon added to label policy + removed: Icon removed from label policy + dark: + added: Icon added to dark label policy + removed: Icon removed from dark label policy + logo: + added: Logo added to label policy + removed: Logo removed from label policy + dark: + added: Logo added to dark label policy + removed: Logo removed from dark label policy + lockout: + added: Lockout policy added + changed: Lockout policy changed + login: + added: Login policy added + changed: Login policy changed + idpprovider: + added: Identity Provider added to login policy + cascade: + removed: Identity Provider cascade removed from login policy + removed: Identity Provider removed from login policy + multifactor: + added: Multifactor added to login policy + removed: Multifactor removed from login policy + secondfactor: + added: Secondfactor added to login policy + removed: Secondfactor removed from login policy + password: + age: + added: Password age policy added + changed: Password age policy changed + complexity: + added: Password complexity policy added + changed: Password complexity policy removed + privacy: + added: Privacy policy added + changed: Privacy policy changed + security: + set: Security policy set + + removed: Instance removed + secret: + generator: + added: Secret generator added + changed: Secret generator changed + removed: Secret generator removed + sms: + configtwilio: + activated: Twilio SMS configuration activated + added: Twilio SMS configuration added + changed: Twilio SMS configuration changed + deactivated: Twilio SMS configuration deactivated + removed: Twilio SMS configuration removed + token: + changed: Token of Twilio SMS configuration changed + smtp: + config: + added: SMTP configuration added + changed: SMTP configuration changed + password: + changed: Password of SMTP configuration changed + removed: SMTP configuration removed Application: OIDC: diff --git a/internal/static/i18n/fr.yaml b/internal/static/i18n/fr.yaml index e04fd4c066..9de4794226 100644 --- a/internal/static/i18n/fr.yaml +++ b/internal/static/i18n/fr.yaml @@ -425,6 +425,16 @@ Errors: CloseRows: L'instruction SQL n'a pas pu être terminée SQLStatement: L'instruction SQL n'a pas pu être créée InvalidRequest: La requête n'est pas valide + +AggregateTypes: + action: Action + instance: Instance + key_pair: Paire de clés + org: Organisation + project: Projet + user: Utilisateur + usergrant: Subvention de l'utilisateur + EventTypes: user: added: Utilisateur ajouté diff --git a/internal/static/i18n/it.yaml b/internal/static/i18n/it.yaml index 271185ebb8..0ca4d0a9dc 100644 --- a/internal/static/i18n/it.yaml +++ b/internal/static/i18n/it.yaml @@ -425,6 +425,16 @@ Errors: CloseRows: Lo statement SQL non può essere terminato SQLStatement: Lo statement SQL non può essere creato InvalidRequest: La richiesta non è valida + +AggregateTypes: + action: Azione + instance: Istanza + key_pair: Coppia di chiavi + org: Organizzazione + project: Progetto + user: Utente + usergrant: Sovvenzione utente + EventTypes: user: added: Utente aggiunto @@ -636,7 +646,7 @@ EventTypes: changed: Membro dell'organizzazione cambiato removed: Membro dell'organizzazione rimosso cascade: - removeD: Cascata di membri dell'organizzazione rimossa + removed: Cascata di membri dell'organizzazione rimossa iam: policy: added: Impostazioni IAM aggiunti @@ -732,7 +742,7 @@ EventTypes: changed: Membro del progetto cambiato removed: Membro del progetto rimosso cascade: - removeD: Cascata di membri del progetto rimossa + removed: Cascata di membri del progetto rimossa role: added: Ruolo del progetto aggiunto changed: Il ruolo del progetto è cambiato diff --git a/internal/static/i18n/zh.yaml b/internal/static/i18n/zh.yaml index 1547e4265b..cfd0d8c401 100644 --- a/internal/static/i18n/zh.yaml +++ b/internal/static/i18n/zh.yaml @@ -444,7 +444,7 @@ EventTypes: email: reserved: 电子邮件地址已保留 released: 电子邮件地址已发布 - changed: 电子邮件地址已更改 + changed: 电子邮件地址已更改 verified: 电子邮件地址已验证 verification: failed: 电子邮件验证失败 @@ -474,7 +474,7 @@ EventTypes: reserved: 保留用户名 released: 用户名已发布 email: - changed: 电子邮件地址已更改 + changed: 电子邮件地址已更改 verified: 电子邮件地址已验证 verification: failed: 电子邮件地址验证失败 @@ -636,7 +636,7 @@ EventTypes: changed: 更改组织成员 removed: 删除组织成员 cascade: - removeD: 已删除组织级联成员 + removed: 已删除组织级联成员 iam: policy: added: 添加系统策略 @@ -750,7 +750,7 @@ EventTypes: changed: 更改访问成员 removed: 删除访问成员 cascade: - removeD: 删除管理访问级联 + removed: 删除管理访问级联 application: added: 添加应用 changed: 更改应用 diff --git a/pkg/grpc/admin/event.go b/pkg/grpc/admin/event.go new file mode 100644 index 0000000000..bc1972406e --- /dev/null +++ b/pkg/grpc/admin/event.go @@ -0,0 +1,79 @@ +package admin + +import ( + "context" + + event_grpc "github.com/zitadel/zitadel/internal/api/grpc/event" + "github.com/zitadel/zitadel/internal/api/grpc/server/middleware" + "github.com/zitadel/zitadel/internal/query" + "github.com/zitadel/zitadel/internal/telemetry/tracing" + event_pb "github.com/zitadel/zitadel/pkg/grpc/event" +) + +func EventTypesToPb(eventTypes []string) *ListEventTypesResponse { + res := &ListEventTypesResponse{EventTypes: make([]*event_pb.EventType, len(eventTypes))} + + for i, eventType := range eventTypes { + res.EventTypes[i] = event_grpc.EventTypeToPb(eventType) + } + + return res +} + +func AggregateTypesToPb(aggregateTypes []string) *ListAggregateTypesResponse { + res := &ListAggregateTypesResponse{AggregateTypes: make([]*event_pb.AggregateType, len(aggregateTypes))} + + for i, aggregateType := range aggregateTypes { + res.AggregateTypes[i] = event_grpc.AggregateTypeToPb(aggregateType) + } + + return res +} + +func EventsToPb(ctx context.Context, events []*query.Event) (_ *ListEventsResponse, err error) { + _, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + res, err := event_grpc.EventsToPb(events) + if err != nil { + return nil, err + } + return &ListEventsResponse{ + Events: res, + }, nil +} + +func (resp *ListEventTypesResponse) Localizers() []middleware.Localizer { + if resp == nil { + return nil + } + + localizers := make([]middleware.Localizer, len(resp.EventTypes)) + for i, eventType := range resp.EventTypes { + localizers[i] = eventType.Localized + } + return localizers +} + +func (resp *ListAggregateTypesResponse) Localizers() []middleware.Localizer { + if resp == nil { + return nil + } + + localizers := make([]middleware.Localizer, len(resp.AggregateTypes)) + for i, aggregateType := range resp.AggregateTypes { + localizers[i] = aggregateType.Localized + } + return localizers +} + +func (resp *ListEventsResponse) Localizers() []middleware.Localizer { + if resp == nil { + return nil + } + + localizers := make([]middleware.Localizer, 0, len(resp.Events)*2) + for _, event := range resp.Events { + localizers = append(localizers, event.Type.Localized, event.Aggregate.Type.Localized) + } + return localizers +} diff --git a/pkg/grpc/message/message.go b/pkg/grpc/message/message.go index 034228c74c..0f05bda79b 100644 --- a/pkg/grpc/message/message.go +++ b/pkg/grpc/message/message.go @@ -12,6 +12,10 @@ func NewLocalizedEventType(key string) *LocalizedMessage { return &LocalizedMessage{Key: "EventTypes." + key} } +func NewLocalizedAggregateType(key string) *LocalizedMessage { + return &LocalizedMessage{Key: "AggregateTypes." + key} +} + func NewLocalizedMessage(key string) *LocalizedMessage { return &LocalizedMessage{Key: key} } diff --git a/proto/zitadel/admin.proto b/proto/zitadel/admin.proto index c41570424b..81cf9e35bb 100644 --- a/proto/zitadel/admin.proto +++ b/proto/zitadel/admin.proto @@ -13,6 +13,7 @@ import "zitadel/member.proto"; import "zitadel/event.proto"; import "zitadel/management.proto"; import "zitadel/v1.proto"; +import "zitadel/message.proto"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; @@ -4854,27 +4855,32 @@ message ListEventsRequest { } ]; string editor_user_id = 4 [ + (validate.rules).string = {min_len: 0, max_len: 200}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"69629023906488334\""; } ]; // the types are or filtered and must match the type exatly repeated string event_types = 5 [ + (validate.rules).repeated = {max_items: 30}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "[\"user.human.added\", \"user.machine\"]"; } ]; string aggregate_id = 6 [ + (validate.rules).string = {min_len: 0, max_len: 200}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"69629023906488334\""; } ]; - string aggregate_type = 7 [ + repeated string aggregate_types = 7 [ + (validate.rules).repeated = {max_items: 10}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"user\""; } ]; string resource_owner = 8 [ + (validate.rules).string = {min_len: 0, max_len: 200}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"69629023906488334\""; } @@ -4896,11 +4902,11 @@ message ListEventsResponse { message ListEventTypesRequest {} message ListEventTypesResponse { - repeated string event_types = 1; + repeated zitadel.event.v1.EventType event_types = 1; } message ListAggregateTypesRequest {} message ListAggregateTypesResponse { - repeated string aggregate_types = 1; + repeated zitadel.event.v1.AggregateType aggregate_types = 1; } diff --git a/proto/zitadel/event.proto b/proto/zitadel/event.proto index edca6fe049..b8ee2944bc 100644 --- a/proto/zitadel/event.proto +++ b/proto/zitadel/event.proto @@ -3,6 +3,8 @@ syntax = "proto3"; import "google/protobuf/timestamp.proto"; import "google/protobuf/struct.proto"; +import "zitadel/message.proto"; + import "protoc-gen-openapiv2/options/annotations.proto"; package zitadel.event.v1; @@ -20,7 +22,7 @@ message Event { } ]; google.protobuf.Struct payload = 5; - string type = 6; + EventType type = 6; } message Editor { @@ -31,6 +33,16 @@ message Editor { message Aggregate { string id = 1; - string type = 2; + AggregateType type = 2; string resource_owner = 3; } + +message EventType { + string type = 1; + zitadel.v1.LocalizedMessage localized = 2; +} + +message AggregateType { + string type = 1; + zitadel.v1.LocalizedMessage localized = 2; +} \ No newline at end of file