mirror of
https://dev.azure.com/schwarzit/schwarzit.stackit-public/_git/audit-go
synced 2026-02-09 09:37:24 +00:00
145 lines
4 KiB
Go
145 lines
4 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/audit/messaging"
|
|
auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/gen/go/audit/v1"
|
|
)
|
|
|
|
// routablePayload implements SerializedPayload.
|
|
type routablePayload struct {
|
|
payload []byte
|
|
contentType string
|
|
}
|
|
|
|
// GetPayload implements SerializedPayload.GetPayload.
|
|
func (p *routablePayload) GetPayload() []byte {
|
|
return p.payload
|
|
}
|
|
|
|
// GetContentType implements SerializedPayload.GetContentType.
|
|
func (p *routablePayload) GetContentType() string {
|
|
return p.contentType
|
|
}
|
|
|
|
// routableTopicNameResolver implements TopicNameResolver.
|
|
// Resolves topic names by concatenating topic type prefixes with routing identifiers.
|
|
type routableTopicNameResolver struct {
|
|
organizationTopicPrefix string
|
|
ProjectTopicPrefix string
|
|
// If no identifier is provided for routing, it will be routed to a system topic
|
|
systemTopicName string
|
|
}
|
|
|
|
// Resolve implements TopicNameResolver.Resolve.
|
|
func (r *routableTopicNameResolver) Resolve(routingIdentifier *RoutingIdentifier) (string, error) {
|
|
|
|
if routingIdentifier == nil {
|
|
return r.systemTopicName, nil
|
|
}
|
|
|
|
switch routingIdentifier.Type {
|
|
case RoutingIdentifierTypeOrganization:
|
|
return fmt.Sprintf("topic://%s/%s", r.organizationTopicPrefix, routingIdentifier.Identifier), nil
|
|
case RoutingIdentifierTypeProject:
|
|
return fmt.Sprintf("topic://%s/%s", r.ProjectTopicPrefix, routingIdentifier.Identifier), nil
|
|
default:
|
|
return "", ErrUnsupportedObjectIdentifierType
|
|
}
|
|
}
|
|
|
|
// topicNameConfig provides topic name information required for the topic name resolution.
|
|
type topicNameConfig struct {
|
|
OrganizationTopicPrefix string
|
|
ProjectTopicPrefix string
|
|
SystemTopicName string
|
|
}
|
|
|
|
// routableAuditApi is an implementation of AuditApi.
|
|
// Warning: It is only there for local (compatibility) testing.
|
|
// DO NOT USE IT!
|
|
type routableAuditApi struct {
|
|
messagingApi *messaging.MessagingApi
|
|
topicNameResolver *TopicNameResolver
|
|
validator *ProtobufValidator
|
|
}
|
|
|
|
// NewRoutableAuditApi can be used to initialize the audit log api.
|
|
func newRoutableAuditApi(
|
|
messagingApi *messaging.MessagingApi,
|
|
topicNameConfig topicNameConfig,
|
|
validator ProtobufValidator,
|
|
) (*AuditApi, error) {
|
|
|
|
if messagingApi == nil {
|
|
return nil, errors.New("messaging api nil")
|
|
}
|
|
|
|
// Topic resolver
|
|
var topicNameResolver TopicNameResolver = &routableTopicNameResolver{
|
|
organizationTopicPrefix: topicNameConfig.OrganizationTopicPrefix,
|
|
ProjectTopicPrefix: topicNameConfig.ProjectTopicPrefix,
|
|
systemTopicName: topicNameConfig.SystemTopicName,
|
|
}
|
|
|
|
// Audit api
|
|
var auditApi AuditApi = &routableAuditApi{
|
|
messagingApi: messagingApi,
|
|
topicNameResolver: &topicNameResolver,
|
|
validator: &validator,
|
|
}
|
|
|
|
return &auditApi, nil
|
|
}
|
|
|
|
// Log implements AuditApi.Log
|
|
func (a *routableAuditApi) Log(
|
|
ctx context.Context,
|
|
event *auditV1.AuditEvent,
|
|
visibility auditV1.Visibility,
|
|
routingIdentifier *RoutingIdentifier,
|
|
objectIdentifier *auditV1.ObjectIdentifier,
|
|
) error {
|
|
|
|
serializedPayload, err := a.ValidateAndSerialize(event, visibility, routingIdentifier, objectIdentifier)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return a.Send(ctx, routingIdentifier, &serializedPayload)
|
|
}
|
|
|
|
// ValidateAndSerialize implements AuditApi.ValidateAndSerialize
|
|
func (a *routableAuditApi) ValidateAndSerialize(
|
|
event *auditV1.AuditEvent,
|
|
visibility auditV1.Visibility,
|
|
routingIdentifier *RoutingIdentifier,
|
|
objectIdentifier *auditV1.ObjectIdentifier,
|
|
) (SerializedPayload, error) {
|
|
|
|
routableEvent, err := validateAndSerializePartially(
|
|
a.validator,
|
|
event,
|
|
visibility,
|
|
routingIdentifier,
|
|
objectIdentifier)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return serializeToProtobufMessage(routableEvent)
|
|
}
|
|
|
|
// Send implements AuditApi.Send
|
|
func (a *routableAuditApi) Send(
|
|
ctx context.Context,
|
|
routingIdentifier *RoutingIdentifier,
|
|
serializedPayload *SerializedPayload,
|
|
) error {
|
|
|
|
return send(a.topicNameResolver, a.messagingApi, ctx, routingIdentifier, serializedPayload)
|
|
}
|