From fbd54f6efbffcf491703ba0fb8744b41603c4b13 Mon Sep 17 00:00:00 2001 From: MTRNord Date: Sat, 7 Oct 2017 00:46:49 +0200 Subject: [PATCH] Add "GET /register/available?username=...." endpoint Signed-off-by: MTRNord --- .../dendrite/clientapi/readers/register.go | 65 +++++++++++++++++++ .../dendrite/clientapi/routing/routing.go | 4 ++ 2 files changed, 69 insertions(+) create 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 new file mode 100644 index 000000000..845b97722 --- /dev/null +++ b/src/github.com/matrix-org/dendrite/clientapi/readers/register.go @@ -0,0 +1,65 @@ +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"` +} + +func RegisterAvailable( + req *http.Request, + accountDB *accounts.Database, +) util.JSONResponse { + username := req.URL.Query().Get("username") + + if resErr := validate(username); resErr != nil { + return *resErr + } + + if _, resErr := accountDB.GetProfileByLocalpart(req.Context(), username); resErr == nil { + 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 b32ddf147..2fd59b999 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go +++ b/src/github.com/matrix-org/dendrite/clientapi/routing/routing.go @@ -131,6 +131,10 @@ func Setup( return writers.LegacyRegister(req, accountDB, deviceDB, &cfg) })).Methods("POST", "OPTIONS") + r0mux.Handle("/register/available", common.MakeExternalAPI("registerAvailable", func(req *http.Request) util.JSONResponse { + return readers.RegisterAvailable(req, accountDB) + })).Methods("GET", "OPTIONS") + r0mux.Handle("/directory/room/{roomAlias}", common.MakeAuthAPI("directory_room", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse { vars := mux.Vars(req)