Support inhibit_login registration option

This commit is contained in:
Andrew Morgan 2018-06-29 15:37:17 +01:00
parent d2b349a75a
commit 1333cacb4c

View file

@ -16,7 +16,6 @@
package routing
import (
"context"
"crypto/hmac"
"crypto/sha1"
"encoding/json"
@ -116,7 +115,10 @@ type registerRequest struct {
InitialDisplayName *string `json:"initial_device_display_name"`
// Application services place Type in the root of their registration
// Prevent this user from logging in
InhibitLogin int `json:"inhibit_login"`
// Application Services place Type in the root of their registration
// request, whereas clients place it in the authDict struct.
Type authtypes.LoginType `json:"type"`
}
@ -163,9 +165,9 @@ func newUserInteractiveResponse(
// http://matrix.org/speculator/spec/HEAD/client_server/unstable.html#post-matrix-client-unstable-register
type registerResponse struct {
UserID string `json:"user_id"`
AccessToken string `json:"access_token"`
AccessToken string `json:"access_token,omitempty"`
HomeServer gomatrixserverlib.ServerName `json:"home_server"`
DeviceID string `json:"device_id"`
DeviceID string `json:"device_id,omitempty"`
}
// recaptchaResponse represents the HTTP response from a Google Recaptcha server
@ -552,8 +554,10 @@ func handleRegistrationFlow(
// If no error, application service was successfully validated.
// Don't need to worry about appending to registration stages as
// application service registration is entirely separate.
return completeRegistration(req.Context(), accountDB, deviceDB,
r.Username, "", appserviceID, r.InitialDisplayName)
return completeRegistration(
req, accountDB, deviceDB, r.Username, "", appserviceID,
r.InhibitLogin, r.InitialDisplayName,
)
case authtypes.LoginTypeDummy:
// there is nothing to do
@ -588,8 +592,10 @@ func checkAndCompleteFlow(
) util.JSONResponse {
if checkFlowCompleted(flow, cfg.Derived.Registration.Flows) {
// This flow was completed, registration can continue
return completeRegistration(req.Context(), accountDB, deviceDB,
r.Username, r.Password, "", r.InitialDisplayName)
return completeRegistration(
req, accountDB, deviceDB, r.Username, r.Password, "",
r.InhibitLogin, r.InitialDisplayName,
)
}
// There are still more stages to complete.
@ -639,10 +645,10 @@ func LegacyRegister(
return util.MessageResponse(http.StatusForbidden, "HMAC incorrect")
}
return completeRegistration(req.Context(), accountDB, deviceDB, r.Username, r.Password, "", nil)
return completeRegistration(req, accountDB, deviceDB, r.Username, r.Password, "", 0, nil)
case authtypes.LoginTypeDummy:
// there is nothing to do
return completeRegistration(req.Context(), accountDB, deviceDB, r.Username, r.Password, "", nil)
return completeRegistration(req, accountDB, deviceDB, r.Username, r.Password, "", 0, nil)
default:
return util.JSONResponse{
Code: http.StatusNotImplemented,
@ -681,11 +687,11 @@ func parseAndValidateLegacyLogin(req *http.Request, r *legacyRegisterRequest) *u
}
func completeRegistration(
ctx context.Context,
req *http.Request,
accountDB *accounts.Database,
deviceDB *devices.Database,
username, password, appserviceID string,
displayName *string,
inhibitLogin int, displayName *string,
) util.JSONResponse {
if username == "" {
return util.JSONResponse{
@ -701,7 +707,7 @@ func completeRegistration(
}
}
acc, err := accountDB.CreateAccount(ctx, username, password, appserviceID)
acc, err := accountDB.CreateAccount(req.Context(), username, password, appserviceID)
if err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
@ -714,6 +720,18 @@ func completeRegistration(
}
}
// Check whether inhibit_login option is set. If so, don't create an access
// token or a device for this user
if inhibitLogin != 0 {
return util.JSONResponse{
Code: http.StatusOK,
JSON: registerResponse{
UserID: userutil.MakeUserID(username, acc.ServerName),
HomeServer: acc.ServerName,
},
}
}
token, err := auth.GenerateAccessToken()
if err != nil {
return util.JSONResponse{
@ -722,8 +740,8 @@ func completeRegistration(
}
}
// // TODO: Use the device ID in the request.
dev, err := deviceDB.CreateDevice(ctx, username, nil, token, displayName)
// TODO: Use the device ID in the request.
dev, err := deviceDB.CreateDevice(req.Context(), username, nil, token, displayName)
if err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,