Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
143 lines
4.3 KiB
Go
143 lines
4.3 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) HookVerifyNewAddress() *hook.VerifyNewAddress {
|
|
if m.hookVerifyNewAddress == nil {
|
|
m.hookVerifyNewAddress = hook.NewVerifyNewAddress(m)
|
|
}
|
|
return m.hookVerifyNewAddress
|
|
}
|
|
|
|
func (m *RegistryDefault) HookNotifyPreviousAddresses(c *hook.NotifyPreviousAddressesConfig) *hook.NotifyPreviousAddresses {
|
|
return hook.NewNotifyPreviousAddresses(m, c)
|
|
}
|
|
|
|
func (m *RegistryDefault) WithHooks(hooks map[string]NewHookFn) {
|
|
m.injectedSelfserviceHooks = hooks
|
|
}
|
|
func (m *RegistryDefault) WithExtraHandlers(handlers []NewHandler) {
|
|
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 _, hookConfig := range configs {
|
|
switch hookConfig.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(hookConfig.Config, &cfg); err != nil {
|
|
m.l.WithError(err).WithField("raw_config", string(hookConfig.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)
|
|
}
|
|
case hook.KeyVerifyNewAddress:
|
|
if h, ok := any(m.HookVerifyNewAddress()).(T); ok {
|
|
hooks = append(hooks, h)
|
|
}
|
|
case hook.KeyNotifyPreviousAddresses:
|
|
cfg := &hook.NotifyPreviousAddressesConfig{}
|
|
if len(hookConfig.Config) > 0 {
|
|
if err := json.Unmarshal(hookConfig.Config, cfg); err != nil {
|
|
m.l.WithError(err).WithField("raw_config", string(hookConfig.Config)).Error("failed to unmarshal hook configuration, ignoring hook")
|
|
return nil, errors.WithStack(fmt.Errorf("failed to unmarshal notify_previous_addresses configuration for %s: %w", credentialsType, err))
|
|
}
|
|
}
|
|
if h, ok := any(m.HookNotifyPreviousAddresses(cfg)).(T); ok {
|
|
hooks = append(hooks, h)
|
|
}
|
|
default:
|
|
for name, newHook := range m.injectedSelfserviceHooks {
|
|
if name == hookConfig.Name {
|
|
if h, ok := newHook(hookConfig, m).(T); ok {
|
|
hooks = append(hooks, h)
|
|
}
|
|
continue allHooksLoop
|
|
}
|
|
}
|
|
m.l.
|
|
WithField("for", credentialsType).
|
|
WithField("hook", hookConfig.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
|
|
}
|