Skip to content

Commit

Permalink
feat: forward parsed request cookies to webhook Jsonnet snippet (#2917)
Browse files Browse the repository at this point in the history
Request cookies were already available in raw form in
the ctx.request_headers top-level argument to the Jsonnet snippet.
Parsing cookies in Jsonnet is tedious and error-prone, though, so
we parse them internally for convenience.
  • Loading branch information
alnr authored Dec 1, 2022
1 parent 624e1f0 commit 70ed068
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 8 deletions.
3 changes: 2 additions & 1 deletion selfservice/hook/stub/test_body.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ function(ctx) {
identity_id: if std.objectHas(ctx, "identity") then ctx.identity.id,
headers: ctx.request_headers,
url: ctx.request_url,
method: ctx.request_method
method: ctx.request_method,
cookies: ctx.request_cookies,
}
23 changes: 23 additions & 0 deletions selfservice/hook/web_hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type (
RequestHeaders http.Header `json:"request_headers"`
RequestMethod string `json:"request_method"`
RequestURL string `json:"request_url"`
RequestCookies map[string]string `json:"request_cookies"`
Identity *identity.Identity `json:"identity,omitempty"`
}

Expand All @@ -82,6 +83,16 @@ type (
}
)

func cookies(req *http.Request) map[string]string {
cookies := make(map[string]string)
for _, c := range req.Cookies() {
if c.Name != "" {
cookies[c.Name] = c.Value
}
}
return cookies
}

func NewWebHook(r webHookDependencies, c json.RawMessage) *WebHook {
return &WebHook{deps: r, conf: c}
}
Expand All @@ -93,6 +104,7 @@ func (e *WebHook) ExecuteLoginPreHook(_ http.ResponseWriter, req *http.Request,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
})
}

Expand All @@ -103,6 +115,7 @@ func (e *WebHook) ExecuteLoginPostHook(_ http.ResponseWriter, req *http.Request,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: session.Identity,
})
}
Expand All @@ -114,6 +127,7 @@ func (e *WebHook) ExecuteVerificationPreHook(_ http.ResponseWriter, req *http.Re
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
})
}

Expand All @@ -124,6 +138,7 @@ func (e *WebHook) ExecutePostVerificationHook(_ http.ResponseWriter, req *http.R
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
})
}
Expand All @@ -134,6 +149,7 @@ func (e *WebHook) ExecuteRecoveryPreHook(_ http.ResponseWriter, req *http.Reques
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestCookies: cookies(req),
RequestURL: x.RequestURL(req).String(),
})
}
Expand All @@ -145,6 +161,7 @@ func (e *WebHook) ExecutePostRecoveryHook(_ http.ResponseWriter, req *http.Reque
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: session.Identity,
})
}
Expand All @@ -156,6 +173,7 @@ func (e *WebHook) ExecuteRegistrationPreHook(_ http.ResponseWriter, req *http.Re
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
})
}

Expand All @@ -170,6 +188,7 @@ func (e *WebHook) ExecutePostRegistrationPrePersistHook(_ http.ResponseWriter, r
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
})
}
Expand All @@ -185,6 +204,7 @@ func (e *WebHook) ExecutePostRegistrationPostPersistHook(_ http.ResponseWriter,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: session.Identity,
})
}
Expand All @@ -196,6 +216,7 @@ func (e *WebHook) ExecuteSettingsPreHook(_ http.ResponseWriter, req *http.Reques
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
})
}

Expand All @@ -210,6 +231,7 @@ func (e *WebHook) ExecuteSettingsPostPersistHook(_ http.ResponseWriter, req *htt
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
})
}
Expand All @@ -225,6 +247,7 @@ func (e *WebHook) ExecuteSettingsPrePersistHook(_ http.ResponseWriter, req *http
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
})
}
Expand Down
43 changes: 36 additions & 7 deletions selfservice/hook/web_hook_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,12 @@ func TestWebHooks(t *testing.T) {
"identity_id": null,
"headers": %s,
"method": "%s",
"url": "%s"
"url": "%s",
"cookies": {
"Some-Cookie-1": "Some-Cookie-Value",
"Some-Cookie-2": "Some-other-Cookie-Value",
"Some-Cookie-3": "Third-Cookie-Value"
}
}`, f.GetID(), string(h), req.Method, "http://www.ory.sh/some_end_point")
}

Expand All @@ -130,7 +135,12 @@ func TestWebHooks(t *testing.T) {
"identity_id": "%s",
"headers": %s,
"method": "%s",
"url": "%s"
"url": "%s",
"cookies": {
"Some-Cookie-1": "Some-Cookie-Value",
"Some-Cookie-2": "Some-other-Cookie-Value",
"Some-Cookie-3": "Third-Cookie-Value"
}
}`, f.GetID(), s.Identity.ID, string(h), req.Method, "http://www.ory.sh/some_end_point")
}

Expand Down Expand Up @@ -275,12 +285,28 @@ func TestWebHooks(t *testing.T) {
t.Run("method="+method, func(t *testing.T) {
f := tc.createFlow()
req := &http.Request{
Host: "www.ory.sh",
Header: map[string][]string{"Some-Header": {"Some-Value"}},
Host: "www.ory.sh",
Header: map[string][]string{
"Some-Header": {"Some-Value"},
"Cookie": {"Some-Cookie-1=Some-Cookie-Value; Some-Cookie-2=Some-other-Cookie-Value", "Some-Cookie-3=Third-Cookie-Value"},
},
RequestURI: "/some_end_point",
Method: http.MethodPost,
URL: &url.URL{Path: "/some_end_point"},
}
cookie, err := req.Cookie("Some-Cookie-1")
require.NoError(t, err)
require.Equal(t, cookie.Name, "Some-Cookie-1")
require.Equal(t, cookie.Value, "Some-Cookie-Value")
cookie, err = req.Cookie("Some-Cookie-2")
require.NoError(t, err)
require.Equal(t, cookie.Name, "Some-Cookie-2")
require.Equal(t, cookie.Value, "Some-other-Cookie-Value")
cookie, err = req.Cookie("Some-Cookie-3")
require.NoError(t, err)
require.Equal(t, cookie.Name, "Some-Cookie-3")
require.Equal(t, cookie.Value, "Third-Cookie-Value")

s := &session.Session{ID: x.NewUUID(), Identity: &identity.Identity{ID: x.NewUUID()}}
whr := &WebHookRequest{}
ts := newServer(webHookEndPoint(whr))
Expand All @@ -293,7 +319,7 @@ func TestWebHooks(t *testing.T) {

wh := hook.NewWebHook(&whDeps, conf)

err := tc.callWebHook(wh, req, f, s)
err = tc.callWebHook(wh, req, f, s)
if method == "GARBAGE" {
assert.Error(t, err)
return
Expand Down Expand Up @@ -541,8 +567,11 @@ func TestWebHooks(t *testing.T) {
t.Run("method="+method, func(t *testing.T) {
f := tc.createFlow()
req := &http.Request{
Host: "www.ory.sh",
Header: map[string][]string{"Some-Header": {"Some-Value"}, "X-Forwarded-Proto": {"https"}},
Host: "www.ory.sh",
Header: map[string][]string{
"Some-Header": {"Some-Value"},
"X-Forwarded-Proto": {"https"},
"Cookie": {"Some-Cookie-1=Some-Cookie-Value; Some-Cookie-2=Some-other-Cookie-Value", "Some-Cookie-3=Third-Cookie-Value"}},
RequestURI: "/some_end_point",
Method: http.MethodPost,
URL: &url.URL{
Expand Down

0 comments on commit 70ed068

Please sign in to comment.