Merge branch 'master' into neilalexander/gobind

This commit is contained in:
Neil Alexander 2020-06-18 09:44:18 +01:00
commit b6762dd19a
257 changed files with 3658 additions and 2022 deletions

View file

@ -22,10 +22,9 @@ import (
"database/sql" "database/sql"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/dendrite/internal"
) )
// RoomAliasExistsRequest is a request to an application service // RoomAliasExistsRequest is a request to an application service
@ -110,7 +109,7 @@ func RetrieveUserProfile(
// If no user exists, return // If no user exists, return
if !userResp.UserIDExists { if !userResp.UserIDExists {
return nil, internal.ErrProfileNoExists return nil, eventutil.ErrProfileNoExists
} }
// Try to query the user from the local database again // Try to query the user from the local database again

View file

@ -16,7 +16,6 @@ package appservice
import ( import (
"context" "context"
"errors"
"net/http" "net/http"
"sync" "sync"
"time" "time"
@ -29,12 +28,10 @@ import (
"github.com/matrix-org/dendrite/appservice/storage" "github.com/matrix-org/dendrite/appservice/storage"
"github.com/matrix-org/dendrite/appservice/types" "github.com/matrix-org/dendrite/appservice/types"
"github.com/matrix-org/dendrite/appservice/workers" "github.com/matrix-org/dendrite/appservice/workers"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/basecomponent"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/setup"
roomserverAPI "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/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -46,9 +43,8 @@ func AddInternalRoutes(router *mux.Router, queryAPI appserviceAPI.AppServiceQuer
// NewInternalAPI returns a concerete implementation of the internal API. Callers // 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. // can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
func NewInternalAPI( func NewInternalAPI(
base *basecomponent.BaseDendrite, base *setup.BaseDendrite,
accountsDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
rsAPI roomserverAPI.RoomserverInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI,
) appserviceAPI.AppServiceQueryAPI { ) appserviceAPI.AppServiceQueryAPI {
// Create a connection to the appservice postgres DB // Create a connection to the appservice postgres DB
@ -70,7 +66,7 @@ func NewInternalAPI(
workerStates[i] = ws workerStates[i] = ws
// Create bot account for this AS if it doesn't already exist // Create bot account for this AS if it doesn't already exist
if err = generateAppServiceAccount(accountsDB, deviceDB, appservice); err != nil { if err = generateAppServiceAccount(userAPI, appservice); err != nil {
logrus.WithFields(logrus.Fields{ logrus.WithFields(logrus.Fields{
"appservice": appservice.ID, "appservice": appservice.ID,
}).WithError(err).Panicf("failed to generate bot account for appservice") }).WithError(err).Panicf("failed to generate bot account for appservice")
@ -86,12 +82,16 @@ func NewInternalAPI(
Cfg: base.Cfg, Cfg: base.Cfg,
} }
consumer := consumers.NewOutputRoomEventConsumer( // Only consume if we actually have ASes to track, else we'll just chew cycles needlessly.
base.Cfg, base.KafkaConsumer, accountsDB, appserviceDB, // We can't add ASes at runtime so this is safe to do.
rsAPI, workerStates, if len(workerStates) > 0 {
) consumer := consumers.NewOutputRoomEventConsumer(
if err := consumer.Start(); err != nil { base.Cfg, base.KafkaConsumer, appserviceDB,
logrus.WithError(err).Panicf("failed to start appservice roomserver consumer") rsAPI, workerStates,
)
if err := consumer.Start(); err != nil {
logrus.WithError(err).Panicf("failed to start appservice roomserver consumer")
}
} }
// Create application service transaction workers // Create application service transaction workers
@ -105,22 +105,25 @@ func NewInternalAPI(
// `sender_localpart` field of each application service if it doesn't // `sender_localpart` field of each application service if it doesn't
// exist already // exist already
func generateAppServiceAccount( func generateAppServiceAccount(
accountsDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
as config.ApplicationService, as config.ApplicationService,
) error { ) error {
ctx := context.Background() var accRes userapi.PerformAccountCreationResponse
err := userAPI.PerformAccountCreation(context.Background(), &userapi.PerformAccountCreationRequest{
// Create an account for the application service AccountType: userapi.AccountTypeUser,
_, err := accountsDB.CreateAccount(ctx, as.SenderLocalpart, "", as.ID) Localpart: as.SenderLocalpart,
AppServiceID: as.ID,
OnConflict: userapi.ConflictUpdate,
}, &accRes)
if err != nil { if err != nil {
if errors.Is(err, internal.ErrUserExists) { // This account already exists
return nil
}
return err return err
} }
var devRes userapi.PerformDeviceCreationResponse
// Create a dummy device with a dummy token for the application service err = userAPI.PerformDeviceCreation(context.Background(), &userapi.PerformDeviceCreationRequest{
_, err = deviceDB.CreateDevice(ctx, as.SenderLocalpart, nil, as.ASToken, &as.SenderLocalpart) Localpart: as.SenderLocalpart,
AccessToken: as.ASToken,
DeviceID: &as.SenderLocalpart,
DeviceDisplayName: &as.SenderLocalpart,
}, &devRes)
return err return err
} }

View file

@ -20,7 +20,6 @@ import (
"github.com/matrix-org/dendrite/appservice/storage" "github.com/matrix-org/dendrite/appservice/storage"
"github.com/matrix-org/dendrite/appservice/types" "github.com/matrix-org/dendrite/appservice/types"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
@ -33,7 +32,6 @@ import (
// OutputRoomEventConsumer consumes events that originated in the room server. // OutputRoomEventConsumer consumes events that originated in the room server.
type OutputRoomEventConsumer struct { type OutputRoomEventConsumer struct {
roomServerConsumer *internal.ContinualConsumer roomServerConsumer *internal.ContinualConsumer
db accounts.Database
asDB storage.Database asDB storage.Database
rsAPI api.RoomserverInternalAPI rsAPI api.RoomserverInternalAPI
serverName string serverName string
@ -45,7 +43,6 @@ type OutputRoomEventConsumer struct {
func NewOutputRoomEventConsumer( func NewOutputRoomEventConsumer(
cfg *config.Dendrite, cfg *config.Dendrite,
kafkaConsumer sarama.Consumer, kafkaConsumer sarama.Consumer,
store accounts.Database,
appserviceDB storage.Database, appserviceDB storage.Database,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
workerStates []types.ApplicationServiceWorkerState, workerStates []types.ApplicationServiceWorkerState,
@ -53,11 +50,10 @@ func NewOutputRoomEventConsumer(
consumer := internal.ContinualConsumer{ consumer := internal.ContinualConsumer{
Topic: string(cfg.Kafka.Topics.OutputRoomEvent), Topic: string(cfg.Kafka.Topics.OutputRoomEvent),
Consumer: kafkaConsumer, Consumer: kafkaConsumer,
PartitionStore: store, PartitionStore: appserviceDB,
} }
s := &OutputRoomEventConsumer{ s := &OutputRoomEventConsumer{
roomServerConsumer: &consumer, roomServerConsumer: &consumer,
db: store,
asDB: appserviceDB, asDB: appserviceDB,
rsAPI: rsAPI, rsAPI: rsAPI,
serverName: string(cfg.Matrix.ServerName), serverName: string(cfg.Matrix.ServerName),
@ -91,60 +87,13 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
return nil return nil
} }
ev := output.NewRoomEvent.Event events := []gomatrixserverlib.HeaderedEvent{output.NewRoomEvent.Event}
log.WithFields(log.Fields{ events = append(events, output.NewRoomEvent.AddStateEvents...)
"event_id": ev.EventID(),
"room_id": ev.RoomID(),
"type": ev.Type(),
}).Info("appservice received an event from roomserver")
missingEvents, err := s.lookupMissingStateEvents(output.NewRoomEvent.AddsStateEventIDs, ev)
if err != nil {
return err
}
events := append(missingEvents, ev)
// Send event to any relevant application services // Send event to any relevant application services
return s.filterRoomserverEvents(context.TODO(), events) return s.filterRoomserverEvents(context.TODO(), events)
} }
// lookupMissingStateEvents looks up the state events that are added by a new event,
// and returns any not already present.
func (s *OutputRoomEventConsumer) lookupMissingStateEvents(
addsStateEventIDs []string, event gomatrixserverlib.HeaderedEvent,
) ([]gomatrixserverlib.HeaderedEvent, error) {
// Fast path if there aren't any new state events.
if len(addsStateEventIDs) == 0 {
return []gomatrixserverlib.HeaderedEvent{}, nil
}
// Fast path if the only state event added is the event itself.
if len(addsStateEventIDs) == 1 && addsStateEventIDs[0] == event.EventID() {
return []gomatrixserverlib.HeaderedEvent{}, nil
}
result := []gomatrixserverlib.HeaderedEvent{}
missing := []string{}
for _, id := range addsStateEventIDs {
if id != event.EventID() {
// If the event isn't the current one, add it to the list of events
// to retrieve from the roomserver
missing = append(missing, id)
}
}
// Request the missing events from the roomserver
eventReq := api.QueryEventsByIDRequest{EventIDs: missing}
var eventResp api.QueryEventsByIDResponse
if err := s.rsAPI.QueryEventsByID(context.TODO(), &eventReq, &eventResp); err != nil {
return nil, err
}
result = append(result, eventResp.Events...)
return result, nil
}
// filterRoomserverEvents takes in events and decides whether any of them need // filterRoomserverEvents takes in events and decides whether any of them need
// to be passed on to an external application service. It does this by checking // to be passed on to an external application service. It does this by checking
// each namespace of each registered application service, and if there is a // each namespace of each registered application service, and if there is a

View file

@ -6,7 +6,7 @@ import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/appservice/api" "github.com/matrix-org/dendrite/appservice/api"
internalHTTP "github.com/matrix-org/dendrite/internal/http" "github.com/matrix-org/dendrite/internal/httputil"
"github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go"
) )
@ -46,7 +46,7 @@ func (h *httpAppServiceQueryAPI) RoomAliasExists(
defer span.Finish() defer span.Finish()
apiURL := h.appserviceURL + AppServiceRoomAliasExistsPath apiURL := h.appserviceURL + AppServiceRoomAliasExistsPath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// UserIDExists implements AppServiceQueryAPI // UserIDExists implements AppServiceQueryAPI
@ -59,5 +59,5 @@ func (h *httpAppServiceQueryAPI) UserIDExists(
defer span.Finish() defer span.Finish()
apiURL := h.appserviceURL + AppServiceUserIDExistsPath apiURL := h.appserviceURL + AppServiceUserIDExistsPath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
} }

View file

@ -6,7 +6,7 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/matrix-org/dendrite/appservice/api" "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -14,7 +14,7 @@ import (
func AddRoutes(a api.AppServiceQueryAPI, internalAPIMux *mux.Router) { func AddRoutes(a api.AppServiceQueryAPI, internalAPIMux *mux.Router) {
internalAPIMux.Handle( internalAPIMux.Handle(
AppServiceRoomAliasExistsPath, AppServiceRoomAliasExistsPath,
internal.MakeInternalAPI("appserviceRoomAliasExists", func(req *http.Request) util.JSONResponse { httputil.MakeInternalAPI("appserviceRoomAliasExists", func(req *http.Request) util.JSONResponse {
var request api.RoomAliasExistsRequest var request api.RoomAliasExistsRequest
var response api.RoomAliasExistsResponse var response api.RoomAliasExistsResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -28,7 +28,7 @@ func AddRoutes(a api.AppServiceQueryAPI, internalAPIMux *mux.Router) {
) )
internalAPIMux.Handle( internalAPIMux.Handle(
AppServiceUserIDExistsPath, AppServiceUserIDExistsPath,
internal.MakeInternalAPI("appserviceUserIDExists", func(req *http.Request) util.JSONResponse { httputil.MakeInternalAPI("appserviceUserIDExists", func(req *http.Request) util.JSONResponse {
var request api.UserIDExistsRequest var request api.UserIDExistsRequest
var response api.UserIDExistsResponse var response api.UserIDExistsResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {

View file

@ -17,10 +17,12 @@ package storage
import ( import (
"context" "context"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
type Database interface { type Database interface {
internal.PartitionStorer
StoreEvent(ctx context.Context, appServiceID string, event *gomatrixserverlib.HeaderedEvent) error StoreEvent(ctx context.Context, appServiceID string, event *gomatrixserverlib.HeaderedEvent) error
GetEventsWithAppServiceID(ctx context.Context, appServiceID string, limit int) (int, int, []gomatrixserverlib.HeaderedEvent, bool, error) GetEventsWithAppServiceID(ctx context.Context, appServiceID string, limit int) (int, int, []gomatrixserverlib.HeaderedEvent, bool, error)
CountEventsWithAppServiceID(ctx context.Context, appServiceID string) (int, error) CountEventsWithAppServiceID(ctx context.Context, appServiceID string) (int, error)

View file

@ -21,20 +21,20 @@ import (
// Import postgres database driver // Import postgres database driver
_ "github.com/lib/pq" _ "github.com/lib/pq"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
// Database stores events intended to be later sent to application services // Database stores events intended to be later sent to application services
type Database struct { type Database struct {
sqlutil.PartitionOffsetStatements
events eventsStatements events eventsStatements
txnID txnStatements txnID txnStatements
db *sql.DB db *sql.DB
} }
// NewDatabase opens a new database // NewDatabase opens a new database
func NewDatabase(dataSourceName string, dbProperties internal.DbProperties) (*Database, error) { func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) {
var result Database var result Database
var err error var err error
if result.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil { if result.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil {
@ -43,6 +43,9 @@ func NewDatabase(dataSourceName string, dbProperties internal.DbProperties) (*Da
if err = result.prepare(); err != nil { if err = result.prepare(); err != nil {
return nil, err return nil, err
} }
if err = result.PartitionOffsetStatements.Prepare(result.db, "appservice"); err != nil {
return nil, err
}
return &result, nil return &result, nil
} }

View file

@ -20,7 +20,6 @@ import (
"database/sql" "database/sql"
// Import SQLite database driver // Import SQLite database driver
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
@ -28,6 +27,7 @@ import (
// Database stores events intended to be later sent to application services // Database stores events intended to be later sent to application services
type Database struct { type Database struct {
sqlutil.PartitionOffsetStatements
events eventsStatements events eventsStatements
txnID txnStatements txnID txnStatements
db *sql.DB db *sql.DB
@ -41,12 +41,15 @@ func NewDatabase(dataSourceName string) (*Database, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if result.db, err = sqlutil.Open(internal.SQLiteDriverName(), cs, nil); err != nil { if result.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
return nil, err return nil, err
} }
if err = result.prepare(); err != nil { if err = result.prepare(); err != nil {
return nil, err return nil, err
} }
if err = result.PartitionOffsetStatements.Prepare(result.db, "appservice"); err != nil {
return nil, err
}
return &result, nil return &result, nil
} }

View file

@ -21,12 +21,12 @@ import (
"github.com/matrix-org/dendrite/appservice/storage/postgres" "github.com/matrix-org/dendrite/appservice/storage/postgres"
"github.com/matrix-org/dendrite/appservice/storage/sqlite3" "github.com/matrix-org/dendrite/appservice/storage/sqlite3"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/sqlutil"
) )
// NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme) // NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme)
// and sets DB connection parameters // and sets DB connection parameters
func NewDatabase(dataSourceName string, dbProperties internal.DbProperties) (Database, error) { func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) {
uri, err := url.Parse(dataSourceName) uri, err := url.Parse(dataSourceName)
if err != nil { if err != nil {
return postgres.NewDatabase(dataSourceName, dbProperties) return postgres.NewDatabase(dataSourceName, dbProperties)

View file

@ -19,12 +19,12 @@ import (
"net/url" "net/url"
"github.com/matrix-org/dendrite/appservice/storage/sqlite3" "github.com/matrix-org/dendrite/appservice/storage/sqlite3"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/sqlutil"
) )
func NewDatabase( func NewDatabase(
dataSourceName string, dataSourceName string,
dbProperties internal.DbProperties, // nolint:unparam dbProperties sqlutil.DbProperties, // nolint:unparam
) (Database, error) { ) (Database, error) {
uri, err := url.Parse(dataSourceName) uri, err := url.Parse(dataSourceName)
if err != nil { if err != nil {

View file

@ -97,8 +97,8 @@ rst PUT power_levels should not explode if the old power levels were empty
rst Both GET and PUT work rst Both GET and PUT work
rct POST /rooms/:room_id/receipt can create receipts rct POST /rooms/:room_id/receipt can create receipts
red POST /rooms/:room_id/read_markers can create read marker red POST /rooms/:room_id/read_markers can create read marker
med POST /media/v1/upload can create an upload med POST /media/r0/upload can create an upload
med GET /media/v1/download can fetch the value again med GET /media/r0/download can fetch the value again
cap GET /capabilities is present and well formed for registered user cap GET /capabilities is present and well formed for registered user
cap GET /r0/capabilities is not public cap GET /r0/capabilities is not public
reg Register with a recaptcha reg Register with a recaptcha

View file

@ -33,6 +33,7 @@ import sys
test_mappings = { test_mappings = {
"nsp": "Non-Spec API", "nsp": "Non-Spec API",
"unk": "Unknown API (no group specified)",
"f": "Federation", # flag to mark test involves federation "f": "Federation", # flag to mark test involves federation
"federation_apis": { "federation_apis": {
@ -214,7 +215,8 @@ def main(results_tap_path, verbose):
# } # }
}, },
"nonspec": { "nonspec": {
"nsp": {} "nsp": {},
"unk": {}
}, },
} }
with open(results_tap_path, "r") as f: with open(results_tap_path, "r") as f:
@ -225,7 +227,7 @@ def main(results_tap_path, verbose):
name = test_result["name"] name = test_result["name"]
group_id = test_name_to_group_id.get(name) group_id = test_name_to_group_id.get(name)
if not group_id: if not group_id:
raise Exception("The test '%s' doesn't have a group" % (name,)) summary["nonspec"]["unk"][name] = test_result["ok"]
if group_id == "nsp": if group_id == "nsp":
summary["nonspec"]["nsp"][name] = test_result["ok"] summary["nonspec"]["nsp"][name] = test_result["ok"]
elif group_id in test_mappings["federation_apis"]: elif group_id in test_mappings["federation_apis"]:

View file

@ -18,17 +18,13 @@ package auth
import ( import (
"context" "context"
"crypto/rand" "crypto/rand"
"database/sql"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"net/http" "net/http"
"strings" "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/jsonerror"
"github.com/matrix-org/dendrite/clientapi/userutil" "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -39,21 +35,13 @@ var tokenByteLength = 32
// DeviceDatabase represents a device database. // DeviceDatabase represents a device database.
type DeviceDatabase interface { type DeviceDatabase interface {
// Look up the device matching the given access token. // 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. // AccountDatabase represents an account database.
type AccountDatabase interface { type AccountDatabase interface {
// Look up the account matching the given localpart. // Look up the account matching the given localpart.
GetAccountByLocalpart(ctx context.Context, localpart string) (*authtypes.Account, error) GetAccountByLocalpart(ctx context.Context, localpart string) (*api.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, // VerifyUserFromRequest authenticates the HTTP request,
@ -62,8 +50,8 @@ type Data struct {
// Note: For an AS user, AS dummy device is returned. // Note: For an AS user, AS dummy device is returned.
// On failure returns an JSON error response which can be sent to the client. // On failure returns an JSON error response which can be sent to the client.
func VerifyUserFromRequest( func VerifyUserFromRequest(
req *http.Request, data Data, req *http.Request, userAPI api.UserInternalAPI,
) (*authtypes.Device, *util.JSONResponse) { ) (*api.Device, *util.JSONResponse) {
// Try to find the Application Service user // Try to find the Application Service user
token, err := ExtractAccessToken(req) token, err := ExtractAccessToken(req)
if err != nil { if err != nil {
@ -72,105 +60,31 @@ func VerifyUserFromRequest(
JSON: jsonerror.MissingToken(err.Error()), JSON: jsonerror.MissingToken(err.Error()),
} }
} }
var res api.QueryAccessTokenResponse
// Search for app service with given access_token err = userAPI.QueryAccessToken(req.Context(), &api.QueryAccessTokenRequest{
var appService *config.ApplicationService AccessToken: token,
for _, as := range data.AppServices { AppServiceUserID: req.URL.Query().Get("user_id"),
if as.ASToken == token { }, &res)
appService = &as if err != nil {
break util.GetLogger(req.Context()).WithError(err).Error("userAPI.QueryAccessToken failed")
} jsonErr := jsonerror.InternalServerError()
return nil, &jsonErr
} }
if res.Err != nil {
if appService != nil { if forbidden, ok := res.Err.(*api.ErrorForbidden); ok {
// 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
}
return nil, &util.JSONResponse{ return nil, &util.JSONResponse{
Code: http.StatusForbidden, 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
} }
if res.Device == nil {
// Try to find local user from device database return nil, &util.JSONResponse{
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{
Code: http.StatusUnauthorized, Code: http.StatusUnauthorized,
JSON: jsonerror.MissingToken(err.Error()), JSON: jsonerror.UnknownToken("Unknown token"),
}
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
} }
} }
return return res.Device, nil
} }
// GenerateAccessToken creates a new access token. Returns an error if failed to generate // GenerateAccessToken creates a new access token. Returns an error if failed to generate

View file

@ -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
}

View file

@ -18,8 +18,6 @@ import (
"github.com/Shopify/sarama" "github.com/Shopify/sarama"
"github.com/gorilla/mux" "github.com/gorilla/mux"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/clientapi/consumers" "github.com/matrix-org/dendrite/clientapi/consumers"
"github.com/matrix-org/dendrite/clientapi/producers" "github.com/matrix-org/dendrite/clientapi/producers"
"github.com/matrix-org/dendrite/clientapi/routing" "github.com/matrix-org/dendrite/clientapi/routing"
@ -28,6 +26,9 @@ import (
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/transactions" "github.com/matrix-org/dendrite/internal/transactions"
roomserverAPI "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/dendrite/userapi/storage/accounts"
"github.com/matrix-org/dendrite/userapi/storage/devices"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -41,12 +42,12 @@ func AddPublicRoutes(
deviceDB devices.Database, deviceDB devices.Database,
accountsDB accounts.Database, accountsDB accounts.Database,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
keyRing *gomatrixserverlib.KeyRing,
rsAPI roomserverAPI.RoomserverInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI,
eduInputAPI eduServerAPI.EDUServerInputAPI, eduInputAPI eduServerAPI.EDUServerInputAPI,
asAPI appserviceAPI.AppServiceQueryAPI, asAPI appserviceAPI.AppServiceQueryAPI,
transactionsCache *transactions.Cache, transactionsCache *transactions.Cache,
fsAPI federationSenderAPI.FederationSenderInternalAPI, fsAPI federationSenderAPI.FederationSenderInternalAPI,
userAPI userapi.UserInternalAPI,
) { ) {
syncProducer := &producers.SyncAPIProducer{ syncProducer := &producers.SyncAPIProducer{
Producer: producer, Producer: producer,
@ -62,7 +63,7 @@ func AddPublicRoutes(
routing.Setup( routing.Setup(
router, cfg, eduInputAPI, rsAPI, asAPI, router, cfg, eduInputAPI, rsAPI, asAPI,
accountsDB, deviceDB, federation, *keyRing, accountsDB, deviceDB, userAPI, federation,
syncProducer, transactionsCache, fsAPI, syncProducer, transactionsCache, fsAPI,
) )
} }

View file

@ -18,10 +18,10 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/Shopify/sarama" "github.com/Shopify/sarama"
@ -84,63 +84,9 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
return nil return nil
} }
ev := output.NewRoomEvent.Event return s.db.UpdateMemberships(
log.WithFields(log.Fields{ context.TODO(),
"event_id": ev.EventID(), gomatrixserverlib.UnwrapEventHeaders(output.NewRoomEvent.AddsState()),
"room_id": ev.RoomID(), output.NewRoomEvent.RemovesStateEventIDs,
"type": ev.Type(), )
}).Info("received event from roomserver")
events, err := s.lookupStateEvents(output.NewRoomEvent.AddsStateEventIDs, ev.Event)
if err != nil {
return err
}
return s.db.UpdateMemberships(context.TODO(), events, output.NewRoomEvent.RemovesStateEventIDs)
}
// lookupStateEvents looks up the state events that are added by a new event.
func (s *OutputRoomEventConsumer) lookupStateEvents(
addsStateEventIDs []string, event gomatrixserverlib.Event,
) ([]gomatrixserverlib.Event, error) {
// Fast path if there aren't any new state events.
if len(addsStateEventIDs) == 0 {
// If the event is a membership update (e.g. for a profile update), it won't
// show up in AddsStateEventIDs, so we need to add it manually
if event.Type() == "m.room.member" {
return []gomatrixserverlib.Event{event}, nil
}
return nil, nil
}
// Fast path if the only state event added is the event itself.
if len(addsStateEventIDs) == 1 && addsStateEventIDs[0] == event.EventID() {
return []gomatrixserverlib.Event{event}, nil
}
result := []gomatrixserverlib.Event{}
missing := []string{}
for _, id := range addsStateEventIDs {
// Append the current event in the results if its ID is in the events list
if id == event.EventID() {
result = append(result, event)
} else {
// If the event isn't the current one, add it to the list of events
// to retrieve from the roomserver
missing = append(missing, id)
}
}
// Request the missing events from the roomserver
eventReq := api.QueryEventsByIDRequest{EventIDs: missing}
var eventResp api.QueryEventsByIDResponse
if err := s.rsAPI.QueryEventsByID(context.TODO(), &eventReq, &eventResp); err != nil {
return nil, err
}
for _, headeredEvent := range eventResp.Events {
result = append(result, headeredEvent.Event)
}
return result, nil
} }

View file

@ -17,9 +17,9 @@ package producers
import ( import (
"encoding/json" "encoding/json"
"github.com/matrix-org/dendrite/internal"
"github.com/Shopify/sarama" "github.com/Shopify/sarama"
"github.com/matrix-org/dendrite/internal/eventutil"
log "github.com/sirupsen/logrus"
) )
// SyncAPIProducer produces events for the sync API server to consume // SyncAPIProducer produces events for the sync API server to consume
@ -32,7 +32,7 @@ type SyncAPIProducer struct {
func (p *SyncAPIProducer) SendData(userID string, roomID string, dataType string) error { func (p *SyncAPIProducer) SendData(userID string, roomID string, dataType string) error {
var m sarama.ProducerMessage var m sarama.ProducerMessage
data := internal.AccountData{ data := eventutil.AccountData{
RoomID: roomID, RoomID: roomID,
Type: dataType, Type: dataType,
} }
@ -44,6 +44,11 @@ func (p *SyncAPIProducer) SendData(userID string, roomID string, dataType string
m.Topic = string(p.Topic) m.Topic = string(p.Topic)
m.Key = sarama.StringEncoder(userID) m.Key = sarama.StringEncoder(userID)
m.Value = sarama.ByteEncoder(value) m.Value = sarama.ByteEncoder(value)
log.WithFields(log.Fields{
"user_id": userID,
"room_id": roomID,
"data_type": dataType,
}).Infof("Producing to topic '%s'", p.Topic)
_, _, err = p.Producer.SendMessage(&m) _, _, err = p.Producer.SendMessage(&m)
return err return err

View file

@ -19,10 +19,10 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "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/jsonerror"
"github.com/matrix-org/dendrite/clientapi/producers" "github.com/matrix-org/dendrite/clientapi/producers"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
@ -30,7 +30,7 @@ import (
// GetAccountData implements GET /user/{userId}/[rooms/{roomid}/]account_data/{type} // GetAccountData implements GET /user/{userId}/[rooms/{roomid}/]account_data/{type}
func GetAccountData( 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, userID string, roomID string, dataType string,
) util.JSONResponse { ) util.JSONResponse {
if userID != device.UserID { if userID != device.UserID {
@ -51,7 +51,7 @@ func GetAccountData(
); err == nil { ); err == nil {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: data, JSON: data.Content,
} }
} }
@ -63,7 +63,7 @@ func GetAccountData(
// SaveAccountData implements PUT /user/{userId}/[rooms/{roomId}/]account_data/{type} // SaveAccountData implements PUT /user/{userId}/[rooms/{roomId}/]account_data/{type}
func SaveAccountData( 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, userID string, roomID string, dataType string, syncProducer *producers.SyncAPIProducer,
) util.JSONResponse { ) util.JSONResponse {
if userID != device.UserID { if userID != device.UserID {

View file

@ -24,14 +24,14 @@ import (
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
roomserverVersion "github.com/matrix-org/dendrite/roomserver/version" 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/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/threepid" "github.com/matrix-org/dendrite/clientapi/threepid"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -98,7 +98,7 @@ func (r createRoomRequest) Validate() *util.JSONResponse {
// Validate creation_content fields defined in the spec by marshalling the // Validate creation_content fields defined in the spec by marshalling the
// creation_content map into bytes and then unmarshalling the bytes into // creation_content map into bytes and then unmarshalling the bytes into
// internal.CreateContent. // eventutil.CreateContent.
creationContentBytes, err := json.Marshal(r.CreationContent) creationContentBytes, err := json.Marshal(r.CreationContent)
if err != nil { if err != nil {
@ -135,7 +135,7 @@ type fledglingEvent struct {
// CreateRoom implements /createRoom // CreateRoom implements /createRoom
func CreateRoom( func CreateRoom(
req *http.Request, device *authtypes.Device, req *http.Request, device *api.Device,
cfg *config.Dendrite, cfg *config.Dendrite,
accountDB accounts.Database, rsAPI roomserverAPI.RoomserverInternalAPI, accountDB accounts.Database, rsAPI roomserverAPI.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI, asAPI appserviceAPI.AppServiceQueryAPI,
@ -149,7 +149,7 @@ func CreateRoom(
// createRoom implements /createRoom // createRoom implements /createRoom
// nolint: gocyclo // nolint: gocyclo
func createRoom( func createRoom(
req *http.Request, device *authtypes.Device, req *http.Request, device *api.Device,
cfg *config.Dendrite, roomID string, cfg *config.Dendrite, roomID string,
accountDB accounts.Database, rsAPI roomserverAPI.RoomserverInternalAPI, accountDB accounts.Database, rsAPI roomserverAPI.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI, asAPI appserviceAPI.AppServiceQueryAPI,
@ -279,25 +279,25 @@ func createRoom(
eventsToMake := []fledglingEvent{ eventsToMake := []fledglingEvent{
{"m.room.create", "", r.CreationContent}, {"m.room.create", "", r.CreationContent},
{"m.room.member", userID, membershipContent}, {"m.room.member", userID, membershipContent},
{"m.room.power_levels", "", internal.InitialPowerLevelsContent(userID)}, {"m.room.power_levels", "", eventutil.InitialPowerLevelsContent(userID)},
{"m.room.join_rules", "", gomatrixserverlib.JoinRuleContent{JoinRule: joinRules}}, {"m.room.join_rules", "", gomatrixserverlib.JoinRuleContent{JoinRule: joinRules}},
{"m.room.history_visibility", "", internal.HistoryVisibilityContent{HistoryVisibility: historyVisibility}}, {"m.room.history_visibility", "", eventutil.HistoryVisibilityContent{HistoryVisibility: historyVisibility}},
} }
if roomAlias != "" { if roomAlias != "" {
// TODO: bit of a chicken and egg problem here as the alias doesn't exist and cannot until we have made the room. // TODO: bit of a chicken and egg problem here as the alias doesn't exist and cannot until we have made the room.
// This means we might fail creating the alias but say the canonical alias is something that doesn't exist. // This means we might fail creating the alias but say the canonical alias is something that doesn't exist.
// m.room.aliases is handled when we call roomserver.SetRoomAlias // m.room.aliases is handled when we call roomserver.SetRoomAlias
eventsToMake = append(eventsToMake, fledglingEvent{"m.room.canonical_alias", "", internal.CanonicalAlias{Alias: roomAlias}}) eventsToMake = append(eventsToMake, fledglingEvent{"m.room.canonical_alias", "", eventutil.CanonicalAlias{Alias: roomAlias}})
} }
if r.GuestCanJoin { if r.GuestCanJoin {
eventsToMake = append(eventsToMake, fledglingEvent{"m.room.guest_access", "", internal.GuestAccessContent{GuestAccess: "can_join"}}) eventsToMake = append(eventsToMake, fledglingEvent{"m.room.guest_access", "", eventutil.GuestAccessContent{GuestAccess: "can_join"}})
} }
eventsToMake = append(eventsToMake, r.InitialState...) eventsToMake = append(eventsToMake, r.InitialState...)
if r.Name != "" { if r.Name != "" {
eventsToMake = append(eventsToMake, fledglingEvent{"m.room.name", "", internal.NameContent{Name: r.Name}}) eventsToMake = append(eventsToMake, fledglingEvent{"m.room.name", "", eventutil.NameContent{Name: r.Name}})
} }
if r.Topic != "" { if r.Topic != "" {
eventsToMake = append(eventsToMake, fledglingEvent{"m.room.topic", "", internal.TopicContent{Topic: r.Topic}}) eventsToMake = append(eventsToMake, fledglingEvent{"m.room.topic", "", eventutil.TopicContent{Topic: r.Topic}})
} }
// TODO: invite events // TODO: invite events
// TODO: 3pid invite events // TODO: 3pid invite events

View file

@ -19,9 +19,9 @@ import (
"encoding/json" "encoding/json"
"net/http" "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/clientapi/jsonerror"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/devices"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -47,7 +47,7 @@ type devicesDeleteJSON struct {
// GetDeviceByID handles /devices/{deviceID} // GetDeviceByID handles /devices/{deviceID}
func GetDeviceByID( func GetDeviceByID(
req *http.Request, deviceDB devices.Database, device *authtypes.Device, req *http.Request, deviceDB devices.Database, device *api.Device,
deviceID string, deviceID string,
) util.JSONResponse { ) util.JSONResponse {
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
@ -78,7 +78,7 @@ func GetDeviceByID(
// GetDevicesByLocalpart handles /devices // GetDevicesByLocalpart handles /devices
func GetDevicesByLocalpart( func GetDevicesByLocalpart(
req *http.Request, deviceDB devices.Database, device *authtypes.Device, req *http.Request, deviceDB devices.Database, device *api.Device,
) util.JSONResponse { ) util.JSONResponse {
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil { if err != nil {
@ -110,7 +110,7 @@ func GetDevicesByLocalpart(
// UpdateDeviceByID handles PUT on /devices/{deviceID} // UpdateDeviceByID handles PUT on /devices/{deviceID}
func UpdateDeviceByID( func UpdateDeviceByID(
req *http.Request, deviceDB devices.Database, device *authtypes.Device, req *http.Request, deviceDB devices.Database, device *api.Device,
deviceID string, deviceID string,
) util.JSONResponse { ) util.JSONResponse {
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
@ -160,7 +160,7 @@ func UpdateDeviceByID(
// DeleteDeviceById handles DELETE requests to /devices/{deviceId} // DeleteDeviceById handles DELETE requests to /devices/{deviceId}
func DeleteDeviceById( func DeleteDeviceById(
req *http.Request, deviceDB devices.Database, device *authtypes.Device, req *http.Request, deviceDB devices.Database, device *api.Device,
deviceID string, deviceID string,
) util.JSONResponse { ) util.JSONResponse {
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
@ -185,7 +185,7 @@ func DeleteDeviceById(
// DeleteDevices handles POST requests to /delete_devices // DeleteDevices handles POST requests to /delete_devices
func DeleteDevices( func DeleteDevices(
req *http.Request, deviceDB devices.Database, device *authtypes.Device, req *http.Request, deviceDB devices.Database, device *api.Device,
) util.JSONResponse { ) util.JSONResponse {
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil { if err != nil {

View file

@ -18,12 +18,12 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -112,7 +112,7 @@ func DirectoryRoom(
// TODO: Check if the user has the power level to set an alias // TODO: Check if the user has the power level to set an alias
func SetLocalAlias( func SetLocalAlias(
req *http.Request, req *http.Request,
device *authtypes.Device, device *api.Device,
alias string, alias string,
cfg *config.Dendrite, cfg *config.Dendrite,
aliasAPI roomserverAPI.RoomserverInternalAPI, aliasAPI roomserverAPI.RoomserverInternalAPI,
@ -188,7 +188,7 @@ func SetLocalAlias(
// RemoveLocalAlias implements DELETE /directory/room/{roomAlias} // RemoveLocalAlias implements DELETE /directory/room/{roomAlias}
func RemoveLocalAlias( func RemoveLocalAlias(
req *http.Request, req *http.Request,
device *authtypes.Device, device *api.Device,
alias string, alias string,
aliasAPI roomserverAPI.RoomserverInternalAPI, aliasAPI roomserverAPI.RoomserverInternalAPI,
) util.JSONResponse { ) util.JSONResponse {

View file

@ -17,17 +17,17 @@ package routing
import ( import (
"net/http" "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/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
// GetFilter implements GET /_matrix/client/r0/user/{userId}/filter/{filterId} // GetFilter implements GET /_matrix/client/r0/user/{userId}/filter/{filterId}
func GetFilter( 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 { ) util.JSONResponse {
if userID != device.UserID { if userID != device.UserID {
return util.JSONResponse{ return util.JSONResponse{
@ -64,7 +64,7 @@ type filterResponse struct {
//PutFilter implements POST /_matrix/client/r0/user/{userId}/filter //PutFilter implements POST /_matrix/client/r0/user/{userId}/filter
func PutFilter( 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 { ) util.JSONResponse {
if userID != device.UserID { if userID != device.UserID {
return util.JSONResponse{ return util.JSONResponse{

View file

@ -17,22 +17,21 @@ package routing
import ( import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
type getEventRequest struct { type getEventRequest struct {
req *http.Request req *http.Request
device *authtypes.Device device *userapi.Device
roomID string roomID string
eventID string eventID string
cfg *config.Dendrite cfg *config.Dendrite
federation *gomatrixserverlib.FederationClient federation *gomatrixserverlib.FederationClient
keyRing gomatrixserverlib.KeyRing
requestedEvent gomatrixserverlib.Event requestedEvent gomatrixserverlib.Event
} }
@ -40,13 +39,12 @@ type getEventRequest struct {
// https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-event-eventid // https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-event-eventid
func GetEvent( func GetEvent(
req *http.Request, req *http.Request,
device *authtypes.Device, device *userapi.Device,
roomID string, roomID string,
eventID string, eventID string,
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
keyRing gomatrixserverlib.KeyRing,
) util.JSONResponse { ) util.JSONResponse {
eventsReq := api.QueryEventsByIDRequest{ eventsReq := api.QueryEventsByIDRequest{
EventIDs: []string{eventID}, EventIDs: []string{eventID},
@ -75,7 +73,6 @@ func GetEvent(
eventID: eventID, eventID: eventID,
cfg: cfg, cfg: cfg,
federation: federation, federation: federation,
keyRing: keyRing,
requestedEvent: requestedEvent, requestedEvent: requestedEvent,
} }

View file

@ -17,18 +17,18 @@ package routing
import ( import (
"net/http" "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/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
func JoinRoomByIDOrAlias( func JoinRoomByIDOrAlias(
req *http.Request, req *http.Request,
device *authtypes.Device, device *api.Device,
rsAPI roomserverAPI.RoomserverInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI,
accountDB accounts.Database, accountDB accounts.Database,
roomIDOrAlias string, roomIDOrAlias string,
@ -43,9 +43,7 @@ func JoinRoomByIDOrAlias(
// If content was provided in the request then incude that // If content was provided in the request then incude that
// in the request. It'll get used as a part of the membership // in the request. It'll get used as a part of the membership
// event content. // event content.
if err := httputil.UnmarshalJSONRequest(req, &joinReq.Content); err != nil { _ = httputil.UnmarshalJSONRequest(req, &joinReq.Content)
return *err
}
// Work out our localpart for the client profile request. // Work out our localpart for the client profile request.
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)

View file

@ -17,15 +17,15 @@ package routing
import ( import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
func LeaveRoomByID( func LeaveRoomByID(
req *http.Request, req *http.Request,
device *authtypes.Device, device *api.Device,
rsAPI roomserverAPI.RoomserverInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI,
roomID string, roomID string,
) util.JSONResponse { ) util.JSONResponse {

View file

@ -22,13 +22,13 @@ import (
"context" "context"
"github.com/matrix-org/dendrite/clientapi/auth" "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/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/userutil" "github.com/matrix-org/dendrite/clientapi/userutil"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/dendrite/userapi/storage/devices"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -49,9 +49,8 @@ type loginIdentifier struct {
type loginWithPasswordRequest struct { type loginWithPasswordRequest struct {
Identifier loginIdentifier `json:"identifier"` Identifier loginIdentifier `json:"identifier"`
Medium string `json:"medium"` // third-party only User string `json:"user"` // deprecated in favour of identifier
Password string `json:"password"` // m.login.password only Password string `json:"password"`
Token string `json:"token"` // m.login.token only
// Both DeviceID and InitialDisplayName can be omitted, or empty strings ("") // Both DeviceID and InitialDisplayName can be omitted, or empty strings ("")
// Thus a pointer is needed to differentiate between the two // Thus a pointer is needed to differentiate between the two
InitialDisplayName *string `json:"initial_device_display_name"` InitialDisplayName *string `json:"initial_device_display_name"`
@ -88,9 +87,10 @@ func Login(
JSON: passwordLogin(), JSON: passwordLogin(),
} }
} else if req.Method == http.MethodPost { } else if req.Method == http.MethodPost {
var temp interface{} var r passwordRequest
var acc *authtypes.Account var acc *api.Account
resErr := httputil.UnmarshalJSONRequest(req, &temp) var errJSON *util.JSONResponse
resErr := httputil.UnmarshalJSONRequest(req, &r)
if resErr != nil { if resErr != nil {
return *resErr return *resErr
} }
@ -113,43 +113,23 @@ func Login(
JSON: jsonerror.BadJSON("'user' must be supplied."), JSON: jsonerror.BadJSON("'user' must be supplied."),
} }
} }
}
util.GetLogger(req.Context()).WithField("user", r.Identifier.User).Info("Processing login request") acc, errJSON = r.processUsernamePasswordLoginRequest(req, accountDB, cfg, r.Identifier.User)
if errJSON != nil {
localpart, err := userutil.ParseUsernameParam(r.Identifier.User, &cfg.Matrix.ServerName) return *errJSON
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.InvalidUsername(err.Error()),
}
}
acc, err = accountDB.GetAccountByPassword(req.Context(), localpart, r.Password)
if err != nil {
// Technically we could tell them if the user does not exist by checking if err == sql.ErrNoRows
// but that would leak the existence of the user.
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("username or password was incorrect, or the account does not exist"),
}
}
case "m.login.token":
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.Unknown("Token login is not supported"),
}
default:
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.Unknown("login identifier '" + r.Identifier.Type + "' not supported"),
}
} }
default: default:
return util.JSONResponse{ // TODO: The below behaviour is deprecated but without it Riot iOS won't log in
Code: http.StatusBadRequest, if r.User != "" {
JSON: jsonerror.Unknown(fmt.Sprintf("Login type %q not supported", r.Type)), acc, errJSON = r.processUsernamePasswordLoginRequest(req, accountDB, cfg, r.User)
if errJSON != nil {
return *errJSON
}
} else {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON("login identifier '" + r.Identifier.Type + "' not supported"),
}
} }
} }
@ -188,11 +168,40 @@ func getDevice(
ctx context.Context, ctx context.Context,
r loginWithPasswordRequest, r loginWithPasswordRequest,
deviceDB devices.Database, deviceDB devices.Database,
acc *authtypes.Account, acc *api.Account,
token string, token string,
) (dev *authtypes.Device, err error) { ) (dev *api.Device, err error) {
dev, err = deviceDB.CreateDevice( dev, err = deviceDB.CreateDevice(
ctx, acc.Localpart, r.DeviceID, token, r.InitialDisplayName, ctx, acc.Localpart, r.DeviceID, token, r.InitialDisplayName,
) )
return return
} }
func (r *passwordRequest) processUsernamePasswordLoginRequest(
req *http.Request, accountDB accounts.Database,
cfg *config.Dendrite, username string,
) (acc *api.Account, errJSON *util.JSONResponse) {
util.GetLogger(req.Context()).WithField("user", username).Info("Processing login request")
localpart, err := userutil.ParseUsernameParam(username, &cfg.Matrix.ServerName)
if err != nil {
errJSON = &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.InvalidUsername(err.Error()),
}
return
}
acc, err = accountDB.GetAccountByPassword(req.Context(), localpart, r.Password)
if err != nil {
// Technically we could tell them if the user does not exist by checking if err == sql.ErrNoRows
// but that would leak the existence of the user.
errJSON = &util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("username or password was incorrect, or the account does not exist"),
}
return
}
return
}

View file

@ -17,16 +17,16 @@ package routing
import ( import (
"net/http" "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/clientapi/jsonerror"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/devices"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
// Logout handles POST /logout // Logout handles POST /logout
func Logout( func Logout(
req *http.Request, deviceDB devices.Database, device *authtypes.Device, req *http.Request, deviceDB devices.Database, device *api.Device,
) util.JSONResponse { ) util.JSONResponse {
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil { if err != nil {
@ -47,7 +47,7 @@ func Logout(
// LogoutAll handles POST /logout/all // LogoutAll handles POST /logout/all
func LogoutAll( func LogoutAll(
req *http.Request, deviceDB devices.Database, device *authtypes.Device, req *http.Request, deviceDB devices.Database, device *api.Device,
) util.JSONResponse { ) util.JSONResponse {
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil { if err != nil {

View file

@ -22,14 +22,15 @@ import (
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "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/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/threepid" "github.com/matrix-org/dendrite/clientapi/threepid"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
roomserverAPI "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/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "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? // TODO: Can we improve the cyclo count here? Separate code paths for invites?
// nolint:gocyclo // nolint:gocyclo
func SendMembership( 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, roomID string, membership string, cfg *config.Dendrite,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI, rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
) util.JSONResponse { ) util.JSONResponse {
@ -95,7 +96,7 @@ func SendMembership(
Code: http.StatusBadRequest, Code: http.StatusBadRequest,
JSON: jsonerror.BadJSON(err.Error()), JSON: jsonerror.BadJSON(err.Error()),
} }
} else if err == internal.ErrRoomNoExists { } else if err == eventutil.ErrRoomNoExists {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,
JSON: jsonerror.NotFound(err.Error()), JSON: jsonerror.NotFound(err.Error()),
@ -149,7 +150,7 @@ func SendMembership(
func buildMembershipEvent( func buildMembershipEvent(
ctx context.Context, ctx context.Context,
body threepid.MembershipRequest, accountDB accounts.Database, body threepid.MembershipRequest, accountDB accounts.Database,
device *authtypes.Device, device *userapi.Device,
membership, roomID string, isDirect bool, membership, roomID string, isDirect bool,
cfg *config.Dendrite, evTime time.Time, cfg *config.Dendrite, evTime time.Time,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI, rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
@ -188,7 +189,7 @@ func buildMembershipEvent(
return nil, err return nil, err
} }
return internal.BuildEvent(ctx, &builder, cfg, evTime, rsAPI, nil) return eventutil.BuildEvent(ctx, &builder, cfg, evTime, rsAPI, nil)
} }
// loadProfile lookups the profile of a given user from the database and returns // loadProfile lookups the profile of a given user from the database and returns
@ -223,7 +224,7 @@ func loadProfile(
// In the latter case, if there was an issue retrieving the user ID from the request body, // 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. // returns a JSONResponse with a corresponding error code and message.
func getMembershipStateKey( func getMembershipStateKey(
body threepid.MembershipRequest, device *authtypes.Device, membership string, body threepid.MembershipRequest, device *userapi.Device, membership string,
) (stateKey string, reason string, err error) { ) (stateKey string, reason string, err error) {
if membership == gomatrixserverlib.Ban || membership == "unban" || membership == "kick" || membership == gomatrixserverlib.Invite { 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, // If we're in this case, the state key is contained in the request body,
@ -245,7 +246,7 @@ func getMembershipStateKey(
func checkAndProcessThreepid( func checkAndProcessThreepid(
req *http.Request, req *http.Request,
device *authtypes.Device, device *userapi.Device,
body *threepid.MembershipRequest, body *threepid.MembershipRequest,
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI roomserverAPI.RoomserverInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI,
@ -268,7 +269,7 @@ func checkAndProcessThreepid(
Code: http.StatusBadRequest, Code: http.StatusBadRequest,
JSON: jsonerror.NotTrusted(body.IDServer), JSON: jsonerror.NotTrusted(body.IDServer),
} }
} else if err == internal.ErrRoomNoExists { } else if err == eventutil.ErrRoomNoExists {
return inviteStored, &util.JSONResponse{ return inviteStored, &util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,
JSON: jsonerror.NotFound(err.Error()), JSON: jsonerror.NotFound(err.Error()),

View file

@ -15,14 +15,15 @@
package routing package routing
import ( import (
"encoding/json"
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -35,9 +36,19 @@ type getJoinedRoomsResponse struct {
JoinedRooms []string `json:"joined_rooms"` JoinedRooms []string `json:"joined_rooms"`
} }
// https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-joined-members
type getJoinedMembersResponse struct {
Joined map[string]joinedMember `json:"joined"`
}
type joinedMember struct {
DisplayName string `json:"display_name"`
AvatarURL string `json:"avatar_url"`
}
// GetMemberships implements GET /rooms/{roomId}/members // GetMemberships implements GET /rooms/{roomId}/members
func GetMemberships( func GetMemberships(
req *http.Request, device *authtypes.Device, roomID string, joinedOnly bool, req *http.Request, device *userapi.Device, roomID string, joinedOnly bool,
_ *config.Dendrite, _ *config.Dendrite,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
) util.JSONResponse { ) util.JSONResponse {
@ -59,6 +70,22 @@ func GetMemberships(
} }
} }
if joinedOnly {
var res getJoinedMembersResponse
res.Joined = make(map[string]joinedMember)
for _, ev := range queryRes.JoinEvents {
var content joinedMember
if err := json.Unmarshal(ev.Content, &content); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("failed to unmarshal event content")
return jsonerror.InternalServerError()
}
res.Joined[ev.Sender] = content
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: res,
}
}
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: getMembershipResponse{queryRes.JoinEvents}, JSON: getMembershipResponse{queryRes.JoinEvents},
@ -67,7 +94,7 @@ func GetMemberships(
func GetJoinedRooms( func GetJoinedRooms(
req *http.Request, req *http.Request,
device *authtypes.Device, device *userapi.Device,
accountsDB accounts.Database, accountsDB accounts.Database,
) util.JSONResponse { ) util.JSONResponse {
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)

View file

@ -21,12 +21,13 @@ import (
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "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/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrix"
@ -42,7 +43,7 @@ func GetProfile(
) util.JSONResponse { ) util.JSONResponse {
profile, err := getProfile(req.Context(), accountDB, cfg, userID, asAPI, federation) profile, err := getProfile(req.Context(), accountDB, cfg, userID, asAPI, federation)
if err != nil { if err != nil {
if err == internal.ErrProfileNoExists { if err == eventutil.ErrProfileNoExists {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,
JSON: jsonerror.NotFound("The user does not exist or does not have a profile"), JSON: jsonerror.NotFound("The user does not exist or does not have a profile"),
@ -55,7 +56,7 @@ func GetProfile(
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: internal.ProfileResponse{ JSON: eventutil.ProfileResponse{
AvatarURL: profile.AvatarURL, AvatarURL: profile.AvatarURL,
DisplayName: profile.DisplayName, DisplayName: profile.DisplayName,
}, },
@ -70,7 +71,7 @@ func GetAvatarURL(
) util.JSONResponse { ) util.JSONResponse {
profile, err := getProfile(req.Context(), accountDB, cfg, userID, asAPI, federation) profile, err := getProfile(req.Context(), accountDB, cfg, userID, asAPI, federation)
if err != nil { if err != nil {
if err == internal.ErrProfileNoExists { if err == eventutil.ErrProfileNoExists {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,
JSON: jsonerror.NotFound("The user does not exist or does not have a profile"), JSON: jsonerror.NotFound("The user does not exist or does not have a profile"),
@ -83,7 +84,7 @@ func GetAvatarURL(
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: internal.AvatarURL{ JSON: eventutil.AvatarURL{
AvatarURL: profile.AvatarURL, AvatarURL: profile.AvatarURL,
}, },
} }
@ -92,7 +93,7 @@ func GetAvatarURL(
// SetAvatarURL implements PUT /profile/{userID}/avatar_url // SetAvatarURL implements PUT /profile/{userID}/avatar_url
// nolint:gocyclo // nolint:gocyclo
func SetAvatarURL( 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, userID string, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI,
) util.JSONResponse { ) util.JSONResponse {
if userID != device.UserID { if userID != device.UserID {
@ -102,7 +103,7 @@ func SetAvatarURL(
} }
} }
var r internal.AvatarURL var r eventutil.AvatarURL
if resErr := httputil.UnmarshalJSONRequest(req, &r); resErr != nil { if resErr := httputil.UnmarshalJSONRequest(req, &r); resErr != nil {
return *resErr return *resErr
} }
@ -184,7 +185,7 @@ func GetDisplayName(
) util.JSONResponse { ) util.JSONResponse {
profile, err := getProfile(req.Context(), accountDB, cfg, userID, asAPI, federation) profile, err := getProfile(req.Context(), accountDB, cfg, userID, asAPI, federation)
if err != nil { if err != nil {
if err == internal.ErrProfileNoExists { if err == eventutil.ErrProfileNoExists {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,
JSON: jsonerror.NotFound("The user does not exist or does not have a profile"), JSON: jsonerror.NotFound("The user does not exist or does not have a profile"),
@ -197,7 +198,7 @@ func GetDisplayName(
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: internal.DisplayName{ JSON: eventutil.DisplayName{
DisplayName: profile.DisplayName, DisplayName: profile.DisplayName,
}, },
} }
@ -206,7 +207,7 @@ func GetDisplayName(
// SetDisplayName implements PUT /profile/{userID}/displayname // SetDisplayName implements PUT /profile/{userID}/displayname
// nolint:gocyclo // nolint:gocyclo
func SetDisplayName( 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, userID string, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI,
) util.JSONResponse { ) util.JSONResponse {
if userID != device.UserID { if userID != device.UserID {
@ -216,7 +217,7 @@ func SetDisplayName(
} }
} }
var r internal.DisplayName var r eventutil.DisplayName
if resErr := httputil.UnmarshalJSONRequest(req, &r); resErr != nil { if resErr := httputil.UnmarshalJSONRequest(req, &r); resErr != nil {
return *resErr return *resErr
} }
@ -293,7 +294,7 @@ func SetDisplayName(
// getProfile gets the full profile of a user by querying the database or a // getProfile gets the full profile of a user by querying the database or a
// remote homeserver. // remote homeserver.
// Returns an error when something goes wrong or specifically // Returns an error when something goes wrong or specifically
// internal.ErrProfileNoExists when the profile doesn't exist. // eventutil.ErrProfileNoExists when the profile doesn't exist.
func getProfile( func getProfile(
ctx context.Context, accountDB accounts.Database, cfg *config.Dendrite, ctx context.Context, accountDB accounts.Database, cfg *config.Dendrite,
userID string, userID string,
@ -310,7 +311,7 @@ func getProfile(
if fedErr != nil { if fedErr != nil {
if x, ok := fedErr.(gomatrix.HTTPError); ok { if x, ok := fedErr.(gomatrix.HTTPError); ok {
if x.Code == http.StatusNotFound { if x.Code == http.StatusNotFound {
return nil, internal.ErrProfileNoExists return nil, eventutil.ErrProfileNoExists
} }
} }
@ -365,7 +366,7 @@ func buildMembershipEvents(
return nil, err return nil, err
} }
event, err := internal.BuildEvent(ctx, &builder, cfg, evTime, rsAPI, nil) event, err := eventutil.BuildEvent(ctx, &builder, cfg, evTime, rsAPI, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -33,15 +33,15 @@ import (
"time" "time"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/clientapi/auth" "github.com/matrix-org/dendrite/clientapi/auth"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "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/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/userutil" "github.com/matrix-org/dendrite/clientapi/userutil"
"github.com/matrix-org/dendrite/internal" userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/tokens" "github.com/matrix-org/gomatrixserverlib/tokens"
"github.com/matrix-org/util" "github.com/matrix-org/util"
@ -136,7 +136,7 @@ type registerRequest struct {
DeviceID *string `json:"device_id"` DeviceID *string `json:"device_id"`
// Prevent this user from logging in // Prevent this user from logging in
InhibitLogin internal.WeakBoolean `json:"inhibit_login"` InhibitLogin eventutil.WeakBoolean `json:"inhibit_login"`
// Application Services place Type in the root of their registration // Application Services place Type in the root of their registration
// request, whereas clients place it in the authDict struct. // request, whereas clients place it in the authDict struct.
@ -440,8 +440,8 @@ func validateApplicationService(
// http://matrix.org/speculator/spec/HEAD/client_server/unstable.html#post-matrix-client-unstable-register // http://matrix.org/speculator/spec/HEAD/client_server/unstable.html#post-matrix-client-unstable-register
func Register( func Register(
req *http.Request, req *http.Request,
userAPI userapi.UserInternalAPI,
accountDB accounts.Database, accountDB accounts.Database,
deviceDB devices.Database,
cfg *config.Dendrite, cfg *config.Dendrite,
) util.JSONResponse { ) util.JSONResponse {
var r registerRequest var r registerRequest
@ -450,7 +450,7 @@ func Register(
return *resErr return *resErr
} }
if req.URL.Query().Get("kind") == "guest" { if req.URL.Query().Get("kind") == "guest" {
return handleGuestRegistration(req, r, cfg, accountDB, deviceDB) return handleGuestRegistration(req, r, cfg, userAPI)
} }
// Retrieve or generate the sessionID // Retrieve or generate the sessionID
@ -506,21 +506,19 @@ func Register(
"session_id": r.Auth.Session, "session_id": r.Auth.Session,
}).Info("Processing registration request") }).Info("Processing registration request")
resp := handleRegistrationFlow(req, r, sessionID, cfg, accountDB, deviceDB) return handleRegistrationFlow(req, r, sessionID, cfg, userAPI)
j, _ := json.MarshalIndent(resp, "", " ")
fmt.Println("ERROR!")
fmt.Println(string(j))
return resp
} }
func handleGuestRegistration( func handleGuestRegistration(
req *http.Request, req *http.Request,
r registerRequest, r registerRequest,
cfg *config.Dendrite, cfg *config.Dendrite,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
) util.JSONResponse { ) util.JSONResponse {
acc, err := accountDB.CreateGuestAccount(req.Context()) var res userapi.PerformAccountCreationResponse
err := userAPI.PerformAccountCreation(req.Context(), &userapi.PerformAccountCreationRequest{
AccountType: userapi.AccountTypeGuest,
}, &res)
if err != nil { if err != nil {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusInternalServerError, Code: http.StatusInternalServerError,
@ -529,8 +527,8 @@ func handleGuestRegistration(
} }
token, err := tokens.GenerateLoginToken(tokens.TokenOptions{ token, err := tokens.GenerateLoginToken(tokens.TokenOptions{
ServerPrivateKey: cfg.Matrix.PrivateKey.Seed(), ServerPrivateKey: cfg.Matrix.PrivateKey.Seed(),
ServerName: string(acc.ServerName), ServerName: string(res.Account.ServerName),
UserID: acc.UserID, UserID: res.Account.UserID,
}) })
if err != nil { if err != nil {
@ -540,7 +538,12 @@ func handleGuestRegistration(
} }
} }
//we don't allow guests to specify their own device_id //we don't allow guests to specify their own device_id
dev, err := deviceDB.CreateDevice(req.Context(), acc.Localpart, nil, token, r.InitialDisplayName) var devRes userapi.PerformDeviceCreationResponse
err = userAPI.PerformDeviceCreation(req.Context(), &userapi.PerformDeviceCreationRequest{
Localpart: res.Account.Localpart,
DeviceDisplayName: r.InitialDisplayName,
AccessToken: token,
}, &devRes)
if err != nil { if err != nil {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusInternalServerError, Code: http.StatusInternalServerError,
@ -550,10 +553,10 @@ func handleGuestRegistration(
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: registerResponse{ JSON: registerResponse{
UserID: dev.UserID, UserID: devRes.Device.UserID,
AccessToken: dev.AccessToken, AccessToken: devRes.Device.AccessToken,
HomeServer: acc.ServerName, HomeServer: res.Account.ServerName,
DeviceID: dev.ID, DeviceID: devRes.Device.ID,
}, },
} }
} }
@ -566,8 +569,7 @@ func handleRegistrationFlow(
r registerRequest, r registerRequest,
sessionID string, sessionID string,
cfg *config.Dendrite, cfg *config.Dendrite,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
) util.JSONResponse { ) util.JSONResponse {
// TODO: Shared secret registration (create new user scripts) // TODO: Shared secret registration (create new user scripts)
// TODO: Enable registration config flag // TODO: Enable registration config flag
@ -618,7 +620,7 @@ func handleRegistrationFlow(
// by whether the request contains an access token. // by whether the request contains an access token.
if err == nil { if err == nil {
return handleApplicationServiceRegistration( return handleApplicationServiceRegistration(
accessToken, err, req, r, cfg, accountDB, deviceDB, accessToken, err, req, r, cfg, userAPI,
) )
} }
@ -629,7 +631,7 @@ func handleRegistrationFlow(
// don't need a condition on that call since the registration is clearly // don't need a condition on that call since the registration is clearly
// stated as being AS-related. // stated as being AS-related.
return handleApplicationServiceRegistration( return handleApplicationServiceRegistration(
accessToken, err, req, r, cfg, accountDB, deviceDB, accessToken, err, req, r, cfg, userAPI,
) )
case authtypes.LoginTypeDummy: case authtypes.LoginTypeDummy:
@ -648,7 +650,7 @@ func handleRegistrationFlow(
// A response with current registration flow and remaining available methods // A response with current registration flow and remaining available methods
// will be returned if a flow has not been successfully completed yet // will be returned if a flow has not been successfully completed yet
return checkAndCompleteFlow(sessions.GetCompletedStages(sessionID), return checkAndCompleteFlow(sessions.GetCompletedStages(sessionID),
req, r, sessionID, cfg, accountDB, deviceDB) req, r, sessionID, cfg, userAPI)
} }
// handleApplicationServiceRegistration handles the registration of an // handleApplicationServiceRegistration handles the registration of an
@ -665,8 +667,7 @@ func handleApplicationServiceRegistration(
req *http.Request, req *http.Request,
r registerRequest, r registerRequest,
cfg *config.Dendrite, cfg *config.Dendrite,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
) util.JSONResponse { ) util.JSONResponse {
// Check if we previously had issues extracting the access token from the // Check if we previously had issues extracting the access token from the
// request. // request.
@ -690,7 +691,7 @@ func handleApplicationServiceRegistration(
// Don't need to worry about appending to registration stages as // Don't need to worry about appending to registration stages as
// application service registration is entirely separate. // application service registration is entirely separate.
return completeRegistration( return completeRegistration(
req.Context(), accountDB, deviceDB, r.Username, "", appserviceID, req.Context(), userAPI, r.Username, "", appserviceID,
r.InhibitLogin, r.InitialDisplayName, r.DeviceID, r.InhibitLogin, r.InitialDisplayName, r.DeviceID,
) )
} }
@ -704,13 +705,12 @@ func checkAndCompleteFlow(
r registerRequest, r registerRequest,
sessionID string, sessionID string,
cfg *config.Dendrite, cfg *config.Dendrite,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
) util.JSONResponse { ) util.JSONResponse {
if checkFlowCompleted(flow, cfg.Derived.Registration.Flows) { if checkFlowCompleted(flow, cfg.Derived.Registration.Flows) {
// This flow was completed, registration can continue // This flow was completed, registration can continue
return completeRegistration( return completeRegistration(
req.Context(), accountDB, deviceDB, r.Username, r.Password, "", req.Context(), userAPI, r.Username, r.Password, "",
r.InhibitLogin, r.InitialDisplayName, r.DeviceID, r.InhibitLogin, r.InitialDisplayName, r.DeviceID,
) )
} }
@ -727,8 +727,7 @@ func checkAndCompleteFlow(
// LegacyRegister process register requests from the legacy v1 API // LegacyRegister process register requests from the legacy v1 API
func LegacyRegister( func LegacyRegister(
req *http.Request, req *http.Request,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
cfg *config.Dendrite, cfg *config.Dendrite,
) util.JSONResponse { ) util.JSONResponse {
var r legacyRegisterRequest var r legacyRegisterRequest
@ -763,10 +762,10 @@ func LegacyRegister(
return util.MessageResponse(http.StatusForbidden, "HMAC incorrect") return util.MessageResponse(http.StatusForbidden, "HMAC incorrect")
} }
return completeRegistration(req.Context(), accountDB, deviceDB, r.Username, r.Password, "", false, nil, nil) return completeRegistration(req.Context(), userAPI, r.Username, r.Password, "", false, nil, nil)
case authtypes.LoginTypeDummy: case authtypes.LoginTypeDummy:
// there is nothing to do // there is nothing to do
return completeRegistration(req.Context(), accountDB, deviceDB, r.Username, r.Password, "", false, nil, nil) return completeRegistration(req.Context(), userAPI, r.Username, r.Password, "", false, nil, nil)
default: default:
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotImplemented, Code: http.StatusNotImplemented,
@ -812,10 +811,9 @@ func parseAndValidateLegacyLogin(req *http.Request, r *legacyRegisterRequest) *u
// not all // not all
func completeRegistration( func completeRegistration(
ctx context.Context, ctx context.Context,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
username, password, appserviceID string, username, password, appserviceID string,
inhibitLogin internal.WeakBoolean, inhibitLogin eventutil.WeakBoolean,
displayName, deviceID *string, displayName, deviceID *string,
) util.JSONResponse { ) util.JSONResponse {
if username == "" { if username == "" {
@ -832,9 +830,16 @@ func completeRegistration(
} }
} }
acc, err := accountDB.CreateAccount(ctx, username, password, appserviceID) var accRes userapi.PerformAccountCreationResponse
err := userAPI.PerformAccountCreation(ctx, &userapi.PerformAccountCreationRequest{
AppServiceID: appserviceID,
Localpart: username,
Password: password,
AccountType: userapi.AccountTypeUser,
OnConflict: userapi.ConflictAbort,
}, &accRes)
if err != nil { if err != nil {
if errors.Is(err, internal.ErrUserExists) { // user already exists if _, ok := err.(*userapi.ErrorConflict); ok { // user already exists
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusBadRequest, Code: http.StatusBadRequest,
JSON: jsonerror.UserInUse("Desired user ID is already taken."), JSON: jsonerror.UserInUse("Desired user ID is already taken."),
@ -855,8 +860,8 @@ func completeRegistration(
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: registerResponse{ JSON: registerResponse{
UserID: userutil.MakeUserID(username, acc.ServerName), UserID: userutil.MakeUserID(username, accRes.Account.ServerName),
HomeServer: acc.ServerName, HomeServer: accRes.Account.ServerName,
}, },
} }
} }
@ -869,7 +874,13 @@ func completeRegistration(
} }
} }
dev, err := deviceDB.CreateDevice(ctx, username, deviceID, token, displayName) var devRes userapi.PerformDeviceCreationResponse
err = userAPI.PerformDeviceCreation(ctx, &userapi.PerformDeviceCreationRequest{
Localpart: username,
AccessToken: token,
DeviceDisplayName: displayName,
DeviceID: deviceID,
}, &devRes)
if err != nil { if err != nil {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusInternalServerError, Code: http.StatusInternalServerError,
@ -880,10 +891,10 @@ func completeRegistration(
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: registerResponse{ JSON: registerResponse{
UserID: dev.UserID, UserID: devRes.Device.UserID,
AccessToken: dev.AccessToken, AccessToken: devRes.Device.AccessToken,
HomeServer: acc.ServerName, HomeServer: accRes.Account.ServerName,
DeviceID: dev.ID, DeviceID: devRes.Device.ID,
}, },
} }
} }

View file

@ -20,11 +20,11 @@ import (
"github.com/sirupsen/logrus" "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/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/producers" "github.com/matrix-org/dendrite/clientapi/producers"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrix"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
@ -41,7 +41,7 @@ func newTag() gomatrix.TagContent {
func GetTags( func GetTags(
req *http.Request, req *http.Request,
accountDB accounts.Database, accountDB accounts.Database,
device *authtypes.Device, device *api.Device,
userID string, userID string,
roomID string, roomID string,
syncProducer *producers.SyncAPIProducer, syncProducer *producers.SyncAPIProducer,
@ -79,7 +79,7 @@ func GetTags(
func PutTag( func PutTag(
req *http.Request, req *http.Request,
accountDB accounts.Database, accountDB accounts.Database,
device *authtypes.Device, device *api.Device,
userID string, userID string,
roomID string, roomID string,
tag string, tag string,
@ -139,7 +139,7 @@ func PutTag(
func DeleteTag( func DeleteTag(
req *http.Request, req *http.Request,
accountDB accounts.Database, accountDB accounts.Database,
device *authtypes.Device, device *api.Device,
userID string, userID string,
roomID string, roomID string,
tag string, tag string,

View file

@ -21,18 +21,17 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" 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" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/producers" "github.com/matrix-org/dendrite/clientapi/producers"
eduServerAPI "github.com/matrix-org/dendrite/eduserver/api" eduServerAPI "github.com/matrix-org/dendrite/eduserver/api"
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/transactions" "github.com/matrix-org/dendrite/internal/transactions"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/dendrite/userapi/storage/devices"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -54,15 +53,15 @@ func Setup(
asAPI appserviceAPI.AppServiceQueryAPI, asAPI appserviceAPI.AppServiceQueryAPI,
accountDB accounts.Database, accountDB accounts.Database,
deviceDB devices.Database, deviceDB devices.Database,
userAPI api.UserInternalAPI,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
keyRing gomatrixserverlib.KeyRing,
syncProducer *producers.SyncAPIProducer, syncProducer *producers.SyncAPIProducer,
transactionsCache *transactions.Cache, transactionsCache *transactions.Cache,
federationSender federationSenderAPI.FederationSenderInternalAPI, federationSender federationSenderAPI.FederationSenderInternalAPI,
) { ) {
publicAPIMux.Handle("/client/versions", publicAPIMux.Handle("/client/versions",
internal.MakeExternalAPI("versions", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("versions", func(req *http.Request) util.JSONResponse {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: struct { JSON: struct {
@ -81,20 +80,14 @@ func Setup(
v1mux := publicAPIMux.PathPrefix(pathPrefixV1).Subrouter() v1mux := publicAPIMux.PathPrefix(pathPrefixV1).Subrouter()
unstableMux := publicAPIMux.PathPrefix(pathPrefixUnstable).Subrouter() unstableMux := publicAPIMux.PathPrefix(pathPrefixUnstable).Subrouter()
authData := auth.Data{
AccountDB: accountDB,
DeviceDB: deviceDB,
AppServices: cfg.Derived.ApplicationServices,
}
r0mux.Handle("/createRoom", r0mux.Handle("/createRoom",
internal.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) return CreateRoom(req, device, cfg, accountDB, rsAPI, asAPI)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/join/{roomIDOrAlias}", r0mux.Handle("/join/{roomIDOrAlias}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -104,13 +97,13 @@ func Setup(
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/joined_rooms", r0mux.Handle("/joined_rooms",
internal.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) return GetJoinedRooms(req, device, accountDB)
}), }),
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/leave", r0mux.Handle("/rooms/{roomID}/leave",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -120,8 +113,8 @@ func Setup(
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/{membership:(?:join|kick|ban|unban|invite)}", r0mux.Handle("/rooms/{roomID}/{membership:(?:join|kick|ban|unban|invite)}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -129,8 +122,8 @@ func Setup(
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/send/{eventType}", r0mux.Handle("/rooms/{roomID}/send/{eventType}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -138,8 +131,8 @@ func Setup(
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/send/{eventType}/{txnID}", r0mux.Handle("/rooms/{roomID}/send/{eventType}/{txnID}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -149,42 +142,44 @@ func Setup(
}), }),
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/event/{eventID}", r0mux.Handle("/rooms/{roomID}/event/{eventID}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
return GetEvent(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI, federation, keyRing) return GetEvent(req, device, vars["roomID"], vars["eventID"], cfg, rsAPI, federation)
}), }),
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state", internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
return OnIncomingStateRequest(req.Context(), rsAPI, vars["roomID"]) return OnIncomingStateRequest(req.Context(), rsAPI, vars["roomID"])
})).Methods(http.MethodGet, http.MethodOptions) })).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state/{type}", internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
return OnIncomingStateTypeRequest(req.Context(), rsAPI, vars["roomID"], vars["type"], "") eventFormat := req.URL.Query().Get("format") == "event"
return OnIncomingStateTypeRequest(req.Context(), rsAPI, vars["roomID"], vars["type"], "", eventFormat)
})).Methods(http.MethodGet, http.MethodOptions) })).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state/{type}/{stateKey}", internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
return OnIncomingStateTypeRequest(req.Context(), rsAPI, vars["roomID"], vars["type"], vars["stateKey"]) eventFormat := req.URL.Query().Get("format") == "event"
return OnIncomingStateTypeRequest(req.Context(), rsAPI, vars["roomID"], vars["type"], vars["stateKey"], eventFormat)
})).Methods(http.MethodGet, http.MethodOptions) })).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state/{eventType:[^/]+/?}", r0mux.Handle("/rooms/{roomID}/state/{eventType:[^/]+/?}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -199,8 +194,8 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/state/{eventType}/{stateKey}", r0mux.Handle("/rooms/{roomID}/state/{eventType}/{stateKey}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -209,21 +204,21 @@ func Setup(
}), }),
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/register", internal.MakeExternalAPI("register", func(req *http.Request) util.JSONResponse { r0mux.Handle("/register", httputil.MakeExternalAPI("register", func(req *http.Request) util.JSONResponse {
return Register(req, accountDB, deviceDB, cfg) return Register(req, userAPI, accountDB, cfg)
})).Methods(http.MethodPost, http.MethodOptions) })).Methods(http.MethodPost, http.MethodOptions)
v1mux.Handle("/register", internal.MakeExternalAPI("register", func(req *http.Request) util.JSONResponse { v1mux.Handle("/register", httputil.MakeExternalAPI("register", func(req *http.Request) util.JSONResponse {
return LegacyRegister(req, accountDB, deviceDB, cfg) return LegacyRegister(req, userAPI, cfg)
})).Methods(http.MethodPost, http.MethodOptions) })).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/register/available", internal.MakeExternalAPI("registerAvailable", func(req *http.Request) util.JSONResponse { r0mux.Handle("/register/available", httputil.MakeExternalAPI("registerAvailable", func(req *http.Request) util.JSONResponse {
return RegisterAvailable(req, cfg, accountDB) return RegisterAvailable(req, cfg, accountDB)
})).Methods(http.MethodGet, http.MethodOptions) })).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/directory/room/{roomAlias}", r0mux.Handle("/directory/room/{roomAlias}",
internal.MakeExternalAPI("directory_room", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("directory_room", func(req *http.Request) util.JSONResponse {
vars, err := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -232,8 +227,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/directory/room/{roomAlias}", r0mux.Handle("/directory/room/{roomAlias}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -242,8 +237,8 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/directory/room/{roomAlias}", r0mux.Handle("/directory/room/{roomAlias}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -252,20 +247,20 @@ func Setup(
).Methods(http.MethodDelete, http.MethodOptions) ).Methods(http.MethodDelete, http.MethodOptions)
r0mux.Handle("/logout", r0mux.Handle("/logout",
internal.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) return Logout(req, deviceDB, device)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/logout/all", r0mux.Handle("/logout/all",
internal.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) return LogoutAll(req, deviceDB, device)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/typing/{userID}", r0mux.Handle("/rooms/{roomID}/typing/{userID}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -274,8 +269,8 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/sendToDevice/{eventType}/{txnID}", r0mux.Handle("/sendToDevice/{eventType}/{txnID}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -288,8 +283,8 @@ func Setup(
// rather than r0. It's an exact duplicate of the above handler. // rather than r0. It's an exact duplicate of the above handler.
// TODO: Remove this if/when sytest is fixed! // TODO: Remove this if/when sytest is fixed!
unstableMux.Handle("/sendToDevice/{eventType}/{txnID}", unstableMux.Handle("/sendToDevice/{eventType}/{txnID}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -299,7 +294,7 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/account/whoami", r0mux.Handle("/account/whoami",
internal.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) return Whoami(req, device)
}), }),
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
@ -307,20 +302,20 @@ func Setup(
// Stub endpoints required by Riot // Stub endpoints required by Riot
r0mux.Handle("/login", r0mux.Handle("/login",
internal.MakeExternalAPI("login", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("login", func(req *http.Request) util.JSONResponse {
return Login(req, accountDB, deviceDB, cfg) return Login(req, accountDB, deviceDB, cfg)
}), }),
).Methods(http.MethodGet, http.MethodPost, http.MethodOptions) ).Methods(http.MethodGet, http.MethodPost, http.MethodOptions)
r0mux.Handle("/auth/{authType}/fallback/web", r0mux.Handle("/auth/{authType}/fallback/web",
internal.MakeHTMLAPI("auth_fallback", func(w http.ResponseWriter, req *http.Request) *util.JSONResponse { httputil.MakeHTMLAPI("auth_fallback", func(w http.ResponseWriter, req *http.Request) *util.JSONResponse {
vars := mux.Vars(req) vars := mux.Vars(req)
return AuthFallback(w, req, vars["authType"], cfg) return AuthFallback(w, req, vars["authType"], cfg)
}), }),
).Methods(http.MethodGet, http.MethodPost, http.MethodOptions) ).Methods(http.MethodGet, http.MethodPost, http.MethodOptions)
r0mux.Handle("/pushrules/", r0mux.Handle("/pushrules/",
internal.MakeExternalAPI("push_rules", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("push_rules", func(req *http.Request) util.JSONResponse {
// TODO: Implement push rules API // TODO: Implement push rules API
res := json.RawMessage(`{ res := json.RawMessage(`{
"global": { "global": {
@ -339,8 +334,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/user/{userId}/filter", r0mux.Handle("/user/{userId}/filter",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -349,8 +344,8 @@ func Setup(
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/user/{userId}/filter/{filterId}", r0mux.Handle("/user/{userId}/filter/{filterId}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -361,8 +356,8 @@ func Setup(
// Riot user settings // Riot user settings
r0mux.Handle("/profile/{userID}", r0mux.Handle("/profile/{userID}",
internal.MakeExternalAPI("profile", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("profile", func(req *http.Request) util.JSONResponse {
vars, err := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -371,8 +366,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/profile/{userID}/avatar_url", r0mux.Handle("/profile/{userID}/avatar_url",
internal.MakeExternalAPI("profile_avatar_url", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("profile_avatar_url", func(req *http.Request) util.JSONResponse {
vars, err := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -381,8 +376,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/profile/{userID}/avatar_url", r0mux.Handle("/profile/{userID}/avatar_url",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -393,8 +388,8 @@ func Setup(
// PUT requests, so we need to allow this method // PUT requests, so we need to allow this method
r0mux.Handle("/profile/{userID}/displayname", r0mux.Handle("/profile/{userID}/displayname",
internal.MakeExternalAPI("profile_displayname", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("profile_displayname", func(req *http.Request) util.JSONResponse {
vars, err := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -403,8 +398,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/profile/{userID}/displayname", r0mux.Handle("/profile/{userID}/displayname",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -415,32 +410,32 @@ func Setup(
// PUT requests, so we need to allow this method // PUT requests, so we need to allow this method
r0mux.Handle("/account/3pid", r0mux.Handle("/account/3pid",
internal.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) return GetAssociated3PIDs(req, accountDB, device)
}), }),
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/account/3pid", r0mux.Handle("/account/3pid",
internal.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) return CheckAndSave3PIDAssociation(req, accountDB, device, cfg)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
unstableMux.Handle("/account/3pid/delete", unstableMux.Handle("/account/3pid/delete",
internal.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) return Forget3PID(req, accountDB)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/{path:(?:account/3pid|register)}/email/requestToken", r0mux.Handle("/{path:(?:account/3pid|register)}/email/requestToken",
internal.MakeExternalAPI("account_3pid_request_token", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("account_3pid_request_token", func(req *http.Request) util.JSONResponse {
return RequestEmailToken(req, accountDB, cfg) return RequestEmailToken(req, accountDB, cfg)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
// Riot logs get flooded unless this is handled // Riot logs get flooded unless this is handled
r0mux.Handle("/presence/{userID}/status", r0mux.Handle("/presence/{userID}/status",
internal.MakeExternalAPI("presence", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("presence", func(req *http.Request) util.JSONResponse {
// TODO: Set presence (probably the responsibility of a presence server not clientapi) // TODO: Set presence (probably the responsibility of a presence server not clientapi)
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
@ -450,13 +445,13 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/voip/turnServer", r0mux.Handle("/voip/turnServer",
internal.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) return RequestTurnServer(req, device, cfg)
}), }),
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/thirdparty/protocols", r0mux.Handle("/thirdparty/protocols",
internal.MakeExternalAPI("thirdparty_protocols", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("thirdparty_protocols", func(req *http.Request) util.JSONResponse {
// TODO: Return the third party protcols // TODO: Return the third party protcols
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
@ -466,7 +461,7 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/initialSync", r0mux.Handle("/rooms/{roomID}/initialSync",
internal.MakeExternalAPI("rooms_initial_sync", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("rooms_initial_sync", func(req *http.Request) util.JSONResponse {
// TODO: Allow people to peek into rooms. // TODO: Allow people to peek into rooms.
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusForbidden, Code: http.StatusForbidden,
@ -476,8 +471,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/user/{userID}/account_data/{type}", r0mux.Handle("/user/{userID}/account_data/{type}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -486,8 +481,8 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/user/{userID}/rooms/{roomID}/account_data/{type}", r0mux.Handle("/user/{userID}/rooms/{roomID}/account_data/{type}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -496,8 +491,8 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/user/{userID}/account_data/{type}", r0mux.Handle("/user/{userID}/account_data/{type}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -506,8 +501,8 @@ func Setup(
).Methods(http.MethodGet) ).Methods(http.MethodGet)
r0mux.Handle("/user/{userID}/rooms/{roomID}/account_data/{type}", r0mux.Handle("/user/{userID}/rooms/{roomID}/account_data/{type}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -516,8 +511,8 @@ func Setup(
).Methods(http.MethodGet) ).Methods(http.MethodGet)
r0mux.Handle("/rooms/{roomID}/members", r0mux.Handle("/rooms/{roomID}/members",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -526,8 +521,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/joined_members", r0mux.Handle("/rooms/{roomID}/joined_members",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -536,21 +531,21 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/rooms/{roomID}/read_markers", r0mux.Handle("/rooms/{roomID}/read_markers",
internal.MakeExternalAPI("rooms_read_markers", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("rooms_read_markers", func(req *http.Request) util.JSONResponse {
// TODO: return the read_markers. // TODO: return the read_markers.
return util.JSONResponse{Code: http.StatusOK, JSON: struct{}{}} return util.JSONResponse{Code: http.StatusOK, JSON: struct{}{}}
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
r0mux.Handle("/devices", r0mux.Handle("/devices",
internal.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) return GetDevicesByLocalpart(req, deviceDB, device)
}), }),
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/devices/{deviceID}", r0mux.Handle("/devices/{deviceID}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -559,8 +554,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/devices/{deviceID}", r0mux.Handle("/devices/{deviceID}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -569,8 +564,8 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/devices/{deviceID}", r0mux.Handle("/devices/{deviceID}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -579,14 +574,14 @@ func Setup(
).Methods(http.MethodDelete, http.MethodOptions) ).Methods(http.MethodDelete, http.MethodOptions)
r0mux.Handle("/delete_devices", r0mux.Handle("/delete_devices",
internal.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) return DeleteDevices(req, deviceDB, device)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
// Stub implementations for sytest // Stub implementations for sytest
r0mux.Handle("/events", r0mux.Handle("/events",
internal.MakeExternalAPI("events", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("events", func(req *http.Request) util.JSONResponse {
return util.JSONResponse{Code: http.StatusOK, JSON: map[string]interface{}{ return util.JSONResponse{Code: http.StatusOK, JSON: map[string]interface{}{
"chunk": []interface{}{}, "chunk": []interface{}{},
"start": "", "start": "",
@ -596,7 +591,7 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/initialSync", r0mux.Handle("/initialSync",
internal.MakeExternalAPI("initial_sync", func(req *http.Request) util.JSONResponse { httputil.MakeExternalAPI("initial_sync", func(req *http.Request) util.JSONResponse {
return util.JSONResponse{Code: http.StatusOK, JSON: map[string]interface{}{ return util.JSONResponse{Code: http.StatusOK, JSON: map[string]interface{}{
"end": "", "end": "",
}} }}
@ -604,8 +599,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/user/{userId}/rooms/{roomId}/tags", r0mux.Handle("/user/{userId}/rooms/{roomId}/tags",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -614,8 +609,8 @@ func Setup(
).Methods(http.MethodGet, http.MethodOptions) ).Methods(http.MethodGet, http.MethodOptions)
r0mux.Handle("/user/{userId}/rooms/{roomId}/tags/{tag}", r0mux.Handle("/user/{userId}/rooms/{roomId}/tags/{tag}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -624,8 +619,8 @@ func Setup(
).Methods(http.MethodPut, http.MethodOptions) ).Methods(http.MethodPut, http.MethodOptions)
r0mux.Handle("/user/{userId}/rooms/{roomId}/tags/{tag}", r0mux.Handle("/user/{userId}/rooms/{roomId}/tags/{tag}",
internal.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 := internal.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
return util.ErrorResponse(err) return util.ErrorResponse(err)
} }
@ -634,7 +629,7 @@ func Setup(
).Methods(http.MethodDelete, http.MethodOptions) ).Methods(http.MethodDelete, http.MethodOptions)
r0mux.Handle("/capabilities", r0mux.Handle("/capabilities",
internal.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) return GetCapabilities(req, rsAPI)
}), }),
).Methods(http.MethodGet) ).Methods(http.MethodGet)

View file

@ -17,13 +17,13 @@ package routing
import ( import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "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/internal/transactions"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -41,7 +41,7 @@ type sendEventResponse struct {
// /rooms/{roomID}/state/{eventType}/{stateKey} // /rooms/{roomID}/state/{eventType}/{stateKey}
func SendEvent( func SendEvent(
req *http.Request, req *http.Request,
device *authtypes.Device, device *userapi.Device,
roomID, eventType string, txnID, stateKey *string, roomID, eventType string, txnID, stateKey *string,
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
@ -110,7 +110,7 @@ func SendEvent(
func generateSendEvent( func generateSendEvent(
req *http.Request, req *http.Request,
device *authtypes.Device, device *userapi.Device,
roomID, eventType string, stateKey *string, roomID, eventType string, stateKey *string,
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
@ -146,8 +146,8 @@ func generateSendEvent(
} }
var queryRes api.QueryLatestEventsAndStateResponse var queryRes api.QueryLatestEventsAndStateResponse
e, err := internal.BuildEvent(req.Context(), &builder, cfg, evTime, rsAPI, &queryRes) e, err := eventutil.BuildEvent(req.Context(), &builder, cfg, evTime, rsAPI, &queryRes)
if err == internal.ErrRoomNoExists { if err == eventutil.ErrRoomNoExists {
return nil, &util.JSONResponse{ return nil, &util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,
JSON: jsonerror.NotFound("Room does not exist"), JSON: jsonerror.NotFound("Room does not exist"),
@ -158,7 +158,7 @@ func generateSendEvent(
JSON: jsonerror.BadJSON(e.Error()), JSON: jsonerror.BadJSON(e.Error()),
} }
} else if err != nil { } else if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("internal.BuildEvent failed") util.GetLogger(req.Context()).WithError(err).Error("eventutil.BuildEvent failed")
resErr := jsonerror.InternalServerError() resErr := jsonerror.InternalServerError()
return nil, &resErr return nil, &resErr
} }

View file

@ -16,18 +16,18 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/eduserver/api" "github.com/matrix-org/dendrite/eduserver/api"
"github.com/matrix-org/dendrite/internal/transactions" "github.com/matrix-org/dendrite/internal/transactions"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
// SendToDevice handles PUT /_matrix/client/r0/sendToDevice/{eventType}/{txnId} // SendToDevice handles PUT /_matrix/client/r0/sendToDevice/{eventType}/{txnId}
// sends the device events to the EDU Server // sends the device events to the EDU Server
func SendToDevice( func SendToDevice(
req *http.Request, device *authtypes.Device, req *http.Request, device *userapi.Device,
eduAPI api.EDUServerInputAPI, eduAPI api.EDUServerInputAPI,
txnCache *transactions.Cache, txnCache *transactions.Cache,
eventType string, txnID *string, eventType string, txnID *string,

View file

@ -16,12 +16,12 @@ import (
"database/sql" "database/sql"
"net/http" "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/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/userutil" "github.com/matrix-org/dendrite/clientapi/userutil"
"github.com/matrix-org/dendrite/eduserver/api" "github.com/matrix-org/dendrite/eduserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -33,7 +33,7 @@ type typingContentJSON struct {
// SendTyping handles PUT /rooms/{roomID}/typing/{userID} // SendTyping handles PUT /rooms/{roomID}/typing/{userID}
// sends the typing events to client API typingProducer // sends the typing events to client API typingProducer
func SendTyping( func SendTyping(
req *http.Request, device *authtypes.Device, roomID string, req *http.Request, device *userapi.Device, roomID string,
userID string, accountDB accounts.Database, userID string, accountDB accounts.Database,
eduAPI api.EDUServerInputAPI, eduAPI api.EDUServerInputAPI,
) util.JSONResponse { ) util.JSONResponse {

View file

@ -98,7 +98,8 @@ func OnIncomingStateRequest(ctx context.Context, rsAPI api.RoomserverInternalAPI
// /rooms/{roomID}/state/{type}/{statekey} request. It will look in current // /rooms/{roomID}/state/{type}/{statekey} request. It will look in current
// state to see if there is an event with that type and state key, if there // state to see if there is an event with that type and state key, if there
// is then (by default) we return the content, otherwise a 404. // is then (by default) we return the content, otherwise a 404.
func OnIncomingStateTypeRequest(ctx context.Context, rsAPI api.RoomserverInternalAPI, roomID string, evType, stateKey string) util.JSONResponse { // If eventFormat=true, sends the whole event else just the content.
func OnIncomingStateTypeRequest(ctx context.Context, rsAPI api.RoomserverInternalAPI, roomID, evType, stateKey string, eventFormat bool) util.JSONResponse {
// TODO(#287): Auth request and handle the case where the user has left (where // TODO(#287): Auth request and handle the case where the user has left (where
// we should return the state at the poin they left) // we should return the state at the poin they left)
util.GetLogger(ctx).WithFields(log.Fields{ util.GetLogger(ctx).WithFields(log.Fields{
@ -134,8 +135,15 @@ func OnIncomingStateTypeRequest(ctx context.Context, rsAPI api.RoomserverInterna
ClientEvent: gomatrixserverlib.HeaderedToClientEvent(stateRes.StateEvents[0], gomatrixserverlib.FormatAll), ClientEvent: gomatrixserverlib.HeaderedToClientEvent(stateRes.StateEvents[0], gomatrixserverlib.FormatAll),
} }
var res interface{}
if eventFormat {
res = stateEvent
} else {
res = stateEvent.Content
}
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: stateEvent.Content, JSON: res,
} }
} }

View file

@ -18,11 +18,12 @@ import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "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/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/threepid" "github.com/matrix-org/dendrite/clientapi/threepid"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
@ -84,7 +85,7 @@ func RequestEmailToken(req *http.Request, accountDB accounts.Database, cfg *conf
// CheckAndSave3PIDAssociation implements POST /account/3pid // CheckAndSave3PIDAssociation implements POST /account/3pid
func CheckAndSave3PIDAssociation( func CheckAndSave3PIDAssociation(
req *http.Request, accountDB accounts.Database, device *authtypes.Device, req *http.Request, accountDB accounts.Database, device *api.Device,
cfg *config.Dendrite, cfg *config.Dendrite,
) util.JSONResponse { ) util.JSONResponse {
var body threepid.EmailAssociationCheckRequest var body threepid.EmailAssociationCheckRequest
@ -148,7 +149,7 @@ func CheckAndSave3PIDAssociation(
// GetAssociated3PIDs implements GET /account/3pid // GetAssociated3PIDs implements GET /account/3pid
func GetAssociated3PIDs( func GetAssociated3PIDs(
req *http.Request, accountDB accounts.Database, device *authtypes.Device, req *http.Request, accountDB accounts.Database, device *api.Device,
) util.JSONResponse { ) util.JSONResponse {
localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
if err != nil { if err != nil {

View file

@ -22,16 +22,16 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrix"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
// RequestTurnServer implements: // RequestTurnServer implements:
// GET /voip/turnServer // 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 turnConfig := cfg.TURN
// TODO Guest Support // TODO Guest Support

View file

@ -15,7 +15,7 @@ package routing
import ( import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/util" "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. // 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 // 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{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: whoamiResponse{UserID: device.UserID}, JSON: whoamiResponse{UserID: device.UserID},

View file

@ -25,10 +25,11 @@ import (
"time" "time"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
@ -85,7 +86,7 @@ var (
// can be emitted. // can be emitted.
func CheckAndProcessInvite( func CheckAndProcessInvite(
ctx context.Context, 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, rsAPI api.RoomserverInternalAPI, db accounts.Database,
membership string, roomID string, membership string, roomID string,
evTime time.Time, evTime time.Time,
@ -136,7 +137,7 @@ func CheckAndProcessInvite(
// Returns an error if a check or a request failed. // Returns an error if a check or a request failed.
func queryIDServer( func queryIDServer(
ctx context.Context, 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, body *MembershipRequest, roomID string,
) (lookupRes *idServerLookupResponse, storeInviteRes *idServerStoreInviteResponse, err error) { ) (lookupRes *idServerLookupResponse, storeInviteRes *idServerStoreInviteResponse, err error) {
if err = isTrusted(body.IDServer, cfg); err != nil { 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. // Returns an error if the request failed to send or if the response couldn't be parsed.
func queryIDServerStoreInvite( func queryIDServerStoreInvite(
ctx context.Context, 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, body *MembershipRequest, roomID string,
) (*idServerStoreInviteResponse, error) { ) (*idServerStoreInviteResponse, error) {
// Retrieve the sender's profile to get their display name // Retrieve the sender's profile to get their display name
@ -329,7 +330,7 @@ func checkIDServerSignatures(
func emit3PIDInviteEvent( func emit3PIDInviteEvent(
ctx context.Context, ctx context.Context,
body *MembershipRequest, res *idServerStoreInviteResponse, body *MembershipRequest, res *idServerStoreInviteResponse,
device *authtypes.Device, roomID string, cfg *config.Dendrite, device *userapi.Device, roomID string, cfg *config.Dendrite,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
evTime time.Time, evTime time.Time,
) error { ) error {
@ -353,7 +354,7 @@ func emit3PIDInviteEvent(
} }
queryRes := api.QueryLatestEventsAndStateResponse{} queryRes := api.QueryLatestEventsAndStateResponse{}
event, err := internal.BuildEvent(ctx, builder, cfg, evTime, rsAPI, &queryRes) event, err := eventutil.BuildEvent(ctx, builder, cfg, evTime, rsAPI, &queryRes)
if err != nil { if err != nil {
return err return err
} }

View file

@ -20,8 +20,8 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices" "github.com/matrix-org/dendrite/userapi/storage/devices"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )

View file

@ -47,6 +47,7 @@ var (
userID = flag.String("user-id", "@userid:$SERVER_NAME", "The user ID to use as the event sender") userID = flag.String("user-id", "@userid:$SERVER_NAME", "The user ID to use as the event sender")
messageCount = flag.Int("message-count", 10, "The number of m.room.messsage events to generate") messageCount = flag.Int("message-count", 10, "The number of m.room.messsage events to generate")
format = flag.String("Format", "InputRoomEvent", "The output format to use for the messages: InputRoomEvent or Event") format = flag.String("Format", "InputRoomEvent", "The output format to use for the messages: InputRoomEvent or Event")
ver = flag.String("version", string(gomatrixserverlib.RoomVersionV1), "Room version to generate events as")
) )
// By default we use a private key of 0. // By default we use a private key of 0.
@ -109,7 +110,7 @@ func buildAndOutput() gomatrixserverlib.EventReference {
event, err := b.Build( event, err := b.Build(
now, name, key, privateKey, now, name, key, privateKey,
gomatrixserverlib.RoomVersionV1, gomatrixserverlib.RoomVersion(*ver),
) )
if err != nil { if err != nil {
panic(err) panic(err)
@ -127,7 +128,7 @@ func writeEvent(event gomatrixserverlib.Event) {
if *format == "InputRoomEvent" { if *format == "InputRoomEvent" {
var ire api.InputRoomEvent var ire api.InputRoomEvent
ire.Kind = api.KindNew ire.Kind = api.KindNew
ire.Event = event.Headered(gomatrixserverlib.RoomVersionV1) ire.Event = event.Headered(gomatrixserverlib.RoomVersion(*ver))
authEventIDs := []string{} authEventIDs := []string{}
for _, ref := range b.AuthEvents.([]gomatrixserverlib.EventReference) { for _, ref := range b.AuthEvents.([]gomatrixserverlib.EventReference) {
authEventIDs = append(authEventIDs, ref.EventID) authEventIDs = append(authEventIDs, ref.EventID)

View file

@ -16,19 +16,18 @@ package main
import ( import (
"github.com/matrix-org/dendrite/appservice" "github.com/matrix-org/dendrite/appservice"
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "AppServiceAPI", true) base := setup.NewBaseDendrite(cfg, "AppServiceAPI", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
accountDB := base.CreateAccountsDB() userAPI := base.UserAPIClient()
deviceDB := base.CreateDeviceDB()
rsAPI := base.RoomserverHTTPClient() rsAPI := base.RoomserverHTTPClient()
intAPI := appservice.NewInternalAPI(base, accountDB, deviceDB, rsAPI) intAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
appservice.AddInternalRoutes(base.InternalAPIMux, intAPI) appservice.AddInternalRoutes(base.InternalAPIMux, intAPI)
base.SetupAndServeHTTP(string(base.Cfg.Bind.AppServiceAPI), string(base.Cfg.Listen.AppServiceAPI)) base.SetupAndServeHTTP(string(base.Cfg.Bind.AppServiceAPI), string(base.Cfg.Listen.AppServiceAPI))

View file

@ -16,31 +16,29 @@ package main
import ( import (
"github.com/matrix-org/dendrite/clientapi" "github.com/matrix-org/dendrite/clientapi"
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/internal/transactions" "github.com/matrix-org/dendrite/internal/transactions"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "ClientAPI", true) base := setup.NewBaseDendrite(cfg, "ClientAPI", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
accountDB := base.CreateAccountsDB() accountDB := base.CreateAccountsDB()
deviceDB := base.CreateDeviceDB() deviceDB := base.CreateDeviceDB()
federation := base.CreateFederationClient() federation := base.CreateFederationClient()
serverKeyAPI := base.ServerKeyAPIClient()
keyRing := serverKeyAPI.KeyRing()
asQuery := base.AppserviceHTTPClient() asQuery := base.AppserviceHTTPClient()
rsAPI := base.RoomserverHTTPClient() rsAPI := base.RoomserverHTTPClient()
fsAPI := base.FederationSenderHTTPClient() fsAPI := base.FederationSenderHTTPClient()
eduInputAPI := base.EDUServerClient() eduInputAPI := base.EDUServerClient()
userAPI := base.UserAPIClient()
clientapi.AddPublicRoutes( clientapi.AddPublicRoutes(
base.PublicAPIMux, base.Cfg, base.KafkaConsumer, base.KafkaProducer, deviceDB, accountDB, federation, keyRing, 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)) base.SetupAndServeHTTP(string(base.Cfg.Bind.ClientAPI), string(base.Cfg.Listen.ClientAPI))

View file

@ -32,11 +32,12 @@ import (
"github.com/matrix-org/dendrite/cmd/dendrite-demo-libp2p/storage" "github.com/matrix-org/dendrite/cmd/dendrite-demo-libp2p/storage"
"github.com/matrix-org/dendrite/eduserver" "github.com/matrix-org/dendrite/eduserver"
"github.com/matrix-org/dendrite/federationsender" "github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/serverkeyapi" "github.com/matrix-org/dendrite/serverkeyapi"
"github.com/matrix-org/dendrite/userapi"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/eduserver/cache"
@ -79,6 +80,17 @@ func createFederationClient(
) )
} }
func createClient(
base *P2PDendrite,
) *gomatrixserverlib.Client {
tr := &http.Transport{}
tr.RegisterProtocol(
"matrix",
p2phttp.NewTransport(base.LibP2P, p2phttp.ProtocolOption("/matrix")),
)
return gomatrixserverlib.NewClientWithTransport(tr)
}
func main() { func main() {
instanceName := flag.String("name", "dendrite-p2p", "the name of this P2P demo instance") instanceName := flag.String("name", "dendrite-p2p", "the name of this P2P demo instance")
instancePort := flag.Int("port", 8080, "the port that the client API will listen on") instancePort := flag.Int("port", 8080, "the port that the client API will listen on")
@ -101,6 +113,7 @@ func main() {
} }
cfg := config.Dendrite{} cfg := config.Dendrite{}
cfg.SetDefaults()
cfg.Matrix.ServerName = "p2p" cfg.Matrix.ServerName = "p2p"
cfg.Matrix.PrivateKey = privKey cfg.Matrix.PrivateKey = privKey
cfg.Matrix.KeyID = gomatrixserverlib.KeyID(fmt.Sprintf("ed25519:%s", *instanceName)) cfg.Matrix.KeyID = gomatrixserverlib.KeyID(fmt.Sprintf("ed25519:%s", *instanceName))
@ -128,6 +141,7 @@ func main() {
accountDB := base.Base.CreateAccountsDB() accountDB := base.Base.CreateAccountsDB()
deviceDB := base.Base.CreateDeviceDB() deviceDB := base.Base.CreateDeviceDB()
federation := createFederationClient(base) federation := createFederationClient(base)
userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, nil)
serverKeyAPI := serverkeyapi.NewInternalAPI( serverKeyAPI := serverkeyapi.NewInternalAPI(
base.Base.Cfg, federation, base.Base.Caches, base.Base.Cfg, federation, base.Base.Caches,
@ -141,9 +155,9 @@ func main() {
&base.Base, keyRing, federation, &base.Base, keyRing, federation,
) )
eduInputAPI := eduserver.NewInternalAPI( eduInputAPI := eduserver.NewInternalAPI(
&base.Base, cache.New(), deviceDB, &base.Base, cache.New(), userAPI,
) )
asAPI := appservice.NewInternalAPI(&base.Base, accountDB, deviceDB, rsAPI) asAPI := appservice.NewInternalAPI(&base.Base, userAPI, rsAPI)
fsAPI := federationsender.NewInternalAPI( fsAPI := federationsender.NewInternalAPI(
&base.Base, federation, rsAPI, keyRing, &base.Base, federation, rsAPI, keyRing,
) )
@ -157,6 +171,7 @@ func main() {
Config: base.Base.Cfg, Config: base.Base.Cfg,
AccountDB: accountDB, AccountDB: accountDB,
DeviceDB: deviceDB, DeviceDB: deviceDB,
Client: createClient(base),
FedClient: federation, FedClient: federation,
KeyRing: keyRing, KeyRing: keyRing,
KafkaConsumer: base.Base.KafkaConsumer, KafkaConsumer: base.Base.KafkaConsumer,
@ -167,13 +182,14 @@ func main() {
FederationSenderAPI: fsAPI, FederationSenderAPI: fsAPI,
RoomserverAPI: rsAPI, RoomserverAPI: rsAPI,
ServerKeyAPI: serverKeyAPI, ServerKeyAPI: serverKeyAPI,
UserAPI: userAPI,
PublicRoomsDB: publicRoomsDB, PublicRoomsDB: publicRoomsDB,
} }
monolith.AddAllPublicRoutes(base.Base.PublicAPIMux) monolith.AddAllPublicRoutes(base.Base.PublicAPIMux)
internal.SetupHTTPAPI( httputil.SetupHTTPAPI(
http.DefaultServeMux, base.Base.BaseMux,
base.Base.PublicAPIMux, base.Base.PublicAPIMux,
base.Base.InternalAPIMux, base.Base.InternalAPIMux,
&cfg, &cfg,
@ -184,7 +200,7 @@ func main() {
go func() { go func() {
httpBindAddr := fmt.Sprintf(":%d", *instancePort) httpBindAddr := fmt.Sprintf(":%d", *instancePort)
logrus.Info("Listening on ", httpBindAddr) logrus.Info("Listening on ", httpBindAddr)
logrus.Fatal(http.ListenAndServe(httpBindAddr, nil)) logrus.Fatal(http.ListenAndServe(httpBindAddr, base.Base.BaseMux))
}() }()
// Expose the matrix APIs also via libp2p // Expose the matrix APIs also via libp2p
if base.LibP2P != nil { if base.LibP2P != nil {
@ -197,7 +213,7 @@ func main() {
defer func() { defer func() {
logrus.Fatal(listener.Close()) logrus.Fatal(listener.Close())
}() }()
logrus.Fatal(http.Serve(listener, nil)) logrus.Fatal(http.Serve(listener, base.Base.BaseMux))
}() }()
} }

View file

@ -22,7 +22,7 @@ import (
pstore "github.com/libp2p/go-libp2p-core/peerstore" pstore "github.com/libp2p/go-libp2p-core/peerstore"
record "github.com/libp2p/go-libp2p-record" record "github.com/libp2p/go-libp2p-record"
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
"github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p"
circuit "github.com/libp2p/go-libp2p-circuit" circuit "github.com/libp2p/go-libp2p-circuit"
@ -39,7 +39,7 @@ import (
// P2PDendrite is a Peer-to-Peer variant of BaseDendrite. // P2PDendrite is a Peer-to-Peer variant of BaseDendrite.
type P2PDendrite struct { type P2PDendrite struct {
Base basecomponent.BaseDendrite Base setup.BaseDendrite
// Store our libp2p object so that we can make outgoing connections from it // Store our libp2p object so that we can make outgoing connections from it
// later // later
@ -54,7 +54,7 @@ type P2PDendrite struct {
// The componentName is used for logging purposes, and should be a friendly name // The componentName is used for logging purposes, and should be a friendly name
// of the component running, e.g. SyncAPI. // of the component running, e.g. SyncAPI.
func NewP2PDendrite(cfg *config.Dendrite, componentName string) *P2PDendrite { func NewP2PDendrite(cfg *config.Dendrite, componentName string) *P2PDendrite {
baseDendrite := basecomponent.NewBaseDendrite(cfg, componentName, false) baseDendrite := setup.NewBaseDendrite(cfg, componentName, false)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())

View file

@ -30,12 +30,12 @@ import (
"github.com/matrix-org/dendrite/eduserver" "github.com/matrix-org/dendrite/eduserver"
"github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/federationsender" "github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/basecomponent"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/publicroomsapi/storage"
"github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/userapi"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -91,7 +91,7 @@ func main() {
panic(err) panic(err)
} }
base := basecomponent.NewBaseDendrite(cfg, "Monolith", false) base := setup.NewBaseDendrite(cfg, "Monolith", false)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
accountDB := base.CreateAccountsDB() accountDB := base.CreateAccountsDB()
@ -101,16 +101,18 @@ func main() {
serverKeyAPI := &signing.YggdrasilKeys{} serverKeyAPI := &signing.YggdrasilKeys{}
keyRing := serverKeyAPI.KeyRing() keyRing := serverKeyAPI.KeyRing()
userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, nil)
rsComponent := roomserver.NewInternalAPI( rsComponent := roomserver.NewInternalAPI(
base, keyRing, federation, base, keyRing, federation,
) )
rsAPI := rsComponent rsAPI := rsComponent
eduInputAPI := eduserver.NewInternalAPI( eduInputAPI := eduserver.NewInternalAPI(
base, cache.New(), deviceDB, base, cache.New(), userAPI,
) )
asAPI := appservice.NewInternalAPI(base, accountDB, deviceDB, rsAPI) asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
fsAPI := federationsender.NewInternalAPI( fsAPI := federationsender.NewInternalAPI(
base, federation, rsAPI, keyRing, base, federation, rsAPI, keyRing,
@ -129,6 +131,7 @@ func main() {
Config: base.Cfg, Config: base.Cfg,
AccountDB: accountDB, AccountDB: accountDB,
DeviceDB: deviceDB, DeviceDB: deviceDB,
Client: createClient(ygg),
FedClient: federation, FedClient: federation,
KeyRing: keyRing, KeyRing: keyRing,
KafkaConsumer: base.KafkaConsumer, KafkaConsumer: base.KafkaConsumer,
@ -138,20 +141,34 @@ func main() {
EDUInternalAPI: eduInputAPI, EDUInternalAPI: eduInputAPI,
FederationSenderAPI: fsAPI, FederationSenderAPI: fsAPI,
RoomserverAPI: rsAPI, RoomserverAPI: rsAPI,
UserAPI: userAPI,
//ServerKeyAPI: serverKeyAPI, //ServerKeyAPI: serverKeyAPI,
PublicRoomsDB: publicRoomsDB, PublicRoomsDB: publicRoomsDB,
} }
monolith.AddAllPublicRoutes(base.PublicAPIMux) monolith.AddAllPublicRoutes(base.PublicAPIMux)
internal.SetupHTTPAPI( httputil.SetupHTTPAPI(
http.DefaultServeMux, base.BaseMux,
base.PublicAPIMux, base.PublicAPIMux,
base.InternalAPIMux, base.InternalAPIMux,
cfg, cfg,
base.UseHTTPAPIs, base.UseHTTPAPIs,
) )
// Build both ends of a HTTP multiplex.
httpServer := &http.Server{
Addr: ":0",
TLSNextProto: map[string]func(*http.Server, *tls.Conn, http.Handler){},
ReadTimeout: 15 * time.Second,
WriteTimeout: 45 * time.Second,
IdleTimeout: 60 * time.Second,
BaseContext: func(_ net.Listener) context.Context {
return context.Background()
},
Handler: base.BaseMux,
}
go func() { go func() {
logrus.Info("Listening on ", ygg.DerivedServerName()) logrus.Info("Listening on ", ygg.DerivedServerName())
logrus.Fatal(httpServer.Serve(ygg)) logrus.Fatal(httpServer.Serve(ygg))
@ -159,7 +176,7 @@ func main() {
go func() { go func() {
httpBindAddr := fmt.Sprintf(":%d", *instancePort) httpBindAddr := fmt.Sprintf(":%d", *instancePort)
logrus.Info("Listening on ", httpBindAddr) logrus.Info("Listening on ", httpBindAddr)
logrus.Fatal(http.ListenAndServe(httpBindAddr, nil)) logrus.Fatal(http.ListenAndServe(httpBindAddr, base.BaseMux))
}() }()
select {} select {}

View file

@ -15,13 +15,16 @@
package yggconn package yggconn
import ( import (
"context"
"crypto/ed25519" "crypto/ed25519"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net"
"os" "os"
"strings"
"sync" "sync"
"github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/convert" "github.com/matrix-org/dendrite/cmd/dendrite-demo-yggdrasil/convert"
@ -48,6 +51,21 @@ type Node struct {
incoming chan *yamux.Stream incoming chan *yamux.Stream
} }
func (n *Node) Dialer(_, address string) (net.Conn, error) {
tokens := strings.Split(address, ":")
raw, err := hex.DecodeString(tokens[0])
if err != nil {
return nil, fmt.Errorf("hex.DecodeString: %w", err)
}
converted := convert.Ed25519PublicKeyToCurve25519(ed25519.PublicKey(raw))
convhex := hex.EncodeToString(converted)
return n.Dial("curve25519", convhex)
}
func (n *Node) DialerContext(ctx context.Context, network, address string) (net.Conn, error) {
return n.Dialer(network, address)
}
// nolint:gocyclo // nolint:gocyclo
func Setup(instanceName, instancePeer, storageDirectory string) (*Node, error) { func Setup(instanceName, instancePeer, storageDirectory string) (*Node, error) {
n := &Node{ n := &Node{

View file

@ -17,21 +17,20 @@ import (
"github.com/matrix-org/dendrite/eduserver" "github.com/matrix-org/dendrite/eduserver"
"github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "EDUServerAPI", true) base := setup.NewBaseDendrite(cfg, "EDUServerAPI", true)
defer func() { defer func() {
if err := base.Close(); err != nil { if err := base.Close(); err != nil {
logrus.WithError(err).Warn("BaseDendrite close failed") logrus.WithError(err).Warn("BaseDendrite close failed")
} }
}() }()
deviceDB := base.CreateDeviceDB()
intAPI := eduserver.NewInternalAPI(base, cache.New(), deviceDB) intAPI := eduserver.NewInternalAPI(base, cache.New(), base.UserAPIClient())
eduserver.AddInternalRoutes(base.InternalAPIMux, intAPI) eduserver.AddInternalRoutes(base.InternalAPIMux, intAPI)
base.SetupAndServeHTTP(string(base.Cfg.Bind.EDUServer), string(base.Cfg.Listen.EDUServer)) base.SetupAndServeHTTP(string(base.Cfg.Bind.EDUServer), string(base.Cfg.Listen.EDUServer))

View file

@ -16,26 +16,24 @@ package main
import ( import (
"github.com/matrix-org/dendrite/federationapi" "github.com/matrix-org/dendrite/federationapi"
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "FederationAPI", true) base := setup.NewBaseDendrite(cfg, "FederationAPI", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
accountDB := base.CreateAccountsDB() userAPI := base.UserAPIClient()
deviceDB := base.CreateDeviceDB()
federation := base.CreateFederationClient() federation := base.CreateFederationClient()
serverKeyAPI := base.ServerKeyAPIClient() serverKeyAPI := base.ServerKeyAPIClient()
keyRing := serverKeyAPI.KeyRing() keyRing := serverKeyAPI.KeyRing()
fsAPI := base.FederationSenderHTTPClient() fsAPI := base.FederationSenderHTTPClient()
rsAPI := base.RoomserverHTTPClient() rsAPI := base.RoomserverHTTPClient()
asAPI := base.AppserviceHTTPClient()
federationapi.AddPublicRoutes( federationapi.AddPublicRoutes(
base.PublicAPIMux, base.Cfg, accountDB, deviceDB, federation, keyRing, base.PublicAPIMux, base.Cfg, userAPI, federation, keyRing,
rsAPI, asAPI, fsAPI, base.EDUServerClient(), rsAPI, fsAPI, base.EDUServerClient(),
) )
base.SetupAndServeHTTP(string(base.Cfg.Bind.FederationAPI), string(base.Cfg.Listen.FederationAPI)) base.SetupAndServeHTTP(string(base.Cfg.Bind.FederationAPI), string(base.Cfg.Listen.FederationAPI))

View file

@ -16,12 +16,12 @@ package main
import ( import (
"github.com/matrix-org/dendrite/federationsender" "github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "FederationSender", true) base := setup.NewBaseDendrite(cfg, "FederationSender", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
federation := base.CreateFederationClient() federation := base.CreateFederationClient()

View file

@ -15,19 +15,18 @@
package main package main
import ( import (
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/keyserver" "github.com/matrix-org/dendrite/keyserver"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "KeyServer", true) base := setup.NewBaseDendrite(cfg, "KeyServer", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
accountDB := base.CreateAccountsDB() userAPI := base.UserAPIClient()
deviceDB := base.CreateDeviceDB()
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)) base.SetupAndServeHTTP(string(base.Cfg.Bind.KeyServer), string(base.Cfg.Listen.KeyServer))

View file

@ -15,18 +15,20 @@
package main package main
import ( import (
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/mediaapi" "github.com/matrix-org/dendrite/mediaapi"
"github.com/matrix-org/gomatrixserverlib"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "MediaAPI", true) base := setup.NewBaseDendrite(cfg, "MediaAPI", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
deviceDB := base.CreateDeviceDB() userAPI := base.UserAPIClient()
client := gomatrixserverlib.NewClient()
mediaapi.AddPublicRoutes(base.PublicAPIMux, base.Cfg, deviceDB) mediaapi.AddPublicRoutes(base.PublicAPIMux, base.Cfg, userAPI, client)
base.SetupAndServeHTTP(string(base.Cfg.Bind.MediaAPI), string(base.Cfg.Listen.MediaAPI)) base.SetupAndServeHTTP(string(base.Cfg.Bind.MediaAPI), string(base.Cfg.Listen.MediaAPI))

View file

@ -17,18 +17,21 @@ package main
import ( import (
"flag" "flag"
"net/http" "net/http"
"os"
"github.com/matrix-org/dendrite/appservice" "github.com/matrix-org/dendrite/appservice"
"github.com/matrix-org/dendrite/eduserver" "github.com/matrix-org/dendrite/eduserver"
"github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/federationsender" "github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/basecomponent"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/publicroomsapi/storage"
"github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/serverkeyapi" "github.com/matrix-org/dendrite/serverkeyapi"
"github.com/matrix-org/dendrite/userapi"
"github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -39,10 +42,11 @@ var (
certFile = flag.String("tls-cert", "", "The PEM formatted X509 certificate to use for TLS") certFile = flag.String("tls-cert", "", "The PEM formatted X509 certificate to use for TLS")
keyFile = flag.String("tls-key", "", "The PEM private key to use for TLS") keyFile = flag.String("tls-key", "", "The PEM private key to use for TLS")
enableHTTPAPIs = flag.Bool("api", false, "Use HTTP APIs instead of short-circuiting (warning: exposes API endpoints!)") enableHTTPAPIs = flag.Bool("api", false, "Use HTTP APIs instead of short-circuiting (warning: exposes API endpoints!)")
traceInternal = os.Getenv("DENDRITE_TRACE_INTERNAL") == "1"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(true) cfg := setup.ParseFlags(true)
if *enableHTTPAPIs { if *enableHTTPAPIs {
// If the HTTP APIs are enabled then we need to update the Listen // If the HTTP APIs are enabled then we need to update the Listen
// statements in the configuration so that we know where to find // statements in the configuration so that we know where to find
@ -56,7 +60,7 @@ func main() {
cfg.Listen.ServerKeyAPI = addr cfg.Listen.ServerKeyAPI = addr
} }
base := basecomponent.NewBaseDendrite(cfg, "Monolith", *enableHTTPAPIs) base := setup.NewBaseDendrite(cfg, "Monolith", *enableHTTPAPIs)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
accountDB := base.CreateAccountsDB() accountDB := base.CreateAccountsDB()
@ -71,25 +75,32 @@ func main() {
serverKeyAPI = base.ServerKeyAPIClient() serverKeyAPI = base.ServerKeyAPIClient()
} }
keyRing := serverKeyAPI.KeyRing() keyRing := serverKeyAPI.KeyRing()
userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, cfg.Derived.ApplicationServices)
rsComponent := roomserver.NewInternalAPI( rsImpl := roomserver.NewInternalAPI(
base, keyRing, federation, base, keyRing, federation,
) )
rsAPI := rsComponent // call functions directly on the impl unless running in HTTP mode
rsAPI := rsImpl
if base.UseHTTPAPIs { if base.UseHTTPAPIs {
roomserver.AddInternalRoutes(base.InternalAPIMux, rsAPI) roomserver.AddInternalRoutes(base.InternalAPIMux, rsImpl)
rsAPI = base.RoomserverHTTPClient() rsAPI = base.RoomserverHTTPClient()
} }
if traceInternal {
rsAPI = &api.RoomserverInternalAPITrace{
Impl: rsAPI,
}
}
eduInputAPI := eduserver.NewInternalAPI( eduInputAPI := eduserver.NewInternalAPI(
base, cache.New(), deviceDB, base, cache.New(), userAPI,
) )
if base.UseHTTPAPIs { if base.UseHTTPAPIs {
eduserver.AddInternalRoutes(base.InternalAPIMux, eduInputAPI) eduserver.AddInternalRoutes(base.InternalAPIMux, eduInputAPI)
eduInputAPI = base.EDUServerClient() eduInputAPI = base.EDUServerClient()
} }
asAPI := appservice.NewInternalAPI(base, accountDB, deviceDB, rsAPI) asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
if base.UseHTTPAPIs { if base.UseHTTPAPIs {
appservice.AddInternalRoutes(base.InternalAPIMux, asAPI) appservice.AddInternalRoutes(base.InternalAPIMux, asAPI)
asAPI = base.AppserviceHTTPClient() asAPI = base.AppserviceHTTPClient()
@ -102,7 +113,9 @@ func main() {
federationsender.AddInternalRoutes(base.InternalAPIMux, fsAPI) federationsender.AddInternalRoutes(base.InternalAPIMux, fsAPI)
fsAPI = base.FederationSenderHTTPClient() fsAPI = base.FederationSenderHTTPClient()
} }
rsComponent.SetFederationSenderAPI(fsAPI) // The underlying roomserver implementation needs to be able to call the fedsender.
// This is different to rsAPI which can be the http client which doesn't need this dependency
rsImpl.SetFederationSenderAPI(fsAPI)
publicRoomsDB, err := storage.NewPublicRoomsServerDatabase(string(base.Cfg.Database.PublicRoomsAPI), base.Cfg.DbProperties(), cfg.Matrix.ServerName) publicRoomsDB, err := storage.NewPublicRoomsServerDatabase(string(base.Cfg.Database.PublicRoomsAPI), base.Cfg.DbProperties(), cfg.Matrix.ServerName)
if err != nil { if err != nil {
@ -113,6 +126,7 @@ func main() {
Config: base.Cfg, Config: base.Cfg,
AccountDB: accountDB, AccountDB: accountDB,
DeviceDB: deviceDB, DeviceDB: deviceDB,
Client: gomatrixserverlib.NewClient(),
FedClient: federation, FedClient: federation,
KeyRing: keyRing, KeyRing: keyRing,
KafkaConsumer: base.KafkaConsumer, KafkaConsumer: base.KafkaConsumer,
@ -123,13 +137,14 @@ func main() {
FederationSenderAPI: fsAPI, FederationSenderAPI: fsAPI,
RoomserverAPI: rsAPI, RoomserverAPI: rsAPI,
ServerKeyAPI: serverKeyAPI, ServerKeyAPI: serverKeyAPI,
UserAPI: userAPI,
PublicRoomsDB: publicRoomsDB, PublicRoomsDB: publicRoomsDB,
} }
monolith.AddAllPublicRoutes(base.PublicAPIMux) monolith.AddAllPublicRoutes(base.PublicAPIMux)
internal.SetupHTTPAPI( httputil.SetupHTTPAPI(
http.DefaultServeMux, base.BaseMux,
base.PublicAPIMux, base.PublicAPIMux,
base.InternalAPIMux, base.InternalAPIMux,
cfg, cfg,
@ -140,7 +155,8 @@ func main() {
go func() { go func() {
serv := http.Server{ serv := http.Server{
Addr: *httpBindAddr, Addr: *httpBindAddr,
WriteTimeout: basecomponent.HTTPServerTimeout, WriteTimeout: setup.HTTPServerTimeout,
Handler: base.BaseMux,
} }
logrus.Info("Listening on ", serv.Addr) logrus.Info("Listening on ", serv.Addr)
@ -151,7 +167,8 @@ func main() {
go func() { go func() {
serv := http.Server{ serv := http.Server{
Addr: *httpsBindAddr, Addr: *httpsBindAddr,
WriteTimeout: basecomponent.HTTPServerTimeout, WriteTimeout: setup.HTTPServerTimeout,
Handler: base.BaseMux,
} }
logrus.Info("Listening on ", serv.Addr) logrus.Info("Listening on ", serv.Addr)

View file

@ -15,18 +15,18 @@
package main package main
import ( import (
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/publicroomsapi" "github.com/matrix-org/dendrite/publicroomsapi"
"github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/publicroomsapi/storage"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "PublicRoomsAPI", true) base := setup.NewBaseDendrite(cfg, "PublicRoomsAPI", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
deviceDB := base.CreateDeviceDB() userAPI := base.UserAPIClient()
rsAPI := base.RoomserverHTTPClient() rsAPI := base.RoomserverHTTPClient()
@ -34,7 +34,7 @@ func main() {
if err != nil { if err != nil {
logrus.WithError(err).Panicf("failed to connect to public rooms db") 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)) base.SetupAndServeHTTP(string(base.Cfg.Bind.PublicRoomsAPI), string(base.Cfg.Listen.PublicRoomsAPI))

View file

@ -15,13 +15,13 @@
package main package main
import ( import (
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/roomserver"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "RoomServerAPI", true) base := setup.NewBaseDendrite(cfg, "RoomServerAPI", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
federation := base.CreateFederationClient() federation := base.CreateFederationClient()

View file

@ -15,13 +15,13 @@
package main package main
import ( import (
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/serverkeyapi" "github.com/matrix-org/dendrite/serverkeyapi"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "ServerKeyAPI", true) base := setup.NewBaseDendrite(cfg, "ServerKeyAPI", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
federation := base.CreateFederationClient() federation := base.CreateFederationClient()

View file

@ -15,22 +15,21 @@
package main package main
import ( import (
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/syncapi" "github.com/matrix-org/dendrite/syncapi"
) )
func main() { func main() {
cfg := basecomponent.ParseFlags(false) cfg := setup.ParseFlags(false)
base := basecomponent.NewBaseDendrite(cfg, "SyncAPI", true) base := setup.NewBaseDendrite(cfg, "SyncAPI", true)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
deviceDB := base.CreateDeviceDB() userAPI := base.UserAPIClient()
accountDB := base.CreateAccountsDB()
federation := base.CreateFederationClient() federation := base.CreateFederationClient()
rsAPI := base.RoomserverHTTPClient() rsAPI := base.RoomserverHTTPClient()
syncapi.AddPublicRoutes(base.PublicAPIMux, base.KafkaConsumer, deviceDB, accountDB, rsAPI, federation, cfg) syncapi.AddPublicRoutes(base.PublicAPIMux, base.KafkaConsumer, userAPI, rsAPI, federation, cfg)
base.SetupAndServeHTTP(string(base.Cfg.Bind.SyncAPI), string(base.Cfg.Listen.SyncAPI)) base.SetupAndServeHTTP(string(base.Cfg.Bind.SyncAPI), string(base.Cfg.Listen.SyncAPI))

View file

@ -28,7 +28,7 @@ import (
// JSServer exposes an HTTP-like server interface which allows JS to 'send' requests to it. // JSServer exposes an HTTP-like server interface which allows JS to 'send' requests to it.
type JSServer struct { type JSServer struct {
// The router which will service requests // The router which will service requests
Mux *http.ServeMux Mux http.Handler
} }
// OnRequestFromJS is the function that JS will invoke when there is a new request. // OnRequestFromJS is the function that JS will invoke when there is a new request.

View file

@ -19,19 +19,18 @@ package main
import ( import (
"crypto/ed25519" "crypto/ed25519"
"fmt" "fmt"
"net/http"
"syscall/js" "syscall/js"
"github.com/matrix-org/dendrite/appservice" "github.com/matrix-org/dendrite/appservice"
"github.com/matrix-org/dendrite/eduserver" "github.com/matrix-org/dendrite/eduserver"
"github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/federationsender" "github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/basecomponent"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/setup" "github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/publicroomsapi/storage"
"github.com/matrix-org/dendrite/roomserver" "github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/userapi"
go_http_js_libp2p "github.com/matrix-org/go-http-js-libp2p" go_http_js_libp2p "github.com/matrix-org/go-http-js-libp2p"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
@ -146,6 +145,11 @@ func createFederationClient(cfg *config.Dendrite, node *go_http_js_libp2p.P2pLoc
return fed return fed
} }
func createClient(node *go_http_js_libp2p.P2pLocalNode) *gomatrixserverlib.Client {
tr := go_http_js_libp2p.NewP2pTransport(node)
return gomatrixserverlib.NewClientWithTransport(tr)
}
func createP2PNode(privKey ed25519.PrivateKey) (serverName string, node *go_http_js_libp2p.P2pLocalNode) { func createP2PNode(privKey ed25519.PrivateKey) (serverName string, node *go_http_js_libp2p.P2pLocalNode) {
hosted := "/dns4/rendezvous.matrix.org/tcp/8443/wss/p2p-websocket-star/" hosted := "/dns4/rendezvous.matrix.org/tcp/8443/wss/p2p-websocket-star/"
node = go_http_js_libp2p.NewP2pLocalNode("org.matrix.p2p.experiment", privKey.Seed(), []string{hosted}, "p2p") node = go_http_js_libp2p.NewP2pLocalNode("org.matrix.p2p.experiment", privKey.Seed(), []string{hosted}, "p2p")
@ -184,12 +188,13 @@ func main() {
if err := cfg.Derive(); err != nil { if err := cfg.Derive(); err != nil {
logrus.Fatalf("Failed to derive values from config: %s", err) logrus.Fatalf("Failed to derive values from config: %s", err)
} }
base := basecomponent.NewBaseDendrite(cfg, "Monolith", false) base := setup.NewBaseDendrite(cfg, "Monolith", false)
defer base.Close() // nolint: errcheck defer base.Close() // nolint: errcheck
accountDB := base.CreateAccountsDB() accountDB := base.CreateAccountsDB()
deviceDB := base.CreateDeviceDB() deviceDB := base.CreateDeviceDB()
federation := createFederationClient(cfg, node) federation := createFederationClient(cfg, node)
userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, nil)
fetcher := &libp2pKeyFetcher{} fetcher := &libp2pKeyFetcher{}
keyRing := gomatrixserverlib.KeyRing{ keyRing := gomatrixserverlib.KeyRing{
@ -200,9 +205,9 @@ func main() {
} }
rsAPI := roomserver.NewInternalAPI(base, keyRing, federation) rsAPI := roomserver.NewInternalAPI(base, keyRing, federation)
eduInputAPI := eduserver.NewInternalAPI(base, cache.New(), deviceDB) eduInputAPI := eduserver.NewInternalAPI(base, cache.New(), userAPI)
asQuery := appservice.NewInternalAPI( asQuery := appservice.NewInternalAPI(
base, accountDB, deviceDB, rsAPI, base, userAPI, rsAPI,
) )
fedSenderAPI := federationsender.NewInternalAPI(base, federation, rsAPI, &keyRing) fedSenderAPI := federationsender.NewInternalAPI(base, federation, rsAPI, &keyRing)
rsAPI.SetFederationSenderAPI(fedSenderAPI) rsAPI.SetFederationSenderAPI(fedSenderAPI)
@ -217,6 +222,7 @@ func main() {
Config: base.Cfg, Config: base.Cfg,
AccountDB: accountDB, AccountDB: accountDB,
DeviceDB: deviceDB, DeviceDB: deviceDB,
Client: createClient(node),
FedClient: federation, FedClient: federation,
KeyRing: &keyRing, KeyRing: &keyRing,
KafkaConsumer: base.KafkaConsumer, KafkaConsumer: base.KafkaConsumer,
@ -226,6 +232,7 @@ func main() {
EDUInternalAPI: eduInputAPI, EDUInternalAPI: eduInputAPI,
FederationSenderAPI: fedSenderAPI, FederationSenderAPI: fedSenderAPI,
RoomserverAPI: rsAPI, RoomserverAPI: rsAPI,
UserAPI: userAPI,
//ServerKeyAPI: serverKeyAPI, //ServerKeyAPI: serverKeyAPI,
PublicRoomsDB: publicRoomsDB, PublicRoomsDB: publicRoomsDB,
@ -233,8 +240,8 @@ func main() {
} }
monolith.AddAllPublicRoutes(base.PublicAPIMux) monolith.AddAllPublicRoutes(base.PublicAPIMux)
internal.SetupHTTPAPI( httputil.SetupHTTPAPI(
http.DefaultServeMux, base.BaseMux,
base.PublicAPIMux, base.PublicAPIMux,
base.InternalAPIMux, base.InternalAPIMux,
cfg, cfg,
@ -246,7 +253,7 @@ func main() {
go func() { go func() {
logrus.Info("Listening on libp2p-js host ID ", node.Id) logrus.Info("Listening on libp2p-js host ID ", node.Id)
s := JSServer{ s := JSServer{
Mux: http.DefaultServeMux, Mux: base.BaseMux,
} }
s.ListenAndServe("p2p") s.ListenAndServe("p2p")
}() }()
@ -256,7 +263,7 @@ func main() {
go func() { go func() {
logrus.Info("Listening for service-worker fetch traffic") logrus.Info("Listening for service-worker fetch traffic")
s := JSServer{ s := JSServer{
Mux: http.DefaultServeMux, Mux: base.BaseMux,
} }
s.ListenAndServe("fetch") s.ListenAndServe("fetch")
}() }()

View file

@ -255,7 +255,7 @@ func testRoomserver(input []string, wantOutput []string, checkQueries func(api.R
panic(err) panic(err)
} }
cache, err := caching.NewInMemoryLRUCache() cache, err := caching.NewInMemoryLRUCache(false)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View file

@ -140,6 +140,7 @@ listen:
edu_server: "localhost:7778" edu_server: "localhost:7778"
key_server: "localhost:7779" key_server: "localhost:7779"
server_key_api: "localhost:7780" server_key_api: "localhost:7780"
user_api: "localhost:7781"
# The configuration for tracing the dendrite components. # The configuration for tracing the dendrite components.
tracing: tracing:

73
docs/WIRING-Current.md Normal file
View file

@ -0,0 +1,73 @@
This document details how various components communicate with each other. There are two kinds of components:
- Public-facing: exposes CS/SS API endpoints and need to be routed to via client-api-proxy or equivalent.
- Internal-only: exposes internal APIs and produces Kafka events.
## Internal HTTP APIs
Not everything can be done using Kafka logs. For example, requesting the latest events in a room is much better suited to
a request/response model like HTTP or RPC. Therefore, components can expose "internal APIs" which sit outside of Kafka logs.
Note in Monolith mode these are actually direct function calls and are not serialised HTTP requests.
```
Tier 1 Sync PublicRooms FederationAPI ClientAPI MediaAPI
Public Facing | .-----1------` | | | | | | | | |
2 | .-------3-----------------` | | | `--------|-|-|-|--11--------------------.
| | | .--------4----------------------------------` | | | |
| | | | .---5-----------` | | | | | |
| | | | | .---6----------------------------` | | |
| | | | | | | .-----7----------` | |
| | | | | | 8 | | 10 |
| | | | | | | | `---9----. | |
V V V V V V V V V V V
Tier 2 Roomserver EDUServer FedSender AppService KeyServer ServerKeyAPI
Internal only | `------------------------12----------^ ^
`------------------------------------------------------------13----------`
Client ---> Server
```
- 1 (PublicRooms -> Roomserver): Calculating current auth for changing visibility
- 2 (Sync -> Roomserver): When making backfill requests
- 3 (FedAPI -> Roomserver): Calculating (prev/auth events) and sending new events, processing backfill/state/state_ids requests
- 4 (ClientAPI -> Roomserver): Calculating (prev/auth events) and sending new events, processing /state requests
- 5 (FedAPI -> EDUServer): Sending typing/send-to-device events
- 6 (ClientAPI -> EDUServer): Sending typing/send-to-device events
- 7 (ClientAPI -> FedSender): Handling directory lookups
- 8 (FedAPI -> FedSender): Resetting backoffs when receiving traffic from a server. Querying joined hosts when handling alias lookup requests
- 9 (FedAPI -> AppService): Working out if the client is an appservice user
- 10 (ClientAPI -> AppService): Working out if the client is an appservice user
- 11 (FedAPI -> ServerKeyAPI): Verifying incoming event signatures
- 12 (FedSender -> ServerKeyAPI): Verifying event signatures of responses (e.g from send_join)
- 13 (Roomserver -> ServerKeyAPI): Verifying event signatures of backfilled events
In addition to this, all public facing components (Tier 1) talk to the `UserAPI` to verify access tokens and extract profile information where needed.
## Kafka logs
```
.----1--------------------------------------------.
V |
Tier 1 Sync PublicRooms FederationAPI ClientAPI MediaAPI
Public Facing ^ ^ ^ ^
| | | |
2 | | |
| `-3------------. |
| | | |
| | | |
| .------4------` | |
| | .--------5-----|------------------------------`
| | | |
Tier 2 Roomserver EDUServer FedSender AppService KeyServer ServerKeyAPI
Internal only | | ^ ^
| `-----6----------` |
`--------------------7--------`
Producer ----> Consumer
```
- 1 (ClientAPI -> Sync): For tracking account data
- 2 (Roomserver -> Sync): For all data to send to clients
- 3 (EDUServer -> Sync): For typing/send-to-device data to send to clients
- 4 (Roomserver -> PublicRooms): For tracking the current room name/topic/joined count/etc.
- 5 (Roomserver -> ClientAPI): For tracking memberships for profile updates.
- 6 (EDUServer -> FedSender): For sending EDUs over federation
- 7 (Roomserver -> FedSender): For sending PDUs over federation, for tracking joined hosts.

View file

@ -18,12 +18,12 @@ package eduserver
import ( import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/eduserver/api" "github.com/matrix-org/dendrite/eduserver/api"
"github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/eduserver/input" "github.com/matrix-org/dendrite/eduserver/input"
"github.com/matrix-org/dendrite/eduserver/inthttp" "github.com/matrix-org/dendrite/eduserver/inthttp"
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
userapi "github.com/matrix-org/dendrite/userapi/api"
) )
// AddInternalRoutes registers HTTP handlers for the internal API. Invokes functions // AddInternalRoutes registers HTTP handlers for the internal API. Invokes functions
@ -35,13 +35,13 @@ func AddInternalRoutes(internalMux *mux.Router, inputAPI api.EDUServerInputAPI)
// NewInternalAPI returns a concerete implementation of the internal API. Callers // 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. // can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
func NewInternalAPI( func NewInternalAPI(
base *basecomponent.BaseDendrite, base *setup.BaseDendrite,
eduCache *cache.EDUCache, eduCache *cache.EDUCache,
deviceDB devices.Database, userAPI userapi.UserInternalAPI,
) api.EDUServerInputAPI { ) api.EDUServerInputAPI {
return &input.EDUServerInputAPI{ return &input.EDUServerInputAPI{
Cache: eduCache, Cache: eduCache,
DeviceDB: deviceDB, UserAPI: userAPI,
Producer: base.KafkaProducer, Producer: base.KafkaProducer,
OutputTypingEventTopic: string(base.Cfg.Kafka.Topics.OutputTypingEvent), OutputTypingEventTopic: string(base.Cfg.Kafka.Topics.OutputTypingEvent),
OutputSendToDeviceEventTopic: string(base.Cfg.Kafka.Topics.OutputSendToDeviceEvent), OutputSendToDeviceEventTopic: string(base.Cfg.Kafka.Topics.OutputSendToDeviceEvent),

View file

@ -22,9 +22,9 @@ import (
"time" "time"
"github.com/Shopify/sarama" "github.com/Shopify/sarama"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/eduserver/api" "github.com/matrix-org/dendrite/eduserver/api"
"github.com/matrix-org/dendrite/eduserver/cache" "github.com/matrix-org/dendrite/eduserver/cache"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -39,8 +39,8 @@ type EDUServerInputAPI struct {
OutputSendToDeviceEventTopic string OutputSendToDeviceEventTopic string
// kafka producer // kafka producer
Producer sarama.SyncProducer Producer sarama.SyncProducer
// device database // Internal user query API
DeviceDB devices.Database UserAPI userapi.UserInternalAPI
// our server name // our server name
ServerName gomatrixserverlib.ServerName ServerName gomatrixserverlib.ServerName
} }
@ -97,6 +97,11 @@ func (t *EDUServerInputAPI) sendTypingEvent(ite *api.InputTypingEvent) error {
if err != nil { if err != nil {
return err return err
} }
logrus.WithFields(logrus.Fields{
"room_id": ite.RoomID,
"user_id": ite.UserID,
"typing": ite.Typing,
}).Infof("Producing to topic '%s'", t.OutputTypingEventTopic)
m := &sarama.ProducerMessage{ m := &sarama.ProducerMessage{
Topic: string(t.OutputTypingEventTopic), Topic: string(t.OutputTypingEventTopic),
@ -110,7 +115,7 @@ func (t *EDUServerInputAPI) sendTypingEvent(ite *api.InputTypingEvent) error {
func (t *EDUServerInputAPI) sendToDeviceEvent(ise *api.InputSendToDeviceEvent) error { func (t *EDUServerInputAPI) sendToDeviceEvent(ise *api.InputSendToDeviceEvent) error {
devices := []string{} devices := []string{}
localpart, domain, err := gomatrixserverlib.SplitID('@', ise.UserID) _, domain, err := gomatrixserverlib.SplitID('@', ise.UserID)
if err != nil { if err != nil {
return err return err
} }
@ -121,17 +126,25 @@ func (t *EDUServerInputAPI) sendToDeviceEvent(ise *api.InputSendToDeviceEvent) e
// wildcard as we don't know about the remote devices, so instead we leave it // wildcard as we don't know about the remote devices, so instead we leave it
// as-is, so that the federation sender can send it on with the wildcard intact. // as-is, so that the federation sender can send it on with the wildcard intact.
if domain == t.ServerName && ise.DeviceID == "*" { if domain == t.ServerName && ise.DeviceID == "*" {
devs, err := t.DeviceDB.GetDevicesByLocalpart(context.TODO(), localpart) var res userapi.QueryDevicesResponse
err = t.UserAPI.QueryDevices(context.TODO(), &userapi.QueryDevicesRequest{
UserID: ise.UserID,
}, &res)
if err != nil { if err != nil {
return err return err
} }
for _, dev := range devs { for _, dev := range res.Devices {
devices = append(devices, dev.ID) devices = append(devices, dev.ID)
} }
} else { } else {
devices = append(devices, ise.DeviceID) devices = append(devices, ise.DeviceID)
} }
logrus.WithFields(logrus.Fields{
"user_id": ise.UserID,
"num_devices": len(devices),
"type": ise.Type,
}).Infof("Producing to topic '%s'", t.OutputSendToDeviceEventTopic)
for _, device := range devices { for _, device := range devices {
ote := &api.OutputSendToDeviceEvent{ ote := &api.OutputSendToDeviceEvent{
UserID: ise.UserID, UserID: ise.UserID,
@ -139,12 +152,6 @@ func (t *EDUServerInputAPI) sendToDeviceEvent(ise *api.InputSendToDeviceEvent) e
SendToDeviceEvent: ise.SendToDeviceEvent, SendToDeviceEvent: ise.SendToDeviceEvent,
} }
logrus.WithFields(logrus.Fields{
"user_id": ise.UserID,
"device_id": ise.DeviceID,
"event_type": ise.Type,
}).Info("handling send-to-device message")
eventJSON, err := json.Marshal(ote) eventJSON, err := json.Marshal(ote)
if err != nil { if err != nil {
logrus.WithError(err).Error("sendToDevice failed json.Marshal") logrus.WithError(err).Error("sendToDevice failed json.Marshal")

View file

@ -6,7 +6,7 @@ import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/eduserver/api" "github.com/matrix-org/dendrite/eduserver/api"
internalHTTP "github.com/matrix-org/dendrite/internal/http" "github.com/matrix-org/dendrite/internal/httputil"
"github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go"
) )
@ -39,7 +39,7 @@ func (h *httpEDUServerInputAPI) InputTypingEvent(
defer span.Finish() defer span.Finish()
apiURL := h.eduServerURL + EDUServerInputTypingEventPath apiURL := h.eduServerURL + EDUServerInputTypingEventPath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// InputSendToDeviceEvent implements EDUServerInputAPI // InputSendToDeviceEvent implements EDUServerInputAPI
@ -52,5 +52,5 @@ func (h *httpEDUServerInputAPI) InputSendToDeviceEvent(
defer span.Finish() defer span.Finish()
apiURL := h.eduServerURL + EDUServerInputSendToDeviceEventPath apiURL := h.eduServerURL + EDUServerInputSendToDeviceEventPath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
} }

View file

@ -6,14 +6,14 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/matrix-org/dendrite/eduserver/api" "github.com/matrix-org/dendrite/eduserver/api"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
// AddRoutes adds the EDUServerInputAPI handlers to the http.ServeMux. // AddRoutes adds the EDUServerInputAPI handlers to the http.ServeMux.
func AddRoutes(t api.EDUServerInputAPI, internalAPIMux *mux.Router) { func AddRoutes(t api.EDUServerInputAPI, internalAPIMux *mux.Router) {
internalAPIMux.Handle(EDUServerInputTypingEventPath, internalAPIMux.Handle(EDUServerInputTypingEventPath,
internal.MakeInternalAPI("inputTypingEvents", func(req *http.Request) util.JSONResponse { httputil.MakeInternalAPI("inputTypingEvents", func(req *http.Request) util.JSONResponse {
var request api.InputTypingEventRequest var request api.InputTypingEventRequest
var response api.InputTypingEventResponse var response api.InputTypingEventResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -26,7 +26,7 @@ func AddRoutes(t api.EDUServerInputAPI, internalAPIMux *mux.Router) {
}), }),
) )
internalAPIMux.Handle(EDUServerInputSendToDeviceEventPath, internalAPIMux.Handle(EDUServerInputSendToDeviceEventPath,
internal.MakeInternalAPI("inputSendToDeviceEvents", func(req *http.Request) util.JSONResponse { httputil.MakeInternalAPI("inputSendToDeviceEvents", func(req *http.Request) util.JSONResponse {
var request api.InputSendToDeviceEventRequest var request api.InputSendToDeviceEventRequest
var response api.InputSendToDeviceEventResponse var response api.InputSendToDeviceEventResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {

View file

@ -16,13 +16,11 @@ package federationapi
import ( import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
eduserverAPI "github.com/matrix-org/dendrite/eduserver/api" eduserverAPI "github.com/matrix-org/dendrite/eduserver/api"
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
roomserverAPI "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/dendrite/federationapi/routing" "github.com/matrix-org/dendrite/federationapi/routing"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
@ -32,19 +30,17 @@ import (
func AddPublicRoutes( func AddPublicRoutes(
router *mux.Router, router *mux.Router,
cfg *config.Dendrite, cfg *config.Dendrite,
accountsDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
keyRing *gomatrixserverlib.KeyRing, keyRing gomatrixserverlib.JSONVerifier,
rsAPI roomserverAPI.RoomserverInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI,
federationSenderAPI federationSenderAPI.FederationSenderInternalAPI, federationSenderAPI federationSenderAPI.FederationSenderInternalAPI,
eduAPI eduserverAPI.EDUServerInputAPI, eduAPI eduserverAPI.EDUServerInputAPI,
) { ) {
routing.Setup( routing.Setup(
router, cfg, rsAPI, asAPI, router, cfg, rsAPI,
eduAPI, federationSenderAPI, *keyRing, eduAPI, federationSenderAPI, keyRing,
federation, accountsDB, deviceDB, federation, userAPI,
) )
} }

View file

@ -0,0 +1,102 @@
package federationapi_test
import (
"context"
"crypto/ed25519"
"strings"
"testing"
"github.com/matrix-org/dendrite/federationapi"
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/setup"
"github.com/matrix-org/dendrite/internal/test"
"github.com/matrix-org/gomatrix"
"github.com/matrix-org/gomatrixserverlib"
)
// Tests that event IDs with '/' in them (escaped as %2F) are correctly passed to the right handler and don't 404.
// Relevant for v3 rooms and a cause of flakey sytests as the IDs are randomly generated.
func TestRoomsV3URLEscapeDoNot404(t *testing.T) {
_, privKey, _ := ed25519.GenerateKey(nil)
cfg := &config.Dendrite{}
cfg.Matrix.KeyID = gomatrixserverlib.KeyID("ed25519:auto")
cfg.Matrix.ServerName = gomatrixserverlib.ServerName("localhost")
cfg.Matrix.PrivateKey = privKey
cfg.Kafka.UseNaffka = true
cfg.Database.Naffka = "file::memory:"
cfg.SetDefaults()
base := setup.NewBaseDendrite(cfg, "Test", false)
keyRing := &test.NopJSONVerifier{}
fsAPI := base.FederationSenderHTTPClient()
// TODO: This is pretty fragile, as if anything calls anything on these nils this test will break.
// Unfortunately, it makes little sense to instantiate these dependencies when we just want to test routing.
federationapi.AddPublicRoutes(base.PublicAPIMux, cfg, nil, nil, keyRing, nil, fsAPI, nil)
httputil.SetupHTTPAPI(
base.BaseMux,
base.PublicAPIMux,
base.InternalAPIMux,
cfg,
base.UseHTTPAPIs,
)
baseURL, cancel := test.ListenAndServe(t, base.BaseMux, true)
defer cancel()
serverName := gomatrixserverlib.ServerName(strings.TrimPrefix(baseURL, "https://"))
fedCli := gomatrixserverlib.NewFederationClient(serverName, cfg.Matrix.KeyID, cfg.Matrix.PrivateKey)
testCases := []struct {
roomVer gomatrixserverlib.RoomVersion
eventJSON string
}{
{
eventJSON: `{"auth_events":[["$Nzfbrhc3oaYVKzGM:localhost",{"sha256":"BCBHOgB4qxLPQkBd6th8ydFSyqjth/LF99VNjYffOQ0"}],["$EZzkD2BH1Gtm5v1D:localhost",{"sha256":"3dLUnDBs8/iC5DMw/ydKtmAqVZtzqqtHpsjsQPk7GJA"}]],"content":{"body":"Test Message"},"depth":11,"event_id":"$mGiPO3oGjQfCkIUw:localhost","hashes":{"sha256":"h+t+4DwIBC9UNyJ3jzyAQAAl4H3yQHVuHrm2S1JZizU"},"origin":"localhost","origin_server_ts":0,"prev_events":[["$tFr64vpiSHdLU0Qr:localhost",{"sha256":"+R07ZrIs4c4tjPFE+tmcYIGUfeLGFI/4e0OITb9uEcM"}]],"room_id":"!roomid:localhost","sender":"@userid:localhost","signatures":{"localhost":{"ed25519:auto":"LYFr/rW9m5/7UKBQMF5qWnG82He4VGsRESUgDmvkn5DrJRyS4TLL/7zl0Lymn3pa3q2yaTO74LQX/CRotqG1BA"}},"type":"m.room.message"}`,
roomVer: gomatrixserverlib.RoomVersionV1,
},
// single / (handlers which do not UseEncodedPath will fail this test)
// EventID: $0SFh2WJbjBs3OT+E0yl95giDKo/3Zp52HsHUUk4uPyg
{
eventJSON: `{"auth_events":["$x4MKEPRSF6OGlo0qpnsP3BfSmYX5HhVlykOsQH3ECyg","$BcEcbZnlFLB5rxSNSZNBn6fO3jU/TKAJ79wfKyCQLiU"],"content":{"body":"Test Message"},"depth":8,"hashes":{"sha256":"dfK0MBn1RZZqCVJqWsn/MGY7QJHjQcwqF0unOonLCTU"},"origin":"localhost","origin_server_ts":0,"prev_events":["$1SwcZ1XY/Y8yKLjP4DzAOHN5WFBcDAZxb5vFDnW2ubA"],"room_id":"!roomid:localhost","sender":"@userid:localhost","signatures":{"localhost":{"ed25519:auto":"INOjuWMg+GmFkUpmzhMB0bqLNs73mSvwldY1ftYIQ/B3lD9soD2OMG3AF+wgZW/I8xqzY4DOHfbnbUeYPf67BA"}},"type":"m.room.message"}`,
roomVer: gomatrixserverlib.RoomVersionV3,
},
// multiple /
// EventID: $OzENBCuVv/fnRAYCeQudIon/84/V5pxtEjQMTgi3emk
{
eventJSON: `{"auth_events":["$x4MKEPRSF6OGlo0qpnsP3BfSmYX5HhVlykOsQH3ECyg","$BcEcbZnlFLB5rxSNSZNBn6fO3jU/TKAJ79wfKyCQLiU"],"content":{"body":"Test Message"},"depth":2,"hashes":{"sha256":"U5+WsiJAhiEM88J8HTjuUjPImVGVzDFD3v/WS+jb2f0"},"origin":"localhost","origin_server_ts":0,"prev_events":["$BcEcbZnlFLB5rxSNSZNBn6fO3jU/TKAJ79wfKyCQLiU"],"room_id":"!roomid:localhost","sender":"@userid:localhost","signatures":{"localhost":{"ed25519:auto":"tKS469e9+wdWPEKB/LbBJWQ8vfOOdKgTWER5IwbSAH1CxmLvkCziUsgVu85zfzDSLoUi5mU5FHLiMTC6P/qICw"}},"type":"m.room.message"}`,
roomVer: gomatrixserverlib.RoomVersionV3,
},
// two slashes (handlers which clean paths before UseEncodedPath will fail this test)
// EventID: $EmwNBlHoSOVmCZ1cM//yv/OvxB6r4OFEIGSJea7+Amk
{
eventJSON: `{"auth_events":["$x4MKEPRSF6OGlo0qpnsP3BfSmYX5HhVlykOsQH3ECyg","$BcEcbZnlFLB5rxSNSZNBn6fO3jU/TKAJ79wfKyCQLiU"],"content":{"body":"Test Message"},"depth":3917,"hashes":{"sha256":"cNAWtlHIegrji0mMA6x1rhpYCccY8W1NsWZqSpJFhjs"},"origin":"localhost","origin_server_ts":0,"prev_events":["$4GDB0bVjkWwS3G4noUZCq5oLWzpBYpwzdMcf7gj24CI"],"room_id":"!roomid:localhost","sender":"@userid:localhost","signatures":{"localhost":{"ed25519:auto":"NKym6Kcy3u9mGUr21Hjfe3h7DfDilDhN5PqztT0QZ4NTZ+8Y7owseLolQVXp+TvNjecvzdDywsXXVvGiuQiWAQ"}},"type":"m.room.message"}`,
roomVer: gomatrixserverlib.RoomVersionV3,
},
}
for _, tc := range testCases {
ev, err := gomatrixserverlib.NewEventFromTrustedJSON([]byte(tc.eventJSON), false, tc.roomVer)
if err != nil {
t.Errorf("failed to parse event: %s", err)
}
he := ev.Headered(tc.roomVer)
invReq, err := gomatrixserverlib.NewInviteV2Request(&he, nil)
if err != nil {
t.Errorf("failed to create invite v2 request: %s", err)
continue
}
_, err = fedCli.SendInviteV2(context.Background(), serverName, invReq)
if err == nil {
t.Errorf("expected an error, got none")
continue
}
gerr, ok := err.(gomatrix.HTTPError)
if !ok {
t.Errorf("failed to cast response error as gomatrix.HTTPError")
continue
}
t.Logf("Error: %+v", gerr)
if gerr.Code == 404 {
t.Errorf("invite event resulted in a 404")
}
}
}

View file

@ -37,7 +37,7 @@ func Backfill(
roomID string, roomID string,
cfg *config.Dendrite, cfg *config.Dendrite,
) util.JSONResponse { ) util.JSONResponse {
var res api.QueryBackfillResponse var res api.PerformBackfillResponse
var eIDs []string var eIDs []string
var limit string var limit string
var exists bool var exists bool
@ -68,7 +68,7 @@ func Backfill(
} }
// Populate the request. // Populate the request.
req := api.QueryBackfillRequest{ req := api.PerformBackfillRequest{
RoomID: roomID, RoomID: roomID,
// we don't know who the successors are for these events, which won't // we don't know who the successors are for these events, which won't
// be a problem because we don't use that information when servicing /backfill requests, // be a problem because we don't use that information when servicing /backfill requests,
@ -87,8 +87,8 @@ func Backfill(
} }
// Query the roomserver. // Query the roomserver.
if err = rsAPI.QueryBackfill(httpReq.Context(), &req, &res); err != nil { if err = rsAPI.PerformBackfill(httpReq.Context(), &req, &res); err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("query.QueryBackfill failed") util.GetLogger(httpReq.Context()).WithError(err).Error("query.PerformBackfill failed")
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }

View file

@ -15,9 +15,8 @@ package routing
import ( import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/userutil" userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -25,17 +24,9 @@ import (
// GetUserDevices for the given user id // GetUserDevices for the given user id
func GetUserDevices( func GetUserDevices(
req *http.Request, req *http.Request,
deviceDB devices.Database, userAPI userapi.UserInternalAPI,
userID string, userID string,
) util.JSONResponse { ) util.JSONResponse {
localpart, err := userutil.ParseUsernameParam(userID, nil)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.InvalidArgumentValue("Invalid user ID"),
}
}
response := gomatrixserverlib.RespUserDevices{ response := gomatrixserverlib.RespUserDevices{
UserID: userID, UserID: userID,
// TODO: we should return an incrementing stream ID each time the device // TODO: we should return an incrementing stream ID each time the device
@ -43,13 +34,16 @@ func GetUserDevices(
StreamID: 0, StreamID: 0,
} }
devs, err := deviceDB.GetDevicesByLocalpart(req.Context(), localpart) var res userapi.QueryDevicesResponse
err := userAPI.QueryDevices(req.Context(), &userapi.QueryDevicesRequest{
UserID: userID,
}, &res)
if err != nil { if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("deviceDB.GetDevicesByLocalPart failed") util.GetLogger(req.Context()).WithError(err).Error("userAPI.QueryDevices failed")
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }
for _, dev := range devs { for _, dev := range res.Devices {
device := gomatrixserverlib.RespUserDevice{ device := gomatrixserverlib.RespUserDevice{
DeviceID: dev.ID, DeviceID: dev.ID,
DisplayName: dev.DisplayName, DisplayName: dev.DisplayName,

View file

@ -35,7 +35,7 @@ func Invite(
eventID string, eventID string,
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
keys gomatrixserverlib.KeyRing, keys gomatrixserverlib.JSONVerifier,
) util.JSONResponse { ) util.JSONResponse {
inviteReq := gomatrixserverlib.InviteV2Request{} inviteReq := gomatrixserverlib.InviteV2Request{}
if err := json.Unmarshal(request.Content(), &inviteReq); err != nil { if err := json.Unmarshal(request.Content(), &inviteReq); err != nil {

View file

@ -21,8 +21,8 @@ import (
"time" "time"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
@ -95,8 +95,8 @@ func MakeJoin(
queryRes := api.QueryLatestEventsAndStateResponse{ queryRes := api.QueryLatestEventsAndStateResponse{
RoomVersion: verRes.RoomVersion, RoomVersion: verRes.RoomVersion,
} }
event, err := internal.BuildEvent(httpReq.Context(), &builder, cfg, time.Now(), rsAPI, &queryRes) event, err := eventutil.BuildEvent(httpReq.Context(), &builder, cfg, time.Now(), rsAPI, &queryRes)
if err == internal.ErrRoomNoExists { if err == eventutil.ErrRoomNoExists {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,
JSON: jsonerror.NotFound("Room does not exist"), JSON: jsonerror.NotFound("Room does not exist"),
@ -107,7 +107,7 @@ func MakeJoin(
JSON: jsonerror.BadJSON(e.Error()), JSON: jsonerror.BadJSON(e.Error()),
} }
} else if err != nil { } else if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("internal.BuildEvent failed") util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }
@ -143,7 +143,7 @@ func SendJoin(
request *gomatrixserverlib.FederationRequest, request *gomatrixserverlib.FederationRequest,
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
keys gomatrixserverlib.KeyRing, keys gomatrixserverlib.JSONVerifier,
roomID, eventID string, roomID, eventID string,
) util.JSONResponse { ) util.JSONResponse {
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID} verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}

View file

@ -17,8 +17,8 @@ import (
"time" "time"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
@ -69,8 +69,8 @@ func MakeLeave(
} }
var queryRes api.QueryLatestEventsAndStateResponse var queryRes api.QueryLatestEventsAndStateResponse
event, err := internal.BuildEvent(httpReq.Context(), &builder, cfg, time.Now(), rsAPI, &queryRes) event, err := eventutil.BuildEvent(httpReq.Context(), &builder, cfg, time.Now(), rsAPI, &queryRes)
if err == internal.ErrRoomNoExists { if err == eventutil.ErrRoomNoExists {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusNotFound, Code: http.StatusNotFound,
JSON: jsonerror.NotFound("Room does not exist"), JSON: jsonerror.NotFound("Room does not exist"),
@ -81,7 +81,7 @@ func MakeLeave(
JSON: jsonerror.BadJSON(e.Error()), JSON: jsonerror.BadJSON(e.Error()),
} }
} else if err != nil { } else if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("internal.BuildEvent failed") util.GetLogger(httpReq.Context()).WithError(err).Error("eventutil.BuildEvent failed")
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }
@ -113,7 +113,7 @@ func SendLeave(
request *gomatrixserverlib.FederationRequest, request *gomatrixserverlib.FederationRequest,
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
keys gomatrixserverlib.KeyRing, keys gomatrixserverlib.JSONVerifier,
roomID, eventID string, roomID, eventID string,
) util.JSONResponse { ) util.JSONResponse {
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID} verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}

View file

@ -18,11 +18,10 @@ import (
"fmt" "fmt"
"net/http" "net/http"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -30,9 +29,8 @@ import (
// GetProfile implements GET /_matrix/federation/v1/query/profile // GetProfile implements GET /_matrix/federation/v1/query/profile
func GetProfile( func GetProfile(
httpReq *http.Request, httpReq *http.Request,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
cfg *config.Dendrite, cfg *config.Dendrite,
asAPI appserviceAPI.AppServiceQueryAPI,
) util.JSONResponse { ) util.JSONResponse {
userID, field := httpReq.FormValue("user_id"), httpReq.FormValue("field") userID, field := httpReq.FormValue("user_id"), httpReq.FormValue("field")
@ -60,9 +58,12 @@ func GetProfile(
} }
} }
profile, err := appserviceAPI.RetrieveUserProfile(httpReq.Context(), userID, asAPI, accountDB) var profileRes userapi.QueryProfileResponse
err = userAPI.QueryProfile(httpReq.Context(), &userapi.QueryProfileRequest{
UserID: userID,
}, &profileRes)
if err != nil { if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("appserviceAPI.RetrieveUserProfile failed") util.GetLogger(httpReq.Context()).WithError(err).Error("userAPI.QueryProfile failed")
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }
@ -72,21 +73,21 @@ func GetProfile(
if field != "" { if field != "" {
switch field { switch field {
case "displayname": case "displayname":
res = internal.DisplayName{ res = eventutil.DisplayName{
DisplayName: profile.DisplayName, DisplayName: profileRes.DisplayName,
} }
case "avatar_url": case "avatar_url":
res = internal.AvatarURL{ res = eventutil.AvatarURL{
AvatarURL: profile.AvatarURL, AvatarURL: profileRes.AvatarURL,
} }
default: default:
code = http.StatusBadRequest code = http.StatusBadRequest
res = jsonerror.InvalidArgumentValue("The request body did not contain an allowed value of argument 'field'. Allowed values are either: 'avatar_url', 'displayname'.") res = jsonerror.InvalidArgumentValue("The request body did not contain an allowed value of argument 'field'. Allowed values are either: 'avatar_url', 'displayname'.")
} }
} else { } else {
res = internal.ProfileResponse{ res = eventutil.ProfileResponse{
AvatarURL: profile.AvatarURL, AvatarURL: profileRes.AvatarURL,
DisplayName: profile.DisplayName, DisplayName: profileRes.DisplayName,
} }
} }

View file

@ -18,14 +18,13 @@ import (
"net/http" "net/http"
"github.com/gorilla/mux" "github.com/gorilla/mux"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
eduserverAPI "github.com/matrix-org/dendrite/eduserver/api" eduserverAPI "github.com/matrix-org/dendrite/eduserver/api"
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api" federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/httputil"
roomserverAPI "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/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
@ -48,23 +47,21 @@ func Setup(
publicAPIMux *mux.Router, publicAPIMux *mux.Router,
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI roomserverAPI.RoomserverInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI,
eduAPI eduserverAPI.EDUServerInputAPI, eduAPI eduserverAPI.EDUServerInputAPI,
fsAPI federationSenderAPI.FederationSenderInternalAPI, fsAPI federationSenderAPI.FederationSenderInternalAPI,
keys gomatrixserverlib.KeyRing, keys gomatrixserverlib.JSONVerifier,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
deviceDB devices.Database,
) { ) {
v2keysmux := publicAPIMux.PathPrefix(pathPrefixV2Keys).Subrouter() v2keysmux := publicAPIMux.PathPrefix(pathPrefixV2Keys).Subrouter()
v1fedmux := publicAPIMux.PathPrefix(pathPrefixV1Federation).Subrouter() v1fedmux := publicAPIMux.PathPrefix(pathPrefixV1Federation).Subrouter()
v2fedmux := publicAPIMux.PathPrefix(pathPrefixV2Federation).Subrouter() v2fedmux := publicAPIMux.PathPrefix(pathPrefixV2Federation).Subrouter()
wakeup := &internal.FederationWakeups{ wakeup := &httputil.FederationWakeups{
FsAPI: fsAPI, FsAPI: fsAPI,
} }
localKeys := internal.MakeExternalAPI("localkeys", func(req *http.Request) util.JSONResponse { localKeys := httputil.MakeExternalAPI("localkeys", func(req *http.Request) util.JSONResponse {
return LocalKeys(cfg) return LocalKeys(cfg)
}) })
@ -76,7 +73,7 @@ func Setup(
v2keysmux.Handle("/server/", localKeys).Methods(http.MethodGet) v2keysmux.Handle("/server/", localKeys).Methods(http.MethodGet)
v2keysmux.Handle("/server", localKeys).Methods(http.MethodGet) v2keysmux.Handle("/server", localKeys).Methods(http.MethodGet)
v1fedmux.Handle("/send/{txnID}", internal.MakeFedAPI( v1fedmux.Handle("/send/{txnID}", httputil.MakeFedAPI(
"federation_send", cfg.Matrix.ServerName, keys, wakeup, "federation_send", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return Send( return Send(
@ -86,7 +83,7 @@ func Setup(
}, },
)).Methods(http.MethodPut, http.MethodOptions) )).Methods(http.MethodPut, http.MethodOptions)
v2fedmux.Handle("/invite/{roomID}/{eventID}", internal.MakeFedAPI( v2fedmux.Handle("/invite/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_invite", cfg.Matrix.ServerName, keys, wakeup, "federation_invite", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return Invite( return Invite(
@ -96,13 +93,13 @@ func Setup(
}, },
)).Methods(http.MethodPut, http.MethodOptions) )).Methods(http.MethodPut, http.MethodOptions)
v1fedmux.Handle("/3pid/onbind", internal.MakeExternalAPI("3pid_onbind", v1fedmux.Handle("/3pid/onbind", httputil.MakeExternalAPI("3pid_onbind",
func(req *http.Request) util.JSONResponse { func(req *http.Request) util.JSONResponse {
return CreateInvitesFrom3PIDInvites(req, rsAPI, asAPI, cfg, federation, accountDB) return CreateInvitesFrom3PIDInvites(req, rsAPI, cfg, federation, userAPI)
}, },
)).Methods(http.MethodPost, http.MethodOptions) )).Methods(http.MethodPost, http.MethodOptions)
v1fedmux.Handle("/exchange_third_party_invite/{roomID}", internal.MakeFedAPI( v1fedmux.Handle("/exchange_third_party_invite/{roomID}", httputil.MakeFedAPI(
"exchange_third_party_invite", cfg.Matrix.ServerName, keys, wakeup, "exchange_third_party_invite", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return ExchangeThirdPartyInvite( return ExchangeThirdPartyInvite(
@ -111,7 +108,7 @@ func Setup(
}, },
)).Methods(http.MethodPut, http.MethodOptions) )).Methods(http.MethodPut, http.MethodOptions)
v1fedmux.Handle("/event/{eventID}", internal.MakeFedAPI( v1fedmux.Handle("/event/{eventID}", httputil.MakeFedAPI(
"federation_get_event", cfg.Matrix.ServerName, keys, wakeup, "federation_get_event", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return GetEvent( return GetEvent(
@ -120,7 +117,7 @@ func Setup(
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/state/{roomID}", internal.MakeFedAPI( v1fedmux.Handle("/state/{roomID}", httputil.MakeFedAPI(
"federation_get_state", cfg.Matrix.ServerName, keys, wakeup, "federation_get_state", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return GetState( return GetState(
@ -129,7 +126,7 @@ func Setup(
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/state_ids/{roomID}", internal.MakeFedAPI( v1fedmux.Handle("/state_ids/{roomID}", httputil.MakeFedAPI(
"federation_get_state_ids", cfg.Matrix.ServerName, keys, wakeup, "federation_get_state_ids", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return GetStateIDs( return GetStateIDs(
@ -138,7 +135,7 @@ func Setup(
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/event_auth/{roomID}/{eventID}", internal.MakeFedAPI( v1fedmux.Handle("/event_auth/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_get_event_auth", cfg.Matrix.ServerName, keys, wakeup, "federation_get_event_auth", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return GetEventAuth( return GetEventAuth(
@ -147,7 +144,7 @@ func Setup(
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/query/directory", internal.MakeFedAPI( v1fedmux.Handle("/query/directory", httputil.MakeFedAPI(
"federation_query_room_alias", cfg.Matrix.ServerName, keys, wakeup, "federation_query_room_alias", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return RoomAliasToID( return RoomAliasToID(
@ -156,25 +153,25 @@ func Setup(
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/query/profile", internal.MakeFedAPI( v1fedmux.Handle("/query/profile", httputil.MakeFedAPI(
"federation_query_profile", cfg.Matrix.ServerName, keys, wakeup, "federation_query_profile", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return GetProfile( return GetProfile(
httpReq, accountDB, cfg, asAPI, httpReq, userAPI, cfg,
) )
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/user/devices/{userID}", internal.MakeFedAPI( v1fedmux.Handle("/user/devices/{userID}", httputil.MakeFedAPI(
"federation_user_devices", cfg.Matrix.ServerName, keys, wakeup, "federation_user_devices", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return GetUserDevices( return GetUserDevices(
httpReq, deviceDB, vars["userID"], httpReq, userAPI, vars["userID"],
) )
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/make_join/{roomID}/{eventID}", internal.MakeFedAPI( v1fedmux.Handle("/make_join/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_make_join", cfg.Matrix.ServerName, keys, wakeup, "federation_make_join", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
roomID := vars["roomID"] roomID := vars["roomID"]
@ -199,7 +196,7 @@ func Setup(
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/send_join/{roomID}/{eventID}", internal.MakeFedAPI( v1fedmux.Handle("/send_join/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_send_join", cfg.Matrix.ServerName, keys, wakeup, "federation_send_join", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
roomID := vars["roomID"] roomID := vars["roomID"]
@ -207,17 +204,25 @@ func Setup(
res := SendJoin( res := SendJoin(
httpReq, request, cfg, rsAPI, keys, roomID, eventID, httpReq, request, cfg, rsAPI, keys, roomID, eventID,
) )
// not all responses get wrapped in [code, body]
var body interface{}
body = []interface{}{
res.Code, res.JSON,
}
jerr, ok := res.JSON.(*jsonerror.MatrixError)
if ok {
body = jerr
}
return util.JSONResponse{ return util.JSONResponse{
Headers: res.Headers, Headers: res.Headers,
Code: res.Code, Code: res.Code,
JSON: []interface{}{ JSON: body,
res.Code, res.JSON,
},
} }
}, },
)).Methods(http.MethodPut) )).Methods(http.MethodPut)
v2fedmux.Handle("/send_join/{roomID}/{eventID}", internal.MakeFedAPI( v2fedmux.Handle("/send_join/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_send_join", cfg.Matrix.ServerName, keys, wakeup, "federation_send_join", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
roomID := vars["roomID"] roomID := vars["roomID"]
@ -228,7 +233,7 @@ func Setup(
}, },
)).Methods(http.MethodPut) )).Methods(http.MethodPut)
v1fedmux.Handle("/make_leave/{roomID}/{eventID}", internal.MakeFedAPI( v1fedmux.Handle("/make_leave/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_make_leave", cfg.Matrix.ServerName, keys, wakeup, "federation_make_leave", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
roomID := vars["roomID"] roomID := vars["roomID"]
@ -239,7 +244,7 @@ func Setup(
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v2fedmux.Handle("/send_leave/{roomID}/{eventID}", internal.MakeFedAPI( v2fedmux.Handle("/send_leave/{roomID}/{eventID}", httputil.MakeFedAPI(
"federation_send_leave", cfg.Matrix.ServerName, keys, wakeup, "federation_send_leave", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
roomID := vars["roomID"] roomID := vars["roomID"]
@ -250,21 +255,21 @@ func Setup(
}, },
)).Methods(http.MethodPut) )).Methods(http.MethodPut)
v1fedmux.Handle("/version", internal.MakeExternalAPI( v1fedmux.Handle("/version", httputil.MakeExternalAPI(
"federation_version", "federation_version",
func(httpReq *http.Request) util.JSONResponse { func(httpReq *http.Request) util.JSONResponse {
return Version() return Version()
}, },
)).Methods(http.MethodGet) )).Methods(http.MethodGet)
v1fedmux.Handle("/get_missing_events/{roomID}", internal.MakeFedAPI( v1fedmux.Handle("/get_missing_events/{roomID}", httputil.MakeFedAPI(
"federation_get_missing_events", cfg.Matrix.ServerName, keys, wakeup, "federation_get_missing_events", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return GetMissingEvents(httpReq, request, rsAPI, vars["roomID"]) return GetMissingEvents(httpReq, request, rsAPI, vars["roomID"])
}, },
)).Methods(http.MethodPost) )).Methods(http.MethodPost)
v1fedmux.Handle("/backfill/{roomID}", internal.MakeFedAPI( v1fedmux.Handle("/backfill/{roomID}", httputil.MakeFedAPI(
"federation_backfill", cfg.Matrix.ServerName, keys, wakeup, "federation_backfill", cfg.Matrix.ServerName, keys, wakeup,
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse { func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
return Backfill(httpReq, request, rsAPI, vars["roomID"], cfg) return Backfill(httpReq, request, rsAPI, vars["roomID"], cfg)

View file

@ -37,7 +37,7 @@ func Send(
cfg *config.Dendrite, cfg *config.Dendrite,
rsAPI api.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
eduAPI eduserverAPI.EDUServerInputAPI, eduAPI eduserverAPI.EDUServerInputAPI,
keys gomatrixserverlib.KeyRing, keys gomatrixserverlib.JSONVerifier,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
) util.JSONResponse { ) util.JSONResponse {
t := txnReq{ t := txnReq{

View file

@ -10,6 +10,7 @@ import (
eduAPI "github.com/matrix-org/dendrite/eduserver/api" eduAPI "github.com/matrix-org/dendrite/eduserver/api"
fsAPI "github.com/matrix-org/dendrite/federationsender/api" fsAPI "github.com/matrix-org/dendrite/federationsender/api"
"github.com/matrix-org/dendrite/internal/test"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
@ -53,15 +54,6 @@ func init() {
} }
} }
type testNopJSONVerifier struct {
// this verifier verifies nothing
}
func (t *testNopJSONVerifier) VerifyJSONs(ctx context.Context, requests []gomatrixserverlib.VerifyJSONRequest) ([]gomatrixserverlib.VerifyJSONResult, error) {
result := make([]gomatrixserverlib.VerifyJSONResult, len(requests))
return result, nil
}
type testEDUProducer struct { type testEDUProducer struct {
// this producer keeps track of calls to InputTypingEvent // this producer keeps track of calls to InputTypingEvent
invocations []eduAPI.InputTypingEventRequest invocations []eduAPI.InputTypingEventRequest
@ -128,7 +120,6 @@ func (t *testRoomserverAPI) QueryLatestEventsAndState(
response *api.QueryLatestEventsAndStateResponse, response *api.QueryLatestEventsAndStateResponse,
) error { ) error {
r := t.queryLatestEventsAndState(request) r := t.queryLatestEventsAndState(request)
response.QueryLatestEventsAndStateRequest = *request
response.RoomExists = r.RoomExists response.RoomExists = r.RoomExists
response.RoomVersion = testRoomVersion response.RoomVersion = testRoomVersion
response.LatestEvents = r.LatestEvents response.LatestEvents = r.LatestEvents
@ -144,7 +135,6 @@ func (t *testRoomserverAPI) QueryStateAfterEvents(
response *api.QueryStateAfterEventsResponse, response *api.QueryStateAfterEventsResponse,
) error { ) error {
response.RoomVersion = testRoomVersion response.RoomVersion = testRoomVersion
response.QueryStateAfterEventsRequest = *request
res := t.queryStateAfterEvents(request) res := t.queryStateAfterEvents(request)
response.PrevEventsExist = res.PrevEventsExist response.PrevEventsExist = res.PrevEventsExist
response.RoomExists = res.RoomExists response.RoomExists = res.RoomExists
@ -181,15 +171,6 @@ func (t *testRoomserverAPI) QueryMembershipsForRoom(
return fmt.Errorf("not implemented") return fmt.Errorf("not implemented")
} }
// Query a list of invite event senders for a user in a room.
func (t *testRoomserverAPI) QueryInvitesForUser(
ctx context.Context,
request *api.QueryInvitesForUserRequest,
response *api.QueryInvitesForUserResponse,
) error {
return fmt.Errorf("not implemented")
}
// Query whether a server is allowed to see an event // Query whether a server is allowed to see an event
func (t *testRoomserverAPI) QueryServerAllowedToSeeEvent( func (t *testRoomserverAPI) QueryServerAllowedToSeeEvent(
ctx context.Context, ctx context.Context,
@ -220,10 +201,10 @@ func (t *testRoomserverAPI) QueryStateAndAuthChain(
} }
// Query a given amount (or less) of events prior to a given set of events. // Query a given amount (or less) of events prior to a given set of events.
func (t *testRoomserverAPI) QueryBackfill( func (t *testRoomserverAPI) PerformBackfill(
ctx context.Context, ctx context.Context,
request *api.QueryBackfillRequest, request *api.PerformBackfillRequest,
response *api.QueryBackfillResponse, response *api.PerformBackfillResponse,
) error { ) error {
return fmt.Errorf("not implemented") return fmt.Errorf("not implemented")
} }
@ -341,7 +322,7 @@ func mustCreateTransaction(rsAPI api.RoomserverInternalAPI, fedClient txnFederat
context: context.Background(), context: context.Background(),
rsAPI: rsAPI, rsAPI: rsAPI,
eduAPI: &testEDUProducer{}, eduAPI: &testEDUProducer{},
keys: &testNopJSONVerifier{}, keys: &test.NopJSONVerifier{},
federation: fedClient, federation: fedClient,
haveEvents: make(map[string]*gomatrixserverlib.HeaderedEvent), haveEvents: make(map[string]*gomatrixserverlib.HeaderedEvent),
newEvents: make(map[string]bool), newEvents: make(map[string]bool),
@ -621,7 +602,6 @@ func TestTransactionFetchMissingStateByStateIDs(t *testing.T) {
} }
} }
} }
res.QueryEventsByIDRequest = *req
return res return res
}, },
} }

View file

@ -107,15 +107,13 @@ func getState(
return nil, &util.JSONResponse{Code: http.StatusNotFound, JSON: nil} return nil, &util.JSONResponse{Code: http.StatusNotFound, JSON: nil}
} }
authEventIDs := getIDsFromEventRef(event.AuthEvents())
var response api.QueryStateAndAuthChainResponse var response api.QueryStateAndAuthChainResponse
err := rsAPI.QueryStateAndAuthChain( err := rsAPI.QueryStateAndAuthChain(
ctx, ctx,
&api.QueryStateAndAuthChainRequest{ &api.QueryStateAndAuthChainRequest{
RoomID: roomID, RoomID: roomID,
PrevEventIDs: []string{eventID}, PrevEventIDs: []string{eventID},
AuthEventIDs: authEventIDs, AuthEventIDs: event.AuthEventIDs(),
}, },
&response, &response,
) )
@ -134,15 +132,6 @@ func getState(
}, nil }, nil
} }
func getIDsFromEventRef(events []gomatrixserverlib.EventReference) []string {
IDs := make([]string, len(events))
for i := range events {
IDs[i] = events[i].EventID
}
return IDs
}
func getIDsFromEvent(events []gomatrixserverlib.Event) []string { func getIDsFromEvent(events []gomatrixserverlib.Event) []string {
IDs := make([]string, len(events)) IDs := make([]string, len(events))
for i := range events { for i := range events {

View file

@ -21,13 +21,11 @@ import (
"net/http" "net/http"
"time" "time"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
"github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/httputil"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/roomserver/api" "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/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
@ -57,10 +55,10 @@ var (
// CreateInvitesFrom3PIDInvites implements POST /_matrix/federation/v1/3pid/onbind // CreateInvitesFrom3PIDInvites implements POST /_matrix/federation/v1/3pid/onbind
func CreateInvitesFrom3PIDInvites( func CreateInvitesFrom3PIDInvites(
req *http.Request, rsAPI roomserverAPI.RoomserverInternalAPI, req *http.Request, rsAPI api.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI, cfg *config.Dendrite, cfg *config.Dendrite,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
) util.JSONResponse { ) util.JSONResponse {
var body invites var body invites
if reqErr := httputil.UnmarshalJSONRequest(req, &body); reqErr != nil { if reqErr := httputil.UnmarshalJSONRequest(req, &body); reqErr != nil {
@ -79,7 +77,7 @@ func CreateInvitesFrom3PIDInvites(
} }
event, err := createInviteFrom3PIDInvite( event, err := createInviteFrom3PIDInvite(
req.Context(), rsAPI, asAPI, cfg, inv, federation, accountDB, req.Context(), rsAPI, cfg, inv, federation, userAPI,
) )
if err != nil { if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("createInviteFrom3PIDInvite failed") util.GetLogger(req.Context()).WithError(err).Error("createInviteFrom3PIDInvite failed")
@ -107,7 +105,7 @@ func ExchangeThirdPartyInvite(
httpReq *http.Request, httpReq *http.Request,
request *gomatrixserverlib.FederationRequest, request *gomatrixserverlib.FederationRequest,
roomID string, roomID string,
rsAPI roomserverAPI.RoomserverInternalAPI, rsAPI api.RoomserverInternalAPI,
cfg *config.Dendrite, cfg *config.Dendrite,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
) util.JSONResponse { ) util.JSONResponse {
@ -197,10 +195,10 @@ func ExchangeThirdPartyInvite(
// Returns an error if there was a problem building the event or fetching the // Returns an error if there was a problem building the event or fetching the
// necessary data to do so. // necessary data to do so.
func createInviteFrom3PIDInvite( func createInviteFrom3PIDInvite(
ctx context.Context, rsAPI roomserverAPI.RoomserverInternalAPI, ctx context.Context, rsAPI api.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI, cfg *config.Dendrite, cfg *config.Dendrite,
inv invite, federation *gomatrixserverlib.FederationClient, inv invite, federation *gomatrixserverlib.FederationClient,
accountDB accounts.Database, userAPI userapi.UserInternalAPI,
) (*gomatrixserverlib.Event, error) { ) (*gomatrixserverlib.Event, error) {
verReq := api.QueryRoomVersionForRoomRequest{RoomID: inv.RoomID} verReq := api.QueryRoomVersionForRoomRequest{RoomID: inv.RoomID}
verRes := api.QueryRoomVersionForRoomResponse{} verRes := api.QueryRoomVersionForRoomResponse{}
@ -225,14 +223,17 @@ func createInviteFrom3PIDInvite(
StateKey: &inv.MXID, StateKey: &inv.MXID,
} }
profile, err := appserviceAPI.RetrieveUserProfile(ctx, inv.MXID, asAPI, accountDB) var res userapi.QueryProfileResponse
err = userAPI.QueryProfile(ctx, &userapi.QueryProfileRequest{
UserID: inv.MXID,
}, &res)
if err != nil { if err != nil {
return nil, err return nil, err
} }
content := gomatrixserverlib.MemberContent{ content := gomatrixserverlib.MemberContent{
AvatarURL: profile.AvatarURL, AvatarURL: res.AvatarURL,
DisplayName: profile.DisplayName, DisplayName: res.DisplayName,
Membership: gomatrixserverlib.Invite, Membership: gomatrixserverlib.Invite,
ThirdPartyInvite: &gomatrixserverlib.MemberThirdPartyInvite{ ThirdPartyInvite: &gomatrixserverlib.MemberThirdPartyInvite{
Signed: inv.Signed, Signed: inv.Signed,
@ -261,7 +262,7 @@ func createInviteFrom3PIDInvite(
// Returns an error if something failed during the process. // Returns an error if something failed during the process.
func buildMembershipEvent( func buildMembershipEvent(
ctx context.Context, ctx context.Context,
builder *gomatrixserverlib.EventBuilder, rsAPI roomserverAPI.RoomserverInternalAPI, builder *gomatrixserverlib.EventBuilder, rsAPI api.RoomserverInternalAPI,
cfg *config.Dendrite, cfg *config.Dendrite,
) (*gomatrixserverlib.Event, error) { ) (*gomatrixserverlib.Event, error) {
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder) eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
@ -274,11 +275,11 @@ func buildMembershipEvent(
} }
// Ask the roomserver for information about this room // Ask the roomserver for information about this room
queryReq := roomserverAPI.QueryLatestEventsAndStateRequest{ queryReq := api.QueryLatestEventsAndStateRequest{
RoomID: builder.RoomID, RoomID: builder.RoomID,
StateToFetch: eventsNeeded.Tuples(), StateToFetch: eventsNeeded.Tuples(),
} }
var queryRes roomserverAPI.QueryLatestEventsAndStateResponse var queryRes api.QueryLatestEventsAndStateResponse
if err = rsAPI.QueryLatestEventsAndState(ctx, &queryReq, &queryRes); err != nil { if err = rsAPI.QueryLatestEventsAndState(ctx, &queryReq, &queryRes); err != nil {
return nil, err return nil, err
} }

View file

@ -15,14 +15,6 @@ type FederationSenderInternalAPI interface {
request *PerformDirectoryLookupRequest, request *PerformDirectoryLookupRequest,
response *PerformDirectoryLookupResponse, response *PerformDirectoryLookupResponse,
) error ) error
// Query the joined hosts and the membership events accounting for their participation in a room.
// Note that if a server has multiple users in the room, it will have multiple entries in the returned slice.
// See `QueryJoinedHostServerNamesInRoom` for a de-duplicated version.
QueryJoinedHostsInRoom(
ctx context.Context,
request *QueryJoinedHostsInRoomRequest,
response *QueryJoinedHostsInRoomResponse,
) error
// Query the server names of the joined hosts in a room. // Query the server names of the joined hosts in a room.
// Unlike QueryJoinedHostsInRoom, this function returns a de-duplicated slice // Unlike QueryJoinedHostsInRoom, this function returns a de-duplicated slice
// containing only the server names (without information for membership events). // containing only the server names (without information for membership events).
@ -88,22 +80,12 @@ type PerformServersAliveRequest struct {
type PerformServersAliveResponse struct { type PerformServersAliveResponse struct {
} }
// QueryJoinedHostsInRoomRequest is a request to QueryJoinedHostsInRoom // QueryJoinedHostServerNamesInRoomRequest is a request to QueryJoinedHostServerNames
type QueryJoinedHostsInRoomRequest struct {
RoomID string `json:"room_id"`
}
// QueryJoinedHostsInRoomResponse is a response to QueryJoinedHostsInRoom
type QueryJoinedHostsInRoomResponse struct {
JoinedHosts []types.JoinedHost `json:"joined_hosts"`
}
// QueryJoinedHostServerNamesRequest is a request to QueryJoinedHostServerNames
type QueryJoinedHostServerNamesInRoomRequest struct { type QueryJoinedHostServerNamesInRoomRequest struct {
RoomID string `json:"room_id"` RoomID string `json:"room_id"`
} }
// QueryJoinedHostServerNamesResponse is a response to QueryJoinedHostServerNames // QueryJoinedHostServerNamesInRoomResponse is a response to QueryJoinedHostServerNames
type QueryJoinedHostServerNamesInRoomResponse struct { type QueryJoinedHostServerNamesInRoomResponse struct {
ServerNames []gomatrixserverlib.ServerName `json:"server_names"` ServerNames []gomatrixserverlib.ServerName `json:"server_names"`
} }

View file

@ -86,11 +86,6 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
switch output.Type { switch output.Type {
case api.OutputTypeNewRoomEvent: case api.OutputTypeNewRoomEvent:
ev := &output.NewRoomEvent.Event ev := &output.NewRoomEvent.Event
log.WithFields(log.Fields{
"event_id": ev.EventID(),
"room_id": ev.RoomID(),
"send_as_server": output.NewRoomEvent.SendAsServer,
}).Info("received room event from roomserver")
if err := s.processMessage(*output.NewRoomEvent); err != nil { if err := s.processMessage(*output.NewRoomEvent); err != nil {
// panic rather than continue with an inconsistent database // panic rather than continue with an inconsistent database
@ -131,11 +126,7 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
// processMessage updates the list of currently joined hosts in the room // processMessage updates the list of currently joined hosts in the room
// and then sends the event to the hosts that were joined before the event. // and then sends the event to the hosts that were joined before the event.
func (s *OutputRoomEventConsumer) processMessage(ore api.OutputNewRoomEvent) error { func (s *OutputRoomEventConsumer) processMessage(ore api.OutputNewRoomEvent) error {
addsStateEvents, err := s.lookupStateEvents(ore.AddsStateEventIDs, ore.Event.Event) addsJoinedHosts, err := joinedHostsFromEvents(gomatrixserverlib.UnwrapEventHeaders(ore.AddsState()))
if err != nil {
return err
}
addsJoinedHosts, err := joinedHostsFromEvents(addsStateEvents)
if err != nil { if err != nil {
return err return err
} }

View file

@ -23,7 +23,7 @@ import (
"github.com/matrix-org/dendrite/federationsender/queue" "github.com/matrix-org/dendrite/federationsender/queue"
"github.com/matrix-org/dendrite/federationsender/storage" "github.com/matrix-org/dendrite/federationsender/storage"
"github.com/matrix-org/dendrite/federationsender/types" "github.com/matrix-org/dendrite/federationsender/types"
"github.com/matrix-org/dendrite/internal/basecomponent" "github.com/matrix-org/dendrite/internal/setup"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -38,7 +38,7 @@ func AddInternalRoutes(router *mux.Router, intAPI api.FederationSenderInternalAP
// NewInternalAPI returns a concerete implementation of the internal API. Callers // 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. // can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
func NewInternalAPI( func NewInternalAPI(
base *basecomponent.BaseDendrite, base *setup.BaseDendrite,
federation *gomatrixserverlib.FederationClient, federation *gomatrixserverlib.FederationClient,
rsAPI roomserverAPI.RoomserverInternalAPI, rsAPI roomserverAPI.RoomserverInternalAPI,
keyRing *gomatrixserverlib.KeyRing, keyRing *gomatrixserverlib.KeyRing,

View file

@ -7,16 +7,6 @@ import (
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
// QueryJoinedHostsInRoom implements api.FederationSenderInternalAPI
func (f *FederationSenderInternalAPI) QueryJoinedHostsInRoom(
ctx context.Context,
request *api.QueryJoinedHostsInRoomRequest,
response *api.QueryJoinedHostsInRoomResponse,
) (err error) {
response.JoinedHosts, err = f.db.GetJoinedHosts(ctx, request.RoomID)
return
}
// QueryJoinedHostServerNamesInRoom implements api.FederationSenderInternalAPI // QueryJoinedHostServerNamesInRoom implements api.FederationSenderInternalAPI
func (f *FederationSenderInternalAPI) QueryJoinedHostServerNamesInRoom( func (f *FederationSenderInternalAPI) QueryJoinedHostServerNamesInRoom(
ctx context.Context, ctx context.Context,

View file

@ -6,13 +6,12 @@ import (
"net/http" "net/http"
"github.com/matrix-org/dendrite/federationsender/api" "github.com/matrix-org/dendrite/federationsender/api"
internalHTTP "github.com/matrix-org/dendrite/internal/http" "github.com/matrix-org/dendrite/internal/httputil"
"github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go"
) )
// HTTP paths for the internal HTTP API // HTTP paths for the internal HTTP API
const ( const (
FederationSenderQueryJoinedHostsInRoomPath = "/federationsender/queryJoinedHostsInRoom"
FederationSenderQueryJoinedHostServerNamesInRoomPath = "/federationsender/queryJoinedHostServerNamesInRoom" FederationSenderQueryJoinedHostServerNamesInRoomPath = "/federationsender/queryJoinedHostServerNamesInRoom"
FederationSenderPerformDirectoryLookupRequestPath = "/federationsender/performDirectoryLookup" FederationSenderPerformDirectoryLookupRequestPath = "/federationsender/performDirectoryLookup"
@ -45,7 +44,7 @@ func (h *httpFederationSenderInternalAPI) PerformLeave(
defer span.Finish() defer span.Finish()
apiURL := h.federationSenderURL + FederationSenderPerformLeaveRequestPath apiURL := h.federationSenderURL + FederationSenderPerformLeaveRequestPath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
func (h *httpFederationSenderInternalAPI) PerformServersAlive( func (h *httpFederationSenderInternalAPI) PerformServersAlive(
@ -57,7 +56,7 @@ func (h *httpFederationSenderInternalAPI) PerformServersAlive(
defer span.Finish() defer span.Finish()
apiURL := h.federationSenderURL + FederationSenderPerformServersAlivePath apiURL := h.federationSenderURL + FederationSenderPerformServersAlivePath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// QueryJoinedHostServerNamesInRoom implements FederationSenderInternalAPI // QueryJoinedHostServerNamesInRoom implements FederationSenderInternalAPI
@ -70,20 +69,7 @@ func (h *httpFederationSenderInternalAPI) QueryJoinedHostServerNamesInRoom(
defer span.Finish() defer span.Finish()
apiURL := h.federationSenderURL + FederationSenderQueryJoinedHostServerNamesInRoomPath apiURL := h.federationSenderURL + FederationSenderQueryJoinedHostServerNamesInRoomPath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
}
// QueryJoinedHostsInRoom implements FederationSenderInternalAPI
func (h *httpFederationSenderInternalAPI) QueryJoinedHostsInRoom(
ctx context.Context,
request *api.QueryJoinedHostsInRoomRequest,
response *api.QueryJoinedHostsInRoomResponse,
) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryJoinedHostsInRoom")
defer span.Finish()
apiURL := h.federationSenderURL + FederationSenderQueryJoinedHostsInRoomPath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// Handle an instruction to make_join & send_join with a remote server. // Handle an instruction to make_join & send_join with a remote server.
@ -96,7 +82,7 @@ func (h *httpFederationSenderInternalAPI) PerformJoin(
defer span.Finish() defer span.Finish()
apiURL := h.federationSenderURL + FederationSenderPerformJoinRequestPath apiURL := h.federationSenderURL + FederationSenderPerformJoinRequestPath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
} }
// Handle an instruction to make_join & send_join with a remote server. // Handle an instruction to make_join & send_join with a remote server.
@ -109,5 +95,5 @@ func (h *httpFederationSenderInternalAPI) PerformDirectoryLookup(
defer span.Finish() defer span.Finish()
apiURL := h.federationSenderURL + FederationSenderPerformDirectoryLookupRequestPath apiURL := h.federationSenderURL + FederationSenderPerformDirectoryLookupRequestPath
return internalHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response) return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
} }

View file

@ -6,29 +6,15 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/matrix-org/dendrite/federationsender/api" "github.com/matrix-org/dendrite/federationsender/api"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/util" "github.com/matrix-org/util"
) )
// AddRoutes adds the FederationSenderInternalAPI handlers to the http.ServeMux. // AddRoutes adds the FederationSenderInternalAPI handlers to the http.ServeMux.
func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Router) { func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Router) {
internalAPIMux.Handle(
FederationSenderQueryJoinedHostsInRoomPath,
internal.MakeInternalAPI("QueryJoinedHostsInRoom", func(req *http.Request) util.JSONResponse {
var request api.QueryJoinedHostsInRoomRequest
var response api.QueryJoinedHostsInRoomResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
return util.ErrorResponse(err)
}
if err := intAPI.QueryJoinedHostsInRoom(req.Context(), &request, &response); err != nil {
return util.ErrorResponse(err)
}
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
internalAPIMux.Handle( internalAPIMux.Handle(
FederationSenderQueryJoinedHostServerNamesInRoomPath, FederationSenderQueryJoinedHostServerNamesInRoomPath,
internal.MakeInternalAPI("QueryJoinedHostServerNamesInRoom", func(req *http.Request) util.JSONResponse { httputil.MakeInternalAPI("QueryJoinedHostServerNamesInRoom", func(req *http.Request) util.JSONResponse {
var request api.QueryJoinedHostServerNamesInRoomRequest var request api.QueryJoinedHostServerNamesInRoomRequest
var response api.QueryJoinedHostServerNamesInRoomResponse var response api.QueryJoinedHostServerNamesInRoomResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -41,7 +27,7 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route
}), }),
) )
internalAPIMux.Handle(FederationSenderPerformJoinRequestPath, internalAPIMux.Handle(FederationSenderPerformJoinRequestPath,
internal.MakeInternalAPI("PerformJoinRequest", func(req *http.Request) util.JSONResponse { httputil.MakeInternalAPI("PerformJoinRequest", func(req *http.Request) util.JSONResponse {
var request api.PerformJoinRequest var request api.PerformJoinRequest
var response api.PerformJoinResponse var response api.PerformJoinResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -54,7 +40,7 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route
}), }),
) )
internalAPIMux.Handle(FederationSenderPerformLeaveRequestPath, internalAPIMux.Handle(FederationSenderPerformLeaveRequestPath,
internal.MakeInternalAPI("PerformLeaveRequest", func(req *http.Request) util.JSONResponse { httputil.MakeInternalAPI("PerformLeaveRequest", func(req *http.Request) util.JSONResponse {
var request api.PerformLeaveRequest var request api.PerformLeaveRequest
var response api.PerformLeaveResponse var response api.PerformLeaveResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -67,7 +53,7 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route
}), }),
) )
internalAPIMux.Handle(FederationSenderPerformDirectoryLookupRequestPath, internalAPIMux.Handle(FederationSenderPerformDirectoryLookupRequestPath,
internal.MakeInternalAPI("PerformDirectoryLookupRequest", func(req *http.Request) util.JSONResponse { httputil.MakeInternalAPI("PerformDirectoryLookupRequest", func(req *http.Request) util.JSONResponse {
var request api.PerformDirectoryLookupRequest var request api.PerformDirectoryLookupRequest
var response api.PerformDirectoryLookupResponse var response api.PerformDirectoryLookupResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
@ -80,7 +66,7 @@ func AddRoutes(intAPI api.FederationSenderInternalAPI, internalAPIMux *mux.Route
}), }),
) )
internalAPIMux.Handle(FederationSenderPerformServersAlivePath, internalAPIMux.Handle(FederationSenderPerformServersAlivePath,
internal.MakeInternalAPI("PerformServersAliveRequest", func(req *http.Request) util.JSONResponse { httputil.MakeInternalAPI("PerformServersAliveRequest", func(req *http.Request) util.JSONResponse {
var request api.PerformServersAliveRequest var request api.PerformServersAliveRequest
var response api.PerformServersAliveResponse var response api.PerformServersAliveResponse
if err := json.NewDecoder(req.Body).Decode(&request); err != nil { if err := json.NewDecoder(req.Body).Decode(&request); err != nil {

View file

@ -107,6 +107,9 @@ func (oqs *OutgoingQueues) SendEvent(
// Remove our own server from the list of destinations. // Remove our own server from the list of destinations.
destinations = filterAndDedupeDests(oqs.origin, destinations) destinations = filterAndDedupeDests(oqs.origin, destinations)
if len(destinations) == 0 {
return nil
}
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"destinations": destinations, "event": ev.EventID(), "destinations": destinations, "event": ev.EventID(),

View file

@ -22,6 +22,7 @@ import (
"github.com/lib/pq" "github.com/lib/pq"
"github.com/matrix-org/dendrite/federationsender/types" "github.com/matrix-org/dendrite/federationsender/types"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
@ -85,7 +86,7 @@ func (s *joinedHostsStatements) insertJoinedHosts(
roomID, eventID string, roomID, eventID string,
serverName gomatrixserverlib.ServerName, serverName gomatrixserverlib.ServerName,
) error { ) error {
stmt := internal.TxStmt(txn, s.insertJoinedHostsStmt) stmt := sqlutil.TxStmt(txn, s.insertJoinedHostsStmt)
_, err := stmt.ExecContext(ctx, roomID, eventID, serverName) _, err := stmt.ExecContext(ctx, roomID, eventID, serverName)
return err return err
} }
@ -93,7 +94,7 @@ func (s *joinedHostsStatements) insertJoinedHosts(
func (s *joinedHostsStatements) deleteJoinedHosts( func (s *joinedHostsStatements) deleteJoinedHosts(
ctx context.Context, txn *sql.Tx, eventIDs []string, ctx context.Context, txn *sql.Tx, eventIDs []string,
) error { ) error {
stmt := internal.TxStmt(txn, s.deleteJoinedHostsStmt) stmt := sqlutil.TxStmt(txn, s.deleteJoinedHostsStmt)
_, err := stmt.ExecContext(ctx, pq.StringArray(eventIDs)) _, err := stmt.ExecContext(ctx, pq.StringArray(eventIDs))
return err return err
} }
@ -101,7 +102,7 @@ func (s *joinedHostsStatements) deleteJoinedHosts(
func (s *joinedHostsStatements) selectJoinedHostsWithTx( func (s *joinedHostsStatements) selectJoinedHostsWithTx(
ctx context.Context, txn *sql.Tx, roomID string, ctx context.Context, txn *sql.Tx, roomID string,
) ([]types.JoinedHost, error) { ) ([]types.JoinedHost, error) {
stmt := internal.TxStmt(txn, s.selectJoinedHostsStmt) stmt := sqlutil.TxStmt(txn, s.selectJoinedHostsStmt)
return joinedHostsFromStmt(ctx, stmt, roomID) return joinedHostsFromStmt(ctx, stmt, roomID)
} }

View file

@ -19,7 +19,7 @@ import (
"context" "context"
"database/sql" "database/sql"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/sqlutil"
) )
const roomSchema = ` const roomSchema = `
@ -71,7 +71,7 @@ func (s *roomStatements) prepare(db *sql.DB) (err error) {
func (s *roomStatements) insertRoom( func (s *roomStatements) insertRoom(
ctx context.Context, txn *sql.Tx, roomID string, ctx context.Context, txn *sql.Tx, roomID string,
) error { ) error {
_, err := internal.TxStmt(txn, s.insertRoomStmt).ExecContext(ctx, roomID) _, err := sqlutil.TxStmt(txn, s.insertRoomStmt).ExecContext(ctx, roomID)
return err return err
} }
@ -82,7 +82,7 @@ func (s *roomStatements) selectRoomForUpdate(
ctx context.Context, txn *sql.Tx, roomID string, ctx context.Context, txn *sql.Tx, roomID string,
) (string, error) { ) (string, error) {
var lastEventID string var lastEventID string
stmt := internal.TxStmt(txn, s.selectRoomForUpdateStmt) stmt := sqlutil.TxStmt(txn, s.selectRoomForUpdateStmt)
err := stmt.QueryRowContext(ctx, roomID).Scan(&lastEventID) err := stmt.QueryRowContext(ctx, roomID).Scan(&lastEventID)
if err != nil { if err != nil {
return "", err return "", err
@ -95,7 +95,7 @@ func (s *roomStatements) selectRoomForUpdate(
func (s *roomStatements) updateRoom( func (s *roomStatements) updateRoom(
ctx context.Context, txn *sql.Tx, roomID, lastEventID string, ctx context.Context, txn *sql.Tx, roomID, lastEventID string,
) error { ) error {
stmt := internal.TxStmt(txn, s.updateRoomStmt) stmt := sqlutil.TxStmt(txn, s.updateRoomStmt)
_, err := stmt.ExecContext(ctx, roomID, lastEventID) _, err := stmt.ExecContext(ctx, roomID, lastEventID)
return err return err
} }

View file

@ -20,7 +20,6 @@ import (
"database/sql" "database/sql"
"github.com/matrix-org/dendrite/federationsender/types" "github.com/matrix-org/dendrite/federationsender/types"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
) )
@ -28,12 +27,12 @@ import (
type Database struct { type Database struct {
joinedHostsStatements joinedHostsStatements
roomStatements roomStatements
internal.PartitionOffsetStatements sqlutil.PartitionOffsetStatements
db *sql.DB db *sql.DB
} }
// NewDatabase opens a new database // NewDatabase opens a new database
func NewDatabase(dataSourceName string, dbProperties internal.DbProperties) (*Database, error) { func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) {
var result Database var result Database
var err error var err error
if result.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil { if result.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil {
@ -70,7 +69,7 @@ func (d *Database) UpdateRoom(
addHosts []types.JoinedHost, addHosts []types.JoinedHost,
removeHosts []string, removeHosts []string,
) (joinedHosts []types.JoinedHost, err error) { ) (joinedHosts []types.JoinedHost, err error) {
err = internal.WithTransaction(d.db, func(txn *sql.Tx) error { err = sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error {
err = d.insertRoom(ctx, txn, roomID) err = d.insertRoom(ctx, txn, roomID)
if err != nil { if err != nil {
return err return err

View file

@ -21,6 +21,7 @@ import (
"github.com/matrix-org/dendrite/federationsender/types" "github.com/matrix-org/dendrite/federationsender/types"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
) )
@ -84,7 +85,7 @@ func (s *joinedHostsStatements) insertJoinedHosts(
roomID, eventID string, roomID, eventID string,
serverName gomatrixserverlib.ServerName, serverName gomatrixserverlib.ServerName,
) error { ) error {
stmt := internal.TxStmt(txn, s.insertJoinedHostsStmt) stmt := sqlutil.TxStmt(txn, s.insertJoinedHostsStmt)
_, err := stmt.ExecContext(ctx, roomID, eventID, serverName) _, err := stmt.ExecContext(ctx, roomID, eventID, serverName)
return err return err
} }
@ -93,7 +94,7 @@ func (s *joinedHostsStatements) deleteJoinedHosts(
ctx context.Context, txn *sql.Tx, eventIDs []string, ctx context.Context, txn *sql.Tx, eventIDs []string,
) error { ) error {
for _, eventID := range eventIDs { for _, eventID := range eventIDs {
stmt := internal.TxStmt(txn, s.deleteJoinedHostsStmt) stmt := sqlutil.TxStmt(txn, s.deleteJoinedHostsStmt)
if _, err := stmt.ExecContext(ctx, eventID); err != nil { if _, err := stmt.ExecContext(ctx, eventID); err != nil {
return err return err
} }
@ -104,7 +105,7 @@ func (s *joinedHostsStatements) deleteJoinedHosts(
func (s *joinedHostsStatements) selectJoinedHostsWithTx( func (s *joinedHostsStatements) selectJoinedHostsWithTx(
ctx context.Context, txn *sql.Tx, roomID string, ctx context.Context, txn *sql.Tx, roomID string,
) ([]types.JoinedHost, error) { ) ([]types.JoinedHost, error) {
stmt := internal.TxStmt(txn, s.selectJoinedHostsStmt) stmt := sqlutil.TxStmt(txn, s.selectJoinedHostsStmt)
return joinedHostsFromStmt(ctx, stmt, roomID) return joinedHostsFromStmt(ctx, stmt, roomID)
} }

View file

@ -19,7 +19,7 @@ import (
"context" "context"
"database/sql" "database/sql"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/sqlutil"
) )
const roomSchema = ` const roomSchema = `
@ -71,7 +71,7 @@ func (s *roomStatements) prepare(db *sql.DB) (err error) {
func (s *roomStatements) insertRoom( func (s *roomStatements) insertRoom(
ctx context.Context, txn *sql.Tx, roomID string, ctx context.Context, txn *sql.Tx, roomID string,
) error { ) error {
_, err := internal.TxStmt(txn, s.insertRoomStmt).ExecContext(ctx, roomID) _, err := sqlutil.TxStmt(txn, s.insertRoomStmt).ExecContext(ctx, roomID)
return err return err
} }
@ -82,7 +82,7 @@ func (s *roomStatements) selectRoomForUpdate(
ctx context.Context, txn *sql.Tx, roomID string, ctx context.Context, txn *sql.Tx, roomID string,
) (string, error) { ) (string, error) {
var lastEventID string var lastEventID string
stmt := internal.TxStmt(txn, s.selectRoomForUpdateStmt) stmt := sqlutil.TxStmt(txn, s.selectRoomForUpdateStmt)
err := stmt.QueryRowContext(ctx, roomID).Scan(&lastEventID) err := stmt.QueryRowContext(ctx, roomID).Scan(&lastEventID)
if err != nil { if err != nil {
return "", err return "", err
@ -95,7 +95,7 @@ func (s *roomStatements) selectRoomForUpdate(
func (s *roomStatements) updateRoom( func (s *roomStatements) updateRoom(
ctx context.Context, txn *sql.Tx, roomID, lastEventID string, ctx context.Context, txn *sql.Tx, roomID, lastEventID string,
) error { ) error {
stmt := internal.TxStmt(txn, s.updateRoomStmt) stmt := sqlutil.TxStmt(txn, s.updateRoomStmt)
_, err := stmt.ExecContext(ctx, roomID, lastEventID) _, err := stmt.ExecContext(ctx, roomID, lastEventID)
return err return err
} }

View file

@ -22,7 +22,6 @@ import (
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
"github.com/matrix-org/dendrite/federationsender/types" "github.com/matrix-org/dendrite/federationsender/types"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
) )
@ -30,7 +29,7 @@ import (
type Database struct { type Database struct {
joinedHostsStatements joinedHostsStatements
roomStatements roomStatements
internal.PartitionOffsetStatements sqlutil.PartitionOffsetStatements
db *sql.DB db *sql.DB
} }
@ -42,7 +41,7 @@ func NewDatabase(dataSourceName string) (*Database, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if result.db, err = sqlutil.Open(internal.SQLiteDriverName(), cs, nil); err != nil { if result.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
return nil, err return nil, err
} }
if err = result.prepare(); err != nil { if err = result.prepare(); err != nil {
@ -76,7 +75,7 @@ func (d *Database) UpdateRoom(
addHosts []types.JoinedHost, addHosts []types.JoinedHost,
removeHosts []string, removeHosts []string,
) (joinedHosts []types.JoinedHost, err error) { ) (joinedHosts []types.JoinedHost, err error) {
err = internal.WithTransaction(d.db, func(txn *sql.Tx) error { err = sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error {
err = d.insertRoom(ctx, txn, roomID) err = d.insertRoom(ctx, txn, roomID)
if err != nil { if err != nil {
return err return err

View file

@ -21,11 +21,11 @@ import (
"github.com/matrix-org/dendrite/federationsender/storage/postgres" "github.com/matrix-org/dendrite/federationsender/storage/postgres"
"github.com/matrix-org/dendrite/federationsender/storage/sqlite3" "github.com/matrix-org/dendrite/federationsender/storage/sqlite3"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/sqlutil"
) )
// NewDatabase opens a new database // NewDatabase opens a new database
func NewDatabase(dataSourceName string, dbProperties internal.DbProperties) (Database, error) { func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) {
uri, err := url.Parse(dataSourceName) uri, err := url.Parse(dataSourceName)
if err != nil { if err != nil {
return postgres.NewDatabase(dataSourceName, dbProperties) return postgres.NewDatabase(dataSourceName, dbProperties)

View file

@ -19,13 +19,13 @@ import (
"net/url" "net/url"
"github.com/matrix-org/dendrite/federationsender/storage/sqlite3" "github.com/matrix-org/dendrite/federationsender/storage/sqlite3"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/sqlutil"
) )
// NewDatabase opens a new database // NewDatabase opens a new database
func NewDatabase( func NewDatabase(
dataSourceName string, dataSourceName string,
dbProperties internal.DbProperties, // nolint:unparam dbProperties sqlutil.DbProperties, // nolint:unparam
) (Database, error) { ) (Database, error) {
uri, err := url.Parse(dataSourceName) uri, err := url.Parse(dataSourceName)
if err != nil { if err != nil {

2
go.mod
View file

@ -20,7 +20,7 @@ require (
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4 github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3 github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26
github.com/matrix-org/gomatrixserverlib v0.0.0-20200608125510-defe251235b1 github.com/matrix-org/gomatrixserverlib v0.0.0-20200617141855-5539854e4abc
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7
github.com/mattn/go-sqlite3 v2.0.2+incompatible github.com/mattn/go-sqlite3 v2.0.2+incompatible

10
go.sum
View file

@ -131,7 +131,6 @@ github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hjson/hjson-go v3.0.1-0.20190209023717-9147687966d9+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio=
github.com/hjson/hjson-go v3.0.2-0.20200316202735-d5d0e8b0617d+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio= github.com/hjson/hjson-go v3.0.2-0.20200316202735-d5d0e8b0617d+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@ -372,8 +371,10 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3 h1:Yb+Wlf
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo= github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo=
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bhrnp3Ky1qgx/fzCtCALOoGYylh2tpS9K4= github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bhrnp3Ky1qgx/fzCtCALOoGYylh2tpS9K4=
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0= github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200608125510-defe251235b1 h1:BfrvDrbjoPBvYua/3F/FmrqiZTRGrvtoMRgCVnrufMI= github.com/matrix-org/gomatrixserverlib v0.0.0-20200616150727-7ac22b6f8e65 h1:2CcCcBnWdDPDOqFKiGOM+mi/KDDZXSTKmvFy/0/+ZJI=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200608125510-defe251235b1/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU= github.com/matrix-org/gomatrixserverlib v0.0.0-20200616150727-7ac22b6f8e65/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200617141855-5539854e4abc h1:Oxidxr/H1Nh8aOFWAhTzQYLDOc9OuoJwfDjgEHpyqNE=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200617141855-5539854e4abc/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f h1:pRz4VTiRCO4zPlEMc3ESdUOcW4PXHH4Kj+YDz1XyE+Y= github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f h1:pRz4VTiRCO4zPlEMc3ESdUOcW4PXHH4Kj+YDz1XyE+Y=
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f/go.mod h1:y0oDTjZDv5SM9a2rp3bl+CU+bvTRINQsdb7YlDql5Go= github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f/go.mod h1:y0oDTjZDv5SM9a2rp3bl+CU+bvTRINQsdb7YlDql5Go=
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo= github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=
@ -566,8 +567,6 @@ github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhe
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yggdrasil-network/yggdrasil-extras v0.0.0-20200525205615-6c8a4a2e8855/go.mod h1:xQdsh08Io6nV4WRnOVTe6gI8/2iTvfLDQ0CYa5aMt+I= github.com/yggdrasil-network/yggdrasil-extras v0.0.0-20200525205615-6c8a4a2e8855/go.mod h1:xQdsh08Io6nV4WRnOVTe6gI8/2iTvfLDQ0CYa5aMt+I=
github.com/yggdrasil-network/yggdrasil-go v0.3.14 h1:vWzYzCQxOruS+J5FkLfXOS0JhCJx1yI9Erj/h2wfZ/E=
github.com/yggdrasil-network/yggdrasil-go v0.3.14/go.mod h1:rkQzLzVHlFdzsEMG+bDdTI+KeWPCZq1HpXRFzwinf6M=
github.com/yggdrasil-network/yggdrasil-go v0.3.15-0.20200530233943-aec82d7a391b h1:ELOisSxFXCcptRs4LFub+Hz5fYUvV12wZrTps99Eb3E= github.com/yggdrasil-network/yggdrasil-go v0.3.15-0.20200530233943-aec82d7a391b h1:ELOisSxFXCcptRs4LFub+Hz5fYUvV12wZrTps99Eb3E=
github.com/yggdrasil-network/yggdrasil-go v0.3.15-0.20200530233943-aec82d7a391b/go.mod h1:d+Nz6SPeG6kmeSPFL0cvfWfgwEql75fUnZiAONgvyBE= github.com/yggdrasil-network/yggdrasil-go v0.3.15-0.20200530233943-aec82d7a391b/go.mod h1:d+Nz6SPeG6kmeSPFL0cvfWfgwEql75fUnZiAONgvyBE=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@ -670,6 +669,7 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View file

@ -15,17 +15,32 @@ const (
// ServerKeyCache contains the subset of functions needed for // ServerKeyCache contains the subset of functions needed for
// a server key cache. // a server key cache.
type ServerKeyCache interface { type ServerKeyCache interface {
GetServerKey(request gomatrixserverlib.PublicKeyLookupRequest) (response gomatrixserverlib.PublicKeyLookupResult, ok bool) // request -> timestamp is emulating gomatrixserverlib.FetchKeys:
// https://github.com/matrix-org/gomatrixserverlib/blob/f69539c86ea55d1e2cc76fd8e944e2d82d30397c/keyring.go#L95
// The timestamp should be the timestamp of the event that is being
// verified. We will not return keys from the cache that are not valid
// at this timestamp.
GetServerKey(request gomatrixserverlib.PublicKeyLookupRequest, timestamp gomatrixserverlib.Timestamp) (response gomatrixserverlib.PublicKeyLookupResult, ok bool)
// request -> result is emulating gomatrixserverlib.StoreKeys:
// https://github.com/matrix-org/gomatrixserverlib/blob/f69539c86ea55d1e2cc76fd8e944e2d82d30397c/keyring.go#L112
StoreServerKey(request gomatrixserverlib.PublicKeyLookupRequest, response gomatrixserverlib.PublicKeyLookupResult) StoreServerKey(request gomatrixserverlib.PublicKeyLookupRequest, response gomatrixserverlib.PublicKeyLookupResult)
} }
func (c Caches) GetServerKey( func (c Caches) GetServerKey(
request gomatrixserverlib.PublicKeyLookupRequest, request gomatrixserverlib.PublicKeyLookupRequest,
timestamp gomatrixserverlib.Timestamp,
) (gomatrixserverlib.PublicKeyLookupResult, bool) { ) (gomatrixserverlib.PublicKeyLookupResult, bool) {
key := fmt.Sprintf("%s/%s", request.ServerName, request.KeyID) key := fmt.Sprintf("%s/%s", request.ServerName, request.KeyID)
val, found := c.ServerKeys.Get(key) val, found := c.ServerKeys.Get(key)
if found && val != nil { if found && val != nil {
if keyLookupResult, ok := val.(gomatrixserverlib.PublicKeyLookupResult); ok { if keyLookupResult, ok := val.(gomatrixserverlib.PublicKeyLookupResult); ok {
if !keyLookupResult.WasValidAt(timestamp, true) {
// The key wasn't valid at the requested timestamp so don't
// return it. The caller will have to work out what to do.
c.ServerKeys.Unset(key)
return gomatrixserverlib.PublicKeyLookupResult{}, false
}
return keyLookupResult, true return keyLookupResult, true
} }
} }

View file

@ -12,4 +12,5 @@ type Caches struct {
type Cache interface { type Cache interface {
Get(key string) (value interface{}, ok bool) Get(key string) (value interface{}, ok bool)
Set(key string, value interface{}) Set(key string, value interface{})
Unset(key string)
} }

Some files were not shown because too many files have changed in this diff Show more