Skip to content

Commit

Permalink
fix: improve debugging output for registration hook and restructure f…
Browse files Browse the repository at this point in the history
…iles
  • Loading branch information
aeneasr committed Aug 25, 2020
1 parent dabac40 commit ec11775
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 25 deletions.
42 changes: 21 additions & 21 deletions selfservice/flow/registration/flow.go
Expand Up @@ -94,45 +94,45 @@ func NewFlow(exp time.Duration, csrf string, r *http.Request, ft flow.Type) *Flo
}
}

func (r *Flow) BeforeSave(_ *pop.Connection) error {
r.MethodsRaw = make([]FlowMethod, 0, len(r.Methods))
for _, m := range r.Methods {
r.MethodsRaw = append(r.MethodsRaw, *m)
func (f *Flow) BeforeSave(_ *pop.Connection) error {
f.MethodsRaw = make([]FlowMethod, 0, len(f.Methods))
for _, m := range f.Methods {
f.MethodsRaw = append(f.MethodsRaw, *m)
}
r.Methods = nil
f.Methods = nil
return nil
}

func (r *Flow) AfterCreate(c *pop.Connection) error {
return r.AfterFind(c)
func (f *Flow) AfterCreate(c *pop.Connection) error {
return f.AfterFind(c)
}

func (r *Flow) AfterUpdate(c *pop.Connection) error {
return r.AfterFind(c)
func (f *Flow) AfterUpdate(c *pop.Connection) error {
return f.AfterFind(c)
}

func (r *Flow) AfterFind(_ *pop.Connection) error {
r.Methods = make(FlowMethods)
for key := range r.MethodsRaw {
m := r.MethodsRaw[key] // required for pointer dereference
r.Methods[m.Method] = &m
func (f *Flow) AfterFind(_ *pop.Connection) error {
f.Methods = make(FlowMethods)
for key := range f.MethodsRaw {
m := f.MethodsRaw[key] // required for pointer dereference
f.Methods[m.Method] = &m
}
r.MethodsRaw = nil
f.MethodsRaw = nil
return nil
}

func (r Flow) TableName() string {
func (f Flow) TableName() string {
// This must be stay a value receiver, using a pointer receiver will cause issues with pop.
return "selfservice_registration_flows"
}

func (r *Flow) GetID() uuid.UUID {
return r.ID
func (f *Flow) GetID() uuid.UUID {
return f.ID
}

func (r *Flow) Valid() error {
if r.ExpiresAt.Before(time.Now()) {
return errors.WithStack(NewFlowExpiredError(time.Since(r.ExpiresAt)))
func (f *Flow) Valid() error {
if f.ExpiresAt.Before(time.Now()) {
return errors.WithStack(NewFlowExpiredError(time.Since(f.ExpiresAt)))
}
return nil
}
Expand Down
34 changes: 30 additions & 4 deletions selfservice/flow/registration/hook.go
@@ -1,15 +1,18 @@
package registration

import (
"errors"
"fmt"
"net/http"
"time"

"github.com/pkg/errors"

"github.com/ory/x/sqlcon"

"github.com/ory/kratos/driver/configuration"
"github.com/ory/kratos/identity"
"github.com/ory/kratos/schema"
"github.com/ory/kratos/selfservice/flow"
"github.com/ory/kratos/session"
"github.com/ory/kratos/x"
)
Expand Down Expand Up @@ -37,6 +40,14 @@ type (
}
)

func PostHookPostPersistExecutorNames(e []PostHookPostPersistExecutor) []string {
names := make([]string, len(e))
for k, ee := range e {
names[k] = fmt.Sprintf("%T", ee)
}
return names
}

func (f PreHookExecutorFunc) ExecuteRegistrationPreHook(w http.ResponseWriter, r *http.Request, a *Flow) error {
return f(w, r, a)
}
Expand All @@ -51,6 +62,7 @@ type (
executorDependencies interface {
identity.ManagementProvider
identity.ValidationProvider
session.PersistenceProvider
HooksProvider
x.LoggingProvider
x.WriterProvider
Expand Down Expand Up @@ -93,24 +105,38 @@ func (e *HookExecutor) PostRegistrationHook(w http.ResponseWriter, r *http.Reque
return err
}

e.d.Logger().
e.d.Audit().
WithRequest(r).
WithField("identity_id", i.ID).
Debug("A new identity has registered using self-service registration. Running post execution hooks.")
Info("A new identity has registered using self-service registration. Running post execution hooks.")

s := session.NewActiveSession(i, e.c, time.Now().UTC())
for _, executor := range e.d.PostRegistrationPostPersistHooks(ct) {
for k, executor := range e.d.PostRegistrationPostPersistHooks(ct) {
if err := executor.ExecutePostRegistrationPostPersistHook(w, r, a, s); err != nil {
if errors.Is(err, ErrHookAbortFlow) {
e.d.Logger().
WithRequest(r).
WithField("executor", fmt.Sprintf("%T", executor)).
WithField("executor_position", k).
WithField("executors", PostHookPostPersistExecutorNames(e.d.PostRegistrationPostPersistHooks(ct))).
WithField("identity_id", i.ID).
Debug("Post registration execution hooks aborted early.")
return nil
}
return err
}
}

e.d.Logger().
WithRequest(r).
WithField("identity_id", i.ID).
Debug("Post registration execution hooks completed successfully.")

if a.Type == flow.TypeAPI {
e.d.Writer().Write(w, r, &APIFlowResponse{Identity: i})
return nil
}

return x.SecureContentNegotiationRedirection(w, r, s.Declassify(), a.RequestURL,
e.d.Writer(), e.c, x.SecureRedirectOverrideDefaultReturnTo(e.c.SelfServiceFlowRegistrationReturnTo(ct.String())))
}
Expand Down
40 changes: 40 additions & 0 deletions selfservice/flow/registration/session.go
@@ -0,0 +1,40 @@
package registration

import (
"github.com/ory/kratos/identity"
"github.com/ory/kratos/session"
)

// The Response for Registration Flows via API
//
// swagger:model registrationViaApiResponse
type APIFlowResponse struct {
// The Session Token
//
// This field is only set when the session hook is configured as a post-registration hook.
//
// A session token is equivalent to a session cookie, but it can be sent in the HTTP Authorization
// Header:
//
// Authorization: bearer <session-token>
//
// The session token is only issued for API flows, not for Browser flows!
//
// required: true
Token string `json:"session_token,omitempty"`

// The Session
//
// This field is only set when the session hook is configured as a post-registration hook.
//
// The session contains information about the user, the session device, and so on.
// This is only available for API flows, not for Browser flows!
Session *session.Session `json:"session,omitempty"`

// The Identity
//
// The identity that just signed up.
//
// required: true
Identity *identity.Identity `json:"identity"`
}

0 comments on commit ec11775

Please sign in to comment.