kratos/driver/registry_default_hooks.go

117 lines
3.2 KiB
Go

// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package driver
import (
"encoding/json"
"fmt"
"github.com/pkg/errors"
"github.com/ory/kratos/driver/config"
"github.com/ory/kratos/request"
"github.com/ory/kratos/selfservice/hook"
)
func (m *RegistryDefault) HookVerifier() *hook.Verifier {
if m.hookVerifier == nil {
m.hookVerifier = hook.NewVerifier(m)
}
return m.hookVerifier
}
func (m *RegistryDefault) HookSessionIssuer() *hook.SessionIssuer {
if m.hookSessionIssuer == nil {
m.hookSessionIssuer = hook.NewSessionIssuer(m)
}
return m.hookSessionIssuer
}
func (m *RegistryDefault) HookSessionDestroyer() *hook.SessionDestroyer {
if m.hookSessionDestroyer == nil {
m.hookSessionDestroyer = hook.NewSessionDestroyer(m)
}
return m.hookSessionDestroyer
}
func (m *RegistryDefault) HookAddressVerifier() *hook.AddressVerifier {
if m.hookAddressVerifier == nil {
m.hookAddressVerifier = hook.NewAddressVerifier(m)
}
return m.hookAddressVerifier
}
func (m *RegistryDefault) HookShowVerificationUI() *hook.ShowVerificationUIHook {
if m.hookShowVerificationUI == nil {
m.hookShowVerificationUI = hook.NewShowVerificationUIHook(m)
}
return m.hookShowVerificationUI
}
func (m *RegistryDefault) WithHooks(hooks map[string]func(config.SelfServiceHook) interface{}) {
m.injectedSelfserviceHooks = hooks
}
func (m *RegistryDefault) WithExtraHandlers(handlers []NewHandlerRegistrar) {
m.extraHandlerFactories = handlers
}
func getHooks[T any](m *RegistryDefault, credentialsType string, configs []config.SelfServiceHook) ([]T, error) {
hooks := make([]T, 0, len(configs))
var addSessionIssuer bool
allHooksLoop:
for _, h := range configs {
switch h.Name {
case hook.KeySessionIssuer:
// The session issuer hook always needs to come last.
addSessionIssuer = true
case hook.KeySessionDestroyer:
if h, ok := any(m.HookSessionDestroyer()).(T); ok {
hooks = append(hooks, h)
}
case hook.KeyWebHook:
cfg := request.Config{}
if err := json.Unmarshal(h.Config, &cfg); err != nil {
m.l.WithError(err).WithField("raw_config", string(h.Config)).Error("failed to unmarshal hook configuration, ignoring hook")
return nil, errors.WithStack(fmt.Errorf("failed to unmarshal webhook configuration for %s: %w", credentialsType, err))
}
if h, ok := any(hook.NewWebHook(m, &cfg)).(T); ok {
hooks = append(hooks, h)
}
case hook.KeyRequireVerifiedAddress:
if h, ok := any(m.HookAddressVerifier()).(T); ok {
hooks = append(hooks, h)
}
case hook.KeyVerificationUI:
if h, ok := any(m.HookShowVerificationUI()).(T); ok {
hooks = append(hooks, h)
}
case hook.KeyVerifier:
if h, ok := any(m.HookVerifier()).(T); ok {
hooks = append(hooks, h)
}
default:
for name, m := range m.injectedSelfserviceHooks {
if name == h.Name {
if h, ok := m(h).(T); ok {
hooks = append(hooks, h)
}
continue allHooksLoop
}
}
m.l.
WithField("for", credentialsType).
WithField("hook", h.Name).
Warn("A configuration for a non-existing hook was found and will be ignored.")
}
}
if addSessionIssuer {
if h, ok := any(m.HookSessionIssuer()).(T); ok {
hooks = append(hooks, h)
}
}
return hooks, nil
}