Hacks for supporting Riot iOS (#1148)

* Join room body is optional

* Support deprecated login by user/password

* Implement dummy key upload endpoint

* Make a very determinate end to /messages if we hit the create event in back-pagination

* Linting
This commit is contained in:
Neil Alexander 2020-06-17 17:41:45 +01:00 committed by GitHub
parent 84a7881468
commit ddf1c8adf1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 42 deletions

View file

@ -43,9 +43,7 @@ func JoinRoomByIDOrAlias(
// If content was provided in the request then incude that
// in the request. It'll get used as a part of the membership
// event content.
if err := httputil.UnmarshalJSONRequest(req, &joinReq.Content); err != nil {
return *err
}
_ = httputil.UnmarshalJSONRequest(req, &joinReq.Content)
// Work out our localpart for the client profile request.
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)

View file

@ -47,6 +47,7 @@ type loginIdentifier struct {
type passwordRequest struct {
Identifier loginIdentifier `json:"identifier"`
User string `json:"user"` // deprecated in favour of identifier
Password string `json:"password"`
// Both DeviceID and InitialDisplayName can be omitted, or empty strings ("")
// Thus a pointer is needed to differentiate between the two
@ -81,6 +82,7 @@ func Login(
} else if req.Method == http.MethodPost {
var r passwordRequest
var acc *api.Account
var errJSON *util.JSONResponse
resErr := httputil.UnmarshalJSONRequest(req, &r)
if resErr != nil {
return *resErr
@ -93,30 +95,22 @@ func Login(
JSON: jsonerror.BadJSON("'user' must be supplied."),
}
}
util.GetLogger(req.Context()).WithField("user", r.Identifier.User).Info("Processing login request")
localpart, err := userutil.ParseUsernameParam(r.Identifier.User, &cfg.Matrix.ServerName)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.InvalidUsername(err.Error()),
}
}
acc, err = accountDB.GetAccountByPassword(req.Context(), localpart, r.Password)
if err != nil {
// Technically we could tell them if the user does not exist by checking if err == sql.ErrNoRows
// but that would leak the existence of the user.
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("username or password was incorrect, or the account does not exist"),
}
acc, errJSON = r.processUsernamePasswordLoginRequest(req, accountDB, cfg, r.Identifier.User)
if errJSON != nil {
return *errJSON
}
default:
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON("login identifier '" + r.Identifier.Type + "' not supported"),
// TODO: The below behaviour is deprecated but without it Riot iOS won't log in
if r.User != "" {
acc, errJSON = r.processUsernamePasswordLoginRequest(req, accountDB, cfg, r.User)
if errJSON != nil {
return *errJSON
}
} else {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON("login identifier '" + r.Identifier.Type + "' not supported"),
}
}
}
@ -163,3 +157,32 @@ func getDevice(
)
return
}
func (r *passwordRequest) processUsernamePasswordLoginRequest(
req *http.Request, accountDB accounts.Database,
cfg *config.Dendrite, username string,
) (acc *api.Account, errJSON *util.JSONResponse) {
util.GetLogger(req.Context()).WithField("user", username).Info("Processing login request")
localpart, err := userutil.ParseUsernameParam(username, &cfg.Matrix.ServerName)
if err != nil {
errJSON = &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.InvalidUsername(err.Error()),
}
return
}
acc, err = accountDB.GetAccountByPassword(req.Context(), localpart, r.Password)
if err != nil {
// Technically we could tell them if the user does not exist by checking if err == sql.ErrNoRows
// but that would leak the existence of the user.
errJSON = &util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("username or password was incorrect, or the account does not exist"),
}
return
}
return
}