Skip to content

Commit

Permalink
selfservice/password: Remove request field and ensure method is set (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
zepatrik authored and aeneasr committed Jan 22, 2020
1 parent ede9c0e commit e035adc
Show file tree
Hide file tree
Showing 11 changed files with 41 additions and 40 deletions.
3 changes: 2 additions & 1 deletion cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
package cmd

import (
"github.com/ory/x/flagx"
"os"
"strconv"

"github.com/ory/x/flagx"

"github.com/spf13/cobra"

"github.com/ory/kratos/cmd/daemon"
Expand Down
6 changes: 3 additions & 3 deletions driver/configuration/provider_viper.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
)

type ViperProvider struct {
l logrus.FieldLogger
ss [][]byte
l logrus.FieldLogger
ss [][]byte
dev bool
}

Expand Down Expand Up @@ -74,7 +74,7 @@ const (

func NewViperProvider(l logrus.FieldLogger, dev bool) *ViperProvider {
return &ViperProvider{
l: l,
l: l,
dev: dev,
}
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/cenkalti/backoff v2.1.1+incompatible
github.com/coreos/go-oidc v2.1.0+incompatible
github.com/fsnotify/fsnotify v1.4.7
github.com/ghodss/yaml v1.0.0
github.com/go-errors/errors v1.0.1
github.com/go-openapi/errors v0.19.2
github.com/go-openapi/runtime v0.19.5
Expand Down
2 changes: 1 addition & 1 deletion selfservice/flow/login/request_method.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (c *RequestMethodConfig) Value() (driver.Value, error) {
}

func (c *RequestMethodConfig) UnmarshalJSON(data []byte) error {
c.RequestMethodConfigurator = new(form.HTMLForm)
c.RequestMethodConfigurator = form.NewHTMLForm("")
return json.Unmarshal(data, c.RequestMethodConfigurator)
}

Expand Down
2 changes: 1 addition & 1 deletion selfservice/flow/profile/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func NewRequest(exp time.Duration, r *http.Request, s *session.Session) *Request
RequestURL: source.String(),
IdentityID: s.Identity.ID,
Identity: s.Identity,
Form: new(form.HTMLForm),
Form: form.NewHTMLForm(""),
}
}

Expand Down
2 changes: 1 addition & 1 deletion selfservice/flow/registration/request_method.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (c *RequestMethodConfig) Value() (driver.Value, error) {
}

func (c *RequestMethodConfig) UnmarshalJSON(data []byte) error {
c.RequestMethodConfigurator = new(form.HTMLForm)
c.RequestMethodConfigurator = form.NewHTMLForm("")
return json.Unmarshal(data, c.RequestMethodConfigurator)
}

Expand Down
14 changes: 4 additions & 10 deletions selfservice/form/fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
)

