mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-29 01:33:10 -06:00
Cherry-pick Feature/login with email (#2)
This commit is contained in:
parent
1fbed4194a
commit
f290e722c3
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/clientapi/userutil"
|
"github.com/matrix-org/dendrite/clientapi/userutil"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/userapi/api"
|
"github.com/matrix-org/dendrite/userapi/api"
|
||||||
|
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -29,13 +30,16 @@ type GetAccountByPassword func(ctx context.Context, localpart, password string)
|
||||||
|
|
||||||
type PasswordRequest struct {
|
type PasswordRequest struct {
|
||||||
Login
|
Login
|
||||||
|
Address string `json:"address"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
|
Medium string `json:"medium"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoginTypePassword implements https://matrix.org/docs/spec/client_server/r0.6.1#password-based
|
// LoginTypePassword implements https://matrix.org/docs/spec/client_server/r0.6.1#password-based
|
||||||
type LoginTypePassword struct {
|
type LoginTypePassword struct {
|
||||||
GetAccountByPassword GetAccountByPassword
|
GetAccountByPassword GetAccountByPassword
|
||||||
Config *config.ClientAPI
|
Config *config.ClientAPI
|
||||||
|
AccountDB accounts.Database
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *LoginTypePassword) Name() string {
|
func (t *LoginTypePassword) Name() string {
|
||||||
|
|
@ -48,14 +52,36 @@ func (t *LoginTypePassword) Request() interface{} {
|
||||||
|
|
||||||
func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login, *util.JSONResponse) {
|
func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login, *util.JSONResponse) {
|
||||||
r := req.(*PasswordRequest)
|
r := req.(*PasswordRequest)
|
||||||
username := r.Username()
|
var username string
|
||||||
if username == "" {
|
var localpart string
|
||||||
return nil, &util.JSONResponse{
|
var err error
|
||||||
Code: http.StatusUnauthorized,
|
username = r.Username()
|
||||||
JSON: jsonerror.BadJSON("A username must be supplied."),
|
if username != "" {
|
||||||
|
localpart, err = userutil.ParseUsernameParam(username, &t.Config.Matrix.ServerName)
|
||||||
|
} else {
|
||||||
|
if r.Medium == "email" {
|
||||||
|
if r.Address != "" {
|
||||||
|
localpart, err = t.AccountDB.GetLocalpartForThreePID(ctx, r.Address, "email")
|
||||||
|
if localpart == "" {
|
||||||
|
return nil, &util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: jsonerror.Forbidden("email or password was incorrect, or the account does not exist"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.Login.User = localpart
|
||||||
|
} else {
|
||||||
|
return nil, &util.JSONResponse{
|
||||||
|
Code: http.StatusUnauthorized,
|
||||||
|
JSON: jsonerror.BadJSON("'address' must be supplied."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, &util.JSONResponse{
|
||||||
|
Code: http.StatusUnauthorized,
|
||||||
|
JSON: jsonerror.BadJSON("'user' must be supplied."),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
localpart, err := userutil.ParseUsernameParam(username, &t.Config.Matrix.ServerName)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &util.JSONResponse{
|
return nil, &util.JSONResponse{
|
||||||
Code: http.StatusUnauthorized,
|
Code: http.StatusUnauthorized,
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ func Login(
|
||||||
typePassword := auth.LoginTypePassword{
|
typePassword := auth.LoginTypePassword{
|
||||||
GetAccountByPassword: accountDB.GetAccountByPassword,
|
GetAccountByPassword: accountDB.GetAccountByPassword,
|
||||||
Config: cfg,
|
Config: cfg,
|
||||||
|
AccountDB: accountDB,
|
||||||
}
|
}
|
||||||
r := typePassword.Request()
|
r := typePassword.Request()
|
||||||
resErr := httputil.UnmarshalJSONRequest(req, r)
|
resErr := httputil.UnmarshalJSONRequest(req, r)
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,12 @@ type EmailAssociationRequest struct {
|
||||||
Secret string `json:"client_secret"`
|
Secret string `json:"client_secret"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
SendAttempt int `json:"send_attempt"`
|
SendAttempt int `json:"send_attempt"`
|
||||||
|
NextLink string `json:"next_link"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmailAssociationCheckRequest represents the request defined at https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-account-3pid
|
// EmailAssociationCheckRequest represents the request defined at https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-account-3pid
|
||||||
type EmailAssociationCheckRequest struct {
|
type EmailAssociationCheckRequest struct {
|
||||||
Creds Credentials `json:"threePidCreds"`
|
Creds Credentials `json:"three_pid_creds"`
|
||||||
Bind bool `json:"bind"`
|
Bind bool `json:"bind"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,6 +67,7 @@ func CreateSession(
|
||||||
data.Add("client_secret", req.Secret)
|
data.Add("client_secret", req.Secret)
|
||||||
data.Add("email", req.Email)
|
data.Add("email", req.Email)
|
||||||
data.Add("send_attempt", strconv.Itoa(req.SendAttempt))
|
data.Add("send_attempt", strconv.Itoa(req.SendAttempt))
|
||||||
|
data.Add("next_link", req.NextLink)
|
||||||
|
|
||||||
request, err := http.NewRequest(http.MethodPost, postURL, strings.NewReader(data.Encode()))
|
request, err := http.NewRequest(http.MethodPost, postURL, strings.NewReader(data.Encode()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -81,7 +83,7 @@ func CreateSession(
|
||||||
|
|
||||||
// Error if the status isn't OK
|
// Error if the status isn't OK
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return "", fmt.Errorf("could not create a session on the server %s", req.IDServer)
|
return "", fmt.Errorf("Could not create a session on the server %s, got status code: %d", req.IDServer, resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the SID from the response and return it
|
// Extract the SID from the response and return it
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,9 @@ client_api:
|
||||||
turn_username: ""
|
turn_username: ""
|
||||||
turn_password: ""
|
turn_password: ""
|
||||||
|
|
||||||
|
# Whether login by email is enabled .
|
||||||
|
email_login: true
|
||||||
|
|
||||||
# Settings for rate-limited endpoints. Rate limiting will kick in after the
|
# Settings for rate-limited endpoints. Rate limiting will kick in after the
|
||||||
# threshold number of "slots" have been taken by requests from a specific
|
# threshold number of "slots" have been taken by requests from a specific
|
||||||
# host. Each "slot" will be released after the cooloff time in milliseconds.
|
# host. Each "slot" will be released after the cooloff time in milliseconds.
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ type ClientAPI struct {
|
||||||
InternalAPI InternalAPIOptions `yaml:"internal_api"`
|
InternalAPI InternalAPIOptions `yaml:"internal_api"`
|
||||||
ExternalAPI ExternalAPIOptions `yaml:"external_api"`
|
ExternalAPI ExternalAPIOptions `yaml:"external_api"`
|
||||||
|
|
||||||
|
EmailLogin bool `yaml:"email_login"`
|
||||||
|
|
||||||
// If set disables new users from registering (except via shared
|
// If set disables new users from registering (except via shared
|
||||||
// secrets)
|
// secrets)
|
||||||
RegistrationDisabled bool `yaml:"registration_disabled"`
|
RegistrationDisabled bool `yaml:"registration_disabled"`
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue