Skip to content

Commit

Permalink
ss/profile: Use request ID as query param everywhere (#202)
Browse files Browse the repository at this point in the history
Closes #190
  • Loading branch information
aeneasr authored Jan 30, 2020
1 parent a392027 commit ed32b14
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 21 deletions.
44 changes: 25 additions & 19 deletions selfservice/flow/profile/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@ func (h *Handler) initUpdateProfile(w http.ResponseWriter, r *http.Request, ps h
}

a := NewRequest(h.c.SelfServiceProfileRequestLifespan(), r, s)
a.Form = form.NewHTMLFormFromJSON(urlx.AppendPaths(h.c.SelfPublicURL(), BrowserProfileUpdatePath).String(), json.RawMessage(s.Identity.Traits), "traits")
a.Form = form.NewHTMLFormFromJSON(urlx.CopyWithQuery(
urlx.AppendPaths(h.c.SelfPublicURL(), BrowserProfileUpdatePath),
url.Values{"request": {a.ID.String()}},
).String(), json.RawMessage(s.Identity.Traits), "traits")
if err := h.d.ProfileRequestPersister().CreateProfileRequest(r.Context(), a); err != nil {
h.d.SelfServiceErrorManager().ForwardError(r.Context(), w, r, err)
return
Expand Down Expand Up @@ -157,12 +160,6 @@ func (h *Handler) fetchUpdateProfileRequest(w http.ResponseWriter, r *http.Reque
return
}

ar.Form.SetField("request", form.Field{
Name: "request",
Type: "hidden",
Required: true,
Value: rid,
})
ar.Form.SetCSRF(nosurf.Token(r))
sort.Sort(ar.Form.Fields)
h.d.Writer().Write(w, r, ar)
Expand All @@ -171,6 +168,13 @@ func (h *Handler) fetchUpdateProfileRequest(w http.ResponseWriter, r *http.Reque
// swagger:parameters completeSelfServiceBrowserProfileManagementFlow
// nolint:deadcode,unused
type completeProfileManagementParameters struct {
// Request is the request ID.
//
// type: string
// required: true
// in: query
Request uuid.UUID `json:"request"`

// in: body
// required: true
Body completeSelfServiceBrowserProfileManagementFlowPayload
Expand All @@ -185,12 +189,6 @@ type completeSelfServiceBrowserProfileManagementFlowPayload struct {
// format: binary
// required: true
Traits json.RawMessage `json:"traits"`

// Request is the request ID.
//
// type: string
// required: true
Request uuid.UUID `json:"request"`
}

// swagger:route POST /self-service/browser/flows/profile/update public completeSelfServiceBrowserProfileManagementFlow
Expand Down Expand Up @@ -240,12 +238,13 @@ func (h *Handler) completeProfileManagementFlow(w http.ResponseWriter, r *http.R
return
}

if x.IsZeroUUID(p.Request) {
rid := r.URL.Query().Get("request")
if len(rid) == 0 {
h.handleProfileManagementError(w, r, nil, s.Identity.Traits, errors.WithStack(herodot.ErrBadRequest.WithReasonf("The request query parameter is missing.")))
return
}

ar, err := h.d.ProfileRequestPersister().GetProfileRequest(r.Context(), p.Request)
ar, err := h.d.ProfileRequestPersister().GetProfileRequest(r.Context(), x.ParseUUID(rid))
if err != nil {
h.handleProfileManagementError(w, r, nil, s.Identity.Traits, err)
return
Expand Down Expand Up @@ -307,12 +306,15 @@ func (h *Handler) completeProfileManagementFlow(w http.ResponseWriter, r *http.R
return
}

action := urlx.CopyWithQuery(
urlx.AppendPaths(h.c.SelfPublicURL(), BrowserProfileUpdatePath),
url.Values{"request": {ar.ID.String()}},
)
ar.Form.Reset()
ar.UpdateSuccessful = true
for _, field := range form.NewHTMLFormFromJSON("", json.RawMessage(i.Traits), "traits").Fields {
for _, field := range form.NewHTMLFormFromJSON(action.String(), json.RawMessage(i.Traits), "traits").Fields {
ar.Form.SetField(field.Name, field)
}
ar.Form.SetValue("request", r.Form.Get("request"))
ar.Form.SetCSRF(nosurf.Token(r))
sort.Sort(ar.Form.Fields)

Expand All @@ -331,15 +333,19 @@ func (h *Handler) completeProfileManagementFlow(w http.ResponseWriter, r *http.R
// during a profile management request.
func (h *Handler) handleProfileManagementError(w http.ResponseWriter, r *http.Request, rr *Request, traits identity.Traits, err error) {
if rr != nil {
action := urlx.CopyWithQuery(
urlx.AppendPaths(h.c.SelfPublicURL(), BrowserProfileUpdatePath),
url.Values{"request": {rr.ID.String()}},
)

rr.Form.Reset()
rr.UpdateSuccessful = false

if traits != nil {
for _, field := range form.NewHTMLFormFromJSON("", json.RawMessage(traits), "traits").Fields {
for _, field := range form.NewHTMLFormFromJSON(action.String(), json.RawMessage(traits), "traits").Fields {
rr.Form.SetField(field.Name, field)
}
}
rr.Form.SetValue("request", r.Form.Get("request"))
rr.Form.SetCSRF(nosurf.Token(r))
sort.Sort(rr.Form.Fields)
}
Expand Down
3 changes: 1 addition & 2 deletions selfservice/flow/profile/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,9 @@ func TestUpdateProfile(t *testing.T) {
require.True(t, found)

assert.Equal(t, &models.Form{
Action: kratos.URL + profile.BrowserProfileUpdatePath,
Action: kratos.URL + profile.BrowserProfileUpdatePath + "?request=" + rid,
Method: "POST",
Fields: models.FormFields{
&models.FormField{Name: "request", Required: true, Type: "hidden", Value: rid},
&models.FormField{Name: "traits.booly", Required: false, Type: "checkbox", Value: false},
&models.FormField{Name: "traits.email", Required: false, Type: "text", Value: "john@doe.com"},
&models.FormField{Name: "traits.numby", Required: false, Type: "number", Value: json.Number("2.5")},
Expand Down

0 comments on commit ed32b14

Please sign in to comment.