From 12e120fd1ba5549469257e85c915da6c89531b4e Mon Sep 17 00:00:00 2001 From: Huseyin BABAL Date: Thu, 8 Jun 2023 18:42:07 +0300 Subject: [PATCH 1/3] grpc auth added --- pkg/bot/cloudslack.go | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/pkg/bot/cloudslack.go b/pkg/bot/cloudslack.go index 55fef230b..e794b62eb 100644 --- a/pkg/bot/cloudslack.go +++ b/pkg/bot/cloudslack.go @@ -15,6 +15,7 @@ import ( "github.com/slack-go/slack/slackevents" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/metadata" "github.com/kubeshop/botkube/internal/config/remote" "github.com/kubeshop/botkube/pkg/api" @@ -28,6 +29,11 @@ import ( "github.com/kubeshop/botkube/pkg/sliceutil" ) +const ( + APIKeyContextKey = "X-Api-Key" // #nosec + DeploymentIDContextKey = "X-Deployment-Id" // #nosec +) + var _ Bot = &CloudSlack{} // CloudSlack listens for user's message, execute commands and sends back the response. @@ -92,7 +98,7 @@ func NewCloudSlack(log logrus.FieldLogger, func (b *CloudSlack) Start(ctx context.Context) error { creds := grpc.WithTransportCredentials(insecure.NewCredentials()) - opts := []grpc.DialOption{creds} + opts := []grpc.DialOption{creds, grpc.WithStreamInterceptor(b.addCredentials())} conn, err := grpc.Dial(b.cfg.Server.URL, opts...) if err != nil { @@ -515,3 +521,25 @@ func (b *CloudSlack) getChannelsToNotify(sourceBindings []string) []string { } return out } + +func (b *CloudSlack) addCredentials() grpc.StreamClientInterceptor { + return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + remoteCfg, ok := remote.GetConfig() + if !ok { + return nil, errors.New("while getting remote configuration") + } + md := metadata.New(map[string]string{ + APIKeyContextKey: remoteCfg.APIKey, + DeploymentIDContextKey: remoteCfg.Identifier, + }) + + ctx = metadata.NewOutgoingContext(ctx, md) + + clientStream, err := streamer(ctx, desc, cc, method, opts...) + if err != nil { + return nil, err + } + + return clientStream, nil + } +} From 0e05f4e24c50533ff947a7fc7b91a1f826f53398 Mon Sep 17 00:00:00 2001 From: Huseyin BABAL Date: Tue, 13 Jun 2023 14:17:26 +0300 Subject: [PATCH 2/3] unary client interceptor added --- pkg/bot/cloudslack.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/pkg/bot/cloudslack.go b/pkg/bot/cloudslack.go index e794b62eb..8af9d7344 100644 --- a/pkg/bot/cloudslack.go +++ b/pkg/bot/cloudslack.go @@ -98,7 +98,10 @@ func NewCloudSlack(log logrus.FieldLogger, func (b *CloudSlack) Start(ctx context.Context) error { creds := grpc.WithTransportCredentials(insecure.NewCredentials()) - opts := []grpc.DialOption{creds, grpc.WithStreamInterceptor(b.addCredentials())} + opts := []grpc.DialOption{creds, + grpc.WithStreamInterceptor(b.addStreamingClientCredentials()), + grpc.WithUnaryInterceptor(b.addUnaryClientCredentials()), + } conn, err := grpc.Dial(b.cfg.Server.URL, opts...) if err != nil { @@ -522,7 +525,7 @@ func (b *CloudSlack) getChannelsToNotify(sourceBindings []string) []string { return out } -func (b *CloudSlack) addCredentials() grpc.StreamClientInterceptor { +func (b *CloudSlack) addStreamingClientCredentials() grpc.StreamClientInterceptor { return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { remoteCfg, ok := remote.GetConfig() if !ok { @@ -543,3 +546,19 @@ func (b *CloudSlack) addCredentials() grpc.StreamClientInterceptor { return clientStream, nil } } + +func (b *CloudSlack) addUnaryClientCredentials() grpc.UnaryClientInterceptor { + return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + remoteCfg, ok := remote.GetConfig() + if !ok { + return errors.New("while getting remote configuration") + } + md := metadata.New(map[string]string{ + APIKeyContextKey: remoteCfg.APIKey, + DeploymentIDContextKey: remoteCfg.Identifier, + }) + + ctx = metadata.NewOutgoingContext(ctx, md) + return invoker(ctx, method, req, reply, cc, opts...) + } +} From a536756ef0ad6d4ff12d03d0e8380f8fc51ab6df Mon Sep 17 00:00:00 2001 From: Huseyin BABAL Date: Tue, 13 Jun 2023 14:19:26 +0300 Subject: [PATCH 3/3] refactor error text --- pkg/bot/cloudslack.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/bot/cloudslack.go b/pkg/bot/cloudslack.go index 8af9d7344..e1cc5851c 100644 --- a/pkg/bot/cloudslack.go +++ b/pkg/bot/cloudslack.go @@ -529,7 +529,7 @@ func (b *CloudSlack) addStreamingClientCredentials() grpc.StreamClientIntercepto return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { remoteCfg, ok := remote.GetConfig() if !ok { - return nil, errors.New("while getting remote configuration") + return nil, errors.New("empty remote configuration") } md := metadata.New(map[string]string{ APIKeyContextKey: remoteCfg.APIKey, @@ -551,7 +551,7 @@ func (b *CloudSlack) addUnaryClientCredentials() grpc.UnaryClientInterceptor { return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { remoteCfg, ok := remote.GetConfig() if !ok { - return errors.New("while getting remote configuration") + return errors.New("empty remote configuration") } md := metadata.New(map[string]string{ APIKeyContextKey: remoteCfg.APIKey,