From 1836782978a479ce14b01afdc586a73582574aad Mon Sep 17 00:00:00 2001 From: arekkas Date: Wed, 1 Aug 2018 13:08:10 +0200 Subject: [PATCH 1/4] cmd: Refresh rules in api mode Signed-off-by: arekkas --- cmd/serve_api.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/serve_api.go b/cmd/serve_api.go index 61c8da22ea..95c28a8450 100644 --- a/cmd/serve_api.go +++ b/cmd/serve_api.go @@ -124,7 +124,8 @@ HTTP CONTROLS n.UseHandler(judgeHandler) ch := cors.New(corsx.ParseOptions()).Handler(n) - go refreshKeys(keyManager) + go refreshKeys(keyManager, 0) + go refreshRules(matcher, 0) addr := fmt.Sprintf("%s:%s", viper.GetString("HOST"), viper.GetString("PORT")) server := graceful.WithDefaults(&http.Server{ From f8d16a7f82a4c3afc69c4b38974200edaf1c63a9 Mon Sep 17 00:00:00 2001 From: arekkas Date: Wed, 1 Aug 2018 13:08:27 +0200 Subject: [PATCH 2/4] cmd: Improve refresh subroutines Signed-off-by: arekkas --- cmd/helper_server.go | 16 ++++++++++------ cmd/serve_proxy.go | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cmd/helper_server.go b/cmd/helper_server.go index 85cb1b8423..5ae9cea7aa 100644 --- a/cmd/helper_server.go +++ b/cmd/helper_server.go @@ -50,10 +50,12 @@ func getHydraSDK() hydra.SDK { return sdk } -func refreshRules(m rule.Refresher) { - duration, _ := time.ParseDuration(viper.GetString("RULES_REFRESH_INTERVAL")) +func refreshRules(m rule.Refresher, duration time.Duration) { if duration == 0 { - duration = time.Second * 30 + duration, _ = time.ParseDuration(viper.GetString("RULES_REFRESH_INTERVAL")) + if duration == 0 { + duration = time.Second * 30 + } } var fails int @@ -74,10 +76,12 @@ func refreshRules(m rule.Refresher) { } } -func refreshKeys(k rsakey.Manager) { - duration, _ := time.ParseDuration(viper.GetString("CREDENTIALS_ISSUER_ID_TOKEN_JWK_REFRESH_INTERVAL")) +func refreshKeys(k rsakey.Manager, duration time.Duration) { if duration == 0 { - duration = time.Minute * 5 + duration, _ = time.ParseDuration(viper.GetString("CREDENTIALS_ISSUER_ID_TOKEN_JWK_REFRESH_INTERVAL")) + if duration == 0 { + duration = time.Minute * 5 + } } var fails int diff --git a/cmd/serve_proxy.go b/cmd/serve_proxy.go index 58c8ccb0c6..ae44539e83 100644 --- a/cmd/serve_proxy.go +++ b/cmd/serve_proxy.go @@ -159,8 +159,8 @@ OTHER CONTROLS logger.WithError(err).Fatalln("Unable to initialize the ID Token signing algorithm") } - go refreshRules(matcher) - go refreshKeys(keyManager) + go refreshRules(matcher, 0) + go refreshKeys(keyManager, 0) var authorizers = []proxy.Authorizer{ proxy.NewAuthorizerAllow(), From a9175971c1dd2f21c10b6da348d63a40a049ae1e Mon Sep 17 00:00:00 2001 From: arekkas Date: Wed, 1 Aug 2018 13:12:23 +0200 Subject: [PATCH 3/4] rule: Allow regex in match scheme Closes #92 Signed-off-by: arekkas --- rule/rule_validator.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rule/rule_validator.go b/rule/rule_validator.go index 9f8d2eafc4..b34faece75 100644 --- a/rule/rule_validator.go +++ b/rule/rule_validator.go @@ -37,9 +37,10 @@ func ValidateRule( methods := []string{"GET", "POST", "PUT", "HEAD", "DELETE", "PATCH", "OPTIONS", "TRACE", "CONNECT"} return func(r *Rule) error { - if !govalidator.IsURL(r.Match.URL) { - return errors.WithStack(helper.ErrBadRequest.WithReason(fmt.Sprintf("Value \"%s\" from match.url field is not a valid url.", r.Match.URL))) - } + // This is disabled because it doesn't support checking for regular expressions (obviously). + // if !govalidator.IsURL(r.Match.URL) { + // return errors.WithStack(helper.ErrBadRequest.WithReason(fmt.Sprintf("Value \"%s\" from match.url field is not a valid url.", r.Match.URL))) + // } for _, m := range r.Match.Methods { if !stringslice.Has(methods, m) { From 394702c704bcda09f6cdaf323933bd1e6e7b6661 Mon Sep 17 00:00:00 2001 From: arekkas Date: Wed, 1 Aug 2018 13:18:24 +0200 Subject: [PATCH 4/4] rule: Allow empty upstream in rules Signed-off-by: arekkas --- proxy/proxy.go | 4 ++++ rule/rule_validator.go | 7 ++++++- rule/rule_validator_test.go | 12 ++++++------ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index 6567fd0cfb..aef9218f71 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -143,6 +143,10 @@ func EnrichRequestedURL(r *http.Request) { } func configureBackendURL(r *http.Request, rl *rule.Rule) error { + if rl.Upstream.URL == "" { + return errors.Errorf("Unable to forward the request because matched rule does not define an upstream URL") + } + p, err := url.Parse(rl.Upstream.URL) if err != nil { return errors.WithStack(err) diff --git a/rule/rule_validator.go b/rule/rule_validator.go index b34faece75..f6d782e20d 100644 --- a/rule/rule_validator.go +++ b/rule/rule_validator.go @@ -41,6 +41,9 @@ func ValidateRule( // if !govalidator.IsURL(r.Match.URL) { // return errors.WithStack(helper.ErrBadRequest.WithReason(fmt.Sprintf("Value \"%s\" from match.url field is not a valid url.", r.Match.URL))) // } + if r.Match.URL == "" { + return errors.WithStack(helper.ErrBadRequest.WithReason(fmt.Sprintf("Value \"%s\" from match.url field is not a valid url.", r.Match.URL))) + } for _, m := range r.Match.Methods { if !stringslice.Has(methods, m) { @@ -48,7 +51,9 @@ func ValidateRule( } } - if !govalidator.IsURL(r.Upstream.URL) { + if r.Upstream.URL == "" { + // Having no upstream URL is fine here because the judge does not need an upstream! + } else if !govalidator.IsURL(r.Upstream.URL) { return errors.WithStack(helper.ErrBadRequest.WithReason(fmt.Sprintf("Value \"%s\" from upstream.url field is not a valid url.", r.Upstream.URL))) } diff --git a/rule/rule_validator_test.go b/rule/rule_validator_test.go index 5472b41c84..84e4ea74a0 100644 --- a/rule/rule_validator_test.go +++ b/rule/rule_validator_test.go @@ -39,17 +39,17 @@ func TestValidateRule(t *testing.T) { assertReason(t, v(&Rule{}), "from match.url field is not a valid url.") - assertReason(t, v(&Rule{ - Match: RuleMatch{URL: "asdf"}, - }), "from match.url field is not a valid url.") + // assertReason(t, v(&Rule{ + // Match: RuleMatch{URL: "asdf"}, + // }), "from match.url field is not a valid url.") assertReason(t, v(&Rule{ Match: RuleMatch{URL: "https://www.ory.sh", Methods: []string{"FOO"}}, }), "from match.methods is not a valid HTTP method") - assertReason(t, v(&Rule{ - Match: RuleMatch{URL: "https://www.ory.sh", Methods: []string{"POST"}}, - }), "from upstream.url field is not a valid url.") + // assertReason(t, v(&Rule{ + // Match: RuleMatch{URL: "https://www.ory.sh", Methods: []string{"POST"}}, + // }), "from upstream.url field is not a valid url.") assertReason(t, v(&Rule{ Match: RuleMatch{URL: "https://www.ory.sh", Methods: []string{"POST"}},