From db23640f6999a42e7024fc987975b81c0b9757b2 Mon Sep 17 00:00:00 2001 From: Kegsay Date: Thu, 25 May 2017 17:41:45 +0100 Subject: [PATCH] cmd: Add create test accounts command (#119) --- .../clientapi/auth/storage/devices/storage.go | 14 +-- .../dendrite/cmd/create-account/main.go | 98 +++++++++++++++++++ .../cmd/syncserver-integration-tests/main.go | 25 +++++ travis-test.sh | 1 + 4 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 src/github.com/matrix-org/dendrite/cmd/create-account/main.go diff --git a/src/github.com/matrix-org/dendrite/clientapi/auth/storage/devices/storage.go b/src/github.com/matrix-org/dendrite/clientapi/auth/storage/devices/storage.go index 49c4a90c..185dbba1 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/auth/storage/devices/storage.go +++ b/src/github.com/matrix-org/dendrite/clientapi/auth/storage/devices/storage.go @@ -44,27 +44,21 @@ func NewDatabase(dataSourceName string, serverName gomatrixserverlib.ServerName) // GetDeviceByAccessToken returns the device matching the given access token. // Returns sql.ErrNoRows if no matching device was found. func (d *Database) GetDeviceByAccessToken(token string) (*authtypes.Device, error) { - // return d.devices.selectDeviceByToken(token) TODO: Figure out how to make integ tests pass - return &authtypes.Device{ - UserID: token, - AccessToken: token, - }, nil + return d.devices.selectDeviceByToken(token) } // CreateDevice makes a new device associated with the given user ID localpart. // If there is already a device with the same device ID for this user, that access token will be revoked -// and replaced with a newly generated token. +// and replaced with the given accessToken. If the given accessToken is already in use for another device, +// an error will be returned. // Returns the device on success. -func (d *Database) CreateDevice(localpart, deviceID string) (dev *authtypes.Device, returnErr error) { +func (d *Database) CreateDevice(localpart, deviceID, accessToken string) (dev *authtypes.Device, returnErr error) { returnErr = runTransaction(d.db, func(txn *sql.Tx) error { var err error // Revoke existing token for this device if err = d.devices.deleteDevice(txn, deviceID, localpart); err != nil { return err } - // TODO: generate an access token. We should probably make sure that it's not possible for this - // token to be the same as the one we just revoked... - accessToken := makeUserID(localpart, d.devices.serverName) dev, err = d.devices.insertDevice(txn, deviceID, localpart, accessToken) if err != nil { diff --git a/src/github.com/matrix-org/dendrite/cmd/create-account/main.go b/src/github.com/matrix-org/dendrite/cmd/create-account/main.go new file mode 100644 index 00000000..bd5d2f78 --- /dev/null +++ b/src/github.com/matrix-org/dendrite/cmd/create-account/main.go @@ -0,0 +1,98 @@ +// Copyright 2017 Vector Creations Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" + "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" + "github.com/matrix-org/gomatrixserverlib" +) + +const usage = `Usage: %s + +Generate a new Matrix account for testing purposes. + +Arguments: + +` + +var ( + database = flag.String("database", "", "The location of the account database.") + username = flag.String("username", "", "The user ID localpart to register e.g 'alice' in '@alice:localhost'.") + password = flag.String("password", "", "Optional. The password to register with. If not specified, this account will be password-less.") + serverNameStr = flag.String("servername", "localhost", "The Matrix server domain which will form the domain part of the user ID.") + accessToken = flag.String("token", "", "Optional. The desired access_token to have. If not specified, a random access_token will be made.") +) + +func main() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, usage, os.Args[0]) + flag.PrintDefaults() + } + + flag.Parse() + + if *username == "" { + flag.Usage() + fmt.Println("Missing --username") + os.Exit(1) + } + + if *database == "" { + flag.Usage() + fmt.Println("Missing --database") + os.Exit(1) + } + + serverName := gomatrixserverlib.ServerName(*serverNameStr) + + accountDB, err := accounts.NewDatabase(*database, serverName) + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + + _, err = accountDB.CreateAccount(*username, *password) + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + + deviceDB, err := devices.NewDatabase(*database, serverName) + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + + if *accessToken == "" { + t := "token_" + *username + accessToken = &t + } + + device, err := deviceDB.CreateDevice(*username, "create-account-script", *accessToken) + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } + + fmt.Println("Created account:") + fmt.Printf("user_id = %s\n", device.UserID) + fmt.Printf("device_id = %s\n", device.ID) + fmt.Printf("access_token = %s\n", device.AccessToken) +} diff --git a/src/github.com/matrix-org/dendrite/cmd/syncserver-integration-tests/main.go b/src/github.com/matrix-org/dendrite/cmd/syncserver-integration-tests/main.go index fb1fdfcb..f8f6ff91 100644 --- a/src/github.com/matrix-org/dendrite/cmd/syncserver-integration-tests/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/syncserver-integration-tests/main.go @@ -133,6 +133,21 @@ func canonicalJSONInput(jsonData []string) []string { return jsonData } +func createTestUser(database, username, token string) error { + cmd := exec.Command( + filepath.Join(filepath.Dir(os.Args[0]), "create-account"), + "--database", database, + "--username", username, + "--token", token, + ) + + // Send stdout and stderr to our stderr so that we see error messages from + // the create-account process + cmd.Stdout = os.Stderr + cmd.Stderr = os.Stderr + return cmd.Run() +} + // clientEventJSONForOutputRoomEvent parses the given output room event and extracts the 'Event' JSON. It is // trimmed to the client format and then canonicalised and returned as a string. // Panics if there are any problems. @@ -217,6 +232,16 @@ func startSyncServer() (*exec.Cmd, chan error) { panic(err) } + if err := createTestUser(testDatabase, "alice", "@alice:localhost"); err != nil { + panic(err) + } + if err := createTestUser(testDatabase, "bob", "@bob:localhost"); err != nil { + panic(err) + } + if err := createTestUser(testDatabase, "charlie", "@charlie:localhost"); err != nil { + panic(err) + } + const configFileName = "sync-api-server-config-test.yaml" err := ioutil.WriteFile(configFileName, []byte(syncServerConfigFileContents), 0644) if err != nil { diff --git a/travis-test.sh b/travis-test.sh index 8836f647..b1f12679 100755 --- a/travis-test.sh +++ b/travis-test.sh @@ -7,6 +7,7 @@ gb build github.com/matrix-org/dendrite/cmd/dendrite-room-server gb build github.com/matrix-org/dendrite/cmd/roomserver-integration-tests gb build github.com/matrix-org/dendrite/cmd/dendrite-sync-api-server gb build github.com/matrix-org/dendrite/cmd/syncserver-integration-tests +gb build github.com/matrix-org/dendrite/cmd/create-account # Run the pre commit hooks ./hooks/pre-commit