diff --git a/clientapi/routing/register.go b/clientapi/routing/register.go index d0f36a6fd..4d9c9d2b7 100644 --- a/clientapi/routing/register.go +++ b/clientapi/routing/register.go @@ -22,6 +22,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/matrix-org/gomatrixserverlib/tokens" "io/ioutil" "net/http" "net/url" @@ -449,6 +450,9 @@ func Register( if resErr != nil { return *resErr } + if req.URL.Query().Get("kind") == "guest" { + return handleGuestRegistration(req, r, cfg, accountDB, deviceDB) + } // Retrieve or generate the sessionID sessionID := r.Auth.Session @@ -505,6 +509,61 @@ func Register( return handleRegistrationFlow(req, r, sessionID, cfg, accountDB, deviceDB) } +func handleGuestRegistration( + req *http.Request, + r registerRequest, + cfg *config.Dendrite, + accountDB *accounts.Database, + deviceDB *devices.Database, +) util.JSONResponse { + + //Generate numeric local part for guest user + id, err := accountDB.GetNewNumericLocalpart(req.Context()) + if err != nil { + return httputil.LogThenError(req, err) + } + + localpart := strconv.FormatInt(id, 10) + acc, err := accountDB.CreateAccount(req.Context(), localpart, "", "") + if err != nil { + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: jsonerror.Unknown("failed to create account: " + err.Error()), + } + } + //we don't allow guests to specify their own device_id + deviceId := "guest_device" + + token, err := tokens.GenerateLoginToken(tokens.TokenOptions{ + ServerPrivateKey: cfg.Matrix.PrivateKey.Seed(), + ServerName: string(acc.ServerName), + UserID: acc.UserID, + }) + + if err != nil { + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: jsonerror.Unknown("Failed to generate access token"), + } + } + dev, err := deviceDB.CreateDevice(req.Context(), acc.Localpart, &deviceId, token, r.InitialDisplayName) + if err != nil { + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: jsonerror.Unknown("failed to create device: " + err.Error()), + } + } + return util.JSONResponse{ + Code: http.StatusOK, + JSON: registerResponse{ + UserID: dev.UserID, + AccessToken: dev.AccessToken, + HomeServer: acc.ServerName, + DeviceID: dev.ID, + }, + } +} + // handleRegistrationFlow will direct and complete registration flow stages // that the client has requested. // nolint: gocyclo diff --git a/go.mod b/go.mod index 990b839eb..4c894ad99 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,8 @@ require ( github.com/matrix-org/naffka v0.0.0-20171115094957-662bfd0841d0 github.com/matrix-org/util v0.0.0-20171127121716-2e2df66af2f5 github.com/miekg/dns v1.1.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 github.com/opentracing/opentracing-go v1.0.2 github.com/pierrec/lz4 v0.0.0-20161206202305-5c9560bfa9ac // indirect