package api import ( "context" "github.com/google/uuid" "time" auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/gen/go/audit/v1" "google.golang.org/protobuf/proto" ) type EventType string type SingularType string type PluralType string const ( EventTypeAdminActivity EventType = "admin-activity" EventTypeSystemEvent EventType = "system-event" EventTypePolicyDenied EventType = "policy-denied" EventTypeDataAccess EventType = "data-access" ) var SystemIdentifier = &auditV1.ObjectIdentifier{Identifier: uuid.Nil.String(), Type: string(SingularTypeSystem)} var RoutableSystemIdentifier = NewRoutableIdentifier(SystemIdentifier) // AuditApi is the interface to log audit events. // // It provides a Log method that can be used to validate and directly send events. // If the transactional outbox patter should be used, the ValidateAndSerialize and Send methods // can be called manually to decouple operations. type AuditApi interface { // Log is a convenience method that validates, serializes and sends data over the wire. // If the transactional outbox patter should be used, the ValidateAndSerialize method // and Send method can be called manually. // // Parameters: // * ctx - the context object // * event - the auditV1.AuditEvent // * visibility - route the event only internally or to the customer (no routing in the legacy solution) // * routableIdentifier - the identifier of the object // // It may return one of the following errors: // // - ErrUnknownSingularType - if the routableIdentifier type is unknown // - ErrUnknownPluralType - if the routableIdentifier type is unknown // - ErrEventNil - if event is nil // - ErrObjectIdentifierNil - if the object identifier is nil // - ErrObjectIdentifierVisibilityMismatch - if object identifier and visibility are not in a valid state // - ErrUnsupportedObjectIdentifierType - if an unsupported object identifier type was provided // - ErrAttributeIdentifierInvalid - if identifier in a checked attribute and the object identifier do not match // - ErrAttributeTypeInvalid - if the type from checked attribute and the type from object identifier do not match // - protovalidate.ValidationError - if schema validation errors have been detected // - protobuf serialization errors - if the event couldn't be serialized Log( ctx context.Context, event *auditV1.AuditLogEntry, visibility auditV1.Visibility, routableIdentifier *RoutableIdentifier, ) error // LogWithTrace is a convenience method that validates, serializes and sends data over the wire. // If the transactional outbox patter should be used, the ValidateAndSerialize method // and Send method can be called manually. // // Parameters: // * ctx - the context object // * event - the auditV1.AuditEvent // * visibility - route the event only internally or to the customer (no routing in the legacy solution) // * routableIdentifier - the identifier of the object // * traceParent - optional trace parent // * traceState - optional trace state // // It may return one of the following errors: // // - ErrUnknownSingularType - if the routableIdentifier type is unknown // - ErrUnknownPluralType - if the routableIdentifier type is unknown // - ErrEventNil - if event is nil // - ErrObjectIdentifierNil - if the object identifier is nil // - ErrObjectIdentifierVisibilityMismatch - if object identifier and visibility are not in a valid state // - ErrUnsupportedObjectIdentifierType - if an unsupported object identifier type was provided // - ErrAttributeIdentifierInvalid - if identifier in a checked attribute and the object identifier do not match // - ErrAttributeTypeInvalid - if the type from checked attribute and the type from object identifier do not match // - protovalidate.ValidationError - if schema validation errors have been detected // - protobuf serialization errors - if the event couldn't be serialized LogWithTrace( ctx context.Context, event *auditV1.AuditLogEntry, visibility auditV1.Visibility, routableIdentifier *RoutableIdentifier, traceParent *string, traceState *string, ) error // ValidateAndSerialize validates and serializes the event into a byte representation. // The result has to be sent explicitly by calling the Send method. ValidateAndSerialize( event *auditV1.AuditLogEntry, visibility auditV1.Visibility, routableIdentifier *RoutableIdentifier, ) (*CloudEvent, error) // ValidateAndSerializeWithTrace validates and serializes the event into a byte representation. // The result has to be sent explicitly by calling the Send method. ValidateAndSerializeWithTrace( event *auditV1.AuditLogEntry, visibility auditV1.Visibility, routableIdentifier *RoutableIdentifier, traceParent *string, traceState *string, ) (*CloudEvent, error) // Send the serialized content as byte array to the audit log system. // It may return one of the following errors: // // - ErrTopicNameResolverNil - if the topic name resolver is nil // - ErrMessagingApiNil - if the messaging api is nil // - ErrCloudEventNil - if the cloud event is nil // - ErrObjectIdentifierNil - if the object identifier is nil // - amqp errors - if the event couldn't be sent Send( ctx context.Context, routableIdentifier *RoutableIdentifier, cloudEvent *CloudEvent, ) error } // ProtobufValidator is an abstraction for validators. // Concrete implementations are e.g. protovalidate.Validator type ProtobufValidator interface { Validate(msg proto.Message) error } // CloudEvent is a representation of a cloudevents.io object. // // More information about the schema and attribute semantics can be found here: // https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#required-attributes type CloudEvent struct { // The version of the CloudEvents specification which the event uses. // This enables the interpretation of the context. Compliant event producers MUST use a value of 1.0 // when referring to this version of the specification. // // Currently, this attribute will only have the 'major' and 'minor' version numbers included in it. // This allows for 'patch' changes to the specification to be made without changing this property's // value in the serialization. specVersion string // The source system uri-reference. Producers MUST ensure that source + id is unique for each distinct event. source string // Identifier of the event. Producers MUST ensure that source + id is unique for each distinct event. // If a duplicate event is re-sent (e.g. due to a network error) it MAY have the same id. // Consumers MAY assume that Events with identical source and id are duplicates. id string // The time when the event happened time time.Time // The content type of the payload // Examples could be: // - application/cloudevents+json // - application/cloudevents+json; charset=UTF-8 // - application/cloudevents-batch+json // - application/cloudevents+protobuf // - application/cloudevents+avro // Source: https://github.com/cloudevents/spec/blob/main/cloudevents/formats/protobuf-format.md dataContentType string // The object type (i.e. the fully qualified protobuf type name) dataType string // The identifier of the referring object. subject string // The serialized payload data []byte // Optional W3C conform trace parent: // https://www.w3.org/TR/trace-context/#traceparent-header // // Format: --- // // Examples: // "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" traceParent *string // Optional W3C conform trace state header: // https://www.w3.org/TR/trace-context/#tracestate-header // // Format: =[,=] // // Examples: // "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE" traceState *string } // TopicNameResolver is an abstraction for dynamic topic name resolution // based on event data or api parameters. type TopicNameResolver interface { // Resolve returns a topic name for the given object identifier Resolve(objectIdentifier *RoutableIdentifier) (string, error) } type RoutableIdentifier struct { Identifier string Type SingularType } func NewRoutableIdentifier(objectIdentifier *auditV1.ObjectIdentifier) *RoutableIdentifier { if objectIdentifier == nil { return nil } return &RoutableIdentifier{ Identifier: objectIdentifier.Identifier, Type: SingularType(objectIdentifier.Type), } } func (r RoutableIdentifier) ToObjectIdentifier() *auditV1.ObjectIdentifier { return &auditV1.ObjectIdentifier{ Identifier: r.Identifier, Type: string(r.Type), } }