// Fields contains multiple fields asdfasdf
// Fields contains multiple fields
//
// swagger:model formFields
type Fields map[string]Field
Expand All @@ -15,18 +15,12 @@ type Fields map[string]Field
// swagger:model formField
type Field struct {
// Name is the equivalent of <input name="{{.Name}}">
//
// Extensions:
// ---
// x-go-name: Asdffsdafsad
// x-go-asdffasd: Asdffsdafsad
// ---
Name string `json:"name"`
// Name is the equivalent of <input type="{{.Type}}">
// Type is the equivalent of <input type="{{.Type}}">
Type string `json:"type,omitempty"`
// Name is the equivalent of <input required="{{.Required}}">
// Required is the equivalent of <input required="{{.Required}}">
Required bool `json:"required,omitempty"`
// Name is the equivalent of <input value="{{.Value}}">
// Value is the equivalent of <input value="{{.Value}}">
Value interface{} `json:"value,omitempty" faker:"name"`
// Errors contains all validation errors this particular field has caused.
Errors []Error `json:"errors,omitempty"`
Expand Down
2 changes: 1 addition & 1 deletion selfservice/strategy/password/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ func (s *Strategy) handleLoginError(w http.ResponseWriter, r *http.Request, rr *
if method, ok := rr.Methods[identity.CredentialsTypePassword]; ok {
method.Config.Reset()
method.Config.SetValue("identifier", r.PostForm.Get("identifier"))
method.Config.SetValue("request", r.PostForm.Get("request"))
method.Config.SetCSRF(s.cg(r))
rr.Methods[identity.CredentialsTypePassword] = method
}
Expand Down Expand Up @@ -118,6 +117,7 @@ func (s *Strategy) PopulateLoginMethod(r *http.Request, sr *login.Request) error

f := &form.HTMLForm{
Action: action.String(),
Method: "POST",
Fields: form.Fields{
"identifier": {
Name: "identifier",
Expand Down
15 changes: 4 additions & 11 deletions selfservice/strategy/password/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func nlr(exp time.Duration) *login.Request {
Method: identity.CredentialsTypePassword,
Config: &login.RequestMethodConfig{
RequestMethodConfigurator: &form.HTMLForm{
Method: "POST",
Action: "/action",
Fields: form.Fields{
"identifier": {
Expand All @@ -62,12 +63,6 @@ func nlr(exp time.Duration) *login.Request {
Required: true,
Value: "anti-rf-token",
},
"request": {
Name: "request",
Type: "hidden",
Required: true,
Value: id.String(),
},
},
},
},
Expand All @@ -84,12 +79,9 @@ type loginStrategyDependencies interface {

func TestLogin(t *testing.T) {
var ensureFieldsExist = func(t *testing.T, body []byte) {
for _, k := range []string{"identifier",
checkFormContent(t, body, "identifier",
"password",
"csrf_token",
} {
assert.Equal(t, k, gjson.GetBytes(body, fmt.Sprintf("methods.password.config.fields.%s.name", k)).String())
}
"csrf_token")
}

type testCase struct {
Expand Down Expand Up @@ -304,6 +296,7 @@ func TestLogin(t *testing.T) {
Config: &login.RequestMethodConfig{
RequestMethodConfigurator: &password.RequestMethod{
HTMLForm: &form.HTMLForm{
Method: "POST",
Action: "/action",
Errors: []form.Error{{Message: "some error"}},
Fields: form.Fields{
Expand Down
7 changes: 0 additions & 7 deletions selfservice/strategy/password/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,7 @@ func (s *Strategy) handleRegistrationError(w http.ResponseWriter, r *http.Reques
}
}

method.Config.SetField("request", form.Field{
Name: "request",
Type: "hidden",
Required: true,
Value: r.PostForm.Get("request"),
})
method.Config.SetCSRF(s.cg(r))

rr.Methods[identity.CredentialsTypePassword] = method
}
}
Expand Down
27 changes: 23 additions & 4 deletions selfservice/strategy/password/registration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,31 @@ import (
"github.com/ory/kratos/x"
)

func checkFormContent(t *testing.T, body []byte, requiredFields ...string) {
fieldNameSet(t, body, requiredFields)
outdatedFieldsDoNotExist(t, body)
formMethodIsPOST(t, body)
}

// fieldNameSet checks if the fields have the right "name" set.
func fieldNameSet(t *testing.T, body []byte, fields ...string) {
func fieldNameSet(t *testing.T, body []byte, fields []string) {
for _, f := range fields {
fieldid := strings.Replace(f, ".", "\\.", -1) // we need to escape this because otherwise json path will interpret this as a nested object (it is not).
assert.Equal(t, gjson.GetBytes(body, fmt.Sprintf("methods.password.config.fields.%s.name", fieldid)).String(), f, "%s", body)
}
}

// checks if some keys are not set, this should be used to catch regression issues
func outdatedFieldsDoNotExist(t *testing.T, body []byte) {
for _, k := range []string{"request"} {
assert.Equal(t, false, gjson.GetBytes(body, fmt.Sprintf("methods.password.config.fields.%s", k)).Exists())
}
}

func formMethodIsPOST(t *testing.T, body []byte) {
assert.Equal(t, "POST", gjson.GetBytes(body, "methods.password.config.method").String())
}

func TestRegistration(t *testing.T) {
t.Run("case=registration", func(t *testing.T) {
_, reg := internal.NewRegistryDefault(t)
Expand Down Expand Up @@ -77,6 +94,7 @@ func TestRegistration(t *testing.T) {
Config: &registration.RequestMethodConfig{
RequestMethodConfigurator: password.RequestMethod{
HTMLForm: &form.HTMLForm{
Method: "POST",
Action: "/action",
Fields: form.Fields{
"password": {Name: "password", Type: "password", Required: true},
Expand Down Expand Up @@ -141,7 +159,7 @@ func TestRegistration(t *testing.T) {
assert.Contains(t, res.Request.URL.Path, "signup-ts")
assert.Equal(t, rr.ID.String(), gjson.GetBytes(body, "id").String(), "%s", body)
assert.Equal(t, "/action", gjson.GetBytes(body, "methods.password.config.action").String(), "%s", body)
fieldNameSet(t, body, "password", "csrf_token", "traits.username", "traits.foobar")
checkFormContent(t, body, "password", "csrf_token", "traits.username", "traits.foobar")
assert.Contains(t, gjson.GetBytes(body, "methods.password.config.fields.password.errors.0").String(), "data breaches and must no longer be used.", "%s", body)
})

Expand All @@ -154,7 +172,7 @@ func TestRegistration(t *testing.T) {
assert.Contains(t, res.Request.URL.Path, "signup-ts")
assert.Equal(t, rr.ID.String(), gjson.GetBytes(body, "id").String(), "%s", body)
assert.Equal(t, "/action", gjson.GetBytes(body, "methods.password.config.action").String(), "%s", body)
fieldNameSet(t, body, "password", "csrf_token", "traits.username", "traits.foobar")
checkFormContent(t, body, "password", "csrf_token", "traits.username", "traits.foobar")
assert.Contains(t, gjson.GetBytes(body, "methods.password.config.fields.traits\\.foobar.errors.0").String(), "foobar is required", "%s", body)
})

Expand Down Expand Up @@ -222,6 +240,7 @@ func TestRegistration(t *testing.T) {
Config: &registration.RequestMethodConfig{
RequestMethodConfigurator: &password.RequestMethod{
HTMLForm: &form.HTMLForm{
Method: "POST",
Action: "/action",
Errors: []form.Error{{Message: "some error"}},
Fields: form.Fields{
Expand All @@ -246,7 +265,7 @@ func TestRegistration(t *testing.T) {
assert.Contains(t, res.Request.URL.Path, "signup-ts")
assert.Equal(t, rr.ID.String(), gjson.GetBytes(body, "id").String(), "%s", body)
assert.Equal(t, "/action", gjson.GetBytes(body, "methods.password.config.action").String(), "%s", body)
fieldNameSet(t, body, "password", "csrf_token", "traits.username")
checkFormContent(t, body, "password", "csrf_token", "traits.username")

assert.Empty(t, gjson.GetBytes(body, "methods.password.config.fields.traits\\.foo.value"), "%s", body)
assert.Empty(t, gjson.GetBytes(body, "methods.password.config.fields.traits\\.foo.error"))
Expand Down

0 comments on commit e035adc

Please sign in to comment.