Skip to content

Commit

Permalink
feat: support JSON payloads in password login flow
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Aug 6, 2020
1 parent 1776d58 commit dd32c23
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 18 deletions.
19 changes: 19 additions & 0 deletions selfservice/strategy/password/.schema/login.schema.json
@@ -0,0 +1,19 @@
{
"$id": "https://schemas.ory.sh/kratos/selfservice/strategy/password/login.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"password",
"identifier"
],
"properties": {
"password": {
"type": "string",
"minLength": 1
},
"identifier": {
"type": "string",
"minLength": 1
}
}
}
14 changes: 8 additions & 6 deletions selfservice/strategy/password/login.go
Expand Up @@ -7,6 +7,7 @@ import (
"net/url"

"github.com/julienschmidt/httprouter"
"github.com/ory/x/decoderx"
"github.com/pkg/errors"

"github.com/ory/herodot"
Expand Down Expand Up @@ -61,14 +62,15 @@ func (s *Strategy) handleLogin(w http.ResponseWriter, r *http.Request, _ httprou
}

var p LoginFormPayload
if err := r.ParseForm(); err != nil {
if err := s.hd.Decode(r, &p,
decoderx.HTTPFormDecoder(), decoderx.HTTPJSONDecoder(),
decoderx.MustHTTPRawJSONSchemaCompiler(loginSchema),
decoderx.HTTPDecoderSetIgnoreParseErrorsStrategy(decoderx.ParseErrorIgnore),
); err != nil {
s.handleLoginError(w, r, ar, errors.WithStack(herodot.ErrBadRequest.WithDebug(err.Error()).WithReasonf("Unable to parse HTTP form request: %s", err.Error())))
return
}

p.Identifier = r.PostForm.Get("identifier")
p.Password = r.PostForm.Get("password")

if len(p.Identifier) == 0 {
s.handleLoginError(w, r, ar, schema.NewRequiredError("#/identifier", "identifier"))
return
Expand Down Expand Up @@ -131,8 +133,8 @@ func (s *Strategy) PopulateLoginMethod(r *http.Request, sr *login.Request) error

action := urlx.CopyWithQuery(
urlx.AppendPaths(s.c.SelfPublicURL(), LoginPath),
url.Values{"request": {sr.ID.String()}},
)
url.Values{"request": {sr.ID.String()}})

f := &form.HTMLForm{
Action: action.String(),
Method: "POST",
Expand Down
8 changes: 4 additions & 4 deletions selfservice/strategy/password/login_test.go
Expand Up @@ -107,7 +107,7 @@ func TestLoginNew(t *testing.T) {
c.Jar, _ = cookiejar.New(&cookiejar.Options{})
}

u := ts.URL + login.BrowserLoginPath
u := ts.URL + login.BrowserInitPath
if force {
u = u + "?refresh=true"
}
Expand Down Expand Up @@ -309,20 +309,20 @@ func TestLoginNew(t *testing.T) {
c := &http.Client{Jar: jar}

t.Run("redirect to returnTS if refresh is missing", func(t *testing.T) {
res, err := c.Get(ts.URL + login.BrowserLoginPath)
res, err := c.Get(ts.URL + login.BrowserInitPath)
require.NoError(t, err)
require.EqualValues(t, http.StatusOK, res.StatusCode)
})

t.Run("show UI and hint at username", func(t *testing.T) {
res, err := c.Get(ts.URL + login.BrowserLoginPath + "?refresh=true")
res, err := c.Get(ts.URL + login.BrowserInitPath + "?refresh=true")
require.NoError(t, err)
require.EqualValues(t, http.StatusOK, res.StatusCode)

rid := res.Request.URL.Query().Get("request")
assert.NotEmpty(t, rid, "%s", res.Request.URL)

res, err = c.Get(ts.URL + login.BrowserLoginRequestsPath + "?request=" + rid)
res, err = c.Get(ts.URL + login.BrowserRequestsPath + "?request=" + rid)
require.NoError(t, err)
require.EqualValues(t, http.StatusOK, res.StatusCode)

Expand Down
15 changes: 9 additions & 6 deletions selfservice/strategy/password/strategy.go
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"strings"

"github.com/ory/x/decoderx"
"github.com/pkg/errors"
"gopkg.in/go-playground/validator.v9"

Expand Down Expand Up @@ -59,9 +60,10 @@ type registrationStrategyDependencies interface {
}

type Strategy struct {
c configuration.Provider
d registrationStrategyDependencies
v *validator.Validate
c configuration.Provider
d registrationStrategyDependencies
v *validator.Validate
hd *decoderx.HTTP
}

func (s *Strategy) CountActiveCredentials(cc map[identity.CredentialsType]identity.Credentials) (count int, err error) {
Expand All @@ -86,9 +88,10 @@ func NewStrategy(
c configuration.Provider,
) *Strategy {
return &Strategy{
c: c,
d: d,
v: validator.New(),
c: c,
d: d,
v: validator.New(),
hd: decoderx.NewHTTP(),
}
}

Expand Down
4 changes: 2 additions & 2 deletions selfservice/strategy/password/types.go
Expand Up @@ -11,8 +11,8 @@ type (

// LoginFormPayload is used to decode the login form payload.
LoginFormPayload struct {
Password string `form:"password"`
Identifier string `form:"identifier"`
Password string `form:"password" json:"password"`
Identifier string `form:"identifier" json:"identifier"`
}
)

Expand Down

0 comments on commit dd32c23

Please sign in to comment.