From 9da9657cded496e5c52a81c3f35c2df5da3425eb Mon Sep 17 00:00:00 2001 From: MTRNord Date: Sat, 7 Oct 2017 23:08:40 +0200 Subject: [PATCH] Move RegisterAvailable function from readers to writers Signed-off-by: MTRNord --- .../dendrite/clientapi/readers/register.go | 73 ----------------- .../dendrite/clientapi/routing/routing.go | 2 +- .../dendrite/clientapi/writers/register.go | 80 +++++++++++++++---- 3 files changed, 66 insertions(+), 89 deletions(-) delete mode 100644 src/github.com/matrix-org/dendrite/clientapi/readers/register.go diff --git a/src/github.com/matrix-org/dendrite/clientapi/readers/register.go b/src/github.com/matrix-org/dendrite/clientapi/readers/register.go deleted file mode 100644 index c0a67f799..000000000 --- a/src/github.com/matrix-org/dendrite/clientapi/readers/register.go +++ /dev/null @@ -1,73 +0,0 @@ -package readers - -import ( - "fmt" - "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" - "github.com/matrix-org/dendrite/clientapi/jsonerror" - "github.com/matrix-org/util" - "net/http" - "regexp" -) - -const ( - maxUsernameLength = 254 // http://matrix.org/speculator/spec/HEAD/intro.html#user-identifiers TODO account for domain -) - -var validUsernameRegex = regexp.MustCompile(`^[0-9a-zA-Z_\-./]+$`) - -func validate(username string) *util.JSONResponse { - if len(username) > maxUsernameLength { - return &util.JSONResponse{ - Code: 400, - JSON: jsonerror.BadJSON(fmt.Sprintf("'username' >%d characters", maxUsernameLength)), - } - } else if !validUsernameRegex.MatchString(username) { - return &util.JSONResponse{ - Code: 400, - JSON: jsonerror.InvalidUsername("User ID can only contain characters a-z, 0-9, or '_-./'"), - } - } else if username[0] == '_' { // Regex checks its not a zero length string - return &util.JSONResponse{ - Code: 400, - JSON: jsonerror.InvalidUsername("User ID can't start with a '_'"), - } - } - return nil -} - -type availableResponse struct { - Available bool `json:"available"` -} - -// RegisterAvailable checks if the username is already taken or invalid -func RegisterAvailable( - req *http.Request, - accountDB *accounts.Database, -) util.JSONResponse { - username := req.URL.Query().Get("username") - - if resErr := validate(username); resErr != nil { - return *resErr - } - - availability, availabilityErr := accountDB.CheckAccountAvailability(req.Context(), username) - if availabilityErr != nil { - return util.JSONResponse{ - Code: 500, - JSON: jsonerror.Unknown("failed to check availability: " + availabilityErr.Error()), - } - } - if !availability { - return util.JSONResponse{ - Code: 400, - JSON: jsonerror.InvalidUsername("A different user ID has already been registered for this session"), - } - } - - return util.JSONResponse{ - Code: 200, - JSON: availableResponse{ - Available: true, - }, - } -} diff --git a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go index 858a57ab9..00bdd15f4 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go @@ -132,7 +132,7 @@ func Setup( })).Methods("POST", "OPTIONS") r0mux.Handle("/register/available", common.MakeExternalAPI("registerAvailable", func(req *http.Request) util.JSONResponse { - return readers.RegisterAvailable(req, accountDB) + return writers.RegisterAvailable(req, accountDB) })).Methods("GET") r0mux.Handle("/directory/room/{roomAlias}", diff --git a/src/github.com/matrix-org/dendrite/clientapi/writers/register.go b/src/github.com/matrix-org/dendrite/clientapi/writers/register.go index 8519c9a1f..84227d155 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/writers/register.go +++ b/src/github.com/matrix-org/dendrite/clientapi/writers/register.go @@ -91,24 +91,14 @@ type registerResponse struct { DeviceID string `json:"device_id"` } -// Validate returns an error response if the username/password are invalid -func validate(username, password string) *util.JSONResponse { +// validateUserName returns an error response if the username is invalid +func validateUserName(username string) *util.JSONResponse { // https://github.com/matrix-org/synapse/blob/v0.20.0/synapse/rest/client/v2_alpha/register.py#L161 - if len(password) > maxPasswordLength { - return &util.JSONResponse{ - Code: 400, - JSON: jsonerror.BadJSON(fmt.Sprintf("'password' >%d characters", maxPasswordLength)), - } - } else if len(username) > maxUsernameLength { + if len(username) > maxUsernameLength { return &util.JSONResponse{ Code: 400, JSON: jsonerror.BadJSON(fmt.Sprintf("'username' >%d characters", maxUsernameLength)), } - } else if len(password) > 0 && len(password) < minPasswordLength { - return &util.JSONResponse{ - Code: 400, - JSON: jsonerror.WeakPassword(fmt.Sprintf("password too weak: min %d chars", minPasswordLength)), - } } else if !validUsernameRegex.MatchString(username) { return &util.JSONResponse{ Code: 400, @@ -123,6 +113,23 @@ func validate(username, password string) *util.JSONResponse { return nil } +// validatePassword returns an error response if the password is invalid +func validatePassword(password string) *util.JSONResponse { + // https://github.com/matrix-org/synapse/blob/v0.20.0/synapse/rest/client/v2_alpha/register.py#L161 + if len(password) > maxPasswordLength { + return &util.JSONResponse{ + Code: 400, + JSON: jsonerror.BadJSON(fmt.Sprintf("'password' >%d characters", maxPasswordLength)), + } + } else if len(password) > 0 && len(password) < minPasswordLength { + return &util.JSONResponse{ + Code: 400, + JSON: jsonerror.WeakPassword(fmt.Sprintf("password too weak: min %d chars", minPasswordLength)), + } + } + return nil +} + // Register processes a /register request. http://matrix.org/speculator/spec/HEAD/client_server/unstable.html#post-matrix-client-unstable-register func Register( req *http.Request, @@ -149,7 +156,10 @@ func Register( } } - if resErr = validate(r.Username, r.Password); resErr != nil { + if resErr = validateUserName(r.Username); resErr != nil { + return *resErr + } + if resErr = validatePassword(r.Password); resErr != nil { return *resErr } @@ -209,7 +219,10 @@ func LegacyRegister( if resErr != nil { return *resErr } - if resErr = validate(r.Username, r.Password); resErr != nil { + if resErr = validateUserName(r.Username); resErr != nil { + return *resErr + } + if resErr = validatePassword(r.Password); resErr != nil { return *resErr } @@ -344,3 +357,40 @@ func isValidMacLogin( return hmac.Equal(givenMac, expectedMAC), nil } + +type availableResponse struct { + Available bool `json:"available"` +} + +// RegisterAvailable checks if the username is already taken or invalid +func RegisterAvailable( + req *http.Request, + accountDB *accounts.Database, +) util.JSONResponse { + username := req.URL.Query().Get("username") + + if err := validateUserName(username); err != nil { + return *err + } + + availability, availabilityErr := accountDB.CheckAccountAvailability(req.Context(), username) + if availabilityErr != nil { + return util.JSONResponse{ + Code: 500, + JSON: jsonerror.Unknown("failed to check availability: " + availabilityErr.Error()), + } + } + if !availability { + return util.JSONResponse{ + Code: 400, + JSON: jsonerror.InvalidUsername("A different user ID has already been registered for this session"), + } + } + + return util.JSONResponse{ + Code: 200, + JSON: availableResponse{ + Available: true, + }, + } +}