From 7800d8bc879bd807bd1cfb7b09702be236c1211d Mon Sep 17 00:00:00 2001 From: Emmanuel Gautier Date: Sat, 15 Apr 2023 11:50:23 +0200 Subject: [PATCH] feat: manage upstream --- cmd/generate/root.go | 7 +- contrib/quickstart/access-rules.json | 409 +++++++++++++++++---------- generator/generator.go | 16 +- generator/generator_test.go | 68 ++++- 4 files changed, 333 insertions(+), 167 deletions(-) diff --git a/cmd/generate/root.go b/cmd/generate/root.go index 4f954f7..8f06eee 100644 --- a/cmd/generate/root.go +++ b/cmd/generate/root.go @@ -22,6 +22,9 @@ var ( allowedIssuers map[string]string allowedAudiences map[string]string serverUrls []string + + upstreamUrl string + upstreamStripPath string ) func NewGenerateCmd() (generateCmd *cobra.Command) { @@ -51,7 +54,7 @@ func NewGenerateCmd() (generateCmd *cobra.Command) { panic(err) } - g := generator.NewGenerator(prefixId, jwksUris, allowedIssuers, allowedAudiences, serverUrls) + g := generator.NewGenerator(prefixId, jwksUris, allowedIssuers, allowedAudiences, serverUrls, upstreamUrl, upstreamStripPath) if loadErr := g.LoadOpenAPI3Doc(ctx, doc); loadErr != nil { panic(loadErr) } @@ -86,6 +89,8 @@ func NewGenerateCmd() (generateCmd *cobra.Command) { generateCmd.PersistentFlags().StringArrayVarP(&serverUrls, "server-url", "", nil, "API Server Urls") generateCmd.PersistentFlags().StringVarP(&fileurl, "url", "u", "", "OpenAPI URL") generateCmd.PersistentFlags().StringVarP(&filepath, "file", "f", "", "OpenAPI File Path") + generateCmd.PersistentFlags().StringVarP(&upstreamUrl, "upstream-url", "", "", "The Upstream URL the request will be forwarded to") + generateCmd.PersistentFlags().StringVarP(&upstreamStripPath, "upstream-strip-path", "", "", "Replaces the provided path prefix when forwarding the requested URL to the upstream URL") generateCmd.PersistentFlags().StringVarP(&outputpath, "output", "o", "", "Oathkeeper Rules output path") return generateCmd diff --git a/contrib/quickstart/access-rules.json b/contrib/quickstart/access-rules.json index 19ad69a..6f96468 100644 --- a/contrib/quickstart/access-rules.json +++ b/contrib/quickstart/access-rules.json @@ -1,18 +1,30 @@ [ { - "id": "logoutUser", + "id": "addPet", "version": "", - "description": "", + "description": "Add a new pet to the store", "match": { "methods": [ - "GET" + "POST" ], - "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/logout/?)$>" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/?)$>" }, "authenticators": [ { - "handler": "noop", - "config": null + "handler": "jwt", + "config": { + "jwks_urls": [ + "https://console.ory.sh/.well-known/jwks.json" + ], + "trusted_issuers": [ + "https://console.ory.sh/" + ], + "required_scope": [ + "write:pets", + "read:pets" + ], + "target_audience": [] + } } ], "authorizer": { @@ -25,7 +37,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -33,14 +50,14 @@ } }, { - "id": "findPetsByStatus", + "id": "updatePet", "version": "", - "description": "Multiple status values can be provided with comma separated strings", + "description": "Update an existing pet by Id", "match": { "methods": [ - "GET" + "PUT" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/findByStatus/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/?)$>" }, "authenticators": [ { @@ -55,7 +72,8 @@ "required_scope": [ "write:pets", "read:pets" - ] + ], + "target_audience": [] } } ], @@ -69,7 +87,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -77,14 +100,14 @@ } }, { - "id": "findPetsByTags", + "id": "findPetsByStatus", "version": "", - "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", + "description": "Multiple status values can be provided with comma separated strings", "match": { "methods": [ "GET" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/findByTags/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/findByStatus/?)$>" }, "authenticators": [ { @@ -99,7 +122,8 @@ "required_scope": [ "write:pets", "read:pets" - ] + ], + "target_audience": [] } } ], @@ -113,7 +137,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -121,19 +150,31 @@ } }, { - "id": "getInventory", + "id": "findPetsByTags", "version": "", - "description": "Returns a map of status codes to quantities", + "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", "match": { "methods": [ "GET" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/store/inventory/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/findByTags/?)$>" }, "authenticators": [ { - "handler": "noop", - "config": null + "handler": "jwt", + "config": { + "jwks_urls": [ + "https://console.ory.sh/.well-known/jwks.json" + ], + "trusted_issuers": [ + "https://console.ory.sh/" + ], + "required_scope": [ + "write:pets", + "read:pets" + ], + "target_audience": [] + } } ], "authorizer": { @@ -146,7 +187,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -154,19 +200,31 @@ } }, { - "id": "placeOrder", + "id": "deletePet", "version": "", - "description": "Place a new order in the store", + "description": "", "match": { "methods": [ - "POST" + "DELETE" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/store/order/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/(.+)/?)$>" }, "authenticators": [ { - "handler": "noop", - "config": null + "handler": "jwt", + "config": { + "jwks_urls": [ + "https://console.ory.sh/.well-known/jwks.json" + ], + "trusted_issuers": [ + "https://console.ory.sh/" + ], + "required_scope": [ + "write:pets", + "read:pets" + ], + "target_audience": [] + } } ], "authorizer": { @@ -179,7 +237,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -187,19 +250,31 @@ } }, { - "id": "deleteOrder", + "id": "getPetById", "version": "", - "description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", + "description": "Returns a single pet", "match": { "methods": [ - "DELETE" + "GET" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/store/order/(.+)/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/(.+)/?)$>" }, "authenticators": [ { - "handler": "noop", - "config": null + "handler": "jwt", + "config": { + "jwks_urls": [ + "https://console.ory.sh/.well-known/jwks.json" + ], + "trusted_issuers": [ + "https://console.ory.sh/" + ], + "required_scope": [ + "write:pets", + "read:pets" + ], + "target_audience": [] + } } ], "authorizer": { @@ -212,7 +287,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -220,19 +300,31 @@ } }, { - "id": "getOrderById", + "id": "updatePetWithForm", "version": "", - "description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions.", + "description": "", "match": { "methods": [ - "GET" + "POST" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/store/order/(.+)/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/(.+)/?)$>" }, "authenticators": [ { - "handler": "noop", - "config": null + "handler": "jwt", + "config": { + "jwks_urls": [ + "https://console.ory.sh/.well-known/jwks.json" + ], + "trusted_issuers": [ + "https://console.ory.sh/" + ], + "required_scope": [ + "write:pets", + "read:pets" + ], + "target_audience": [] + } } ], "authorizer": { @@ -245,7 +337,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -253,14 +350,14 @@ } }, { - "id": "createUsersWithListInput", + "id": "placeOrder", "version": "", - "description": "Creates list of users with given input array", + "description": "Place a new order in the store", "match": { "methods": [ "POST" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/createWithList/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/store/order/?)$>" }, "authenticators": [ { @@ -278,7 +375,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -293,7 +395,7 @@ "methods": [ "GET" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/login/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/login/?)$>" }, "authenticators": [ { @@ -311,7 +413,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -326,7 +433,7 @@ "methods": [ "DELETE" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/(.+)/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/(.+)/?)$>" }, "authenticators": [ { @@ -344,7 +451,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -359,7 +471,7 @@ "methods": [ "GET" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/(.+)/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/(.+)/?)$>" }, "authenticators": [ { @@ -377,7 +489,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -392,7 +509,7 @@ "methods": [ "PUT" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/(.+)/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/(.+)/?)$>" }, "authenticators": [ { @@ -410,7 +527,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -418,14 +540,14 @@ } }, { - "id": "addPet", + "id": "uploadFile", "version": "", - "description": "Add a new pet to the store", + "description": "", "match": { "methods": [ "POST" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/(.+)/uploadImage/?)$>" }, "authenticators": [ { @@ -440,7 +562,8 @@ "required_scope": [ "write:pets", "read:pets" - ] + ], + "target_audience": [] } } ], @@ -454,7 +577,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -462,30 +590,19 @@ } }, { - "id": "updatePet", + "id": "getInventory", "version": "", - "description": "Update an existing pet by Id", + "description": "Returns a map of status codes to quantities", "match": { "methods": [ - "PUT" + "GET" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/store/inventory/?)$>" }, "authenticators": [ { - "handler": "jwt", - "config": { - "jwks_urls": [ - "https://console.ory.sh/.well-known/jwks.json" - ], - "trusted_issuers": [ - "https://console.ory.sh/" - ], - "required_scope": [ - "write:pets", - "read:pets" - ] - } + "handler": "noop", + "config": null } ], "authorizer": { @@ -498,7 +615,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -506,30 +628,19 @@ } }, { - "id": "deletePet", + "id": "deleteOrder", "version": "", - "description": "", + "description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", "match": { "methods": [ "DELETE" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/(.+)/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/store/order/(.+)/?)$>" }, "authenticators": [ { - "handler": "jwt", - "config": { - "jwks_urls": [ - "https://console.ory.sh/.well-known/jwks.json" - ], - "trusted_issuers": [ - "https://console.ory.sh/" - ], - "required_scope": [ - "write:pets", - "read:pets" - ] - } + "handler": "noop", + "config": null } ], "authorizer": { @@ -542,7 +653,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -550,30 +666,19 @@ } }, { - "id": "getPetById", + "id": "getOrderById", "version": "", - "description": "Returns a single pet", + "description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions.", "match": { "methods": [ "GET" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/(.+)/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/store/order/(.+)/?)$>" }, "authenticators": [ { - "handler": "jwt", - "config": { - "jwks_urls": [ - "https://console.ory.sh/.well-known/jwks.json" - ], - "trusted_issuers": [ - "https://console.ory.sh/" - ], - "required_scope": [ - "write:pets", - "read:pets" - ] - } + "handler": "noop", + "config": null } ], "authorizer": { @@ -586,7 +691,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -594,30 +704,19 @@ } }, { - "id": "updatePetWithForm", + "id": "createUser", "version": "", - "description": "", + "description": "This can only be done by the logged in user.", "match": { "methods": [ "POST" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/(.+)/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/?)$>" }, "authenticators": [ { - "handler": "jwt", - "config": { - "jwks_urls": [ - "https://console.ory.sh/.well-known/jwks.json" - ], - "trusted_issuers": [ - "https://console.ory.sh/" - ], - "required_scope": [ - "write:pets", - "read:pets" - ] - } + "handler": "noop", + "config": null } ], "authorizer": { @@ -630,7 +729,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -638,30 +742,19 @@ } }, { - "id": "uploadFile", + "id": "createUsersWithListInput", "version": "", - "description": "", + "description": "Creates list of users with given input array", "match": { "methods": [ "POST" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/pet/(.+)/uploadImage/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/createWithList/?)$>" }, "authenticators": [ { - "handler": "jwt", - "config": { - "jwks_urls": [ - "https://console.ory.sh/.well-known/jwks.json" - ], - "trusted_issuers": [ - "https://console.ory.sh/" - ], - "required_scope": [ - "write:pets", - "read:pets" - ] - } + "handler": "noop", + "config": null } ], "authorizer": { @@ -674,7 +767,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", @@ -682,14 +780,14 @@ } }, { - "id": "createUser", + "id": "logoutUser", "version": "", - "description": "This can only be done by the logged in user.", + "description": "", "match": { "methods": [ - "POST" + "GET" ], - "url": "^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/?)$" + "url": "<^(https://cerberauth\\.com/api/v3|http://swagger\\.io/api/v3)(/user/logout/?)$>" }, "authenticators": [ { @@ -707,7 +805,12 @@ "config": null } ], - "errors": null, + "errors": [ + { + "handler": "json", + "config": null + } + ], "upstream": { "preserve_host": false, "strip_path": "", diff --git a/generator/generator.go b/generator/generator.go index 36dcad5..95f9fd9 100644 --- a/generator/generator.go +++ b/generator/generator.go @@ -18,6 +18,8 @@ type Generator struct { jwksUris map[string]string allowedIssuers map[string]string allowedAudiences map[string]string + + upstream *rule.Upstream } func (g *Generator) computeId(operationId string) string { @@ -38,6 +40,7 @@ func (g *Generator) createRule(verb string, path string, o *openapi3.Operation) ID: g.computeId(o.OperationID), Description: o.Description, Match: match, + Upstream: *g.upstream, Authenticators: []rule.Handler{}, Authorizer: rule.Handler{ Handler: "allow", @@ -86,7 +89,16 @@ func (g *Generator) createRule(verb string, path string, o *openapi3.Operation) return &rule, nil } -func NewGenerator(prefixId string, jwksUris map[string]string, allowedIssuers map[string]string, allowedAudiences map[string]string, serverUrls []string) *Generator { +func NewGenerator(prefixId string, jwksUris map[string]string, allowedIssuers map[string]string, allowedAudiences map[string]string, serverUrls []string, upstreamUrl string, upstreamStripPath string) *Generator { + var upstream = rule.Upstream{} + if upstreamUrl != "" { + upstream.URL = upstreamUrl + } + + if upstreamStripPath != "" { + upstream.StripPath = upstreamStripPath + } + return &Generator{ PrefixId: prefixId, @@ -94,6 +106,8 @@ func NewGenerator(prefixId string, jwksUris map[string]string, allowedIssuers ma allowedIssuers: allowedIssuers, allowedAudiences: allowedAudiences, serverUrls: serverUrls, + + upstream: &upstream, } } diff --git a/generator/generator_test.go b/generator/generator_test.go index 16af0df..3c2bef7 100644 --- a/generator/generator_test.go +++ b/generator/generator_test.go @@ -44,13 +44,13 @@ func getRuleById(rules []rule.Rule, id string) *rule.Rule { return nil } -func newGenerator(docpath string, prefixId string, jwksUris map[string]string, allowedIssuers map[string]string, allowedAudiences map[string]string, serverUrls []string) (*Generator, error) { +func newGenerator(docpath string, prefixId string, jwksUris map[string]string, allowedIssuers map[string]string, allowedAudiences map[string]string, serverUrls []string, upstreamUrl string, upstreamStripPath string) (*Generator, error) { doc, err := openapi3.NewLoader().LoadFromFile(path.Join(basepath, docpath)) if err != nil { return nil, err } - g := NewGenerator(prefixId, jwksUris, allowedIssuers, allowedAudiences, serverUrls) + g := NewGenerator(prefixId, jwksUris, allowedIssuers, allowedAudiences, serverUrls, upstreamUrl, upstreamStripPath) ctx := context.Background() if loadErr := g.LoadOpenAPI3Doc(ctx, doc); loadErr != nil { @@ -89,7 +89,7 @@ func TestGenerateFromSimpleOpenAPI(t *testing.T) { }, }, } - g, newGeneratorErr := newGenerator("../test/stub/simple.openapi.json", "", nil, nil, nil, nil) + g, newGeneratorErr := newGenerator("../test/stub/simple.openapi.json", "", nil, nil, nil, nil, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) } @@ -129,7 +129,7 @@ func TestGenerateFromSimpleOpenAPIWithPrefixId(t *testing.T) { }, }, } - g, newGeneratorErr := newGenerator("../test/stub/simple.openapi.json", "prefix", nil, nil, nil, nil) + g, newGeneratorErr := newGenerator("../test/stub/simple.openapi.json", "prefix", nil, nil, nil, nil, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) } @@ -170,7 +170,7 @@ func TestGenerateFromSimpleOpenAPIWithOneServerUrl(t *testing.T) { }, } serverUrls := []string{"https://www.cerberauth.com/api"} - g, newGeneratorErr := newGenerator("../test/stub/simple.openapi.json", "", nil, nil, nil, serverUrls) + g, newGeneratorErr := newGenerator("../test/stub/simple.openapi.json", "", nil, nil, nil, serverUrls, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) } @@ -214,7 +214,7 @@ func TestGenerateFromSimpleOpenAPIWithSeveralServerUrls(t *testing.T) { "https://www.cerberauth.com/api", "https://api.cerberauth.com/api", } - g, newGeneratorErr := newGenerator("../test/stub/simple.openapi.json", "", nil, nil, nil, serverUrls) + g, newGeneratorErr := newGenerator("../test/stub/simple.openapi.json", "", nil, nil, nil, serverUrls, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) } @@ -262,7 +262,7 @@ func TestGenerateFromSimpleOpenAPIWithOpenIdConnect(t *testing.T) { }, }, } - g, newGeneratorErr := newGenerator("../test/stub/simple_openidconnect.openapi.json", "", nil, nil, nil, nil) + g, newGeneratorErr := newGenerator("../test/stub/simple_openidconnect.openapi.json", "", nil, nil, nil, nil, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) } @@ -318,7 +318,7 @@ func TestGenerateFromSimpleOpenAPIWithOAuth2(t *testing.T) { "petstore_auth": "https://cerberauth.com", }, map[string]string{ "petstore_auth": "https://api.cerberauth.com", - }, nil) + }, nil, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) } @@ -371,7 +371,7 @@ func TestGenerateFromSimpleOpenAPIWithHttpBearer(t *testing.T) { "petstore_auth": "https://cerberauth.com", }, map[string]string{ "petstore_auth": "https://api.cerberauth.com", - }, nil) + }, nil, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) } @@ -417,7 +417,7 @@ func TestGenerateFromSimpleOpenAPIWithOpenIdConnectWithGlobalSecurityScheme(t *t }, }, } - g, newGeneratorErr := newGenerator("../test/stub/simple_openidconnect_global.openapi.json", "", nil, nil, nil, nil) + g, newGeneratorErr := newGenerator("../test/stub/simple_openidconnect_global.openapi.json", "", nil, nil, nil, nil, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) } @@ -428,6 +428,50 @@ func TestGenerateFromSimpleOpenAPIWithOpenIdConnectWithGlobalSecurityScheme(t *t assert.Equal(t, *getRuleById(rules, "updatePet"), expectedRule) } +func TestGenerateFromSimpleOpenAPIWithUpstreamUrlAndPath(t *testing.T) { + expectedRules := []rule.Rule{ + { + ID: "prefix:findPetsByStatus", + Description: "Multiple status values can be provided with comma separated strings", + Match: &rule.Match{ + URL: "<^(https://petstore\\.swagger\\.io/api/v3)(/pet/findByStatus/?)$>", + Methods: []string{"GET"}, + }, + Upstream: rule.Upstream{ + URL: "https://petstore.com", + StripPath: "/api", + }, + Authenticators: []rule.Handler{ + { + Handler: "noop", + }, + }, + Authorizer: rule.Handler{ + Handler: "allow", + }, + Mutators: []rule.Handler{ + { + Handler: "noop", + }, + }, + Errors: []rule.ErrorHandler{ + { + Handler: "json", + }, + }, + }, + } + g, newGeneratorErr := newGenerator("../test/stub/simple.openapi.json", "prefix", nil, nil, nil, nil, "https://petstore.com", "/api") + if newGeneratorErr != nil { + t.Fatal(newGeneratorErr) + } + + rules, err := g.Generate() + + require.NoError(t, err) + assert.Equal(t, rules, expectedRules) +} + func TestGenerateFromSimpleOpenAPIWithOpenIdConnectWithGlobalAndLocalOverrideSecurityScheme(t *testing.T) { expectedRule := rule.Rule{ ID: "findPetsByStatus", @@ -462,7 +506,7 @@ func TestGenerateFromSimpleOpenAPIWithOpenIdConnectWithGlobalAndLocalOverrideSec }, }, } - g, newGeneratorErr := newGenerator("../test/stub/simple_openidconnect_global.openapi.json", "", nil, nil, nil, nil) + g, newGeneratorErr := newGenerator("../test/stub/simple_openidconnect_global.openapi.json", "", nil, nil, nil, nil, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) } @@ -480,7 +524,7 @@ func TestGenerateFromPetstoreWithOpenIdConnect(t *testing.T) { "petstore_auth": "https://cerberauth.com", }, map[string]string{ "petstore_auth": "https://api.cerberauth.com", - }, nil) + }, nil, "", "") if newGeneratorErr != nil { t.Fatal(newGeneratorErr) }