From 99d6da412127cf47839328d226930e8c714c5fb7 Mon Sep 17 00:00:00 2001 From: Jim Date: Sat, 23 Oct 2021 21:23:49 -0400 Subject: [PATCH] feature (events): Add audit request interceptors (#1620) --- internal/gen/controller/auth/auth.pb.go | 35 ++++++++--- .../proto/local/controller/auth/v1/auth.proto | 6 ++ internal/servers/controller/gateway.go | 22 ++++++- internal/servers/controller/handler.go | 12 ++++ .../handlers/outgoing_response_filter.go | 7 --- internal/servers/controller/interceptor.go | 63 +++++++++++++++++++ .../servers/controller/interceptor_test.go | 45 ++++++++++++- internal/servers/controller/listeners.go | 2 +- 8 files changed, 171 insertions(+), 21 deletions(-) diff --git a/internal/gen/controller/auth/auth.pb.go b/internal/gen/controller/auth/auth.pb.go index 103a2360a..90649f069 100644 --- a/internal/gen/controller/auth/auth.pb.go +++ b/internal/gen/controller/auth/auth.pb.go @@ -49,6 +49,10 @@ type RequestInfo struct { // ticket is a unique id that allows the grpc-gateway to verify that the info // came from its companion http proxy Ticket string `protobuf:"bytes,110,opt,name=ticket,proto3" json:"ticket,omitempty"` + // trace_id is the request's trace_id + TraceId string `protobuf:"bytes,120,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` + // event_id is the request's event id + EventId string `protobuf:"bytes,130,opt,name=event_id,json=eventId,proto3" json:"event_id,omitempty"` } func (x *RequestInfo) Reset() { @@ -160,13 +164,27 @@ func (x *RequestInfo) GetTicket() string { return "" } +func (x *RequestInfo) GetTraceId() string { + if x != nil { + return x.TraceId + } + return "" +} + +func (x *RequestInfo) GetEventId() string { + if x != nil { + return x.EventId + } + return "" +} + var File_controller_auth_v1_auth_proto protoreflect.FileDescriptor var file_controller_auth_v1_auth_proto_rawDesc = []byte{ 0x0a, 0x1d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x75, 0x74, 0x68, - 0x2e, 0x76, 0x31, 0x22, 0x90, 0x03, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x2e, 0x76, 0x31, 0x22, 0xc7, 0x03, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, @@ -191,12 +209,15 @@ var file_controller_auth_v1_auth_proto_rawDesc = []byte{ 0x65, 0x6c, 0x79, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x75, 0x74, 0x68, 0x45, 0x6e, 0x74, 0x69, 0x72, 0x65, 0x6c, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, - 0x61, 0x75, 0x74, 0x68, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x74, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x78, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x82, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x42, 0x41, 0x5a, + 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x3b, 0x61, 0x75, 0x74, 0x68, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/internal/proto/local/controller/auth/v1/auth.proto b/internal/proto/local/controller/auth/v1/auth.proto index 840ffa12b..d4395722c 100644 --- a/internal/proto/local/controller/auth/v1/auth.proto +++ b/internal/proto/local/controller/auth/v1/auth.proto @@ -39,4 +39,10 @@ message RequestInfo { // ticket is a unique id that allows the grpc-gateway to verify that the info // came from its companion http proxy string ticket = 110; + + // trace_id is the request's trace_id + string trace_id = 120; + + // event_id is the request's event id + string event_id = 130; } diff --git a/internal/servers/controller/gateway.go b/internal/servers/controller/gateway.go index 41f6d76a9..40142890e 100644 --- a/internal/servers/controller/gateway.go +++ b/internal/servers/controller/gateway.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/observability/event" "github.com/hashicorp/boundary/internal/servers/controller/common" "github.com/hashicorp/boundary/internal/servers/controller/handlers" "google.golang.org/grpc" @@ -49,19 +50,34 @@ func newGatewayMux() *runtime.ServeMux { ) } -func newGatewayServer(ctx context.Context, iamRepoFn common.IamRepoFactory, authTokenRepoFn common.AuthTokenRepoFactory, serversRepoFn common.ServersRepoFactory, kms *kms.Kms) (*grpc.Server, string, error) { +func newGatewayServer( + ctx context.Context, + iamRepoFn common.IamRepoFactory, + authTokenRepoFn common.AuthTokenRepoFactory, + serversRepoFn common.ServersRepoFactory, + kms *kms.Kms, + eventer *event.Eventer, +) (*grpc.Server, string, error) { const op = "controller.newGatewayServer" ticket, err := db.NewPrivateId("gwticket") if err != nil { return nil, "", errors.Wrap(ctx, err, op, errors.WithMsg("unable to generate gateway ticket")) } - requestCtxInterceptor, err := requestCtxInterceptor(ctx, iamRepoFn, authTokenRepoFn, serversRepoFn, kms, ticket) + requestCtxInterceptor, err := requestCtxInterceptor(ctx, iamRepoFn, authTokenRepoFn, serversRepoFn, kms, ticket, eventer) if err != nil { return nil, "", err } return grpc.NewServer( grpc.MaxRecvMsgSize(math.MaxInt32), grpc.MaxSendMsgSize(math.MaxInt32), - grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(requestCtxInterceptor, errorInterceptor(ctx), statusCodeInterceptor(ctx))), + grpc.UnaryInterceptor( + grpc_middleware.ChainUnaryServer( + requestCtxInterceptor, // populated requestInfo from headers into the request ctx + auditRequestInterceptor(ctx), // before we get started, audit the request + errorInterceptor(ctx), // convert domain and api errors into headers for the http proxy + statusCodeInterceptor(ctx), // convert grpc codes into http status codes for the http proxy (can modify the resp) + auditResponseInterceptor(ctx), // as we finish, audit the response + ), + ), ), ticket, nil } diff --git a/internal/servers/controller/handler.go b/internal/servers/controller/handler.go index da5f6d5ec..1f92de586 100644 --- a/internal/servers/controller/handler.go +++ b/internal/servers/controller/handler.go @@ -287,6 +287,16 @@ func wrapHandlerWithCommonFuncs(h http.Handler, c *Controller, props HandlerProp requestInfo.PublicId, requestInfo.EncryptedToken, requestInfo.TokenFormat = auth.GetTokenFromRequest(ctx, c.kms, r) + if info, ok := event.RequestInfoFromContext(ctx); ok { + // piggyback some eventing fields with the auth info proto message + requestInfo.EventId = info.EventId + requestInfo.TraceId = info.Id + } else { + w.WriteHeader(http.StatusInternalServerError) + event.WriteError(ctx, op, errors.New("unable to read event request info from context")) + return + } + // Serialize the request info to send it across the wire to the // grpc-gateway via an http header requestInfo.Ticket = c.gatewayTicket // allows the grpc-gateway to verify the request info came from it's in-memory companion http proxy @@ -301,6 +311,8 @@ func wrapHandlerWithCommonFuncs(h http.Handler, c *Controller, props HandlerProp // See: https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime#DefaultHeaderMatcher r.Header.Set("Grpc-Metadata-"+requestInfoMdKey, base58.FastBase58Encoding(marshalledRequestInfo)) + // Set the context back on the request + r = r.WithContext(ctx) h.ServeHTTP(w, r) }) } diff --git a/internal/servers/controller/handlers/outgoing_response_filter.go b/internal/servers/controller/handlers/outgoing_response_filter.go index 304409775..08150f783 100644 --- a/internal/servers/controller/handlers/outgoing_response_filter.go +++ b/internal/servers/controller/handlers/outgoing_response_filter.go @@ -11,7 +11,6 @@ import ( "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" - "github.com/hashicorp/boundary/internal/observability/event" authtokenpb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/authtokens" "google.golang.org/grpc" @@ -65,12 +64,6 @@ func OutgoingResponseFilter(ctx context.Context, w http.ResponseWriter, m proto. } } - // add the outgoing resp proto. See: common.flushGatedEvents is where the - // event.Response.StatusCode is added. - if err := event.WriteAudit(ctx, op, event.WithResponse(&event.Response{Details: m})); err != nil { - return fmt.Errorf("%s: unable to write audit event: %w", op, err) - } - switch m := m.(type) { case *pbs.AuthenticateResponse: if m.GetAttributes() == nil || m.GetAttributes().GetFields() == nil { diff --git a/internal/servers/controller/interceptor.go b/internal/servers/controller/interceptor.go index 4dfaeab98..c7887ce76 100644 --- a/internal/servers/controller/interceptor.go +++ b/internal/servers/controller/interceptor.go @@ -11,6 +11,7 @@ import ( authpb "github.com/hashicorp/boundary/internal/gen/controller/auth" pberrors "github.com/hashicorp/boundary/internal/gen/errors" "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/observability/event" "github.com/hashicorp/boundary/internal/requests" "github.com/hashicorp/boundary/internal/servers/controller/auth" "github.com/hashicorp/boundary/internal/servers/controller/common" @@ -48,6 +49,7 @@ func requestCtxInterceptor( serversRepoFn common.ServersRepoFactory, kms *kms.Kms, ticket string, + eventer *event.Eventer, ) (grpc.UnaryServerInterceptor, error) { const op = "controller.requestCtxInterceptor" if iamRepoFn == nil { @@ -65,6 +67,9 @@ func requestCtxInterceptor( if ticket == "" { return nil, errors.New(ctx, errors.InvalidParameter, op, "missing ticket") } + if eventer == nil { + return nil, errors.New(ctx, errors.InvalidParameter, op, "missing eventer") + } // Authorization unary interceptor function to handle authorize per RPC call return func(interceptorCtx context.Context, req interface{}, @@ -112,6 +117,23 @@ func requestCtxInterceptor( Method: requestInfo.Method, }) + // This event request info is required by downstream handlers + info := &event.RequestInfo{ + EventId: requestInfo.EventId, + Id: requestInfo.TraceId, + PublicId: requestInfo.PublicId, + Method: requestInfo.Method, + Path: requestInfo.Path, + } + interceptorCtx, err = event.NewRequestInfoContext(interceptorCtx, info) + if err != nil { + return nil, errors.Wrap(interceptorCtx, err, op, errors.WithCode(errors.Internal), errors.WithMsg("unable to create context with request info")) + } + interceptorCtx, err = event.NewEventerContext(interceptorCtx, eventer) + if err != nil { + return nil, errors.Wrap(interceptorCtx, err, op, errors.WithCode(errors.Internal), errors.WithMsg("unable to create context with eventer")) + } + // Calls the handler h, err := handler(interceptorCtx, req) @@ -205,3 +227,44 @@ func isNil(i interface{}) bool { } return false } + +func auditRequestInterceptor( + _ context.Context, +) grpc.UnaryServerInterceptor { + const op = "controller.auditRequestInterceptor" + return func(interceptorCtx context.Context, + req interface{}, + _ *grpc.UnaryServerInfo, + handler grpc.UnaryHandler) (interface{}, error) { + + if msg, ok := req.(proto.Message); ok { + if err := event.WriteAudit(interceptorCtx, op, event.WithRequest(&event.Request{Details: msg})); err != nil { + return req, status.Errorf(codes.Internal, "unable to write request msg audit: %s", err) + } + } + + return handler(interceptorCtx, req) + } +} + +func auditResponseInterceptor( + _ context.Context, +) grpc.UnaryServerInterceptor { + const op = "controller.auditRequestInterceptor" + return func(interceptorCtx context.Context, + req interface{}, + _ *grpc.UnaryServerInfo, + handler grpc.UnaryHandler) (interface{}, error) { + + // call the handler... + resp, err := handler(interceptorCtx, req) + + if msg, ok := resp.(proto.Message); ok { + if err := event.WriteAudit(interceptorCtx, op, event.WithResponse(&event.Response{Details: msg})); err != nil { + return req, status.Errorf(codes.Internal, "unable to write response msg audit: %s", err) + } + } + + return resp, err + } +} diff --git a/internal/servers/controller/interceptor_test.go b/internal/servers/controller/interceptor_test.go index f970022c0..d1b0d5740 100644 --- a/internal/servers/controller/interceptor_test.go +++ b/internal/servers/controller/interceptor_test.go @@ -6,6 +6,7 @@ import ( "net/http" "net/http/httptest" "strconv" + "sync" "testing" "github.com/hashicorp/boundary/internal/authtoken" @@ -17,10 +18,12 @@ import ( "github.com/hashicorp/boundary/internal/gen/testing/interceptor" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/observability/event" "github.com/hashicorp/boundary/internal/servers" "github.com/hashicorp/boundary/internal/servers/controller/auth" "github.com/hashicorp/boundary/internal/servers/controller/common" "github.com/hashicorp/boundary/internal/servers/controller/handlers" + "github.com/hashicorp/go-hclog" "github.com/mr-tron/base58" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -59,8 +62,10 @@ func Test_requestCtxInterceptor(t *testing.T) { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokValue)) // Add values for authn/authz checking requestInfo := authpb.RequestInfo{ - Path: req.URL.Path, - Method: req.Method, + Path: req.URL.Path, + Method: req.Method, + EventId: "test-event-id", + TraceId: "test-trace-id", } requestInfo.PublicId, requestInfo.EncryptedToken, requestInfo.TokenFormat = auth.GetTokenFromRequest(context.TODO(), kmsCache, req) requestInfo.Ticket = gwTicket // allows the grpc-gateway to verify the request info came from it's in-memory companion http proxy @@ -82,6 +87,15 @@ func Test_requestCtxInterceptor(t *testing.T) { return ctx, nil } + c := event.TestEventerConfig(t, "Test_requestCtxInterceptor", event.TestWithAuditSink(t), event.TestWithObservationSink(t)) + testLock := &sync.Mutex{} + testLogger := hclog.New(&hclog.LoggerOptions{ + Mutex: testLock, + Name: "test", + }) + testEventer, err := event.NewEventer(testLogger, testLock, "Test_requestCtxInterceptor", c.EventerConfig) + require.NoError(t, err) + tests := []struct { name string requestCtx context.Context @@ -89,6 +103,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn common.AuthTokenRepoFactory serversRepoFn common.ServersRepoFactory kms *kms.Kms + eventer *event.Eventer ticket string wantFactoryErr bool wantFactoryErrMatch *errors.Template @@ -103,6 +118,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, wantFactoryErr: true, wantFactoryErrMatch: errors.T(errors.InvalidParameter), wantFactoryErrContains: "missing iam repo", @@ -113,6 +129,7 @@ func Test_requestCtxInterceptor(t *testing.T) { iamRepoFn: iamRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, wantFactoryErr: true, wantFactoryErrMatch: errors.T(errors.InvalidParameter), wantFactoryErrContains: "missing auth token repo", @@ -123,6 +140,7 @@ func Test_requestCtxInterceptor(t *testing.T) { iamRepoFn: iamRepoFn, authTokenRepoFn: atRepoFn, kms: kmsCache, + eventer: testEventer, wantFactoryErr: true, wantFactoryErrMatch: errors.T(errors.InvalidParameter), wantFactoryErrContains: "missing servers repo function", @@ -133,6 +151,17 @@ func Test_requestCtxInterceptor(t *testing.T) { iamRepoFn: iamRepoFn, authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, + eventer: testEventer, + wantFactoryErr: true, + wantFactoryErrMatch: errors.T(errors.InvalidParameter), + wantFactoryErrContains: "missing kms", + }, + { + name: "missing-eventer", + requestCtx: newReqCtx(validGatewayTicket), + iamRepoFn: iamRepoFn, + authTokenRepoFn: atRepoFn, + serversRepoFn: serversRepoFn, wantFactoryErr: true, wantFactoryErrMatch: errors.T(errors.InvalidParameter), wantFactoryErrContains: "missing kms", @@ -144,6 +173,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, wantFactoryErr: true, wantFactoryErrMatch: errors.T(errors.InvalidParameter), wantFactoryErrContains: "missing ticket", @@ -155,6 +185,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, ticket: validGatewayTicket, wantRequestErr: true, wantRequestErrMatch: errors.T(errors.Internal), @@ -170,6 +201,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, ticket: validGatewayTicket, wantRequestErr: true, wantRequestErrMatch: errors.T(errors.Internal), @@ -185,6 +217,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, ticket: validGatewayTicket, wantRequestErr: true, wantRequestErrMatch: errors.T(errors.Internal), @@ -200,6 +233,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, ticket: validGatewayTicket, wantRequestErr: true, wantRequestErrMatch: errors.T(errors.Internal), @@ -215,6 +249,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, ticket: validGatewayTicket, wantRequestErr: true, wantRequestErrMatch: errors.T(errors.Internal), @@ -230,6 +265,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, ticket: validGatewayTicket, wantRequestErr: true, wantRequestErrMatch: errors.T(errors.Internal), @@ -242,6 +278,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, ticket: "validGatewayTicket", wantRequestErr: true, wantRequestErrMatch: errors.T(errors.Internal), @@ -254,6 +291,7 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, ticket: "validGatewayTicket", wantRequestErr: true, wantRequestErrMatch: errors.T(errors.Internal), @@ -266,13 +304,14 @@ func Test_requestCtxInterceptor(t *testing.T) { authTokenRepoFn: atRepoFn, serversRepoFn: serversRepoFn, kms: kmsCache, + eventer: testEventer, ticket: validGatewayTicket, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { assert, require := assert.New(t), require.New(t) - interceptor, err := requestCtxInterceptor(factoryCtx, tt.iamRepoFn, tt.authTokenRepoFn, tt.serversRepoFn, tt.kms, tt.ticket) + interceptor, err := requestCtxInterceptor(factoryCtx, tt.iamRepoFn, tt.authTokenRepoFn, tt.serversRepoFn, tt.kms, tt.ticket, tt.eventer) if tt.wantFactoryErr { require.Error(err) assert.Nil(interceptor) diff --git a/internal/servers/controller/listeners.go b/internal/servers/controller/listeners.go index ad62e2822..d5c175ff4 100644 --- a/internal/servers/controller/listeners.go +++ b/internal/servers/controller/listeners.go @@ -26,7 +26,7 @@ func (c *Controller) startListeners(ctx context.Context) error { configureForAPI := func(ln *base.ServerListener) error { var err error - if c.gatewayServer, c.gatewayTicket, err = newGatewayServer(ctx, c.IamRepoFn, c.AuthTokenRepoFn, c.ServersRepoFn, c.kms); err != nil { + if c.gatewayServer, c.gatewayTicket, err = newGatewayServer(ctx, c.IamRepoFn, c.AuthTokenRepoFn, c.ServersRepoFn, c.kms, c.conf.Eventer); err != nil { return err } c.gatewayMux = newGatewayMux()