Skip to content

Commit

Permalink
fix: webhook tracing instrumentation+memory leak
Browse files Browse the repository at this point in the history
  • Loading branch information
alnr committed Dec 20, 2022
1 parent 7ce3a74 commit f0044a3
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 100 deletions.
1 change: 1 addition & 0 deletions driver/registry_default.go
Expand Up @@ -517,6 +517,7 @@ func (m *RegistryDefault) ContinuityCookieManager(ctx context.Context) sessions.

func (m *RegistryDefault) Tracer(ctx context.Context) *otelx.Tracer {
if m.trc == nil {
m.Logger().WithError(errors.WithStack(errors.New(""))).Warn("No tracer setup in RegistryDefault")
return otelx.NewNoop(m.l, m.Config().Tracing(ctx)) // should never happen
}
return m.trc
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -77,7 +77,7 @@ require (
github.com/ory/jsonschema/v3 v3.0.7
github.com/ory/mail/v3 v3.0.0
github.com/ory/nosurf v1.2.7
github.com/ory/x v0.0.521-0.20221216212409-f080646b8e21
github.com/ory/x v0.0.523
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
github.com/pkg/errors v0.9.1
github.com/pquerna/otp v1.4.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -1141,8 +1141,8 @@ github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2 h1:zm6sDvHy/U9XrGpi
github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/ory/viper v1.7.5 h1:+xVdq7SU3e1vNaCsk/ixsfxE4zylk1TJUiJrY647jUE=
github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM=
github.com/ory/x v0.0.521-0.20221216212409-f080646b8e21 h1:orPnF0wdAveQNU8Q9fRj8fbQ4bESesM2JnugkEFinfg=
github.com/ory/x v0.0.521-0.20221216212409-f080646b8e21/go.mod h1:ayJio5x/fK4RwTgfgzs3JetOaaOSxso9hQjc3mFY8z0=
github.com/ory/x v0.0.523 h1:vn8e+8tV3RqD8RlvoE6lLPUnjpjua1ExJDMFy3Z5TAQ=
github.com/ory/x v0.0.523/go.mod h1:ayJio5x/fK4RwTgfgzs3JetOaaOSxso9hQjc3mFY8z0=
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
Expand Down
2 changes: 1 addition & 1 deletion persistence/sql/persister_session.go
Expand Up @@ -120,7 +120,7 @@ func (p *Persister) ListSessions(ctx context.Context, active *bool, paginatorOpt
return nil, 0, nil, err
}

s, nextPage := keysetpagination.Result[session.Session](s, paginator)
s, nextPage := keysetpagination.Result(s, paginator)
return s, t, nextPage, nil
}

Expand Down
201 changes: 105 additions & 96 deletions selfservice/hook/web_hook.go
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/ory/kratos/ui/node"
"github.com/ory/x/jsonnetsecure"
"github.com/ory/x/otelx"

"github.com/ory/kratos/identity"
"github.com/ory/kratos/request"
Expand Down Expand Up @@ -100,157 +101,165 @@ func NewWebHook(r webHookDependencies, c json.RawMessage) *WebHook {
}

func (e *WebHook) ExecuteLoginPreHook(_ http.ResponseWriter, req *http.Request, flow *login.Flow) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePreLoginHook")
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecuteLoginPreHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
})
})
}

func (e *WebHook) ExecuteLoginPostHook(_ http.ResponseWriter, req *http.Request, _ node.UiNodeGroup, flow *login.Flow, session *session.Session) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePostLoginHook")
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: session.Identity,
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecuteLoginPostHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: session.Identity,
})
})
}

func (e *WebHook) ExecuteVerificationPreHook(_ http.ResponseWriter, req *http.Request, flow *verification.Flow) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePreVerificationHook")
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecuteVerificationPreHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
})
})
}

func (e *WebHook) ExecutePostVerificationHook(_ http.ResponseWriter, req *http.Request, flow *verification.Flow, id *identity.Identity) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePostVerificationHook")
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecutePostVerificationHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
})
})
}

func (e *WebHook) ExecuteRecoveryPreHook(_ http.ResponseWriter, req *http.Request, flow *recovery.Flow) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePreRecoveryHook")
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestCookies: cookies(req),
RequestURL: x.RequestURL(req).String(),
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecuteRecoveryPreHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestCookies: cookies(req),
RequestURL: x.RequestURL(req).String(),
})
})
}

func (e *WebHook) ExecutePostRecoveryHook(_ http.ResponseWriter, req *http.Request, flow *recovery.Flow, session *session.Session) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePostRecoveryHook")
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: session.Identity,
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecutePostRecoveryHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: session.Identity,
})
})
}

func (e *WebHook) ExecuteRegistrationPreHook(_ http.ResponseWriter, req *http.Request, flow *registration.Flow) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecuteRegistrationPreHook")
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecuteRegistrationPreHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
})
})
}

func (e *WebHook) ExecutePostRegistrationPrePersistHook(_ http.ResponseWriter, req *http.Request, flow *registration.Flow, id *identity.Identity) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePostRegistrationPrePersistHook")
if !gjson.GetBytes(e.conf, "can_interrupt").Bool() {
return nil
}

return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecutePostRegistrationPrePersistHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
})
})
}

func (e *WebHook) ExecutePostRegistrationPostPersistHook(_ http.ResponseWriter, req *http.Request, flow *registration.Flow, session *session.Session) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePostRegistrationPostPersistHook")
if gjson.GetBytes(e.conf, "can_interrupt").Bool() {
return nil
}

return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: session.Identity,
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecutePostRegistrationPostPersistHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: session.Identity,
})
})
}

func (e *WebHook) ExecuteSettingsPreHook(_ http.ResponseWriter, req *http.Request, flow *settings.Flow) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecutePreSettingsHook")
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecuteSettingsPreHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
})
})
}

func (e *WebHook) ExecuteSettingsPostPersistHook(_ http.ResponseWriter, req *http.Request, flow *settings.Flow, id *identity.Identity) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecuteSettingsPostPersistHook")
if gjson.GetBytes(e.conf, "can_interrupt").Bool() {
return nil
}

return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecuteSettingsPostPersistHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
})
})
}

func (e *WebHook) ExecuteSettingsPrePersistHook(_ http.ResponseWriter, req *http.Request, flow *settings.Flow, id *identity.Identity) error {
ctx, _ := e.deps.Tracer(req.Context()).Tracer().Start(req.Context(), "selfservice.hook.ExecuteSettingsPrePersistHook")
if !gjson.GetBytes(e.conf, "can_interrupt").Bool() {
return nil
}

return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
return otelx.WithSpan(req.Context(), "selfservice.hook.ExecuteSettingsPrePersistHook", func(ctx context.Context) error {
return e.execute(ctx, &templateContext{
Flow: flow,
RequestHeaders: req.Header,
RequestMethod: req.Method,
RequestURL: x.RequestURL(req).String(),
RequestCookies: cookies(req),
Identity: id,
})
})
}

Expand Down Expand Up @@ -284,7 +293,7 @@ func (e *WebHook) execute(ctx context.Context, data *templateContext) error {
errChan = make(chan error, 1)
)

ctx, span := tracer.Start(ctx, "Webhook", spanOpts...)
ctx, span := tracer.Start(ctx, "selfservice.webhook", spanOpts...)
e.deps.Logger().WithRequest(req.Request).Info("Dispatching webhook")

req = req.WithContext(ctx)
Expand Down

0 comments on commit f0044a3

Please sign in to comment.