mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-26 08:13:09 -06:00
Handle m.login.email.identity auth type in /register endpoint
This commit is contained in:
parent
080ae6a829
commit
e8161a9f39
|
|
@ -10,4 +10,5 @@ const (
|
|||
LoginTypeSharedSecret = "org.matrix.login.shared_secret"
|
||||
LoginTypeRecaptcha = "m.login.recaptcha"
|
||||
LoginTypeApplicationService = "m.login.application_service"
|
||||
LoginTypeEmailIdentity = "m.login.email.identity"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -150,9 +150,34 @@ type authDict struct {
|
|||
|
||||
// Recaptcha
|
||||
Response string `json:"response"`
|
||||
// m.login.email.identity and m.login.msisdn
|
||||
ThreePidCreds *threepidCreds `json:"threepidCreds"`
|
||||
// TODO: Lots of custom keys depending on the type
|
||||
}
|
||||
|
||||
type threepidCreds struct {
|
||||
Sid string `json:"sid"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
IdServer string `json:"id_server"`
|
||||
IdAccessToken string `json:"id_access_token"`
|
||||
}
|
||||
|
||||
func (c *threepidCreds) validate() *jsonerror.MatrixError {
|
||||
if c.Sid == "" {
|
||||
return jsonerror.BadJSON("sid field in threepidCreds is required")
|
||||
}
|
||||
if c.ClientSecret == "" {
|
||||
return jsonerror.BadJSON("client_secret in threepidCreds is required")
|
||||
}
|
||||
if c.IdServer == "" {
|
||||
return jsonerror.BadJSON("id_server in threepidCreds is required")
|
||||
}
|
||||
if c.IdAccessToken == "" {
|
||||
return jsonerror.BadJSON("id_access_token in threepidCreds is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// http://matrix.org/speculator/spec/HEAD/client_server/unstable.html#user-interactive-authentication-api
|
||||
type userInteractiveResponse struct {
|
||||
Flows []authtypes.Flow `json:"flows"`
|
||||
|
|
@ -310,6 +335,55 @@ func validateRecaptcha(
|
|||
return nil
|
||||
}
|
||||
|
||||
func validateEmailIdentity(
|
||||
ctx context.Context,
|
||||
cred *threepidCreds,
|
||||
// cfg *config.ClientAPI,
|
||||
) *util.JSONResponse {
|
||||
url := strings.Join([]string{
|
||||
cred.IdServer,
|
||||
"_matrix/identity/api/v1/3pid/getValidated3pid",
|
||||
}, "/")
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", url, nil)
|
||||
if err != nil {
|
||||
return &util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
}
|
||||
}
|
||||
q := req.URL.Query()
|
||||
q.Add("client_secret", cred.ClientSecret)
|
||||
q.Add("sid", cred.Sid)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return &util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.Unknown("validate 3pid on indentity server failed"),
|
||||
}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 404:
|
||||
return &util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden("provided sid or client_secret not found on identity server"),
|
||||
}
|
||||
case 400:
|
||||
return &util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden("session has not been validated"),
|
||||
}
|
||||
case 200:
|
||||
return nil
|
||||
default:
|
||||
return &util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UserIDIsWithinApplicationServiceNamespace checks to see if a given userID
|
||||
// falls within any of the namespaces of a given Application Service. If no
|
||||
// Application Service is given, it will check to see if it matches any
|
||||
|
|
@ -659,6 +733,24 @@ func handleRegistrationFlow(
|
|||
// Add Dummy to the list of completed registration stages
|
||||
AddCompletedSessionStage(sessionID, authtypes.LoginTypeDummy)
|
||||
|
||||
case authtypes.LoginTypeEmailIdentity:
|
||||
if r.Auth.ThreePidCreds == nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.BadJSON("threepidCreds not found in auth field"),
|
||||
}
|
||||
}
|
||||
if err := r.Auth.ThreePidCreds.validate(); err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: err,
|
||||
}
|
||||
}
|
||||
if err := validateEmailIdentity(req.Context(), r.Auth.ThreePidCreds); err != nil {
|
||||
return *err
|
||||
}
|
||||
AddCompletedSessionStage(sessionID, authtypes.LoginTypeApplicationService)
|
||||
|
||||
case "":
|
||||
// An empty auth type means that we want to fetch the available
|
||||
// flows. It can also mean that we want to register as an appservice
|
||||
|
|
|
|||
Loading…
Reference in a new issue