Skip to content

Commit 88e75d9

Browse files
authored
fix: do not double-commit webhooks on registration (#2888)
1 parent 5bce0b9 commit 88e75d9

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

selfservice/hook/web_hook.go

+38-5
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,17 @@ import (
3232
"github.com/ory/x/otelx"
3333
)
3434

35-
var _ registration.PostHookPostPersistExecutor = new(WebHook)
36-
var _ registration.PostHookPrePersistExecutor = new(WebHook)
37-
var _ verification.PostHookExecutor = new(WebHook)
38-
var _ recovery.PostHookExecutor = new(WebHook)
39-
var _ settings.PostHookPostPersistExecutor = new(WebHook)
35+
var (
36+
_ registration.PostHookPostPersistExecutor = new(WebHook)
37+
_ registration.PostHookPrePersistExecutor = new(WebHook)
38+
39+
_ verification.PostHookExecutor = new(WebHook)
40+
41+
_ recovery.PostHookExecutor = new(WebHook)
42+
43+
_ settings.PostHookPostPersistExecutor = new(WebHook)
44+
_ settings.PostHookPrePersistExecutor = new(WebHook)
45+
)
4046

4147
type (
4248
webHookDependencies interface {
@@ -155,6 +161,10 @@ func (e *WebHook) ExecuteRegistrationPreHook(_ http.ResponseWriter, req *http.Re
155161

156162
func (e *WebHook) ExecutePostRegistrationPrePersistHook(_ http.ResponseWriter, req *http.Request, flow *registration.Flow, id *identity.Identity) error {
157163
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePostRegistrationPrePersistHook")
164+
if !gjson.GetBytes(e.conf, "can_interrupt").Bool() {
165+
return nil
166+
}
167+
158168
return e.execute(ctx, &templateContext{
159169
Flow: flow,
160170
RequestHeaders: req.Header,
@@ -166,6 +176,10 @@ func (e *WebHook) ExecutePostRegistrationPrePersistHook(_ http.ResponseWriter, r
166176

167177
func (e *WebHook) ExecutePostRegistrationPostPersistHook(_ http.ResponseWriter, req *http.Request, flow *registration.Flow, session *session.Session) error {
168178
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePostRegistrationPostPersistHook")
179+
if gjson.GetBytes(e.conf, "can_interrupt").Bool() {
180+
return nil
181+
}
182+
169183
return e.execute(ctx, &templateContext{
170184
Flow: flow,
171185
RequestHeaders: req.Header,
@@ -187,6 +201,25 @@ func (e *WebHook) ExecuteSettingsPreHook(_ http.ResponseWriter, req *http.Reques
187201

188202
func (e *WebHook) ExecuteSettingsPostPersistHook(_ http.ResponseWriter, req *http.Request, flow *settings.Flow, id *identity.Identity) error {
189203
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecuteSettingsPostPersistHook")
204+
if gjson.GetBytes(e.conf, "can_interrupt").Bool() {
205+
return nil
206+
}
207+
208+
return e.execute(ctx, &templateContext{
209+
Flow: flow,
210+
RequestHeaders: req.Header,
211+
RequestMethod: req.Method,
212+
RequestURL: x.RequestURL(req).String(),
213+
Identity: id,
214+
})
215+
}
216+
217+
func (e *WebHook) ExecuteSettingsPrePersistHook(_ http.ResponseWriter, req *http.Request, flow *settings.Flow, id *identity.Identity) error {
218+
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecuteSettingsPrePersistHook")
219+
if !gjson.GetBytes(e.conf, "can_interrupt").Bool() {
220+
return nil
221+
}
222+
190223
return e.execute(ctx, &templateContext{
191224
Flow: flow,
192225
RequestHeaders: req.Header,

selfservice/hook/web_hook_integration_test.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -425,15 +425,16 @@ func TestWebHooks(t *testing.T) {
425425
expectedError: nil,
426426
},
427427
{
428-
uc: "Post Registration Post Persists Hook - block",
428+
uc: "Post Registration Post Persist Hook - block has no effect",
429429
createFlow: func() flow.Flow { return &registration.Flow{ID: x.NewUUID()} },
430430
callWebHook: func(wh *hook.WebHook, req *http.Request, f flow.Flow, s *session.Session) error {
431431
return wh.ExecutePostRegistrationPostPersistHook(nil, req, f.(*registration.Flow), s)
432432
},
433+
// This would usually error, but post persist does not execute blocking web hooks, so we expect no error.
433434
webHookResponse: func() (int, []byte) {
434435
return http.StatusBadRequest, webHookResponse
435436
},
436-
expectedError: webhookError,
437+
expectedError: nil,
437438
},
438439
{
439440
uc: "Post Registration Pre Persist Hook - no block",
@@ -513,16 +514,27 @@ func TestWebHooks(t *testing.T) {
513514
expectedError: nil,
514515
},
515516
{
516-
uc: "Post Settings Hook - block",
517+
uc: "Post Settings Hook Pre Persist - block",
517518
createFlow: func() flow.Flow { return &settings.Flow{ID: x.NewUUID()} },
518519
callWebHook: func(wh *hook.WebHook, req *http.Request, f flow.Flow, s *session.Session) error {
519-
return wh.ExecuteSettingsPostPersistHook(nil, req, f.(*settings.Flow), s.Identity)
520+
return wh.ExecuteSettingsPrePersistHook(nil, req, f.(*settings.Flow), s.Identity)
520521
},
521522
webHookResponse: func() (int, []byte) {
522523
return http.StatusBadRequest, webHookResponse
523524
},
524525
expectedError: webhookError,
525526
},
527+
{
528+
uc: "Post Settings Hook Post Persist - block has no effect",
529+
createFlow: func() flow.Flow { return &settings.Flow{ID: x.NewUUID()} },
530+
callWebHook: func(wh *hook.WebHook, req *http.Request, f flow.Flow, s *session.Session) error {
531+
return wh.ExecuteSettingsPostPersistHook(nil, req, f.(*settings.Flow), s.Identity)
532+
},
533+
webHookResponse: func() (int, []byte) {
534+
return http.StatusBadRequest, webHookResponse
535+
},
536+
expectedError: nil,
537+
},
526538
} {
527539
t.Run("uc="+tc.uc, func(t *testing.T) {
528540
for _, method := range []string{"CONNECT", "DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT", "TRACE"} {

0 commit comments

Comments
 (0)