audit-go/audit/api/api.go
Christian Schaible 50be98360c Rename module
2024-08-23 07:28:15 +02:00

228 lines
8.5 KiB
Go

package api
import (
"context"
"time"
"github.com/google/uuid"
auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/audit-go.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: <version>-<trace-id>-<parent-id>-<trace-flags>
//
// Examples:
// "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
TraceParent *string
// Optional W3C conform trace state header:
// https://www.w3.org/TR/trace-context/#tracestate-header
//
// Format: <key1>=<value1>[,<keyN>=<valueN>]
//
// 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(routableIdentifier *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),
}
}