diff --git a/src/github.com/matrix-org/dendrite/clientapi/routing/register.go b/src/github.com/matrix-org/dendrite/clientapi/routing/register.go index 3e3a7c4c6..3a5cf25e8 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/routing/register.go +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/register.go @@ -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,