package api import ( "encoding/base64" "encoding/json" "errors" "strings" ) const base64AuditEventV1 = "v1" var ErrBase64StringEmpty = errors.New("base64 string must not be empty") var ErrRoutableIdentifierNil = errors.New("routableIdentifier must not be nil") var ErrUnsupportedBase64StringVersion = errors.New("unsupported base64 cloud event string version") type serializableEvent struct { CloudEvent CloudEvent `json:"cloudEvent"` RoutableIdentifier RoutableIdentifier `json:"routableIdentifier"` } func ToBase64( cloudEvent *CloudEvent, routableIdentifier *RoutableIdentifier) (*string, error) { if cloudEvent == nil { return nil, ErrCloudEventNil } if routableIdentifier == nil { return nil, ErrRoutableIdentifierNil } event := serializableEvent{ CloudEvent: *cloudEvent, RoutableIdentifier: *routableIdentifier, } serializedEvent, err := json.Marshal(event) if err != nil { return nil, err } base64Str := base64.StdEncoding.EncodeToString(serializedEvent) base64Str = base64Str + base64AuditEventV1 return &base64Str, nil } func FromBase64(base64Str string) (*CloudEvent, *RoutableIdentifier, error) { if base64Str == "" { return nil, nil, ErrBase64StringEmpty } if !strings.HasSuffix(base64Str, base64AuditEventV1) { return nil, nil, ErrUnsupportedBase64StringVersion } base64Str = strings.TrimSuffix(base64Str, base64AuditEventV1) base64Bytes, err := base64.StdEncoding.DecodeString(base64Str) if err != nil { return nil, nil, err } event := serializableEvent{} err = json.Unmarshal(base64Bytes, &event) if err != nil { return nil, nil, err } return &event.CloudEvent, &event.RoutableIdentifier, nil }