From 4cc6b9f8de8506e30cc112ad7163ea2b0083c16e Mon Sep 17 00:00:00 2001 From: "Andrew (anoa)" Date: Wed, 22 Nov 2017 17:22:48 -0800 Subject: [PATCH] Server is responding to Recaptcha requests. * We now send back the correct params for each registration stage Signed-off-by: Andrew (anoa) --- .../dendrite/clientapi/auth/authtypes/Flow.go | 2 +- .../dendrite/clientapi/routing/register.go | 51 +++++++++++++------ .../dendrite/common/config/config.go | 10 +++- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/clientapi/auth/authtypes/Flow.go b/src/github.com/matrix-org/dendrite/clientapi/auth/authtypes/Flow.go index 1fa681151..385e3dd99 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/auth/authtypes/Flow.go +++ b/src/github.com/matrix-org/dendrite/clientapi/auth/authtypes/Flow.go @@ -14,7 +14,7 @@ package authtypes -// AuthFlow represents one possible way that the client can authenticate a request. +// Flow represents one possible way that the client can authenticate a request. // http://matrix.org/speculator/spec/HEAD/client_server/unstable.html#user-interactive-authentication-api type Flow struct { Stages []LoginType `json:"stages"` 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 9234b946d..7030bbee0 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/routing/register.go +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/register.go @@ -101,9 +101,13 @@ type legacyRegisterRequest struct { Mac gomatrixserverlib.HexString `json:"mac"` } -func newUserInteractiveResponse(sessionID string, fs []authtypes.Flow) userInteractiveResponse { +func newUserInteractiveResponse( + sessionID string, + fs []authtypes.Flow, + params map[string]interface{}, +) userInteractiveResponse { return userInteractiveResponse{ - fs, sessions[sessionID], make(map[string]interface{}), sessionID, + fs, sessions[sessionID], params, sessionID, } } @@ -164,7 +168,6 @@ func validatePassword(password string) *util.JSONResponse { // validateRecaptcha returns an error response if the captcha response is invalid func validateRecaptcha( - req *http.Request, cfg *config.Dendrite, response string, clientip string, @@ -193,7 +196,7 @@ func validateRecaptcha( } // Close the request once we're finishing reading from it - defer resp.Body.Close() // noline: errcheck + defer resp.Body.Close() // nolint: errcheck // Grab the body of the response from the captcha server var r recaptchaResponse @@ -250,7 +253,8 @@ func Register( if r.Auth.Type == "" { return util.JSONResponse{ Code: 401, - JSON: newUserInteractiveResponse(sessionID, cfg.Derived.Flows), + JSON: newUserInteractiveResponse(sessionID, + cfg.Derived.Flows, cfg.Derived.Params), } } @@ -268,6 +272,19 @@ func Register( "session_id": r.Auth.Session, }).Info("Processing registration request") + return handleRegistrationFlow(req, r, sessionID, cfg, accountDB, deviceDB) +} + +// handleRegistrationFlow will direct and complete registration flow stages +// that the client has requested. +func handleRegistrationFlow( + req *http.Request, + r registerRequest, + sessionID string, + cfg *config.Dendrite, + accountDB *accounts.Database, + deviceDB *devices.Database, +) util.JSONResponse { // TODO: Shared secret registration (create new user scripts) // TODO: AS API registration // TODO: Enable registration config flag @@ -290,7 +307,8 @@ func Register( }).Info("Submitting recaptcha response") // Check given captcha response - if resErr = validateRecaptcha(req, cfg, r.Auth.Response, req.RemoteAddr); resErr != nil { + resErr := validateRecaptcha(cfg, r.Auth.Response, req.RemoteAddr) + if resErr != nil { return *resErr } @@ -340,7 +358,8 @@ func Register( // Return the flows and those that have been completed. return util.JSONResponse{ Code: 401, - JSON: newUserInteractiveResponse(sessionID, cfg.Derived.Flows), + JSON: newUserInteractiveResponse(sessionID, + cfg.Derived.Flows, cfg.Derived.Params), } } @@ -503,11 +522,11 @@ const ( letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits ) +var src = rand.NewSource(time.Now().UnixNano()) + // RandString returns a random string of characters with a given length. // Do note that it is not thread-safe in its current form. // https://stackoverflow.com/a/31832326 -var src = rand.NewSource(time.Now().UnixNano()) - func RandString(n int) string { b := make([]byte, n) @@ -536,20 +555,20 @@ func checkFlowsEqual(aFlow, bFlow authtypes.Flow) bool { return false } - a_copy := make([]string, len(a)) - b_copy := make([]string, len(b)) + aCopy := make([]string, len(a)) + bCopy := make([]string, len(b)) for loginType := range a { - a_copy = append(a_copy, string(loginType)) + aCopy = append(aCopy, string(loginType)) } for loginType := range b { - b_copy = append(b_copy, string(loginType)) + bCopy = append(bCopy, string(loginType)) } - sort.Strings(a_copy) - sort.Strings(b_copy) + sort.Strings(aCopy) + sort.Strings(bCopy) - return reflect.DeepEqual(a_copy, b_copy) + return reflect.DeepEqual(aCopy, bCopy) } type availableResponse struct { diff --git a/src/github.com/matrix-org/dendrite/common/config/config.go b/src/github.com/matrix-org/dendrite/common/config/config.go index 7f8faf5f6..7ed9ab7b6 100644 --- a/src/github.com/matrix-org/dendrite/common/config/config.go +++ b/src/github.com/matrix-org/dendrite/common/config/config.go @@ -208,6 +208,10 @@ type Dendrite struct { // Flows for registration. As long as they given flows only relies on config file options, // we can generate them on startup and store them until needed Flows []authtypes.Flow `json:"flows"` + + // Params for registration. Data that is returned to the client while registering and + // that which is necessary to complete certain registration flow stages + Params map[string]interface{} `json:"params"` } } @@ -335,11 +339,15 @@ func loadConfig( // the config file func (config *Dendrite) derive() { // Determine registrations flows based off config values + + config.Derived.Params = make(map[string]interface{}) + // TODO: Add email auth type // TODO: Add MSISDN auth type if config.Matrix.RecaptchaEnabled { - config.Derived.Flows = append(config.Derived.Flows, + config.Derived.Params[authtypes.LoginTypeRecaptcha] = map[string]string{"public_key": config.Matrix.RecaptchaPublicKey} + config.Derived.Flows = append(config.Derived.Flows, authtypes.Flow{[]authtypes.LoginType{authtypes.LoginTypeRecaptcha}}) } else { config.Derived.Flows = append(config.Derived.Flows,