diff --git a/cmd/policy/main.go b/cmd/policy/main.go index 71dccc16b819b627a9f4aa572d957ee5ca1cfa69..f941473116eae58d78626bab031c280dd8e1846f 100644 --- a/cmd/policy/main.go +++ b/cmd/policy/main.go @@ -29,7 +29,7 @@ import ( goapolicy "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/gen/policy" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/clients/cache" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/config" - header "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/middleware" + "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/header" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/regocache" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/regofunc" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/service" diff --git a/internal/middleware/header.go b/internal/header/header.go similarity index 100% rename from internal/middleware/header.go rename to internal/header/header.go diff --git a/internal/header/header_test.go b/internal/header/header_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6f4e1ce3413aec9a59c16a4073552c858155694f --- /dev/null +++ b/internal/header/header_test.go @@ -0,0 +1,27 @@ +package header_test + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/header" +) + +func TestMiddleware(t *testing.T) { + expected := http.Header{"Authorization": []string{"my-token"}} + + req := httptest.NewRequest("POST", "/example", nil) + req.Header = expected + + nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + value, ok := header.FromContext(r.Context()) + assert.True(t, ok) + assert.Equal(t, expected, value) + }) + + middleware := header.Middleware() + handlerToTest := middleware(nextHandler) + handlerToTest.ServeHTTP(httptest.NewRecorder(), req) +} diff --git a/internal/service/policy/service.go b/internal/service/policy/service.go index afca866261880d6fdb52285dd197c6293f82a22e..e76c0b6aa8f993255eb1eace345d6ef640f7a413 100644 --- a/internal/service/policy/service.go +++ b/internal/service/policy/service.go @@ -12,7 +12,7 @@ import ( "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/errors" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/gen/policy" - header2 "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/middleware" + "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/header" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/regofunc" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/storage" ) @@ -84,7 +84,7 @@ func (s *Service) Evaluate(ctx context.Context, req *policy.EvaluateRequest) (*p } // add headers to the request input - input, err := s.addHeadersToEvaluateInput(ctx, req) + input, err := s.addHeadersToEvaluateInput(ctx, req.Input) if err != nil { logger.Error("error adding headers to evaluate input", zap.Error(err)) return nil, errors.New("error adding headers to evaluate input", err) @@ -278,19 +278,24 @@ func (s *Service) queryCacheKey(group, policyName, version string) string { return fmt.Sprintf("%s,%s,%s", group, policyName, version) } -func (s *Service) addHeadersToEvaluateInput(ctx context.Context, req *policy.EvaluateRequest) (map[string]interface{}, error) { - i, ok := req.Input.(*interface{}) +func (s *Service) addHeadersToEvaluateInput(ctx context.Context, in interface{}) (map[string]interface{}, error) { + // goa framework decodes the body of the request into a pointer to interface + // for this reason we cast it first to interface pointer and then to map, which is the expected value + i, ok := in.(*interface{}) if !ok { return nil, errors.New("unexpected request body: unsuccessful casting to interface") } i2 := *i + if i2 == nil { // no request body + i2 = map[string]interface{}{} + } input, ok := i2.(map[string]interface{}) if !ok { return nil, errors.New("unexpected request body: unsuccessful casting to map") } - header, ok := header2.FromContext(ctx) + header, ok := header.FromContext(ctx) if !ok { return nil, errors.New("error getting headers from context") } diff --git a/internal/service/policy/service_test.go b/internal/service/policy/service_test.go index 3c4fcba1415c4b3a2f212afaae89ad4452d06de6..e25f01615ace12067b7cf7cdbeef7acc481e1fda 100644 --- a/internal/service/policy/service_test.go +++ b/internal/service/policy/service_test.go @@ -14,7 +14,7 @@ import ( "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/errors" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/ptr" goapolicy "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/gen/policy" - header "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/middleware" + "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/header" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/service/policy" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/service/policy/policyfakes" "gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/policy/internal/storage" @@ -61,6 +61,19 @@ func TestService_Evaluate(t *testing.T) { } } + // prepare test request with empty body + testEmptyReq := func() *goapolicy.EvaluateRequest { + var body interface{} = nil + + return &goapolicy.EvaluateRequest{ + Group: "testgroup", + PolicyName: "example", + Version: "1.0", + Input: &body, + TTL: ptr.Int(30), + } + } + // prepare http.Request for tests httpReq := func() *http.Request { req := httptest.NewRequest("GET", "/", nil) @@ -337,6 +350,36 @@ func TestService_Evaluate(t *testing.T) { Result: map[string]interface{}{"token": []interface{}{"my-token"}}, }, }, + { + name: "policy with empty input is evaluated successfully", + ctx: ctxWithHeaders(), + req: testEmptyReq(), + regocache: &policyfakes.FakeRegoCache{ + GetStub: func(key string) (*rego.PreparedEvalQuery, bool) { + return nil, false + }, + }, + storage: &policyfakes.FakeStorage{ + PolicyStub: func(ctx context.Context, s string, s2 string, s3 string) (*storage.Policy, error) { + return &storage.Policy{ + Name: "example", + Group: "testgroup", + Version: "1.0", + Rego: testPolicy, + Locked: false, + LastUpdate: time.Now(), + }, nil + }, + }, + cache: &policyfakes.FakeCache{ + SetStub: func(ctx context.Context, s string, s2 string, s3 string, bytes []byte, i int) error { + return nil + }, + }, + res: &goapolicy.EvaluateResult{ + Result: map[string]interface{}{"allow": false}, + }, + }, } for _, test := range tests {