From 9c77022513f400db59409f5b55fc6223d38d6bb8 Mon Sep 17 00:00:00 2001 From: Kegsay Date: Tue, 16 Jun 2020 14:10:55 +0100 Subject: [PATCH] Make userapi responsible for checking access tokens (#1133) * Make userapi responsible for checking access tokens There's still plenty of dependencies on account/device DBs, but this is a start. This is a breaking change as it adds a required config value `listen.user_api`. * Cleanup * Review comments and test fix --- clientapi/auth/auth.go | 125 +++--------------- clientapi/auth/authtypes/device.go | 30 ----- clientapi/auth/storage/devices/interface.go | 10 +- .../storage/devices/postgres/devices_table.go | 20 +-- .../auth/storage/devices/postgres/storage.go | 10 +- .../storage/devices/sqlite3/devices_table.go | 20 +-- .../auth/storage/devices/sqlite3/storage.go | 10 +- clientapi/clientapi.go | 4 +- clientapi/routing/account_data.go | 6 +- clientapi/routing/createroom.go | 6 +- clientapi/routing/device.go | 12 +- clientapi/routing/directory.go | 6 +- clientapi/routing/filter.go | 6 +- clientapi/routing/getevent.go | 6 +- clientapi/routing/joinroom.go | 4 +- clientapi/routing/leaveroom.go | 4 +- clientapi/routing/login.go | 3 +- clientapi/routing/logout.go | 6 +- clientapi/routing/membership.go | 9 +- clientapi/routing/memberships.go | 6 +- clientapi/routing/profile.go | 5 +- clientapi/routing/room_tagging.go | 8 +- clientapi/routing/routing.go | 98 +++++++------- clientapi/routing/sendevent.go | 6 +- clientapi/routing/sendtodevice.go | 4 +- clientapi/routing/sendtyping.go | 4 +- clientapi/routing/threepid.go | 5 +- clientapi/routing/voip.go | 4 +- clientapi/routing/whoami.go | 4 +- clientapi/threepid/invites.go | 9 +- cmd/dendrite-client-api-server/main.go | 3 +- cmd/dendrite-demo-libp2p/main.go | 3 + cmd/dendrite-demo-yggdrasil/main.go | 3 + cmd/dendrite-key-server/main.go | 5 +- cmd/dendrite-media-api-server/main.go | 4 +- cmd/dendrite-monolith-server/main.go | 4 + cmd/dendrite-public-rooms-api-server/main.go | 4 +- cmd/dendrite-sync-api-server/main.go | 4 +- cmd/dendritejs/main.go | 4 + dendrite-config.yaml | 1 + internal/config/config.go | 11 ++ internal/config/config_test.go | 1 + internal/httputil/httpapi.go | 8 +- internal/setup/base.go | 11 ++ internal/setup/monolith.go | 12 +- keyserver/keyserver.go | 9 +- keyserver/routing/routing.go | 18 +-- mediaapi/mediaapi.go | 7 +- mediaapi/routing/routing.go | 17 +-- publicroomsapi/directory/directory.go | 4 +- publicroomsapi/publicroomsapi.go | 6 +- publicroomsapi/routing/routing.go | 14 +- syncapi/routing/routing.go | 16 +-- syncapi/storage/interface.go | 8 +- syncapi/storage/shared/syncserver.go | 17 +-- syncapi/storage/storage_test.go | 4 +- syncapi/sync/notifier_test.go | 5 +- syncapi/sync/request.go | 7 +- syncapi/sync/requestpool.go | 4 +- syncapi/syncapi.go | 6 +- userapi/api/api.go | 41 +++++- userapi/internal/api.go | 68 ++++++++++ userapi/inthttp/client.go | 15 ++- userapi/inthttp/server.go | 13 ++ userapi/userapi.go | 12 +- userapi/userapi_test.go | 2 +- 66 files changed, 421 insertions(+), 400 deletions(-) delete mode 100644 clientapi/auth/authtypes/device.go diff --git a/clientapi/auth/auth.go b/clientapi/auth/auth.go index 3482e501..b8e40853 100644 --- a/clientapi/auth/auth.go +++ b/clientapi/auth/auth.go @@ -18,17 +18,14 @@ package auth import ( "context" "crypto/rand" - "database/sql" "encoding/base64" "fmt" "net/http" "strings" - "github.com/matrix-org/dendrite/appservice/types" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/jsonerror" - "github.com/matrix-org/dendrite/clientapi/userutil" - "github.com/matrix-org/dendrite/internal/config" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/util" ) @@ -39,7 +36,7 @@ var tokenByteLength = 32 // DeviceDatabase represents a device database. type DeviceDatabase interface { // Look up the device matching the given access token. - GetDeviceByAccessToken(ctx context.Context, token string) (*authtypes.Device, error) + GetDeviceByAccessToken(ctx context.Context, token string) (*api.Device, error) } // AccountDatabase represents an account database. @@ -48,22 +45,14 @@ type AccountDatabase interface { GetAccountByLocalpart(ctx context.Context, localpart string) (*authtypes.Account, error) } -// Data contains information required to authenticate a request. -type Data struct { - AccountDB AccountDatabase - DeviceDB DeviceDatabase - // AppServices is the list of all registered AS - AppServices []config.ApplicationService -} - // VerifyUserFromRequest authenticates the HTTP request, // on success returns Device of the requester. // Finds local user or an application service user. // Note: For an AS user, AS dummy device is returned. // On failure returns an JSON error response which can be sent to the client. func VerifyUserFromRequest( - req *http.Request, data Data, -) (*authtypes.Device, *util.JSONResponse) { + req *http.Request, userAPI api.UserInternalAPI, +) (*api.Device, *util.JSONResponse) { // Try to find the Application Service user token, err := ExtractAccessToken(req) if err != nil { @@ -72,105 +61,31 @@ func VerifyUserFromRequest( JSON: jsonerror.MissingToken(err.Error()), } } - - // Search for app service with given access_token - var appService *config.ApplicationService - for _, as := range data.AppServices { - if as.ASToken == token { - appService = &as - break - } + var res api.QueryAccessTokenResponse + err = userAPI.QueryAccessToken(req.Context(), &api.QueryAccessTokenRequest{ + AccessToken: token, + AppServiceUserID: req.URL.Query().Get("user_id"), + }, &res) + if err != nil { + util.GetLogger(req.Context()).WithError(err).Error("userAPI.QueryAccessToken failed") + jsonErr := jsonerror.InternalServerError() + return nil, &jsonErr } - - if appService != nil { - // Create a dummy device for AS user - dev := authtypes.Device{ - // Use AS dummy device ID - ID: types.AppServiceDeviceID, - // AS dummy device has AS's token. - AccessToken: token, - } - - userID := req.URL.Query().Get("user_id") - localpart, err := userutil.ParseUsernameParam(userID, nil) - if err != nil { - return nil, &util.JSONResponse{ - Code: http.StatusBadRequest, - JSON: jsonerror.InvalidUsername(err.Error()), - } - } - - if localpart != "" { // AS is masquerading as another user - // Verify that the user is registered - account, err := data.AccountDB.GetAccountByLocalpart(req.Context(), localpart) - // Verify that account exists & appServiceID matches - if err == nil && account.AppServiceID == appService.ID { - // Set the userID of dummy device - dev.UserID = userID - return &dev, nil - } - + if res.Err != nil { + if forbidden, ok := res.Err.(*api.ErrorForbidden); ok { return nil, &util.JSONResponse{ Code: http.StatusForbidden, - JSON: jsonerror.Forbidden("Application service has not registered this user"), + JSON: jsonerror.Forbidden(forbidden.Message), } } - - // AS is not masquerading as any user, so use AS's sender_localpart - dev.UserID = appService.SenderLocalpart - return &dev, nil } - - // Try to find local user from device database - dev, devErr := verifyAccessToken(req, data.DeviceDB) - if devErr == nil { - return dev, verifyUserParameters(req) - } - - return nil, &util.JSONResponse{ - Code: http.StatusUnauthorized, - JSON: jsonerror.UnknownToken("Unrecognized access token"), // nolint: misspell - } -} - -// verifyUserParameters ensures that a request coming from a regular user is not -// using any query parameters reserved for an application service -func verifyUserParameters(req *http.Request) *util.JSONResponse { - if req.URL.Query().Get("ts") != "" { - return &util.JSONResponse{ - Code: http.StatusBadRequest, - JSON: jsonerror.Unknown("parameter 'ts' not allowed without valid parameter 'access_token'"), - } - } - return nil -} - -// verifyAccessToken verifies that an access token was supplied in the given HTTP request -// and returns the device it corresponds to. Returns resErr (an error response which can be -// sent to the client) if the token is invalid or there was a problem querying the database. -func verifyAccessToken(req *http.Request, deviceDB DeviceDatabase) (device *authtypes.Device, resErr *util.JSONResponse) { - token, err := ExtractAccessToken(req) - if err != nil { - resErr = &util.JSONResponse{ + if res.Device == nil { + return nil, &util.JSONResponse{ Code: http.StatusUnauthorized, - JSON: jsonerror.MissingToken(err.Error()), - } - return - } - device, err = deviceDB.GetDeviceByAccessToken(req.Context(), token) - if err != nil { - if err == sql.ErrNoRows { - resErr = &util.JSONResponse{ - Code: http.StatusUnauthorized, - JSON: jsonerror.UnknownToken("Unknown token"), - } - } else { - util.GetLogger(req.Context()).WithError(err).Error("deviceDB.GetDeviceByAccessToken failed") - jsonErr := jsonerror.InternalServerError() - resErr = &jsonErr + JSON: jsonerror.UnknownToken("Unknown token"), } } - return + return res.Device, nil } // GenerateAccessToken creates a new access token. Returns an error if failed to generate diff --git a/clientapi/auth/authtypes/device.go b/clientapi/auth/authtypes/device.go deleted file mode 100644 index 299eff03..00000000 --- a/clientapi/auth/authtypes/device.go +++ /dev/null @@ -1,30 +0,0 @@ -// 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 authtypes - -// Device represents a client's device (mobile, web, etc) -type Device struct { - ID string - UserID string - // The access_token granted to this device. - // This uniquely identifies the device from all other devices and clients. - AccessToken string - // The unique ID of the session identified by the access token. - // Can be used as a secure substitution in places where data needs to be - // associated with access tokens. - SessionID int64 - // TODO: display name, last used timestamp, keys, etc - DisplayName string -} diff --git a/clientapi/auth/storage/devices/interface.go b/clientapi/auth/storage/devices/interface.go index 95291e4a..fc2f4a32 100644 --- a/clientapi/auth/storage/devices/interface.go +++ b/clientapi/auth/storage/devices/interface.go @@ -17,14 +17,14 @@ package devices import ( "context" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" + "github.com/matrix-org/dendrite/userapi/api" ) type Database interface { - GetDeviceByAccessToken(ctx context.Context, token string) (*authtypes.Device, error) - GetDeviceByID(ctx context.Context, localpart, deviceID string) (*authtypes.Device, error) - GetDevicesByLocalpart(ctx context.Context, localpart string) ([]authtypes.Device, error) - CreateDevice(ctx context.Context, localpart string, deviceID *string, accessToken string, displayName *string) (dev *authtypes.Device, returnErr error) + GetDeviceByAccessToken(ctx context.Context, token string) (*api.Device, error) + GetDeviceByID(ctx context.Context, localpart, deviceID string) (*api.Device, error) + GetDevicesByLocalpart(ctx context.Context, localpart string) ([]api.Device, error) + CreateDevice(ctx context.Context, localpart string, deviceID *string, accessToken string, displayName *string) (dev *api.Device, returnErr error) UpdateDevice(ctx context.Context, localpart, deviceID string, displayName *string) error RemoveDevice(ctx context.Context, deviceID, localpart string) error RemoveDevices(ctx context.Context, localpart string, devices []string) error diff --git a/clientapi/auth/storage/devices/postgres/devices_table.go b/clientapi/auth/storage/devices/postgres/devices_table.go index 149ca659..1d036d1b 100644 --- a/clientapi/auth/storage/devices/postgres/devices_table.go +++ b/clientapi/auth/storage/devices/postgres/devices_table.go @@ -20,10 +20,10 @@ import ( "time" "github.com/lib/pq" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/userutil" "github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" ) @@ -135,14 +135,14 @@ func (s *devicesStatements) prepare(db *sql.DB, server gomatrixserverlib.ServerN func (s *devicesStatements) insertDevice( ctx context.Context, txn *sql.Tx, id, localpart, accessToken string, displayName *string, -) (*authtypes.Device, error) { +) (*api.Device, error) { createdTimeMS := time.Now().UnixNano() / 1000000 var sessionID int64 stmt := sqlutil.TxStmt(txn, s.insertDeviceStmt) if err := stmt.QueryRowContext(ctx, id, localpart, accessToken, createdTimeMS, displayName).Scan(&sessionID); err != nil { return nil, err } - return &authtypes.Device{ + return &api.Device{ ID: id, UserID: userutil.MakeUserID(localpart, s.serverName), AccessToken: accessToken, @@ -189,8 +189,8 @@ func (s *devicesStatements) updateDeviceName( func (s *devicesStatements) selectDeviceByToken( ctx context.Context, accessToken string, -) (*authtypes.Device, error) { - var dev authtypes.Device +) (*api.Device, error) { + var dev api.Device var localpart string stmt := s.selectDeviceByTokenStmt err := stmt.QueryRowContext(ctx, accessToken).Scan(&dev.SessionID, &dev.ID, &localpart) @@ -205,8 +205,8 @@ func (s *devicesStatements) selectDeviceByToken( // localpart and deviceID func (s *devicesStatements) selectDeviceByID( ctx context.Context, localpart, deviceID string, -) (*authtypes.Device, error) { - var dev authtypes.Device +) (*api.Device, error) { + var dev api.Device stmt := s.selectDeviceByIDStmt err := stmt.QueryRowContext(ctx, localpart, deviceID).Scan(&dev.DisplayName) if err == nil { @@ -218,8 +218,8 @@ func (s *devicesStatements) selectDeviceByID( func (s *devicesStatements) selectDevicesByLocalpart( ctx context.Context, localpart string, -) ([]authtypes.Device, error) { - devices := []authtypes.Device{} +) ([]api.Device, error) { + devices := []api.Device{} rows, err := s.selectDevicesByLocalpartStmt.QueryContext(ctx, localpart) @@ -229,7 +229,7 @@ func (s *devicesStatements) selectDevicesByLocalpart( defer internal.CloseAndLogIfError(ctx, rows, "selectDevicesByLocalpart: rows.close() failed") for rows.Next() { - var dev authtypes.Device + var dev api.Device var id, displayname sql.NullString err = rows.Scan(&id, &displayname) if err != nil { diff --git a/clientapi/auth/storage/devices/postgres/storage.go b/clientapi/auth/storage/devices/postgres/storage.go index 2b9aede2..801657bd 100644 --- a/clientapi/auth/storage/devices/postgres/storage.go +++ b/clientapi/auth/storage/devices/postgres/storage.go @@ -20,8 +20,8 @@ import ( "database/sql" "encoding/base64" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" ) @@ -52,7 +52,7 @@ func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties, serve // Returns sql.ErrNoRows if no matching device was found. func (d *Database) GetDeviceByAccessToken( ctx context.Context, token string, -) (*authtypes.Device, error) { +) (*api.Device, error) { return d.devices.selectDeviceByToken(ctx, token) } @@ -60,14 +60,14 @@ func (d *Database) GetDeviceByAccessToken( // Returns sql.ErrNoRows if no matching device was found. func (d *Database) GetDeviceByID( ctx context.Context, localpart, deviceID string, -) (*authtypes.Device, error) { +) (*api.Device, error) { return d.devices.selectDeviceByID(ctx, localpart, deviceID) } // GetDevicesByLocalpart returns the devices matching the given localpart. func (d *Database) GetDevicesByLocalpart( ctx context.Context, localpart string, -) ([]authtypes.Device, error) { +) ([]api.Device, error) { return d.devices.selectDevicesByLocalpart(ctx, localpart) } @@ -80,7 +80,7 @@ func (d *Database) GetDevicesByLocalpart( func (d *Database) CreateDevice( ctx context.Context, localpart string, deviceID *string, accessToken string, displayName *string, -) (dev *authtypes.Device, returnErr error) { +) (dev *api.Device, returnErr error) { if deviceID != nil { returnErr = sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error { var err error diff --git a/clientapi/auth/storage/devices/sqlite3/devices_table.go b/clientapi/auth/storage/devices/sqlite3/devices_table.go index 4656b004..07ea5dca 100644 --- a/clientapi/auth/storage/devices/sqlite3/devices_table.go +++ b/clientapi/auth/storage/devices/sqlite3/devices_table.go @@ -21,8 +21,8 @@ import ( "time" "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/userapi/api" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/userutil" "github.com/matrix-org/gomatrixserverlib" ) @@ -125,7 +125,7 @@ func (s *devicesStatements) prepare(db *sql.DB, server gomatrixserverlib.ServerN func (s *devicesStatements) insertDevice( ctx context.Context, txn *sql.Tx, id, localpart, accessToken string, displayName *string, -) (*authtypes.Device, error) { +) (*api.Device, error) { createdTimeMS := time.Now().UnixNano() / 1000000 var sessionID int64 countStmt := sqlutil.TxStmt(txn, s.selectDevicesCountStmt) @@ -137,7 +137,7 @@ func (s *devicesStatements) insertDevice( if _, err := insertStmt.ExecContext(ctx, id, localpart, accessToken, createdTimeMS, displayName, sessionID); err != nil { return nil, err } - return &authtypes.Device{ + return &api.Device{ ID: id, UserID: userutil.MakeUserID(localpart, s.serverName), AccessToken: accessToken, @@ -190,8 +190,8 @@ func (s *devicesStatements) updateDeviceName( func (s *devicesStatements) selectDeviceByToken( ctx context.Context, accessToken string, -) (*authtypes.Device, error) { - var dev authtypes.Device +) (*api.Device, error) { + var dev api.Device var localpart string stmt := s.selectDeviceByTokenStmt err := stmt.QueryRowContext(ctx, accessToken).Scan(&dev.SessionID, &dev.ID, &localpart) @@ -206,8 +206,8 @@ func (s *devicesStatements) selectDeviceByToken( // localpart and deviceID func (s *devicesStatements) selectDeviceByID( ctx context.Context, localpart, deviceID string, -) (*authtypes.Device, error) { - var dev authtypes.Device +) (*api.Device, error) { + var dev api.Device stmt := s.selectDeviceByIDStmt err := stmt.QueryRowContext(ctx, localpart, deviceID).Scan(&dev.DisplayName) if err == nil { @@ -219,8 +219,8 @@ func (s *devicesStatements) selectDeviceByID( func (s *devicesStatements) selectDevicesByLocalpart( ctx context.Context, localpart string, -) ([]authtypes.Device, error) { - devices := []authtypes.Device{} +) ([]api.Device, error) { + devices := []api.Device{} rows, err := s.selectDevicesByLocalpartStmt.QueryContext(ctx, localpart) @@ -229,7 +229,7 @@ func (s *devicesStatements) selectDevicesByLocalpart( } for rows.Next() { - var dev authtypes.Device + var dev api.Device var id, displayname sql.NullString err = rows.Scan(&id, &displayname) if err != nil { diff --git a/clientapi/auth/storage/devices/sqlite3/storage.go b/clientapi/auth/storage/devices/sqlite3/storage.go index 09e0bc81..f248abda 100644 --- a/clientapi/auth/storage/devices/sqlite3/storage.go +++ b/clientapi/auth/storage/devices/sqlite3/storage.go @@ -20,8 +20,8 @@ import ( "database/sql" "encoding/base64" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/internal/sqlutil" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" _ "github.com/mattn/go-sqlite3" @@ -58,7 +58,7 @@ func NewDatabase(dataSourceName string, serverName gomatrixserverlib.ServerName) // Returns sql.ErrNoRows if no matching device was found. func (d *Database) GetDeviceByAccessToken( ctx context.Context, token string, -) (*authtypes.Device, error) { +) (*api.Device, error) { return d.devices.selectDeviceByToken(ctx, token) } @@ -66,14 +66,14 @@ func (d *Database) GetDeviceByAccessToken( // Returns sql.ErrNoRows if no matching device was found. func (d *Database) GetDeviceByID( ctx context.Context, localpart, deviceID string, -) (*authtypes.Device, error) { +) (*api.Device, error) { return d.devices.selectDeviceByID(ctx, localpart, deviceID) } // GetDevicesByLocalpart returns the devices matching the given localpart. func (d *Database) GetDevicesByLocalpart( ctx context.Context, localpart string, -) ([]authtypes.Device, error) { +) ([]api.Device, error) { return d.devices.selectDevicesByLocalpart(ctx, localpart) } @@ -86,7 +86,7 @@ func (d *Database) GetDevicesByLocalpart( func (d *Database) CreateDevice( ctx context.Context, localpart string, deviceID *string, accessToken string, displayName *string, -) (dev *authtypes.Device, returnErr error) { +) (dev *api.Device, returnErr error) { if deviceID != nil { returnErr = sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error { var err error diff --git a/clientapi/clientapi.go b/clientapi/clientapi.go index 545b95b0..637e1469 100644 --- a/clientapi/clientapi.go +++ b/clientapi/clientapi.go @@ -28,6 +28,7 @@ import ( "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/transactions" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/sirupsen/logrus" ) @@ -46,6 +47,7 @@ func AddPublicRoutes( asAPI appserviceAPI.AppServiceQueryAPI, transactionsCache *transactions.Cache, fsAPI federationSenderAPI.FederationSenderInternalAPI, + userAPI userapi.UserInternalAPI, ) { syncProducer := &producers.SyncAPIProducer{ Producer: producer, @@ -61,7 +63,7 @@ func AddPublicRoutes( routing.Setup( router, cfg, eduInputAPI, rsAPI, asAPI, - accountsDB, deviceDB, federation, + accountsDB, deviceDB, userAPI, federation, syncProducer, transactionsCache, fsAPI, ) } diff --git a/clientapi/routing/account_data.go b/clientapi/routing/account_data.go index a5d53c32..5e0509a5 100644 --- a/clientapi/routing/account_data.go +++ b/clientapi/routing/account_data.go @@ -19,10 +19,10 @@ import ( "io/ioutil" "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/producers" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" @@ -30,7 +30,7 @@ import ( // GetAccountData implements GET /user/{userId}/[rooms/{roomid}/]account_data/{type} func GetAccountData( - req *http.Request, accountDB accounts.Database, device *authtypes.Device, + req *http.Request, accountDB accounts.Database, device *api.Device, userID string, roomID string, dataType string, ) util.JSONResponse { if userID != device.UserID { @@ -63,7 +63,7 @@ func GetAccountData( // SaveAccountData implements PUT /user/{userId}/[rooms/{roomId}/]account_data/{type} func SaveAccountData( - req *http.Request, accountDB accounts.Database, device *authtypes.Device, + req *http.Request, accountDB accounts.Database, device *api.Device, userID string, roomID string, dataType string, syncProducer *producers.SyncAPIProducer, ) util.JSONResponse { if userID != device.UserID { diff --git a/clientapi/routing/createroom.go b/clientapi/routing/createroom.go index fd91a106..2bb537b0 100644 --- a/clientapi/routing/createroom.go +++ b/clientapi/routing/createroom.go @@ -24,8 +24,8 @@ import ( appserviceAPI "github.com/matrix-org/dendrite/appservice/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverVersion "github.com/matrix-org/dendrite/roomserver/version" + "github.com/matrix-org/dendrite/userapi/api" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" @@ -135,7 +135,7 @@ type fledglingEvent struct { // CreateRoom implements /createRoom func CreateRoom( - req *http.Request, device *authtypes.Device, + req *http.Request, device *api.Device, cfg *config.Dendrite, accountDB accounts.Database, rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI, @@ -149,7 +149,7 @@ func CreateRoom( // createRoom implements /createRoom // nolint: gocyclo func createRoom( - req *http.Request, device *authtypes.Device, + req *http.Request, device *api.Device, cfg *config.Dendrite, roomID string, accountDB accounts.Database, rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI, diff --git a/clientapi/routing/device.go b/clientapi/routing/device.go index 89c39491..02acb462 100644 --- a/clientapi/routing/device.go +++ b/clientapi/routing/device.go @@ -19,9 +19,9 @@ import ( "encoding/json" "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/clientapi/jsonerror" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) @@ -45,7 +45,7 @@ type devicesDeleteJSON struct { // GetDeviceByID handles /devices/{deviceID} func GetDeviceByID( - req *http.Request, deviceDB devices.Database, device *authtypes.Device, + req *http.Request, deviceDB devices.Database, device *api.Device, deviceID string, ) util.JSONResponse { localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) @@ -77,7 +77,7 @@ func GetDeviceByID( // GetDevicesByLocalpart handles /devices func GetDevicesByLocalpart( - req *http.Request, deviceDB devices.Database, device *authtypes.Device, + req *http.Request, deviceDB devices.Database, device *api.Device, ) util.JSONResponse { localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) if err != nil { @@ -110,7 +110,7 @@ func GetDevicesByLocalpart( // UpdateDeviceByID handles PUT on /devices/{deviceID} func UpdateDeviceByID( - req *http.Request, deviceDB devices.Database, device *authtypes.Device, + req *http.Request, deviceDB devices.Database, device *api.Device, deviceID string, ) util.JSONResponse { localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) @@ -160,7 +160,7 @@ func UpdateDeviceByID( // DeleteDeviceById handles DELETE requests to /devices/{deviceId} func DeleteDeviceById( - req *http.Request, deviceDB devices.Database, device *authtypes.Device, + req *http.Request, deviceDB devices.Database, device *api.Device, deviceID string, ) util.JSONResponse { localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) @@ -185,7 +185,7 @@ func DeleteDeviceById( // DeleteDevices handles POST requests to /delete_devices func DeleteDevices( - req *http.Request, deviceDB devices.Database, device *authtypes.Device, + req *http.Request, deviceDB devices.Database, device *api.Device, ) util.JSONResponse { localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) if err != nil { diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go index 3d4b5f5b..0dc4d560 100644 --- a/clientapi/routing/directory.go +++ b/clientapi/routing/directory.go @@ -18,12 +18,12 @@ import ( "fmt" "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" "github.com/matrix-org/dendrite/internal/config" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) @@ -112,7 +112,7 @@ func DirectoryRoom( // TODO: Check if the user has the power level to set an alias func SetLocalAlias( req *http.Request, - device *authtypes.Device, + device *api.Device, alias string, cfg *config.Dendrite, aliasAPI roomserverAPI.RoomserverInternalAPI, @@ -188,7 +188,7 @@ func SetLocalAlias( // RemoveLocalAlias implements DELETE /directory/room/{roomAlias} func RemoveLocalAlias( req *http.Request, - device *authtypes.Device, + device *api.Device, alias string, aliasAPI roomserverAPI.RoomserverInternalAPI, ) util.JSONResponse { diff --git a/clientapi/routing/filter.go b/clientapi/routing/filter.go index 505e0927..7c583045 100644 --- a/clientapi/routing/filter.go +++ b/clientapi/routing/filter.go @@ -17,17 +17,17 @@ package routing import ( "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) // GetFilter implements GET /_matrix/client/r0/user/{userId}/filter/{filterId} func GetFilter( - req *http.Request, device *authtypes.Device, accountDB accounts.Database, userID string, filterID string, + req *http.Request, device *api.Device, accountDB accounts.Database, userID string, filterID string, ) util.JSONResponse { if userID != device.UserID { return util.JSONResponse{ @@ -64,7 +64,7 @@ type filterResponse struct { //PutFilter implements POST /_matrix/client/r0/user/{userId}/filter func PutFilter( - req *http.Request, device *authtypes.Device, accountDB accounts.Database, userID string, + req *http.Request, device *api.Device, accountDB accounts.Database, userID string, ) util.JSONResponse { if userID != device.UserID { return util.JSONResponse{ diff --git a/clientapi/routing/getevent.go b/clientapi/routing/getevent.go index 16f36d66..2a51db73 100644 --- a/clientapi/routing/getevent.go +++ b/clientapi/routing/getevent.go @@ -17,17 +17,17 @@ package routing import ( "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) type getEventRequest struct { req *http.Request - device *authtypes.Device + device *userapi.Device roomID string eventID string cfg *config.Dendrite @@ -39,7 +39,7 @@ type getEventRequest struct { // https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-event-eventid func GetEvent( req *http.Request, - device *authtypes.Device, + device *userapi.Device, roomID string, eventID string, cfg *config.Dendrite, diff --git a/clientapi/routing/joinroom.go b/clientapi/routing/joinroom.go index a3d67653..a00b34a5 100644 --- a/clientapi/routing/joinroom.go +++ b/clientapi/routing/joinroom.go @@ -17,18 +17,18 @@ package routing import ( "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) func JoinRoomByIDOrAlias( req *http.Request, - device *authtypes.Device, + device *api.Device, rsAPI roomserverAPI.RoomserverInternalAPI, accountDB accounts.Database, roomIDOrAlias string, diff --git a/clientapi/routing/leaveroom.go b/clientapi/routing/leaveroom.go index bd769618..38cef118 100644 --- a/clientapi/routing/leaveroom.go +++ b/clientapi/routing/leaveroom.go @@ -17,15 +17,15 @@ package routing import ( "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/jsonerror" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/util" ) func LeaveRoomByID( req *http.Request, - device *authtypes.Device, + device *api.Device, rsAPI roomserverAPI.RoomserverInternalAPI, roomID string, ) util.JSONResponse { diff --git a/clientapi/routing/login.go b/clientapi/routing/login.go index c0042fa9..2eb480ef 100644 --- a/clientapi/routing/login.go +++ b/clientapi/routing/login.go @@ -27,6 +27,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/userutil" "github.com/matrix-org/dendrite/internal/config" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) @@ -157,7 +158,7 @@ func getDevice( deviceDB devices.Database, acc *authtypes.Account, token string, -) (dev *authtypes.Device, err error) { +) (dev *api.Device, err error) { dev, err = deviceDB.CreateDevice( ctx, acc.Localpart, r.DeviceID, token, r.InitialDisplayName, ) diff --git a/clientapi/routing/logout.go b/clientapi/routing/logout.go index 26b7f117..f1276082 100644 --- a/clientapi/routing/logout.go +++ b/clientapi/routing/logout.go @@ -17,16 +17,16 @@ package routing import ( "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/clientapi/jsonerror" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) // Logout handles POST /logout func Logout( - req *http.Request, deviceDB devices.Database, device *authtypes.Device, + req *http.Request, deviceDB devices.Database, device *api.Device, ) util.JSONResponse { localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) if err != nil { @@ -47,7 +47,7 @@ func Logout( // LogoutAll handles POST /logout/all func LogoutAll( - req *http.Request, deviceDB devices.Database, device *authtypes.Device, + req *http.Request, deviceDB devices.Database, device *api.Device, ) util.JSONResponse { localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) if err != nil { diff --git a/clientapi/routing/membership.go b/clientapi/routing/membership.go index 53484a1a..c7b91613 100644 --- a/clientapi/routing/membership.go +++ b/clientapi/routing/membership.go @@ -30,6 +30,7 @@ import ( "github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" @@ -42,7 +43,7 @@ var errMissingUserID = errors.New("'user_id' must be supplied") // TODO: Can we improve the cyclo count here? Separate code paths for invites? // nolint:gocyclo func SendMembership( - req *http.Request, accountDB accounts.Database, device *authtypes.Device, + req *http.Request, accountDB accounts.Database, device *userapi.Device, roomID string, membership string, cfg *config.Dendrite, rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI, ) util.JSONResponse { @@ -149,7 +150,7 @@ func SendMembership( func buildMembershipEvent( ctx context.Context, body threepid.MembershipRequest, accountDB accounts.Database, - device *authtypes.Device, + device *userapi.Device, membership, roomID string, isDirect bool, cfg *config.Dendrite, evTime time.Time, rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI, @@ -223,7 +224,7 @@ func loadProfile( // In the latter case, if there was an issue retrieving the user ID from the request body, // returns a JSONResponse with a corresponding error code and message. func getMembershipStateKey( - body threepid.MembershipRequest, device *authtypes.Device, membership string, + body threepid.MembershipRequest, device *userapi.Device, membership string, ) (stateKey string, reason string, err error) { if membership == gomatrixserverlib.Ban || membership == "unban" || membership == "kick" || membership == gomatrixserverlib.Invite { // If we're in this case, the state key is contained in the request body, @@ -245,7 +246,7 @@ func getMembershipStateKey( func checkAndProcessThreepid( req *http.Request, - device *authtypes.Device, + device *userapi.Device, body *threepid.MembershipRequest, cfg *config.Dendrite, rsAPI roomserverAPI.RoomserverInternalAPI, diff --git a/clientapi/routing/memberships.go b/clientapi/routing/memberships.go index 095a85c0..a5bb2a90 100644 --- a/clientapi/routing/memberships.go +++ b/clientapi/routing/memberships.go @@ -19,10 +19,10 @@ import ( "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) @@ -37,7 +37,7 @@ type getJoinedRoomsResponse struct { // GetMemberships implements GET /rooms/{roomId}/members func GetMemberships( - req *http.Request, device *authtypes.Device, roomID string, joinedOnly bool, + req *http.Request, device *userapi.Device, roomID string, joinedOnly bool, _ *config.Dendrite, rsAPI api.RoomserverInternalAPI, ) util.JSONResponse { @@ -67,7 +67,7 @@ func GetMemberships( func GetJoinedRooms( req *http.Request, - device *authtypes.Device, + device *userapi.Device, accountsDB accounts.Database, ) util.JSONResponse { localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) diff --git a/clientapi/routing/profile.go b/clientapi/routing/profile.go index a7a82ed5..a72ad3bc 100644 --- a/clientapi/routing/profile.go +++ b/clientapi/routing/profile.go @@ -27,6 +27,7 @@ import ( "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrix" @@ -92,7 +93,7 @@ func GetAvatarURL( // SetAvatarURL implements PUT /profile/{userID}/avatar_url // nolint:gocyclo func SetAvatarURL( - req *http.Request, accountDB accounts.Database, device *authtypes.Device, + req *http.Request, accountDB accounts.Database, device *userapi.Device, userID string, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI, ) util.JSONResponse { if userID != device.UserID { @@ -206,7 +207,7 @@ func GetDisplayName( // SetDisplayName implements PUT /profile/{userID}/displayname // nolint:gocyclo func SetDisplayName( - req *http.Request, accountDB accounts.Database, device *authtypes.Device, + req *http.Request, accountDB accounts.Database, device *userapi.Device, userID string, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI, ) util.JSONResponse { if userID != device.UserID { diff --git a/clientapi/routing/room_tagging.go b/clientapi/routing/room_tagging.go index 5c68668d..a3fe0e42 100644 --- a/clientapi/routing/room_tagging.go +++ b/clientapi/routing/room_tagging.go @@ -20,11 +20,11 @@ import ( "github.com/sirupsen/logrus" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/producers" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" @@ -41,7 +41,7 @@ func newTag() gomatrix.TagContent { func GetTags( req *http.Request, accountDB accounts.Database, - device *authtypes.Device, + device *api.Device, userID string, roomID string, syncProducer *producers.SyncAPIProducer, @@ -79,7 +79,7 @@ func GetTags( func PutTag( req *http.Request, accountDB accounts.Database, - device *authtypes.Device, + device *api.Device, userID string, roomID string, tag string, @@ -139,7 +139,7 @@ func PutTag( func DeleteTag( req *http.Request, accountDB accounts.Database, - device *authtypes.Device, + device *api.Device, userID string, roomID string, tag string, diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go index 82a80fff..80d9ab66 100644 --- a/clientapi/routing/routing.go +++ b/clientapi/routing/routing.go @@ -21,8 +21,6 @@ import ( "github.com/gorilla/mux" appserviceAPI "github.com/matrix-org/dendrite/appservice/api" - "github.com/matrix-org/dendrite/clientapi/auth" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/clientapi/jsonerror" @@ -33,6 +31,7 @@ import ( "github.com/matrix-org/dendrite/internal/httputil" "github.com/matrix-org/dendrite/internal/transactions" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) @@ -54,6 +53,7 @@ func Setup( asAPI appserviceAPI.AppServiceQueryAPI, accountDB accounts.Database, deviceDB devices.Database, + userAPI api.UserInternalAPI, federation *gomatrixserverlib.FederationClient, syncProducer *producers.SyncAPIProducer, transactionsCache *transactions.Cache, @@ -80,19 +80,13 @@ func Setup( v1mux := publicAPIMux.PathPrefix(pathPrefixV1).Subrouter() unstableMux := publicAPIMux.PathPrefix(pathPrefixUnstable).Subrouter() - authData := auth.Data{ - AccountDB: accountDB, - DeviceDB: deviceDB, - AppServices: cfg.Derived.ApplicationServices, - } - r0mux.Handle("/createRoom", - httputil.MakeAuthAPI("createRoom", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("createRoom", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return CreateRoom(req, device, cfg, accountDB, rsAPI, asAPI) }), ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/join/{roomIDOrAlias}", - httputil.MakeAuthAPI(gomatrixserverlib.Join, authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI(gomatrixserverlib.Join, userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -103,12 +97,12 @@ func Setup( }), ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/joined_rooms", - httputil.MakeAuthAPI("joined_rooms", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("joined_rooms", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return GetJoinedRooms(req, device, accountDB) }), ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/leave", - httputil.MakeAuthAPI("membership", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("membership", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -119,7 +113,7 @@ func Setup( }), ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/{membership:(?:join|kick|ban|unban|invite)}", - httputil.MakeAuthAPI("membership", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("membership", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -128,7 +122,7 @@ func Setup( }), ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/send/{eventType}", - httputil.MakeAuthAPI("send_message", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("send_message", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -137,7 +131,7 @@ func Setup( }), ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/send/{eventType}/{txnID}", - httputil.MakeAuthAPI("send_message", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("send_message", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -148,7 +142,7 @@ func Setup( }), ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/event/{eventID}", - httputil.MakeAuthAPI("rooms_get_event", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("rooms_get_event", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -157,7 +151,7 @@ func Setup( }), ).Methods(http.MethodGet, http.MethodOptions) - r0mux.Handle("/rooms/{roomID}/state", httputil.MakeAuthAPI("room_state", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + r0mux.Handle("/rooms/{roomID}/state", httputil.MakeAuthAPI("room_state", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -165,7 +159,7 @@ func Setup( return OnIncomingStateRequest(req.Context(), rsAPI, vars["roomID"]) })).Methods(http.MethodGet, http.MethodOptions) - r0mux.Handle("/rooms/{roomID}/state/{type}", httputil.MakeAuthAPI("room_state", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + r0mux.Handle("/rooms/{roomID}/state/{type}", httputil.MakeAuthAPI("room_state", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -173,7 +167,7 @@ func Setup( return OnIncomingStateTypeRequest(req.Context(), rsAPI, vars["roomID"], vars["type"], "") })).Methods(http.MethodGet, http.MethodOptions) - r0mux.Handle("/rooms/{roomID}/state/{type}/{stateKey}", httputil.MakeAuthAPI("room_state", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + r0mux.Handle("/rooms/{roomID}/state/{type}/{stateKey}", httputil.MakeAuthAPI("room_state", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -182,7 +176,7 @@ func Setup( })).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/state/{eventType:[^/]+/?}", - httputil.MakeAuthAPI("send_message", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("send_message", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -198,7 +192,7 @@ func Setup( ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/state/{eventType}/{stateKey}", - httputil.MakeAuthAPI("send_message", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("send_message", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -231,7 +225,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/directory/room/{roomAlias}", - httputil.MakeAuthAPI("directory_room", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("directory_room", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -241,7 +235,7 @@ func Setup( ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/directory/room/{roomAlias}", - httputil.MakeAuthAPI("directory_room", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("directory_room", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -251,19 +245,19 @@ func Setup( ).Methods(http.MethodDelete, http.MethodOptions) r0mux.Handle("/logout", - httputil.MakeAuthAPI("logout", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("logout", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return Logout(req, deviceDB, device) }), ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/logout/all", - httputil.MakeAuthAPI("logout", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("logout", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return LogoutAll(req, deviceDB, device) }), ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/typing/{userID}", - httputil.MakeAuthAPI("rooms_typing", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("rooms_typing", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -273,7 +267,7 @@ func Setup( ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/sendToDevice/{eventType}/{txnID}", - httputil.MakeAuthAPI("send_to_device", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("send_to_device", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -287,7 +281,7 @@ func Setup( // rather than r0. It's an exact duplicate of the above handler. // TODO: Remove this if/when sytest is fixed! unstableMux.Handle("/sendToDevice/{eventType}/{txnID}", - httputil.MakeAuthAPI("send_to_device", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("send_to_device", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -298,7 +292,7 @@ func Setup( ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/account/whoami", - httputil.MakeAuthAPI("whoami", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("whoami", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return Whoami(req, device) }), ).Methods(http.MethodGet, http.MethodOptions) @@ -338,7 +332,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/user/{userId}/filter", - httputil.MakeAuthAPI("put_filter", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("put_filter", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -348,7 +342,7 @@ func Setup( ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/user/{userId}/filter/{filterId}", - httputil.MakeAuthAPI("get_filter", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("get_filter", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -380,7 +374,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/profile/{userID}/avatar_url", - httputil.MakeAuthAPI("profile_avatar_url", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("profile_avatar_url", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -402,7 +396,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/profile/{userID}/displayname", - httputil.MakeAuthAPI("profile_displayname", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("profile_displayname", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -414,19 +408,19 @@ func Setup( // PUT requests, so we need to allow this method r0mux.Handle("/account/3pid", - httputil.MakeAuthAPI("account_3pid", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("account_3pid", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return GetAssociated3PIDs(req, accountDB, device) }), ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/account/3pid", - httputil.MakeAuthAPI("account_3pid", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("account_3pid", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return CheckAndSave3PIDAssociation(req, accountDB, device, cfg) }), ).Methods(http.MethodPost, http.MethodOptions) unstableMux.Handle("/account/3pid/delete", - httputil.MakeAuthAPI("account_3pid", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("account_3pid", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return Forget3PID(req, accountDB) }), ).Methods(http.MethodPost, http.MethodOptions) @@ -449,7 +443,7 @@ func Setup( ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/voip/turnServer", - httputil.MakeAuthAPI("turn_server", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("turn_server", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return RequestTurnServer(req, device, cfg) }), ).Methods(http.MethodGet, http.MethodOptions) @@ -475,7 +469,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/user/{userID}/account_data/{type}", - httputil.MakeAuthAPI("user_account_data", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("user_account_data", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -485,7 +479,7 @@ func Setup( ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/user/{userID}/rooms/{roomID}/account_data/{type}", - httputil.MakeAuthAPI("user_account_data", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("user_account_data", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -495,7 +489,7 @@ func Setup( ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/user/{userID}/account_data/{type}", - httputil.MakeAuthAPI("user_account_data", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("user_account_data", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -505,7 +499,7 @@ func Setup( ).Methods(http.MethodGet) r0mux.Handle("/user/{userID}/rooms/{roomID}/account_data/{type}", - httputil.MakeAuthAPI("user_account_data", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("user_account_data", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -515,7 +509,7 @@ func Setup( ).Methods(http.MethodGet) r0mux.Handle("/rooms/{roomID}/members", - httputil.MakeAuthAPI("rooms_members", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("rooms_members", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -525,7 +519,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/rooms/{roomID}/joined_members", - httputil.MakeAuthAPI("rooms_members", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("rooms_members", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -542,13 +536,13 @@ func Setup( ).Methods(http.MethodPost, http.MethodOptions) r0mux.Handle("/devices", - httputil.MakeAuthAPI("get_devices", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("get_devices", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return GetDevicesByLocalpart(req, deviceDB, device) }), ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/devices/{deviceID}", - httputil.MakeAuthAPI("get_device", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("get_device", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -558,7 +552,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/devices/{deviceID}", - httputil.MakeAuthAPI("device_data", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("device_data", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -568,7 +562,7 @@ func Setup( ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/devices/{deviceID}", - httputil.MakeAuthAPI("delete_device", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("delete_device", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -578,7 +572,7 @@ func Setup( ).Methods(http.MethodDelete, http.MethodOptions) r0mux.Handle("/delete_devices", - httputil.MakeAuthAPI("delete_devices", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("delete_devices", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return DeleteDevices(req, deviceDB, device) }), ).Methods(http.MethodPost, http.MethodOptions) @@ -603,7 +597,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/user/{userId}/rooms/{roomId}/tags", - httputil.MakeAuthAPI("get_tags", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("get_tags", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -613,7 +607,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) r0mux.Handle("/user/{userId}/rooms/{roomId}/tags/{tag}", - httputil.MakeAuthAPI("put_tag", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("put_tag", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -623,7 +617,7 @@ func Setup( ).Methods(http.MethodPut, http.MethodOptions) r0mux.Handle("/user/{userId}/rooms/{roomId}/tags/{tag}", - httputil.MakeAuthAPI("delete_tag", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("delete_tag", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) @@ -633,7 +627,7 @@ func Setup( ).Methods(http.MethodDelete, http.MethodOptions) r0mux.Handle("/capabilities", - httputil.MakeAuthAPI("capabilities", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("capabilities", userAPI, func(req *http.Request, device *api.Device) util.JSONResponse { return GetCapabilities(req, rsAPI) }), ).Methods(http.MethodGet) diff --git a/clientapi/routing/sendevent.go b/clientapi/routing/sendevent.go index 77a37077..d8936f75 100644 --- a/clientapi/routing/sendevent.go +++ b/clientapi/routing/sendevent.go @@ -17,13 +17,13 @@ package routing import ( "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/dendrite/internal/transactions" "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" "github.com/sirupsen/logrus" @@ -41,7 +41,7 @@ type sendEventResponse struct { // /rooms/{roomID}/state/{eventType}/{stateKey} func SendEvent( req *http.Request, - device *authtypes.Device, + device *userapi.Device, roomID, eventType string, txnID, stateKey *string, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI, @@ -110,7 +110,7 @@ func SendEvent( func generateSendEvent( req *http.Request, - device *authtypes.Device, + device *userapi.Device, roomID, eventType string, stateKey *string, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI, diff --git a/clientapi/routing/sendtodevice.go b/clientapi/routing/sendtodevice.go index dc0a6572..768e8e0e 100644 --- a/clientapi/routing/sendtodevice.go +++ b/clientapi/routing/sendtodevice.go @@ -16,18 +16,18 @@ import ( "encoding/json" "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/eduserver/api" "github.com/matrix-org/dendrite/internal/transactions" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/util" ) // SendToDevice handles PUT /_matrix/client/r0/sendToDevice/{eventType}/{txnId} // sends the device events to the EDU Server func SendToDevice( - req *http.Request, device *authtypes.Device, + req *http.Request, device *userapi.Device, eduAPI api.EDUServerInputAPI, txnCache *transactions.Cache, eventType string, txnID *string, diff --git a/clientapi/routing/sendtyping.go b/clientapi/routing/sendtyping.go index 2eae1658..213e7fdc 100644 --- a/clientapi/routing/sendtyping.go +++ b/clientapi/routing/sendtyping.go @@ -16,12 +16,12 @@ import ( "database/sql" "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/userutil" "github.com/matrix-org/dendrite/eduserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/util" ) @@ -33,7 +33,7 @@ type typingContentJSON struct { // SendTyping handles PUT /rooms/{roomID}/typing/{userID} // sends the typing events to client API typingProducer func SendTyping( - req *http.Request, device *authtypes.Device, roomID string, + req *http.Request, device *userapi.Device, roomID string, userID string, accountDB accounts.Database, eduAPI api.EDUServerInputAPI, ) util.JSONResponse { diff --git a/clientapi/routing/threepid.go b/clientapi/routing/threepid.go index 49a9f304..c712c1c3 100644 --- a/clientapi/routing/threepid.go +++ b/clientapi/routing/threepid.go @@ -23,6 +23,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/threepid" "github.com/matrix-org/dendrite/internal/config" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" @@ -84,7 +85,7 @@ func RequestEmailToken(req *http.Request, accountDB accounts.Database, cfg *conf // CheckAndSave3PIDAssociation implements POST /account/3pid func CheckAndSave3PIDAssociation( - req *http.Request, accountDB accounts.Database, device *authtypes.Device, + req *http.Request, accountDB accounts.Database, device *api.Device, cfg *config.Dendrite, ) util.JSONResponse { var body threepid.EmailAssociationCheckRequest @@ -148,7 +149,7 @@ func CheckAndSave3PIDAssociation( // GetAssociated3PIDs implements GET /account/3pid func GetAssociated3PIDs( - req *http.Request, accountDB accounts.Database, device *authtypes.Device, + req *http.Request, accountDB accounts.Database, device *api.Device, ) util.JSONResponse { localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) if err != nil { diff --git a/clientapi/routing/voip.go b/clientapi/routing/voip.go index 212d9b0a..046e8781 100644 --- a/clientapi/routing/voip.go +++ b/clientapi/routing/voip.go @@ -22,16 +22,16 @@ import ( "net/http" "time" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/internal/config" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrix" "github.com/matrix-org/util" ) // RequestTurnServer implements: // GET /voip/turnServer -func RequestTurnServer(req *http.Request, device *authtypes.Device, cfg *config.Dendrite) util.JSONResponse { +func RequestTurnServer(req *http.Request, device *api.Device, cfg *config.Dendrite) util.JSONResponse { turnConfig := cfg.TURN // TODO Guest Support diff --git a/clientapi/routing/whoami.go b/clientapi/routing/whoami.go index 840bcb5f..26280f6c 100644 --- a/clientapi/routing/whoami.go +++ b/clientapi/routing/whoami.go @@ -15,7 +15,7 @@ package routing import ( "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" + "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/util" ) @@ -26,7 +26,7 @@ type whoamiResponse struct { // Whoami implements `/account/whoami` which enables client to query their account user id. // https://matrix.org/docs/spec/client_server/r0.3.0.html#get-matrix-client-r0-account-whoami -func Whoami(req *http.Request, device *authtypes.Device) util.JSONResponse { +func Whoami(req *http.Request, device *api.Device) util.JSONResponse { return util.JSONResponse{ Code: http.StatusOK, JSON: whoamiResponse{UserID: device.UserID}, diff --git a/clientapi/threepid/invites.go b/clientapi/threepid/invites.go index 11bf965d..d9da5c50 100644 --- a/clientapi/threepid/invites.go +++ b/clientapi/threepid/invites.go @@ -29,6 +29,7 @@ import ( "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" ) @@ -85,7 +86,7 @@ var ( // can be emitted. func CheckAndProcessInvite( ctx context.Context, - device *authtypes.Device, body *MembershipRequest, cfg *config.Dendrite, + device *userapi.Device, body *MembershipRequest, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI, db accounts.Database, membership string, roomID string, evTime time.Time, @@ -136,7 +137,7 @@ func CheckAndProcessInvite( // Returns an error if a check or a request failed. func queryIDServer( ctx context.Context, - db accounts.Database, cfg *config.Dendrite, device *authtypes.Device, + db accounts.Database, cfg *config.Dendrite, device *userapi.Device, body *MembershipRequest, roomID string, ) (lookupRes *idServerLookupResponse, storeInviteRes *idServerStoreInviteResponse, err error) { if err = isTrusted(body.IDServer, cfg); err != nil { @@ -205,7 +206,7 @@ func queryIDServerLookup(ctx context.Context, body *MembershipRequest) (*idServe // Returns an error if the request failed to send or if the response couldn't be parsed. func queryIDServerStoreInvite( ctx context.Context, - db accounts.Database, cfg *config.Dendrite, device *authtypes.Device, + db accounts.Database, cfg *config.Dendrite, device *userapi.Device, body *MembershipRequest, roomID string, ) (*idServerStoreInviteResponse, error) { // Retrieve the sender's profile to get their display name @@ -329,7 +330,7 @@ func checkIDServerSignatures( func emit3PIDInviteEvent( ctx context.Context, body *MembershipRequest, res *idServerStoreInviteResponse, - device *authtypes.Device, roomID string, cfg *config.Dendrite, + device *userapi.Device, roomID string, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI, evTime time.Time, ) error { diff --git a/cmd/dendrite-client-api-server/main.go b/cmd/dendrite-client-api-server/main.go index a28eb8b3..fe5f30a0 100644 --- a/cmd/dendrite-client-api-server/main.go +++ b/cmd/dendrite-client-api-server/main.go @@ -34,10 +34,11 @@ func main() { rsAPI := base.RoomserverHTTPClient() fsAPI := base.FederationSenderHTTPClient() eduInputAPI := base.EDUServerClient() + userAPI := base.UserAPIClient() clientapi.AddPublicRoutes( base.PublicAPIMux, base.Cfg, base.KafkaConsumer, base.KafkaProducer, deviceDB, accountDB, federation, - rsAPI, eduInputAPI, asQuery, transactions.New(), fsAPI, + rsAPI, eduInputAPI, asQuery, transactions.New(), fsAPI, userAPI, ) base.SetupAndServeHTTP(string(base.Cfg.Bind.ClientAPI), string(base.Cfg.Listen.ClientAPI)) diff --git a/cmd/dendrite-demo-libp2p/main.go b/cmd/dendrite-demo-libp2p/main.go index 0e757de9..51e1e2d5 100644 --- a/cmd/dendrite-demo-libp2p/main.go +++ b/cmd/dendrite-demo-libp2p/main.go @@ -37,6 +37,7 @@ import ( "github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/serverkeyapi" + "github.com/matrix-org/dendrite/userapi" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/dendrite/eduserver/cache" @@ -152,6 +153,7 @@ func main() { if err != nil { logrus.WithError(err).Panicf("failed to connect to public rooms db") } + userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, nil) monolith := setup.Monolith{ Config: base.Base.Cfg, @@ -167,6 +169,7 @@ func main() { FederationSenderAPI: fsAPI, RoomserverAPI: rsAPI, ServerKeyAPI: serverKeyAPI, + UserAPI: userAPI, PublicRoomsDB: publicRoomsDB, } diff --git a/cmd/dendrite-demo-yggdrasil/main.go b/cmd/dendrite-demo-yggdrasil/main.go index 6923b68b..c6a7286e 100644 --- a/cmd/dendrite-demo-yggdrasil/main.go +++ b/cmd/dendrite-demo-yggdrasil/main.go @@ -39,6 +39,7 @@ import ( "github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/roomserver" + "github.com/matrix-org/dendrite/userapi" "github.com/matrix-org/gomatrixserverlib" "github.com/sirupsen/logrus" @@ -155,6 +156,7 @@ func main() { } embed.Embed(*instancePort, "Yggdrasil Demo") + userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, nil) monolith := setup.Monolith{ Config: base.Cfg, @@ -169,6 +171,7 @@ func main() { EDUInternalAPI: eduInputAPI, FederationSenderAPI: fsAPI, RoomserverAPI: rsAPI, + UserAPI: userAPI, //ServerKeyAPI: serverKeyAPI, PublicRoomsDB: publicRoomsDB, diff --git a/cmd/dendrite-key-server/main.go b/cmd/dendrite-key-server/main.go index 06629d39..b557cbd9 100644 --- a/cmd/dendrite-key-server/main.go +++ b/cmd/dendrite-key-server/main.go @@ -24,10 +24,9 @@ func main() { base := setup.NewBaseDendrite(cfg, "KeyServer", true) defer base.Close() // nolint: errcheck - accountDB := base.CreateAccountsDB() - deviceDB := base.CreateDeviceDB() + userAPI := base.UserAPIClient() - keyserver.AddPublicRoutes(base.PublicAPIMux, base.Cfg, deviceDB, accountDB) + keyserver.AddPublicRoutes(base.PublicAPIMux, base.Cfg, userAPI) base.SetupAndServeHTTP(string(base.Cfg.Bind.KeyServer), string(base.Cfg.Listen.KeyServer)) diff --git a/cmd/dendrite-media-api-server/main.go b/cmd/dendrite-media-api-server/main.go index 52c76027..8fd80d7b 100644 --- a/cmd/dendrite-media-api-server/main.go +++ b/cmd/dendrite-media-api-server/main.go @@ -24,9 +24,9 @@ func main() { base := setup.NewBaseDendrite(cfg, "MediaAPI", true) defer base.Close() // nolint: errcheck - deviceDB := base.CreateDeviceDB() + userAPI := base.UserAPIClient() - mediaapi.AddPublicRoutes(base.PublicAPIMux, base.Cfg, deviceDB) + mediaapi.AddPublicRoutes(base.PublicAPIMux, base.Cfg, userAPI) base.SetupAndServeHTTP(string(base.Cfg.Bind.MediaAPI), string(base.Cfg.Listen.MediaAPI)) diff --git a/cmd/dendrite-monolith-server/main.go b/cmd/dendrite-monolith-server/main.go index 3a0a84ef..675474b8 100644 --- a/cmd/dendrite-monolith-server/main.go +++ b/cmd/dendrite-monolith-server/main.go @@ -30,6 +30,7 @@ import ( "github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/serverkeyapi" + "github.com/matrix-org/dendrite/userapi" "github.com/sirupsen/logrus" ) @@ -119,6 +120,8 @@ func main() { logrus.WithError(err).Panicf("failed to connect to public rooms db") } + userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, cfg.Derived.ApplicationServices) + monolith := setup.Monolith{ Config: base.Cfg, AccountDB: accountDB, @@ -133,6 +136,7 @@ func main() { FederationSenderAPI: fsAPI, RoomserverAPI: rsAPI, ServerKeyAPI: serverKeyAPI, + UserAPI: userAPI, PublicRoomsDB: publicRoomsDB, } diff --git a/cmd/dendrite-public-rooms-api-server/main.go b/cmd/dendrite-public-rooms-api-server/main.go index 3ba45dc6..23866b75 100644 --- a/cmd/dendrite-public-rooms-api-server/main.go +++ b/cmd/dendrite-public-rooms-api-server/main.go @@ -26,7 +26,7 @@ func main() { base := setup.NewBaseDendrite(cfg, "PublicRoomsAPI", true) defer base.Close() // nolint: errcheck - deviceDB := base.CreateDeviceDB() + userAPI := base.UserAPIClient() rsAPI := base.RoomserverHTTPClient() @@ -34,7 +34,7 @@ func main() { if err != nil { logrus.WithError(err).Panicf("failed to connect to public rooms db") } - publicroomsapi.AddPublicRoutes(base.PublicAPIMux, base.Cfg, base.KafkaConsumer, deviceDB, publicRoomsDB, rsAPI, nil, nil) + publicroomsapi.AddPublicRoutes(base.PublicAPIMux, base.Cfg, base.KafkaConsumer, userAPI, publicRoomsDB, rsAPI, nil, nil) base.SetupAndServeHTTP(string(base.Cfg.Bind.PublicRoomsAPI), string(base.Cfg.Listen.PublicRoomsAPI)) diff --git a/cmd/dendrite-sync-api-server/main.go b/cmd/dendrite-sync-api-server/main.go index 41e79680..a17b648d 100644 --- a/cmd/dendrite-sync-api-server/main.go +++ b/cmd/dendrite-sync-api-server/main.go @@ -24,13 +24,13 @@ func main() { base := setup.NewBaseDendrite(cfg, "SyncAPI", true) defer base.Close() // nolint: errcheck - deviceDB := base.CreateDeviceDB() + userAPI := base.UserAPIClient() accountDB := base.CreateAccountsDB() federation := base.CreateFederationClient() rsAPI := base.RoomserverHTTPClient() - syncapi.AddPublicRoutes(base.PublicAPIMux, base.KafkaConsumer, deviceDB, accountDB, rsAPI, federation, cfg) + syncapi.AddPublicRoutes(base.PublicAPIMux, base.KafkaConsumer, userAPI, accountDB, rsAPI, federation, cfg) base.SetupAndServeHTTP(string(base.Cfg.Bind.SyncAPI), string(base.Cfg.Listen.SyncAPI)) diff --git a/cmd/dendritejs/main.go b/cmd/dendritejs/main.go index 8c19eb6d..7930c28d 100644 --- a/cmd/dendritejs/main.go +++ b/cmd/dendritejs/main.go @@ -30,6 +30,7 @@ import ( "github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/roomserver" + "github.com/matrix-org/dendrite/userapi" go_http_js_libp2p "github.com/matrix-org/go-http-js-libp2p" "github.com/matrix-org/gomatrixserverlib" @@ -211,6 +212,8 @@ func main() { logrus.WithError(err).Panicf("failed to connect to public rooms db") } + userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, nil) + monolith := setup.Monolith{ Config: base.Cfg, AccountDB: accountDB, @@ -224,6 +227,7 @@ func main() { EDUInternalAPI: eduInputAPI, FederationSenderAPI: fedSenderAPI, RoomserverAPI: rsAPI, + UserAPI: userAPI, //ServerKeyAPI: serverKeyAPI, PublicRoomsDB: publicRoomsDB, diff --git a/dendrite-config.yaml b/dendrite-config.yaml index a5b29597..52793cda 100644 --- a/dendrite-config.yaml +++ b/dendrite-config.yaml @@ -140,6 +140,7 @@ listen: edu_server: "localhost:7778" key_server: "localhost:7779" server_key_api: "localhost:7780" + user_api: "localhost:7781" # The configuration for tracing the dendrite components. tracing: diff --git a/internal/config/config.go b/internal/config/config.go index bff4945b..2bd56ad9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -241,6 +241,7 @@ type Dendrite struct { ServerKeyAPI Address `yaml:"server_key_api"` AppServiceAPI Address `yaml:"appservice_api"` SyncAPI Address `yaml:"sync_api"` + UserAPI Address `yaml:"user_api"` RoomServer Address `yaml:"room_server"` FederationSender Address `yaml:"federation_sender"` PublicRoomsAPI Address `yaml:"public_rooms_api"` @@ -610,6 +611,7 @@ func (config *Dendrite) checkListen(configErrs *configErrors) { checkNotEmpty(configErrs, "listen.room_server", string(config.Listen.RoomServer)) checkNotEmpty(configErrs, "listen.edu_server", string(config.Listen.EDUServer)) checkNotEmpty(configErrs, "listen.server_key_api", string(config.Listen.EDUServer)) + checkNotEmpty(configErrs, "listen.user_api", string(config.Listen.UserAPI)) } // checkLogging verifies the parameters logging.* are valid. @@ -723,6 +725,15 @@ func (config *Dendrite) RoomServerURL() string { return "http://" + string(config.Listen.RoomServer) } +// UserAPIURL returns an HTTP URL for where the userapi is listening. +func (config *Dendrite) UserAPIURL() string { + // Hard code the userapi to talk HTTP for now. + // If we support HTTPS we need to think of a practical way to do certificate validation. + // People setting up servers shouldn't need to get a certificate valid for the public + // internet for an internal API. + return "http://" + string(config.Listen.UserAPI) +} + // EDUServerURL returns an HTTP URL for where the EDU server is listening. func (config *Dendrite) EDUServerURL() string { // Hard code the EDU server to talk HTTP for now. diff --git a/internal/config/config_test.go b/internal/config/config_test.go index b72f5fad..9a543e76 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -63,6 +63,7 @@ listen: media_api: "localhost:7774" appservice_api: "localhost:7777" edu_server: "localhost:7778" + user_api: "localhost:7779" logging: - type: "file" level: "info" diff --git a/internal/httputil/httpapi.go b/internal/httputil/httpapi.go index a35a10d6..d371d172 100644 --- a/internal/httputil/httpapi.go +++ b/internal/httputil/httpapi.go @@ -27,9 +27,9 @@ import ( "github.com/gorilla/mux" "github.com/matrix-org/dendrite/clientapi/auth" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" federationsenderAPI "github.com/matrix-org/dendrite/federationsender/api" "github.com/matrix-org/dendrite/internal/config" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" opentracing "github.com/opentracing/opentracing-go" @@ -48,11 +48,11 @@ type BasicAuth struct { // MakeAuthAPI turns a util.JSONRequestHandler function into an http.Handler which authenticates the request. func MakeAuthAPI( - metricsName string, data auth.Data, - f func(*http.Request, *authtypes.Device) util.JSONResponse, + metricsName string, userAPI userapi.UserInternalAPI, + f func(*http.Request, *userapi.Device) util.JSONResponse, ) http.Handler { h := func(req *http.Request) util.JSONResponse { - device, err := auth.VerifyUserFromRequest(req, data) + device, err := auth.VerifyUserFromRequest(req, userAPI) if err != nil { return *err } diff --git a/internal/setup/base.go b/internal/setup/base.go index 59bdfd2e..e287cfbd 100644 --- a/internal/setup/base.go +++ b/internal/setup/base.go @@ -46,6 +46,8 @@ import ( rsinthttp "github.com/matrix-org/dendrite/roomserver/inthttp" serverKeyAPI "github.com/matrix-org/dendrite/serverkeyapi/api" skinthttp "github.com/matrix-org/dendrite/serverkeyapi/inthttp" + userapi "github.com/matrix-org/dendrite/userapi/api" + userapiinthttp "github.com/matrix-org/dendrite/userapi/inthttp" "github.com/sirupsen/logrus" _ "net/http/pprof" @@ -160,6 +162,15 @@ func (b *BaseDendrite) RoomserverHTTPClient() roomserverAPI.RoomserverInternalAP return rsAPI } +// UserAPIClient returns UserInternalAPI for hitting the userapi over HTTP. +func (b *BaseDendrite) UserAPIClient() userapi.UserInternalAPI { + userAPI, err := userapiinthttp.NewUserAPIClient(b.Cfg.UserAPIURL(), b.httpClient) + if err != nil { + logrus.WithError(err).Panic("UserAPIClient failed", b.httpClient) + } + return userAPI +} + // EDUServerClient returns EDUServerInputAPI for hitting the EDU server over HTTP func (b *BaseDendrite) EDUServerClient() eduServerAPI.EDUServerInputAPI { e, err := eduinthttp.NewEDUServerClient(b.Cfg.EDUServerURL(), b.httpClient) diff --git a/internal/setup/monolith.go b/internal/setup/monolith.go index 4dfbf711..f28fea8f 100644 --- a/internal/setup/monolith.go +++ b/internal/setup/monolith.go @@ -34,6 +34,7 @@ import ( roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" serverKeyAPI "github.com/matrix-org/dendrite/serverkeyapi/api" "github.com/matrix-org/dendrite/syncapi" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" ) @@ -53,6 +54,7 @@ type Monolith struct { FederationSenderAPI federationSenderAPI.FederationSenderInternalAPI RoomserverAPI roomserverAPI.RoomserverInternalAPI ServerKeyAPI serverKeyAPI.ServerKeyInternalAPI + UserAPI userapi.UserInternalAPI // TODO: can we remove this? It's weird that we are required the database // yet every other component can do that on its own. libp2p-demo uses a custom @@ -69,21 +71,21 @@ func (m *Monolith) AddAllPublicRoutes(publicMux *mux.Router) { publicMux, m.Config, m.KafkaConsumer, m.KafkaProducer, m.DeviceDB, m.AccountDB, m.FedClient, m.RoomserverAPI, m.EDUInternalAPI, m.AppserviceAPI, transactions.New(), - m.FederationSenderAPI, + m.FederationSenderAPI, m.UserAPI, ) - keyserver.AddPublicRoutes(publicMux, m.Config, m.DeviceDB, m.AccountDB) + keyserver.AddPublicRoutes(publicMux, m.Config, m.UserAPI) federationapi.AddPublicRoutes( publicMux, m.Config, m.AccountDB, m.DeviceDB, m.FedClient, m.KeyRing, m.RoomserverAPI, m.AppserviceAPI, m.FederationSenderAPI, m.EDUInternalAPI, ) - mediaapi.AddPublicRoutes(publicMux, m.Config, m.DeviceDB) + mediaapi.AddPublicRoutes(publicMux, m.Config, m.UserAPI) publicroomsapi.AddPublicRoutes( - publicMux, m.Config, m.KafkaConsumer, m.DeviceDB, m.PublicRoomsDB, m.RoomserverAPI, m.FedClient, + publicMux, m.Config, m.KafkaConsumer, m.UserAPI, m.PublicRoomsDB, m.RoomserverAPI, m.FedClient, m.ExtPublicRoomsProvider, ) syncapi.AddPublicRoutes( - publicMux, m.KafkaConsumer, m.DeviceDB, m.AccountDB, m.RoomserverAPI, m.FedClient, m.Config, + publicMux, m.KafkaConsumer, m.UserAPI, m.AccountDB, m.RoomserverAPI, m.FedClient, m.Config, ) } diff --git a/keyserver/keyserver.go b/keyserver/keyserver.go index 1eb73054..bedc4dfb 100644 --- a/keyserver/keyserver.go +++ b/keyserver/keyserver.go @@ -16,17 +16,14 @@ package keyserver import ( "github.com/gorilla/mux" - "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" - "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/keyserver/routing" + userapi "github.com/matrix-org/dendrite/userapi/api" ) // AddPublicRoutes registers HTTP handlers for CS API calls func AddPublicRoutes( - router *mux.Router, cfg *config.Dendrite, - deviceDB devices.Database, - accountsDB accounts.Database, + router *mux.Router, cfg *config.Dendrite, userAPI userapi.UserInternalAPI, ) { - routing.Setup(router, cfg, accountsDB, deviceDB) + routing.Setup(router, cfg, userAPI) } diff --git a/keyserver/routing/routing.go b/keyserver/routing/routing.go index bce3c46b..c09031d8 100644 --- a/keyserver/routing/routing.go +++ b/keyserver/routing/routing.go @@ -18,12 +18,9 @@ import ( "net/http" "github.com/gorilla/mux" - "github.com/matrix-org/dendrite/clientapi/auth" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" - "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" - "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/httputil" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/util" ) @@ -36,20 +33,11 @@ const pathPrefixR0 = "/client/r0" // applied: // nolint: gocyclo func Setup( - publicAPIMux *mux.Router, cfg *config.Dendrite, - accountDB accounts.Database, - deviceDB devices.Database, + publicAPIMux *mux.Router, cfg *config.Dendrite, userAPI userapi.UserInternalAPI, ) { r0mux := publicAPIMux.PathPrefix(pathPrefixR0).Subrouter() - - authData := auth.Data{ - AccountDB: accountDB, - DeviceDB: deviceDB, - AppServices: cfg.Derived.ApplicationServices, - } - r0mux.Handle("/keys/query", - httputil.MakeAuthAPI("queryKeys", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("queryKeys", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { return QueryKeys(req) }), ).Methods(http.MethodPost, http.MethodOptions) diff --git a/mediaapi/mediaapi.go b/mediaapi/mediaapi.go index d4e260ea..9219ba20 100644 --- a/mediaapi/mediaapi.go +++ b/mediaapi/mediaapi.go @@ -16,18 +16,17 @@ package mediaapi import ( "github.com/gorilla/mux" - "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/mediaapi/routing" "github.com/matrix-org/dendrite/mediaapi/storage" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/sirupsen/logrus" ) // AddPublicRoutes sets up and registers HTTP handlers for the MediaAPI component. func AddPublicRoutes( - router *mux.Router, cfg *config.Dendrite, - deviceDB devices.Database, + router *mux.Router, cfg *config.Dendrite, userAPI userapi.UserInternalAPI, ) { mediaDB, err := storage.Open(string(cfg.Database.MediaAPI), cfg.DbProperties()) if err != nil { @@ -35,6 +34,6 @@ func AddPublicRoutes( } routing.Setup( - router, cfg, mediaDB, deviceDB, gomatrixserverlib.NewClient(), + router, cfg, mediaDB, userAPI, gomatrixserverlib.NewClient(), ) } diff --git a/mediaapi/routing/routing.go b/mediaapi/routing/routing.go index 6bcd3f55..71804606 100644 --- a/mediaapi/routing/routing.go +++ b/mediaapi/routing/routing.go @@ -17,11 +17,9 @@ package routing import ( "net/http" - "github.com/matrix-org/dendrite/clientapi/auth" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/gorilla/mux" - "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/httputil" "github.com/matrix-org/dendrite/mediaapi/storage" @@ -44,7 +42,7 @@ func Setup( publicAPIMux *mux.Router, cfg *config.Dendrite, db storage.Database, - deviceDB devices.Database, + userAPI userapi.UserInternalAPI, client *gomatrixserverlib.Client, ) { r0mux := publicAPIMux.PathPrefix(pathPrefixR0).Subrouter() @@ -52,16 +50,9 @@ func Setup( activeThumbnailGeneration := &types.ActiveThumbnailGeneration{ PathToResult: map[string]*types.ThumbnailGenerationResult{}, } - authData := auth.Data{ - AccountDB: nil, - DeviceDB: deviceDB, - AppServices: nil, - } - - // TODO: Add AS support r0mux.Handle("/upload", httputil.MakeAuthAPI( - "upload", authData, - func(req *http.Request, _ *authtypes.Device) util.JSONResponse { + "upload", userAPI, + func(req *http.Request, _ *userapi.Device) util.JSONResponse { return Upload(req, cfg, db, activeThumbnailGeneration) }, )).Methods(http.MethodPost, http.MethodOptions) diff --git a/publicroomsapi/directory/directory.go b/publicroomsapi/directory/directory.go index fe7a6793..8b68279a 100644 --- a/publicroomsapi/directory/directory.go +++ b/publicroomsapi/directory/directory.go @@ -17,8 +17,8 @@ package directory import ( "net/http" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" @@ -59,7 +59,7 @@ func GetVisibility( // SetVisibility implements PUT /directory/list/room/{roomID} // TODO: Allow admin users to edit the room visibility func SetVisibility( - req *http.Request, publicRoomsDatabase storage.Database, rsAPI api.RoomserverInternalAPI, dev *authtypes.Device, + req *http.Request, publicRoomsDatabase storage.Database, rsAPI api.RoomserverInternalAPI, dev *userapi.Device, roomID string, ) util.JSONResponse { queryMembershipReq := api.QueryMembershipForUserRequest{ diff --git a/publicroomsapi/publicroomsapi.go b/publicroomsapi/publicroomsapi.go index 1f98a4e0..b9baa105 100644 --- a/publicroomsapi/publicroomsapi.go +++ b/publicroomsapi/publicroomsapi.go @@ -17,13 +17,13 @@ package publicroomsapi import ( "github.com/Shopify/sarama" "github.com/gorilla/mux" - "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/publicroomsapi/consumers" "github.com/matrix-org/dendrite/publicroomsapi/routing" "github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/publicroomsapi/types" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/sirupsen/logrus" ) @@ -34,7 +34,7 @@ func AddPublicRoutes( router *mux.Router, cfg *config.Dendrite, consumer sarama.Consumer, - deviceDB devices.Database, + userAPI userapi.UserInternalAPI, publicRoomsDB storage.Database, rsAPI roomserverAPI.RoomserverInternalAPI, fedClient *gomatrixserverlib.FederationClient, @@ -47,5 +47,5 @@ func AddPublicRoutes( logrus.WithError(err).Panic("failed to start public rooms server consumer") } - routing.Setup(router, deviceDB, publicRoomsDB, rsAPI, fedClient, extRoomsProvider) + routing.Setup(router, userAPI, publicRoomsDB, rsAPI, fedClient, extRoomsProvider) } diff --git a/publicroomsapi/routing/routing.go b/publicroomsapi/routing/routing.go index 2da555f9..9c82d350 100644 --- a/publicroomsapi/routing/routing.go +++ b/publicroomsapi/routing/routing.go @@ -19,11 +19,9 @@ import ( "github.com/matrix-org/dendrite/internal/httputil" "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/gorilla/mux" - "github.com/matrix-org/dendrite/clientapi/auth" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" - "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/publicroomsapi/directory" "github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/publicroomsapi/types" @@ -39,17 +37,11 @@ const pathPrefixR0 = "/client/r0" // applied: // nolint: gocyclo func Setup( - publicAPIMux *mux.Router, deviceDB devices.Database, publicRoomsDB storage.Database, rsAPI api.RoomserverInternalAPI, + publicAPIMux *mux.Router, userAPI userapi.UserInternalAPI, publicRoomsDB storage.Database, rsAPI api.RoomserverInternalAPI, fedClient *gomatrixserverlib.FederationClient, extRoomsProvider types.ExternalPublicRoomsProvider, ) { r0mux := publicAPIMux.PathPrefix(pathPrefixR0).Subrouter() - authData := auth.Data{ - AccountDB: nil, - DeviceDB: deviceDB, - AppServices: nil, - } - r0mux.Handle("/directory/list/room/{roomID}", httputil.MakeExternalAPI("directory_list", func(req *http.Request) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) @@ -61,7 +53,7 @@ func Setup( ).Methods(http.MethodGet, http.MethodOptions) // TODO: Add AS support r0mux.Handle("/directory/list/room/{roomID}", - httputil.MakeAuthAPI("directory_list", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + httputil.MakeAuthAPI("directory_list", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) diff --git a/syncapi/routing/routing.go b/syncapi/routing/routing.go index 50b46917..5744de05 100644 --- a/syncapi/routing/routing.go +++ b/syncapi/routing/routing.go @@ -18,14 +18,12 @@ import ( "net/http" "github.com/gorilla/mux" - "github.com/matrix-org/dendrite/clientapi/auth" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" - "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/httputil" "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/syncapi/storage" "github.com/matrix-org/dendrite/syncapi/sync" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) @@ -39,24 +37,18 @@ const pathPrefixR0 = "/client/r0" // nolint: gocyclo func Setup( publicAPIMux *mux.Router, srp *sync.RequestPool, syncDB storage.Database, - deviceDB devices.Database, federation *gomatrixserverlib.FederationClient, + userAPI userapi.UserInternalAPI, federation *gomatrixserverlib.FederationClient, rsAPI api.RoomserverInternalAPI, cfg *config.Dendrite, ) { r0mux := publicAPIMux.PathPrefix(pathPrefixR0).Subrouter() - authData := auth.Data{ - AccountDB: nil, - DeviceDB: deviceDB, - AppServices: nil, - } - // TODO: Add AS support for all handlers below. - r0mux.Handle("/sync", httputil.MakeAuthAPI("sync", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + r0mux.Handle("/sync", httputil.MakeAuthAPI("sync", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { return srp.OnIncomingSyncRequest(req, device) })).Methods(http.MethodGet, http.MethodOptions) - r0mux.Handle("/rooms/{roomID}/messages", httputil.MakeAuthAPI("room_messages", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse { + r0mux.Handle("/rooms/{roomID}/messages", httputil.MakeAuthAPI("room_messages", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) if err != nil { return util.ErrorResponse(err) diff --git a/syncapi/storage/interface.go b/syncapi/storage/interface.go index 566e5d58..7b3bd678 100644 --- a/syncapi/storage/interface.go +++ b/syncapi/storage/interface.go @@ -18,11 +18,11 @@ import ( "context" "time" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/syncapi/types" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" ) @@ -57,10 +57,10 @@ type Database interface { // from when the device sent the event via an API that included a transaction // ID. A response object must be provided for IncrementaSync to populate - it // will not create one. - IncrementalSync(ctx context.Context, res *types.Response, device authtypes.Device, fromPos, toPos types.StreamingToken, numRecentEventsPerRoom int, wantFullState bool) (*types.Response, error) + IncrementalSync(ctx context.Context, res *types.Response, device userapi.Device, fromPos, toPos types.StreamingToken, numRecentEventsPerRoom int, wantFullState bool) (*types.Response, error) // CompleteSync returns a complete /sync API response for the given user. A response object // must be provided for CompleteSync to populate - it will not create one. - CompleteSync(ctx context.Context, res *types.Response, device authtypes.Device, numRecentEventsPerRoom int) (*types.Response, error) + CompleteSync(ctx context.Context, res *types.Response, device userapi.Device, numRecentEventsPerRoom int) (*types.Response, error) // GetAccountDataInRange returns all account data for a given user inserted or // updated between two given positions // Returns a map following the format data[roomID] = []dataTypes @@ -103,7 +103,7 @@ type Database interface { // StreamEventsToEvents converts streamEvent to Event. If device is non-nil and // matches the streamevent.transactionID device then the transaction ID gets // added to the unsigned section of the output event. - StreamEventsToEvents(device *authtypes.Device, in []types.StreamEvent) []gomatrixserverlib.HeaderedEvent + StreamEventsToEvents(device *userapi.Device, in []types.StreamEvent) []gomatrixserverlib.HeaderedEvent // SyncStreamPosition returns the latest position in the sync stream. Returns 0 if there are no events yet. SyncStreamPosition(ctx context.Context) (types.StreamPosition, error) // AddSendToDevice increases the EDU position in the cache and returns the stream position. diff --git a/syncapi/storage/shared/syncserver.go b/syncapi/storage/shared/syncserver.go index 21d8df37..74ae3eab 100644 --- a/syncapi/storage/shared/syncserver.go +++ b/syncapi/storage/shared/syncserver.go @@ -21,7 +21,8 @@ import ( "fmt" "time" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" + userapi "github.com/matrix-org/dendrite/userapi/api" + "github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/roomserver/api" @@ -214,7 +215,7 @@ func (d *Database) UpsertAccountData( return } -func (d *Database) StreamEventsToEvents(device *authtypes.Device, in []types.StreamEvent) []gomatrixserverlib.HeaderedEvent { +func (d *Database) StreamEventsToEvents(device *userapi.Device, in []types.StreamEvent) []gomatrixserverlib.HeaderedEvent { out := make([]gomatrixserverlib.HeaderedEvent, len(in)) for i := 0; i < len(in); i++ { out[i] = in[i].HeaderedEvent @@ -442,7 +443,7 @@ func (d *Database) syncPositionTx( // IDs of all rooms the user joined are returned so EDU deltas can be added for them. func (d *Database) addPDUDeltaToResponse( ctx context.Context, - device authtypes.Device, + device userapi.Device, r types.Range, numRecentEventsPerRoom int, wantFullState bool, @@ -549,7 +550,7 @@ func (d *Database) addEDUDeltaToResponse( func (d *Database) IncrementalSync( ctx context.Context, res *types.Response, - device authtypes.Device, + device userapi.Device, fromPos, toPos types.StreamingToken, numRecentEventsPerRoom int, wantFullState bool, @@ -687,7 +688,7 @@ func (d *Database) getResponseWithPDUsForCompleteSync( func (d *Database) CompleteSync( ctx context.Context, res *types.Response, - device authtypes.Device, numRecentEventsPerRoom int, + device userapi.Device, numRecentEventsPerRoom int, ) (*types.Response, error) { toPos, joinedRoomIDs, err := d.getResponseWithPDUsForCompleteSync( ctx, res, device.UserID, numRecentEventsPerRoom, @@ -758,7 +759,7 @@ func (d *Database) getBackwardTopologyPos( // addRoomDeltaToResponse adds a room state delta to a sync response func (d *Database) addRoomDeltaToResponse( ctx context.Context, - device *authtypes.Device, + device *userapi.Device, txn *sql.Tx, r types.Range, delta stateDelta, @@ -904,7 +905,7 @@ func (d *Database) fetchMissingStateEvents( // the user has new membership events. // A list of joined room IDs is also returned in case the caller needs it. func (d *Database) getStateDeltas( - ctx context.Context, device *authtypes.Device, txn *sql.Tx, + ctx context.Context, device *userapi.Device, txn *sql.Tx, r types.Range, userID string, stateFilter *gomatrixserverlib.StateFilter, ) ([]stateDelta, []string, error) { @@ -979,7 +980,7 @@ func (d *Database) getStateDeltas( // Fetches full state for all joined rooms and uses selectStateInRange to get // updates for other rooms. func (d *Database) getStateDeltasForFullStateSync( - ctx context.Context, device *authtypes.Device, txn *sql.Tx, + ctx context.Context, device *userapi.Device, txn *sql.Tx, r types.Range, userID string, stateFilter *gomatrixserverlib.StateFilter, ) ([]stateDelta, []string, error) { diff --git a/syncapi/storage/storage_test.go b/syncapi/storage/storage_test.go index 4661ede4..85084fac 100644 --- a/syncapi/storage/storage_test.go +++ b/syncapi/storage/storage_test.go @@ -8,10 +8,10 @@ import ( "testing" "time" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/syncapi/storage" "github.com/matrix-org/dendrite/syncapi/storage/sqlite3" "github.com/matrix-org/dendrite/syncapi/types" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" ) @@ -22,7 +22,7 @@ var ( testRoomID = fmt.Sprintf("!hallownest:%s", testOrigin) testUserIDA = fmt.Sprintf("@hornet:%s", testOrigin) testUserIDB = fmt.Sprintf("@paleking:%s", testOrigin) - testUserDeviceA = authtypes.Device{ + testUserDeviceA = userapi.Device{ UserID: testUserIDA, ID: "device_id_A", DisplayName: "Device A", diff --git a/syncapi/sync/notifier_test.go b/syncapi/sync/notifier_test.go index 13231557..ecc4fcbf 100644 --- a/syncapi/sync/notifier_test.go +++ b/syncapi/sync/notifier_test.go @@ -22,9 +22,8 @@ import ( "testing" "time" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" - "github.com/matrix-org/dendrite/syncapi/types" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" ) @@ -357,7 +356,7 @@ func lockedFetchUserStream(n *Notifier, userID, deviceID string) *UserDeviceStre func newTestSyncRequest(userID, deviceID string, since types.StreamingToken) syncRequest { return syncRequest{ - device: authtypes.Device{ + device: userapi.Device{ UserID: userID, ID: deviceID, }, diff --git a/syncapi/sync/request.go b/syncapi/sync/request.go index c7796b56..beeaa40f 100644 --- a/syncapi/sync/request.go +++ b/syncapi/sync/request.go @@ -21,9 +21,8 @@ import ( "strconv" "time" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" - "github.com/matrix-org/dendrite/syncapi/types" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/util" log "github.com/sirupsen/logrus" ) @@ -42,7 +41,7 @@ type filter struct { // syncRequest represents a /sync request, with sensible defaults/sanity checks applied. type syncRequest struct { ctx context.Context - device authtypes.Device + device userapi.Device limit int timeout time.Duration since *types.StreamingToken // nil means that no since token was supplied @@ -50,7 +49,7 @@ type syncRequest struct { log *log.Entry } -func newSyncRequest(req *http.Request, device authtypes.Device) (*syncRequest, error) { +func newSyncRequest(req *http.Request, device userapi.Device) (*syncRequest, error) { timeout := getTimeout(req.URL.Query().Get("timeout")) fullState := req.URL.Query().Get("full_state") wantFullState := fullState != "" && fullState != "false" diff --git a/syncapi/sync/requestpool.go b/syncapi/sync/requestpool.go index 8b93cad4..ec22a05f 100644 --- a/syncapi/sync/requestpool.go +++ b/syncapi/sync/requestpool.go @@ -21,11 +21,11 @@ import ( "net/http" "time" - "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/syncapi/storage" "github.com/matrix-org/dendrite/syncapi/types" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" log "github.com/sirupsen/logrus" @@ -46,7 +46,7 @@ func NewRequestPool(db storage.Database, n *Notifier, adb accounts.Database) *Re // OnIncomingSyncRequest is called when a client makes a /sync request. This function MUST be // called in a dedicated goroutine for this request. This function will block the goroutine // until a response is ready, or it times out. -func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *authtypes.Device) util.JSONResponse { +func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *userapi.Device) util.JSONResponse { var syncData *types.Response // Extract values from request diff --git a/syncapi/syncapi.go b/syncapi/syncapi.go index 40e652af..2351ee4d 100644 --- a/syncapi/syncapi.go +++ b/syncapi/syncapi.go @@ -24,9 +24,9 @@ import ( "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/roomserver/api" + userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" - "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/syncapi/consumers" "github.com/matrix-org/dendrite/syncapi/routing" "github.com/matrix-org/dendrite/syncapi/storage" @@ -38,7 +38,7 @@ import ( func AddPublicRoutes( router *mux.Router, consumer sarama.Consumer, - deviceDB devices.Database, + userAPI userapi.UserInternalAPI, accountsDB accounts.Database, rsAPI api.RoomserverInternalAPI, federation *gomatrixserverlib.FederationClient, @@ -90,5 +90,5 @@ func AddPublicRoutes( logrus.WithError(err).Panicf("failed to start send-to-device consumer") } - routing.Setup(router, requestPool, syncDB, deviceDB, federation, rsAPI, cfg) + routing.Setup(router, requestPool, syncDB, userAPI, federation, rsAPI, cfg) } diff --git a/userapi/api/api.go b/userapi/api/api.go index 8534fb17..57b5165a 100644 --- a/userapi/api/api.go +++ b/userapi/api/api.go @@ -19,6 +19,21 @@ import "context" // UserInternalAPI is the internal API for information about users and devices. type UserInternalAPI interface { QueryProfile(ctx context.Context, req *QueryProfileRequest, res *QueryProfileResponse) error + QueryAccessToken(ctx context.Context, req *QueryAccessTokenRequest, res *QueryAccessTokenResponse) error +} + +// QueryAccessTokenRequest is the request for QueryAccessToken +type QueryAccessTokenRequest struct { + AccessToken string + // optional user ID, valid only if the token is an appservice. + // https://matrix.org/docs/spec/application_service/r0.1.2#using-sync-and-events + AppServiceUserID string +} + +// QueryAccessTokenResponse is the response for QueryAccessToken +type QueryAccessTokenResponse struct { + Device *Device + Err error // e.g ErrorForbidden } // QueryProfileRequest is the request for QueryProfile @@ -29,10 +44,34 @@ type QueryProfileRequest struct { // QueryProfileResponse is the response for QueryProfile type QueryProfileResponse struct { - // True if the user has been created. Querying for a profile does not create them. + // True if the user exists. Querying for a profile does not create them. UserExists bool // The current display name if set. DisplayName string // The current avatar URL if set. AvatarURL string } + +// Device represents a client's device (mobile, web, etc) +type Device struct { + ID string + UserID string + // The access_token granted to this device. + // This uniquely identifies the device from all other devices and clients. + AccessToken string + // The unique ID of the session identified by the access token. + // Can be used as a secure substitution in places where data needs to be + // associated with access tokens. + SessionID int64 + // TODO: display name, last used timestamp, keys, etc + DisplayName string +} + +// ErrorForbidden is an error indicating that the supplied access token is forbidden +type ErrorForbidden struct { + Message string +} + +func (e *ErrorForbidden) Error() string { + return "Forbidden: " + e.Message +} diff --git a/userapi/internal/api.go b/userapi/internal/api.go index 0144526c..1f0d5c94 100644 --- a/userapi/internal/api.go +++ b/userapi/internal/api.go @@ -19,8 +19,11 @@ import ( "database/sql" "fmt" + "github.com/matrix-org/dendrite/appservice/types" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" + "github.com/matrix-org/dendrite/clientapi/userutil" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" ) @@ -29,6 +32,8 @@ type UserInternalAPI struct { AccountDB accounts.Database DeviceDB devices.Database ServerName gomatrixserverlib.ServerName + // AppServices is the list of all registered AS + AppServices []config.ApplicationService } func (a *UserInternalAPI) QueryProfile(ctx context.Context, req *api.QueryProfileRequest, res *api.QueryProfileResponse) error { @@ -51,3 +56,66 @@ func (a *UserInternalAPI) QueryProfile(ctx context.Context, req *api.QueryProfil res.DisplayName = prof.DisplayName return nil } + +func (a *UserInternalAPI) QueryAccessToken(ctx context.Context, req *api.QueryAccessTokenRequest, res *api.QueryAccessTokenResponse) error { + if req.AppServiceUserID != "" { + appServiceDevice, err := a.queryAppServiceToken(ctx, req.AccessToken, req.AppServiceUserID) + res.Device = appServiceDevice + res.Err = err + return nil + } + device, err := a.DeviceDB.GetDeviceByAccessToken(ctx, req.AccessToken) + if err != nil { + if err == sql.ErrNoRows { + return nil + } + return err + } + res.Device = device + return nil +} + +// Return the appservice 'device' or nil if the token is not an appservice. Returns an error if there was a problem +// creating a 'device'. +func (a *UserInternalAPI) queryAppServiceToken(ctx context.Context, token, appServiceUserID string) (*api.Device, error) { + // Search for app service with given access_token + var appService *config.ApplicationService + for _, as := range a.AppServices { + if as.ASToken == token { + appService = &as + break + } + } + if appService == nil { + return nil, nil + } + + // Create a dummy device for AS user + dev := api.Device{ + // Use AS dummy device ID + ID: types.AppServiceDeviceID, + // AS dummy device has AS's token. + AccessToken: token, + } + + localpart, err := userutil.ParseUsernameParam(appServiceUserID, &a.ServerName) + if err != nil { + return nil, err + } + + if localpart != "" { // AS is masquerading as another user + // Verify that the user is registered + account, err := a.AccountDB.GetAccountByLocalpart(ctx, localpart) + // Verify that account exists & appServiceID matches + if err == nil && account.AppServiceID == appService.ID { + // Set the userID of dummy device + dev.UserID = appServiceUserID + return &dev, nil + } + return nil, &api.ErrorForbidden{Message: "appservice has not registered this user"} + } + + // AS is not masquerading as any user, so use AS's sender_localpart + dev.UserID = appService.SenderLocalpart + return &dev, nil +} diff --git a/userapi/inthttp/client.go b/userapi/inthttp/client.go index 90cc54a4..022243fa 100644 --- a/userapi/inthttp/client.go +++ b/userapi/inthttp/client.go @@ -26,7 +26,8 @@ import ( // HTTP paths for the internal HTTP APIs const ( - QueryProfilePath = "/userapi/queryProfile" + QueryProfilePath = "/userapi/queryProfile" + QueryAccessTokenPath = "/userapi/queryAccessToken" ) // NewUserAPIClient creates a UserInternalAPI implemented by talking to a HTTP POST API. @@ -60,3 +61,15 @@ func (h *httpUserInternalAPI) QueryProfile( apiURL := h.apiURL + QueryProfilePath return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } + +func (h *httpUserInternalAPI) QueryAccessToken( + ctx context.Context, + request *api.QueryAccessTokenRequest, + response *api.QueryAccessTokenResponse, +) error { + span, ctx := opentracing.StartSpanFromContext(ctx, "QueryAccessToken") + defer span.Finish() + + apiURL := h.apiURL + QueryAccessTokenPath + return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response) +} diff --git a/userapi/inthttp/server.go b/userapi/inthttp/server.go index f3c17ccd..495b161c 100644 --- a/userapi/inthttp/server.go +++ b/userapi/inthttp/server.go @@ -38,4 +38,17 @@ func AddRoutes(internalAPIMux *mux.Router, s api.UserInternalAPI) { return util.JSONResponse{Code: http.StatusOK, JSON: &response} }), ) + internalAPIMux.Handle(QueryAccessTokenPath, + httputil.MakeInternalAPI("queryAccessToken", func(req *http.Request) util.JSONResponse { + request := api.QueryAccessTokenRequest{} + response := api.QueryAccessTokenResponse{} + if err := json.NewDecoder(req.Body).Decode(&request); err != nil { + return util.MessageResponse(http.StatusBadRequest, err.Error()) + } + if err := s.QueryAccessToken(req.Context(), &request, &response); err != nil { + return util.ErrorResponse(err) + } + return util.JSONResponse{Code: http.StatusOK, JSON: &response} + }), + ) } diff --git a/userapi/userapi.go b/userapi/userapi.go index 32f851cc..961d04fe 100644 --- a/userapi/userapi.go +++ b/userapi/userapi.go @@ -18,6 +18,7 @@ import ( "github.com/gorilla/mux" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/auth/storage/devices" + "github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/dendrite/userapi/internal" "github.com/matrix-org/dendrite/userapi/inthttp" @@ -32,10 +33,13 @@ func AddInternalRoutes(router *mux.Router, intAPI api.UserInternalAPI) { // NewInternalAPI returns a concerete implementation of the internal API. Callers // can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes. -func NewInternalAPI(accountDB accounts.Database, deviceDB devices.Database, serverName gomatrixserverlib.ServerName) api.UserInternalAPI { +func NewInternalAPI(accountDB accounts.Database, deviceDB devices.Database, + serverName gomatrixserverlib.ServerName, appServices []config.ApplicationService) api.UserInternalAPI { + return &internal.UserInternalAPI{ - AccountDB: accountDB, - DeviceDB: deviceDB, - ServerName: serverName, + AccountDB: accountDB, + DeviceDB: deviceDB, + ServerName: serverName, + AppServices: appServices, } } diff --git a/userapi/userapi_test.go b/userapi/userapi_test.go index a4616363..509bdd7e 100644 --- a/userapi/userapi_test.go +++ b/userapi/userapi_test.go @@ -32,7 +32,7 @@ func MustMakeInternalAPI(t *testing.T) (api.UserInternalAPI, accounts.Database, t.Fatalf("failed to create device DB: %s", err) } - return userapi.NewInternalAPI(accountDB, deviceDB, serverName), accountDB, deviceDB + return userapi.NewInternalAPI(accountDB, deviceDB, serverName, nil), accountDB, deviceDB } func TestQueryProfile(t *testing.T) {