audit-go/audit/api/api.go
2024-10-15 15:09:28 +02:00

247 lines
7.4 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
const (
EventTypeAdminActivity EventType = "admin-activity"
EventTypeSystemEvent EventType = "system-event"
EventTypePolicyDenied EventType = "policy-denied"
EventTypeDataAccess EventType = "data-access"
)
type ObjectType string
const (
ObjectTypeSystem ObjectType = "system"
ObjectTypeOrganization ObjectType = "organization"
ObjectTypeFolder ObjectType = "folder"
ObjectTypeProject ObjectType = "project"
)
func ObjectTypeFromPluralString(value string) ObjectType {
switch value {
case "organizations":
return ObjectTypeOrganization
case "folders":
return ObjectTypeFolder
case "projects":
return ObjectTypeProject
case "system":
return ObjectTypeSystem
default:
return ObjectType(value)
}
}
func (t ObjectType) IsSupportedType() error {
switch t {
case ObjectTypeOrganization:
fallthrough
case ObjectTypeFolder:
fallthrough
case ObjectTypeProject:
fallthrough
case ObjectTypeSystem:
return nil
default:
return ErrUnknownObjectType
}
}
func (t ObjectType) Plural() string {
switch t {
case ObjectTypeOrganization:
return "organizations"
case ObjectTypeFolder:
return "folders"
case ObjectTypeProject:
return "projects"
case ObjectTypeSystem:
return "system"
default:
return ""
}
}
var SystemIdentifier = &auditV1.ObjectIdentifier{Identifier: uuid.Nil.String(), Type: string(ObjectTypeSystem)}
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
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
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.
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 ObjectType
}
func NewRoutableIdentifier(objectIdentifier *auditV1.ObjectIdentifier) *RoutableIdentifier {
if objectIdentifier == nil {
return nil
}
return &RoutableIdentifier{
Identifier: objectIdentifier.Identifier,
Type: ObjectType(objectIdentifier.Type),
}
}
func (r RoutableIdentifier) ToObjectIdentifier() *auditV1.ObjectIdentifier {
return &auditV1.ObjectIdentifier{
Identifier: r.Identifier,
Type: string(r.Type),
}
}