Skip to content

Commit

Permalink
feat: Redirect to new auth session on expired auth sessions (#230)
Browse files Browse the repository at this point in the history
Closes #96
  • Loading branch information
zepatrik committed Feb 6, 2020
1 parent d6f0794 commit b477ecd
Show file tree
Hide file tree
Showing 22 changed files with 193 additions and 81 deletions.
6 changes: 6 additions & 0 deletions docs/api.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,9 @@
{
"type": "object"
},
{
"type": "object"
},
{
"type": "object"
}
Expand Down Expand Up @@ -1081,6 +1084,9 @@
{
"type": "object"
},
{
"type": "object"
},
{
"type": "object"
}
Expand Down
21 changes: 20 additions & 1 deletion internal/httpclient/models/login_request_method_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 0 additions & 22 deletions internal/httpclient/models/registration_request_method.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion internal/httpclient/models/registration_request_method_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 16 additions & 6 deletions selfservice/errorx/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,31 @@ func (m *Manager) WithTokenGenerator(f func(r *http.Request) string) {
m.csrf = f
}

// ForwardError is a simple helper that saves all errors in the store and forwards the HTTP Request
// to the error url, appending the error ID.
func (m *Manager) ForwardError(ctx context.Context, w http.ResponseWriter, r *http.Request, errs ...error) {
// Create is a simple helper that saves all errors in the store and returns the
// error url, appending the error ID.
func (m *Manager) Create(ctx context.Context, w http.ResponseWriter, r *http.Request, errs ...error) (string, error) {
for _, err := range errs {
herodot.DefaultErrorLogger(m.d.Logger(), err).Errorf("An error occurred and is being forwarded to the error user interface.")
}

id, emerr := m.d.SelfServiceErrorPersister().Add(ctx, m.csrf(r), errs...)
if emerr != nil {
m.d.Writer().WriteError(w, r, emerr)
return
return "", emerr
}
q := url.Values{}
q.Set("error", id.String())

to := urlx.CopyWithQuery(m.c.ErrorURL(), q).String()
return urlx.CopyWithQuery(m.c.ErrorURL(), q).String(), nil
}

// Forward is a simple helper that saves all errors in the store and forwards the HTTP Request
// to the error url, appending the error ID.
func (m *Manager) Forward(ctx context.Context, w http.ResponseWriter, r *http.Request, errs ...error) {
to, err := m.Create(ctx, w, r, errs...)
if err != nil {
// Everything failed. Resort to standard error output.
m.d.Writer().WriteError(w, r, err)
return
}
http.Redirect(w, r, to, http.StatusFound)
}
6 changes: 3 additions & 3 deletions selfservice/flow/login/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (s *ErrorHandler) HandleLoginError(
Warn("Encountered login error.")

if rr == nil {
s.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
s.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
} else if x.IsJSONRequest(r) {
s.d.Writer().WriteError(w, r, err)
Expand All @@ -76,12 +76,12 @@ func (s *ErrorHandler) HandleLoginError(
}

if err := method.Config.ParseError(err); err != nil {
s.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
s.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}

if err := s.d.LoginRequestPersister().UpdateLoginRequest(r.Context(), rr.ID, ct, method); err != nil {
s.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
s.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}

Expand Down
14 changes: 9 additions & 5 deletions selfservice/flow/login/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (h *Handler) RegisterAdminRoutes(admin *x.RouterAdmin) {
admin.GET(BrowserLoginRequestsPath, h.adminFetchLoginRequest)
}

func (h *Handler) NewLoginRequest(w http.ResponseWriter, r *http.Request, redir func(request *Request) string) error {
func (h *Handler) NewLoginRequest(w http.ResponseWriter, r *http.Request, redir func(request *Request) (string, error)) error {
a := NewLoginRequest(h.c.SelfServiceLoginRequestLifespan(), h.csrf(r), r)
for _, s := range h.d.LoginStrategies() {
if err := s.PopulateLoginMethod(r, a); err != nil {
Expand All @@ -77,9 +77,13 @@ func (h *Handler) NewLoginRequest(w http.ResponseWriter, r *http.Request, redir
return err
}

to, err := redir(a)
if err != nil {
return err
}
http.Redirect(w,
r,
redir(a),
to,
http.StatusFound,
)

Expand All @@ -105,10 +109,10 @@ func (h *Handler) NewLoginRequest(w http.ResponseWriter, r *http.Request, redir
// 302: emptyResponse
// 500: genericError
func (h *Handler) initLoginRequest(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if err := h.NewLoginRequest(w, r, func(a *Request) string {
return urlx.CopyWithQuery(h.c.LoginURL(), url.Values{"request": {a.ID.String()}}).String()
if err := h.NewLoginRequest(w, r, func(a *Request) (string, error) {
return urlx.CopyWithQuery(h.c.LoginURL(), url.Values{"request": {a.ID.String()}}).String(), nil
}); err != nil {
h.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
h.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}
}
Expand Down
1 change: 1 addition & 0 deletions selfservice/flow/login/request_method.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type RequestMethodConfigurator interface {
form.ValueSetter
form.Resetter
form.CSRFSetter
form.ErrorAdder
}

// swagger:model loginRequestMethodConfig
Expand Down
2 changes: 1 addition & 1 deletion selfservice/flow/logout/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (h *Handler) logout(w http.ResponseWriter, r *http.Request, ps httprouter.P
_ = h.d.CSRFHandler().RegenerateToken(w, r)

if err := h.d.SessionManager().PurgeFromRequest(r.Context(), w, r); err != nil {
h.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
h.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}

Expand Down
6 changes: 3 additions & 3 deletions selfservice/flow/profile/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,20 @@ func (s *ErrorHandler) HandleProfileManagementError(
Warn("Encountered profile management error.")

if rr == nil {
s.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
s.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
} else if x.IsJSONRequest(r) {
s.d.Writer().WriteError(w, r, err)
return
}

if err := rr.Form.ParseError(err); err != nil {
s.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
s.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}

if err := s.d.ProfileRequestPersister().UpdateProfileRequest(r.Context(), rr); err != nil {
s.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
s.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}

Expand Down
8 changes: 4 additions & 4 deletions selfservice/flow/profile/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (h *Handler) RegisterAdminRoutes(admin *x.RouterAdmin) {
func (h *Handler) initUpdateProfile(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
s, err := h.d.SessionManager().FetchFromRequest(r.Context(), w, r)
if err != nil {
h.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
h.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}

Expand All @@ -111,15 +111,15 @@ func (h *Handler) initUpdateProfile(w http.ResponseWriter, r *http.Request, ps h

traitsSchema, err := h.c.IdentityTraitsSchemas().FindSchemaByID(s.Identity.TraitsSchemaID)
if err != nil {
h.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
h.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}
if err := a.Form.SortFields(traitsSchema.URL, "traits"); err != nil {
h.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
h.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}
if err := h.d.ProfileRequestPersister().CreateProfileRequest(r.Context(), a); err != nil {
h.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
h.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}

Expand Down
6 changes: 3 additions & 3 deletions selfservice/flow/registration/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (s *ErrorHandler) HandleRegistrationError(
Warn("Encountered login error.")

if rr == nil {
s.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
s.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
} else if x.IsJSONRequest(r) {
s.d.Writer().WriteError(w, r, err)
Expand All @@ -76,12 +76,12 @@ func (s *ErrorHandler) HandleRegistrationError(
}

if err := method.Config.ParseError(err); err != nil {
s.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
s.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}

if err := s.d.RegistrationRequestPersister().UpdateRegistrationRequest(r.Context(), rr.ID, ct, method); err != nil {
s.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
s.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}

Expand Down
14 changes: 9 additions & 5 deletions selfservice/flow/registration/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (h *Handler) RegisterAdminRoutes(admin *x.RouterAdmin) {
admin.GET(BrowserRegistrationRequestsPath, h.adminFetchRegistrationRequest)
}

func (h *Handler) NewRegistrationRequest(w http.ResponseWriter, r *http.Request, redir func(*Request) string) error {
func (h *Handler) NewRegistrationRequest(w http.ResponseWriter, r *http.Request, redir func(*Request) (string, error)) error {
a := NewRequest(h.c.SelfServiceRegistrationRequestLifespan(), h.csrf(r), r)
for _, s := range h.d.RegistrationStrategies() {
if err := s.PopulateRegistrationMethod(r, a); err != nil {
Expand All @@ -77,9 +77,13 @@ func (h *Handler) NewRegistrationRequest(w http.ResponseWriter, r *http.Request,
return err
}

to, err := redir(a)
if err != nil {
return err
}
http.Redirect(w,
r,
redir(a),
to,
http.StatusFound,
)

Expand All @@ -105,10 +109,10 @@ func (h *Handler) NewRegistrationRequest(w http.ResponseWriter, r *http.Request,
// 302: emptyResponse
// 500: genericError
func (h *Handler) initRegistrationRequest(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if err := h.NewRegistrationRequest(w, r, func(a *Request) string {
return urlx.CopyWithQuery(h.c.RegisterURL(), url.Values{"request": {a.ID.String()}}).String()
if err := h.NewRegistrationRequest(w, r, func(a *Request) (string, error) {
return urlx.CopyWithQuery(h.c.RegisterURL(), url.Values{"request": {a.ID.String()}}).String(), nil
}); err != nil {
h.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
h.d.SelfServiceErrorManager().Forward(r.Context(), w, r, err)
return
}
}
Expand Down
1 change: 1 addition & 0 deletions selfservice/flow/registration/request_method.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type RequestMethodConfigurator interface {
form.Resetter
form.CSRFSetter
form.FieldSorter
form.ErrorAdder
}

// swagger:model registrationRequestMethodConfig
Expand Down

0 comments on commit b477ecd

Please sign in to comment.