From d8544a363245967631265cfff846ad9c7c82a071 Mon Sep 17 00:00:00 2001 From: Mark Phelps <209477+markphelps@users.noreply.github.com> Date: Fri, 6 Sep 2024 20:56:37 -0400 Subject: [PATCH 1/6] fix: disable authz for all evaluation endpoints Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com> --- build/testing/integration.go | 56 ++++++++++++++--------- build/testing/integration/authz/auth.go | 38 +++++++++------ internal/server/evaluation/data/server.go | 4 ++ internal/server/evaluation/server_test.go | 5 ++ internal/server/metadata/server_test.go | 13 ++++++ internal/server/ofrep/server.go | 4 ++ internal/server/ofrep/server_test.go | 13 ++++++ 7 files changed, 98 insertions(+), 35 deletions(-) create mode 100644 internal/server/metadata/server_test.go create mode 100644 internal/server/ofrep/server_test.go diff --git a/build/testing/integration.go b/build/testing/integration.go index afbe5572d7..46b06e1eb4 100644 --- a/build/testing/integration.go +++ b/build/testing/integration.go @@ -58,8 +58,8 @@ var ( "api/cockroach": withCockroach(api), "api/cache": cache, "api/cachetls": cacheWithTLS, - "api/snapshot": snapshot, - "api/ofrep": ofrep, + "api/snapshot": withAuthz(snapshot), + "api/ofrep": withAuthz(ofrep), "fs/git": git, "fs/local": local, "fs/s3": s3, @@ -68,7 +68,7 @@ var ( "fs/gcs": gcs, "import/export": importExport, "authn": authn, - "authz": authz, + "authz": withAuthz(authz), "audit/webhook": withWebhook(api), "audit/webhooktmpl": withWebhookTemplates(api), } @@ -672,17 +672,32 @@ func authn(ctx context.Context, _ *dagger.Client, base, flipt *dagger.Container, } func authz(ctx context.Context, _ *dagger.Client, base, flipt *dagger.Container, conf testConfig) func() error { - var ( - policyPath = "/etc/flipt/authz/policy.rego" - policyData = "/etc/flipt/authz/data.json" - ) // create unique instance for test case fliptToTest := flipt. - WithEnvVariable("FLIPT_AUTHORIZATION_REQUIRED", "true"). - WithEnvVariable("FLIPT_AUTHORIZATION_BACKEND", "local"). - WithEnvVariable("FLIPT_AUTHORIZATION_LOCAL_POLICY_PATH", policyPath). - WithNewFile(policyPath, `package flipt.authz.v1 + WithEnvVariable("UNIQUE", uuid.New().String()). + WithExec(nil) + + // import state into instance before running test + if err := importInto(ctx, base, flipt, fliptToTest, "--address", conf.address, "--token", bootstrapToken); err != nil { + return func() error { return err } + } + + return suite(ctx, "authz", base, fliptToTest, conf) +} + +func withAuthz(fn testCaseFn) testCaseFn { + return func(ctx context.Context, client *dagger.Client, base, flipt *dagger.Container, conf testConfig) func() error { + var ( + policyPath = "/etc/flipt/authz/policy.rego" + policyData = "/etc/flipt/authz/data.json" + ) + + return fn(ctx, client, base, flipt. + WithEnvVariable("FLIPT_AUTHORIZATION_REQUIRED", "true"). + WithEnvVariable("FLIPT_AUTHORIZATION_BACKEND", "local"). + WithEnvVariable("FLIPT_AUTHORIZATION_LOCAL_POLICY_PATH", policyPath). + WithNewFile(policyPath, `package flipt.authz.v1 import data import rego.v1 @@ -736,8 +751,8 @@ permit_slice(allowed, _) if { permit_slice(allowed, requested) if { allowed[_] = requested }`). - WithEnvVariable("FLIPT_AUTHORIZATION_LOCAL_DATA_PATH", policyData). - WithNewFile(policyData, `{ + WithEnvVariable("FLIPT_AUTHORIZATION_LOCAL_DATA_PATH", policyData). + WithNewFile(policyData, `{ "version": "0.1.0", "roles": [ { @@ -823,17 +838,14 @@ permit_slice(allowed, requested) if { } ] }`). - WithEnvVariable("UNIQUE", uuid.New().String()). - WithExec(nil) - - // import state into instance before running test - if err := importInto(ctx, base, flipt, fliptToTest, "--address", conf.address, "--token", bootstrapToken); err != nil { - return func() error { return err } + WithEnvVariable("FLIPT_AUTHORIZATION_REQUIRED", "true"). + WithEnvVariable("FLIPT_AUTHORIZATION_BACKEND", "local"). + WithEnvVariable("FLIPT_AUTHORIZATION_LOCAL_POLICY_PATH", "/etc/flipt/authz/policy.rego"). + WithEnvVariable("FLIPT_AUTHORIZATION_LOCAL_DATA_PATH", "/etc/flipt/authz/data.json"), + conf, + ) } - - return suite(ctx, "authz", base, fliptToTest, conf) } - func withWebhook(fn testCaseFn) testCaseFn { return func(ctx context.Context, client *dagger.Client, base, flipt *dagger.Container, conf testConfig) func() error { owntracks := client.Container().From("frxyt/gohrec").WithExposedPort(8080).AsService() diff --git a/build/testing/integration/authz/auth.go b/build/testing/integration/authz/auth.go index f9f6d14b73..95076ae542 100644 --- a/build/testing/integration/authz/auth.go +++ b/build/testing/integration/authz/auth.go @@ -11,6 +11,7 @@ import ( "go.flipt.io/build/testing/integration" "go.flipt.io/flipt/rpc/flipt" "go.flipt.io/flipt/rpc/flipt/auth" + "go.flipt.io/flipt/rpc/flipt/evaluation" sdk "go.flipt.io/flipt/sdk/go" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -19,6 +20,30 @@ import ( func Common(t *testing.T, opts integration.TestOpts) { client := opts.TokenClient(t) + t.Run("Evaluation", func(t *testing.T) { + ctx := context.Background() + + t.Run("Boolean", func(t *testing.T) { + _, err := client.Evaluation().Boolean(ctx, &evaluation.EvaluationRequest{ + FlagKey: "flag_boolean", + Context: map[string]string{ + "in_segment": "segment_001", + }, + }) + require.NoError(t, err) + }) + + t.Run("Variant", func(t *testing.T) { + _, err := client.Evaluation().Variant(ctx, &evaluation.EvaluationRequest{ + FlagKey: "flag_001", + Context: map[string]string{ + "in_segment": "segment_001", + }, + }) + require.NoError(t, err) + }) + }) + t.Run("Authentication Methods", func(t *testing.T) { ctx := context.Background() @@ -124,19 +149,6 @@ func Common(t *testing.T, opts integration.TestOpts) { }) } -func listFlagIsAllowed(t *testing.T, ctx context.Context, client sdk.SDK, namespace string) { - t.Helper() - - t.Run(fmt.Sprintf("ListFlags(namespace: %q)", namespace), func(t *testing.T) { - // construct a new client using the previously obtained client token - resp, err := client.Flipt().ListFlags(ctx, &flipt.ListFlagRequest{ - NamespaceKey: namespace, - }) - require.NoError(t, err) - require.NotEmpty(t, resp.Flags) - }) -} - func canReadAllIn(t *testing.T, ctx context.Context, client sdk.SDK, namespace string) { t.Run("CanReadAll", func(t *testing.T) { clientCallSet{ diff --git a/internal/server/evaluation/data/server.go b/internal/server/evaluation/data/server.go index 481bc7cc6d..eaf0583d52 100644 --- a/internal/server/evaluation/data/server.go +++ b/internal/server/evaluation/data/server.go @@ -360,3 +360,7 @@ func (srv *Server) EvaluationSnapshotNamespace(ctx context.Context, r *evaluatio return resp, nil } + +func (srv *Server) SkipsAuthorization(ctx context.Context) bool { + return true +} diff --git a/internal/server/evaluation/server_test.go b/internal/server/evaluation/server_test.go index afb1b04770..b576462f1a 100644 --- a/internal/server/evaluation/server_test.go +++ b/internal/server/evaluation/server_test.go @@ -11,3 +11,8 @@ func Test_Server_AllowsNamespaceScopedAuthentication(t *testing.T) { server := &Server{} assert.True(t, server.AllowsNamespaceScopedAuthentication(context.Background())) } + +func Test_Server_SkipsAuthorization(t *testing.T) { + server := &Server{} + assert.True(t, server.SkipsAuthorization(context.Background())) +} diff --git a/internal/server/metadata/server_test.go b/internal/server/metadata/server_test.go new file mode 100644 index 0000000000..728587a59e --- /dev/null +++ b/internal/server/metadata/server_test.go @@ -0,0 +1,13 @@ +package metadata + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_Server_SkipsAuthorization(t *testing.T) { + server := &Server{} + assert.True(t, server.SkipsAuthorization(context.Background())) +} diff --git a/internal/server/ofrep/server.go b/internal/server/ofrep/server.go index c089b60f13..334764a907 100644 --- a/internal/server/ofrep/server.go +++ b/internal/server/ofrep/server.go @@ -56,3 +56,7 @@ func New(logger *zap.Logger, cacheCfg config.CacheConfig, bridge Bridge) *Server func (s *Server) RegisterGRPC(server *grpc.Server) { ofrep.RegisterOFREPServiceServer(server, s) } + +func (s *Server) SkipsAuthorization(ctx context.Context) bool { + return true +} diff --git a/internal/server/ofrep/server_test.go b/internal/server/ofrep/server_test.go new file mode 100644 index 0000000000..217c8ad5fe --- /dev/null +++ b/internal/server/ofrep/server_test.go @@ -0,0 +1,13 @@ +package ofrep + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_Server_SkipsAuthorization(t *testing.T) { + server := &Server{} + assert.True(t, server.SkipsAuthorization(context.Background())) +} \ No newline at end of file From 98a932aac21911d41cfdd30abd0e10c16c4ffc0c Mon Sep 17 00:00:00 2001 From: Mark Phelps <209477+markphelps@users.noreply.github.com> Date: Fri, 6 Sep 2024 21:08:07 -0400 Subject: [PATCH 2/6] chore: refactor authz test a bit Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com> --- build/testing/integration.go | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/build/testing/integration.go b/build/testing/integration.go index 46b06e1eb4..2b2f3ed4bf 100644 --- a/build/testing/integration.go +++ b/build/testing/integration.go @@ -68,7 +68,7 @@ var ( "fs/gcs": gcs, "import/export": importExport, "authn": authn, - "authz": withAuthz(authz), + "authz": authz, "audit/webhook": withWebhook(api), "audit/webhooktmpl": withWebhookTemplates(api), } @@ -671,19 +671,21 @@ func authn(ctx context.Context, _ *dagger.Client, base, flipt *dagger.Container, return suite(ctx, "authn", base, fliptToTest, conf) } -func authz(ctx context.Context, _ *dagger.Client, base, flipt *dagger.Container, conf testConfig) func() error { +func authz(ctx context.Context, client *dagger.Client, base, flipt *dagger.Container, conf testConfig) func() error { + return withAuthz(func(ctx context.Context, client *dagger.Client, base, flipt *dagger.Container, conf testConfig) func() error { - // create unique instance for test case - fliptToTest := flipt. - WithEnvVariable("UNIQUE", uuid.New().String()). - WithExec(nil) + // create unique instance for test case + fliptToTest := flipt. + WithEnvVariable("UNIQUE", uuid.New().String()). + WithExec(nil) - // import state into instance before running test - if err := importInto(ctx, base, flipt, fliptToTest, "--address", conf.address, "--token", bootstrapToken); err != nil { - return func() error { return err } - } + // import state into instance before running test + if err := importInto(ctx, base, flipt, fliptToTest, "--address", conf.address, "--token", bootstrapToken); err != nil { + return func() error { return err } + } - return suite(ctx, "authz", base, fliptToTest, conf) + return suite(ctx, "authz", base, fliptToTest, conf) + })(ctx, client, base, flipt, conf) } func withAuthz(fn testCaseFn) testCaseFn { @@ -837,11 +839,7 @@ permit_slice(allowed, requested) if { ] } ] -}`). - WithEnvVariable("FLIPT_AUTHORIZATION_REQUIRED", "true"). - WithEnvVariable("FLIPT_AUTHORIZATION_BACKEND", "local"). - WithEnvVariable("FLIPT_AUTHORIZATION_LOCAL_POLICY_PATH", "/etc/flipt/authz/policy.rego"). - WithEnvVariable("FLIPT_AUTHORIZATION_LOCAL_DATA_PATH", "/etc/flipt/authz/data.json"), +}`), conf, ) } From 138218ab9dd908e399e8879175864b79029267b2 Mon Sep 17 00:00:00 2001 From: Mark Phelps <209477+markphelps@users.noreply.github.com> Date: Fri, 6 Sep 2024 21:30:09 -0400 Subject: [PATCH 3/6] chore: add missing test Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com> --- internal/server/evaluation/data/server_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/server/evaluation/data/server_test.go b/internal/server/evaluation/data/server_test.go index 86c04b7c54..ce39cbb3b3 100644 --- a/internal/server/evaluation/data/server_test.go +++ b/internal/server/evaluation/data/server_test.go @@ -34,3 +34,8 @@ func TestEvaluationSnapshotNamespace(t *testing.T) { store.AssertExpectations(t) }) } + +func Test_Server_SkipsAuthorization(t *testing.T) { + server := &Server{} + assert.True(t, server.SkipsAuthorization(context.Background())) +} From d3cfc18bf6aa22f44429d9c5e5514ac0180a0f59 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 7 Sep 2024 17:35:35 +0100 Subject: [PATCH 4/6] fix(rpc/flipt): implement Requester for evaluation data snapshot (#3439) --- .../authz/middleware/grpc/middleware.go | 30 ++-- internal/server/evaluation/data/server.go | 4 - .../server/evaluation/data/server_test.go | 5 - internal/server/middleware/grpc/middleware.go | 99 ++++++------ rpc/flipt/auth/request.go | 16 +- rpc/flipt/evaluation/request.go | 10 ++ rpc/flipt/request.go | 146 +++++++++--------- 7 files changed, 156 insertions(+), 154 deletions(-) create mode 100644 rpc/flipt/evaluation/request.go diff --git a/internal/server/authz/middleware/grpc/middleware.go b/internal/server/authz/middleware/grpc/middleware.go index 7a2f0d7db5..54c5e091d2 100644 --- a/internal/server/authz/middleware/grpc/middleware.go +++ b/internal/server/authz/middleware/grpc/middleware.go @@ -90,21 +90,21 @@ func AuthorizationRequiredInterceptor(logger *zap.Logger, policyVerifier authz.V return ctx, errUnauthorized } - request := requester.Request() - - allowed, err := policyVerifier.IsAllowed(ctx, map[string]interface{}{ - "request": request, - "authentication": auth, - }) - - if err != nil { - logger.Error("unauthorized", zap.Error(err)) - return ctx, errUnauthorized - } - - if !allowed { - logger.Error("unauthorized", zap.String("reason", "permission denied")) - return ctx, errUnauthorized + for _, request := range requester.Request() { + allowed, err := policyVerifier.IsAllowed(ctx, map[string]interface{}{ + "request": request, + "authentication": auth, + }) + + if err != nil { + logger.Error("unauthorized", zap.Error(err)) + return ctx, errUnauthorized + } + + if !allowed { + logger.Error("unauthorized", zap.String("reason", "permission denied")) + return ctx, errUnauthorized + } } return handler(ctx, req) diff --git a/internal/server/evaluation/data/server.go b/internal/server/evaluation/data/server.go index eaf0583d52..481bc7cc6d 100644 --- a/internal/server/evaluation/data/server.go +++ b/internal/server/evaluation/data/server.go @@ -360,7 +360,3 @@ func (srv *Server) EvaluationSnapshotNamespace(ctx context.Context, r *evaluatio return resp, nil } - -func (srv *Server) SkipsAuthorization(ctx context.Context) bool { - return true -} diff --git a/internal/server/evaluation/data/server_test.go b/internal/server/evaluation/data/server_test.go index ce39cbb3b3..86c04b7c54 100644 --- a/internal/server/evaluation/data/server_test.go +++ b/internal/server/evaluation/data/server_test.go @@ -34,8 +34,3 @@ func TestEvaluationSnapshotNamespace(t *testing.T) { store.AssertExpectations(t) }) } - -func Test_Server_SkipsAuthorization(t *testing.T) { - server := &Server{} - assert.True(t, server.SkipsAuthorization(context.Background())) -} diff --git a/internal/server/middleware/grpc/middleware.go b/internal/server/middleware/grpc/middleware.go index e21e2eea5e..6b2fb192e7 100644 --- a/internal/server/middleware/grpc/middleware.go +++ b/internal/server/middleware/grpc/middleware.go @@ -239,77 +239,78 @@ func EvaluationUnaryInterceptor(analyticsEnabled bool) grpc.UnaryServerIntercept // AuditEventUnaryInterceptor captures events and adds them to the trace span to be consumed downstream. func AuditEventUnaryInterceptor(logger *zap.Logger, eventPairChecker audit.EventPairChecker) grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - var request flipt.Request + var requests []flipt.Request r, ok := req.(flipt.Requester) if !ok { return handler(ctx, req) } - request = r.Request() + requests = r.Request() - var event *audit.Event + var events []*audit.Event actor := authn.ActorFromContext(ctx) defer func() { - if event != nil { - eventPair := fmt.Sprintf("%s:%s", event.Type, event.Action) - - exists := eventPairChecker.Check(eventPair) - if exists { - span := trace.SpanFromContext(ctx) - span.AddEvent("event", trace.WithAttributes(event.DecodeToAttributes()...)) + if events != nil { + for _, event := range events { + eventPair := fmt.Sprintf("%s:%s", event.Type, event.Action) + + exists := eventPairChecker.Check(eventPair) + if exists { + span := trace.SpanFromContext(ctx) + span.AddEvent("event", trace.WithAttributes(event.DecodeToAttributes()...)) + } } } }() resp, err := handler(ctx, req) - if err != nil { - var uerr errs.ErrUnauthorized - if errors.As(err, &uerr) { - request.Status = flipt.StatusDenied - event = audit.NewEvent(request, actor, nil) + for _, request := range requests { + if err != nil { + var uerr errs.ErrUnauthorized + if errors.As(err, &uerr) { + request.Status = flipt.StatusDenied + events = append(events, audit.NewEvent(request, actor, nil)) + } + + continue + } + + // Delete and Order request(s) have to be handled separately because they do not + // return the concrete type but rather an *empty.Empty response. + if request.Action == flipt.ActionDelete { + events = append(events, audit.NewEvent(request, actor, r)) + continue } - return resp, err - } - // Delete and Order request(s) have to be handled separately because they do not - // return the concrete type but rather an *empty.Empty response. - if request.Action == flipt.ActionDelete { - event = audit.NewEvent(request, actor, r) - } else { switch r := req.(type) { case *flipt.OrderRulesRequest, *flipt.OrderRolloutsRequest: - event = audit.NewEvent(request, actor, r) + events = append(events, audit.NewEvent(request, actor, r)) + continue } - } - // Short circuiting the middleware here since we have a non-nil event from - // detecting a delete. - if event != nil { - return resp, err - } - - switch r := resp.(type) { - case *flipt.Flag: - event = audit.NewEvent(request, actor, audit.NewFlag(r)) - case *flipt.Variant: - event = audit.NewEvent(request, actor, audit.NewVariant(r)) - case *flipt.Segment: - event = audit.NewEvent(request, actor, audit.NewSegment(r)) - case *flipt.Distribution: - event = audit.NewEvent(request, actor, audit.NewDistribution(r)) - case *flipt.Constraint: - event = audit.NewEvent(request, actor, audit.NewConstraint(r)) - case *flipt.Namespace: - event = audit.NewEvent(request, actor, audit.NewNamespace(r)) - case *flipt.Rollout: - event = audit.NewEvent(request, actor, audit.NewRollout(r)) - case *flipt.Rule: - event = audit.NewEvent(request, actor, audit.NewRule(r)) - case *auth.CreateTokenResponse: - event = audit.NewEvent(request, actor, r.Authentication.Metadata) + switch r := resp.(type) { + case *flipt.Flag: + events = append(events, audit.NewEvent(request, actor, audit.NewFlag(r))) + case *flipt.Variant: + events = append(events, audit.NewEvent(request, actor, audit.NewVariant(r))) + case *flipt.Segment: + events = append(events, audit.NewEvent(request, actor, audit.NewSegment(r))) + case *flipt.Distribution: + events = append(events, audit.NewEvent(request, actor, audit.NewDistribution(r))) + case *flipt.Constraint: + events = append(events, audit.NewEvent(request, actor, audit.NewConstraint(r))) + case *flipt.Namespace: + events = append(events, audit.NewEvent(request, actor, audit.NewNamespace(r))) + case *flipt.Rollout: + events = append(events, audit.NewEvent(request, actor, audit.NewRollout(r))) + case *flipt.Rule: + events = append(events, audit.NewEvent(request, actor, audit.NewRule(r))) + case *auth.CreateTokenResponse: + events = append(events, audit.NewEvent(request, actor, r.Authentication.Metadata)) + } } return resp, err diff --git a/rpc/flipt/auth/request.go b/rpc/flipt/auth/request.go index 682cef798a..7fa648ea63 100644 --- a/rpc/flipt/auth/request.go +++ b/rpc/flipt/auth/request.go @@ -4,18 +4,18 @@ import ( "go.flipt.io/flipt/rpc/flipt" ) -func (req *CreateTokenRequest) Request() flipt.Request { - return flipt.NewRequest(flipt.ResourceAuthentication, flipt.ActionCreate, flipt.WithSubject(flipt.SubjectToken)) +func (req *CreateTokenRequest) Request() []flipt.Request { + return []flipt.Request{flipt.NewRequest(flipt.ResourceAuthentication, flipt.ActionCreate, flipt.WithSubject(flipt.SubjectToken))} } -func (req *ListAuthenticationsRequest) Request() flipt.Request { - return flipt.NewRequest(flipt.ResourceAuthentication, flipt.ActionRead) +func (req *ListAuthenticationsRequest) Request() []flipt.Request { + return []flipt.Request{flipt.NewRequest(flipt.ResourceAuthentication, flipt.ActionRead)} } -func (req *GetAuthenticationRequest) Request() flipt.Request { - return flipt.NewRequest(flipt.ResourceAuthentication, flipt.ActionRead) +func (req *GetAuthenticationRequest) Request() []flipt.Request { + return []flipt.Request{flipt.NewRequest(flipt.ResourceAuthentication, flipt.ActionRead)} } -func (req *DeleteAuthenticationRequest) Request() flipt.Request { - return flipt.NewRequest(flipt.ResourceAuthentication, flipt.ActionDelete) +func (req *DeleteAuthenticationRequest) Request() []flipt.Request { + return []flipt.Request{flipt.NewRequest(flipt.ResourceAuthentication, flipt.ActionDelete)} } diff --git a/rpc/flipt/evaluation/request.go b/rpc/flipt/evaluation/request.go new file mode 100644 index 0000000000..269914df34 --- /dev/null +++ b/rpc/flipt/evaluation/request.go @@ -0,0 +1,10 @@ +package evaluation + +import "go.flipt.io/flipt/rpc/flipt" + +func (r *EvaluationNamespaceSnapshotRequest) Request() []flipt.Request { + return []flipt.Request{ + flipt.NewRequest(flipt.ResourceFlag, flipt.ActionRead, flipt.WithNamespace(r.Key)), + flipt.NewRequest(flipt.ResourceSegment, flipt.ActionRead, flipt.WithNamespace(r.Key)), + } +} diff --git a/rpc/flipt/request.go b/rpc/flipt/request.go index 1a00da9af5..61e025d8b0 100644 --- a/rpc/flipt/request.go +++ b/rpc/flipt/request.go @@ -1,7 +1,7 @@ package flipt type Requester interface { - Request() Request + Request() []Request } // Resource represents what resource or parent resource is being acted on. @@ -93,153 +93,153 @@ func newSegmentScopedRequest(ns string, s Subject, a Action) Request { } // Namespaces -func (req *GetNamespaceRequest) Request() Request { - return NewRequest(ResourceNamespace, ActionRead, WithNamespace(req.Key)) +func (req *GetNamespaceRequest) Request() []Request { + return []Request{NewRequest(ResourceNamespace, ActionRead, WithNamespace(req.Key))} } -func (req *ListNamespaceRequest) Request() Request { - return NewRequest(ResourceNamespace, ActionRead) +func (req *ListNamespaceRequest) Request() []Request { + return []Request{NewRequest(ResourceNamespace, ActionRead)} } -func (req *CreateNamespaceRequest) Request() Request { - return NewRequest(ResourceNamespace, ActionCreate, WithNamespace(req.Key)) +func (req *CreateNamespaceRequest) Request() []Request { + return []Request{NewRequest(ResourceNamespace, ActionCreate, WithNamespace(req.Key))} } -func (req *UpdateNamespaceRequest) Request() Request { - return NewRequest(ResourceNamespace, ActionUpdate, WithNamespace(req.Key)) +func (req *UpdateNamespaceRequest) Request() []Request { + return []Request{NewRequest(ResourceNamespace, ActionUpdate, WithNamespace(req.Key))} } -func (req *DeleteNamespaceRequest) Request() Request { - return NewRequest(ResourceNamespace, ActionDelete, WithNamespace(req.Key)) +func (req *DeleteNamespaceRequest) Request() []Request { + return []Request{NewRequest(ResourceNamespace, ActionDelete, WithNamespace(req.Key))} } // Flags -func (req *GetFlagRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionRead) +func (req *GetFlagRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionRead)} } -func (req *ListFlagRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionRead) +func (req *ListFlagRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionRead)} } -func (req *CreateFlagRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionCreate) +func (req *CreateFlagRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionCreate)} } -func (req *UpdateFlagRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionUpdate) +func (req *UpdateFlagRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionUpdate)} } -func (req *DeleteFlagRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionDelete) +func (req *DeleteFlagRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectFlag, ActionDelete)} } // Variants -func (req *CreateVariantRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectVariant, ActionCreate) +func (req *CreateVariantRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectVariant, ActionCreate)} } -func (req *UpdateVariantRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectVariant, ActionUpdate) +func (req *UpdateVariantRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectVariant, ActionUpdate)} } -func (req *DeleteVariantRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectVariant, ActionDelete) +func (req *DeleteVariantRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectVariant, ActionDelete)} } // Rules -func (req *ListRuleRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionRead) +func (req *ListRuleRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionRead)} } -func (req *GetRuleRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionRead) +func (req *GetRuleRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionRead)} } -func (req *CreateRuleRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionCreate) +func (req *CreateRuleRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionCreate)} } -func (req *UpdateRuleRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionUpdate) +func (req *UpdateRuleRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionUpdate)} } -func (req *OrderRulesRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionUpdate) +func (req *OrderRulesRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionUpdate)} } -func (req *DeleteRuleRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionDelete) +func (req *DeleteRuleRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRule, ActionDelete)} } // Rollouts -func (req *ListRolloutRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionRead) +func (req *ListRolloutRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionRead)} } -func (req *GetRolloutRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionRead) +func (req *GetRolloutRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionRead)} } -func (req *CreateRolloutRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionCreate) +func (req *CreateRolloutRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionCreate)} } -func (req *UpdateRolloutRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionUpdate) +func (req *UpdateRolloutRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionUpdate)} } -func (req *OrderRolloutsRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionUpdate) +func (req *OrderRolloutsRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionUpdate)} } -func (req *DeleteRolloutRequest) Request() Request { - return newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionDelete) +func (req *DeleteRolloutRequest) Request() []Request { + return []Request{newFlagScopedRequest(req.NamespaceKey, SubjectRollout, ActionDelete)} } // Segments -func (req *GetSegmentRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionRead) +func (req *GetSegmentRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionRead)} } -func (req *ListSegmentRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionRead) +func (req *ListSegmentRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionRead)} } -func (req *CreateSegmentRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionCreate) +func (req *CreateSegmentRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionCreate)} } -func (req *UpdateSegmentRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionUpdate) +func (req *UpdateSegmentRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionUpdate)} } -func (req *DeleteSegmentRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionDelete) +func (req *DeleteSegmentRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectSegment, ActionDelete)} } // Constraints -func (req *CreateConstraintRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectConstraint, ActionCreate) +func (req *CreateConstraintRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectConstraint, ActionCreate)} } -func (req *UpdateConstraintRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectConstraint, ActionUpdate) +func (req *UpdateConstraintRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectConstraint, ActionUpdate)} } -func (req *DeleteConstraintRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectConstraint, ActionDelete) +func (req *DeleteConstraintRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectConstraint, ActionDelete)} } // Distributions -func (req *CreateDistributionRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectDistribution, ActionCreate) +func (req *CreateDistributionRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectDistribution, ActionCreate)} } -func (req *UpdateDistributionRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectDistribution, ActionUpdate) +func (req *UpdateDistributionRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectDistribution, ActionUpdate)} } -func (req *DeleteDistributionRequest) Request() Request { - return newSegmentScopedRequest(req.NamespaceKey, SubjectDistribution, ActionDelete) +func (req *DeleteDistributionRequest) Request() []Request { + return []Request{newSegmentScopedRequest(req.NamespaceKey, SubjectDistribution, ActionDelete)} } From a16b7e14388a9a0334199e8a86718d61b23596c0 Mon Sep 17 00:00:00 2001 From: Mark Phelps <209477+markphelps@users.noreply.github.com> Date: Sat, 7 Sep 2024 13:01:08 -0400 Subject: [PATCH 5/6] chore: fix lint error Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com> --- internal/server/middleware/grpc/middleware.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/internal/server/middleware/grpc/middleware.go b/internal/server/middleware/grpc/middleware.go index 6b2fb192e7..aa24ca7cea 100644 --- a/internal/server/middleware/grpc/middleware.go +++ b/internal/server/middleware/grpc/middleware.go @@ -253,15 +253,13 @@ func AuditEventUnaryInterceptor(logger *zap.Logger, eventPairChecker audit.Event actor := authn.ActorFromContext(ctx) defer func() { - if events != nil { - for _, event := range events { - eventPair := fmt.Sprintf("%s:%s", event.Type, event.Action) - - exists := eventPairChecker.Check(eventPair) - if exists { - span := trace.SpanFromContext(ctx) - span.AddEvent("event", trace.WithAttributes(event.DecodeToAttributes()...)) - } + for _, event := range events { + eventPair := fmt.Sprintf("%s:%s", event.Type, event.Action) + + exists := eventPairChecker.Check(eventPair) + if exists { + span := trace.SpanFromContext(ctx) + span.AddEvent("event", trace.WithAttributes(event.DecodeToAttributes()...)) } } }() From 625b6910078a3eaf24cc0a8713f644adc7f61536 Mon Sep 17 00:00:00 2001 From: Mark Phelps <209477+markphelps@users.noreply.github.com> Date: Sat, 7 Sep 2024 13:39:26 -0400 Subject: [PATCH 6/6] chore: try to fix snapshot IT Signed-off-by: Mark Phelps <209477+markphelps@users.noreply.github.com> --- build/testing/integration/snapshot/snapshot_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/testing/integration/snapshot/snapshot_test.go b/build/testing/integration/snapshot/snapshot_test.go index 506b0d4ef6..4b492e3283 100644 --- a/build/testing/integration/snapshot/snapshot_test.go +++ b/build/testing/integration/snapshot/snapshot_test.go @@ -15,7 +15,7 @@ import ( func TestSnapshot(t *testing.T) { integration.Harness(t, func(t *testing.T, opts integration.TestOpts) { var ( - httpClient = opts.HTTPClient(t) + httpClient = opts.HTTPClient(t, integration.WithRole("viewer")) // TODO: test other roles/namespace combinations protocol = opts.Protocol() )