Skip to content

Commit

Permalink
Support multiple mutators per access rule (#233)
Browse files Browse the repository at this point in the history
Closes #233
  • Loading branch information
jakkab authored and aeneasr committed Aug 12, 2019
1 parent 2e0b3ef commit d21179d
Show file tree
Hide file tree
Showing 273 changed files with 3,898 additions and 1,862 deletions.
44 changes: 44 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,50 @@ before finalizing the upgrade process.

## master

## v0.18.0-beta.1+oryOS.12

### Mutators
1. ORY Oathkeeper now supports multiple mutators. Mutations are performed in the provided order and must all succeed in order for the HTTP request to be forwarded.
2. The `mutator` property was renamed to `mutators` to reflect its true nature (see previous item).

### Access Rule Changes

As already noted, the `mutator` property was renamed to `mutators` and now represents a list of mutation handlers. If you have
existing rules, please update them as follows:

```
[
{
"id": "jwt-rule",
"upstream": {
"url": "http://127.0.0.1:6662"
},
"match": {
"url": "http://127.0.0.1:<6660|6661>/jwt",
"methods": [
"GET"
]
},
"authenticators": [
{
"handler": "jwt"
}
],
"authorizer": {
"handler": "allow"
},
- "mutator": {
- "handler": "id_token"
- }
+ "mutators": [
+ {
+ "handler": "id_token"
+ }
+ ]
}
]
```

## v0.17.0-beta.1+oryOS.12

ORY Oathkeeper now watches configuration files and access rules repositories on
Expand Down
22 changes: 17 additions & 5 deletions api/decision_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ func TestDecisionAPI(t *testing.T) {
Match: rule.RuleMatch{Methods: []string{"GET"}, URL: ts.URL + "/authn-noop/<[0-9]+>"},
Authenticators: []rule.RuleHandler{{Handler: "noop"}},
Authorizer: rule.RuleHandler{Handler: "allow"},
Mutator: rule.RuleHandler{Handler: "noop"},
Mutators: []rule.RuleHandler{{Handler: "noop"}},
Upstream: rule.Upstream{URL: ""},
}
ruleNoOpAuthenticatorModifyUpstream := rule.Rule{
Match: rule.RuleMatch{Methods: []string{"GET"}, URL: ts.URL + "/strip-path/authn-noop/<[0-9]+>"},
Authenticators: []rule.RuleHandler{{Handler: "noop"}},
Authorizer: rule.RuleHandler{Handler: "allow"},
Mutator: rule.RuleHandler{Handler: "noop"},
Mutators: []rule.RuleHandler{{Handler: "noop"}},
Upstream: rule.Upstream{URL: "", StripPath: "/strip-path/", PreserveHost: true},
}

Expand Down Expand Up @@ -146,7 +146,7 @@ func TestDecisionAPI(t *testing.T) {
Match: rule.RuleMatch{Methods: []string{"GET"}, URL: ts.URL + "/authn-anon/authz-allow/cred-noop/<[0-9]+>"},
Authenticators: []rule.RuleHandler{{Handler: "anonymous"}},
Authorizer: rule.RuleHandler{Handler: "allow"},
Mutator: rule.RuleHandler{Handler: "noop"},
Mutators: []rule.RuleHandler{{Handler: "noop"}},
Upstream: rule.Upstream{URL: ""},
}},
code: http.StatusOK,
Expand All @@ -159,7 +159,7 @@ func TestDecisionAPI(t *testing.T) {
Match: rule.RuleMatch{Methods: []string{"GET"}, URL: ts.URL + "/authn-anon/authz-deny/cred-noop/<[0-9]+>"},
Authenticators: []rule.RuleHandler{{Handler: "anonymous"}},
Authorizer: rule.RuleHandler{Handler: "deny"},
Mutator: rule.RuleHandler{Handler: "noop"},
Mutators: []rule.RuleHandler{{Handler: "noop"}},
Upstream: rule.Upstream{URL: ""},
}},
code: http.StatusForbidden,
Expand All @@ -181,7 +181,19 @@ func TestDecisionAPI(t *testing.T) {
Match: rule.RuleMatch{Methods: []string{"GET"}, URL: ts.URL + "/authn-anonymous/authz-allow/cred-broken/<[0-9]+>"},
Authenticators: []rule.RuleHandler{{Handler: "anonymous"}},
Authorizer: rule.RuleHandler{Handler: "allow"},
Mutator: rule.RuleHandler{Handler: "broken"},
Mutators: []rule.RuleHandler{{Handler: "broken"}},
Upstream: rule.Upstream{URL: ""},
}},
code: http.StatusInternalServerError,
},
{
d: "should fail when one of the mutators fails",
url: ts.URL + "/decisions" + "/authn-anonymous/authz-allow/cred-broken/1234",
rules: []rule.Rule{{
Match: rule.RuleMatch{Methods: []string{"GET"}, URL: ts.URL + "/authn-anonymous/authz-allow/cred-broken/<[0-9]+>"},
Authenticators: []rule.RuleHandler{{Handler: "anonymous"}},
Authorizer: rule.RuleHandler{Handler: "allow"},
Mutators: []rule.RuleHandler{{Handler: "noop"}, {Handler: "broken"}},
Upstream: rule.Upstream{URL: ""},
}},
code: http.StatusInternalServerError,
Expand Down
8 changes: 5 additions & 3 deletions api/rule_doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ type swaggerRule struct {
// making the request.
Authorizer swaggerRuleHandler `json:"authorizer"`

// Mutator is a handler that transform the HTTP request. A common use case is generating a new set of credentials
// (e.g. JWT) which then will be forwarded to the upstream server.
Mutator swaggerRuleHandler `json:"mutator"`
// Mutators is a list of mutation handlers that transform the HTTP request. A common use case is generating a new set
// of credentials (e.g. JWT) which then will be forwarded to the upstream server.
//
// Mutations are performed iteratively from index 0 to n and should all succeed in order for the HTTP request to be forwarded.
Mutators []swaggerRuleHandler `json:"mutators"`

// Upstream is the location of the server where requests matching this rule should be forwarded to.
Upstream *rule.Upstream `json:"upstream"`
Expand Down
4 changes: 2 additions & 2 deletions api/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestHandler(t *testing.T) {
Description: "Create users rule",
Authorizer: rule.RuleHandler{Handler: "allow", Config: json.RawMessage(`{"type":"any"}`)},
Authenticators: []rule.RuleHandler{{Handler: "anonymous", Config: json.RawMessage(`{"name":"anonymous1"}`)}},
Mutator: rule.RuleHandler{Handler: "id_token", Config: json.RawMessage(`{"issuer":"anything"}`)},
Mutators: []rule.RuleHandler{{Handler: "id_token", Config: json.RawMessage(`{"issuer":"anything"}`)}},
Upstream: rule.Upstream{
URL: "http://localhost:1235/",
StripPath: "/bar",
Expand All @@ -82,7 +82,7 @@ func TestHandler(t *testing.T) {
Description: "Get users rule",
Authorizer: rule.RuleHandler{Handler: "deny", Config: json.RawMessage(`{"type":"any"}`)},
Authenticators: []rule.RuleHandler{{Handler: "oauth2_introspection", Config: json.RawMessage(`{"name":"anonymous1"}`)}},
Mutator: rule.RuleHandler{Handler: "id_token", Config: json.RawMessage(`{"issuer":"anything"}`)},
Mutators: []rule.RuleHandler{{Handler: "id_token", Config: json.RawMessage(`{"issuer":"anything"}`)}, {Handler: "headers", Config: json.RawMessage(`{"headers":{"X-User":"user"}}`)}},
Upstream: rule.Upstream{
URL: "http://localhost:333/",
StripPath: "/foo",
Expand Down
2 changes: 1 addition & 1 deletion cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func init() {
os.Setenv("AUTHENTICATORS_ANONYMOUS_ENABLED", "true")
os.Setenv("AUTHORIZERS_ALLOW_ENABLED", "true")
os.Setenv("MUTATORS_NOOP_ENABLED", "true")
os.Setenv("ACCESS_RULES_REPOSITORIES", "inline://W3siaWQiOiJ0ZXN0LXJ1bGUtNCIsInVwc3RyZWFtIjp7InByZXNlcnZlX2hvc3QiOnRydWUsInN0cmlwX3BhdGgiOiIvYXBpIiwidXJsIjoibXliYWNrZW5kLmNvbS9hcGkifSwibWF0Y2giOnsidXJsIjoibXlwcm94eS5jb20vYXBpIiwibWV0aG9kcyI6WyJHRVQiLCJQT1NUIl19LCJhdXRoZW50aWNhdG9ycyI6W3siaGFuZGxlciI6Im5vb3AifSx7ImhhbmRsZXIiOiJhbm9ueW1vdXMifV0sImF1dGhvcml6ZXIiOnsiaGFuZGxlciI6ImFsbG93In0sIm11dGF0b3IiOnsiaGFuZGxlciI6Im5vb3AifX1d")
os.Setenv("ACCESS_RULES_REPOSITORIES", "inline://W3siaWQiOiJ0ZXN0LXJ1bGUtNCIsInVwc3RyZWFtIjp7InByZXNlcnZlX2hvc3QiOnRydWUsInN0cmlwX3BhdGgiOiIvYXBpIiwidXJsIjoibXliYWNrZW5kLmNvbS9hcGkifSwibWF0Y2giOnsidXJsIjoibXlwcm94eS5jb20vYXBpIiwibWV0aG9kcyI6WyJHRVQiLCJQT1NUIl19LCJhdXRoZW50aWNhdG9ycyI6W3siaGFuZGxlciI6Im5vb3AifSx7ImhhbmRsZXIiOiJhbm9ueW1vdXMifV0sImF1dGhvcml6ZXIiOnsiaGFuZGxlciI6ImFsbG93In0sIm11dGF0b3JzIjpbeyJoYW5kbGVyIjoibm9vcCJ9XX1d")
}

func ensureOpen(t *testing.T, port int) bool {
Expand Down
Loading

0 comments on commit d21179d

Please sign in to comment.