From d7f1e78a3bba6821fbce71abf0c4e49253029319 Mon Sep 17 00:00:00 2001 From: Jan Steffen Date: Tue, 5 Jul 2022 15:27:55 +0200 Subject: [PATCH] Adjust interface to let the consumer get the real timestamp (#190) * Adjust interface to let the consumer get the real timestamp * Remove dead code * Fix typo --- api/domain/audit/event.proto | 4 +- api/domain/queryhandler_service.proto | 2 +- internal/audit_log_test.go | 20 +-- pkg/api/domain/audit/event.pb.go | 57 ++++---- pkg/api/domain/audit/event.pb.validate.go | 29 +++- .../domain/queryhandler_service_grpc.pb.go | 4 +- pkg/audit/formatters/audit/audit_formatter.go | 3 +- pkg/domain/aggregates/certificate.go | 104 --------------- pkg/domain/aggregates/certificate_test.go | 124 ------------------ pkg/domain/aggregates/suite_test.go | 17 --- pkg/domain/commandhandler.go | 3 - pkg/domain/commands/request_certificate.go | 45 ------- pkg/domain/constants/commands/commands.go | 8 -- pkg/domain/constants/formatters/formatters.go | 15 +-- pkg/domain/formatters/events/certificate.go | 78 ----------- 15 files changed, 73 insertions(+), 440 deletions(-) delete mode 100644 pkg/domain/aggregates/certificate.go delete mode 100644 pkg/domain/aggregates/certificate_test.go delete mode 100644 pkg/domain/commands/request_certificate.go delete mode 100644 pkg/domain/formatters/events/certificate.go diff --git a/api/domain/audit/event.proto b/api/domain/audit/event.proto index a348730c2..48b77ad5d 100644 --- a/api/domain/audit/event.proto +++ b/api/domain/audit/event.proto @@ -17,6 +17,8 @@ syntax = "proto3"; // This file follows google's gRPC naming conventions: // https://cloud.google.com/apis/design/naming_convention +import "google/protobuf/timestamp.proto"; + option go_package = "github.com/finleap-connect/monoskope/pkg/api/domain/audit"; package audit; @@ -24,7 +26,7 @@ package audit; // human readable representation of an event for auditing message HumanReadableEvent { // the timestamp when the event occurred - string when = 1; + google.protobuf.Timestamp timestamp = 1; // issuer name of the event string issuer = 2; // the uuid of the issuer diff --git a/api/domain/queryhandler_service.proto b/api/domain/queryhandler_service.proto index bb71ecdf1..4cce71b26 100644 --- a/api/domain/queryhandler_service.proto +++ b/api/domain/queryhandler_service.proto @@ -91,7 +91,7 @@ service ClusterAccess { } service AuditLog { - // GetByDateRange returns human-readable events within the specified data + // GetByDateRange returns human-readable events within the specified date // range rpc GetByDateRange(GetAuditLogByDateRangeRequest) returns (stream audit.HumanReadableEvent); diff --git a/internal/audit_log_test.go b/internal/audit_log_test.go index 5c1954bcf..57c35feb2 100644 --- a/internal/audit_log_test.go +++ b/internal/audit_log_test.go @@ -26,7 +26,6 @@ import ( cmdData "github.com/finleap-connect/monoskope/pkg/api/domain/commanddata" esApi "github.com/finleap-connect/monoskope/pkg/api/eventsourcing" cmd "github.com/finleap-connect/monoskope/pkg/domain/commands" - "github.com/finleap-connect/monoskope/pkg/domain/constants/aggregates" commandTypes "github.com/finleap-connect/monoskope/pkg/domain/constants/commands" fConsts "github.com/finleap-connect/monoskope/pkg/domain/constants/formatters" "github.com/finleap-connect/monoskope/pkg/domain/constants/roles" @@ -262,23 +261,6 @@ var _ = Describe("AuditLog Test", func() { expectedNumEventsDoneByAdmin++ expectedDetailMsgs = append(expectedDetailMsgs, fConsts.TenantClusterBindingCreatedDetailsFormat.Sprint(testEnv.gatewayTestEnv.AdminUser.Email, "Tenant Z", "Cluster Z")) - // RequestCertificate - command, err = cmd.AddCommandData( - cmd.CreateCommand(uuid.Nil, commandTypes.RequestCertificate), - &cmdData.RequestCertificate{ - ReferencedAggregateId: clusterId.String(), - ReferencedAggregateType: aggregates.Cluster.String(), - SigningRequest: []byte("-----BEGIN CERTIFICATE REQUEST-----this is a CSR-----END CERTIFICATE REQUEST-----"), - }, - ) - Expect(err).ToNot(HaveOccurred()) - Eventually(func(g Gomega) { - reply, err = commandHandlerClient().Execute(ctx, command) - g.Expect(err).ToNot(HaveOccurred()) - }).Should(Succeed()) - expectedNumEventsDoneByAdmin++ - expectedDetailMsgs = append(expectedDetailMsgs, fConsts.CertificateRequestedDetailsFormat.Sprint(testEnv.gatewayTestEnv.AdminUser.Email)) - // DeleteUser _, err = commandHandlerClient().Execute(ctx, cmd.CreateCommand(userId, commandTypes.DeleteUser)) @@ -342,7 +324,7 @@ var _ = Describe("AuditLog Test", func() { } Expect(err).ToNot(HaveOccurred()) - Expect(e.When).ToNot(BeEmpty()) + Expect(e.Timestamp).ToNot(BeNil()) Expect(e.Issuer).ToNot(BeEmpty()) Expect(e.IssuerId).ToNot(BeEmpty()) Expect(e.EventType).ToNot(BeEmpty()) diff --git a/pkg/api/domain/audit/event.pb.go b/pkg/api/domain/audit/event.pb.go index 76b389d2d..856e872cb 100644 --- a/pkg/api/domain/audit/event.pb.go +++ b/pkg/api/domain/audit/event.pb.go @@ -23,6 +23,7 @@ package audit import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -41,7 +42,7 @@ type HumanReadableEvent struct { unknownFields protoimpl.UnknownFields // the timestamp when the event occurred - When string `protobuf:"bytes,1,opt,name=when,proto3" json:"when,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // issuer name of the event Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` // the uuid of the issuer @@ -84,11 +85,11 @@ func (*HumanReadableEvent) Descriptor() ([]byte, []int) { return file_api_domain_audit_event_proto_rawDescGZIP(), []int{0} } -func (x *HumanReadableEvent) GetWhen() string { +func (x *HumanReadableEvent) GetTimestamp() *timestamppb.Timestamp { if x != nil { - return x.When + return x.Timestamp } - return "" + return nil } func (x *HumanReadableEvent) GetIssuer() string { @@ -124,21 +125,25 @@ var File_api_domain_audit_event_proto protoreflect.FileDescriptor var file_api_domain_audit_event_proto_rawDesc = []byte{ 0x0a, 0x1c, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, - 0x61, 0x75, 0x64, 0x69, 0x74, 0x22, 0x96, 0x01, 0x0a, 0x12, 0x48, 0x75, 0x6d, 0x61, 0x6e, 0x52, - 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x77, 0x68, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x77, 0x68, 0x65, 0x6e, - 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x73, 0x75, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x73, 0x73, - 0x75, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x3b, - 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x69, 0x6e, - 0x6c, 0x65, 0x61, 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2f, 0x6d, 0x6f, 0x6e, - 0x6f, 0x73, 0x6b, 0x6f, 0x70, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x61, 0x75, 0x64, 0x69, 0x74, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbc, 0x01, 0x0a, 0x12, 0x48, 0x75, 0x6d, 0x61, 0x6e, + 0x52, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, + 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x69, 0x6e, 0x6c, 0x65, 0x61, 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x2f, 0x6d, 0x6f, 0x6e, 0x6f, 0x73, 0x6b, 0x6f, 0x70, 0x65, 0x2f, 0x70, 0x6b, + 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x61, 0x75, 0x64, + 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -155,14 +160,16 @@ func file_api_domain_audit_event_proto_rawDescGZIP() []byte { var file_api_domain_audit_event_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_api_domain_audit_event_proto_goTypes = []interface{}{ - (*HumanReadableEvent)(nil), // 0: audit.HumanReadableEvent + (*HumanReadableEvent)(nil), // 0: audit.HumanReadableEvent + (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp } var file_api_domain_audit_event_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 1, // 0: audit.HumanReadableEvent.timestamp:type_name -> google.protobuf.Timestamp + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_api_domain_audit_event_proto_init() } diff --git a/pkg/api/domain/audit/event.pb.validate.go b/pkg/api/domain/audit/event.pb.validate.go index 93d6da492..906c19706 100644 --- a/pkg/api/domain/audit/event.pb.validate.go +++ b/pkg/api/domain/audit/event.pb.validate.go @@ -57,7 +57,34 @@ func (m *HumanReadableEvent) validate(all bool) error { var errors []error - // no validation rules for When + if all { + switch v := interface{}(m.GetTimestamp()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, HumanReadableEventValidationError{ + field: "Timestamp", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, HumanReadableEventValidationError{ + field: "Timestamp", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetTimestamp()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return HumanReadableEventValidationError{ + field: "Timestamp", + reason: "embedded message failed validation", + cause: err, + } + } + } // no validation rules for Issuer diff --git a/pkg/api/domain/queryhandler_service_grpc.pb.go b/pkg/api/domain/queryhandler_service_grpc.pb.go index 6c170016b..e09ab4ed3 100644 --- a/pkg/api/domain/queryhandler_service_grpc.pb.go +++ b/pkg/api/domain/queryhandler_service_grpc.pb.go @@ -1058,7 +1058,7 @@ var ClusterAccess_ServiceDesc = grpc.ServiceDesc{ // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type AuditLogClient interface { - // GetByDateRange returns human-readable events within the specified data + // GetByDateRange returns human-readable events within the specified date // range GetByDateRange(ctx context.Context, in *GetAuditLogByDateRangeRequest, opts ...grpc.CallOption) (AuditLog_GetByDateRangeClient, error) // GetByUser returns human-readable events caused by others actions on the @@ -1212,7 +1212,7 @@ func (x *auditLogGetUsersOverviewClient) Recv() (*audit.UserOverview, error) { // All implementations must embed UnimplementedAuditLogServer // for forward compatibility type AuditLogServer interface { - // GetByDateRange returns human-readable events within the specified data + // GetByDateRange returns human-readable events within the specified date // range GetByDateRange(*GetAuditLogByDateRangeRequest, AuditLog_GetByDateRangeServer) error // GetByUser returns human-readable events caused by others actions on the diff --git a/pkg/audit/formatters/audit/audit_formatter.go b/pkg/audit/formatters/audit/audit_formatter.go index 22a35c22d..4af62837e 100644 --- a/pkg/audit/formatters/audit/audit_formatter.go +++ b/pkg/audit/formatters/audit/audit_formatter.go @@ -23,7 +23,6 @@ import ( esApi "github.com/finleap-connect/monoskope/pkg/api/eventsourcing" "github.com/finleap-connect/monoskope/pkg/audit/formatters" "github.com/finleap-connect/monoskope/pkg/audit/formatters/event" - fConsts "github.com/finleap-connect/monoskope/pkg/domain/constants/formatters" _ "github.com/finleap-connect/monoskope/pkg/domain/formatters/events" "github.com/finleap-connect/monoskope/pkg/domain/formatters/overviews" "github.com/finleap-connect/monoskope/pkg/domain/projectors" @@ -57,7 +56,7 @@ func NewAuditFormatter(esClient esApi.EventStoreClient, efRegistry event.EventFo // NewHumanReadableEvent creates a HumanReadableEvent of a given event func (f *auditFormatter) NewHumanReadableEvent(ctx context.Context, event *esApi.Event) *audit.HumanReadableEvent { humanReadableEvent := &audit.HumanReadableEvent{ - When: event.Timestamp.AsTime().Format(fConsts.TimeFormat), + Timestamp: event.Timestamp, Issuer: event.Metadata[auth.HeaderAuthEmail], IssuerId: event.Metadata[auth.HeaderAuthId], EventType: event.Type, diff --git a/pkg/domain/aggregates/certificate.go b/pkg/domain/aggregates/certificate.go deleted file mode 100644 index 7eedbb71f..000000000 --- a/pkg/domain/aggregates/certificate.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2022 Monoskope Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package aggregates - -import ( - "context" - "fmt" - - "github.com/finleap-connect/monoskope/pkg/api/domain/eventdata" - "github.com/finleap-connect/monoskope/pkg/domain/commands" - "github.com/finleap-connect/monoskope/pkg/domain/constants/aggregates" - "github.com/finleap-connect/monoskope/pkg/domain/constants/events" - "github.com/finleap-connect/monoskope/pkg/domain/errors" - es "github.com/finleap-connect/monoskope/pkg/eventsourcing" - "github.com/google/uuid" -) - -// CertificateAggregate is an aggregate for certificates. -type CertificateAggregate struct { - *DomainAggregateBase - aggregateManager es.AggregateStore - referencedAggregateId uuid.UUID - referencedAggregateType es.AggregateType - signingRequest []byte - certificate []byte - caCertBundle []byte -} - -// CertificateAggregate creates a new CertificateAggregate -func NewCertificateAggregate(aggregateManager es.AggregateStore) es.Aggregate { - return &CertificateAggregate{ - DomainAggregateBase: &DomainAggregateBase{ - BaseAggregate: es.NewBaseAggregate(aggregates.Certificate), - }, - aggregateManager: aggregateManager, - } -} - -// HandleCommand implements the HandleCommand method of the Aggregate interface. -func (a *CertificateAggregate) HandleCommand(ctx context.Context, cmd es.Command) (*es.CommandReply, error) { - switch cmd := cmd.(type) { - case *commands.RequestCertificateCommand: - if a.Exists() { - return nil, errors.ErrCertificateAlreadyExists - } - ed := es.ToEventDataFromProto(&eventdata.CertificateRequested{ - ReferencedAggregateId: cmd.GetReferencedAggregateId(), - ReferencedAggregateType: cmd.GetReferencedAggregateType(), - SigningRequest: cmd.GetSigningRequest(), - }) - _ = a.AppendEvent(ctx, events.CertificateRequested, ed) - default: - return nil, fmt.Errorf("couldn't handle command of type '%s'", cmd.CommandType()) - } - return a.DefaultReply(), nil -} - -// ApplyEvent implements the ApplyEvent method of the Aggregate interface. -func (a *CertificateAggregate) ApplyEvent(event es.Event) error { - switch event.EventType() { - case events.CertificateRequested: - data := &eventdata.CertificateRequested{} - err := event.Data().ToProto(data) - if err != nil { - return err - } - - id, err := uuid.Parse(data.GetReferencedAggregateId()) - if err != nil { - return err - } - - a.referencedAggregateId = id - a.referencedAggregateType = es.AggregateType(data.GetReferencedAggregateType()) - a.signingRequest = data.GetSigningRequest() - case events.CertificateIssued: - data := &eventdata.CertificateIssued{} - err := event.Data().ToProto(data) - if err != nil { - return err - } - a.certificate = data.Certificate.GetCertificate() - a.caCertBundle = data.Certificate.GetCa() - case events.CertificateRequestIssued: - // ignored as it does not update the aggregate. TODO: the state of the signing should be tracked in the aggregate, and thus in the projection. - case events.CertificateIssueingFailed: - // ignored as it does not update the aggregate. TODO: the state of the signing should be tracked in the aggregate, and thus in the projection. - default: - return fmt.Errorf("couldn't handle event of type '%s'", event.EventType()) - } - return nil -} diff --git a/pkg/domain/aggregates/certificate_test.go b/pkg/domain/aggregates/certificate_test.go deleted file mode 100644 index dcd088771..000000000 --- a/pkg/domain/aggregates/certificate_test.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2022 Monoskope Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package aggregates - -import ( - "time" - - "github.com/finleap-connect/monoskope/pkg/api/domain/common" - "github.com/finleap-connect/monoskope/pkg/api/domain/eventdata" - "github.com/finleap-connect/monoskope/pkg/domain/constants/events" - es "github.com/finleap-connect/monoskope/pkg/eventsourcing" - "github.com/google/uuid" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Pkg/Domain/Aggregates/Certificate", func() { - It("should handle RequestCertificateCommand correctly", func() { - ctx := createSysAdminCtx() - agg := NewCertificateAggregate(NewTestAggregateManager()) - - reply, err := newRequestCertificateCommand(ctx, agg) - Expect(err).NotTo(HaveOccurred()) - // This is a create command and should set a new ID, regardless of what was passed in. - Expect(reply.Id).ToNot(Equal(uuid.Nil)) - Expect(reply.Id).ToNot(Equal(expectedReferencedAggregateId)) - - event := agg.UncommittedEvents()[0] - - Expect(event.EventType()).To(Equal(events.CertificateRequested)) - - data := &eventdata.CertificateRequested{} - err = event.Data().ToProto(data) - Expect(err).NotTo(HaveOccurred()) - - Expect(data.SigningRequest).To(Equal(expectedCSR)) - Expect(data.ReferencedAggregateId).To(Equal(expectedReferencedAggregateId.String())) - Expect(data.ReferencedAggregateType).To(Equal(expectedReferencedAggregateType.String())) - }) - - It("should handle CertificateRequested event correctly", func() { - ctx := createSysAdminCtx() - agg := NewCertificateAggregate(NewTestAggregateManager()) - - ed := es.ToEventDataFromProto(&eventdata.CertificateRequested{ - ReferencedAggregateId: expectedReferencedAggregateId.String(), - ReferencedAggregateType: expectedReferencedAggregateType.String(), - SigningRequest: expectedCSR, - }) - esEvent := es.NewEvent(ctx, events.CertificateRequested, ed, time.Now().UTC(), - agg.Type(), agg.ID(), agg.Version()) - - err := agg.ApplyEvent(esEvent) - Expect(err).NotTo(HaveOccurred()) - - Expect(agg.(*CertificateAggregate).signingRequest).To(Equal(expectedCSR)) - Expect(agg.(*CertificateAggregate).referencedAggregateId).To(Equal(expectedReferencedAggregateId)) - Expect(agg.(*CertificateAggregate).referencedAggregateType).To(Equal(expectedReferencedAggregateType)) - }) - It("should handle CertificateRequestIssuer event correctly", func() { - - ctx := createSysAdminCtx() - agg := NewCertificateAggregate(NewTestAggregateManager()) - - esEvent := es.NewEvent(ctx, events.CertificateRequestIssued, nil, time.Now().UTC(), - agg.Type(), agg.ID(), agg.Version()) - - err := agg.ApplyEvent(esEvent) - Expect(err).NotTo(HaveOccurred()) - }) - It("should handle CertificateIssued event correctly", func() { - - ctx := createSysAdminCtx() - agg := NewCertificateAggregate(NewTestAggregateManager()) - - cagg := agg.(*CertificateAggregate) - cagg.signingRequest = expectedCSR - cagg.referencedAggregateId = expectedReferencedAggregateId - cagg.referencedAggregateType = expectedReferencedAggregateType - - ed := es.ToEventDataFromProto(&eventdata.CertificateIssued{ - Certificate: &common.CertificateChain{ - Ca: expectedClusterCACertBundle, - Certificate: expectedCertificate, - }, - }) - - esEvent := es.NewEvent(ctx, events.CertificateIssued, ed, time.Now().UTC(), - agg.Type(), agg.ID(), agg.Version()) - - err := agg.ApplyEvent(esEvent) - Expect(err).NotTo(HaveOccurred()) - - Expect(cagg.signingRequest).To(Equal(expectedCSR)) - Expect(cagg.referencedAggregateId).To(Equal(expectedReferencedAggregateId)) - Expect(cagg.referencedAggregateType).To(Equal(expectedReferencedAggregateType)) - Expect(cagg.caCertBundle).To(Equal(expectedClusterCACertBundle)) - Expect(cagg.certificate).To(Equal(expectedCertificate)) - - }) - It("should handle CertificateIssueingFailed event correctly", func() { - - ctx := createSysAdminCtx() - agg := NewCertificateAggregate(NewTestAggregateManager()) - - esEvent := es.NewEvent(ctx, events.CertificateIssueingFailed, nil, time.Now().UTC(), - agg.Type(), agg.ID(), agg.Version()) - - err := agg.ApplyEvent(esEvent) - Expect(err).NotTo(HaveOccurred()) - }) -}) diff --git a/pkg/domain/aggregates/suite_test.go b/pkg/domain/aggregates/suite_test.go index 18c68ceb5..1d63de8ab 100644 --- a/pkg/domain/aggregates/suite_test.go +++ b/pkg/domain/aggregates/suite_test.go @@ -18,7 +18,6 @@ import ( "context" "testing" - "github.com/finleap-connect/monoskope/pkg/domain/commands" cmd "github.com/finleap-connect/monoskope/pkg/domain/commands" "github.com/finleap-connect/monoskope/pkg/domain/constants/aggregates" "github.com/finleap-connect/monoskope/pkg/domain/constants/roles" @@ -41,11 +40,6 @@ var ( expectedResourceId = uuid.New() expectedUserId = uuid.New() - expectedCSR = []byte("This should be a CSR") - expectedReferencedAggregateId = uuid.New() - expectedReferencedAggregateType = aggregates.Cluster - expectedCertificate = []byte("this should be the certificate") - expectedClusterDisplayName = "the one cluster" expectedClusterName = "one-cluster" expectedClusterApiServerAddress = "one.example.com" @@ -82,17 +76,6 @@ func createCluster(ctx context.Context, agg es.Aggregate) (*es.CommandReply, err return agg.HandleCommand(ctx, esCommand) } -func newRequestCertificateCommand(ctx context.Context, agg es.Aggregate) (*es.CommandReply, error) { - esCommand, ok := cmd.NewRequestCertificateCommand(uuid.New()).(*commands.RequestCertificateCommand) - Expect(ok).To(BeTrue()) - - esCommand.SigningRequest = expectedCSR - esCommand.ReferencedAggregateId = expectedReferencedAggregateId.String() - esCommand.ReferencedAggregateType = expectedReferencedAggregateType.String() - - return agg.HandleCommand(ctx, esCommand) -} - type aggregateTestStore struct { bindings map[uuid.UUID]es.Aggregate users map[uuid.UUID]es.Aggregate diff --git a/pkg/domain/commandhandler.go b/pkg/domain/commandhandler.go index 841bfd389..87967c793 100644 --- a/pkg/domain/commandhandler.go +++ b/pkg/domain/commandhandler.go @@ -52,9 +52,6 @@ func registerAggregates(esClient esApi.EventStoreClient) es.AggregateStore { // TenantClusterBinding es.DefaultAggregateRegistry.RegisterAggregate(func() es.Aggregate { return aggregates.NewTenantClusterBindingAggregate(aggregateManager) }) - // Certificate - es.DefaultAggregateRegistry.RegisterAggregate(func() es.Aggregate { return aggregates.NewCertificateAggregate(aggregateManager) }) - return aggregateManager } diff --git a/pkg/domain/commands/request_certificate.go b/pkg/domain/commands/request_certificate.go deleted file mode 100644 index 0d90d0fee..000000000 --- a/pkg/domain/commands/request_certificate.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2022 Monoskope Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package commands - -import ( - cmdData "github.com/finleap-connect/monoskope/pkg/api/domain/commanddata" - "github.com/finleap-connect/monoskope/pkg/domain/constants/aggregates" - "github.com/finleap-connect/monoskope/pkg/domain/constants/commands" - es "github.com/finleap-connect/monoskope/pkg/eventsourcing" - "github.com/google/uuid" - "google.golang.org/protobuf/types/known/anypb" -) - -func init() { - es.DefaultCommandRegistry.RegisterCommand(NewRequestCertificateCommand) -} - -// RequestCertificateCommand is a command for requesting a certificate for a given aggregate. -type RequestCertificateCommand struct { - *es.BaseCommand - cmdData.RequestCertificate -} - -// NewRequestCertificateCommand creates a RequestCertificateCommand. -func NewRequestCertificateCommand(id uuid.UUID) es.Command { - return &RequestCertificateCommand{ - BaseCommand: es.NewBaseCommand(id, aggregates.Certificate, commands.RequestCertificate), - } -} - -func (c *RequestCertificateCommand) SetData(a *anypb.Any) error { - return a.UnmarshalTo(&c.RequestCertificate) -} diff --git a/pkg/domain/constants/commands/commands.go b/pkg/domain/constants/commands/commands.go index 8ab8c2d30..d201e8b09 100644 --- a/pkg/domain/constants/commands/commands.go +++ b/pkg/domain/constants/commands/commands.go @@ -43,9 +43,6 @@ const ( // Command to update a Cluster UpdateCluster es.CommandType = "UpdateCluster" - // Command to request a certificate - RequestCertificate es.CommandType = "RequestCertificate" - // Command to allow a tenant to access a certain cluster CreateTenantClusterBinding es.CommandType = "CreateTenantClusterBinding" // Command to remove access of a tenant to a certain cluster @@ -81,16 +78,11 @@ var ( DeleteTenantClusterBinding, } - CertificateCommands = []es.CommandType{ - RequestCertificate, - } - CommandTypes = map[string][]es.CommandType{ "User": UserCommands, "UserRoleBinding": UserRoleBindingCommands, "Tenant": TenantCommands, "Cluster": ClusterCommands, "TenantClusterBinding": TenantClusterBindingCommands, - "Certificate": CertificateCommands, } ) diff --git a/pkg/domain/constants/formatters/formatters.go b/pkg/domain/constants/formatters/formatters.go index 461000df5..1ebcb1e3c 100644 --- a/pkg/domain/constants/formatters/formatters.go +++ b/pkg/domain/constants/formatters/formatters.go @@ -22,32 +22,27 @@ import ( type DetailsFormat string const ( - TimeFormat = time.RFC822 + TimeFormat = time.RFC3339 LeftQuoteSymbol = "“" RightQuoteSymbol = "“" UserCreatedDetailsFormat DetailsFormat = "“%s“ created user “%s“" - UserUpdatedDetailsFormat DetailsFormat = "“%s“ updated the User" + UserUpdatedDetailsFormat DetailsFormat = "“%s“ updated the user" UserRoleAddedDetailsFormat DetailsFormat = "“%s“ assigned the role “%s“ for scope “%s“ to user “%s“" UserDeletedDetailsFormat DetailsFormat = "“%s“ deleted user “%s“" UserRoleBindingDeletedDetailsFormat DetailsFormat = "“%s“ removed the role “%s“ for scope “%s“ from user “%s“" TenantCreatedDetailsFormat DetailsFormat = "“%s“ created tenant “%s“ with prefix “%s“" - TenantUpdatedDetailsFormat DetailsFormat = "“%s“ updated the Tenant" - TenantClusterBindingCreatedDetailsFormat DetailsFormat = "“%s“ bounded tenant “%s“ to cluster “%s”" + TenantUpdatedDetailsFormat DetailsFormat = "“%s“ updated the tenant" + TenantClusterBindingCreatedDetailsFormat DetailsFormat = "“%s“ granted tenant “%s“ access to cluster “%s”" TenantDeletedDetailsFormat DetailsFormat = "“%s“ deleted tenant “%s“" - TenantClusterBindingDeletedDetailsFormat DetailsFormat = "“%s“ deleted the bound between cluster “%s“ and tenant “%s“" + TenantClusterBindingDeletedDetailsFormat DetailsFormat = "“%s“ revoked access to cluster “%s“ for tenant “%s“" ClusterCreatedDetailsFormat DetailsFormat = "“%s“ created cluster “%s“" ClusterCreatedV2DetailsFormat DetailsFormat = ClusterCreatedDetailsFormat ClusterUpdatedDetailsFormat DetailsFormat = "“%s“ updated the cluster" ClusterDeletedDetailsFormat DetailsFormat = "“%s“ deleted cluster “%s“" - RequestIssuedDetailsFormat DetailsFormat = "“%s“ issued a certificate request" - CertificateRequestedDetailsFormat DetailsFormat = "“%s“ requested a certificate" - CertificateIssuedDetailsFormat DetailsFormat = "“%s“ issued a certificate" - CertificateIssuingFailedDetailsFormat DetailsFormat = "certificate request issuing faild for “%s“" - UserCreatedOverviewDetailsFormat DetailsFormat = "“%s“ was created by “%s“ at “%s“" UserDeletedOverviewDetailsFormat DetailsFormat = " and was deleted by “%s“ at “%s“" UserRoleBindingOverviewDetailsFormat DetailsFormat = "- %s %s\n" diff --git a/pkg/domain/formatters/events/certificate.go b/pkg/domain/formatters/events/certificate.go deleted file mode 100644 index 6bbb224de..000000000 --- a/pkg/domain/formatters/events/certificate.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2022 Monoskope Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package events - -import ( - "context" - - "github.com/finleap-connect/monoskope/internal/gateway/auth" - esApi "github.com/finleap-connect/monoskope/pkg/api/eventsourcing" - "github.com/finleap-connect/monoskope/pkg/audit/errors" - "github.com/finleap-connect/monoskope/pkg/audit/formatters/event" - "github.com/finleap-connect/monoskope/pkg/domain/constants/events" - fConsts "github.com/finleap-connect/monoskope/pkg/domain/constants/formatters" - es "github.com/finleap-connect/monoskope/pkg/eventsourcing" -) - -func init() { - for _, eventType := range events.CertificateEvents { - _ = event.DefaultEventFormatterRegistry.RegisterEventFormatter(eventType, NewCertificateEventFormatter) - } -} - -// certificateEventFormatter EventFormatter implementation for the certificate-aggregate -type certificateEventFormatter struct { - *event.EventFormatterBase - esClient esApi.EventStoreClient -} - -// NewCertificateEventFormatter creates a new event formatter for the certificate-aggregate -func NewCertificateEventFormatter(esClient esApi.EventStoreClient) event.EventFormatter { - return &certificateEventFormatter{ - &event.EventFormatterBase{}, esClient, - } -} - -// GetFormattedDetails formats the certificate-aggregate-events in a human-readable format -func (f *certificateEventFormatter) GetFormattedDetails(_ context.Context, event *esApi.Event) (string, error) { - switch es.EventType(event.Type) { - case events.CertificateRequestIssued: - return f.getFormattedDetailsCertificateRequestIssued(event) - case events.CertificateRequested: - return f.getFormattedDetailsCertificateRequested(event) - case events.CertificateIssued: - return f.getFormattedDetailsCertificateIssued(event) - case events.CertificateIssueingFailed: - return f.getFormattedDetailsCertificateIssuingFailed(event) - } - - return "", errors.ErrMissingFormatterImplementationForEventType -} - -func (f *certificateEventFormatter) getFormattedDetailsCertificateRequestIssued(event *esApi.Event) (string, error) { - return fConsts.RequestIssuedDetailsFormat.Sprint(event.Metadata[auth.HeaderAuthEmail]), nil -} - -func (f *certificateEventFormatter) getFormattedDetailsCertificateRequested(event *esApi.Event) (string, error) { - return fConsts.CertificateRequestedDetailsFormat.Sprint(event.Metadata[auth.HeaderAuthEmail]), nil -} - -func (f *certificateEventFormatter) getFormattedDetailsCertificateIssued(event *esApi.Event) (string, error) { - return fConsts.CertificateIssuedDetailsFormat.Sprint(event.Metadata[auth.HeaderAuthEmail]), nil -} - -func (f *certificateEventFormatter) getFormattedDetailsCertificateIssuingFailed(event *esApi.Event) (string, error) { - return fConsts.CertificateIssuingFailedDetailsFormat.Sprint(event.Metadata[auth.HeaderAuthEmail]), nil -}