Skip to content

Commit f290e72

Browse files
committed
Cherry-pick Feature/login with email (matrix-org#2)
1 parent 1fbed41 commit f290e72

File tree

5 files changed

+42
-8
lines changed

5 files changed

+42
-8
lines changed

clientapi/auth/password.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,24 @@ import (
2222
"github.com/matrix-org/dendrite/clientapi/userutil"
2323
"github.com/matrix-org/dendrite/setup/config"
2424
"github.com/matrix-org/dendrite/userapi/api"
25+
"github.com/matrix-org/dendrite/userapi/storage/accounts"
2526
"github.com/matrix-org/util"
2627
)
2728

2829
type GetAccountByPassword func(ctx context.Context, localpart, password string) (*api.Account, error)
2930

3031
type PasswordRequest struct {
3132
Login
33+
Address string `json:"address"`
3234
Password string `json:"password"`
35+
Medium string `json:"medium"`
3336
}
3437

3538
// LoginTypePassword implements https://matrix.org/docs/spec/client_server/r0.6.1#password-based
3639
type LoginTypePassword struct {
3740
GetAccountByPassword GetAccountByPassword
3841
Config *config.ClientAPI
42+
AccountDB accounts.Database
3943
}
4044

4145
func (t *LoginTypePassword) Name() string {
@@ -48,14 +52,36 @@ func (t *LoginTypePassword) Request() interface{} {
4852

4953
func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login, *util.JSONResponse) {
5054
r := req.(*PasswordRequest)
51-
username := r.Username()
52-
if username == "" {
53-
return nil, &util.JSONResponse{
54-
Code: http.StatusUnauthorized,
55-
JSON: jsonerror.BadJSON("A username must be supplied."),
55+
var username string
56+
var localpart string
57+
var err error
58+
username = r.Username()
59+
if username != "" {
60+
localpart, err = userutil.ParseUsernameParam(username, &t.Config.Matrix.ServerName)
61+
} else {
62+
if r.Medium == "email" {
63+
if r.Address != "" {
64+
localpart, err = t.AccountDB.GetLocalpartForThreePID(ctx, r.Address, "email")
65+
if localpart == "" {
66+
return nil, &util.JSONResponse{
67+
Code: http.StatusForbidden,
68+
JSON: jsonerror.Forbidden("email or password was incorrect, or the account does not exist"),
69+
}
70+
}
71+
r.Login.User = localpart
72+
} else {
73+
return nil, &util.JSONResponse{
74+
Code: http.StatusUnauthorized,
75+
JSON: jsonerror.BadJSON("'address' must be supplied."),
76+
}
77+
}
78+
} else {
79+
return nil, &util.JSONResponse{
80+
Code: http.StatusUnauthorized,
81+
JSON: jsonerror.BadJSON("'user' must be supplied."),
82+
}
5683
}
5784
}
58-
localpart, err := userutil.ParseUsernameParam(username, &t.Config.Matrix.ServerName)
5985
if err != nil {
6086
return nil, &util.JSONResponse{
6187
Code: http.StatusUnauthorized,

clientapi/routing/login.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func Login(
6868
typePassword := auth.LoginTypePassword{
6969
GetAccountByPassword: accountDB.GetAccountByPassword,
7070
Config: cfg,
71+
AccountDB: accountDB,
7172
}
7273
r := typePassword.Request()
7374
resErr := httputil.UnmarshalJSONRequest(req, r)

clientapi/threepid/threepid.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ type EmailAssociationRequest struct {
3333
Secret string `json:"client_secret"`
3434
Email string `json:"email"`
3535
SendAttempt int `json:"send_attempt"`
36+
NextLink string `json:"next_link"`
3637
}
3738

3839
// EmailAssociationCheckRequest represents the request defined at https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-account-3pid
3940
type EmailAssociationCheckRequest struct {
40-
Creds Credentials `json:"threePidCreds"`
41+
Creds Credentials `json:"three_pid_creds"`
4142
Bind bool `json:"bind"`
4243
}
4344

@@ -66,6 +67,7 @@ func CreateSession(
6667
data.Add("client_secret", req.Secret)
6768
data.Add("email", req.Email)
6869
data.Add("send_attempt", strconv.Itoa(req.SendAttempt))
70+
data.Add("next_link", req.NextLink)
6971

7072
request, err := http.NewRequest(http.MethodPost, postURL, strings.NewReader(data.Encode()))
7173
if err != nil {
@@ -81,7 +83,7 @@ func CreateSession(
8183

8284
// Error if the status isn't OK
8385
if resp.StatusCode != http.StatusOK {
84-
return "", fmt.Errorf("could not create a session on the server %s", req.IDServer)
86+
return "", fmt.Errorf("Could not create a session on the server %s, got status code: %d", req.IDServer, resp.StatusCode)
8587
}
8688

8789
// Extract the SID from the response and return it

dendrite-config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ client_api:
170170
turn_username: ""
171171
turn_password: ""
172172

173+
# Whether login by email is enabled .
174+
email_login: true
175+
173176
# Settings for rate-limited endpoints. Rate limiting will kick in after the
174177
# threshold number of "slots" have been taken by requests from a specific
175178
# host. Each "slot" will be released after the cooloff time in milliseconds.

setup/config/config_clientapi.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ type ClientAPI struct {
1212
InternalAPI InternalAPIOptions `yaml:"internal_api"`
1313
ExternalAPI ExternalAPIOptions `yaml:"external_api"`
1414

15+
EmailLogin bool `yaml:"email_login"`
16+
1517
// If set disables new users from registering (except via shared
1618
// secrets)
1719
RegistrationDisabled bool `yaml:"registration_disabled"`

0 commit comments

Comments
 (0)