aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--appservice/appservice.go2
-rw-r--r--appservice/consumers/roomserver.go4
-rw-r--r--appservice/storage/postgres/storage.go5
-rw-r--r--appservice/storage/sqlite3/storage.go9
-rw-r--r--appservice/storage/storage.go22
-rw-r--r--appservice/storage/storage_wasm.go24
-rw-r--r--build/gobind/monolith.go54
-rw-r--r--clientapi/auth/password.go2
-rw-r--r--clientapi/auth/user_interactive.go2
-rw-r--r--clientapi/auth/user_interactive_test.go7
-rw-r--r--clientapi/clientapi.go4
-rw-r--r--clientapi/routing/auth_fallback.go8
-rw-r--r--clientapi/routing/createroom.go6
-rw-r--r--clientapi/routing/directory.go5
-rw-r--r--clientapi/routing/getevent.go4
-rw-r--r--clientapi/routing/login.go2
-rw-r--r--clientapi/routing/membership.go18
-rw-r--r--clientapi/routing/memberships.go2
-rw-r--r--clientapi/routing/profile.go16
-rw-r--r--clientapi/routing/redaction.go4
-rw-r--r--clientapi/routing/register.go42
-rw-r--r--clientapi/routing/register_test.go15
-rw-r--r--clientapi/routing/routing.go2
-rw-r--r--clientapi/routing/sendevent.go6
-rw-r--r--clientapi/routing/threepid.go4
-rw-r--r--clientapi/routing/voip.go2
-rw-r--r--clientapi/threepid/invites.go10
-rw-r--r--clientapi/threepid/threepid.go8
-rw-r--r--cmd/create-account/main.go9
-rw-r--r--cmd/dendrite-appservice-server/main.go2
-rw-r--r--cmd/dendrite-client-api-server/main.go4
-rw-r--r--cmd/dendrite-current-state-server/main.go4
-rw-r--r--cmd/dendrite-demo-libp2p/main.go55
-rw-r--r--cmd/dendrite-demo-libp2p/p2pdendrite.go4
-rw-r--r--cmd/dendrite-demo-yggdrasil/main.go52
-rw-r--r--cmd/dendrite-demo-yggdrasil/yggconn/client.go4
-rw-r--r--cmd/dendrite-edu-server/main.go2
-rw-r--r--cmd/dendrite-federation-api-server/main.go4
-rw-r--r--cmd/dendrite-federation-sender-server/main.go2
-rw-r--r--cmd/dendrite-key-server/main.go4
-rw-r--r--cmd/dendrite-media-api-server/main.go6
-rw-r--r--cmd/dendrite-monolith-server/main.go28
-rw-r--r--cmd/dendrite-room-server/main.go2
-rw-r--r--cmd/dendrite-server-key-api-server/main.go4
-rw-r--r--cmd/dendrite-sync-api-server/main.go4
-rw-r--r--cmd/dendrite-user-api-server/main.go4
-rw-r--r--cmd/dendritejs/main.go54
-rw-r--r--cmd/generate-config/main.go29
-rw-r--r--cmd/mediaapi-integration-tests/main.go8
-rw-r--r--cmd/roomserver-integration-tests/main.go4
-rw-r--r--cmd/syncserver-integration-tests/main.go8
-rw-r--r--currentstateserver/currentstateserver.go6
-rw-r--r--currentstateserver/currentstateserver_test.go22
-rw-r--r--currentstateserver/storage/postgres/storage.go5
-rw-r--r--currentstateserver/storage/sqlite3/storage.go10
-rw-r--r--currentstateserver/storage/storage.go22
-rw-r--r--currentstateserver/storage/storage_wasm.go24
-rw-r--r--dendrite-config.yaml178
-rw-r--r--eduserver/eduserver.go7
-rw-r--r--federationapi/federationapi.go2
-rw-r--r--federationapi/federationapi_test.go21
-rw-r--r--federationapi/routing/backfill.go2
-rw-r--r--federationapi/routing/invite.go6
-rw-r--r--federationapi/routing/join.go6
-rw-r--r--federationapi/routing/keys.go6
-rw-r--r--federationapi/routing/leave.go6
-rw-r--r--federationapi/routing/profile.go2
-rw-r--r--federationapi/routing/query.go2
-rw-r--r--federationapi/routing/routing.go2
-rw-r--r--federationapi/routing/send.go2
-rw-r--r--federationapi/routing/threepid.go10
-rw-r--r--federationsender/consumers/eduserver.go10
-rw-r--r--federationsender/consumers/keychange.go4
-rw-r--r--federationsender/consumers/roomserver.go6
-rw-r--r--federationsender/federationsender.go22
-rw-r--r--federationsender/internal/api.go4
-rw-r--r--federationsender/storage/postgres/storage.go5
-rw-r--r--federationsender/storage/sqlite3/storage.go9
-rw-r--r--federationsender/storage/storage.go22
-rw-r--r--federationsender/storage/storage_wasm.go24
-rw-r--r--go.mod4
-rw-r--r--go.sum6
-rw-r--r--internal/config/config.go577
-rw-r--r--internal/config/config_appservice.go (renamed from internal/config/appservice.go)57
-rw-r--r--internal/config/config_clientapi.go87
-rw-r--r--internal/config/config_currentstate.go25
-rw-r--r--internal/config/config_eduserver.go18
-rw-r--r--internal/config/config_federationapi.go33
-rw-r--r--internal/config/config_federationsender.go64
-rw-r--r--internal/config/config_global.go172
-rw-r--r--internal/config/config_keyserver.go23
-rw-r--r--internal/config/config_mediaapi.go63
-rw-r--r--internal/config/config_roomserver.go23
-rw-r--r--internal/config/config_serverkey.go29
-rw-r--r--internal/config/config_syncapi.go23
-rw-r--r--internal/config/config_test.go189
-rw-r--r--internal/config/config_userapi.go31
-rw-r--r--internal/eventutil/events.go6
-rw-r--r--internal/httputil/httpapi.go2
-rw-r--r--internal/setup/base.go60
-rw-r--r--internal/setup/monolith.go8
-rw-r--r--internal/sqlutil/sql.go8
-rw-r--r--internal/sqlutil/trace.go26
-rw-r--r--internal/sqlutil/uri.go10
-rw-r--r--internal/test/config.go79
-rw-r--r--internal/test/server.go6
-rw-r--r--keyserver/keyserver.go9
-rw-r--r--keyserver/storage/postgres/storage.go5
-rw-r--r--keyserver/storage/sqlite3/storage.go10
-rw-r--r--keyserver/storage/storage.go22
-rw-r--r--keyserver/storage/storage_test.go5
-rw-r--r--keyserver/storage/storage_wasm.go24
-rw-r--r--mediaapi/mediaapi.go4
-rw-r--r--mediaapi/routing/download.go18
-rw-r--r--mediaapi/routing/routing.go4
-rw-r--r--mediaapi/routing/upload.go16
-rw-r--r--mediaapi/storage/postgres/storage.go5
-rw-r--r--mediaapi/storage/sqlite3/storage.go9
-rw-r--r--mediaapi/storage/storage.go22
-rw-r--r--mediaapi/storage/storage_wasm.go24
-rw-r--r--roomserver/internal/api.go2
-rw-r--r--roomserver/internal/perform_join.go12
-rw-r--r--roomserver/internal/perform_leave.go12
-rw-r--r--roomserver/roomserver.go10
-rw-r--r--roomserver/roomserver_test.go10
-rw-r--r--roomserver/storage/postgres/storage.go5
-rw-r--r--roomserver/storage/sqlite3/storage.go10
-rw-r--r--roomserver/storage/storage.go22
-rw-r--r--roomserver/storage/storage_wasm.go24
-rw-r--r--serverkeyapi/serverkeyapi.go7
-rw-r--r--serverkeyapi/serverkeyapi_test.go21
-rw-r--r--serverkeyapi/storage/keydb.go23
-rw-r--r--serverkeyapi/storage/postgres/keydb.go6
-rw-r--r--serverkeyapi/storage/sqlite3/keydb.go9
-rw-r--r--syncapi/consumers/clientapi.go4
-rw-r--r--syncapi/consumers/eduserver_sendtodevice.go4
-rw-r--r--syncapi/consumers/eduserver_typing.go4
-rw-r--r--syncapi/consumers/roomserver.go4
-rw-r--r--syncapi/routing/messages.go4
-rw-r--r--syncapi/routing/routing.go2
-rw-r--r--syncapi/storage/postgres/syncserver.go5
-rw-r--r--syncapi/storage/sqlite3/syncserver.go10
-rw-r--r--syncapi/storage/storage.go22
-rw-r--r--syncapi/storage/storage_test.go5
-rw-r--r--syncapi/storage/storage_wasm.go24
-rw-r--r--syncapi/syncapi.go6
-rw-r--r--userapi/storage/accounts/postgres/storage.go8
-rw-r--r--userapi/storage/accounts/sqlite3/storage.go10
-rw-r--r--userapi/storage/accounts/storage.go22
-rw-r--r--userapi/storage/accounts/storage_wasm.go22
-rw-r--r--userapi/storage/devices/postgres/storage.go8
-rw-r--r--userapi/storage/devices/sqlite3/storage.go10
-rw-r--r--userapi/storage/devices/storage.go22
-rw-r--r--userapi/storage/devices/storage_wasm.go22
-rw-r--r--userapi/userapi_test.go9
155 files changed, 1726 insertions, 1513 deletions
diff --git a/appservice/appservice.go b/appservice/appservice.go
index 72869041..e356f68e 100644
--- a/appservice/appservice.go
+++ b/appservice/appservice.go
@@ -48,7 +48,7 @@ func NewInternalAPI(
rsAPI roomserverAPI.RoomserverInternalAPI,
) appserviceAPI.AppServiceQueryAPI {
// Create a connection to the appservice postgres DB
- appserviceDB, err := storage.NewDatabase(string(base.Cfg.Database.AppService), base.Cfg.DbProperties())
+ appserviceDB, err := storage.NewDatabase(&base.Cfg.AppServiceAPI.Database)
if err != nil {
logrus.WithError(err).Panicf("failed to connect to appservice db")
}
diff --git a/appservice/consumers/roomserver.go b/appservice/consumers/roomserver.go
index 4c0156b2..84f2b9ab 100644
--- a/appservice/consumers/roomserver.go
+++ b/appservice/consumers/roomserver.go
@@ -48,7 +48,7 @@ func NewOutputRoomEventConsumer(
workerStates []types.ApplicationServiceWorkerState,
) *OutputRoomEventConsumer {
consumer := internal.ContinualConsumer{
- Topic: string(cfg.Kafka.Topics.OutputRoomEvent),
+ Topic: string(cfg.Global.Kafka.Topics.OutputRoomEvent),
Consumer: kafkaConsumer,
PartitionStore: appserviceDB,
}
@@ -56,7 +56,7 @@ func NewOutputRoomEventConsumer(
roomServerConsumer: &consumer,
asDB: appserviceDB,
rsAPI: rsAPI,
- serverName: string(cfg.Matrix.ServerName),
+ serverName: string(cfg.Global.ServerName),
workerStates: workerStates,
}
consumer.ProcessMessage = s.onMessage
diff --git a/appservice/storage/postgres/storage.go b/appservice/storage/postgres/storage.go
index 03f331d6..9fda87ae 100644
--- a/appservice/storage/postgres/storage.go
+++ b/appservice/storage/postgres/storage.go
@@ -21,6 +21,7 @@ import (
// Import postgres database driver
_ "github.com/lib/pq"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib"
)
@@ -34,10 +35,10 @@ type Database struct {
}
// NewDatabase opens a new database
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) {
var result Database
var err error
- if result.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil {
+ if result.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
if err = result.prepare(); err != nil {
diff --git a/appservice/storage/sqlite3/storage.go b/appservice/storage/sqlite3/storage.go
index cb55c8d9..59af9016 100644
--- a/appservice/storage/sqlite3/storage.go
+++ b/appservice/storage/sqlite3/storage.go
@@ -20,6 +20,7 @@ import (
"database/sql"
// Import SQLite database driver
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib"
_ "github.com/mattn/go-sqlite3"
@@ -34,14 +35,10 @@ type Database struct {
}
// NewDatabase opens a new database
-func NewDatabase(dataSourceName string) (*Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) {
var result Database
var err error
- cs, err := sqlutil.ParseFileURI(dataSourceName)
- if err != nil {
- return nil, err
- }
- if result.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
+ if result.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
if err = result.prepare(); err != nil {
diff --git a/appservice/storage/storage.go b/appservice/storage/storage.go
index c848d15d..e2d7e4e5 100644
--- a/appservice/storage/storage.go
+++ b/appservice/storage/storage.go
@@ -17,26 +17,22 @@
package storage
import (
- "net/url"
+ "fmt"
"github.com/matrix-org/dendrite/appservice/storage/postgres"
"github.com/matrix-org/dendrite/appservice/storage/sqlite3"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
)
// NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme)
// and sets DB connection parameters
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.NewDatabase(dataSourceName, dbProperties)
- }
- switch uri.Scheme {
- case "postgres":
- return postgres.NewDatabase(dataSourceName, dbProperties)
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
+func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.NewDatabase(dbProperties)
default:
- return postgres.NewDatabase(dataSourceName, dbProperties)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/appservice/storage/storage_wasm.go b/appservice/storage/storage_wasm.go
index 1d6c4b4a..7eb7da26 100644
--- a/appservice/storage/storage_wasm.go
+++ b/appservice/storage/storage_wasm.go
@@ -16,26 +16,18 @@ package storage
import (
"fmt"
- "net/url"
"github.com/matrix-org/dendrite/appservice/storage/sqlite3"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
)
-func NewDatabase(
- dataSourceName string,
- dbProperties sqlutil.DbProperties, // nolint:unparam
-) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return nil, fmt.Errorf("Cannot use postgres implementation")
- }
- switch uri.Scheme {
- case "postgres":
- return nil, fmt.Errorf("Cannot use postgres implementation")
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
+func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return nil, fmt.Errorf("can't use Postgres implementation")
default:
- return nil, fmt.Errorf("Cannot use postgres implementation")
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/build/gobind/monolith.go b/build/gobind/monolith.go
index c0c0ccb4..9c3880b1 100644
--- a/build/gobind/monolith.go
+++ b/build/gobind/monolith.go
@@ -83,29 +83,29 @@ func (m *DendriteMonolith) Start() {
m.YggdrasilNode = ygg
cfg := &config.Dendrite{}
- cfg.SetDefaults()
- cfg.Matrix.ServerName = gomatrixserverlib.ServerName(ygg.DerivedServerName())
- cfg.Matrix.PrivateKey = ygg.SigningPrivateKey()
- cfg.Matrix.KeyID = gomatrixserverlib.KeyID(signing.KeyID)
- cfg.Matrix.FederationMaxRetries = 8
- cfg.Kafka.UseNaffka = true
- cfg.Kafka.Topics.OutputRoomEvent = "roomserverOutput"
- cfg.Kafka.Topics.OutputClientData = "clientapiOutput"
- cfg.Kafka.Topics.OutputTypingEvent = "typingServerOutput"
- cfg.Kafka.Topics.OutputSendToDeviceEvent = "sendToDeviceOutput"
- cfg.Database.Account = config.DataSource(fmt.Sprintf("file:%s/dendrite-account.db", m.StorageDirectory))
- cfg.Database.Device = config.DataSource(fmt.Sprintf("file:%s/dendrite-device.db", m.StorageDirectory))
- cfg.Database.MediaAPI = config.DataSource(fmt.Sprintf("file:%s/dendrite-mediaapi.db", m.StorageDirectory))
- cfg.Database.SyncAPI = config.DataSource(fmt.Sprintf("file:%s/dendrite-syncapi.db", m.StorageDirectory))
- cfg.Database.RoomServer = config.DataSource(fmt.Sprintf("file:%s/dendrite-roomserver.db", m.StorageDirectory))
- cfg.Database.ServerKey = config.DataSource(fmt.Sprintf("file:%s/dendrite-serverkey.db", m.StorageDirectory))
- cfg.Database.E2EKey = config.DataSource(fmt.Sprintf("file:%s/dendrite-keyserver.db", m.StorageDirectory))
- cfg.Database.FederationSender = config.DataSource(fmt.Sprintf("file:%s/dendrite-federationsender.db", m.StorageDirectory))
- cfg.Database.AppService = config.DataSource(fmt.Sprintf("file:%s/dendrite-appservice.db", m.StorageDirectory))
- cfg.Database.CurrentState = config.DataSource(fmt.Sprintf("file:%s/dendrite-currentstate.db", m.StorageDirectory))
- cfg.Database.Naffka = config.DataSource(fmt.Sprintf("file:%s/dendrite-naffka.db", m.StorageDirectory))
- cfg.Media.BasePath = config.Path(fmt.Sprintf("%s/tmp", m.StorageDirectory))
- cfg.Media.AbsBasePath = config.Path(fmt.Sprintf("%s/tmp", m.StorageDirectory))
+ cfg.Defaults()
+ cfg.Global.ServerName = gomatrixserverlib.ServerName(ygg.DerivedServerName())
+ cfg.Global.PrivateKey = ygg.SigningPrivateKey()
+ cfg.Global.KeyID = gomatrixserverlib.KeyID(signing.KeyID)
+ cfg.Global.Kafka.UseNaffka = true
+ cfg.Global.Kafka.Topics.OutputRoomEvent = "roomserverOutput"
+ cfg.Global.Kafka.Topics.OutputClientData = "clientapiOutput"
+ cfg.Global.Kafka.Topics.OutputTypingEvent = "typingServerOutput"
+ cfg.Global.Kafka.Topics.OutputSendToDeviceEvent = "sendToDeviceOutput"
+ cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-naffka.db", m.StorageDirectory))
+ cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-account.db", m.StorageDirectory))
+ cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-device.db", m.StorageDirectory))
+ cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-mediaapi.db", m.StorageDirectory))
+ cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-syncapi.db", m.StorageDirectory))
+ cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-roomserver.db", m.StorageDirectory))
+ cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-serverkey.db", m.StorageDirectory))
+ cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-keyserver.db", m.StorageDirectory))
+ cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-federationsender.db", m.StorageDirectory))
+ cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-appservice.db", m.StorageDirectory))
+ cfg.CurrentStateServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-currentstate.db", m.StorageDirectory))
+ cfg.MediaAPI.BasePath = config.Path(fmt.Sprintf("%s/tmp", m.StorageDirectory))
+ cfg.MediaAPI.AbsBasePath = config.Path(fmt.Sprintf("%s/tmp", m.StorageDirectory))
+ cfg.FederationSender.FederationMaxRetries = 8
if err = cfg.Derive(); err != nil {
panic(err)
}
@@ -119,8 +119,8 @@ func (m *DendriteMonolith) Start() {
serverKeyAPI := &signing.YggdrasilKeys{}
keyRing := serverKeyAPI.KeyRing()
- keyAPI := keyserver.NewInternalAPI(base.Cfg, federation, base.KafkaProducer)
- userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, cfg.Derived.ApplicationServices, keyAPI)
+ keyAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, federation, base.KafkaProducer)
+ userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Global.ServerName, cfg.Derived.ApplicationServices, keyAPI)
keyAPI.SetUserAPI(userAPI)
rsAPI := roomserver.NewInternalAPI(
@@ -132,7 +132,7 @@ func (m *DendriteMonolith) Start() {
)
asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
- stateAPI := currentstateserver.NewInternalAPI(base.Cfg, base.KafkaConsumer)
+ stateAPI := currentstateserver.NewInternalAPI(&base.Cfg.CurrentStateServer, base.KafkaConsumer)
fsAPI := federationsender.NewInternalAPI(
base, federation, rsAPI, stateAPI, keyRing,
)
@@ -180,7 +180,7 @@ func (m *DendriteMonolith) Start() {
base.BaseMux,
base.PublicAPIMux,
base.InternalAPIMux,
- cfg,
+ &cfg.Global,
base.UseHTTPAPIs,
)
diff --git a/clientapi/auth/password.go b/clientapi/auth/password.go
index f4814925..d9801955 100644
--- a/clientapi/auth/password.go
+++ b/clientapi/auth/password.go
@@ -35,7 +35,7 @@ type PasswordRequest struct {
// LoginTypePassword implements https://matrix.org/docs/spec/client_server/r0.6.1#password-based
type LoginTypePassword struct {
GetAccountByPassword GetAccountByPassword
- Config *config.Dendrite
+ Config *config.ClientAPI
}
func (t *LoginTypePassword) Name() string {
diff --git a/clientapi/auth/user_interactive.go b/clientapi/auth/user_interactive.go
index 581a85f0..c67eba15 100644
--- a/clientapi/auth/user_interactive.go
+++ b/clientapi/auth/user_interactive.go
@@ -110,7 +110,7 @@ type UserInteractive struct {
Sessions map[string][]string
}
-func NewUserInteractive(getAccByPass GetAccountByPassword, cfg *config.Dendrite) *UserInteractive {
+func NewUserInteractive(getAccByPass GetAccountByPassword, cfg *config.ClientAPI) *UserInteractive {
typePassword := &LoginTypePassword{
GetAccountByPassword: getAccByPass,
Config: cfg,
diff --git a/clientapi/auth/user_interactive_test.go b/clientapi/auth/user_interactive_test.go
index d12652c0..47d1cad3 100644
--- a/clientapi/auth/user_interactive_test.go
+++ b/clientapi/auth/user_interactive_test.go
@@ -33,8 +33,11 @@ func getAccountByPassword(ctx context.Context, localpart, plaintextPassword stri
}
func setup() *UserInteractive {
- cfg := &config.Dendrite{}
- cfg.Matrix.ServerName = serverName
+ cfg := &config.ClientAPI{
+ Matrix: &config.Global{
+ ServerName: serverName,
+ },
+ }
return NewUserInteractive(getAccountByPassword, cfg)
}
diff --git a/clientapi/clientapi.go b/clientapi/clientapi.go
index 9ed285a8..f3789521 100644
--- a/clientapi/clientapi.go
+++ b/clientapi/clientapi.go
@@ -37,7 +37,7 @@ import (
// AddPublicRoutes sets up and registers HTTP handlers for the ClientAPI component.
func AddPublicRoutes(
router *mux.Router,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
producer sarama.SyncProducer,
deviceDB devices.Database,
accountsDB accounts.Database,
@@ -54,7 +54,7 @@ func AddPublicRoutes(
) {
syncProducer := &producers.SyncAPIProducer{
Producer: producer,
- Topic: string(cfg.Kafka.Topics.OutputClientData),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputClientData),
}
routing.Setup(
diff --git a/clientapi/routing/auth_fallback.go b/clientapi/routing/auth_fallback.go
index b7f2cd6d..e639b101 100644
--- a/clientapi/routing/auth_fallback.go
+++ b/clientapi/routing/auth_fallback.go
@@ -101,7 +101,7 @@ func serveTemplate(w http.ResponseWriter, templateHTML string, data map[string]s
// AuthFallback implements GET and POST /auth/{authType}/fallback/web?session={sessionID}
func AuthFallback(
w http.ResponseWriter, req *http.Request, authType string,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
) *util.JSONResponse {
sessionID := req.URL.Query().Get("session")
@@ -116,7 +116,7 @@ func AuthFallback(
data := map[string]string{
"myUrl": req.URL.String(),
"session": sessionID,
- "siteKey": cfg.Matrix.RecaptchaPublicKey,
+ "siteKey": cfg.RecaptchaPublicKey,
}
serveTemplate(w, recaptchaTemplate, data)
}
@@ -181,11 +181,11 @@ func AuthFallback(
// checkRecaptchaEnabled creates an error response if recaptcha is not usable on homeserver.
func checkRecaptchaEnabled(
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
w http.ResponseWriter,
req *http.Request,
) *util.JSONResponse {
- if !cfg.Matrix.RecaptchaEnabled {
+ if !cfg.RecaptchaEnabled {
return writeHTTPMessage(w, req,
"Recaptcha login is disabled on this Homeserver",
http.StatusBadRequest,
diff --git a/clientapi/routing/createroom.go b/clientapi/routing/createroom.go
index 027a21e7..5412c222 100644
--- a/clientapi/routing/createroom.go
+++ b/clientapi/routing/createroom.go
@@ -135,7 +135,7 @@ type fledglingEvent struct {
// CreateRoom implements /createRoom
func CreateRoom(
req *http.Request, device *api.Device,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
accountDB accounts.Database, rsAPI roomserverAPI.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI,
) util.JSONResponse {
@@ -149,7 +149,7 @@ func CreateRoom(
// nolint: gocyclo
func createRoom(
req *http.Request, device *api.Device,
- cfg *config.Dendrite, roomID string,
+ cfg *config.ClientAPI, roomID string,
accountDB accounts.Database, rsAPI roomserverAPI.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI,
) util.JSONResponse {
@@ -438,7 +438,7 @@ func createRoom(
func buildEvent(
builder *gomatrixserverlib.EventBuilder,
provider gomatrixserverlib.AuthEventProvider,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
evTime time.Time,
roomVersion gomatrixserverlib.RoomVersion,
) (*gomatrixserverlib.Event, error) {
diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go
index 0f78f4a2..62f295fe 100644
--- a/clientapi/routing/directory.go
+++ b/clientapi/routing/directory.go
@@ -47,7 +47,7 @@ func DirectoryRoom(
req *http.Request,
roomAlias string,
federation *gomatrixserverlib.FederationClient,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
rsAPI roomserverAPI.RoomserverInternalAPI,
fedSenderAPI federationSenderAPI.FederationSenderInternalAPI,
) util.JSONResponse {
@@ -116,7 +116,7 @@ func SetLocalAlias(
req *http.Request,
device *api.Device,
alias string,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
aliasAPI roomserverAPI.RoomserverInternalAPI,
) util.JSONResponse {
_, domain, err := gomatrixserverlib.SplitID('#', alias)
@@ -139,6 +139,7 @@ func SetLocalAlias(
// TODO: This code should eventually be refactored with:
// 1. The new method for checking for things matching an AS's namespace
// 2. Using an overall Regex object for all AS's just like we did for usernames
+
for _, appservice := range cfg.Derived.ApplicationServices {
// Don't prevent AS from creating aliases in its own namespace
// Note that Dendrite uses SenderLocalpart as UserID for AS users
diff --git a/clientapi/routing/getevent.go b/clientapi/routing/getevent.go
index 2a51db73..c74509f0 100644
--- a/clientapi/routing/getevent.go
+++ b/clientapi/routing/getevent.go
@@ -30,7 +30,7 @@ type getEventRequest struct {
device *userapi.Device
roomID string
eventID string
- cfg *config.Dendrite
+ cfg *config.ClientAPI
federation *gomatrixserverlib.FederationClient
requestedEvent gomatrixserverlib.Event
}
@@ -42,7 +42,7 @@ func GetEvent(
device *userapi.Device,
roomID string,
eventID string,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
rsAPI api.RoomserverInternalAPI,
federation *gomatrixserverlib.FederationClient,
) util.JSONResponse {
diff --git a/clientapi/routing/login.go b/clientapi/routing/login.go
index 42f828f6..d2bc9337 100644
--- a/clientapi/routing/login.go
+++ b/clientapi/routing/login.go
@@ -58,7 +58,7 @@ func passwordLogin() flows {
// Login implements GET and POST /login
func Login(
req *http.Request, accountDB accounts.Database, userAPI userapi.UserInternalAPI,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
) util.JSONResponse {
if req.Method == http.MethodGet {
// TODO: support other forms of login other than password, depending on config options
diff --git a/clientapi/routing/membership.go b/clientapi/routing/membership.go
index 90ddb699..8303a68e 100644
--- a/clientapi/routing/membership.go
+++ b/clientapi/routing/membership.go
@@ -41,7 +41,7 @@ var errMissingUserID = errors.New("'user_id' must be supplied")
func SendBan(
req *http.Request, accountDB accounts.Database, device *userapi.Device,
- roomID string, cfg *config.Dendrite,
+ roomID string, cfg *config.ClientAPI,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
) util.JSONResponse {
body, evTime, roomVer, reqErr := extractRequestData(req, roomID, rsAPI)
@@ -52,7 +52,7 @@ func SendBan(
}
func sendMembership(ctx context.Context, accountDB accounts.Database, device *userapi.Device,
- roomID, membership, reason string, cfg *config.Dendrite, targetUserID string, evTime time.Time,
+ roomID, membership, reason string, cfg *config.ClientAPI, targetUserID string, evTime time.Time,
roomVer gomatrixserverlib.RoomVersion,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI) util.JSONResponse {
@@ -94,7 +94,7 @@ func sendMembership(ctx context.Context, accountDB accounts.Database, device *us
func SendKick(
req *http.Request, accountDB accounts.Database, device *userapi.Device,
- roomID string, cfg *config.Dendrite,
+ roomID string, cfg *config.ClientAPI,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
stateAPI currentstateAPI.CurrentStateInternalAPI,
) util.JSONResponse {
@@ -135,7 +135,7 @@ func SendKick(
func SendUnban(
req *http.Request, accountDB accounts.Database, device *userapi.Device,
- roomID string, cfg *config.Dendrite,
+ roomID string, cfg *config.ClientAPI,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
) util.JSONResponse {
body, evTime, roomVer, reqErr := extractRequestData(req, roomID, rsAPI)
@@ -170,7 +170,7 @@ func SendUnban(
func SendInvite(
req *http.Request, accountDB accounts.Database, device *userapi.Device,
- roomID string, cfg *config.Dendrite,
+ roomID string, cfg *config.ClientAPI,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
) util.JSONResponse {
body, evTime, roomVer, reqErr := extractRequestData(req, roomID, rsAPI)
@@ -236,7 +236,7 @@ func buildMembershipEvent(
targetUserID, reason string, accountDB accounts.Database,
device *userapi.Device,
membership, roomID string, isDirect bool,
- cfg *config.Dendrite, evTime time.Time,
+ cfg *config.ClientAPI, evTime time.Time,
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
) (*gomatrixserverlib.HeaderedEvent, error) {
profile, err := loadProfile(ctx, targetUserID, cfg, accountDB, asAPI)
@@ -263,7 +263,7 @@ func buildMembershipEvent(
return nil, err
}
- return eventutil.BuildEvent(ctx, &builder, cfg, evTime, rsAPI, nil)
+ return eventutil.BuildEvent(ctx, &builder, cfg.Matrix, evTime, rsAPI, nil)
}
// loadProfile lookups the profile of a given user from the database and returns
@@ -273,7 +273,7 @@ func buildMembershipEvent(
func loadProfile(
ctx context.Context,
userID string,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
accountDB accounts.Database,
asAPI appserviceAPI.AppServiceQueryAPI,
) (*authtypes.Profile, error) {
@@ -326,7 +326,7 @@ func checkAndProcessThreepid(
req *http.Request,
device *userapi.Device,
body *threepid.MembershipRequest,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
rsAPI roomserverAPI.RoomserverInternalAPI,
accountDB accounts.Database,
roomID string,
diff --git a/clientapi/routing/memberships.go b/clientapi/routing/memberships.go
index 9c4cf749..56059350 100644
--- a/clientapi/routing/memberships.go
+++ b/clientapi/routing/memberships.go
@@ -48,7 +48,7 @@ type joinedMember struct {
// GetMemberships implements GET /rooms/{roomId}/members
func GetMemberships(
req *http.Request, device *userapi.Device, roomID string, joinedOnly bool,
- _ *config.Dendrite,
+ _ *config.ClientAPI,
rsAPI api.RoomserverInternalAPI,
) util.JSONResponse {
queryReq := api.QueryMembershipsForRoomRequest{
diff --git a/clientapi/routing/profile.go b/clientapi/routing/profile.go
index 1df4c9b3..faf92451 100644
--- a/clientapi/routing/profile.go
+++ b/clientapi/routing/profile.go
@@ -37,7 +37,7 @@ import (
// GetProfile implements GET /profile/{userID}
func GetProfile(
- req *http.Request, accountDB accounts.Database, cfg *config.Dendrite,
+ req *http.Request, accountDB accounts.Database, cfg *config.ClientAPI,
userID string,
asAPI appserviceAPI.AppServiceQueryAPI,
federation *gomatrixserverlib.FederationClient,
@@ -66,7 +66,7 @@ func GetProfile(
// GetAvatarURL implements GET /profile/{userID}/avatar_url
func GetAvatarURL(
- req *http.Request, accountDB accounts.Database, cfg *config.Dendrite,
+ req *http.Request, accountDB accounts.Database, cfg *config.ClientAPI,
userID string, asAPI appserviceAPI.AppServiceQueryAPI,
federation *gomatrixserverlib.FederationClient,
) util.JSONResponse {
@@ -95,7 +95,7 @@ func GetAvatarURL(
// nolint:gocyclo
func SetAvatarURL(
req *http.Request, accountDB accounts.Database, stateAPI currentstateAPI.CurrentStateInternalAPI,
- device *userapi.Device, userID string, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI,
+ device *userapi.Device, userID string, cfg *config.ClientAPI, rsAPI api.RoomserverInternalAPI,
) util.JSONResponse {
if userID != device.UserID {
return util.JSONResponse{
@@ -184,7 +184,7 @@ func SetAvatarURL(
// GetDisplayName implements GET /profile/{userID}/displayname
func GetDisplayName(
- req *http.Request, accountDB accounts.Database, cfg *config.Dendrite,
+ req *http.Request, accountDB accounts.Database, cfg *config.ClientAPI,
userID string, asAPI appserviceAPI.AppServiceQueryAPI,
federation *gomatrixserverlib.FederationClient,
) util.JSONResponse {
@@ -213,7 +213,7 @@ func GetDisplayName(
// nolint:gocyclo
func SetDisplayName(
req *http.Request, accountDB accounts.Database, stateAPI currentstateAPI.CurrentStateInternalAPI,
- device *userapi.Device, userID string, cfg *config.Dendrite, rsAPI api.RoomserverInternalAPI,
+ device *userapi.Device, userID string, cfg *config.ClientAPI, rsAPI api.RoomserverInternalAPI,
) util.JSONResponse {
if userID != device.UserID {
return util.JSONResponse{
@@ -305,7 +305,7 @@ func SetDisplayName(
// Returns an error when something goes wrong or specifically
// eventutil.ErrProfileNoExists when the profile doesn't exist.
func getProfile(
- ctx context.Context, accountDB accounts.Database, cfg *config.Dendrite,
+ ctx context.Context, accountDB accounts.Database, cfg *config.ClientAPI,
userID string,
asAPI appserviceAPI.AppServiceQueryAPI,
federation *gomatrixserverlib.FederationClient,
@@ -345,7 +345,7 @@ func getProfile(
func buildMembershipEvents(
ctx context.Context,
roomIDs []string,
- newProfile authtypes.Profile, userID string, cfg *config.Dendrite,
+ newProfile authtypes.Profile, userID string, cfg *config.ClientAPI,
evTime time.Time, rsAPI api.RoomserverInternalAPI,
) ([]gomatrixserverlib.HeaderedEvent, error) {
evs := []gomatrixserverlib.HeaderedEvent{}
@@ -375,7 +375,7 @@ func buildMembershipEvents(
return nil, err
}
- event, err := eventutil.BuildEvent(ctx, &builder, cfg, evTime, rsAPI, nil)
+ event, err := eventutil.BuildEvent(ctx, &builder, cfg.Matrix, evTime, rsAPI, nil)
if err != nil {
return nil, err
}
diff --git a/clientapi/routing/redaction.go b/clientapi/routing/redaction.go
index fd80e0ab..bb526513 100644
--- a/clientapi/routing/redaction.go
+++ b/clientapi/routing/redaction.go
@@ -40,7 +40,7 @@ type redactionResponse struct {
}
func SendRedaction(
- req *http.Request, device *userapi.Device, roomID, eventID string, cfg *config.Dendrite,
+ req *http.Request, device *userapi.Device, roomID, eventID string, cfg *config.ClientAPI,
rsAPI roomserverAPI.RoomserverInternalAPI, stateAPI currentstateAPI.CurrentStateInternalAPI,
) util.JSONResponse {
resErr := checkMemberInRoom(req.Context(), stateAPI, device.UserID, roomID)
@@ -115,7 +115,7 @@ func SendRedaction(
}
var queryRes api.QueryLatestEventsAndStateResponse
- e, err := eventutil.BuildEvent(req.Context(), &builder, cfg, time.Now(), rsAPI, &queryRes)
+ e, err := eventutil.BuildEvent(req.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
return util.JSONResponse{
Code: http.StatusNotFound,
diff --git a/clientapi/routing/register.go b/clientapi/routing/register.go
index 69ebdfd7..937abc83 100644
--- a/clientapi/routing/register.go
+++ b/clientapi/routing/register.go
@@ -255,11 +255,11 @@ func validatePassword(password string) *util.JSONResponse {
// validateRecaptcha returns an error response if the captcha response is invalid
func validateRecaptcha(
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
response string,
clientip string,
) *util.JSONResponse {
- if !cfg.Matrix.RecaptchaEnabled {
+ if !cfg.RecaptchaEnabled {
return &util.JSONResponse{
Code: http.StatusConflict,
JSON: jsonerror.Unknown("Captcha registration is disabled"),
@@ -274,9 +274,9 @@ func validateRecaptcha(
}
// Make a POST request to Google's API to check the captcha response
- resp, err := http.PostForm(cfg.Matrix.RecaptchaSiteVerifyAPI,
+ resp, err := http.PostForm(cfg.RecaptchaSiteVerifyAPI,
url.Values{
- "secret": {cfg.Matrix.RecaptchaPrivateKey},
+ "secret": {cfg.RecaptchaPrivateKey},
"response": {response},
"remoteip": {clientip},
},
@@ -324,7 +324,7 @@ func validateRecaptcha(
// Application Service is given, it will check to see if it matches any
// Application Service's namespace.
func UserIDIsWithinApplicationServiceNamespace(
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
userID string,
appservice *config.ApplicationService,
) bool {
@@ -354,7 +354,7 @@ func UserIDIsWithinApplicationServiceNamespace(
// UsernameMatchesMultipleExclusiveNamespaces will check if a given username matches
// more than one exclusive namespace. More than one is not allowed
func UsernameMatchesMultipleExclusiveNamespaces(
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
username string,
) bool {
userID := userutil.MakeUserID(username, cfg.Matrix.ServerName)
@@ -374,7 +374,7 @@ func UsernameMatchesMultipleExclusiveNamespaces(
// UsernameMatchesExclusiveNamespaces will check if a given username matches any
// application service's exclusive users namespace
func UsernameMatchesExclusiveNamespaces(
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
username string,
) bool {
userID := userutil.MakeUserID(username, cfg.Matrix.ServerName)
@@ -386,7 +386,7 @@ func UsernameMatchesExclusiveNamespaces(
// username is within that application service's namespace. As long as these
// two requirements are met, no error will be returned.
func validateApplicationService(
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
username string,
accessToken string,
) (string, *util.JSONResponse) {
@@ -442,7 +442,7 @@ func Register(
req *http.Request,
userAPI userapi.UserInternalAPI,
accountDB accounts.Database,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
) util.JSONResponse {
var r registerRequest
resErr := httputil.UnmarshalJSONRequest(req, &r)
@@ -512,7 +512,7 @@ func Register(
func handleGuestRegistration(
req *http.Request,
r registerRequest,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
userAPI userapi.UserInternalAPI,
) util.JSONResponse {
var res userapi.PerformAccountCreationResponse
@@ -568,7 +568,7 @@ func handleRegistrationFlow(
req *http.Request,
r registerRequest,
sessionID string,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
userAPI userapi.UserInternalAPI,
) util.JSONResponse {
// TODO: Shared secret registration (create new user scripts)
@@ -580,7 +580,7 @@ func handleRegistrationFlow(
// TODO: email / msisdn auth types.
- if cfg.Matrix.RegistrationDisabled && r.Auth.Type != authtypes.LoginTypeSharedSecret {
+ if cfg.RegistrationDisabled && r.Auth.Type != authtypes.LoginTypeSharedSecret {
return util.MessageResponse(http.StatusForbidden, "Registration has been disabled")
}
@@ -666,7 +666,7 @@ func handleApplicationServiceRegistration(
tokenErr error,
req *http.Request,
r registerRequest,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
userAPI userapi.UserInternalAPI,
) util.JSONResponse {
// Check if we previously had issues extracting the access token from the
@@ -704,7 +704,7 @@ func checkAndCompleteFlow(
req *http.Request,
r registerRequest,
sessionID string,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
userAPI userapi.UserInternalAPI,
) util.JSONResponse {
if checkFlowCompleted(flow, cfg.Derived.Registration.Flows) {
@@ -728,7 +728,7 @@ func checkAndCompleteFlow(
func LegacyRegister(
req *http.Request,
userAPI userapi.UserInternalAPI,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
) util.JSONResponse {
var r legacyRegisterRequest
resErr := parseAndValidateLegacyLogin(req, &r)
@@ -742,13 +742,13 @@ func LegacyRegister(
"auth.type": r.Type,
}).Info("Processing registration request")
- if cfg.Matrix.RegistrationDisabled && r.Type != authtypes.LoginTypeSharedSecret {
+ if cfg.RegistrationDisabled && r.Type != authtypes.LoginTypeSharedSecret {
return util.MessageResponse(http.StatusForbidden, "Registration has been disabled")
}
switch r.Type {
case authtypes.LoginTypeSharedSecret:
- if cfg.Matrix.RegistrationSharedSecret == "" {
+ if cfg.RegistrationSharedSecret == "" {
return util.MessageResponse(http.StatusBadRequest, "Shared secret registration is disabled")
}
@@ -902,15 +902,15 @@ func completeRegistration(
// Used for shared secret registration.
// Checks if the username, password and isAdmin flag matches the given mac.
func isValidMacLogin(
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
username, password string,
isAdmin bool,
givenMac []byte,
) (bool, error) {
- sharedSecret := cfg.Matrix.RegistrationSharedSecret
+ sharedSecret := cfg.RegistrationSharedSecret
// Check that shared secret registration isn't disabled.
- if cfg.Matrix.RegistrationSharedSecret == "" {
+ if cfg.RegistrationSharedSecret == "" {
return false, errors.New("Shared secret registration is disabled")
}
@@ -1001,7 +1001,7 @@ type availableResponse struct {
// RegisterAvailable checks if the username is already taken or invalid.
func RegisterAvailable(
req *http.Request,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
accountDB accounts.Database,
) util.JSONResponse {
username := req.URL.Query().Get("username")
diff --git a/clientapi/routing/register_test.go b/clientapi/routing/register_test.go
index a44389f9..0a91ae0f 100644
--- a/clientapi/routing/register_test.go
+++ b/clientapi/routing/register_test.go
@@ -179,30 +179,31 @@ func TestValidationOfApplicationServices(t *testing.T) {
}
// Set up a config
- fakeConfig := config.Dendrite{}
- fakeConfig.Matrix.ServerName = "localhost"
- fakeConfig.Derived.ApplicationServices = []config.ApplicationService{fakeApplicationService}
+ fakeConfig := &config.Dendrite{}
+ fakeConfig.Defaults()
+ fakeConfig.Global.ServerName = "localhost"
+ fakeConfig.ClientAPI.Derived.ApplicationServices = []config.ApplicationService{fakeApplicationService}
// Access token is correct, user_id omitted so we are acting as SenderLocalpart
- asID, resp := validateApplicationService(&fakeConfig, fakeSenderLocalpart, "1234")
+ asID, resp := validateApplicationService(&fakeConfig.ClientAPI, fakeSenderLocalpart, "1234")
if resp != nil || asID != fakeID {
t.Errorf("appservice should have validated and returned correct ID: %s", resp.JSON)
}
// Access token is incorrect, user_id omitted so we are acting as SenderLocalpart
- asID, resp = validateApplicationService(&fakeConfig, fakeSenderLocalpart, "xxxx")
+ asID, resp = validateApplicationService(&fakeConfig.ClientAPI, fakeSenderLocalpart, "xxxx")
if resp == nil || asID == fakeID {
t.Errorf("access_token should have been marked as invalid")
}
// Access token is correct, acting as valid user_id
- asID, resp = validateApplicationService(&fakeConfig, "_appservice_bob", "1234")
+ asID, resp = validateApplicationService(&fakeConfig.ClientAPI, "_appservice_bob", "1234")
if resp != nil || asID != fakeID {
t.Errorf("access_token and user_id should've been valid: %s", resp.JSON)
}
// Access token is correct, acting as invalid user_id
- asID, resp = validateApplicationService(&fakeConfig, "_something_else", "1234")
+ asID, resp = validateApplicationService(&fakeConfig.ClientAPI, "_something_else", "1234")
if resp == nil || asID == fakeID {
t.Errorf("user_id should not have been valid: @_something_else:localhost")
}
diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go
index 0e58129e..883b473b 100644
--- a/clientapi/routing/routing.go
+++ b/clientapi/routing/routing.go
@@ -51,7 +51,7 @@ const pathPrefixUnstable = "/client/unstable"
// applied:
// nolint: gocyclo
func Setup(
- publicAPIMux *mux.Router, cfg *config.Dendrite,
+ publicAPIMux *mux.Router, cfg *config.ClientAPI,
eduAPI eduServerAPI.EDUServerInputAPI,
rsAPI roomserverAPI.RoomserverInternalAPI,
asAPI appserviceAPI.AppServiceQueryAPI,
diff --git a/clientapi/routing/sendevent.go b/clientapi/routing/sendevent.go
index bf32992f..e0cd7eb5 100644
--- a/clientapi/routing/sendevent.go
+++ b/clientapi/routing/sendevent.go
@@ -43,7 +43,7 @@ func SendEvent(
req *http.Request,
device *userapi.Device,
roomID, eventType string, txnID, stateKey *string,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
rsAPI api.RoomserverInternalAPI,
txnCache *transactions.Cache,
) util.JSONResponse {
@@ -112,7 +112,7 @@ func generateSendEvent(
req *http.Request,
device *userapi.Device,
roomID, eventType string, stateKey *string,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
rsAPI api.RoomserverInternalAPI,
) (*gomatrixserverlib.Event, *util.JSONResponse) {
// parse the incoming http request
@@ -146,7 +146,7 @@ func generateSendEvent(
}
var queryRes api.QueryLatestEventsAndStateResponse
- e, err := eventutil.BuildEvent(req.Context(), &builder, cfg, evTime, rsAPI, &queryRes)
+ e, err := eventutil.BuildEvent(req.Context(), &builder, cfg.Matrix, evTime, rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
return nil, &util.JSONResponse{
Code: http.StatusNotFound,
diff --git a/clientapi/routing/threepid.go b/clientapi/routing/threepid.go
index e7aaadf5..54ffa53f 100644
--- a/clientapi/routing/threepid.go
+++ b/clientapi/routing/threepid.go
@@ -40,7 +40,7 @@ type threePIDsResponse struct {
// RequestEmailToken implements:
// POST /account/3pid/email/requestToken
// POST /register/email/requestToken
-func RequestEmailToken(req *http.Request, accountDB accounts.Database, cfg *config.Dendrite) util.JSONResponse {
+func RequestEmailToken(req *http.Request, accountDB accounts.Database, cfg *config.ClientAPI) util.JSONResponse {
var body threepid.EmailAssociationRequest
if reqErr := httputil.UnmarshalJSONRequest(req, &body); reqErr != nil {
return *reqErr
@@ -86,7 +86,7 @@ func RequestEmailToken(req *http.Request, accountDB accounts.Database, cfg *conf
// CheckAndSave3PIDAssociation implements POST /account/3pid
func CheckAndSave3PIDAssociation(
req *http.Request, accountDB accounts.Database, device *api.Device,
- cfg *config.Dendrite,
+ cfg *config.ClientAPI,
) util.JSONResponse {
var body threepid.EmailAssociationCheckRequest
if reqErr := httputil.UnmarshalJSONRequest(req, &body); reqErr != nil {
diff --git a/clientapi/routing/voip.go b/clientapi/routing/voip.go
index 046e8781..536c69fb 100644
--- a/clientapi/routing/voip.go
+++ b/clientapi/routing/voip.go
@@ -31,7 +31,7 @@ import (
// RequestTurnServer implements:
// GET /voip/turnServer
-func RequestTurnServer(req *http.Request, device *api.Device, cfg *config.Dendrite) util.JSONResponse {
+func RequestTurnServer(req *http.Request, device *api.Device, cfg *config.ClientAPI) util.JSONResponse {
turnConfig := cfg.TURN
// TODO Guest Support
diff --git a/clientapi/threepid/invites.go b/clientapi/threepid/invites.go
index 89bc8606..f1d54a47 100644
--- a/clientapi/threepid/invites.go
+++ b/clientapi/threepid/invites.go
@@ -86,7 +86,7 @@ var (
// can be emitted.
func CheckAndProcessInvite(
ctx context.Context,
- device *userapi.Device, body *MembershipRequest, cfg *config.Dendrite,
+ device *userapi.Device, body *MembershipRequest, cfg *config.ClientAPI,
rsAPI api.RoomserverInternalAPI, db accounts.Database,
roomID string,
evTime time.Time,
@@ -137,7 +137,7 @@ func CheckAndProcessInvite(
// Returns an error if a check or a request failed.
func queryIDServer(
ctx context.Context,
- db accounts.Database, cfg *config.Dendrite, device *userapi.Device,
+ db accounts.Database, cfg *config.ClientAPI, device *userapi.Device,
body *MembershipRequest, roomID string,
) (lookupRes *idServerLookupResponse, storeInviteRes *idServerStoreInviteResponse, err error) {
if err = isTrusted(body.IDServer, cfg); err != nil {
@@ -206,7 +206,7 @@ func queryIDServerLookup(ctx context.Context, body *MembershipRequest) (*idServe
// Returns an error if the request failed to send or if the response couldn't be parsed.
func queryIDServerStoreInvite(
ctx context.Context,
- db accounts.Database, cfg *config.Dendrite, device *userapi.Device,
+ db accounts.Database, cfg *config.ClientAPI, device *userapi.Device,
body *MembershipRequest, roomID string,
) (*idServerStoreInviteResponse, error) {
// Retrieve the sender's profile to get their display name
@@ -330,7 +330,7 @@ func checkIDServerSignatures(
func emit3PIDInviteEvent(
ctx context.Context,
body *MembershipRequest, res *idServerStoreInviteResponse,
- device *userapi.Device, roomID string, cfg *config.Dendrite,
+ device *userapi.Device, roomID string, cfg *config.ClientAPI,
rsAPI api.RoomserverInternalAPI,
evTime time.Time,
) error {
@@ -354,7 +354,7 @@ func emit3PIDInviteEvent(
}
queryRes := api.QueryLatestEventsAndStateResponse{}
- event, err := eventutil.BuildEvent(ctx, builder, cfg, evTime, rsAPI, &queryRes)
+ event, err := eventutil.BuildEvent(ctx, builder, cfg.Matrix, evTime, rsAPI, &queryRes)
if err != nil {
return err
}
diff --git a/clientapi/threepid/threepid.go b/clientapi/threepid/threepid.go
index bffe31ad..40fd161d 100644
--- a/clientapi/threepid/threepid.go
+++ b/clientapi/threepid/threepid.go
@@ -53,7 +53,7 @@ type Credentials struct {
// Returns an error if there was a problem sending the request or decoding the
// response, or if the identity server responded with a non-OK status.
func CreateSession(
- ctx context.Context, req EmailAssociationRequest, cfg *config.Dendrite,
+ ctx context.Context, req EmailAssociationRequest, cfg *config.ClientAPI,
) (string, error) {
if err := isTrusted(req.IDServer, cfg); err != nil {
return "", err
@@ -101,7 +101,7 @@ func CreateSession(
// Returns an error if there was a problem sending the request or decoding the
// response, or if the identity server responded with a non-OK status.
func CheckAssociation(
- ctx context.Context, creds Credentials, cfg *config.Dendrite,
+ ctx context.Context, creds Credentials, cfg *config.ClientAPI,
) (bool, string, string, error) {
if err := isTrusted(creds.IDServer, cfg); err != nil {
return false, "", "", err
@@ -142,7 +142,7 @@ func CheckAssociation(
// identifier and a Matrix ID.
// Returns an error if there was a problem sending the request or decoding the
// response, or if the identity server responded with a non-OK status.
-func PublishAssociation(creds Credentials, userID string, cfg *config.Dendrite) error {
+func PublishAssociation(creds Credentials, userID string, cfg *config.ClientAPI) error {
if err := isTrusted(creds.IDServer, cfg); err != nil {
return err
}
@@ -177,7 +177,7 @@ func PublishAssociation(creds Credentials, userID string, cfg *config.Dendrite)
// isTrusted checks if a given identity server is part of the list of trusted
// identity servers in the configuration file.
// Returns an error if the server isn't trusted.
-func isTrusted(idServer string, cfg *config.Dendrite) error {
+func isTrusted(idServer string, cfg *config.ClientAPI) error {
for _, server := range cfg.Matrix.TrustedIDServers {
if idServer == server {
return nil
diff --git a/cmd/create-account/main.go b/cmd/create-account/main.go
index ff022ec3..73e223d6 100644
--- a/cmd/create-account/main.go
+++ b/cmd/create-account/main.go
@@ -20,6 +20,7 @@ import (
"fmt"
"os"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/userapi/storage/accounts"
"github.com/matrix-org/dendrite/userapi/storage/devices"
"github.com/matrix-org/gomatrixserverlib"
@@ -63,7 +64,9 @@ func main() {
serverName := gomatrixserverlib.ServerName(*serverNameStr)
- accountDB, err := accounts.NewDatabase(*database, nil, serverName)
+ accountDB, err := accounts.NewDatabase(&config.DatabaseOptions{
+ ConnectionString: config.DataSource(*database),
+ }, serverName)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
@@ -75,7 +78,9 @@ func main() {
os.Exit(1)
}
- deviceDB, err := devices.NewDatabase(*database, nil, serverName)
+ deviceDB, err := devices.NewDatabase(&config.DatabaseOptions{
+ ConnectionString: config.DataSource(*database),
+ }, serverName)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
diff --git a/cmd/dendrite-appservice-server/main.go b/cmd/dendrite-appservice-server/main.go
index 6719d047..632b45e6 100644
--- a/cmd/dendrite-appservice-server/main.go
+++ b/cmd/dendrite-appservice-server/main.go
@@ -30,6 +30,6 @@ func main() {
intAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
appservice.AddInternalRoutes(base.InternalAPIMux, intAPI)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.AppServiceAPI), string(base.Cfg.Listen.AppServiceAPI))
+ base.SetupAndServeHTTP(string(base.Cfg.AppServiceAPI.Bind), string(base.Cfg.AppServiceAPI.Listen))
}
diff --git a/cmd/dendrite-client-api-server/main.go b/cmd/dendrite-client-api-server/main.go
index 367f27d1..2b6c39b6 100644
--- a/cmd/dendrite-client-api-server/main.go
+++ b/cmd/dendrite-client-api-server/main.go
@@ -39,10 +39,10 @@ func main() {
keyAPI := base.KeyServerHTTPClient()
clientapi.AddPublicRoutes(
- base.PublicAPIMux, base.Cfg, base.KafkaProducer, deviceDB, accountDB, federation,
+ base.PublicAPIMux, &base.Cfg.ClientAPI, base.KafkaProducer, deviceDB, accountDB, federation,
rsAPI, eduInputAPI, asQuery, stateAPI, transactions.New(), fsAPI, userAPI, keyAPI, nil,
)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.ClientAPI), string(base.Cfg.Listen.ClientAPI))
+ base.SetupAndServeHTTP(string(base.Cfg.ClientAPI.Bind), string(base.Cfg.ClientAPI.Listen))
}
diff --git a/cmd/dendrite-current-state-server/main.go b/cmd/dendrite-current-state-server/main.go
index 0d4eae7b..a8c0813f 100644
--- a/cmd/dendrite-current-state-server/main.go
+++ b/cmd/dendrite-current-state-server/main.go
@@ -24,10 +24,10 @@ func main() {
base := setup.NewBaseDendrite(cfg, "CurrentStateServer", true)
defer base.Close() // nolint: errcheck
- stateAPI := currentstateserver.NewInternalAPI(cfg, base.KafkaConsumer)
+ stateAPI := currentstateserver.NewInternalAPI(&cfg.CurrentStateServer, base.KafkaConsumer)
currentstateserver.AddInternalRoutes(base.InternalAPIMux, stateAPI)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.CurrentState), string(base.Cfg.Listen.CurrentState))
+ base.SetupAndServeHTTP(string(base.Cfg.CurrentStateServer.Bind), string(base.Cfg.CurrentStateServer.Listen))
}
diff --git a/cmd/dendrite-demo-libp2p/main.go b/cmd/dendrite-demo-libp2p/main.go
index 93d54f21..8c28014a 100644
--- a/cmd/dendrite-demo-libp2p/main.go
+++ b/cmd/dendrite-demo-libp2p/main.go
@@ -75,8 +75,8 @@ func createFederationClient(
p2phttp.NewTransport(base.LibP2P, p2phttp.ProtocolOption("/matrix")),
)
return gomatrixserverlib.NewFederationClientWithTransport(
- base.Base.Cfg.Matrix.ServerName, base.Base.Cfg.Matrix.KeyID,
- base.Base.Cfg.Matrix.PrivateKey, true, tr,
+ base.Base.Cfg.Global.ServerName, base.Base.Cfg.Global.KeyID,
+ base.Base.Cfg.Global.PrivateKey, true, tr,
)
}
@@ -113,25 +113,28 @@ func main() {
}
cfg := config.Dendrite{}
- cfg.SetDefaults()
- cfg.Matrix.ServerName = "p2p"
- cfg.Matrix.PrivateKey = privKey
- cfg.Matrix.KeyID = gomatrixserverlib.KeyID(fmt.Sprintf("ed25519:%s", *instanceName))
- cfg.Kafka.UseNaffka = true
- cfg.Kafka.Topics.OutputRoomEvent = "roomserverOutput"
- cfg.Kafka.Topics.OutputClientData = "clientapiOutput"
- cfg.Kafka.Topics.OutputTypingEvent = "typingServerOutput"
- cfg.Database.Account = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName))
- cfg.Database.Device = config.DataSource(fmt.Sprintf("file:%s-device.db", *instanceName))
- cfg.Database.MediaAPI = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName))
- cfg.Database.SyncAPI = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName))
- cfg.Database.RoomServer = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName))
- cfg.Database.ServerKey = config.DataSource(fmt.Sprintf("file:%s-serverkey.db", *instanceName))
- cfg.Database.FederationSender = config.DataSource(fmt.Sprintf("file:%s-federationsender.db", *instanceName))
- cfg.Database.AppService = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
- cfg.Database.Naffka = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName))
- cfg.Database.CurrentState = config.DataSource(fmt.Sprintf("file:%s-currentstate.db", *instanceName))
- cfg.Database.E2EKey = config.DataSource(fmt.Sprintf("file:%s-e2ekey.db", *instanceName))
+ cfg.Defaults()
+ cfg.Global.ServerName = "p2p"
+ cfg.Global.PrivateKey = privKey
+ cfg.Global.KeyID = gomatrixserverlib.KeyID(fmt.Sprintf("ed25519:%s", *instanceName))
+ cfg.Global.Kafka.UseNaffka = true
+ cfg.Global.Kafka.Topics.OutputRoomEvent = "roomserverOutput"
+ cfg.Global.Kafka.Topics.OutputClientData = "clientapiOutput"
+ cfg.Global.Kafka.Topics.OutputTypingEvent = "typingServerOutput"
+ cfg.Global.Kafka.Topics.OutputSendToDeviceEvent = "sendToDeviceOutput"
+ cfg.Global.Kafka.Topics.OutputKeyChangeEvent = "keyChangeOutput"
+ cfg.FederationSender.FederationMaxRetries = 6
+ cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName))
+ cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-device.db", *instanceName))
+ cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName))
+ cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName))
+ cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName))
+ cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-serverkey.db", *instanceName))
+ cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationsender.db", *instanceName))
+ cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
+ cfg.CurrentStateServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-currentstate.db", *instanceName))
+ cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName))
+ cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-e2ekey.db", *instanceName))
if err = cfg.Derive(); err != nil {
panic(err)
}
@@ -142,19 +145,19 @@ func main() {
accountDB := base.Base.CreateAccountsDB()
deviceDB := base.Base.CreateDeviceDB()
federation := createFederationClient(base)
- keyAPI := keyserver.NewInternalAPI(base.Base.Cfg, federation, base.Base.KafkaProducer)
- userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, nil, keyAPI)
+ keyAPI := keyserver.NewInternalAPI(&base.Base.Cfg.KeyServer, federation, base.Base.KafkaProducer)
+ userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Global.ServerName, nil, keyAPI)
keyAPI.SetUserAPI(userAPI)
serverKeyAPI := serverkeyapi.NewInternalAPI(
- base.Base.Cfg, federation, base.Base.Caches,
+ &base.Base.Cfg.ServerKeyAPI, federation, base.Base.Caches,
)
keyRing := serverKeyAPI.KeyRing()
createKeyDB(
base, serverKeyAPI,
)
- stateAPI := currentstateserver.NewInternalAPI(base.Base.Cfg, base.Base.KafkaConsumer)
+ stateAPI := currentstateserver.NewInternalAPI(&base.Base.Cfg.CurrentStateServer, base.Base.KafkaConsumer)
rsAPI := roomserver.NewInternalAPI(
&base.Base, keyRing, federation,
)
@@ -198,7 +201,7 @@ func main() {
base.Base.BaseMux,
base.Base.PublicAPIMux,
base.Base.InternalAPIMux,
- &cfg,
+ &cfg.Global,
base.Base.UseHTTPAPIs,
)
diff --git a/cmd/dendrite-demo-libp2p/p2pdendrite.go b/cmd/dendrite-demo-libp2p/p2pdendrite.go
index 4270143f..8fff46af 100644
--- a/cmd/dendrite-demo-libp2p/p2pdendrite.go
+++ b/cmd/dendrite-demo-libp2p/p2pdendrite.go
@@ -58,7 +58,7 @@ func NewP2PDendrite(cfg *config.Dendrite, componentName string) *P2PDendrite {
ctx, cancel := context.WithCancel(context.Background())
- privKey, err := crypto.UnmarshalEd25519PrivateKey(cfg.Matrix.PrivateKey[:])
+ privKey, err := crypto.UnmarshalEd25519PrivateKey(cfg.Global.PrivateKey[:])
if err != nil {
panic(err)
}
@@ -97,7 +97,7 @@ func NewP2PDendrite(cfg *config.Dendrite, componentName string) *P2PDendrite {
fmt.Println("Our node ID:", libp2p.ID())
fmt.Println("Our addresses:", libp2p.Addrs())
- cfg.Matrix.ServerName = gomatrixserverlib.ServerName(libp2p.ID().String())
+ cfg.Global.ServerName = gomatrixserverlib.ServerName(libp2p.ID().String())
return &P2PDendrite{
Base: *baseDendrite,
diff --git a/cmd/dendrite-demo-yggdrasil/main.go b/cmd/dendrite-demo-yggdrasil/main.go
index 81bf994b..cf4c7735 100644
--- a/cmd/dendrite-demo-yggdrasil/main.go
+++ b/cmd/dendrite-demo-yggdrasil/main.go
@@ -68,27 +68,28 @@ func main() {
}
cfg := &config.Dendrite{}
- cfg.SetDefaults()
- cfg.Matrix.ServerName = gomatrixserverlib.ServerName(ygg.DerivedServerName())
- cfg.Matrix.PrivateKey = ygg.SigningPrivateKey()
- cfg.Matrix.KeyID = gomatrixserverlib.KeyID(signing.KeyID)
- cfg.Matrix.FederationMaxRetries = 8
- cfg.Kafka.UseNaffka = true
- cfg.Kafka.Topics.OutputRoomEvent = "roomserverOutput"
- cfg.Kafka.Topics.OutputClientData = "clientapiOutput"
- cfg.Kafka.Topics.OutputTypingEvent = "typingServerOutput"
- cfg.Database.Account = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName))
- cfg.Database.Device = config.DataSource(fmt.Sprintf("file:%s-device.db", *instanceName))
- cfg.Database.MediaAPI = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName))
- cfg.Database.SyncAPI = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName))
- cfg.Database.RoomServer = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName))
- cfg.Database.ServerKey = config.DataSource(fmt.Sprintf("file:%s-serverkey.db", *instanceName))
- cfg.Database.E2EKey = config.DataSource(fmt.Sprintf("file:%s-keyserver.db", *instanceName))
- cfg.Database.FederationSender = config.DataSource(fmt.Sprintf("file:%s-federationsender.db", *instanceName))
- cfg.Database.AppService = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
- cfg.Database.CurrentState = config.DataSource(fmt.Sprintf("file:%s-currentstate.db", *instanceName))
- cfg.Database.Naffka = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName))
- cfg.Database.E2EKey = config.DataSource(fmt.Sprintf("file:%s-e2ekey.db", *instanceName))
+ cfg.Defaults()
+ cfg.Global.ServerName = gomatrixserverlib.ServerName(ygg.DerivedServerName())
+ cfg.Global.PrivateKey = ygg.SigningPrivateKey()
+ cfg.Global.KeyID = gomatrixserverlib.KeyID(signing.KeyID)
+ cfg.Global.Kafka.UseNaffka = true
+ cfg.Global.Kafka.Topics.OutputRoomEvent = "roomserverOutput"
+ cfg.Global.Kafka.Topics.OutputClientData = "clientapiOutput"
+ cfg.Global.Kafka.Topics.OutputTypingEvent = "typingServerOutput"
+ cfg.Global.Kafka.Topics.OutputSendToDeviceEvent = "sendToDeviceOutput"
+ cfg.Global.Kafka.Topics.OutputKeyChangeEvent = "keyChangeOutput"
+ cfg.FederationSender.FederationMaxRetries = 8
+ cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName))
+ cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-device.db", *instanceName))
+ cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName))
+ cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName))
+ cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName))
+ cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-serverkey.db", *instanceName))
+ cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-keyserver.db", *instanceName))
+ cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationsender.db", *instanceName))
+ cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
+ cfg.CurrentStateServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-currentstate.db", *instanceName))
+ cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName))
if err = cfg.Derive(); err != nil {
panic(err)
}
@@ -103,8 +104,8 @@ func main() {
serverKeyAPI := &signing.YggdrasilKeys{}
keyRing := serverKeyAPI.KeyRing()
- keyAPI := keyserver.NewInternalAPI(base.Cfg, federation, base.KafkaProducer)
- userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, nil, keyAPI)
+ keyAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, federation, base.KafkaProducer)
+ userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Global.ServerName, nil, keyAPI)
keyAPI.SetUserAPI(userAPI)
rsComponent := roomserver.NewInternalAPI(
@@ -117,7 +118,7 @@ func main() {
)
asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
- stateAPI := currentstateserver.NewInternalAPI(base.Cfg, base.KafkaConsumer)
+ stateAPI := currentstateserver.NewInternalAPI(&base.Cfg.CurrentStateServer, base.KafkaConsumer)
fsAPI := federationsender.NewInternalAPI(
base, federation, rsAPI, stateAPI, keyRing,
)
@@ -155,7 +156,6 @@ func main() {
UserAPI: userAPI,
StateAPI: stateAPI,
KeyAPI: keyAPI,
- //ServerKeyAPI: serverKeyAPI,
ExtPublicRoomsProvider: yggrooms.NewYggdrasilRoomProvider(
ygg, fsAPI, federation,
),
@@ -166,7 +166,7 @@ func main() {
base.BaseMux,
base.PublicAPIMux,
base.InternalAPIMux,
- cfg,
+ &cfg.Global,
base.UseHTTPAPIs,
)
diff --git a/cmd/dendrite-demo-yggdrasil/yggconn/client.go b/cmd/dendrite-demo-yggdrasil/yggconn/client.go
index 9cb6f975..1236c553 100644
--- a/cmd/dendrite-demo-yggdrasil/yggconn/client.go
+++ b/cmd/dendrite-demo-yggdrasil/yggconn/client.go
@@ -54,7 +54,7 @@ func (n *Node) CreateFederationClient(
},
)
return gomatrixserverlib.NewFederationClientWithTransport(
- base.Cfg.Matrix.ServerName, base.Cfg.Matrix.KeyID,
- base.Cfg.Matrix.PrivateKey, true, tr,
+ base.Cfg.Global.ServerName, base.Cfg.Global.KeyID,
+ base.Cfg.Global.PrivateKey, true, tr,
)
}
diff --git a/cmd/dendrite-edu-server/main.go b/cmd/dendrite-edu-server/main.go
index 6704ebd0..d3e4e0a0 100644
--- a/cmd/dendrite-edu-server/main.go
+++ b/cmd/dendrite-edu-server/main.go
@@ -33,6 +33,6 @@ func main() {
intAPI := eduserver.NewInternalAPI(base, cache.New(), base.UserAPIClient())
eduserver.AddInternalRoutes(base.InternalAPIMux, intAPI)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.EDUServer), string(base.Cfg.Listen.EDUServer))
+ base.SetupAndServeHTTP(string(base.Cfg.EDUServer.Bind), string(base.Cfg.EDUServer.Listen))
}
diff --git a/cmd/dendrite-federation-api-server/main.go b/cmd/dendrite-federation-api-server/main.go
index 70d8394f..3b12a295 100644
--- a/cmd/dendrite-federation-api-server/main.go
+++ b/cmd/dendrite-federation-api-server/main.go
@@ -33,10 +33,10 @@ func main() {
keyAPI := base.KeyServerHTTPClient()
federationapi.AddPublicRoutes(
- base.PublicAPIMux, base.Cfg, userAPI, federation, keyRing,
+ base.PublicAPIMux, &base.Cfg.FederationAPI, userAPI, federation, keyRing,
rsAPI, fsAPI, base.EDUServerClient(), base.CurrentStateAPIClient(), keyAPI,
)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.FederationAPI), string(base.Cfg.Listen.FederationAPI))
+ base.SetupAndServeHTTP(string(base.Cfg.FederationAPI.Bind), string(base.Cfg.FederationAPI.Listen))
}
diff --git a/cmd/dendrite-federation-sender-server/main.go b/cmd/dendrite-federation-sender-server/main.go
index fa6cf7ab..152c798a 100644
--- a/cmd/dendrite-federation-sender-server/main.go
+++ b/cmd/dendrite-federation-sender-server/main.go
@@ -35,6 +35,6 @@ func main() {
)
federationsender.AddInternalRoutes(base.InternalAPIMux, fsAPI)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.FederationSender), string(base.Cfg.Listen.FederationSender))
+ base.SetupAndServeHTTP(string(base.Cfg.FederationSender.Bind), string(base.Cfg.FederationSender.Listen))
}
diff --git a/cmd/dendrite-key-server/main.go b/cmd/dendrite-key-server/main.go
index 94ea819f..f3110a1e 100644
--- a/cmd/dendrite-key-server/main.go
+++ b/cmd/dendrite-key-server/main.go
@@ -24,11 +24,11 @@ func main() {
base := setup.NewBaseDendrite(cfg, "KeyServer", true)
defer base.Close() // nolint: errcheck
- intAPI := keyserver.NewInternalAPI(base.Cfg, base.CreateFederationClient(), base.KafkaProducer)
+ intAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, base.CreateFederationClient(), base.KafkaProducer)
intAPI.SetUserAPI(base.UserAPIClient())
keyserver.AddInternalRoutes(base.InternalAPIMux, intAPI)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.KeyServer), string(base.Cfg.Listen.KeyServer))
+ base.SetupAndServeHTTP(string(base.Cfg.KeyServer.Bind), string(base.Cfg.KeyServer.Listen))
}
diff --git a/cmd/dendrite-media-api-server/main.go b/cmd/dendrite-media-api-server/main.go
index 2b9c5090..1bbb62bd 100644
--- a/cmd/dendrite-media-api-server/main.go
+++ b/cmd/dendrite-media-api-server/main.go
@@ -26,10 +26,10 @@ func main() {
defer base.Close() // nolint: errcheck
userAPI := base.UserAPIClient()
- client := gomatrixserverlib.NewClient(cfg.Matrix.FederationDisableTLSValidation)
+ client := gomatrixserverlib.NewClient(cfg.FederationSender.DisableTLSValidation)
- mediaapi.AddPublicRoutes(base.PublicAPIMux, base.Cfg, userAPI, client)
+ mediaapi.AddPublicRoutes(base.PublicAPIMux, &base.Cfg.MediaAPI, userAPI, client)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.MediaAPI), string(base.Cfg.Listen.MediaAPI))
+ base.SetupAndServeHTTP(string(base.Cfg.MediaAPI.Bind), string(base.Cfg.MediaAPI.Listen))
}
diff --git a/cmd/dendrite-monolith-server/main.go b/cmd/dendrite-monolith-server/main.go
index ed30685b..8f98cdd0 100644
--- a/cmd/dendrite-monolith-server/main.go
+++ b/cmd/dendrite-monolith-server/main.go
@@ -54,11 +54,17 @@ func main() {
// the API endpoints. They'll listen on the same port as the monolith
// itself.
addr := config.Address(*httpBindAddr)
- cfg.Listen.RoomServer = addr
- cfg.Listen.EDUServer = addr
- cfg.Listen.AppServiceAPI = addr
- cfg.Listen.FederationSender = addr
- cfg.Listen.ServerKeyAPI = addr
+ cfg.AppServiceAPI.Listen = addr
+ cfg.ClientAPI.Listen = addr
+ cfg.CurrentStateServer.Listen = addr
+ cfg.EDUServer.Listen = addr
+ cfg.FederationAPI.Listen = addr
+ cfg.FederationSender.Listen = addr
+ cfg.KeyServer.Listen = addr
+ cfg.MediaAPI.Listen = addr
+ cfg.RoomServer.Listen = addr
+ cfg.ServerKeyAPI.Listen = addr
+ cfg.SyncAPI.Listen = addr
}
base := setup.NewBaseDendrite(cfg, "Monolith", *enableHTTPAPIs)
@@ -69,15 +75,15 @@ func main() {
federation := base.CreateFederationClient()
serverKeyAPI := serverkeyapi.NewInternalAPI(
- base.Cfg, federation, base.Caches,
+ &base.Cfg.ServerKeyAPI, federation, base.Caches,
)
if base.UseHTTPAPIs {
serverkeyapi.AddInternalRoutes(base.InternalAPIMux, serverKeyAPI, base.Caches)
serverKeyAPI = base.ServerKeyAPIClient()
}
keyRing := serverKeyAPI.KeyRing()
- keyAPI := keyserver.NewInternalAPI(base.Cfg, federation, base.KafkaProducer)
- userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, cfg.Derived.ApplicationServices, keyAPI)
+ keyAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, federation, base.KafkaProducer)
+ userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Global.ServerName, cfg.Derived.ApplicationServices, keyAPI)
keyAPI.SetUserAPI(userAPI)
rsImpl := roomserver.NewInternalAPI(
@@ -109,7 +115,7 @@ func main() {
asAPI = base.AppserviceHTTPClient()
}
- stateAPI := currentstateserver.NewInternalAPI(base.Cfg, base.KafkaConsumer)
+ stateAPI := currentstateserver.NewInternalAPI(&base.Cfg.CurrentStateServer, base.KafkaConsumer)
fsAPI := federationsender.NewInternalAPI(
base, federation, rsAPI, stateAPI, keyRing,
@@ -126,7 +132,7 @@ func main() {
Config: base.Cfg,
AccountDB: accountDB,
DeviceDB: deviceDB,
- Client: gomatrixserverlib.NewClient(cfg.Matrix.FederationDisableTLSValidation),
+ Client: gomatrixserverlib.NewClient(cfg.FederationSender.DisableTLSValidation),
FedClient: federation,
KeyRing: keyRing,
KafkaConsumer: base.KafkaConsumer,
@@ -147,7 +153,7 @@ func main() {
base.BaseMux,
base.PublicAPIMux,
base.InternalAPIMux,
- cfg,
+ &cfg.Global,
base.UseHTTPAPIs,
)
diff --git a/cmd/dendrite-room-server/main.go b/cmd/dendrite-room-server/main.go
index 627a6867..e1d4b16b 100644
--- a/cmd/dendrite-room-server/main.go
+++ b/cmd/dendrite-room-server/main.go
@@ -33,6 +33,6 @@ func main() {
rsAPI.SetFederationSenderAPI(fsAPI)
roomserver.AddInternalRoutes(base.InternalAPIMux, rsAPI)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.RoomServer), string(base.Cfg.Listen.RoomServer))
+ base.SetupAndServeHTTP(string(base.Cfg.RoomServer.Bind), string(base.Cfg.RoomServer.Listen))
}
diff --git a/cmd/dendrite-server-key-api-server/main.go b/cmd/dendrite-server-key-api-server/main.go
index 9ffaeee3..36f34890 100644
--- a/cmd/dendrite-server-key-api-server/main.go
+++ b/cmd/dendrite-server-key-api-server/main.go
@@ -26,8 +26,8 @@ func main() {
federation := base.CreateFederationClient()
- intAPI := serverkeyapi.NewInternalAPI(base.Cfg, federation, base.Caches)
+ intAPI := serverkeyapi.NewInternalAPI(&base.Cfg.ServerKeyAPI, federation, base.Caches)
serverkeyapi.AddInternalRoutes(base.InternalAPIMux, intAPI, base.Caches)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.ServerKeyAPI), string(base.Cfg.Listen.ServerKeyAPI))
+ base.SetupAndServeHTTP(string(base.Cfg.ServerKeyAPI.Bind), string(base.Cfg.ServerKeyAPI.Listen))
}
diff --git a/cmd/dendrite-sync-api-server/main.go b/cmd/dendrite-sync-api-server/main.go
index 0761a1d1..c25f8ec1 100644
--- a/cmd/dendrite-sync-api-server/main.go
+++ b/cmd/dendrite-sync-api-server/main.go
@@ -31,8 +31,8 @@ func main() {
syncapi.AddPublicRoutes(
base.PublicAPIMux, base.KafkaConsumer, userAPI, rsAPI, base.KeyServerHTTPClient(), base.CurrentStateAPIClient(),
- federation, cfg)
+ federation, &cfg.SyncAPI)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.SyncAPI), string(base.Cfg.Listen.SyncAPI))
+ base.SetupAndServeHTTP(string(base.Cfg.SyncAPI.Bind), string(base.Cfg.SyncAPI.Listen))
}
diff --git a/cmd/dendrite-user-api-server/main.go b/cmd/dendrite-user-api-server/main.go
index e6d61da1..22b6255e 100644
--- a/cmd/dendrite-user-api-server/main.go
+++ b/cmd/dendrite-user-api-server/main.go
@@ -27,9 +27,9 @@ func main() {
accountDB := base.CreateAccountsDB()
deviceDB := base.CreateDeviceDB()
- userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, cfg.Derived.ApplicationServices, base.KeyServerHTTPClient())
+ userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Global.ServerName, cfg.Derived.ApplicationServices, base.KeyServerHTTPClient())
userapi.AddInternalRoutes(base.InternalAPIMux, userAPI)
- base.SetupAndServeHTTP(string(base.Cfg.Bind.UserAPI), string(base.Cfg.Listen.UserAPI))
+ base.SetupAndServeHTTP(string(base.Cfg.UserAPI.Bind), string(base.Cfg.UserAPI.Listen))
}
diff --git a/cmd/dendritejs/main.go b/cmd/dendritejs/main.go
index 274d170e..ce7812fa 100644
--- a/cmd/dendritejs/main.go
+++ b/cmd/dendritejs/main.go
@@ -139,7 +139,7 @@ func createFederationClient(cfg *config.Dendrite, node *go_http_js_libp2p.P2pLoc
tr := go_http_js_libp2p.NewP2pTransport(node)
fed := gomatrixserverlib.NewFederationClient(
- cfg.Matrix.ServerName, cfg.Matrix.KeyID, cfg.Matrix.PrivateKey, true,
+ cfg.Global.ServerName, cfg.Global.KeyID, cfg.Global.PrivateKey, true,
)
fed.Client = *gomatrixserverlib.NewClientWithTransport(true, tr)
@@ -161,31 +161,31 @@ func createP2PNode(privKey ed25519.PrivateKey) (serverName string, node *go_http
func main() {
cfg := &config.Dendrite{}
- cfg.SetDefaults()
- cfg.Kafka.UseNaffka = true
- cfg.Database.Account = "file:/idb/dendritejs_account.db"
- cfg.Database.AppService = "file:/idb/dendritejs_appservice.db"
- cfg.Database.Device = "file:/idb/dendritejs_device.db"
- cfg.Database.FederationSender = "file:/idb/dendritejs_fedsender.db"
- cfg.Database.MediaAPI = "file:/idb/dendritejs_mediaapi.db"
- cfg.Database.Naffka = "file:/idb/dendritejs_naffka.db"
- cfg.Database.RoomServer = "file:/idb/dendritejs_roomserver.db"
- cfg.Database.ServerKey = "file:/idb/dendritejs_serverkey.db"
- cfg.Database.SyncAPI = "file:/idb/dendritejs_syncapi.db"
- cfg.Database.CurrentState = "file:/idb/dendritejs_currentstate.db"
- cfg.Database.E2EKey = "file:/idb/dendritejs_e2ekey.db"
- cfg.Kafka.Topics.OutputTypingEvent = "output_typing_event"
- cfg.Kafka.Topics.OutputSendToDeviceEvent = "output_send_to_device_event"
- cfg.Kafka.Topics.OutputClientData = "output_client_data"
- cfg.Kafka.Topics.OutputRoomEvent = "output_room_event"
- cfg.Matrix.TrustedIDServers = []string{
+ cfg.Defaults()
+ cfg.UserAPI.AccountDatabase.ConnectionString = "file:/idb/dendritejs_account.db"
+ cfg.AppServiceAPI.Database.ConnectionString = "file:/idb/dendritejs_appservice.db"
+ cfg.UserAPI.DeviceDatabase.ConnectionString = "file:/idb/dendritejs_device.db"
+ cfg.FederationSender.Database.ConnectionString = "file:/idb/dendritejs_fedsender.db"
+ cfg.MediaAPI.Database.ConnectionString = "file:/idb/dendritejs_mediaapi.db"
+ cfg.RoomServer.Database.ConnectionString = "file:/idb/dendritejs_roomserver.db"
+ cfg.ServerKeyAPI.Database.ConnectionString = "file:/idb/dendritejs_serverkey.db"
+ cfg.SyncAPI.Database.ConnectionString = "file:/idb/dendritejs_syncapi.db"
+ cfg.CurrentStateServer.Database.ConnectionString = "file:/idb/dendritejs_currentstate.db"
+ cfg.KeyServer.Database.ConnectionString = "file:/idb/dendritejs_e2ekey.db"
+ cfg.Global.Kafka.UseNaffka = true
+ cfg.Global.Kafka.Database.ConnectionString = "file:/idb/dendritejs_naffka.db"
+ cfg.Global.Kafka.Topics.OutputTypingEvent = "output_typing_event"
+ cfg.Global.Kafka.Topics.OutputSendToDeviceEvent = "output_send_to_device_event"
+ cfg.Global.Kafka.Topics.OutputClientData = "output_client_data"
+ cfg.Global.Kafka.Topics.OutputRoomEvent = "output_room_event"
+ cfg.Global.TrustedIDServers = []string{
"matrix.org", "vector.im",
}
- cfg.Matrix.KeyID = libp2pMatrixKeyID
- cfg.Matrix.PrivateKey = generateKey()
+ cfg.Global.KeyID = libp2pMatrixKeyID
+ cfg.Global.PrivateKey = generateKey()
- serverName, node := createP2PNode(cfg.Matrix.PrivateKey)
- cfg.Matrix.ServerName = gomatrixserverlib.ServerName(serverName)
+ serverName, node := createP2PNode(cfg.Global.PrivateKey)
+ cfg.Global.ServerName = gomatrixserverlib.ServerName(serverName)
if err := cfg.Derive(); err != nil {
logrus.Fatalf("Failed to derive values from config: %s", err)
@@ -196,8 +196,8 @@ func main() {
accountDB := base.CreateAccountsDB()
deviceDB := base.CreateDeviceDB()
federation := createFederationClient(cfg, node)
- keyAPI := keyserver.NewInternalAPI(base.Cfg, federation, base.KafkaProducer)
- userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Matrix.ServerName, nil, keyAPI)
+ keyAPI := keyserver.NewInternalAPI(&base.Cfg.KeyServer, federation, base.KafkaProducer)
+ userAPI := userapi.NewInternalAPI(accountDB, deviceDB, cfg.Global.ServerName, nil, keyAPI)
keyAPI.SetUserAPI(userAPI)
fetcher := &libp2pKeyFetcher{}
@@ -208,7 +208,7 @@ func main() {
KeyDatabase: fetcher,
}
- stateAPI := currentstateserver.NewInternalAPI(base.Cfg, base.KafkaConsumer)
+ stateAPI := currentstateserver.NewInternalAPI(&base.Cfg.CurrentStateServer, base.KafkaConsumer)
rsAPI := roomserver.NewInternalAPI(base, keyRing, federation)
eduInputAPI := eduserver.NewInternalAPI(base, cache.New(), userAPI)
asQuery := appservice.NewInternalAPI(
@@ -244,7 +244,7 @@ func main() {
base.BaseMux,
base.PublicAPIMux,
base.InternalAPIMux,
- cfg,
+ &cfg.Global,
base.UseHTTPAPIs,
)
diff --git a/cmd/generate-config/main.go b/cmd/generate-config/main.go
new file mode 100644
index 00000000..4dd12593
--- /dev/null
+++ b/cmd/generate-config/main.go
@@ -0,0 +1,29 @@
+package main
+
+import (
+ "fmt"
+
+ "github.com/matrix-org/dendrite/internal/config"
+ "gopkg.in/yaml.v2"
+)
+
+func main() {
+ cfg := &config.Dendrite{}
+ cfg.Defaults()
+ cfg.Logging = []config.LogrusHook{
+ {
+ Type: "file",
+ Level: "info",
+ Params: map[string]interface{}{
+ "path": "/var/log/dendrite",
+ },
+ },
+ }
+
+ j, err := yaml.Marshal(cfg)
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Println(string(j))
+}
diff --git a/cmd/mediaapi-integration-tests/main.go b/cmd/mediaapi-integration-tests/main.go
index e6ce14d2..4c584979 100644
--- a/cmd/mediaapi-integration-tests/main.go
+++ b/cmd/mediaapi-integration-tests/main.go
@@ -88,9 +88,9 @@ func startMediaAPI(suffix string, dynamicThumbnails bool) (*exec.Cmd, chan error
if err != nil {
panic(err)
}
- cfg.Matrix.ServerName = gomatrixserverlib.ServerName(proxyAddr)
- cfg.Media.DynamicThumbnails = dynamicThumbnails
- if err = yaml.Unmarshal([]byte(thumbnailSizes), &cfg.Media.ThumbnailSizes); err != nil {
+ cfg.Global.ServerName = gomatrixserverlib.ServerName(proxyAddr)
+ cfg.MediaAPI.DynamicThumbnails = dynamicThumbnails
+ if err = yaml.Unmarshal([]byte(thumbnailSizes), &cfg.MediaAPI.ThumbnailSizes); err != nil {
panic(err)
}
@@ -120,7 +120,7 @@ func startMediaAPI(suffix string, dynamicThumbnails bool) (*exec.Cmd, chan error
serverArgs,
)
- fmt.Printf("==TESTSERVER== STARTED %v -> %v : %v\n", proxyAddr, cfg.Listen.MediaAPI, dir)
+ fmt.Printf("==TESTSERVER== STARTED %v -> %v : %v\n", proxyAddr, cfg.MediaAPI.Listen, dir)
return cmd, cmdChan, proxyCmd, proxyAddr, dir
}
diff --git a/cmd/roomserver-integration-tests/main.go b/cmd/roomserver-integration-tests/main.go
index 3860ca1f..4d3095be 100644
--- a/cmd/roomserver-integration-tests/main.go
+++ b/cmd/roomserver-integration-tests/main.go
@@ -240,7 +240,7 @@ func testRoomserver(input []string, wantOutput []string, checkQueries func(api.R
panic(err)
}
- outputTopic := string(cfg.Kafka.Topics.OutputRoomEvent)
+ outputTopic := string(cfg.Global.Kafka.Topics.OutputRoomEvent)
err = exe.DeleteTopic(outputTopic)
if err != nil {
@@ -277,7 +277,7 @@ func testRoomserver(input []string, wantOutput []string, checkQueries func(api.R
cmd.Args = []string{"dendrite-room-server", "--config", filepath.Join(dir, test.ConfigFile)}
gotOutput, err := runAndReadFromTopic(cmd, cfg.RoomServerURL()+"/metrics", doInput, outputTopic, len(wantOutput), func() {
- queryAPI, _ := inthttp.NewRoomserverClient("http://"+string(cfg.Listen.RoomServer), &http.Client{Timeout: timeoutHTTP}, cache)
+ queryAPI, _ := inthttp.NewRoomserverClient("http://"+string(cfg.RoomServer.Listen), &http.Client{Timeout: timeoutHTTP}, cache)
checkQueries(queryAPI)
})
if err != nil {
diff --git a/cmd/syncserver-integration-tests/main.go b/cmd/syncserver-integration-tests/main.go
index cfe8cc16..76fa0eba 100644
--- a/cmd/syncserver-integration-tests/main.go
+++ b/cmd/syncserver-integration-tests/main.go
@@ -132,10 +132,10 @@ func startSyncServer() (*exec.Cmd, chan error) {
panic(err)
}
// TODO use the address assigned by the config generator rather than clobbering.
- cfg.Matrix.ServerName = "localhost"
- cfg.Listen.SyncAPI = config.Address(syncserverAddr)
- cfg.Kafka.Topics.OutputRoomEvent = config.Topic(inputTopic)
- cfg.Kafka.Topics.OutputClientData = config.Topic(clientTopic)
+ cfg.Global.ServerName = "localhost"
+ cfg.SyncAPI.Listen = config.Address(syncserverAddr)
+ cfg.Global.Kafka.Topics.OutputRoomEvent = config.Topic(inputTopic)
+ cfg.Global.Kafka.Topics.OutputClientData = config.Topic(clientTopic)
if err := test.WriteConfig(cfg, dir); err != nil {
panic(err)
diff --git a/currentstateserver/currentstateserver.go b/currentstateserver/currentstateserver.go
index 07d5e54a..8e985e84 100644
--- a/currentstateserver/currentstateserver.go
+++ b/currentstateserver/currentstateserver.go
@@ -34,13 +34,13 @@ func AddInternalRoutes(router *mux.Router, intAPI api.CurrentStateInternalAPI) {
// NewInternalAPI returns a concrete implementation of the internal API. Callers
// can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
-func NewInternalAPI(cfg *config.Dendrite, consumer sarama.Consumer) api.CurrentStateInternalAPI {
- csDB, err := storage.NewDatabase(string(cfg.Database.CurrentState), cfg.DbProperties())
+func NewInternalAPI(cfg *config.CurrentStateServer, consumer sarama.Consumer) api.CurrentStateInternalAPI {
+ csDB, err := storage.NewDatabase(&cfg.Database)
if err != nil {
logrus.WithError(err).Panicf("failed to open database")
}
roomConsumer := consumers.NewOutputRoomEventConsumer(
- string(cfg.Kafka.Topics.OutputRoomEvent), consumer, csDB,
+ string(cfg.Matrix.Kafka.Topics.OutputRoomEvent), consumer, csDB,
)
if err = roomConsumer.Start(); err != nil {
logrus.WithError(err).Panicf("failed to start room server consumer")
diff --git a/currentstateserver/currentstateserver_test.go b/currentstateserver/currentstateserver_test.go
index 19317390..2b0e40c2 100644
--- a/currentstateserver/currentstateserver_test.go
+++ b/currentstateserver/currentstateserver_test.go
@@ -15,6 +15,7 @@
package currentstateserver
import (
+ "bytes"
"context"
"crypto/ed25519"
"encoding/json"
@@ -94,11 +95,15 @@ func MustWriteOutputEvent(t *testing.T, producer sarama.SyncProducer, out *rooms
func MustMakeInternalAPI(t *testing.T) (api.CurrentStateInternalAPI, sarama.SyncProducer, func()) {
cfg := &config.Dendrite{}
+ cfg.Defaults()
stateDBName := "test_state.db"
naffkaDBName := "test_naffka.db"
- cfg.Kafka.Topics.OutputRoomEvent = config.Topic(kafkaTopic)
- cfg.Database.CurrentState = config.DataSource("file:" + stateDBName)
- db, err := sqlutil.Open(sqlutil.SQLiteDriverName(), "file:"+naffkaDBName, nil)
+ cfg.Global.ServerName = "kaer.morhen"
+ cfg.Global.Kafka.Topics.OutputRoomEvent = config.Topic(kafkaTopic)
+ cfg.CurrentStateServer.Database.ConnectionString = config.DataSource("file:" + stateDBName)
+ db, err := sqlutil.Open(&config.DatabaseOptions{
+ ConnectionString: config.DataSource("file:" + naffkaDBName),
+ })
if err != nil {
t.Fatalf("Failed to open naffka database: %s", err)
}
@@ -110,7 +115,7 @@ func MustMakeInternalAPI(t *testing.T) (api.CurrentStateInternalAPI, sarama.Sync
if err != nil {
t.Fatalf("Failed to create naffka consumer: %s", err)
}
- return NewInternalAPI(cfg, naff), naff, func() {
+ return NewInternalAPI(&cfg.CurrentStateServer, naff), naff, func() {
os.Remove(naffkaDBName)
os.Remove(stateDBName)
}
@@ -165,8 +170,13 @@ func TestQueryCurrentState(t *testing.T) {
t.Errorf("QueryCurrentState want tuple %+v but it is missing from the response", tuple)
continue
}
- if !reflect.DeepEqual(gotEvent.JSON(), wantEvent.JSON()) {
- t.Errorf("QueryCurrentState tuple %+v got event JSON %s want %s", tuple, string(gotEvent.JSON()), string(wantEvent.JSON()))
+ gotCanon, err := gomatrixserverlib.CanonicalJSON(gotEvent.JSON())
+ if err != nil {
+ t.Errorf("CanonicalJSON failed: %w", err)
+ continue
+ }
+ if !bytes.Equal(gotCanon, wantEvent.JSON()) {
+ t.Errorf("QueryCurrentState tuple %+v got event JSON %s want %s", tuple, string(gotCanon), string(wantEvent.JSON()))
}
}
}
diff --git a/currentstateserver/storage/postgres/storage.go b/currentstateserver/storage/postgres/storage.go
index f8edb94e..0cd7e555 100644
--- a/currentstateserver/storage/postgres/storage.go
+++ b/currentstateserver/storage/postgres/storage.go
@@ -4,6 +4,7 @@ import (
"database/sql"
"github.com/matrix-org/dendrite/currentstateserver/storage/shared"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
)
@@ -14,10 +15,10 @@ type Database struct {
}
// NewDatabase creates a new sync server database
-func NewDatabase(dbDataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) {
var d Database
var err error
- if d.db, err = sqlutil.Open("postgres", dbDataSourceName, dbProperties); err != nil {
+ if d.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
if err = d.PartitionOffsetStatements.Prepare(d.db, "currentstate"); err != nil {
diff --git a/currentstateserver/storage/sqlite3/storage.go b/currentstateserver/storage/sqlite3/storage.go
index 6975e40b..4454c9ed 100644
--- a/currentstateserver/storage/sqlite3/storage.go
+++ b/currentstateserver/storage/sqlite3/storage.go
@@ -4,6 +4,7 @@ import (
"database/sql"
"github.com/matrix-org/dendrite/currentstateserver/storage/shared"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
)
@@ -15,13 +16,10 @@ type Database struct {
// NewDatabase creates a new sync server database
// nolint: gocyclo
-func NewDatabase(dataSourceName string) (*Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) {
var d Database
- cs, err := sqlutil.ParseFileURI(dataSourceName)
- if err != nil {
- return nil, err
- }
- if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
+ var err error
+ if d.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
if err = d.PartitionOffsetStatements.Prepare(d.db, "currentstate"); err != nil {
diff --git a/currentstateserver/storage/storage.go b/currentstateserver/storage/storage.go
index ad04cf41..e0707def 100644
--- a/currentstateserver/storage/storage.go
+++ b/currentstateserver/storage/storage.go
@@ -17,25 +17,21 @@
package storage
import (
- "net/url"
+ "fmt"
"github.com/matrix-org/dendrite/currentstateserver/storage/postgres"
"github.com/matrix-org/dendrite/currentstateserver/storage/sqlite3"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
)
// NewDatabase opens a database connection.
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.NewDatabase(dataSourceName, dbProperties)
- }
- switch uri.Scheme {
- case "postgres":
- return postgres.NewDatabase(dataSourceName, dbProperties)
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
+func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.NewDatabase(dbProperties)
default:
- return postgres.NewDatabase(dataSourceName, dbProperties)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/currentstateserver/storage/storage_wasm.go b/currentstateserver/storage/storage_wasm.go
index aa46c44d..46a5abd6 100644
--- a/currentstateserver/storage/storage_wasm.go
+++ b/currentstateserver/storage/storage_wasm.go
@@ -16,27 +16,19 @@ package storage
import (
"fmt"
- "net/url"
"github.com/matrix-org/dendrite/currentstateserver/storage/sqlite3"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
)
// NewDatabase opens a database connection.
-func NewDatabase(
- dataSourceName string,
- dbProperties sqlutil.DbProperties, // nolint:unparam
-) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return nil, fmt.Errorf("Cannot use postgres implementation")
- }
- switch uri.Scheme {
- case "postgres":
- return nil, fmt.Errorf("Cannot use postgres implementation")
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
+func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return nil, fmt.Errorf("can't use Postgres implementation")
default:
- return nil, fmt.Errorf("Cannot use postgres implementation")
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/dendrite-config.yaml b/dendrite-config.yaml
deleted file mode 100644
index 8f144875..00000000
--- a/dendrite-config.yaml
+++ /dev/null
@@ -1,178 +0,0 @@
-# The config file format version
-# This is used by dendrite to tell if it understands the config format.
-# This will change if the structure of the config file changes or if the meaning
-# of an existing config key changes.
-version: 0
-
-# The matrix specific config
-matrix:
- # The name of the server. This is usually the domain name, e.g 'matrix.org', 'localhost'.
- server_name: "example.com"
- # The path to the PEM formatted matrix private key.
- private_key: "/etc/dendrite/matrix_key.pem"
- # The x509 certificates used by the federation listeners for this server
- federation_certificates: ["/etc/dendrite/server.crt"]
- # The list of identity servers trusted to verify third party identifiers by this server.
- # Defaults to no trusted servers.
- trusted_third_party_id_servers:
- - vector.im
- - matrix.org
- # Perspective key servers which are used when direct key requests fail
- #key_perspectives:
- # - server_name: matrix.org
- # keys:
- # - key_id: ed25519:auto
- # public_key: Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw
- # - key_id: ed25519:a_RXGa
- # public_key: l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ
- # Disables new users from registering (except via shared secrets)
- registration_disabled: false
- # Whether to disable TLS certificate validation. Warning: this reduces federation
- # security and should not be enabled in production!
- federation_disable_tls_validation: false
-
-# The media repository config
-media:
- # The base path to where the media files will be stored. May be relative or absolute.
- base_path: /var/dendrite/media
-
- # The maximum file size in bytes that is allowed to be stored on this server.
- # Note: if max_file_size_bytes is set to 0, the size is unlimited.
- # Note: if max_file_size_bytes is not set, it will default to 10485760 (10MB)
- max_file_size_bytes: 10485760
-
- # Whether to dynamically generate thumbnails on-the-fly if the requested resolution is not already generated
- # NOTE: This is a possible denial-of-service attack vector - use at your own risk
- dynamic_thumbnails: false
-
- # A list of thumbnail sizes to be pre-generated for downloaded remote / uploaded content
- # method is one of crop or scale. If omitted, it will default to scale.
- # crop scales to fill the requested dimensions and crops the excess.
- # scale scales to fit the requested dimensions and one dimension may be smaller than requested.
- thumbnail_sizes:
- - width: 32
- height: 32
- method: crop
- - width: 96
- height: 96
- method: crop
- - width: 320
- height: 240
- method: scale
- - width: 640
- height: 480
- method: scale
- - width: 800
- height: 600
- method: scale
-
-# Metrics config for Prometheus
-metrics:
- # Whether or not metrics are enabled
- enabled: false
- # Use basic auth to protect the metrics. Uncomment to the complete block to enable.
- #basic_auth:
- # username: prometheusUser
- # password: y0ursecr3tPa$$w0rd
-
-# The config for the TURN server
-turn:
- # Whether or not guests can request TURN credentials
- turn_allow_guests: true
- # How long the authorization should last
- turn_user_lifetime: "1h"
- # The list of TURN URIs to pass to clients
- turn_uris: []
-
- # Authorization via Shared Secret
- # The shared secret from coturn
- turn_shared_secret: "<SECRET STRING GOES HERE>"
-
- # Authorization via Static Username & Password
- # Hardcoded Username and Password
- turn_username: ""
- turn_password: ""
-
-# The config for communicating with kafka
-kafka:
- # Where the kafka servers are running.
- addresses: ["localhost:9092"]
- # Whether to use naffka instead of kafka.
- # Naffka can only be used when running dendrite as a single monolithic server.
- # Kafka can be used both with a monolithic server and when running the
- # components as separate servers.
- # If enabled database.naffka must also be specified.
- use_naffka: false
- # The names of the kafka topics to use.
- topics:
- output_room_event: roomserverOutput
- output_client_data: clientapiOutput
- output_typing_event: eduServerTypingOutput
- output_send_to_device_event: eduServerSendToDeviceOutput
- user_updates: userUpdates
-
-# The postgres connection configs for connecting to the databases, e.g.
-# for Postgres: postgres://username:password@hostname/database
-# for SQLite: file:filename.db or file:///path/to/filename.db
-database:
- account: "postgres://dendrite:itsasecret@localhost/dendrite_account?sslmode=disable"
- device: "postgres://dendrite:itsasecret@localhost/dendrite_device?sslmode=disable"
- media_api: "postgres://dendrite:itsasecret@localhost/dendrite_mediaapi?sslmode=disable"
- sync_api: "postgres://dendrite:itsasecret@localhost/dendrite_syncapi?sslmode=disable"
- room_server: "postgres://dendrite:itsasecret@localhost/dendrite_roomserver?sslmode=disable"
- server_key: "postgres://dendrite:itsasecret@localhost/dendrite_serverkey?sslmode=disable"
- federation_sender: "postgres://dendrite:itsasecret@localhost/dendrite_federationsender?sslmode=disable"
- appservice: "postgres://dendrite:itsasecret@localhost/dendrite_appservice?sslmode=disable"
- current_state: "postgres://dendrite:itsasecret@localhost/dendrite_currentstate?sslmode=disable"
- e2e_key: "postgres://dendrite:itsasecret@localhost/dendrite_e2ekey?sslmode=disable"
- max_open_conns: 100
- max_idle_conns: 2
- conn_max_lifetime: -1
- # If 'use_naffka: true' set above then you need to specify a naffka database
- # naffka: "postgres://dendrite:itsasecret@localhost/dendrite_naffka?sslmode=disable"
-
-# The TCP host:port pairs to bind the internal HTTP APIs to.
-# These shouldn't be exposed to the public internet.
-# These aren't needed when running dendrite as a monolithic server.
-listen:
- room_server: "localhost:7770"
- client_api: "localhost:7771"
- federation_api: "localhost:7772"
- sync_api: "localhost:7773"
- media_api: "localhost:7774"
- federation_sender: "localhost:7776"
- appservice_api: "localhost:7777"
- edu_server: "localhost:7778"
- key_server: "localhost:7779"
- server_key_api: "localhost:7780"
- user_api: "localhost:7781"
- current_state_server: "localhost:7782"
-
-# The configuration for tracing the dendrite components.
-tracing:
- # Config for the jaeger opentracing reporter.
- # See https://godoc.org/github.com/uber/jaeger-client-go/config#Configuration
- # for documentation.
- jaeger:
- disabled: true
-
-# A list of application service config files to use
-application_services:
- config_files: []
-
-# The configuration for dendrite logs
-logging:
- # The logging type, only "file" is supported at the moment
- - type: "file"
- # The logging level, must be one of debug, info, warn, error, fatal, panic.
- level: "info"
- # Parameters for this type of log
- params:
- # File logging must be given a path to a directory. Each component will write to a different file. Logs are rotated each day and gzipped
- path: "/var/log/dendrite"
- # It is possible to have multiple logging hooks at the same time.
- # To save only errors in a different directory, uncomment the following.
- # - type: "file"
- # level: "error"
- # params:
- # path: "/var/log/dendrite/errors"
diff --git a/eduserver/eduserver.go b/eduserver/eduserver.go
index 2e6ba0c8..e0e61b1a 100644
--- a/eduserver/eduserver.go
+++ b/eduserver/eduserver.go
@@ -39,12 +39,13 @@ func NewInternalAPI(
eduCache *cache.EDUCache,
userAPI userapi.UserInternalAPI,
) api.EDUServerInputAPI {
+ cfg := &base.Cfg.EDUServer
return &input.EDUServerInputAPI{
Cache: eduCache,
UserAPI: userAPI,
Producer: base.KafkaProducer,
- OutputTypingEventTopic: string(base.Cfg.Kafka.Topics.OutputTypingEvent),
- OutputSendToDeviceEventTopic: string(base.Cfg.Kafka.Topics.OutputSendToDeviceEvent),
- ServerName: base.Cfg.Matrix.ServerName,
+ OutputTypingEventTopic: string(cfg.Matrix.Kafka.Topics.OutputTypingEvent),
+ OutputSendToDeviceEventTopic: string(cfg.Matrix.Kafka.Topics.OutputSendToDeviceEvent),
+ ServerName: cfg.Matrix.ServerName,
}
}
diff --git a/federationapi/federationapi.go b/federationapi/federationapi.go
index 079f333a..e9a8e40a 100644
--- a/federationapi/federationapi.go
+++ b/federationapi/federationapi.go
@@ -31,7 +31,7 @@ import (
// AddPublicRoutes sets up and registers HTTP handlers on the base API muxes for the FederationAPI component.
func AddPublicRoutes(
router *mux.Router,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
userAPI userapi.UserInternalAPI,
federation *gomatrixserverlib.FederationClient,
keyRing gomatrixserverlib.JSONVerifier,
diff --git a/federationapi/federationapi_test.go b/federationapi/federationapi_test.go
index 0e0d7740..331d3329 100644
--- a/federationapi/federationapi_test.go
+++ b/federationapi/federationapi_test.go
@@ -20,30 +20,31 @@ import (
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)
+ cfg.Defaults()
+ cfg.Global.KeyID = gomatrixserverlib.KeyID("ed25519:auto")
+ cfg.Global.ServerName = gomatrixserverlib.ServerName("localhost")
+ cfg.Global.PrivateKey = privKey
+ cfg.Global.Kafka.UseNaffka = true
+ cfg.Global.Kafka.Database.ConnectionString = config.DataSource("file::memory:")
+ cfg.FederationSender.Database.ConnectionString = config.DataSource("file::memory:")
+ base := setup.NewBaseDendrite(cfg, "Monolith", 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, nil, nil)
+ federationapi.AddPublicRoutes(base.PublicAPIMux, &cfg.FederationAPI, nil, nil, keyRing, nil, fsAPI, nil, nil, nil)
httputil.SetupHTTPAPI(
base.BaseMux,
base.PublicAPIMux,
base.InternalAPIMux,
- cfg,
+ &cfg.Global,
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, true)
+ fedCli := gomatrixserverlib.NewFederationClient(serverName, cfg.Global.KeyID, cfg.Global.PrivateKey, true)
testCases := []struct {
roomVer gomatrixserverlib.RoomVersion
diff --git a/federationapi/routing/backfill.go b/federationapi/routing/backfill.go
index f906c73c..ea77c947 100644
--- a/federationapi/routing/backfill.go
+++ b/federationapi/routing/backfill.go
@@ -35,7 +35,7 @@ func Backfill(
request *gomatrixserverlib.FederationRequest,
rsAPI api.RoomserverInternalAPI,
roomID string,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
) util.JSONResponse {
var res api.PerformBackfillResponse
var eIDs []string
diff --git a/federationapi/routing/invite.go b/federationapi/routing/invite.go
index 4a49463a..3f9661ee 100644
--- a/federationapi/routing/invite.go
+++ b/federationapi/routing/invite.go
@@ -34,7 +34,7 @@ func InviteV2(
request *gomatrixserverlib.FederationRequest,
roomID string,
eventID string,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI api.RoomserverInternalAPI,
keys gomatrixserverlib.JSONVerifier,
) util.JSONResponse {
@@ -56,7 +56,7 @@ func InviteV1(
request *gomatrixserverlib.FederationRequest,
roomID string,
eventID string,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI api.RoomserverInternalAPI,
keys gomatrixserverlib.JSONVerifier,
) util.JSONResponse {
@@ -86,7 +86,7 @@ func processInvite(
strippedState []gomatrixserverlib.InviteV2StrippedState,
roomID string,
eventID string,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI api.RoomserverInternalAPI,
keys gomatrixserverlib.JSONVerifier,
) util.JSONResponse {
diff --git a/federationapi/routing/join.go b/federationapi/routing/join.go
index 17981f53..4874f4d1 100644
--- a/federationapi/routing/join.go
+++ b/federationapi/routing/join.go
@@ -32,7 +32,7 @@ import (
func MakeJoin(
httpReq *http.Request,
request *gomatrixserverlib.FederationRequest,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI api.RoomserverInternalAPI,
roomID, userID string,
remoteVersions []gomatrixserverlib.RoomVersion,
@@ -95,7 +95,7 @@ func MakeJoin(
queryRes := api.QueryLatestEventsAndStateResponse{
RoomVersion: verRes.RoomVersion,
}
- event, err := eventutil.BuildEvent(httpReq.Context(), &builder, cfg, time.Now(), rsAPI, &queryRes)
+ event, err := eventutil.BuildEvent(httpReq.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
return util.JSONResponse{
Code: http.StatusNotFound,
@@ -141,7 +141,7 @@ func MakeJoin(
func SendJoin(
httpReq *http.Request,
request *gomatrixserverlib.FederationRequest,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI api.RoomserverInternalAPI,
keys gomatrixserverlib.JSONVerifier,
roomID, eventID string,
diff --git a/federationapi/routing/keys.go b/federationapi/routing/keys.go
index 90eec9e0..f1ed4176 100644
--- a/federationapi/routing/keys.go
+++ b/federationapi/routing/keys.go
@@ -121,7 +121,7 @@ func ClaimOneTimeKeys(
// LocalKeys returns the local keys for the server.
// See https://matrix.org/docs/spec/server_server/unstable.html#publishing-keys
-func LocalKeys(cfg *config.Dendrite) util.JSONResponse {
+func LocalKeys(cfg *config.FederationAPI) util.JSONResponse {
keys, err := localKeys(cfg, time.Now().Add(cfg.Matrix.KeyValidityPeriod))
if err != nil {
return util.ErrorResponse(err)
@@ -129,7 +129,7 @@ func LocalKeys(cfg *config.Dendrite) util.JSONResponse {
return util.JSONResponse{Code: http.StatusOK, JSON: keys}
}
-func localKeys(cfg *config.Dendrite, validUntil time.Time) (*gomatrixserverlib.ServerKeys, error) {
+func localKeys(cfg *config.FederationAPI, validUntil time.Time) (*gomatrixserverlib.ServerKeys, error) {
var keys gomatrixserverlib.ServerKeys
keys.ServerName = cfg.Matrix.ServerName
@@ -142,7 +142,7 @@ func localKeys(cfg *config.Dendrite, validUntil time.Time) (*gomatrixserverlib.S
},
}
- keys.TLSFingerprints = cfg.Matrix.TLSFingerPrints
+ keys.TLSFingerprints = cfg.TLSFingerPrints
keys.OldVerifyKeys = map[gomatrixserverlib.KeyID]gomatrixserverlib.OldVerifyKey{}
keys.ValidUntilTS = gomatrixserverlib.AsTimestamp(validUntil)
diff --git a/federationapi/routing/leave.go b/federationapi/routing/leave.go
index 56f1b05a..314b4c72 100644
--- a/federationapi/routing/leave.go
+++ b/federationapi/routing/leave.go
@@ -28,7 +28,7 @@ import (
func MakeLeave(
httpReq *http.Request,
request *gomatrixserverlib.FederationRequest,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI api.RoomserverInternalAPI,
roomID, userID string,
) util.JSONResponse {
@@ -60,7 +60,7 @@ func MakeLeave(
}
var queryRes api.QueryLatestEventsAndStateResponse
- event, err := eventutil.BuildEvent(httpReq.Context(), &builder, cfg, time.Now(), rsAPI, &queryRes)
+ event, err := eventutil.BuildEvent(httpReq.Context(), &builder, cfg.Matrix, time.Now(), rsAPI, &queryRes)
if err == eventutil.ErrRoomNoExists {
return util.JSONResponse{
Code: http.StatusNotFound,
@@ -102,7 +102,7 @@ func MakeLeave(
func SendLeave(
httpReq *http.Request,
request *gomatrixserverlib.FederationRequest,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI api.RoomserverInternalAPI,
keys gomatrixserverlib.JSONVerifier,
roomID, eventID string,
diff --git a/federationapi/routing/profile.go b/federationapi/routing/profile.go
index a6180ae6..f1d90bbf 100644
--- a/federationapi/routing/profile.go
+++ b/federationapi/routing/profile.go
@@ -30,7 +30,7 @@ import (
func GetProfile(
httpReq *http.Request,
userAPI userapi.UserInternalAPI,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
) util.JSONResponse {
userID, field := httpReq.FormValue("user_id"), httpReq.FormValue("field")
diff --git a/federationapi/routing/query.go b/federationapi/routing/query.go
index 39fd6d2e..99b5460b 100644
--- a/federationapi/routing/query.go
+++ b/federationapi/routing/query.go
@@ -31,7 +31,7 @@ import (
func RoomAliasToID(
httpReq *http.Request,
federation *gomatrixserverlib.FederationClient,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI roomserverAPI.RoomserverInternalAPI,
senderAPI federationSenderAPI.FederationSenderInternalAPI,
) util.JSONResponse {
diff --git a/federationapi/routing/routing.go b/federationapi/routing/routing.go
index 30a65271..88fd8757 100644
--- a/federationapi/routing/routing.go
+++ b/federationapi/routing/routing.go
@@ -47,7 +47,7 @@ const (
// nolint: gocyclo
func Setup(
publicAPIMux *mux.Router,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI roomserverAPI.RoomserverInternalAPI,
eduAPI eduserverAPI.EDUServerInputAPI,
fsAPI federationSenderAPI.FederationSenderInternalAPI,
diff --git a/federationapi/routing/send.go b/federationapi/routing/send.go
index f85da148..d1aa728c 100644
--- a/federationapi/routing/send.go
+++ b/federationapi/routing/send.go
@@ -35,7 +35,7 @@ func Send(
httpReq *http.Request,
request *gomatrixserverlib.FederationRequest,
txnID gomatrixserverlib.TransactionID,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
rsAPI api.RoomserverInternalAPI,
eduAPI eduserverAPI.EDUServerInputAPI,
keyAPI keyapi.KeyInternalAPI,
diff --git a/federationapi/routing/threepid.go b/federationapi/routing/threepid.go
index 61788010..e8d9a939 100644
--- a/federationapi/routing/threepid.go
+++ b/federationapi/routing/threepid.go
@@ -56,7 +56,7 @@ var (
// CreateInvitesFrom3PIDInvites implements POST /_matrix/federation/v1/3pid/onbind
func CreateInvitesFrom3PIDInvites(
req *http.Request, rsAPI api.RoomserverInternalAPI,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
federation *gomatrixserverlib.FederationClient,
userAPI userapi.UserInternalAPI,
) util.JSONResponse {
@@ -106,7 +106,7 @@ func ExchangeThirdPartyInvite(
request *gomatrixserverlib.FederationRequest,
roomID string,
rsAPI api.RoomserverInternalAPI,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
federation *gomatrixserverlib.FederationClient,
) util.JSONResponse {
var builder gomatrixserverlib.EventBuilder
@@ -196,7 +196,7 @@ func ExchangeThirdPartyInvite(
// necessary data to do so.
func createInviteFrom3PIDInvite(
ctx context.Context, rsAPI api.RoomserverInternalAPI,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
inv invite, federation *gomatrixserverlib.FederationClient,
userAPI userapi.UserInternalAPI,
) (*gomatrixserverlib.Event, error) {
@@ -263,7 +263,7 @@ func createInviteFrom3PIDInvite(
func buildMembershipEvent(
ctx context.Context,
builder *gomatrixserverlib.EventBuilder, rsAPI api.RoomserverInternalAPI,
- cfg *config.Dendrite,
+ cfg *config.FederationAPI,
) (*gomatrixserverlib.Event, error) {
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
if err != nil {
@@ -327,7 +327,7 @@ func buildMembershipEvent(
// them responded with an error.
func sendToRemoteServer(
ctx context.Context, inv invite,
- federation *gomatrixserverlib.FederationClient, _ *config.Dendrite,
+ federation *gomatrixserverlib.FederationClient, _ *config.FederationAPI,
builder gomatrixserverlib.EventBuilder,
) (err error) {
remoteServers := make([]gomatrixserverlib.ServerName, 2)
diff --git a/federationsender/consumers/eduserver.go b/federationsender/consumers/eduserver.go
index 7b539530..74ce65db 100644
--- a/federationsender/consumers/eduserver.go
+++ b/federationsender/consumers/eduserver.go
@@ -43,27 +43,27 @@ type OutputEDUConsumer struct {
// NewOutputEDUConsumer creates a new OutputEDUConsumer. Call Start() to begin consuming from EDU servers.
func NewOutputEDUConsumer(
- cfg *config.Dendrite,
+ cfg *config.FederationSender,
kafkaConsumer sarama.Consumer,
queues *queue.OutgoingQueues,
store storage.Database,
) *OutputEDUConsumer {
c := &OutputEDUConsumer{
typingConsumer: &internal.ContinualConsumer{
- Topic: string(cfg.Kafka.Topics.OutputTypingEvent),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputTypingEvent),
Consumer: kafkaConsumer,
PartitionStore: store,
},
sendToDeviceConsumer: &internal.ContinualConsumer{
- Topic: string(cfg.Kafka.Topics.OutputSendToDeviceEvent),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputSendToDeviceEvent),
Consumer: kafkaConsumer,
PartitionStore: store,
},
queues: queues,
db: store,
ServerName: cfg.Matrix.ServerName,
- TypingTopic: string(cfg.Kafka.Topics.OutputTypingEvent),
- SendToDeviceTopic: string(cfg.Kafka.Topics.OutputSendToDeviceEvent),
+ TypingTopic: string(cfg.Matrix.Kafka.Topics.OutputTypingEvent),
+ SendToDeviceTopic: string(cfg.Matrix.Kafka.Topics.OutputSendToDeviceEvent),
}
c.typingConsumer.ProcessMessage = c.onTypingEvent
c.sendToDeviceConsumer.ProcessMessage = c.onSendToDeviceEvent
diff --git a/federationsender/consumers/keychange.go b/federationsender/consumers/keychange.go
index d33a6e07..8060125e 100644
--- a/federationsender/consumers/keychange.go
+++ b/federationsender/consumers/keychange.go
@@ -41,7 +41,7 @@ type KeyChangeConsumer struct {
// NewKeyChangeConsumer creates a new KeyChangeConsumer. Call Start() to begin consuming from key servers.
func NewKeyChangeConsumer(
- cfg *config.Dendrite,
+ cfg *config.KeyServer,
kafkaConsumer sarama.Consumer,
queues *queue.OutgoingQueues,
store storage.Database,
@@ -49,7 +49,7 @@ func NewKeyChangeConsumer(
) *KeyChangeConsumer {
c := &KeyChangeConsumer{
consumer: &internal.ContinualConsumer{
- Topic: string(cfg.Kafka.Topics.OutputKeyChangeEvent),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputKeyChangeEvent),
Consumer: kafkaConsumer,
PartitionStore: store,
},
diff --git a/federationsender/consumers/roomserver.go b/federationsender/consumers/roomserver.go
index 299c7b37..b3a4cde3 100644
--- a/federationsender/consumers/roomserver.go
+++ b/federationsender/consumers/roomserver.go
@@ -33,7 +33,7 @@ import (
// OutputRoomEventConsumer consumes events that originated in the room server.
type OutputRoomEventConsumer struct {
- cfg *config.Dendrite
+ cfg *config.FederationSender
rsAPI api.RoomserverInternalAPI
rsConsumer *internal.ContinualConsumer
db storage.Database
@@ -42,14 +42,14 @@ type OutputRoomEventConsumer struct {
// NewOutputRoomEventConsumer creates a new OutputRoomEventConsumer. Call Start() to begin consuming from room servers.
func NewOutputRoomEventConsumer(
- cfg *config.Dendrite,
+ cfg *config.FederationSender,
kafkaConsumer sarama.Consumer,
queues *queue.OutgoingQueues,
store storage.Database,
rsAPI api.RoomserverInternalAPI,
) *OutputRoomEventConsumer {
consumer := internal.ContinualConsumer{
- Topic: string(cfg.Kafka.Topics.OutputRoomEvent),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputRoomEvent),
Consumer: kafkaConsumer,
PartitionStore: store,
}
diff --git a/federationsender/federationsender.go b/federationsender/federationsender.go
index fbf506aa..b02686fe 100644
--- a/federationsender/federationsender.go
+++ b/federationsender/federationsender.go
@@ -45,27 +45,29 @@ func NewInternalAPI(
stateAPI stateapi.CurrentStateInternalAPI,
keyRing *gomatrixserverlib.KeyRing,
) api.FederationSenderInternalAPI {
- federationSenderDB, err := storage.NewDatabase(string(base.Cfg.Database.FederationSender), base.Cfg.DbProperties())
+ cfg := &base.Cfg.FederationSender
+
+ federationSenderDB, err := storage.NewDatabase(&cfg.Database)
if err != nil {
logrus.WithError(err).Panic("failed to connect to federation sender db")
}
stats := &statistics.Statistics{
DB: federationSenderDB,
- FailuresUntilBlacklist: base.Cfg.Matrix.FederationMaxRetries,
+ FailuresUntilBlacklist: cfg.FederationMaxRetries,
}
queues := queue.NewOutgoingQueues(
- federationSenderDB, base.Cfg.Matrix.ServerName, federation, rsAPI, stats,
+ federationSenderDB, cfg.Matrix.ServerName, federation, rsAPI, stats,
&queue.SigningInfo{
- KeyID: base.Cfg.Matrix.KeyID,
- PrivateKey: base.Cfg.Matrix.PrivateKey,
- ServerName: base.Cfg.Matrix.ServerName,
+ KeyID: cfg.Matrix.KeyID,
+ PrivateKey: cfg.Matrix.PrivateKey,
+ ServerName: cfg.Matrix.ServerName,
},
)
rsConsumer := consumers.NewOutputRoomEventConsumer(
- base.Cfg, base.KafkaConsumer, queues,
+ cfg, base.KafkaConsumer, queues,
federationSenderDB, rsAPI,
)
if err = rsConsumer.Start(); err != nil {
@@ -73,17 +75,17 @@ func NewInternalAPI(
}
tsConsumer := consumers.NewOutputEDUConsumer(
- base.Cfg, base.KafkaConsumer, queues, federationSenderDB,
+ cfg, base.KafkaConsumer, queues, federationSenderDB,
)
if err := tsConsumer.Start(); err != nil {
logrus.WithError(err).Panic("failed to start typing server consumer")
}
keyConsumer := consumers.NewKeyChangeConsumer(
- base.Cfg, base.KafkaConsumer, queues, federationSenderDB, stateAPI,
+ &base.Cfg.KeyServer, base.KafkaConsumer, queues, federationSenderDB, stateAPI,
)
if err := keyConsumer.Start(); err != nil {
logrus.WithError(err).Panic("failed to start key server consumer")
}
- return internal.NewFederationSenderInternalAPI(federationSenderDB, base.Cfg, rsAPI, federation, keyRing, stats, queues)
+ return internal.NewFederationSenderInternalAPI(federationSenderDB, cfg, rsAPI, federation, keyRing, stats, queues)
}
diff --git a/federationsender/internal/api.go b/federationsender/internal/api.go
index 9a9880ce..647e3fcb 100644
--- a/federationsender/internal/api.go
+++ b/federationsender/internal/api.go
@@ -12,7 +12,7 @@ import (
// FederationSenderInternalAPI is an implementation of api.FederationSenderInternalAPI
type FederationSenderInternalAPI struct {
db storage.Database
- cfg *config.Dendrite
+ cfg *config.FederationSender
statistics *statistics.Statistics
rsAPI api.RoomserverInternalAPI
federation *gomatrixserverlib.FederationClient
@@ -21,7 +21,7 @@ type FederationSenderInternalAPI struct {
}
func NewFederationSenderInternalAPI(
- db storage.Database, cfg *config.Dendrite,
+ db storage.Database, cfg *config.FederationSender,
rsAPI api.RoomserverInternalAPI,
federation *gomatrixserverlib.FederationClient,
keyRing *gomatrixserverlib.KeyRing,
diff --git a/federationsender/storage/postgres/storage.go b/federationsender/storage/postgres/storage.go
index a3094bda..b65ff0b6 100644
--- a/federationsender/storage/postgres/storage.go
+++ b/federationsender/storage/postgres/storage.go
@@ -19,6 +19,7 @@ import (
"database/sql"
"github.com/matrix-org/dendrite/federationsender/storage/shared"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
)
@@ -30,10 +31,10 @@ type Database struct {
}
// NewDatabase opens a new database
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) {
var d Database
var err error
- if d.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil {
+ if d.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
joinedHosts, err := NewPostgresJoinedHostsTable(d.db)
diff --git a/federationsender/storage/sqlite3/storage.go b/federationsender/storage/sqlite3/storage.go
index c303d094..41b91871 100644
--- a/federationsender/storage/sqlite3/storage.go
+++ b/federationsender/storage/sqlite3/storage.go
@@ -21,6 +21,7 @@ import (
_ "github.com/mattn/go-sqlite3"
"github.com/matrix-org/dendrite/federationsender/storage/shared"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
)
@@ -32,14 +33,10 @@ type Database struct {
}
// NewDatabase opens a new database
-func NewDatabase(dataSourceName string) (*Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions) (*Database, error) {
var d Database
var err error
- cs, err := sqlutil.ParseFileURI(dataSourceName)
- if err != nil {
- return nil, err
- }
- if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
+ if d.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
joinedHosts, err := NewSQLiteJoinedHostsTable(d.db)
diff --git a/federationsender/storage/storage.go b/federationsender/storage/storage.go
index d3736005..1380fefd 100644
--- a/federationsender/storage/storage.go
+++ b/federationsender/storage/storage.go
@@ -17,25 +17,21 @@
package storage
import (
- "net/url"
+ "fmt"
"github.com/matrix-org/dendrite/federationsender/storage/postgres"
"github.com/matrix-org/dendrite/federationsender/storage/sqlite3"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
)
// NewDatabase opens a new database
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.NewDatabase(dataSourceName, dbProperties)
- }
- switch uri.Scheme {
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
- case "postgres":
- return postgres.NewDatabase(dataSourceName, dbProperties)
+func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.NewDatabase(dbProperties)
default:
- return postgres.NewDatabase(dataSourceName, dbProperties)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/federationsender/storage/storage_wasm.go b/federationsender/storage/storage_wasm.go
index e5c8f293..459329e9 100644
--- a/federationsender/storage/storage_wasm.go
+++ b/federationsender/storage/storage_wasm.go
@@ -16,27 +16,19 @@ package storage
import (
"fmt"
- "net/url"
"github.com/matrix-org/dendrite/federationsender/storage/sqlite3"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
)
// NewDatabase opens a new database
-func NewDatabase(
- dataSourceName string,
- dbProperties sqlutil.DbProperties, // nolint:unparam
-) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return nil, fmt.Errorf("Cannot use postgres implementation")
- }
- switch uri.Scheme {
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
- case "postgres":
- return nil, fmt.Errorf("Cannot use postgres implementation")
+func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return nil, fmt.Errorf("can't use Postgres implementation")
default:
- return nil, fmt.Errorf("Cannot use postgres implementation")
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/go.mod b/go.mod
index 2f301e04..d5cf9171 100644
--- a/go.mod
+++ b/go.mod
@@ -2,7 +2,9 @@ module github.com/matrix-org/dendrite
require (
github.com/Shopify/sarama v1.26.1
+ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
+ github.com/ghodss/yaml v1.0.0
github.com/gologme/log v1.2.0
github.com/gorilla/mux v1.7.3
github.com/hashicorp/golang-lru v0.5.4
@@ -40,7 +42,7 @@ require (
go.uber.org/atomic v1.4.0
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5
gopkg.in/h2non/bimg.v1 v1.0.18
- gopkg.in/yaml.v2 v2.2.8
+ gopkg.in/yaml.v2 v2.3.0
)
go 1.13
diff --git a/go.sum b/go.sum
index bc3bb195..8ed62ffd 100644
--- a/go.sum
+++ b/go.sum
@@ -51,6 +51,9 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/cheggaaa/pb/v3 v3.0.4/go.mod h1:7rgWxLrAUcFMkvJuv09+DYi7mMUYi8nO9iOWcvGJPfw=
+github.com/circonus-labs/circonus-gometrics v1.2.0 h1:Kqa/+nIJhqFJ12B07aeekgC6F95J7yYgEtpD57NQzrE=
+github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY=
+github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
@@ -91,6 +94,7 @@ github.com/frankban/quicktest v1.7.2 h1:2QxQoC1TS09S7fhCPsrvqYdvP1H5M1P1ih5ABm3B
github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
@@ -857,6 +861,8 @@ gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099 h1:XJP7lxbSxWLOMNdBE4B/STaqVy6L73o0knwj2vIlxnw=
diff --git a/internal/config/config.go b/internal/config/config.go
index 900d3b14..cf9168f7 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -24,7 +24,6 @@ import (
"path/filepath"
"regexp"
"strings"
- "time"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/gomatrixserverlib"
@@ -38,7 +37,7 @@ import (
// Version is the current version of the config format.
// This will change whenever we make breaking changes to the config format.
-const Version = 0
+const Version = 1
// Dendrite contains all the config used by a dendrite process.
// Relative paths are resolved relative to the current working directory
@@ -51,217 +50,19 @@ type Dendrite struct {
// been a breaking change to the config file format.
Version int `yaml:"version"`
- // The configuration required for a matrix server.
- Matrix struct {
- // The name of the server. This is usually the domain name, e.g 'matrix.org', 'localhost'.
- ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
- // Path to the private key which will be used to sign requests and events.
- PrivateKeyPath Path `yaml:"private_key"`
- // The private key which will be used to sign requests and events.
- PrivateKey ed25519.PrivateKey `yaml:"-"`
- // An arbitrary string used to uniquely identify the PrivateKey. Must start with the
- // prefix "ed25519:".
- KeyID gomatrixserverlib.KeyID `yaml:"-"`
- // List of paths to X509 certificates used by the external federation listeners.
- // These are used to calculate the TLS fingerprints to publish for this server.
- // Other matrix servers talking to this server will expect the x509 certificate
- // to match one of these certificates.
- // The certificates should be in PEM format.
- FederationCertificatePaths []Path `yaml:"federation_certificates"`
- // A list of SHA256 TLS fingerprints for the X509 certificates used by the
- // federation listener for this server.
- TLSFingerPrints []gomatrixserverlib.TLSFingerprint `yaml:"-"`
- // How long a remote server can cache our server key for before requesting it again.
- // Increasing this number will reduce the number of requests made by remote servers
- // for our key, but increases the period a compromised key will be considered valid
- // by remote servers.
- // Defaults to 24 hours.
- KeyValidityPeriod time.Duration `yaml:"key_validity_period"`
- // List of domains that the server will trust as identity servers to
- // verify third-party identifiers.
- // Defaults to an empty array.
- TrustedIDServers []string `yaml:"trusted_third_party_id_servers"`
- // If set, allows registration by anyone who also has the shared
- // secret, even if registration is otherwise disabled.
- RegistrationSharedSecret string `yaml:"registration_shared_secret"`
- // This Home Server's ReCAPTCHA public key.
- RecaptchaPublicKey string `yaml:"recaptcha_public_key"`
- // This Home Server's ReCAPTCHA private key.
- RecaptchaPrivateKey string `yaml:"recaptcha_private_key"`
- // Boolean stating whether catpcha registration is enabled
- // and required
- RecaptchaEnabled bool `yaml:"enable_registration_captcha"`
- // Secret used to bypass the captcha registration entirely
- RecaptchaBypassSecret string `yaml:"captcha_bypass_secret"`
- // HTTP API endpoint used to verify whether the captcha response
- // was successful
- RecaptchaSiteVerifyAPI string `yaml:"recaptcha_siteverify_api"`
- // If set disables new users from registering (except via shared
- // secrets)
- RegistrationDisabled bool `yaml:"registration_disabled"`
- // Perspective keyservers, to use as a backup when direct key fetch
- // requests don't succeed
- KeyPerspectives KeyPerspectives `yaml:"key_perspectives"`
- // Federation failure threshold. How many consecutive failures that we should
- // tolerate when sending federation requests to a specific server. The backoff
- // is 2**x seconds, so 1 = 2 seconds, 2 = 4 seconds, 3 = 8 seconds, etc.
- // The default value is 16 if not specified, which is circa 18 hours.
- FederationMaxRetries uint32 `yaml:"federation_max_retries"`
- // FederationDisableTLSValidation disables the validation of X.509 TLS certs
- // on remote federation endpoints. This is not recommended in production!
- FederationDisableTLSValidation bool `yaml:"federation_disable_tls_validation"`
- } `yaml:"matrix"`
-
- // The configuration specific to the media repostitory.
- Media struct {
- // The base path to where the media files will be stored. May be relative or absolute.
- BasePath Path `yaml:"base_path"`
- // The absolute base path to where media files will be stored.
- AbsBasePath Path `yaml:"-"`
- // The maximum file size in bytes that is allowed to be stored on this server.
- // Note: if max_file_size_bytes is set to 0, the size is unlimited.
- // Note: if max_file_size_bytes is not set, it will default to 10485760 (10MB)
- MaxFileSizeBytes *FileSizeBytes `yaml:"max_file_size_bytes,omitempty"`
- // Whether to dynamically generate thumbnails on-the-fly if the requested resolution is not already generated
- DynamicThumbnails bool `yaml:"dynamic_thumbnails"`
- // The maximum number of simultaneous thumbnail generators. default: 10
- MaxThumbnailGenerators int `yaml:"max_thumbnail_generators"`
- // A list of thumbnail sizes to be pre-generated for downloaded remote / uploaded content
- ThumbnailSizes []ThumbnailSize `yaml:"thumbnail_sizes"`
- } `yaml:"media"`
-
- // The configuration to use for Prometheus metrics
- Metrics struct {
- // Whether or not the metrics are enabled
- Enabled bool `yaml:"enabled"`
- // Use BasicAuth for Authorization
- BasicAuth struct {
- // Authorization via Static Username & Password
- // Hardcoded Username and Password
- Username string `yaml:"username"`
- Password string `yaml:"password"`
- } `yaml:"basic_auth"`
- } `yaml:"metrics"`
-
- // The configuration for talking to kafka.
- Kafka struct {
- // A list of kafka addresses to connect to.
- Addresses []string `yaml:"addresses"`
- // Whether to use naffka instead of kafka.
- // Naffka can only be used when running dendrite as a single monolithic server.
- // Kafka can be used both with a monolithic server and when running the
- // components as separate servers.
- UseNaffka bool `yaml:"use_naffka,omitempty"`
- // The names of the topics to use when reading and writing from kafka.
- Topics struct {
- // Topic for roomserver/api.OutputRoomEvent events.
- OutputRoomEvent Topic `yaml:"output_room_event"`
- // Topic for sending account data from client API to sync API
- OutputClientData Topic `yaml:"output_client_data"`
- // Topic for eduserver/api.OutputTypingEvent events.
- OutputTypingEvent Topic `yaml:"output_typing_event"`
- // Topic for eduserver/api.OutputSendToDeviceEvent events.
- OutputSendToDeviceEvent Topic `yaml:"output_send_to_device_event"`
- // Topic for keyserver when new device keys are added.
- OutputKeyChangeEvent Topic `yaml:"output_key_change_event"`
- }
- } `yaml:"kafka"`
-
- // Postgres Config
- Database struct {
- // The Account database stores the login details and account information
- // for local users. It is accessed by the UserAPI.
- Account DataSource `yaml:"account"`
- // The CurrentState database stores the current state of all rooms.
- // It is accessed by the CurrentStateServer.
- CurrentState DataSource `yaml:"current_state"`
- // The Device database stores session information for the devices of logged
- // in local users. It is accessed by the UserAPI.
- Device DataSource `yaml:"device"`
- // The MediaAPI database stores information about files uploaded and downloaded
- // by local users. It is only accessed by the MediaAPI.
- MediaAPI DataSource `yaml:"media_api"`
- // The ServerKey database caches the public keys of remote servers.
- // It may be accessed by the FederationAPI, the ClientAPI, and the MediaAPI.
- ServerKey DataSource `yaml:"server_key"`
- // The E2EKey database stores one-time public keys for devices in addition to
- // signed device keys. Used for E2E.
- E2EKey DataSource `yaml:"e2e_key"`
- // The SyncAPI stores information used by the SyncAPI server.
- // It is only accessed by the SyncAPI server.
- SyncAPI DataSource `yaml:"sync_api"`
- // The RoomServer database stores information about matrix rooms.
- // It is only accessed by the RoomServer.
- RoomServer DataSource `yaml:"room_server"`
- // The FederationSender database stores information used by the FederationSender
- // It is only accessed by the FederationSender.
- FederationSender DataSource `yaml:"federation_sender"`
- // The AppServices database stores information used by the AppService component.
- // It is only accessed by the AppService component.
- AppService DataSource `yaml:"appservice"`
- // The Naffka database is used internally by the naffka library, if used.
- Naffka DataSource `yaml:"naffka,omitempty"`
- // Maximum open connections to the DB (0 = use default, negative means unlimited)
- MaxOpenConns int `yaml:"max_open_conns"`
- // Maximum idle connections to the DB (0 = use default, negative means unlimited)
- MaxIdleConns int `yaml:"max_idle_conns"`
- // maximum amount of time (in seconds) a connection may be reused (<= 0 means unlimited)
- ConnMaxLifetimeSec int `yaml:"conn_max_lifetime"`
- } `yaml:"database"`
-
- // TURN Server Config
- TURN struct {
- // TODO Guest Support
- // Whether or not guests can request TURN credentials
- //AllowGuests bool `yaml:"turn_allow_guests"`
- // How long the authorization should last
- UserLifetime string `yaml:"turn_user_lifetime"`
- // The list of TURN URIs to pass to clients
- URIs []string `yaml:"turn_uris"`
-
- // Authorization via Shared Secret
- // The shared secret from coturn
- SharedSecret string `yaml:"turn_shared_secret"`
-
- // Authorization via Static Username & Password
- // Hardcoded Username and Password
- Username string `yaml:"turn_username"`
- Password string `yaml:"turn_password"`
- } `yaml:"turn"`
-
- // The internal addresses the components will listen on.
- // These should not be exposed externally as they expose metrics and debugging APIs.
- // Falls back to addresses listed in Listen if not specified
- Bind struct {
- MediaAPI Address `yaml:"media_api"`
- ClientAPI Address `yaml:"client_api"`
- CurrentState Address `yaml:"current_state_server"`
- FederationAPI Address `yaml:"federation_api"`
- ServerKeyAPI Address `yaml:"server_key_api"`
- AppServiceAPI Address `yaml:"appservice_api"`
- SyncAPI Address `yaml:"sync_api"`
- UserAPI Address `yaml:"user_api"`
- RoomServer Address `yaml:"room_server"`
- FederationSender Address `yaml:"federation_sender"`
- EDUServer Address `yaml:"edu_server"`
- KeyServer Address `yaml:"key_server"`
- } `yaml:"bind"`
-
- // The addresses for talking to other microservices.
- Listen struct {
- MediaAPI Address `yaml:"media_api"`
- ClientAPI Address `yaml:"client_api"`
- CurrentState Address `yaml:"current_state_server"`
- FederationAPI Address `yaml:"federation_api"`
- ServerKeyAPI Address `yaml:"server_key_api"`
- AppServiceAPI Address `yaml:"appservice_api"`
- SyncAPI Address `yaml:"sync_api"`
- UserAPI Address `yaml:"user_api"`
- RoomServer Address `yaml:"room_server"`
- FederationSender Address `yaml:"federation_sender"`
- EDUServer Address `yaml:"edu_server"`
- KeyServer Address `yaml:"key_server"`
- } `yaml:"listen"`
+ Global Global `yaml:"global"`
+ AppServiceAPI AppServiceAPI `yaml:"app_service_api"`
+ ClientAPI ClientAPI `yaml:"client_api"`
+ CurrentStateServer CurrentStateServer `yaml:"current_state_server"`
+ EDUServer EDUServer `yaml:"edu_server"`
+ FederationAPI FederationAPI `yaml:"federation_api"`
+ FederationSender FederationSender `yaml:"federation_sender"`
+ KeyServer KeyServer `yaml:"key_server"`
+ MediaAPI MediaAPI `yaml:"media_api"`
+ RoomServer RoomServer `yaml:"room_server"`
+ ServerKeyAPI ServerKeyAPI `yaml:"server_key_api"`
+ SyncAPI SyncAPI `yaml:"sync_api"`
+ UserAPI UserAPI `yaml:"user_api"`
// The config for tracing the dendrite servers.
Tracing struct {
@@ -271,56 +72,42 @@ type Dendrite struct {
Jaeger jaegerconfig.Configuration `yaml:"jaeger"`
} `yaml:"tracing"`
- // Application Services
- // https://matrix.org/docs/spec/application_service/unstable.html
- ApplicationServices struct {
- // Configuration files for various application services
- ConfigFiles []string `yaml:"config_files"`
- } `yaml:"application_services"`
-
// The config for logging informations. Each hook will be added to logrus.
Logging []LogrusHook `yaml:"logging"`
- // The config for setting a proxy to use for server->server requests
- Proxy *struct {
- // The protocol for the proxy (http / https / socks5)
- Protocol string `yaml:"protocol"`
- // The host where the proxy is listening
- Host string `yaml:"host"`
- // The port on which the proxy is listening
- Port uint16 `yaml:"port"`
- } `yaml:"proxy"`
-
// Any information derived from the configuration options for later use.
- Derived struct {
- Registration struct {
- // Flows is a slice of flows, which represent one possible way that the client can authenticate a request.
- // http://matrix.org/docs/spec/HEAD/client_server/r0.3.0.html#user-interactive-authentication-api
- // As long as the generated flows only rely on config file options,
- // we can generate them on startup and store them until needed
- Flows []authtypes.Flow `json:"flows"`
-
- // Params that need to be returned to the client during
- // registration in order to complete registration stages.
- Params map[string]interface{} `json:"params"`
- }
+ Derived Derived `yaml:"-"`
+}
- // Application services parsed from their config files
- // The paths of which were given above in the main config file
- ApplicationServices []ApplicationService
+// TODO: Kill Derived
+type Derived struct {
+ Registration struct {
+ // Flows is a slice of flows, which represent one possible way that the client can authenticate a request.
+ // http://matrix.org/docs/spec/HEAD/client_server/r0.3.0.html#user-interactive-authentication-api
+ // As long as the generated flows only rely on config file options,
+ // we can generate them on startup and store them until needed
+ Flows []authtypes.Flow `json:"flows"`
+
+ // Params that need to be returned to the client during
+ // registration in order to complete registration stages.
+ Params map[string]interface{} `json:"params"`
+ }
- // Meta-regexes compiled from all exclusive application service
- // Regexes.
- //
- // When a user registers, we check that their username does not match any
- // exclusive application service namespaces
- ExclusiveApplicationServicesUsernameRegexp *regexp.Regexp
- // When a user creates a room alias, we check that it isn't already
- // reserved by an application service
- ExclusiveApplicationServicesAliasRegexp *regexp.Regexp
- // Note: An Exclusive Regex for room ID isn't necessary as we aren't blocking
- // servers from creating RoomIDs in exclusive application service namespaces
- } `yaml:"-"`
+ // Application services parsed from their config files
+ // The paths of which were given above in the main config file
+ ApplicationServices []ApplicationService
+
+ // Meta-regexes compiled from all exclusive application service
+ // Regexes.
+ //
+ // When a user registers, we check that their username does not match any
+ // exclusive application service namespaces
+ ExclusiveApplicationServicesUsernameRegexp *regexp.Regexp
+ // When a user creates a room alias, we check that it isn't already
+ // reserved by an application service
+ ExclusiveApplicationServicesAliasRegexp *regexp.Regexp
+ // Note: An Exclusive Regex for room ID isn't necessary as we aren't blocking
+ // servers from creating RoomIDs in exclusive application service namespaces
}
// KeyPerspectives are used to configure perspective key servers for
@@ -344,6 +131,16 @@ type Path string
// A DataSource for opening a postgresql database using lib/pq.
type DataSource string
+func (d DataSource) IsSQLite() bool {
+ return strings.HasPrefix(string(d), "file:")
+}
+
+func (d DataSource) IsPostgres() bool {
+ // commented line may not always be true?
+ // return strings.HasPrefix(string(d), "postgres:")
+ return !d.IsSQLite()
+}
+
// A Topic in kafka.
type Topic string
@@ -379,9 +176,9 @@ type LogrusHook struct {
Params map[string]interface{} `yaml:"params"`
}
-// configErrors stores problems encountered when parsing a config file.
+// ConfigErrors stores problems encountered when parsing a config file.
// It implements the error interface.
-type configErrors []string
+type ConfigErrors []string
// Load a yaml config file for a server run as multiple processes or as a monolith.
// Checks the config to ensure that it is valid.
@@ -405,29 +202,29 @@ func loadConfig(
readFile func(string) ([]byte, error),
monolithic bool,
) (*Dendrite, error) {
- var config Dendrite
+ var c Dendrite
+ c.Defaults()
+
var err error
- if err = yaml.Unmarshal(configData, &config); err != nil {
+ if err = yaml.Unmarshal(configData, &c); err != nil {
return nil, err
}
- config.SetDefaults()
-
- if err = config.check(monolithic); err != nil {
+ if err = c.check(monolithic); err != nil {
return nil, err
}
- privateKeyPath := absPath(basePath, config.Matrix.PrivateKeyPath)
+ privateKeyPath := absPath(basePath, c.Global.PrivateKeyPath)
privateKeyData, err := readFile(privateKeyPath)
if err != nil {
return nil, err
}
- if config.Matrix.KeyID, config.Matrix.PrivateKey, err = readKeyPEM(privateKeyPath, privateKeyData); err != nil {
+ if c.Global.KeyID, c.Global.PrivateKey, err = readKeyPEM(privateKeyPath, privateKeyData); err != nil {
return nil, err
}
- for _, certPath := range config.Matrix.FederationCertificatePaths {
+ for _, certPath := range c.FederationAPI.FederationCertificatePaths {
absCertPath := absPath(basePath, certPath)
var pemData []byte
pemData, err = readFile(absCertPath)
@@ -438,18 +235,19 @@ func loadConfig(
if fingerprint == nil {
return nil, fmt.Errorf("no certificate PEM data in %q", absCertPath)
}
- config.Matrix.TLSFingerPrints = append(config.Matrix.TLSFingerPrints, *fingerprint)
+ c.FederationAPI.TLSFingerPrints = append(c.FederationAPI.TLSFingerPrints, *fingerprint)
}
- config.Media.AbsBasePath = Path(absPath(basePath, config.Media.BasePath))
+ c.MediaAPI.AbsBasePath = Path(absPath(basePath, c.MediaAPI.BasePath))
// Generate data from config options
- err = config.Derive()
+ err = c.Derive()
if err != nil {
return nil, err
}
- return &config, nil
+ c.Wiring()
+ return &c, nil
}
// Derive generates data that is derived from various values provided in
@@ -462,8 +260,8 @@ func (config *Dendrite) Derive() error {
// TODO: Add email auth type
// TODO: Add MSISDN auth type
- if config.Matrix.RecaptchaEnabled {
- config.Derived.Registration.Params[authtypes.LoginTypeRecaptcha] = map[string]string{"public_key": config.Matrix.RecaptchaPublicKey}
+ if config.ClientAPI.RecaptchaEnabled {
+ config.Derived.Registration.Params[authtypes.LoginTypeRecaptcha] = map[string]string{"public_key": config.ClientAPI.RecaptchaPublicKey}
config.Derived.Registration.Flows = append(config.Derived.Registration.Flows,
authtypes.Flow{Stages: []authtypes.LoginType{authtypes.LoginTypeRecaptcha}})
} else {
@@ -472,7 +270,7 @@ func (config *Dendrite) Derive() error {
}
// Load application service configuration files
- if err := loadAppServices(config); err != nil {
+ if err := loadAppServices(&config.AppServiceAPI, &config.Derived); err != nil {
return err
}
@@ -480,41 +278,62 @@ func (config *Dendrite) Derive() error {
}
// SetDefaults sets default config values if they are not explicitly set.
-func (config *Dendrite) SetDefaults() {
- if config.Matrix.KeyValidityPeriod == 0 {
- config.Matrix.KeyValidityPeriod = 24 * time.Hour
- }
-
- if config.Matrix.TrustedIDServers == nil {
- config.Matrix.TrustedIDServers = []string{}
- }
-
- if config.Matrix.FederationMaxRetries == 0 {
- config.Matrix.FederationMaxRetries = 16
- }
-
- if config.Media.MaxThumbnailGenerators == 0 {
- config.Media.MaxThumbnailGenerators = 10
- }
-
- if config.Media.MaxFileSizeBytes == nil {
- defaultMaxFileSizeBytes := FileSizeBytes(10485760)
- config.Media.MaxFileSizeBytes = &defaultMaxFileSizeBytes
- }
-
- if config.Database.MaxIdleConns == 0 {
- config.Database.MaxIdleConns = 2
- }
-
- if config.Database.MaxOpenConns == 0 {
- config.Database.MaxOpenConns = 100
- }
-
+func (c *Dendrite) Defaults() {
+ c.Version = 1
+
+ c.Global.Defaults()
+ c.ClientAPI.Defaults()
+ c.CurrentStateServer.Defaults()
+ c.EDUServer.Defaults()
+ c.FederationAPI.Defaults()
+ c.FederationSender.Defaults()
+ c.KeyServer.Defaults()
+ c.MediaAPI.Defaults()
+ c.RoomServer.Defaults()
+ c.ServerKeyAPI.Defaults()
+ c.SyncAPI.Defaults()
+ c.UserAPI.Defaults()
+ c.AppServiceAPI.Defaults()
+
+ c.Wiring()
+}
+
+func (c *Dendrite) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ type verifiable interface {
+ Verify(configErrs *ConfigErrors, isMonolith bool)
+ }
+ for _, c := range []verifiable{
+ &c.Global, &c.ClientAPI, &c.CurrentStateServer,
+ &c.EDUServer, &c.FederationAPI, &c.FederationSender,
+ &c.KeyServer, &c.MediaAPI, &c.RoomServer,
+ &c.ServerKeyAPI, &c.SyncAPI, &c.UserAPI,
+ &c.AppServiceAPI,
+ } {
+ c.Verify(configErrs, isMonolith)
+ }
+}
+
+func (c *Dendrite) Wiring() {
+ c.ClientAPI.Matrix = &c.Global
+ c.CurrentStateServer.Matrix = &c.Global
+ c.EDUServer.Matrix = &c.Global
+ c.FederationAPI.Matrix = &c.Global
+ c.FederationSender.Matrix = &c.Global
+ c.KeyServer.Matrix = &c.Global
+ c.MediaAPI.Matrix = &c.Global
+ c.RoomServer.Matrix = &c.Global
+ c.ServerKeyAPI.Matrix = &c.Global
+ c.SyncAPI.Matrix = &c.Global
+ c.UserAPI.Matrix = &c.Global
+ c.AppServiceAPI.Matrix = &c.Global
+
+ c.ClientAPI.Derived = &c.Derived
+ c.AppServiceAPI.Derived = &c.Derived
}
// Error returns a string detailing how many errors were contained within a
// configErrors type.
-func (errs configErrors) Error() string {
+func (errs ConfigErrors) Error() string {
if len(errs) == 1 {
return errs[0]
}
@@ -528,13 +347,13 @@ func (errs configErrors) Error() string {
// the client code.
// This method is safe to use with an uninitialized configErrors because
// if it is nil, it will be properly allocated.
-func (errs *configErrors) Add(str string) {
+func (errs *ConfigErrors) Add(str string) {
*errs = append(*errs, str)
}
// checkNotEmpty verifies the given value is not empty in the configuration.
// If it is, adds an error to the list.
-func checkNotEmpty(configErrs *configErrors, key, value string) {
+func checkNotEmpty(configErrs *ConfigErrors, key, value string) {
if value == "" {
configErrs.Add(fmt.Sprintf("missing config key %q", key))
}
@@ -542,7 +361,7 @@ func checkNotEmpty(configErrs *configErrors, key, value string) {
// checkNotZero verifies the given value is not zero in the configuration.
// If it is, adds an error to the list.
-func checkNotZero(configErrs *configErrors, key string, value int64) {
+func checkNotZero(configErrs *ConfigErrors, key string, value int64) {
if value == 0 {
configErrs.Add(fmt.Sprintf("missing config key %q", key))
}
@@ -550,96 +369,14 @@ func checkNotZero(configErrs *configErrors, key string, value int64) {
// checkPositive verifies the given value is positive (zero included)
// in the configuration. If it is not, adds an error to the list.
-func checkPositive(configErrs *configErrors, key string, value int64) {
+func checkPositive(configErrs *ConfigErrors, key string, value int64) {
if value < 0 {
configErrs.Add(fmt.Sprintf("invalid value for config key %q: %d", key, value))
}
}
-// checkTurn verifies the parameters turn.* are valid.
-func (config *Dendrite) checkTurn(configErrs *configErrors) {
- value := config.TURN.UserLifetime
- if value != "" {
- if _, err := time.ParseDuration(value); err != nil {
- configErrs.Add(fmt.Sprintf("invalid duration for config key %q: %s", "turn.turn_user_lifetime", value))
- }
- }
-}
-
-// checkMatrix verifies the parameters matrix.* are valid.
-func (config *Dendrite) checkMatrix(configErrs *configErrors) {
- checkNotEmpty(configErrs, "matrix.server_name", string(config.Matrix.ServerName))
- checkNotEmpty(configErrs, "matrix.private_key", string(config.Matrix.PrivateKeyPath))
- checkNotZero(configErrs, "matrix.federation_certificates", int64(len(config.Matrix.FederationCertificatePaths)))
- if config.Matrix.RecaptchaEnabled {
- checkNotEmpty(configErrs, "matrix.recaptcha_public_key", string(config.Matrix.RecaptchaPublicKey))
- checkNotEmpty(configErrs, "matrix.recaptcha_private_key", string(config.Matrix.RecaptchaPrivateKey))
- checkNotEmpty(configErrs, "matrix.recaptcha_siteverify_api", string(config.Matrix.RecaptchaSiteVerifyAPI))
- }
-}
-
-// checkMedia verifies the parameters media.* are valid.
-func (config *Dendrite) checkMedia(configErrs *configErrors) {
- checkNotEmpty(configErrs, "media.base_path", string(config.Media.BasePath))
- checkPositive(configErrs, "media.max_file_size_bytes", int64(*config.Media.MaxFileSizeBytes))
- checkPositive(configErrs, "media.max_thumbnail_generators", int64(config.Media.MaxThumbnailGenerators))
-
- for i, size := range config.Media.ThumbnailSizes {
- checkPositive(configErrs, fmt.Sprintf("media.thumbnail_sizes[%d].width", i), int64(size.Width))
- checkPositive(configErrs, fmt.Sprintf("media.thumbnail_sizes[%d].height", i), int64(size.Height))
- }
-}
-
-// checkKafka verifies the parameters kafka.* and the related
-// database.naffka are valid.
-func (config *Dendrite) checkKafka(configErrs *configErrors, monolithic bool) {
-
- if config.Kafka.UseNaffka {
- if !monolithic {
- configErrs.Add(fmt.Sprintf("naffka can only be used in a monolithic server"))
- }
-
- checkNotEmpty(configErrs, "database.naffka", string(config.Database.Naffka))
- } else {
- // If we aren't using naffka then we need to have at least one kafka
- // server to talk to.
- checkNotZero(configErrs, "kafka.addresses", int64(len(config.Kafka.Addresses)))
- }
- checkNotEmpty(configErrs, "kafka.topics.output_room_event", string(config.Kafka.Topics.OutputRoomEvent))
- checkNotEmpty(configErrs, "kafka.topics.output_client_data", string(config.Kafka.Topics.OutputClientData))
- checkNotEmpty(configErrs, "kafka.topics.output_typing_event", string(config.Kafka.Topics.OutputTypingEvent))
- checkNotEmpty(configErrs, "kafka.topics.output_send_to_device_event", string(config.Kafka.Topics.OutputSendToDeviceEvent))
- checkNotEmpty(configErrs, "kafka.topics.output_key_change_event", string(config.Kafka.Topics.OutputKeyChangeEvent))
-}
-
-// checkDatabase verifies the parameters database.* are valid.
-func (config *Dendrite) checkDatabase(configErrs *configErrors) {
- checkNotEmpty(configErrs, "database.account", string(config.Database.Account))
- checkNotEmpty(configErrs, "database.device", string(config.Database.Device))
- checkNotEmpty(configErrs, "database.server_key", string(config.Database.ServerKey))
- checkNotEmpty(configErrs, "database.media_api", string(config.Database.MediaAPI))
- checkNotEmpty(configErrs, "database.sync_api", string(config.Database.SyncAPI))
- checkNotEmpty(configErrs, "database.room_server", string(config.Database.RoomServer))
- checkNotEmpty(configErrs, "database.current_state", string(config.Database.CurrentState))
- checkNotEmpty(configErrs, "database.e2e_key", string(config.Database.E2EKey))
-}
-
-// checkListen verifies the parameters listen.* are valid.
-func (config *Dendrite) checkListen(configErrs *configErrors) {
- checkNotEmpty(configErrs, "listen.media_api", string(config.Listen.MediaAPI))
- checkNotEmpty(configErrs, "listen.client_api", string(config.Listen.ClientAPI))
- checkNotEmpty(configErrs, "listen.federation_api", string(config.Listen.FederationAPI))
- checkNotEmpty(configErrs, "listen.sync_api", string(config.Listen.SyncAPI))
- checkNotEmpty(configErrs, "listen.room_server", string(config.Listen.RoomServer))
- checkNotEmpty(configErrs, "listen.edu_server", string(config.Listen.EDUServer))
- checkNotEmpty(configErrs, "listen.server_key_api", string(config.Listen.EDUServer))
- checkNotEmpty(configErrs, "listen.user_api", string(config.Listen.UserAPI))
- checkNotEmpty(configErrs, "listen.current_state_server", string(config.Listen.CurrentState))
- checkNotEmpty(configErrs, "listen.key_server", string(config.Listen.KeyServer))
-}
-
// checkLogging verifies the parameters logging.* are valid.
-func (config *Dendrite) checkLogging(configErrs *configErrors) {
+func (config *Dendrite) checkLogging(configErrs *ConfigErrors) {
for _, logrusHook := range config.Logging {
checkNotEmpty(configErrs, "logging.type", string(logrusHook.Type))
checkNotEmpty(configErrs, "logging.level", string(logrusHook.Level))
@@ -648,8 +385,8 @@ func (config *Dendrite) checkLogging(configErrs *configErrors) {
// check returns an error type containing all errors found within the config
// file.
-func (config *Dendrite) check(monolithic bool) error {
- var configErrs configErrors
+func (config *Dendrite) check(_ bool) error { // monolithic
+ var configErrs ConfigErrors
if config.Version != Version {
configErrs.Add(fmt.Sprintf(
@@ -658,17 +395,8 @@ func (config *Dendrite) check(monolithic bool) error {
return configErrs
}
- config.checkMatrix(&configErrs)
- config.checkMedia(&configErrs)
- config.checkTurn(&configErrs)
- config.checkKafka(&configErrs, monolithic)
- config.checkDatabase(&configErrs)
config.checkLogging(&configErrs)
- if !monolithic {
- config.checkListen(&configErrs)
- }
-
// Due to how Golang manages its interface types, this condition is not redundant.
// In order to get the proper behaviour, it is necessary to return an explicit nil
// and not a nil configErrors.
@@ -737,7 +465,7 @@ func (config *Dendrite) AppServiceURL() string {
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
- return "http://" + string(config.Listen.AppServiceAPI)
+ return "http://" + string(config.AppServiceAPI.Listen)
}
// RoomServerURL returns an HTTP URL for where the roomserver is listening.
@@ -746,7 +474,7 @@ func (config *Dendrite) RoomServerURL() string {
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
- return "http://" + string(config.Listen.RoomServer)
+ return "http://" + string(config.RoomServer.Listen)
}
// UserAPIURL returns an HTTP URL for where the userapi is listening.
@@ -755,7 +483,7 @@ func (config *Dendrite) UserAPIURL() string {
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
- return "http://" + string(config.Listen.UserAPI)
+ return "http://" + string(config.UserAPI.Listen)
}
// CurrentStateAPIURL returns an HTTP URL for where the currentstateserver is listening.
@@ -764,7 +492,7 @@ func (config *Dendrite) CurrentStateAPIURL() string {
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
- return "http://" + string(config.Listen.CurrentState)
+ return "http://" + string(config.CurrentStateServer.Listen)
}
// EDUServerURL returns an HTTP URL for where the EDU server is listening.
@@ -773,7 +501,7 @@ func (config *Dendrite) EDUServerURL() string {
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
- return "http://" + string(config.Listen.EDUServer)
+ return "http://" + string(config.EDUServer.Listen)
}
// FederationSenderURL returns an HTTP URL for where the federation sender is listening.
@@ -782,7 +510,7 @@ func (config *Dendrite) FederationSenderURL() string {
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
- return "http://" + string(config.Listen.FederationSender)
+ return "http://" + string(config.FederationSender.Listen)
}
// ServerKeyAPIURL returns an HTTP URL for where the server key API is listening.
@@ -791,7 +519,7 @@ func (config *Dendrite) ServerKeyAPIURL() string {
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
- return "http://" + string(config.Listen.ServerKeyAPI)
+ return "http://" + string(config.ServerKeyAPI.Listen)
}
// KeyServerURL returns an HTTP URL for where the key server is listening.
@@ -800,7 +528,7 @@ func (config *Dendrite) KeyServerURL() string {
// If we support HTTPS we need to think of a practical way to do certificate validation.
// People setting up servers shouldn't need to get a certificate valid for the public
// internet for an internal API.
- return "http://" + string(config.Listen.KeyServer)
+ return "http://" + string(config.KeyServer.Listen)
}
// SetupTracing configures the opentracing using the supplied configuration.
@@ -815,33 +543,6 @@ func (config *Dendrite) SetupTracing(serviceName string) (closer io.Closer, err
)
}
-// MaxIdleConns returns maximum idle connections to the DB
-func (config Dendrite) MaxIdleConns() int {
- return config.Database.MaxIdleConns
-}
-
-// MaxOpenConns returns maximum open connections to the DB
-func (config Dendrite) MaxOpenConns() int {
- return config.Database.MaxOpenConns
-}
-
-// ConnMaxLifetime returns maximum amount of time a connection may be reused
-func (config Dendrite) ConnMaxLifetime() time.Duration {
- return time.Duration(config.Database.ConnMaxLifetimeSec) * time.Second
-}
-
-// DbProperties functions return properties used by database/sql/DB
-type DbProperties interface {
- MaxIdleConns() int
- MaxOpenConns() int
- ConnMaxLifetime() time.Duration
-}
-
-// DbProperties returns cfg as a DbProperties interface
-func (config Dendrite) DbProperties() DbProperties {
- return config
-}
-
// logrusLogger is a small wrapper that implements jaeger.Logger using logrus.
type logrusLogger struct {
l *logrus.Logger
diff --git a/internal/config/appservice.go b/internal/config/config_appservice.go
index bf5f089b..b8962ded 100644
--- a/internal/config/appservice.go
+++ b/internal/config/config_appservice.go
@@ -25,6 +25,31 @@ import (
yaml "gopkg.in/yaml.v2"
)
+type AppServiceAPI struct {
+ Matrix *Global `yaml:"-"`
+ Derived *Derived `yaml:"-"` // TODO: Nuke Derived from orbit
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ Database DatabaseOptions `yaml:"database"`
+
+ ConfigFiles []string `yaml:"config_files"`
+}
+
+func (c *AppServiceAPI) Defaults() {
+ c.Listen = "localhost:7777"
+ c.Bind = "localhost:7777"
+ c.Database.Defaults()
+ c.Database.ConnectionString = "file:appservice.db"
+}
+
+func (c *AppServiceAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "app_service_api.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "app_service_api.bind", string(c.Bind))
+ checkNotEmpty(configErrs, "app_service_api.database.connection_string", string(c.Database.ConnectionString))
+}
+
// ApplicationServiceNamespace is the namespace that a specific application
// service has management over.
type ApplicationServiceNamespace struct {
@@ -132,8 +157,8 @@ func (a *ApplicationService) IsInterestedInRoomAlias(
// loadAppServices iterates through all application service config files
// and loads their data into the config object for later access.
-func loadAppServices(config *Dendrite) error {
- for _, configPath := range config.ApplicationServices.ConfigFiles {
+func loadAppServices(config *AppServiceAPI, derived *Derived) error {
+ for _, configPath := range config.ConfigFiles {
// Create a new application service with default options
appservice := ApplicationService{
RateLimited: true,
@@ -157,26 +182,26 @@ func loadAppServices(config *Dendrite) error {
}
// Append the parsed application service to the global config
- config.Derived.ApplicationServices = append(
- config.Derived.ApplicationServices, appservice,
+ derived.ApplicationServices = append(
+ derived.ApplicationServices, appservice,
)
}
// Check for any errors in the loaded application services
- return checkErrors(config)
+ return checkErrors(config, derived)
}
// setupRegexps will create regex objects for exclusive and non-exclusive
// usernames, aliases and rooms of all application services, so that other
// methods can quickly check if a particular string matches any of them.
-func setupRegexps(cfg *Dendrite) (err error) {
+func setupRegexps(_ *AppServiceAPI, derived *Derived) (err error) {
// Combine all exclusive namespaces for later string checking
var exclusiveUsernameStrings, exclusiveAliasStrings []string
// If an application service's regex is marked as exclusive, add
// its contents to the overall exlusive regex string. Room regex
// not necessary as we aren't denying exclusive room ID creation
- for _, appservice := range cfg.Derived.ApplicationServices {
+ for _, appservice := range derived.ApplicationServices {
for key, namespaceSlice := range appservice.NamespaceMap {
switch key {
case "users":
@@ -204,10 +229,10 @@ func setupRegexps(cfg *Dendrite) (err error) {
}
// Store compiled Regex
- if cfg.Derived.ExclusiveApplicationServicesUsernameRegexp, err = regexp.Compile(exclusiveUsernames); err != nil {
+ if derived.ExclusiveApplicationServicesUsernameRegexp, err = regexp.Compile(exclusiveUsernames); err != nil {
return err
}
- if cfg.Derived.ExclusiveApplicationServicesAliasRegexp, err = regexp.Compile(exclusiveAliases); err != nil {
+ if derived.ExclusiveApplicationServicesAliasRegexp, err = regexp.Compile(exclusiveAliases); err != nil {
return err
}
@@ -234,7 +259,7 @@ func appendExclusiveNamespaceRegexs(
// checkErrors checks for any configuration errors amongst the loaded
// application services according to the application service spec.
-func checkErrors(config *Dendrite) (err error) {
+func checkErrors(config *AppServiceAPI, derived *Derived) (err error) {
var idMap = make(map[string]bool)
var tokenMap = make(map[string]bool)
@@ -242,7 +267,7 @@ func checkErrors(config *Dendrite) (err error) {
groupIDRegexp := regexp.MustCompile(`\+.*:.*`)
// Check each application service for any config errors
- for _, appservice := range config.Derived.ApplicationServices {
+ for _, appservice := range derived.ApplicationServices {
// Namespace-related checks
for key, namespaceSlice := range appservice.NamespaceMap {
for _, namespace := range namespaceSlice {
@@ -258,13 +283,13 @@ func checkErrors(config *Dendrite) (err error) {
// Check if we've already seen this ID. No two application services
// can have the same ID or token.
if idMap[appservice.ID] {
- return configErrors([]string{fmt.Sprintf(
+ return ConfigErrors([]string{fmt.Sprintf(
"Application service ID %s must be unique", appservice.ID,
)})
}
// Check if we've already seen this token
if tokenMap[appservice.ASToken] {
- return configErrors([]string{fmt.Sprintf(
+ return ConfigErrors([]string{fmt.Sprintf(
"Application service Token %s must be unique", appservice.ASToken,
)})
}
@@ -284,7 +309,7 @@ func checkErrors(config *Dendrite) (err error) {
}
}
- return setupRegexps(config)
+ return setupRegexps(config, derived)
}
// validateNamespace returns nil or an error based on whether a given
@@ -298,7 +323,7 @@ func validateNamespace(
) error {
// Check that namespace(s) are valid regex
if !IsValidRegex(namespace.Regex) {
- return configErrors([]string{fmt.Sprintf(
+ return ConfigErrors([]string{fmt.Sprintf(
"Invalid regex string for Application Service %s", appservice.ID,
)})
}
@@ -310,7 +335,7 @@ func validateNamespace(
correctFormat := groupIDRegexp.MatchString(namespace.GroupID)
if !correctFormat {
- return configErrors([]string{fmt.Sprintf(
+ return ConfigErrors([]string{fmt.Sprintf(
"Invalid user group_id field for application service %s.",
appservice.ID,
)})
diff --git a/internal/config/config_clientapi.go b/internal/config/config_clientapi.go
new file mode 100644
index 00000000..c441a9c0
--- /dev/null
+++ b/internal/config/config_clientapi.go
@@ -0,0 +1,87 @@
+package config
+
+import (
+ "fmt"
+ "time"
+)
+
+type ClientAPI struct {
+ Matrix *Global `yaml:"-"`
+ Derived *Derived `yaml:"-"` // TODO: Nuke Derived from orbit
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ // If set, allows registration by anyone who also has the shared
+ // secret, even if registration is otherwise disabled.
+ RegistrationSharedSecret string `yaml:"registration_shared_secret"`
+ // This Home Server's ReCAPTCHA public key.
+ RecaptchaPublicKey string `yaml:"recaptcha_public_key"`
+ // This Home Server's ReCAPTCHA private key.
+ RecaptchaPrivateKey string `yaml:"recaptcha_private_key"`
+ // Boolean stating whether catpcha registration is enabled
+ // and required
+ RecaptchaEnabled bool `yaml:"enable_registration_captcha"`
+ // Secret used to bypass the captcha registration entirely
+ RecaptchaBypassSecret string `yaml:"captcha_bypass_secret"`
+ // HTTP API endpoint used to verify whether the captcha response
+ // was successful
+ RecaptchaSiteVerifyAPI string `yaml:"recaptcha_siteverify_api"`
+ // If set disables new users from registering (except via shared
+ // secrets)
+ RegistrationDisabled bool `yaml:"registration_disabled"`
+
+ // TURN options
+ TURN TURN `yaml:"turn"`
+}
+
+func (c *ClientAPI) Defaults() {
+ c.Listen = "localhost:7771"
+ c.Bind = "localhost:7771"
+ c.RegistrationSharedSecret = ""
+ c.RecaptchaPublicKey = ""
+ c.RecaptchaPrivateKey = ""
+ c.RecaptchaEnabled = false
+ c.RecaptchaBypassSecret = ""
+ c.RecaptchaSiteVerifyAPI = ""
+ c.RegistrationDisabled = false
+}
+
+func (c *ClientAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "client_api.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "client_api.bind", string(c.Bind))
+ if c.RecaptchaEnabled {
+ checkNotEmpty(configErrs, "client_api.recaptcha_public_key", string(c.RecaptchaPublicKey))
+ checkNotEmpty(configErrs, "client_api.recaptcha_private_key", string(c.RecaptchaPrivateKey))
+ checkNotEmpty(configErrs, "client_api.recaptcha_siteverify_api", string(c.RecaptchaSiteVerifyAPI))
+ }
+ c.TURN.Verify(configErrs)
+}
+
+type TURN struct {
+ // TODO Guest Support
+ // Whether or not guests can request TURN credentials
+ // AllowGuests bool `yaml:"turn_allow_guests"`
+ // How long the authorization should last
+ UserLifetime string `yaml:"turn_user_lifetime"`
+ // The list of TURN URIs to pass to clients
+ URIs []string `yaml:"turn_uris"`
+
+ // Authorization via Shared Secret
+ // The shared secret from coturn
+ SharedSecret string `yaml:"turn_shared_secret"`
+
+ // Authorization via Static Username & Password
+ // Hardcoded Username and Password
+ Username string `yaml:"turn_username"`
+ Password string `yaml:"turn_password"`
+}
+
+func (c *TURN) Verify(configErrs *ConfigErrors) {
+ value := c.UserLifetime
+ if value != "" {
+ if _, err := time.ParseDuration(value); err != nil {
+ configErrs.Add(fmt.Sprintf("invalid duration for config key %q: %s", "client_api.turn.turn_user_lifetime", value))
+ }
+ }
+}
diff --git a/internal/config/config_currentstate.go b/internal/config/config_currentstate.go
new file mode 100644
index 00000000..2687f7f5
--- /dev/null
+++ b/internal/config/config_currentstate.go
@@ -0,0 +1,25 @@
+package config
+
+type CurrentStateServer struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ // The CurrentState database stores the current state of all rooms.
+ // It is accessed by the CurrentStateServer.
+ Database DatabaseOptions `yaml:"database"`
+}
+
+func (c *CurrentStateServer) Defaults() {
+ c.Listen = "localhost:7782"
+ c.Bind = "localhost:7782"
+ c.Database.Defaults()
+ c.Database.ConnectionString = "file:currentstate.db"
+}
+
+func (c *CurrentStateServer) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "current_state_server.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "current_state_server.bind", string(c.Bind))
+ checkNotEmpty(configErrs, "current_state_server.database.connection_string", string(c.Database.ConnectionString))
+}
diff --git a/internal/config/config_eduserver.go b/internal/config/config_eduserver.go
new file mode 100644
index 00000000..02743041
--- /dev/null
+++ b/internal/config/config_eduserver.go
@@ -0,0 +1,18 @@
+package config
+
+type EDUServer struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+}
+
+func (c *EDUServer) Defaults() {
+ c.Listen = "localhost:7778"
+ c.Bind = "localhost:7778"
+}
+
+func (c *EDUServer) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "edu_server.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "edu_server.bind", string(c.Bind))
+}
diff --git a/internal/config/config_federationapi.go b/internal/config/config_federationapi.go
new file mode 100644
index 00000000..d155ef25
--- /dev/null
+++ b/internal/config/config_federationapi.go
@@ -0,0 +1,33 @@
+package config
+
+import "github.com/matrix-org/gomatrixserverlib"
+
+type FederationAPI struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ // List of paths to X509 certificates used by the external federation listeners.
+ // These are used to calculate the TLS fingerprints to publish for this server.
+ // Other matrix servers talking to this server will expect the x509 certificate
+ // to match one of these certificates.
+ // The certificates should be in PEM format.
+ FederationCertificatePaths []Path `yaml:"federation_certificates"`
+
+ // A list of SHA256 TLS fingerprints for the X509 certificates used by the
+ // federation listener for this server.
+ TLSFingerPrints []gomatrixserverlib.TLSFingerprint `yaml:"-"`
+}
+
+func (c *FederationAPI) Defaults() {
+ c.Listen = "localhost:7772"
+ c.Bind = "localhost:7772"
+}
+
+func (c *FederationAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "federation_api.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "federation_api.bind", string(c.Bind))
+ // TODO: not applicable always, e.g. in demos
+ //checkNotZero(configErrs, "federation_api.federation_certificates", int64(len(c.FederationCertificatePaths)))
+}
diff --git a/internal/config/config_federationsender.go b/internal/config/config_federationsender.go
new file mode 100644
index 00000000..09d8287b
--- /dev/null
+++ b/internal/config/config_federationsender.go
@@ -0,0 +1,64 @@
+package config
+
+type FederationSender struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ // The FederationSender database stores information used by the FederationSender
+ // It is only accessed by the FederationSender.
+ Database DatabaseOptions `yaml:"database"`
+
+ // Federation failure threshold. How many consecutive failures that we should
+ // tolerate when sending federation requests to a specific server. The backoff
+ // is 2**x seconds, so 1 = 2 seconds, 2 = 4 seconds, 3 = 8 seconds, etc.
+ // The default value is 16 if not specified, which is circa 18 hours.
+ FederationMaxRetries uint32 `yaml:"send_max_retries"`
+
+ // FederationDisableTLSValidation disables the validation of X.509 TLS certs
+ // on remote federation endpoints. This is not recommended in production!
+ DisableTLSValidation bool `yaml:"disable_tls_validation"`
+
+ Proxy Proxy `yaml:"proxy_outbound"`
+}
+
+func (c *FederationSender) Defaults() {
+ c.Listen = "localhost:7775"
+ c.Bind = "localhost:7775"
+ c.Database.Defaults()
+ c.Database.ConnectionString = "file:federationsender.db"
+
+ c.FederationMaxRetries = 16
+ c.DisableTLSValidation = false
+
+ c.Proxy.Defaults()
+}
+
+func (c *FederationSender) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "federation_sender.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "federation_sender.bind", string(c.Bind))
+ checkNotEmpty(configErrs, "federation_sender.database.connection_string", string(c.Database.ConnectionString))
+}
+
+// The config for setting a proxy to use for server->server requests
+type Proxy struct {
+ // Is the proxy enabled?
+ Enabled bool `yaml:"enabled"`
+ // The protocol for the proxy (http / https / socks5)
+ Protocol string `yaml:"protocol"`
+ // The host where the proxy is listening
+ Host string `yaml:"host"`
+ // The port on which the proxy is listening
+ Port uint16 `yaml:"port"`
+}
+
+func (c *Proxy) Defaults() {
+ c.Enabled = false
+ c.Protocol = "http"
+ c.Host = "localhost"
+ c.Port = 8080
+}
+
+func (c *Proxy) Verify(configErrs *ConfigErrors) {
+}
diff --git a/internal/config/config_global.go b/internal/config/config_global.go
new file mode 100644
index 00000000..9456dd3f
--- /dev/null
+++ b/internal/config/config_global.go
@@ -0,0 +1,172 @@
+package config
+
+import (
+ "math/rand"
+ "time"
+
+ "github.com/matrix-org/gomatrixserverlib"
+ "golang.org/x/crypto/ed25519"
+)
+
+type Global struct {
+ // The name of the server. This is usually the domain name, e.g 'matrix.org', 'localhost'.
+ ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
+
+ // Path to the private key which will be used to sign requests and events.
+ PrivateKeyPath Path `yaml:"private_key"`
+
+ // The private key which will be used to sign requests and events.
+ PrivateKey ed25519.PrivateKey `yaml:"-"`
+
+ // An arbitrary string used to uniquely identify the PrivateKey. Must start with the
+ // prefix "ed25519:".
+ KeyID gomatrixserverlib.KeyID `yaml:"-"`
+
+ // How long a remote server can cache our server key for before requesting it again.
+ // Increasing this number will reduce the number of requests made by remote servers
+ // for our key, but increases the period a compromised key will be considered valid
+ // by remote servers.
+ // Defaults to 24 hours.
+ KeyValidityPeriod time.Duration `yaml:"key_validity_period"`
+
+ // List of domains that the server will trust as identity servers to
+ // verify third-party identifiers.
+ // Defaults to an empty array.
+ TrustedIDServers []string `yaml:"trusted_third_party_id_servers"`
+
+ // Kafka/Naffka configuration
+ Kafka Kafka `yaml:"kafka"`
+
+ // Metrics configuration
+ Metrics Metrics `yaml:"metrics"`
+}
+
+func (c *Global) Defaults() {
+ c.ServerName = "localhost"
+ c.PrivateKeyPath = "matrix.pem"
+ _, c.PrivateKey, _ = ed25519.GenerateKey(rand.New(rand.NewSource(0)))
+ c.KeyID = "ed25519:auto"
+ c.KeyValidityPeriod = time.Hour * 24 * 7
+
+ c.Kafka.Defaults()
+ c.Metrics.Defaults()
+}
+
+func (c *Global) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "global.server_name", string(c.ServerName))
+ checkNotEmpty(configErrs, "global.private_key", string(c.PrivateKeyPath))
+
+ c.Kafka.Verify(configErrs, isMonolith)
+ c.Metrics.Verify(configErrs, isMonolith)
+}
+
+type Kafka struct {
+ // A list of kafka addresses to connect to.
+ Addresses []string `yaml:"addresses"`
+ // Whether to use naffka instead of kafka.
+ // Naffka can only be used when running dendrite as a single monolithic server.
+ // Kafka can be used both with a monolithic server and when running the
+ // components as separate servers.
+ UseNaffka bool `yaml:"use_naffka"`
+ // The Naffka database is used internally by the naffka library, if used.
+ Database DatabaseOptions `yaml:"naffka_database"`
+ // The names of the topics to use when reading and writing from kafka.
+ Topics struct {
+ // Topic for roomserver/api.OutputRoomEvent events.
+ OutputRoomEvent Topic `yaml:"output_room_event"`
+ // Topic for sending account data from client API to sync API
+ OutputClientData Topic `yaml:"output_client_data"`
+ // Topic for eduserver/api.OutputTypingEvent events.
+ OutputTypingEvent Topic `yaml:"output_typing_event"`
+ // Topic for eduserver/api.OutputSendToDeviceEvent events.
+ OutputSendToDeviceEvent Topic `yaml:"output_send_to_device_event"`
+ // Topic for keyserver when new device keys are added.
+ OutputKeyChangeEvent Topic `yaml:"output_key_change_event"`
+ }
+}
+
+func (c *Kafka) Defaults() {
+ c.UseNaffka = true
+ c.Database.Defaults()
+ c.Database.ConnectionString = DataSource("file:naffka.db")
+ c.Topics.OutputRoomEvent = "OutputRoomEventTopic"
+ c.Topics.OutputClientData = "OutputClientDataTopic"
+ c.Topics.OutputTypingEvent = "OutputTypingEventTopic"
+ c.Topics.OutputSendToDeviceEvent = "OutputSendToDeviceEventTopic"
+ c.Topics.OutputKeyChangeEvent = "OutputKeyChangeEventTopic"
+}
+
+func (c *Kafka) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ if c.UseNaffka {
+ if !isMonolith {
+ configErrs.Add("naffka can only be used in a monolithic server")
+ }
+ checkNotEmpty(configErrs, "global.kafka.database.connection_string", string(c.Database.ConnectionString))
+ } else {
+ // If we aren't using naffka then we need to have at least one kafka
+ // server to talk to.
+ checkNotZero(configErrs, "global.kafka.addresses", int64(len(c.Addresses)))
+ }
+ checkNotEmpty(configErrs, "global.kafka.topics.output_room_event", string(c.Topics.OutputRoomEvent))
+ checkNotEmpty(configErrs, "global.kafka.topics.output_client_data", string(c.Topics.OutputClientData))
+ checkNotEmpty(configErrs, "global.kafka.topics.output_typing_event", string(c.Topics.OutputTypingEvent))
+ checkNotEmpty(configErrs, "global.kafka.topics.output_send_to_device_event", string(c.Topics.OutputSendToDeviceEvent))
+ checkNotEmpty(configErrs, "global.kafka.topics.output_key_change_event", string(c.Topics.OutputKeyChangeEvent))
+}
+
+// The configuration to use for Prometheus metrics
+type Metrics struct {
+ // Whether or not the metrics are enabled
+ Enabled bool `yaml:"enabled"`
+ // Use BasicAuth for Authorization
+ BasicAuth struct {
+ // Authorization via Static Username & Password
+ // Hardcoded Username and Password
+ Username string `yaml:"username"`
+ Password string `yaml:"password"`
+ } `yaml:"basic_auth"`
+}
+
+func (c *Metrics) Defaults() {
+ c.Enabled = false
+ c.BasicAuth.Username = "metrics"
+ c.BasicAuth.Password = "metrics"
+}
+
+func (c *Metrics) Verify(configErrs *ConfigErrors, isMonolith bool) {
+}
+
+type DatabaseOptions struct {
+ // The connection string, file:filename.db or postgres://server....
+ ConnectionString DataSource `yaml:"connection_string"`
+ // Maximum open connections to the DB (0 = use default, negative means unlimited)
+ MaxOpenConnections int `yaml:"max_open_conns"`
+ // Maximum idle connections to the DB (0 = use default, negative means unlimited)
+ MaxIdleConnections int `yaml:"max_idle_conns"`
+ // maximum amount of time (in seconds) a connection may be reused (<= 0 means unlimited)
+ ConnMaxLifetimeSeconds int `yaml:"conn_max_lifetime"`
+}
+
+func (c *DatabaseOptions) Defaults() {
+ c.MaxOpenConnections = 100
+ c.MaxIdleConnections = 2
+ c.ConnMaxLifetimeSeconds = -1
+}
+
+func (c *DatabaseOptions) Verify(configErrs *ConfigErrors, isMonolith bool) {
+}
+
+// MaxIdleConns returns maximum idle connections to the DB
+func (c DatabaseOptions) MaxIdleConns() int {
+ return c.MaxIdleConnections
+}
+
+// MaxOpenConns returns maximum open connections to the DB
+func (c DatabaseOptions) MaxOpenConns() int {
+ return c.MaxOpenConnections
+}
+
+// ConnMaxLifetime returns maximum amount of time a connection may be reused
+func (c DatabaseOptions) ConnMaxLifetime() time.Duration {
+ return time.Duration(c.ConnMaxLifetimeSeconds) * time.Second
+}
diff --git a/internal/config/config_keyserver.go b/internal/config/config_keyserver.go
new file mode 100644
index 00000000..c0967a8a
--- /dev/null
+++ b/internal/config/config_keyserver.go
@@ -0,0 +1,23 @@
+package config
+
+type KeyServer struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ Database DatabaseOptions `yaml:"database"`
+}
+
+func (c *KeyServer) Defaults() {
+ c.Listen = "localhost:7779"
+ c.Bind = "localhost:7779"
+ c.Database.Defaults()
+ c.Database.ConnectionString = "file:keyserver.db"
+}
+
+func (c *KeyServer) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "key_server.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "key_server.bind", string(c.Bind))
+ checkNotEmpty(configErrs, "key_server.database.connection_string", string(c.Database.ConnectionString))
+}
diff --git a/internal/config/config_mediaapi.go b/internal/config/config_mediaapi.go
new file mode 100644
index 00000000..9a4d7e0a
--- /dev/null
+++ b/internal/config/config_mediaapi.go
@@ -0,0 +1,63 @@
+package config
+
+import (
+ "fmt"
+)
+
+type MediaAPI struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ // The MediaAPI database stores information about files uploaded and downloaded
+ // by local users. It is only accessed by the MediaAPI.
+ Database DatabaseOptions `yaml:"database"`
+
+ // The base path to where the media files will be stored. May be relative or absolute.
+ BasePath Path `yaml:"base_path"`
+
+ // The absolute base path to where media files will be stored.
+ AbsBasePath Path `yaml:"-"`
+
+ // The maximum file size in bytes that is allowed to be stored on this server.
+ // Note: if max_file_size_bytes is set to 0, the size is unlimited.
+ // Note: if max_file_size_bytes is not set, it will default to 10485760 (10MB)
+ MaxFileSizeBytes *FileSizeBytes `yaml:"max_file_size_bytes,omitempty"`
+
+ // Whether to dynamically generate thumbnails on-the-fly if the requested resolution is not already generated
+ DynamicThumbnails bool `yaml:"dynamic_thumbnails"`
+
+ // The maximum number of simultaneous thumbnail generators. default: 10
+ MaxThumbnailGenerators int `yaml:"max_thumbnail_generators"`
+
+ // A list of thumbnail sizes to be pre-generated for downloaded remote / uploaded content
+ ThumbnailSizes []ThumbnailSize `yaml:"thumbnail_sizes"`
+}
+
+func (c *MediaAPI) Defaults() {
+ c.Listen = "localhost:7774"
+ c.Bind = "localhost:7774"
+ c.Database.Defaults()
+ c.Database.ConnectionString = "file:mediaapi.db"
+
+ defaultMaxFileSizeBytes := FileSizeBytes(10485760)
+ c.MaxFileSizeBytes = &defaultMaxFileSizeBytes
+ c.MaxThumbnailGenerators = 10
+ c.BasePath = "./media_store"
+}
+
+func (c *MediaAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "media_api.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "media_api.bind", string(c.Bind))
+ checkNotEmpty(configErrs, "media_api.database.connection_string", string(c.Database.ConnectionString))
+
+ checkNotEmpty(configErrs, "media_api.base_path", string(c.BasePath))
+ checkPositive(configErrs, "media_api.max_file_size_bytes", int64(*c.MaxFileSizeBytes))
+ checkPositive(configErrs, "media_api.max_thumbnail_generators", int64(c.MaxThumbnailGenerators))
+
+ for i, size := range c.ThumbnailSizes {
+ checkPositive(configErrs, fmt.Sprintf("media_api.thumbnail_sizes[%d].width", i), int64(size.Width))
+ checkPositive(configErrs, fmt.Sprintf("media_api.thumbnail_sizes[%d].height", i), int64(size.Height))
+ }
+}
diff --git a/internal/config/config_roomserver.go b/internal/config/config_roomserver.go
new file mode 100644
index 00000000..1a16e2b1
--- /dev/null
+++ b/internal/config/config_roomserver.go
@@ -0,0 +1,23 @@
+package config
+
+type RoomServer struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ Database DatabaseOptions `yaml:"database"`
+}
+
+func (c *RoomServer) Defaults() {
+ c.Listen = "localhost:7770"
+ c.Bind = "localhost:7770"
+ c.Database.Defaults()
+ c.Database.ConnectionString = "file:roomserver.db"
+}
+
+func (c *RoomServer) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "room_server.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "room_server.bind", string(c.Bind))
+ checkNotEmpty(configErrs, "room_server.database.connection_string", string(c.Database.ConnectionString))
+}
diff --git a/internal/config/config_serverkey.go b/internal/config/config_serverkey.go
new file mode 100644
index 00000000..cf1f537a
--- /dev/null
+++ b/internal/config/config_serverkey.go
@@ -0,0 +1,29 @@
+package config
+
+type ServerKeyAPI struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ // The ServerKey database caches the public keys of remote servers.
+ // It may be accessed by the FederationAPI, the ClientAPI, and the MediaAPI.
+ Database DatabaseOptions `yaml:"database"`
+
+ // Perspective keyservers, to use as a backup when direct key fetch
+ // requests don't succeed
+ KeyPerspectives KeyPerspectives `yaml:"key_perspectives"`
+}
+
+func (c *ServerKeyAPI) Defaults() {
+ c.Listen = "localhost:7780"
+ c.Bind = "localhost:7780"
+ c.Database.Defaults()
+ c.Database.ConnectionString = "file:serverkeyapi.db"
+}
+
+func (c *ServerKeyAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "server_key_api.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "server_key_api.bind", string(c.Bind))
+ checkNotEmpty(configErrs, "server_key_api.database.connection_string", string(c.Database.ConnectionString))
+}
diff --git a/internal/config/config_syncapi.go b/internal/config/config_syncapi.go
new file mode 100644
index 00000000..488f6658
--- /dev/null
+++ b/internal/config/config_syncapi.go
@@ -0,0 +1,23 @@
+package config
+
+type SyncAPI struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ Database DatabaseOptions `yaml:"database"`
+}
+
+func (c *SyncAPI) Defaults() {
+ c.Listen = "localhost:7773"
+ c.Bind = "localhost:7773"
+ c.Database.Defaults()
+ c.Database.ConnectionString = "file:syncapi.db"
+}
+
+func (c *SyncAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "sync_api.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "sync_api.bind", string(c.Bind))
+ checkNotEmpty(configErrs, "sync_api.database", string(c.Database.ConnectionString))
+}
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index 758d7552..4ff170e4 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -33,48 +33,157 @@ func TestLoadConfigRelative(t *testing.T) {
}
const testConfig = `
-version: 0
-matrix:
+version: 1
+global:
server_name: localhost
private_key: matrix_key.pem
- federation_certificates: [tls_cert.pem]
-media:
- base_path: media_store
-kafka:
- addresses: ["localhost:9092"]
- topics:
- output_room_event: output.room
- output_client_data: output.client
- output_typing_event: output.typing
- output_send_to_device_event: output.std
- output_key_change_event: output.key_change
- user_updates: output.user
-database:
- media_api: "postgresql:///media_api"
- account: "postgresql:///account"
- device: "postgresql:///device"
- server_key: "postgresql:///server_keys"
- sync_api: "postgresql:///syn_api"
- room_server: "postgresql:///room_server"
- appservice: "postgresql:///appservice"
- current_state: "postgresql:///current_state"
- e2e_key: "postgresql:///e2e_key"
-listen:
- room_server: "localhost:7770"
- client_api: "localhost:7771"
- federation_api: "localhost:7772"
- sync_api: "localhost:7773"
- media_api: "localhost:7774"
- appservice_api: "localhost:7777"
- edu_server: "localhost:7778"
- user_api: "localhost:7779"
- current_state_server: "localhost:7775"
- key_server: "localhost:7776"
-logging:
- - type: "file"
- level: "info"
- params:
- path: "/my/log/dir"
+ key_validity_period: 168h0m0s
+ trusted_third_party_id_servers: []
+ kafka:
+ addresses: []
+ use_naffka: true
+ naffka_database:
+ connection_string: file:naffka.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+ topics:
+ output_room_event: OutputRoomEventTopic
+ output_client_data: OutputClientDataTopic
+ output_typing_event: OutputTypingEventTopic
+ output_send_to_device_event: OutputSendToDeviceEventTopic
+ output_key_change_event: OutputKeyChangeEventTopic
+ metrics:
+ enabled: false
+ basic_auth:
+ username: metrics
+ password: metrics
+app_service_api:
+ listen: localhost:7777
+ bind: localhost:7777
+ database:
+ connection_string: file:appservice.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+ config_files: []
+client_api:
+ listen: localhost:7771
+ bind: localhost:7771
+ registration_shared_secret: ""
+ recaptcha_public_key: ""
+ recaptcha_private_key: ""
+ enable_registration_captcha: false
+ captcha_bypass_secret: ""
+ recaptcha_siteverify_api: ""
+ registration_disabled: false
+ turn:
+ turn_user_lifetime: ""
+ turn_uris: []
+ turn_shared_secret: ""
+ turn_username: ""
+ turn_password: ""
+current_state_server:
+ listen: localhost:7782
+ bind: localhost:7782
+ database:
+ connection_string: file:currentstate.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+edu_server:
+ listen: localhost:7778
+ bind: localhost:7778
+federation_api:
+ listen: localhost:7772
+ bind: localhost:7772
+ federation_certificates: []
+federation_sender:
+ listen: localhost:7775
+ bind: localhost:7775
+ database:
+ connection_string: file:federationsender.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+ federation_max_retries: 16
+ proxy_outbound:
+ enabled: false
+ protocol: http
+ host: localhost
+ port: 8080
+key_server:
+ listen: localhost:7779
+ bind: localhost:7779
+ database:
+ connection_string: file:keyserver.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+media_api:
+ listen: localhost:7774
+ bind: localhost:7774
+ database:
+ connection_string: file:mediaapi.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+ base_path: ""
+ max_file_size_bytes: 10485760
+ dynamic_thumbnails: false
+ max_thumbnail_generators: 10
+ thumbnail_sizes: []
+room_server:
+ listen: localhost:7770
+ bind: localhost:7770
+ database:
+ connection_string: file:roomserver.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+server_key_api:
+ listen: localhost:7780
+ bind: localhost:7780
+ database:
+ connection_string: file:serverkeyapi.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+ key_perspectives: []
+sync_api:
+ listen: localhost:7773
+ bind: localhost:7773
+ database:
+ connection_string: file:syncapi.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+user_api:
+ listen: localhost:7781
+ bind: localhost:7781
+ account_database:
+ connection_string: file:userapi_accounts.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+ device_database:
+ connection_string: file:userapi_devices.db
+ max_open_conns: 0
+ max_idle_conns: 0
+ conn_max_lifetime: -1
+tracing:
+ enabled: false
+ jaeger:
+ serviceName: ""
+ disabled: false
+ rpc_metrics: false
+ tags: []
+ sampler: null
+ reporter: null
+ headers: null
+ baggage_restrictions: null
+ throttler: null
+logging: []
`
type mockReadFile map[string]string
diff --git a/internal/config/config_userapi.go b/internal/config/config_userapi.go
new file mode 100644
index 00000000..f7da9e59
--- /dev/null
+++ b/internal/config/config_userapi.go
@@ -0,0 +1,31 @@
+package config
+
+type UserAPI struct {
+ Matrix *Global `yaml:"-"`
+
+ Listen Address `yaml:"listen"`
+ Bind Address `yaml:"bind"`
+
+ // The Account database stores the login details and account information
+ // for local users. It is accessed by the UserAPI.
+ AccountDatabase DatabaseOptions `yaml:"account_database"`
+ // The Device database stores session information for the devices of logged
+ // in local users. It is accessed by the UserAPI.
+ DeviceDatabase DatabaseOptions `yaml:"device_database"`
+}
+
+func (c *UserAPI) Defaults() {
+ c.Listen = "localhost:7781"
+ c.Bind = "localhost:7781"
+ c.AccountDatabase.Defaults()
+ c.DeviceDatabase.Defaults()
+ c.AccountDatabase.ConnectionString = "file:userapi_accounts.db"
+ c.DeviceDatabase.ConnectionString = "file:userapi_devices.db"
+}
+
+func (c *UserAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
+ checkNotEmpty(configErrs, "user_api.listen", string(c.Listen))
+ checkNotEmpty(configErrs, "user_api.bind", string(c.Bind))
+ checkNotEmpty(configErrs, "user_api.account_database.connection_string", string(c.AccountDatabase.ConnectionString))
+ checkNotEmpty(configErrs, "user_api.device_database.connection_string", string(c.DeviceDatabase.ConnectionString))
+}
diff --git a/internal/eventutil/events.go b/internal/eventutil/events.go
index 1e3afac8..35c7f33d 100644
--- a/internal/eventutil/events.go
+++ b/internal/eventutil/events.go
@@ -38,7 +38,7 @@ var ErrRoomNoExists = errors.New("Room does not exist")
// Returns an error if something else went wrong
func BuildEvent(
ctx context.Context,
- builder *gomatrixserverlib.EventBuilder, cfg *config.Dendrite, evTime time.Time,
+ builder *gomatrixserverlib.EventBuilder, cfg *config.Global, evTime time.Time,
rsAPI api.RoomserverInternalAPI, queryRes *api.QueryLatestEventsAndStateResponse,
) (*gomatrixserverlib.HeaderedEvent, error) {
if queryRes == nil {
@@ -52,8 +52,8 @@ func BuildEvent(
}
event, err := builder.Build(
- evTime, cfg.Matrix.ServerName, cfg.Matrix.KeyID,
- cfg.Matrix.PrivateKey, queryRes.RoomVersion,
+ evTime, cfg.ServerName, cfg.KeyID,
+ cfg.PrivateKey, queryRes.RoomVersion,
)
if err != nil {
return nil, err
diff --git a/internal/httputil/httpapi.go b/internal/httputil/httpapi.go
index d371d172..8f7723ef 100644
--- a/internal/httputil/httpapi.go
+++ b/internal/httputil/httpapi.go
@@ -234,7 +234,7 @@ func (f *FederationWakeups) Wakeup(ctx context.Context, origin gomatrixserverlib
}
// SetupHTTPAPI registers an HTTP API mux under /api and sets up a metrics listener
-func SetupHTTPAPI(servMux, publicApiMux, internalApiMux *mux.Router, cfg *config.Dendrite, enableHTTPAPIs bool) {
+func SetupHTTPAPI(servMux, publicApiMux, internalApiMux *mux.Router, cfg *config.Global, enableHTTPAPIs bool) {
if cfg.Metrics.Enabled {
servMux.Handle("/metrics", WrapHandlerInBasicAuth(promhttp.Handler(), cfg.Metrics.BasicAuth))
}
diff --git a/internal/setup/base.go b/internal/setup/base.go
index 4fef0cbc..f59d136e 100644
--- a/internal/setup/base.go
+++ b/internal/setup/base.go
@@ -15,7 +15,6 @@
package setup
import (
- "database/sql"
"fmt"
"io"
"net/http"
@@ -85,6 +84,15 @@ const HTTPClientTimeout = time.Second * 30
// The componentName is used for logging purposes, and should be a friendly name
// of the compontent running, e.g. "SyncAPI"
func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs bool) *BaseDendrite {
+ configErrors := &config.ConfigErrors{}
+ cfg.Verify(configErrors, componentName == "Monolith") // TODO: better way?
+ if len(*configErrors) > 0 {
+ for _, err := range *configErrors {
+ logrus.Errorf("Configuration error: %s", err)
+ }
+ logrus.Fatalf("Failed to start due to configuration errors")
+ }
+
internal.SetupStdLogging()
internal.SetupHookLogging(cfg.Logging, componentName)
internal.SetupPprof()
@@ -96,7 +104,7 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs boo
var kafkaConsumer sarama.Consumer
var kafkaProducer sarama.SyncProducer
- if cfg.Kafka.UseNaffka {
+ if cfg.Global.Kafka.UseNaffka {
kafkaConsumer, kafkaProducer = setupNaffka(cfg)
} else {
kafkaConsumer, kafkaProducer = setupKafka(cfg)
@@ -108,10 +116,10 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs boo
}
client := http.Client{Timeout: HTTPClientTimeout}
- if cfg.Proxy != nil {
+ if cfg.FederationSender.Proxy.Enabled {
client.Transport = &http.Transport{Proxy: http.ProxyURL(&url.URL{
- Scheme: cfg.Proxy.Protocol,
- Host: fmt.Sprintf("%s:%d", cfg.Proxy.Host, cfg.Proxy.Port),
+ Scheme: cfg.FederationSender.Proxy.Protocol,
+ Host: fmt.Sprintf("%s:%d", cfg.FederationSender.Proxy.Host, cfg.FederationSender.Proxy.Port),
})}
}
@@ -228,7 +236,7 @@ func (b *BaseDendrite) KeyServerHTTPClient() keyserverAPI.KeyInternalAPI {
// CreateDeviceDB creates a new instance of the device database. Should only be
// called once per component.
func (b *BaseDendrite) CreateDeviceDB() devices.Database {
- db, err := devices.NewDatabase(string(b.Cfg.Database.Device), b.Cfg.DbProperties(), b.Cfg.Matrix.ServerName)
+ db, err := devices.NewDatabase(&b.Cfg.UserAPI.DeviceDatabase, b.Cfg.Global.ServerName)
if err != nil {
logrus.WithError(err).Panicf("failed to connect to devices db")
}
@@ -239,7 +247,7 @@ func (b *BaseDendrite) CreateDeviceDB() devices.Database {
// CreateAccountsDB creates a new instance of the accounts database. Should only
// be called once per component.
func (b *BaseDendrite) CreateAccountsDB() accounts.Database {
- db, err := accounts.NewDatabase(string(b.Cfg.Database.Account), b.Cfg.DbProperties(), b.Cfg.Matrix.ServerName)
+ db, err := accounts.NewDatabase(&b.Cfg.UserAPI.AccountDatabase, b.Cfg.Global.ServerName)
if err != nil {
logrus.WithError(err).Panicf("failed to connect to accounts db")
}
@@ -251,8 +259,8 @@ func (b *BaseDendrite) CreateAccountsDB() accounts.Database {
// once per component.
func (b *BaseDendrite) CreateFederationClient() *gomatrixserverlib.FederationClient {
return gomatrixserverlib.NewFederationClient(
- b.Cfg.Matrix.ServerName, b.Cfg.Matrix.KeyID, b.Cfg.Matrix.PrivateKey,
- b.Cfg.Matrix.FederationDisableTLSValidation,
+ b.Cfg.Global.ServerName, b.Cfg.Global.KeyID, b.Cfg.Global.PrivateKey,
+ b.Cfg.FederationSender.DisableTLSValidation,
)
}
@@ -277,7 +285,7 @@ func (b *BaseDendrite) SetupAndServeHTTP(bindaddr string, listenaddr string) {
b.BaseMux,
b.PublicAPIMux,
b.InternalAPIMux,
- b.Cfg,
+ &b.Cfg.Global,
b.UseHTTPAPIs,
)
serv.Handler = b.BaseMux
@@ -293,12 +301,12 @@ func (b *BaseDendrite) SetupAndServeHTTP(bindaddr string, listenaddr string) {
// setupKafka creates kafka consumer/producer pair from the config.
func setupKafka(cfg *config.Dendrite) (sarama.Consumer, sarama.SyncProducer) {
- consumer, err := sarama.NewConsumer(cfg.Kafka.Addresses, nil)
+ consumer, err := sarama.NewConsumer(cfg.Global.Kafka.Addresses, nil)
if err != nil {
logrus.WithError(err).Panic("failed to start kafka consumer")
}
- producer, err := sarama.NewSyncProducer(cfg.Kafka.Addresses, nil)
+ producer, err := sarama.NewSyncProducer(cfg.Global.Kafka.Addresses, nil)
if err != nil {
logrus.WithError(err).Panic("failed to setup kafka producers")
}
@@ -308,36 +316,26 @@ func setupKafka(cfg *config.Dendrite) (sarama.Consumer, sarama.SyncProducer) {
// setupNaffka creates kafka consumer/producer pair from the config.
func setupNaffka(cfg *config.Dendrite) (sarama.Consumer, sarama.SyncProducer) {
- var err error
- var db *sql.DB
var naffkaDB *naffka.DatabaseImpl
- uri, err := url.Parse(string(cfg.Database.Naffka))
- if err != nil || uri.Scheme == "file" {
- var cs string
- cs, err = sqlutil.ParseFileURI(string(cfg.Database.Naffka))
- if err != nil {
- logrus.WithError(err).Panic("Failed to parse naffka database file URI")
- }
- db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil)
- if err != nil {
- logrus.WithError(err).Panic("Failed to open naffka database")
- }
+ db, err := sqlutil.Open(&cfg.Global.Kafka.Database)
+ if err != nil {
+ logrus.WithError(err).Panic("Failed to open naffka database")
+ }
+ switch {
+ case cfg.Global.Kafka.Database.ConnectionString.IsSQLite():
naffkaDB, err = naffka.NewSqliteDatabase(db)
if err != nil {
logrus.WithError(err).Panic("Failed to setup naffka database")
}
- } else {
- db, err = sqlutil.Open("postgres", string(cfg.Database.Naffka), nil)
- if err != nil {
- logrus.WithError(err).Panic("Failed to open naffka database")
- }
-
+ case cfg.Global.Kafka.Database.ConnectionString.IsPostgres():
naffkaDB, err = naffka.NewPostgresqlDatabase(db)
if err != nil {
logrus.WithError(err).Panic("Failed to setup naffka database")
}
+ default:
+ panic("unknown naffka database type")
}
if naffkaDB == nil {
diff --git a/internal/setup/monolith.go b/internal/setup/monolith.go
index f33f97ee..92bbca72 100644
--- a/internal/setup/monolith.go
+++ b/internal/setup/monolith.go
@@ -65,19 +65,19 @@ type Monolith struct {
// AddAllPublicRoutes attaches all public paths to the given router
func (m *Monolith) AddAllPublicRoutes(publicMux *mux.Router) {
clientapi.AddPublicRoutes(
- publicMux, m.Config, m.KafkaProducer, m.DeviceDB, m.AccountDB,
+ publicMux, &m.Config.ClientAPI, m.KafkaProducer, m.DeviceDB, m.AccountDB,
m.FedClient, m.RoomserverAPI,
m.EDUInternalAPI, m.AppserviceAPI, m.StateAPI, transactions.New(),
m.FederationSenderAPI, m.UserAPI, m.KeyAPI, m.ExtPublicRoomsProvider,
)
federationapi.AddPublicRoutes(
- publicMux, m.Config, m.UserAPI, m.FedClient,
+ publicMux, &m.Config.FederationAPI, m.UserAPI, m.FedClient,
m.KeyRing, m.RoomserverAPI, m.FederationSenderAPI,
m.EDUInternalAPI, m.StateAPI, m.KeyAPI,
)
- mediaapi.AddPublicRoutes(publicMux, m.Config, m.UserAPI, m.Client)
+ mediaapi.AddPublicRoutes(publicMux, &m.Config.MediaAPI, m.UserAPI, m.Client)
syncapi.AddPublicRoutes(
publicMux, m.KafkaConsumer, m.UserAPI, m.RoomserverAPI,
- m.KeyAPI, m.StateAPI, m.FedClient, m.Config,
+ m.KeyAPI, m.StateAPI, m.FedClient, &m.Config.SyncAPI,
)
}
diff --git a/internal/sqlutil/sql.go b/internal/sqlutil/sql.go
index 2ec6ce29..95467c63 100644
--- a/internal/sqlutil/sql.go
+++ b/internal/sqlutil/sql.go
@@ -19,7 +19,6 @@ import (
"errors"
"fmt"
"runtime"
- "time"
"go.uber.org/atomic"
)
@@ -107,13 +106,6 @@ func SQLiteDriverName() string {
return "sqlite3"
}
-// DbProperties functions return properties used by database/sql/DB
-type DbProperties interface {
- MaxIdleConns() int
- MaxOpenConns() int
- ConnMaxLifetime() time.Duration
-}
-
// TransactionWriter allows queuing database writes so that you don't
// contend on database locks in, e.g. SQLite. Only one task will run
// at a time on a given TransactionWriter.
diff --git a/internal/sqlutil/trace.go b/internal/sqlutil/trace.go
index f6644d59..fbd983be 100644
--- a/internal/sqlutil/trace.go
+++ b/internal/sqlutil/trace.go
@@ -25,6 +25,7 @@ import (
"strings"
"time"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/ngrok/sqlmw"
"github.com/sirupsen/logrus"
)
@@ -77,7 +78,22 @@ func (in *traceInterceptor) RowsNext(c context.Context, rows driver.Rows, dest [
// Open opens a database specified by its database driver name and a driver-specific data source name,
// usually consisting of at least a database name and connection information. Includes tracing driver
// if DENDRITE_TRACE_SQL=1
-func Open(driverName, dsn string, dbProperties DbProperties) (*sql.DB, error) {
+func Open(dbProperties *config.DatabaseOptions) (*sql.DB, error) {
+ var err error
+ var driverName, dsn string
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ driverName = SQLiteDriverName()
+ dsn, err = ParseFileURI(dbProperties.ConnectionString)
+ if err != nil {
+ return nil, fmt.Errorf("ParseFileURI: %w", err)
+ }
+ case dbProperties.ConnectionString.IsPostgres():
+ driverName = "postgres"
+ dsn = string(dbProperties.ConnectionString)
+ default:
+ return nil, fmt.Errorf("invalid database connection string %q", dbProperties.ConnectionString)
+ }
if tracingEnabled {
// install the wrapped driver
driverName += "-trace"
@@ -86,11 +102,11 @@ func Open(driverName, dsn string, dbProperties DbProperties) (*sql.DB, error) {
if err != nil {
return nil, err
}
- if driverName != SQLiteDriverName() && dbProperties != nil {
+ if driverName != SQLiteDriverName() {
logrus.WithFields(logrus.Fields{
- "MaxOpenConns": dbProperties.MaxOpenConns(),
- "MaxIdleConns": dbProperties.MaxIdleConns(),
- "ConnMaxLifetime": dbProperties.ConnMaxLifetime(),
+ "MaxOpenConns": dbProperties.MaxOpenConns,
+ "MaxIdleConns": dbProperties.MaxIdleConns,
+ "ConnMaxLifetime": dbProperties.ConnMaxLifetime,
"dataSourceName": regexp.MustCompile(`://[^@]*@`).ReplaceAllLiteralString(dsn, "://"),
}).Debug("Setting DB connection limits")
db.SetMaxOpenConns(dbProperties.MaxOpenConns())
diff --git a/internal/sqlutil/uri.go b/internal/sqlutil/uri.go
index 703258e6..e2c825d9 100644
--- a/internal/sqlutil/uri.go
+++ b/internal/sqlutil/uri.go
@@ -15,14 +15,20 @@
package sqlutil
import (
+ "errors"
"fmt"
"net/url"
+
+ "github.com/matrix-org/dendrite/internal/config"
)
// ParseFileURI returns the filepath in the given file: URI. Specifically, this will handle
// both relative (file:foo.db) and absolute (file:///path/to/foo) paths.
-func ParseFileURI(dataSourceName string) (string, error) {
- uri, err := url.Parse(dataSourceName)
+func ParseFileURI(dataSourceName config.DataSource) (string, error) {
+ if !dataSourceName.IsSQLite() {
+ return "", errors.New("ParseFileURI expects SQLite connection string")
+ }
+ uri, err := url.Parse(string(dataSourceName))
if err != nil {
return "", err
}
diff --git a/internal/test/config.go b/internal/test/config.go
index bbcc9bed..43a5d1ff 100644
--- a/internal/test/config.go
+++ b/internal/test/config.go
@@ -49,6 +49,7 @@ const (
// Generates new matrix and TLS keys for the server.
func MakeConfig(configDir, kafkaURI, database, host string, startPort int) (*config.Dendrite, int, error) {
var cfg config.Dendrite
+ cfg.Defaults()
port := startPort
assignAddress := func() config.Address {
@@ -72,51 +73,53 @@ func MakeConfig(configDir, kafkaURI, database, host string, startPort int) (*con
cfg.Version = config.Version
- cfg.Matrix.ServerName = gomatrixserverlib.ServerName(assignAddress())
- cfg.Matrix.PrivateKeyPath = config.Path(serverKeyPath)
- cfg.Matrix.FederationCertificatePaths = []config.Path{config.Path(tlsCertPath)}
+ cfg.Global.ServerName = gomatrixserverlib.ServerName(assignAddress())
+ cfg.Global.PrivateKeyPath = config.Path(serverKeyPath)
- cfg.Media.BasePath = config.Path(mediaBasePath)
+ cfg.FederationAPI.FederationCertificatePaths = []config.Path{config.Path(tlsCertPath)}
- cfg.Kafka.Addresses = []string{kafkaURI}
- // TODO: Different servers should be using different topics.
- // Make this configurable somehow?
- cfg.Kafka.Topics.OutputRoomEvent = "test.room.output"
- cfg.Kafka.Topics.OutputClientData = "test.clientapi.output"
- cfg.Kafka.Topics.OutputTypingEvent = "test.typing.output"
+ cfg.MediaAPI.BasePath = config.Path(mediaBasePath)
+
+ cfg.Global.Kafka.Addresses = []string{kafkaURI}
// TODO: Use different databases for the different schemas.
// Using the same database for every schema currently works because
// the table names are globally unique. But we might not want to
// rely on that in the future.
- cfg.Database.Account = config.DataSource(database)
- cfg.Database.AppService = config.DataSource(database)
- cfg.Database.Device = config.DataSource(database)
- cfg.Database.MediaAPI = config.DataSource(database)
- cfg.Database.RoomServer = config.DataSource(database)
- cfg.Database.ServerKey = config.DataSource(database)
- cfg.Database.SyncAPI = config.DataSource(database)
- cfg.Database.CurrentState = config.DataSource(database)
-
- cfg.Listen.ClientAPI = assignAddress()
- cfg.Listen.AppServiceAPI = assignAddress()
- cfg.Listen.FederationAPI = assignAddress()
- cfg.Listen.MediaAPI = assignAddress()
- cfg.Listen.RoomServer = assignAddress()
- cfg.Listen.SyncAPI = assignAddress()
- cfg.Listen.CurrentState = assignAddress()
- cfg.Listen.EDUServer = assignAddress()
-
- // Bind to the same address as the listen address
- // All microservices are run on the same host in testing
- cfg.Bind.ClientAPI = cfg.Listen.ClientAPI
- cfg.Bind.AppServiceAPI = cfg.Listen.AppServiceAPI
- cfg.Bind.FederationAPI = cfg.Listen.FederationAPI
- cfg.Bind.MediaAPI = cfg.Listen.MediaAPI
- cfg.Bind.RoomServer = cfg.Listen.RoomServer
- cfg.Bind.SyncAPI = cfg.Listen.SyncAPI
- cfg.Bind.CurrentState = cfg.Listen.CurrentState
- cfg.Bind.EDUServer = cfg.Listen.EDUServer
+ cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(database)
+ cfg.CurrentStateServer.Database.ConnectionString = config.DataSource(database)
+ cfg.FederationSender.Database.ConnectionString = config.DataSource(database)
+ cfg.KeyServer.Database.ConnectionString = config.DataSource(database)
+ cfg.MediaAPI.Database.ConnectionString = config.DataSource(database)
+ cfg.RoomServer.Database.ConnectionString = config.DataSource(database)
+ cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource(database)
+ cfg.SyncAPI.Database.ConnectionString = config.DataSource(database)
+ cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(database)
+ cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(database)
+
+ cfg.AppServiceAPI.Listen = assignAddress()
+ cfg.CurrentStateServer.Listen = assignAddress()
+ cfg.EDUServer.Listen = assignAddress()
+ cfg.FederationAPI.Listen = assignAddress()
+ cfg.FederationSender.Listen = assignAddress()
+ cfg.KeyServer.Listen = assignAddress()
+ cfg.MediaAPI.Listen = assignAddress()
+ cfg.RoomServer.Listen = assignAddress()
+ cfg.ServerKeyAPI.Listen = assignAddress()
+ cfg.SyncAPI.Listen = assignAddress()
+ cfg.UserAPI.Listen = assignAddress()
+
+ cfg.AppServiceAPI.Bind = cfg.AppServiceAPI.Listen
+ cfg.CurrentStateServer.Bind = cfg.CurrentStateServer.Listen
+ cfg.EDUServer.Bind = cfg.EDUServer.Listen
+ cfg.FederationAPI.Bind = cfg.FederationAPI.Listen
+ cfg.FederationSender.Bind = cfg.FederationSender.Listen
+ cfg.KeyServer.Bind = cfg.KeyServer.Listen
+ cfg.MediaAPI.Bind = cfg.MediaAPI.Listen
+ cfg.RoomServer.Bind = cfg.RoomServer.Listen
+ cfg.ServerKeyAPI.Bind = cfg.ServerKeyAPI.Listen
+ cfg.SyncAPI.Bind = cfg.SyncAPI.Listen
+ cfg.UserAPI.Bind = cfg.UserAPI.Listen
return &cfg, port, nil
}
diff --git a/internal/test/server.go b/internal/test/server.go
index 2d4117f4..57df21db 100644
--- a/internal/test/server.go
+++ b/internal/test/server.go
@@ -96,9 +96,9 @@ func InitDatabase(postgresDatabase, postgresContainerName string, databases []st
func StartProxy(bindAddr string, cfg *config.Dendrite) (*exec.Cmd, chan error) {
proxyArgs := []string{
"--bind-address", bindAddr,
- "--sync-api-server-url", "http://" + string(cfg.Listen.SyncAPI),
- "--client-api-server-url", "http://" + string(cfg.Listen.ClientAPI),
- "--media-api-server-url", "http://" + string(cfg.Listen.MediaAPI),
+ "--sync-api-server-url", "http://" + string(cfg.SyncAPI.Listen),
+ "--client-api-server-url", "http://" + string(cfg.ClientAPI.Listen),
+ "--media-api-server-url", "http://" + string(cfg.MediaAPI.Listen),
"--tls-cert", "server.crt",
"--tls-key", "server.key",
}
diff --git a/keyserver/keyserver.go b/keyserver/keyserver.go
index 4a6fbe3c..b5bbb519 100644
--- a/keyserver/keyserver.go
+++ b/keyserver/keyserver.go
@@ -36,17 +36,14 @@ func AddInternalRoutes(router *mux.Router, intAPI api.KeyInternalAPI) {
// NewInternalAPI returns a concerete implementation of the internal API. Callers
// can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
func NewInternalAPI(
- cfg *config.Dendrite, fedClient *gomatrixserverlib.FederationClient, producer sarama.SyncProducer,
+ cfg *config.KeyServer, fedClient *gomatrixserverlib.FederationClient, producer sarama.SyncProducer,
) api.KeyInternalAPI {
- db, err := storage.NewDatabase(
- string(cfg.Database.E2EKey),
- cfg.DbProperties(),
- )
+ db, err := storage.NewDatabase(&cfg.Database)
if err != nil {
logrus.WithError(err).Panicf("failed to connect to key server database")
}
keyChangeProducer := &producers.KeyChange{
- Topic: string(cfg.Kafka.Topics.OutputKeyChangeEvent),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputKeyChangeEvent),
Producer: producer,
DB: db,
}
diff --git a/keyserver/storage/postgres/storage.go b/keyserver/storage/postgres/storage.go
index de2fabfd..1c693f5b 100644
--- a/keyserver/storage/postgres/storage.go
+++ b/keyserver/storage/postgres/storage.go
@@ -15,14 +15,15 @@
package postgres
import (
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/keyserver/storage/shared"
)
// NewDatabase creates a new sync server database
-func NewDatabase(dbDataSourceName string, dbProperties sqlutil.DbProperties) (*shared.Database, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions) (*shared.Database, error) {
var err error
- db, err := sqlutil.Open("postgres", dbDataSourceName, dbProperties)
+ db, err := sqlutil.Open(dbProperties)
if err != nil {
return nil, err
}
diff --git a/keyserver/storage/sqlite3/storage.go b/keyserver/storage/sqlite3/storage.go
index bbfd1e79..bb293558 100644
--- a/keyserver/storage/sqlite3/storage.go
+++ b/keyserver/storage/sqlite3/storage.go
@@ -15,17 +15,13 @@
package sqlite3
import (
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/keyserver/storage/shared"
)
-func NewDatabase(dataSourceName string) (*shared.Database, error) {
- var err error
- cs, err := sqlutil.ParseFileURI(dataSourceName)
- if err != nil {
- return nil, err
- }
- db, err := sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil)
+func NewDatabase(dbProperties *config.DatabaseOptions) (*shared.Database, error) {
+ db, err := sqlutil.Open(dbProperties)
if err != nil {
return nil, err
}
diff --git a/keyserver/storage/storage.go b/keyserver/storage/storage.go
index ffcead70..e1deaf93 100644
--- a/keyserver/storage/storage.go
+++ b/keyserver/storage/storage.go
@@ -17,26 +17,22 @@
package storage
import (
- "net/url"
+ "fmt"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/keyserver/storage/postgres"
"github.com/matrix-org/dendrite/keyserver/storage/sqlite3"
)
// NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme)
// and sets postgres connection parameters
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.NewDatabase(dataSourceName, dbProperties)
- }
- switch uri.Scheme {
- case "postgres":
- return postgres.NewDatabase(dataSourceName, dbProperties)
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
+func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.NewDatabase(dbProperties)
default:
- return postgres.NewDatabase(dataSourceName, dbProperties)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/keyserver/storage/storage_test.go b/keyserver/storage/storage_test.go
index ec1b299f..358f11e7 100644
--- a/keyserver/storage/storage_test.go
+++ b/keyserver/storage/storage_test.go
@@ -10,6 +10,7 @@ import (
"testing"
"github.com/Shopify/sarama"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/keyserver/api"
)
@@ -21,7 +22,9 @@ func MustCreateDatabase(t *testing.T) (Database, func()) {
log.Fatal(err)
}
t.Logf("Database %s", tmpfile.Name())
- db, err := NewDatabase(fmt.Sprintf("file://%s", tmpfile.Name()), nil)
+ db, err := NewDatabase(&config.DatabaseOptions{
+ ConnectionString: config.DataSource(fmt.Sprintf("file://%s", tmpfile.Name())),
+ })
if err != nil {
t.Fatalf("Failed to NewDatabase: %s", err)
}
diff --git a/keyserver/storage/storage_wasm.go b/keyserver/storage/storage_wasm.go
index 233e5d29..792cd4a5 100644
--- a/keyserver/storage/storage_wasm.go
+++ b/keyserver/storage/storage_wasm.go
@@ -16,26 +16,18 @@ package storage
import (
"fmt"
- "net/url"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/keyserver/storage/sqlite3"
)
-func NewDatabase(
- dataSourceName string,
- dbProperties sqlutil.DbProperties, // nolint:unparam
-) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return nil, fmt.Errorf("Cannot use postgres implementation")
- }
- switch uri.Scheme {
- case "postgres":
- return nil, fmt.Errorf("Cannot use postgres implementation")
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
+func NewDatabase(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return nil, fmt.Errorf("can't use Postgres implementation")
default:
- return nil, fmt.Errorf("Cannot use postgres implementation")
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/mediaapi/mediaapi.go b/mediaapi/mediaapi.go
index 290ef46e..1c14559f 100644
--- a/mediaapi/mediaapi.go
+++ b/mediaapi/mediaapi.go
@@ -26,11 +26,11 @@ import (
// AddPublicRoutes sets up and registers HTTP handlers for the MediaAPI component.
func AddPublicRoutes(
- router *mux.Router, cfg *config.Dendrite,
+ router *mux.Router, cfg *config.MediaAPI,
userAPI userapi.UserInternalAPI,
client *gomatrixserverlib.Client,
) {
- mediaDB, err := storage.Open(string(cfg.Database.MediaAPI), cfg.DbProperties())
+ mediaDB, err := storage.Open(&cfg.Database)
if err != nil {
logrus.WithError(err).Panicf("failed to connect to media db")
}
diff --git a/mediaapi/routing/download.go b/mediaapi/routing/download.go
index 7e121de3..e61fa82b 100644
--- a/mediaapi/routing/download.go
+++ b/mediaapi/routing/download.go
@@ -73,7 +73,7 @@ func Download(
req *http.Request,
origin gomatrixserverlib.ServerName,
mediaID types.MediaID,
- cfg *config.Dendrite,
+ cfg *config.MediaAPI,
db storage.Database,
client *gomatrixserverlib.Client,
activeRemoteRequests *types.ActiveRemoteRequests,
@@ -203,7 +203,7 @@ func (r *downloadRequest) Validate() *util.JSONResponse {
func (r *downloadRequest) doDownload(
ctx context.Context,
w http.ResponseWriter,
- cfg *config.Dendrite,
+ cfg *config.MediaAPI,
db storage.Database,
client *gomatrixserverlib.Client,
activeRemoteRequests *types.ActiveRemoteRequests,
@@ -233,9 +233,9 @@ func (r *downloadRequest) doDownload(
r.MediaMetadata = mediaMetadata
}
return r.respondFromLocalFile(
- ctx, w, cfg.Media.AbsBasePath, activeThumbnailGeneration,
- cfg.Media.MaxThumbnailGenerators, db,
- cfg.Media.DynamicThumbnails, cfg.Media.ThumbnailSizes,
+ ctx, w, cfg.AbsBasePath, activeThumbnailGeneration,
+ cfg.MaxThumbnailGenerators, db,
+ cfg.DynamicThumbnails, cfg.ThumbnailSizes,
)
}
@@ -514,7 +514,7 @@ func (r *downloadRequest) generateThumbnail(
func (r *downloadRequest) getRemoteFile(
ctx context.Context,
client *gomatrixserverlib.Client,
- cfg *config.Dendrite,
+ cfg *config.MediaAPI,
db storage.Database,
activeRemoteRequests *types.ActiveRemoteRequests,
activeThumbnailGeneration *types.ActiveThumbnailGeneration,
@@ -550,9 +550,9 @@ func (r *downloadRequest) getRemoteFile(
// If we do not have a record, we need to fetch the remote file first and then respond from the local file
err := r.fetchRemoteFileAndStoreMetadata(
ctx, client,
- cfg.Media.AbsBasePath, *cfg.Media.MaxFileSizeBytes, db,
- cfg.Media.ThumbnailSizes, activeThumbnailGeneration,
- cfg.Media.MaxThumbnailGenerators,
+ cfg.AbsBasePath, *cfg.MaxFileSizeBytes, db,
+ cfg.ThumbnailSizes, activeThumbnailGeneration,
+ cfg.MaxThumbnailGenerators,
)
if err != nil {
return errors.Wrap(err, "error querying the database.")
diff --git a/mediaapi/routing/routing.go b/mediaapi/routing/routing.go
index f4a8b157..ee5f28f9 100644
--- a/mediaapi/routing/routing.go
+++ b/mediaapi/routing/routing.go
@@ -42,7 +42,7 @@ const pathPrefixV1 = "/media/v1" // TODO: remove when synapse is fixed
// nolint: gocyclo
func Setup(
publicAPIMux *mux.Router,
- cfg *config.Dendrite,
+ cfg *config.MediaAPI,
db storage.Database,
userAPI userapi.UserInternalAPI,
client *gomatrixserverlib.Client,
@@ -81,7 +81,7 @@ func Setup(
func makeDownloadAPI(
name string,
- cfg *config.Dendrite,
+ cfg *config.MediaAPI,
db storage.Database,
client *gomatrixserverlib.Client,
activeRemoteRequests *types.ActiveRemoteRequests,
diff --git a/mediaapi/routing/upload.go b/mediaapi/routing/upload.go
index 9b5dc3df..9f35e90c 100644
--- a/mediaapi/routing/upload.go
+++ b/mediaapi/routing/upload.go
@@ -54,7 +54,7 @@ type uploadResponse struct {
// This implementation supports a configurable maximum file size limit in bytes. If a user tries to upload more than this, they will receive an error that their upload is too large.
// Uploaded files are processed piece-wise to avoid DoS attacks which would starve the server of memory.
// TODO: We should time out requests if they have not received any data within a configured timeout period.
-func Upload(req *http.Request, cfg *config.Dendrite, db storage.Database, activeThumbnailGeneration *types.ActiveThumbnailGeneration) util.JSONResponse {
+func Upload(req *http.Request, cfg *config.MediaAPI, db storage.Database, activeThumbnailGeneration *types.ActiveThumbnailGeneration) util.JSONResponse {
r, resErr := parseAndValidateRequest(req, cfg)
if resErr != nil {
return *resErr
@@ -75,7 +75,7 @@ func Upload(req *http.Request, cfg *config.Dendrite, db storage.Database, active
// parseAndValidateRequest parses the incoming upload request to validate and extract
// all the metadata about the media being uploaded.
// Returns either an uploadRequest or an error formatted as a util.JSONResponse
-func parseAndValidateRequest(req *http.Request, cfg *config.Dendrite) (*uploadRequest, *util.JSONResponse) {
+func parseAndValidateRequest(req *http.Request, cfg *config.MediaAPI) (*uploadRequest, *util.JSONResponse) {
r := &uploadRequest{
MediaMetadata: &types.MediaMetadata{
Origin: cfg.Matrix.ServerName,
@@ -86,7 +86,7 @@ func parseAndValidateRequest(req *http.Request, cfg *config.Dendrite) (*uploadRe
Logger: util.GetLogger(req.Context()).WithField("Origin", cfg.Matrix.ServerName),
}
- if resErr := r.Validate(*cfg.Media.MaxFileSizeBytes); resErr != nil {
+ if resErr := r.Validate(*cfg.MaxFileSizeBytes); resErr != nil {
return nil, resErr
}
@@ -96,7 +96,7 @@ func parseAndValidateRequest(req *http.Request, cfg *config.Dendrite) (*uploadRe
func (r *uploadRequest) doUpload(
ctx context.Context,
reqReader io.Reader,
- cfg *config.Dendrite,
+ cfg *config.MediaAPI,
db storage.Database,
activeThumbnailGeneration *types.ActiveThumbnailGeneration,
) *util.JSONResponse {
@@ -110,10 +110,10 @@ func (r *uploadRequest) doUpload(
// method of deduplicating files to save storage, as well as a way to conduct
// integrity checks on the file data in the repository.
// Data is truncated to maxFileSizeBytes. Content-Length was reported as 0 < Content-Length <= maxFileSizeBytes so this is OK.
- hash, bytesWritten, tmpDir, err := fileutils.WriteTempFile(reqReader, *cfg.Media.MaxFileSizeBytes, cfg.Media.AbsBasePath)
+ hash, bytesWritten, tmpDir, err := fileutils.WriteTempFile(reqReader, *cfg.MaxFileSizeBytes, cfg.AbsBasePath)
if err != nil {
r.Logger.WithError(err).WithFields(log.Fields{
- "MaxFileSizeBytes": *cfg.Media.MaxFileSizeBytes,
+ "MaxFileSizeBytes": *cfg.MaxFileSizeBytes,
}).Warn("Error while transferring file")
fileutils.RemoveDir(tmpDir, r.Logger)
return &util.JSONResponse{
@@ -159,8 +159,8 @@ func (r *uploadRequest) doUpload(
}
return r.storeFileAndMetadata(
- ctx, tmpDir, cfg.Media.AbsBasePath, db, cfg.Media.ThumbnailSizes,
- activeThumbnailGeneration, cfg.Media.MaxThumbnailGenerators,
+ ctx, tmpDir, cfg.AbsBasePath, db, cfg.ThumbnailSizes,
+ activeThumbnailGeneration, cfg.MaxThumbnailGenerators,
)
}
diff --git a/mediaapi/storage/postgres/storage.go b/mediaapi/storage/postgres/storage.go
index e45e0841..756913d3 100644
--- a/mediaapi/storage/postgres/storage.go
+++ b/mediaapi/storage/postgres/storage.go
@@ -21,6 +21,7 @@ import (
// Import the postgres database driver.
_ "github.com/lib/pq"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/mediaapi/types"
"github.com/matrix-org/gomatrixserverlib"
@@ -33,10 +34,10 @@ type Database struct {
}
// Open opens a postgres database.
-func Open(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) {
+func Open(dbProperties *config.DatabaseOptions) (*Database, error) {
var d Database
var err error
- if d.db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil {
+ if d.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
if err = d.statements.prepare(d.db); err != nil {
diff --git a/mediaapi/storage/sqlite3/storage.go b/mediaapi/storage/sqlite3/storage.go
index 010c0a66..a1e7fec7 100644
--- a/mediaapi/storage/sqlite3/storage.go
+++ b/mediaapi/storage/sqlite3/storage.go
@@ -20,6 +20,7 @@ import (
"database/sql"
// Import the postgres database driver.
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/mediaapi/types"
"github.com/matrix-org/gomatrixserverlib"
@@ -33,14 +34,10 @@ type Database struct {
}
// Open opens a postgres database.
-func Open(dataSourceName string) (*Database, error) {
+func Open(dbProperties *config.DatabaseOptions) (*Database, error) {
var d Database
var err error
- cs, err := sqlutil.ParseFileURI(dataSourceName)
- if err != nil {
- return nil, err
- }
- if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
+ if d.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
if err = d.statements.prepare(d.db); err != nil {
diff --git a/mediaapi/storage/storage.go b/mediaapi/storage/storage.go
index 5ff114db..829d47b3 100644
--- a/mediaapi/storage/storage.go
+++ b/mediaapi/storage/storage.go
@@ -17,25 +17,21 @@
package storage
import (
- "net/url"
+ "fmt"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/mediaapi/storage/postgres"
"github.com/matrix-org/dendrite/mediaapi/storage/sqlite3"
)
// Open opens a postgres database.
-func Open(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.Open(dataSourceName, dbProperties)
- }
- switch uri.Scheme {
- case "postgres":
- return postgres.Open(dataSourceName, dbProperties)
- case "file":
- return sqlite3.Open(dataSourceName)
+func Open(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.Open(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.Open(dbProperties)
default:
- return postgres.Open(dataSourceName, dbProperties)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/mediaapi/storage/storage_wasm.go b/mediaapi/storage/storage_wasm.go
index a672271f..6b5de681 100644
--- a/mediaapi/storage/storage_wasm.go
+++ b/mediaapi/storage/storage_wasm.go
@@ -16,27 +16,19 @@ package storage
import (
"fmt"
- "net/url"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/mediaapi/storage/sqlite3"
)
// Open opens a postgres database.
-func Open(
- dataSourceName string,
- dbProperties sqlutil.DbProperties, // nolint:unparam
-) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return nil, fmt.Errorf("Cannot use postgres implementation")
- }
- switch uri.Scheme {
- case "postgres":
- return nil, fmt.Errorf("Cannot use postgres implementation")
- case "file":
- return sqlite3.Open(dataSourceName)
+func Open(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.Open(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return nil, fmt.Errorf("can't use Postgres implementation")
default:
- return nil, fmt.Errorf("Cannot use postgres implementation")
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/roomserver/internal/api.go b/roomserver/internal/api.go
index 37a8a39b..6d7c8fcf 100644
--- a/roomserver/internal/api.go
+++ b/roomserver/internal/api.go
@@ -14,7 +14,7 @@ import (
// RoomserverInternalAPI is an implementation of api.RoomserverInternalAPI
type RoomserverInternalAPI struct {
DB storage.Database
- Cfg *config.Dendrite
+ Cfg *config.RoomServer
Producer sarama.SyncProducer
Cache caching.RoomVersionCache
ServerName gomatrixserverlib.ServerName
diff --git a/roomserver/internal/perform_join.go b/roomserver/internal/perform_join.go
index c5480a5b..73ea008d 100644
--- a/roomserver/internal/perform_join.go
+++ b/roomserver/internal/perform_join.go
@@ -189,12 +189,12 @@ func (r *RoomserverInternalAPI) performJoinRoomByID(
// but everyone has since left. I suspect it does the wrong thing.
buildRes := api.QueryLatestEventsAndStateResponse{}
event, err := eventutil.BuildEvent(
- ctx, // the request context
- &eb, // the template join event
- r.Cfg, // the server configuration
- time.Now(), // the event timestamp to use
- r, // the roomserver API to use
- &buildRes, // the query response
+ ctx, // the request context
+ &eb, // the template join event
+ r.Cfg.Matrix, // the server configuration
+ time.Now(), // the event timestamp to use
+ r, // the roomserver API to use
+ &buildRes, // the query response
)
switch err {
diff --git a/roomserver/internal/perform_leave.go b/roomserver/internal/perform_leave.go
index a19d0da9..79676530 100644
--- a/roomserver/internal/perform_leave.go
+++ b/roomserver/internal/perform_leave.go
@@ -99,12 +99,12 @@ func (r *RoomserverInternalAPI) performLeaveRoomByID(
// but everyone has since left. I suspect it does the wrong thing.
buildRes := api.QueryLatestEventsAndStateResponse{}
event, err := eventutil.BuildEvent(
- ctx, // the request context
- &eb, // the template leave event
- r.Cfg, // the server configuration
- time.Now(), // the event timestamp to use
- r, // the roomserver API to use
- &buildRes, // the query response
+ ctx, // the request context
+ &eb, // the template leave event
+ r.Cfg.Matrix, // the server configuration
+ time.Now(), // the event timestamp to use
+ r, // the roomserver API to use
+ &buildRes, // the query response
)
if err != nil {
return fmt.Errorf("eventutil.BuildEvent: %w", err)
diff --git a/roomserver/roomserver.go b/roomserver/roomserver.go
index 427d5ff3..1c226085 100644
--- a/roomserver/roomserver.go
+++ b/roomserver/roomserver.go
@@ -39,18 +39,20 @@ func NewInternalAPI(
keyRing gomatrixserverlib.JSONVerifier,
fedClient *gomatrixserverlib.FederationClient,
) api.RoomserverInternalAPI {
- roomserverDB, err := storage.Open(string(base.Cfg.Database.RoomServer), base.Cfg.DbProperties())
+ cfg := &base.Cfg.RoomServer
+
+ roomserverDB, err := storage.Open(&cfg.Database)
if err != nil {
logrus.WithError(err).Panicf("failed to connect to room server db")
}
return &internal.RoomserverInternalAPI{
DB: roomserverDB,
- Cfg: base.Cfg,
+ Cfg: cfg,
Producer: base.KafkaProducer,
- OutputRoomEventTopic: string(base.Cfg.Kafka.Topics.OutputRoomEvent),
+ OutputRoomEventTopic: string(cfg.Matrix.Kafka.Topics.OutputRoomEvent),
Cache: base.Caches,
- ServerName: base.Cfg.Matrix.ServerName,
+ ServerName: cfg.Matrix.ServerName,
FedClient: fedClient,
KeyRing: keyRing,
}
diff --git a/roomserver/roomserver_test.go b/roomserver/roomserver_test.go
index d553c5b7..d11c63b2 100644
--- a/roomserver/roomserver_test.go
+++ b/roomserver/roomserver_test.go
@@ -95,12 +95,12 @@ func mustLoadEvents(t *testing.T, ver gomatrixserverlib.RoomVersion, events []js
func mustSendEvents(t *testing.T, ver gomatrixserverlib.RoomVersion, events []json.RawMessage) (api.RoomserverInternalAPI, *dummyProducer, []gomatrixserverlib.HeaderedEvent) {
cfg := &config.Dendrite{}
- cfg.Database.RoomServer = roomserverDBFileURI
- cfg.Kafka.Topics.OutputRoomEvent = "output_room_event"
- cfg.Matrix.ServerName = testOrigin
- cfg.Kafka.UseNaffka = true
+ cfg.Defaults()
+ cfg.Global.ServerName = testOrigin
+ cfg.Global.Kafka.UseNaffka = true
+ cfg.RoomServer.Database.ConnectionString = config.DataSource(roomserverDBFileURI)
dp := &dummyProducer{
- topic: string(cfg.Kafka.Topics.OutputRoomEvent),
+ topic: string(cfg.Global.Kafka.Topics.OutputRoomEvent),
}
cache, err := caching.NewInMemoryLRUCache(true)
if err != nil {
diff --git a/roomserver/storage/postgres/storage.go b/roomserver/storage/postgres/storage.go
index c4f30f04..52ff479b 100644
--- a/roomserver/storage/postgres/storage.go
+++ b/roomserver/storage/postgres/storage.go
@@ -18,6 +18,7 @@ package postgres
import (
"database/sql"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
// Import the postgres database driver.
@@ -32,11 +33,11 @@ type Database struct {
// Open a postgres database.
// nolint: gocyclo
-func Open(dataSourceName string, dbProperties sqlutil.DbProperties) (*Database, error) {
+func Open(dbProperties *config.DatabaseOptions) (*Database, error) {
var d Database
var db *sql.DB
var err error
- if db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil {
+ if db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
eventStateKeys, err := NewPostgresEventStateKeysTable(db)
diff --git a/roomserver/storage/sqlite3/storage.go b/roomserver/storage/sqlite3/storage.go
index 11781ce0..048de192 100644
--- a/roomserver/storage/sqlite3/storage.go
+++ b/roomserver/storage/sqlite3/storage.go
@@ -19,6 +19,7 @@ import (
"context"
"database/sql"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/storage/shared"
"github.com/matrix-org/dendrite/roomserver/storage/tables"
@@ -44,13 +45,10 @@ type Database struct {
// Open a sqlite database.
// nolint: gocyclo
-func Open(dataSourceName string) (*Database, error) {
+func Open(dbProperties *config.DatabaseOptions) (*Database, error) {
var d Database
- cs, err := sqlutil.ParseFileURI(dataSourceName)
- if err != nil {
- return nil, err
- }
- if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
+ var err error
+ if d.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
//d.db.Exec("PRAGMA journal_mode=WAL;")
diff --git a/roomserver/storage/storage.go b/roomserver/storage/storage.go
index d7367e4c..c6561fdc 100644
--- a/roomserver/storage/storage.go
+++ b/roomserver/storage/storage.go
@@ -17,25 +17,21 @@
package storage
import (
- "net/url"
+ "fmt"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/roomserver/storage/postgres"
"github.com/matrix-org/dendrite/roomserver/storage/sqlite3"
)
// Open opens a database connection.
-func Open(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.Open(dataSourceName, dbProperties)
- }
- switch uri.Scheme {
- case "postgres":
- return postgres.Open(dataSourceName, dbProperties)
- case "file":
- return sqlite3.Open(dataSourceName)
+func Open(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.Open(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.Open(dbProperties)
default:
- return postgres.Open(dataSourceName, dbProperties)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/roomserver/storage/storage_wasm.go b/roomserver/storage/storage_wasm.go
index 78405b20..43367f36 100644
--- a/roomserver/storage/storage_wasm.go
+++ b/roomserver/storage/storage_wasm.go
@@ -16,27 +16,19 @@ package storage
import (
"fmt"
- "net/url"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/roomserver/storage/sqlite3"
)
// NewPublicRoomsServerDatabase opens a database connection.
-func Open(
- dataSourceName string,
- dbProperties sqlutil.DbProperties, // nolint:unparam
-) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return nil, fmt.Errorf("Cannot use postgres implementation")
- }
- switch uri.Scheme {
- case "postgres":
- return nil, fmt.Errorf("Cannot use postgres implementation")
- case "file":
- return sqlite3.Open(dataSourceName)
+func Open(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.Open(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return nil, fmt.Errorf("can't use Postgres implementation")
default:
- return nil, fmt.Errorf("Cannot use postgres implementation")
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/serverkeyapi/serverkeyapi.go b/serverkeyapi/serverkeyapi.go
index cddd392e..fbaaefad 100644
--- a/serverkeyapi/serverkeyapi.go
+++ b/serverkeyapi/serverkeyapi.go
@@ -25,13 +25,12 @@ func AddInternalRoutes(router *mux.Router, intAPI api.ServerKeyInternalAPI, cach
// NewInternalAPI returns a concerete implementation of the internal API. Callers
// can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
func NewInternalAPI(
- cfg *config.Dendrite,
+ cfg *config.ServerKeyAPI,
fedClient *gomatrixserverlib.FederationClient,
caches *caching.Caches,
) api.ServerKeyInternalAPI {
innerDB, err := storage.NewDatabase(
- string(cfg.Database.ServerKey),
- cfg.DbProperties(),
+ &cfg.Database,
cfg.Matrix.ServerName,
cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey),
cfg.Matrix.KeyID,
@@ -62,7 +61,7 @@ func NewInternalAPI(
}
var b64e = base64.StdEncoding.WithPadding(base64.NoPadding)
- for _, ps := range cfg.Matrix.KeyPerspectives {
+ for _, ps := range cfg.KeyPerspectives {
perspective := &gomatrixserverlib.PerspectiveKeyFetcher{
PerspectiveServerName: ps.ServerName,
PerspectiveServerKeys: map[gomatrixserverlib.KeyID]ed25519.PublicKey{},
diff --git a/serverkeyapi/serverkeyapi_test.go b/serverkeyapi/serverkeyapi_test.go
index c53575bb..152a853e 100644
--- a/serverkeyapi/serverkeyapi_test.go
+++ b/serverkeyapi/serverkeyapi_test.go
@@ -23,7 +23,8 @@ import (
type server struct {
name gomatrixserverlib.ServerName // server name
validity time.Duration // key validity duration from now
- config *config.Dendrite // skeleton config, from TestMain
+ config *config.ServerKeyAPI // skeleton config, from TestMain
+ fedconfig *config.FederationAPI //
fedclient *gomatrixserverlib.FederationClient // uses MockRoundTripper
cache *caching.Caches // server-specific cache
api api.ServerKeyInternalAPI // server-specific server key API
@@ -69,13 +70,15 @@ func TestMain(m *testing.M) {
// Draw up just enough Dendrite config for the server key
// API to work.
- s.config = &config.Dendrite{}
- s.config.SetDefaults()
- s.config.Matrix.ServerName = gomatrixserverlib.ServerName(s.name)
- s.config.Matrix.PrivateKey = testPriv
- s.config.Matrix.KeyID = serverKeyID
- s.config.Matrix.KeyValidityPeriod = s.validity
- s.config.Database.ServerKey = config.DataSource("file::memory:")
+ cfg := &config.Dendrite{}
+ cfg.Defaults()
+ cfg.Global.ServerName = gomatrixserverlib.ServerName(s.name)
+ cfg.Global.PrivateKey = testPriv
+ cfg.Global.KeyID = serverKeyID
+ cfg.Global.KeyValidityPeriod = s.validity
+ cfg.ServerKeyAPI.Database.ConnectionString = config.DataSource("file::memory:")
+ s.config = &cfg.ServerKeyAPI
+ s.fedconfig = &cfg.FederationAPI
// Create a transport which redirects federation requests to
// the mock round tripper. Since we're not *really* listening for
@@ -115,7 +118,7 @@ func (m *MockRoundTripper) RoundTrip(req *http.Request) (res *http.Response, err
}
// Get the keys and JSON-ify them.
- keys := routing.LocalKeys(s.config)
+ keys := routing.LocalKeys(s.fedconfig)
body, err := json.MarshalIndent(keys.JSON, "", " ")
if err != nil {
return nil, err
diff --git a/serverkeyapi/storage/keydb.go b/serverkeyapi/storage/keydb.go
index c28c4de1..3d3a0c30 100644
--- a/serverkeyapi/storage/keydb.go
+++ b/serverkeyapi/storage/keydb.go
@@ -17,11 +17,11 @@
package storage
import (
- "net/url"
+ "fmt"
"golang.org/x/crypto/ed25519"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/serverkeyapi/storage/postgres"
"github.com/matrix-org/dendrite/serverkeyapi/storage/sqlite3"
"github.com/matrix-org/gomatrixserverlib"
@@ -29,22 +29,17 @@ import (
// NewDatabase opens a database connection.
func NewDatabase(
- dataSourceName string,
- dbProperties sqlutil.DbProperties,
+ dbProperties *config.DatabaseOptions,
serverName gomatrixserverlib.ServerName,
serverKey ed25519.PublicKey,
serverKeyID gomatrixserverlib.KeyID,
) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.NewDatabase(dataSourceName, dbProperties, serverName, serverKey, serverKeyID)
- }
- switch uri.Scheme {
- case "postgres":
- return postgres.NewDatabase(dataSourceName, dbProperties, serverName, serverKey, serverKeyID)
- case "file":
- return sqlite3.NewDatabase(dataSourceName, serverName, serverKey, serverKeyID)
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties, serverName, serverKey, serverKeyID)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.NewDatabase(dbProperties, serverName, serverKey, serverKeyID)
default:
- return postgres.NewDatabase(dataSourceName, dbProperties, serverName, serverKey, serverKeyID)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/serverkeyapi/storage/postgres/keydb.go b/serverkeyapi/storage/postgres/keydb.go
index aaa4409b..63444085 100644
--- a/serverkeyapi/storage/postgres/keydb.go
+++ b/serverkeyapi/storage/postgres/keydb.go
@@ -20,6 +20,7 @@ import (
"golang.org/x/crypto/ed25519"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib"
)
@@ -35,13 +36,12 @@ type Database struct {
// It prepares all the SQL statements that it will use.
// Returns an error if there was a problem talking to the database.
func NewDatabase(
- dataSourceName string,
- dbProperties sqlutil.DbProperties,
+ dbProperties *config.DatabaseOptions,
serverName gomatrixserverlib.ServerName,
serverKey ed25519.PublicKey,
serverKeyID gomatrixserverlib.KeyID,
) (*Database, error) {
- db, err := sqlutil.Open("postgres", dataSourceName, dbProperties)
+ db, err := sqlutil.Open(dbProperties)
if err != nil {
return nil, err
}
diff --git a/serverkeyapi/storage/sqlite3/keydb.go b/serverkeyapi/storage/sqlite3/keydb.go
index dc72b79e..5174ece1 100644
--- a/serverkeyapi/storage/sqlite3/keydb.go
+++ b/serverkeyapi/storage/sqlite3/keydb.go
@@ -20,6 +20,7 @@ import (
"golang.org/x/crypto/ed25519"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib"
@@ -37,16 +38,12 @@ type Database struct {
// It prepares all the SQL statements that it will use.
// Returns an error if there was a problem talking to the database.
func NewDatabase(
- dataSourceName string,
+ dbProperties *config.DatabaseOptions,
serverName gomatrixserverlib.ServerName,
serverKey ed25519.PublicKey,
serverKeyID gomatrixserverlib.KeyID,
) (*Database, error) {
- cs, err := sqlutil.ParseFileURI(dataSourceName)
- if err != nil {
- return nil, err
- }
- db, err := sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil)
+ db, err := sqlutil.Open(dbProperties)
if err != nil {
return nil, err
}
diff --git a/syncapi/consumers/clientapi.go b/syncapi/consumers/clientapi.go
index f7cf96d9..ceaa735a 100644
--- a/syncapi/consumers/clientapi.go
+++ b/syncapi/consumers/clientapi.go
@@ -37,14 +37,14 @@ type OutputClientDataConsumer struct {
// NewOutputClientDataConsumer creates a new OutputClientData consumer. Call Start() to begin consuming from room servers.
func NewOutputClientDataConsumer(
- cfg *config.Dendrite,
+ cfg *config.SyncAPI,
kafkaConsumer sarama.Consumer,
n *sync.Notifier,
store storage.Database,
) *OutputClientDataConsumer {
consumer := internal.ContinualConsumer{
- Topic: string(cfg.Kafka.Topics.OutputClientData),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputClientData),
Consumer: kafkaConsumer,
PartitionStore: store,
}
diff --git a/syncapi/consumers/eduserver_sendtodevice.go b/syncapi/consumers/eduserver_sendtodevice.go
index 06a8928d..20dd1756 100644
--- a/syncapi/consumers/eduserver_sendtodevice.go
+++ b/syncapi/consumers/eduserver_sendtodevice.go
@@ -41,14 +41,14 @@ type OutputSendToDeviceEventConsumer struct {
// NewOutputSendToDeviceEventConsumer creates a new OutputSendToDeviceEventConsumer.
// Call Start() to begin consuming from the EDU server.
func NewOutputSendToDeviceEventConsumer(
- cfg *config.Dendrite,
+ cfg *config.SyncAPI,
kafkaConsumer sarama.Consumer,
n *sync.Notifier,
store storage.Database,
) *OutputSendToDeviceEventConsumer {
consumer := internal.ContinualConsumer{
- Topic: string(cfg.Kafka.Topics.OutputSendToDeviceEvent),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputSendToDeviceEvent),
Consumer: kafkaConsumer,
PartitionStore: store,
}
diff --git a/syncapi/consumers/eduserver_typing.go b/syncapi/consumers/eduserver_typing.go
index 0a9a9c0c..fc5703d3 100644
--- a/syncapi/consumers/eduserver_typing.go
+++ b/syncapi/consumers/eduserver_typing.go
@@ -37,14 +37,14 @@ type OutputTypingEventConsumer struct {
// NewOutputTypingEventConsumer creates a new OutputTypingEventConsumer.
// Call Start() to begin consuming from the EDU server.
func NewOutputTypingEventConsumer(
- cfg *config.Dendrite,
+ cfg *config.SyncAPI,
kafkaConsumer sarama.Consumer,
n *sync.Notifier,
store storage.Database,
) *OutputTypingEventConsumer {
consumer := internal.ContinualConsumer{
- Topic: string(cfg.Kafka.Topics.OutputTypingEvent),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputTypingEvent),
Consumer: kafkaConsumer,
PartitionStore: store,
}
diff --git a/syncapi/consumers/roomserver.go b/syncapi/consumers/roomserver.go
index f8cdcd5c..06c904c3 100644
--- a/syncapi/consumers/roomserver.go
+++ b/syncapi/consumers/roomserver.go
@@ -40,7 +40,7 @@ type OutputRoomEventConsumer struct {
// NewOutputRoomEventConsumer creates a new OutputRoomEventConsumer. Call Start() to begin consuming from room servers.
func NewOutputRoomEventConsumer(
- cfg *config.Dendrite,
+ cfg *config.SyncAPI,
kafkaConsumer sarama.Consumer,
n *sync.Notifier,
store storage.Database,
@@ -49,7 +49,7 @@ func NewOutputRoomEventConsumer(
) *OutputRoomEventConsumer {
consumer := internal.ContinualConsumer{
- Topic: string(cfg.Kafka.Topics.OutputRoomEvent),
+ Topic: string(cfg.Matrix.Kafka.Topics.OutputRoomEvent),
Consumer: kafkaConsumer,
PartitionStore: store,
}
diff --git a/syncapi/routing/messages.go b/syncapi/routing/messages.go
index 15add1b4..0999d3e8 100644
--- a/syncapi/routing/messages.go
+++ b/syncapi/routing/messages.go
@@ -36,7 +36,7 @@ type messagesReq struct {
db storage.Database
rsAPI api.RoomserverInternalAPI
federation *gomatrixserverlib.FederationClient
- cfg *config.Dendrite
+ cfg *config.SyncAPI
roomID string
from *types.TopologyToken
to *types.TopologyToken
@@ -61,7 +61,7 @@ func OnIncomingMessagesRequest(
req *http.Request, db storage.Database, roomID string,
federation *gomatrixserverlib.FederationClient,
rsAPI api.RoomserverInternalAPI,
- cfg *config.Dendrite,
+ cfg *config.SyncAPI,
) util.JSONResponse {
var err error
diff --git a/syncapi/routing/routing.go b/syncapi/routing/routing.go
index ed0f872e..ec21c1b4 100644
--- a/syncapi/routing/routing.go
+++ b/syncapi/routing/routing.go
@@ -39,7 +39,7 @@ func Setup(
publicAPIMux *mux.Router, srp *sync.RequestPool, syncDB storage.Database,
userAPI userapi.UserInternalAPI, federation *gomatrixserverlib.FederationClient,
rsAPI api.RoomserverInternalAPI,
- cfg *config.Dendrite,
+ cfg *config.SyncAPI,
) {
r0mux := publicAPIMux.PathPrefix(pathPrefixR0).Subrouter()
diff --git a/syncapi/storage/postgres/syncserver.go b/syncapi/storage/postgres/syncserver.go
index 10c1b37c..26ef082f 100644
--- a/syncapi/storage/postgres/syncserver.go
+++ b/syncapi/storage/postgres/syncserver.go
@@ -21,6 +21,7 @@ import (
// Import the postgres database driver.
_ "github.com/lib/pq"
"github.com/matrix-org/dendrite/eduserver/cache"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/syncapi/storage/shared"
)
@@ -34,10 +35,10 @@ type SyncServerDatasource struct {
}
// NewDatabase creates a new sync server database
-func NewDatabase(dbDataSourceName string, dbProperties sqlutil.DbProperties) (*SyncServerDatasource, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions) (*SyncServerDatasource, error) {
var d SyncServerDatasource
var err error
- if d.db, err = sqlutil.Open("postgres", dbDataSourceName, dbProperties); err != nil {
+ if d.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
if err = d.PartitionOffsetStatements.Prepare(d.db, "syncapi"); err != nil {
diff --git a/syncapi/storage/sqlite3/syncserver.go b/syncapi/storage/sqlite3/syncserver.go
index c85db5a4..9564a23a 100644
--- a/syncapi/storage/sqlite3/syncserver.go
+++ b/syncapi/storage/sqlite3/syncserver.go
@@ -22,6 +22,7 @@ import (
_ "github.com/mattn/go-sqlite3"
"github.com/matrix-org/dendrite/eduserver/cache"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/syncapi/storage/shared"
)
@@ -37,13 +38,10 @@ type SyncServerDatasource struct {
// NewDatabase creates a new sync server database
// nolint: gocyclo
-func NewDatabase(dataSourceName string) (*SyncServerDatasource, error) {
+func NewDatabase(dbProperties *config.DatabaseOptions) (*SyncServerDatasource, error) {
var d SyncServerDatasource
- cs, err := sqlutil.ParseFileURI(dataSourceName)
- if err != nil {
- return nil, err
- }
- if d.db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
+ var err error
+ if d.db, err = sqlutil.Open(dbProperties); err != nil {
return nil, err
}
if err = d.prepare(); err != nil {
diff --git a/syncapi/storage/storage.go b/syncapi/storage/storage.go
index ea69da3b..c16dcd81 100644
--- a/syncapi/storage/storage.go
+++ b/syncapi/storage/storage.go
@@ -17,25 +17,21 @@
package storage
import (
- "net/url"
+ "fmt"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/syncapi/storage/postgres"
"github.com/matrix-org/dendrite/syncapi/storage/sqlite3"
)
// NewSyncServerDatasource opens a database connection.
-func NewSyncServerDatasource(dataSourceName string, dbProperties sqlutil.DbProperties) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.NewDatabase(dataSourceName, dbProperties)
- }
- switch uri.Scheme {
- case "postgres":
- return postgres.NewDatabase(dataSourceName, dbProperties)
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
+func NewSyncServerDatasource(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.NewDatabase(dbProperties)
default:
- return postgres.NewDatabase(dataSourceName, dbProperties)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/syncapi/storage/storage_test.go b/syncapi/storage/storage_test.go
index 1f679def..0e827c95 100644
--- a/syncapi/storage/storage_test.go
+++ b/syncapi/storage/storage_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"time"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/syncapi/storage"
"github.com/matrix-org/dendrite/syncapi/storage/sqlite3"
"github.com/matrix-org/dendrite/syncapi/types"
@@ -59,7 +60,9 @@ func MustCreateDatabase(t *testing.T) storage.Database {
t.Fatalf("tried to delete stale test database but failed: %s", err)
}
}
- db, err := sqlite3.NewDatabase(fmt.Sprintf("file:%s", dbname))
+ db, err := sqlite3.NewDatabase(&config.DatabaseOptions{
+ ConnectionString: config.DataSource(fmt.Sprintf("file:%s", dbname)),
+ })
if err != nil {
t.Fatalf("NewSyncServerDatasource returned %s", err)
}
diff --git a/syncapi/storage/storage_wasm.go b/syncapi/storage/storage_wasm.go
index 0886b8c2..43b7bbea 100644
--- a/syncapi/storage/storage_wasm.go
+++ b/syncapi/storage/storage_wasm.go
@@ -16,27 +16,19 @@ package storage
import (
"fmt"
- "net/url"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/syncapi/storage/sqlite3"
)
// NewPublicRoomsServerDatabase opens a database connection.
-func NewSyncServerDatasource(
- dataSourceName string,
- dbProperties sqlutil.DbProperties, // nolint:unparam
-) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return nil, fmt.Errorf("Cannot use postgres implementation")
- }
- switch uri.Scheme {
- case "postgres":
- return nil, fmt.Errorf("Cannot use postgres implementation")
- case "file":
- return sqlite3.NewDatabase(dataSourceName)
+func NewSyncServerDatasource(dbProperties *config.DatabaseOptions) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties)
+ case dbProperties.ConnectionString.IsPostgres():
+ return nil, fmt.Errorf("can't use Postgres implementation")
default:
- return nil, fmt.Errorf("Cannot use postgres implementation")
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/syncapi/syncapi.go b/syncapi/syncapi.go
index 5198d59b..9caed7be 100644
--- a/syncapi/syncapi.go
+++ b/syncapi/syncapi.go
@@ -44,9 +44,9 @@ func AddPublicRoutes(
keyAPI keyapi.KeyInternalAPI,
currentStateAPI currentstateapi.CurrentStateInternalAPI,
federation *gomatrixserverlib.FederationClient,
- cfg *config.Dendrite,
+ cfg *config.SyncAPI,
) {
- syncDB, err := storage.NewSyncServerDatasource(string(cfg.Database.SyncAPI), cfg.DbProperties())
+ syncDB, err := storage.NewSyncServerDatasource(&cfg.Database)
if err != nil {
logrus.WithError(err).Panicf("failed to connect to sync db")
}
@@ -65,7 +65,7 @@ func AddPublicRoutes(
requestPool := sync.NewRequestPool(syncDB, notifier, userAPI, keyAPI, currentStateAPI)
keyChangeConsumer := consumers.NewOutputKeyChangeEventConsumer(
- cfg.Matrix.ServerName, string(cfg.Kafka.Topics.OutputKeyChangeEvent),
+ cfg.Matrix.ServerName, string(cfg.Matrix.Kafka.Topics.OutputKeyChangeEvent),
consumer, notifier, keyAPI, currentStateAPI, syncDB,
)
if err = keyChangeConsumer.Start(); err != nil {
diff --git a/userapi/storage/accounts/postgres/storage.go b/userapi/storage/accounts/postgres/storage.go
index f56fb6d8..9653c019 100644
--- a/userapi/storage/accounts/postgres/storage.go
+++ b/userapi/storage/accounts/postgres/storage.go
@@ -22,6 +22,7 @@ import (
"strconv"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
@@ -43,10 +44,9 @@ type Database struct {
}
// NewDatabase creates a new accounts and profiles database
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties, serverName gomatrixserverlib.ServerName) (*Database, error) {
- var db *sql.DB
- var err error
- if db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil {
+func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (*Database, error) {
+ db, err := sqlutil.Open(dbProperties)
+ if err != nil {
return nil, err
}
partitions := sqlutil.PartitionOffsetStatements{}
diff --git a/userapi/storage/accounts/sqlite3/storage.go b/userapi/storage/accounts/sqlite3/storage.go
index 72239014..4d2c5e51 100644
--- a/userapi/storage/accounts/sqlite3/storage.go
+++ b/userapi/storage/accounts/sqlite3/storage.go
@@ -23,6 +23,7 @@ import (
"sync"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
@@ -47,16 +48,11 @@ type Database struct {
}
// NewDatabase creates a new accounts and profiles database
-func NewDatabase(dataSourceName string, serverName gomatrixserverlib.ServerName) (*Database, error) {
- var db *sql.DB
- var err error
- cs, err := sqlutil.ParseFileURI(dataSourceName)
+func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (*Database, error) {
+ db, err := sqlutil.Open(dbProperties)
if err != nil {
return nil, err
}
- if db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
- return nil, err
- }
partitions := sqlutil.PartitionOffsetStatements{}
if err = partitions.Prepare(db, "account"); err != nil {
return nil, err
diff --git a/userapi/storage/accounts/storage.go b/userapi/storage/accounts/storage.go
index 87f626bf..57d5f703 100644
--- a/userapi/storage/accounts/storage.go
+++ b/userapi/storage/accounts/storage.go
@@ -17,9 +17,9 @@
package accounts
import (
- "net/url"
+ "fmt"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/userapi/storage/accounts/postgres"
"github.com/matrix-org/dendrite/userapi/storage/accounts/sqlite3"
"github.com/matrix-org/gomatrixserverlib"
@@ -27,17 +27,13 @@ import (
// NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme)
// and sets postgres connection parameters
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties, serverName gomatrixserverlib.ServerName) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.NewDatabase(dataSourceName, dbProperties, serverName)
- }
- switch uri.Scheme {
- case "postgres":
- return postgres.NewDatabase(dataSourceName, dbProperties, serverName)
- case "file":
- return sqlite3.NewDatabase(dataSourceName, serverName)
+func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties, serverName)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.NewDatabase(dbProperties, serverName)
default:
- return postgres.NewDatabase(dataSourceName, dbProperties, serverName)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/userapi/storage/accounts/storage_wasm.go b/userapi/storage/accounts/storage_wasm.go
index 69256705..ade32b68 100644
--- a/userapi/storage/accounts/storage_wasm.go
+++ b/userapi/storage/accounts/storage_wasm.go
@@ -16,28 +16,22 @@ package accounts
import (
"fmt"
- "net/url"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/userapi/storage/accounts/sqlite3"
"github.com/matrix-org/gomatrixserverlib"
)
func NewDatabase(
- dataSourceName string,
- dbProperties sqlutil.DbProperties, // nolint:unparam
+ dbProperties *config.DatabaseOptions,
serverName gomatrixserverlib.ServerName,
) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return nil, fmt.Errorf("Cannot use postgres implementation")
- }
- switch uri.Scheme {
- case "postgres":
- return nil, fmt.Errorf("Cannot use postgres implementation")
- case "file":
- return sqlite3.NewDatabase(dataSourceName, serverName)
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties, serverName)
+ case dbProperties.ConnectionString.IsPostgres():
+ return nil, fmt.Errorf("can't use Postgres implementation")
default:
- return nil, fmt.Errorf("Cannot use postgres implementation")
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/userapi/storage/devices/postgres/storage.go b/userapi/storage/devices/postgres/storage.go
index 6ac802bb..4a7c7f97 100644
--- a/userapi/storage/devices/postgres/storage.go
+++ b/userapi/storage/devices/postgres/storage.go
@@ -20,6 +20,7 @@ import (
"database/sql"
"encoding/base64"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
@@ -35,10 +36,9 @@ type Database struct {
}
// NewDatabase creates a new device database
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties, serverName gomatrixserverlib.ServerName) (*Database, error) {
- var db *sql.DB
- var err error
- if db, err = sqlutil.Open("postgres", dataSourceName, dbProperties); err != nil {
+func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (*Database, error) {
+ db, err := sqlutil.Open(dbProperties)
+ if err != nil {
return nil, err
}
d := devicesStatements{}
diff --git a/userapi/storage/devices/sqlite3/storage.go b/userapi/storage/devices/sqlite3/storage.go
index b9f08ca1..1f2b59f3 100644
--- a/userapi/storage/devices/sqlite3/storage.go
+++ b/userapi/storage/devices/sqlite3/storage.go
@@ -20,6 +20,7 @@ import (
"database/sql"
"encoding/base64"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
@@ -37,16 +38,11 @@ type Database struct {
}
// NewDatabase creates a new device database
-func NewDatabase(dataSourceName string, serverName gomatrixserverlib.ServerName) (*Database, error) {
- var db *sql.DB
- var err error
- cs, err := sqlutil.ParseFileURI(dataSourceName)
+func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (*Database, error) {
+ db, err := sqlutil.Open(dbProperties)
if err != nil {
return nil, err
}
- if db, err = sqlutil.Open(sqlutil.SQLiteDriverName(), cs, nil); err != nil {
- return nil, err
- }
d := devicesStatements{}
if err = d.prepare(db, serverName); err != nil {
return nil, err
diff --git a/userapi/storage/devices/storage.go b/userapi/storage/devices/storage.go
index e094d202..1bd73a9f 100644
--- a/userapi/storage/devices/storage.go
+++ b/userapi/storage/devices/storage.go
@@ -17,9 +17,9 @@
package devices
import (
- "net/url"
+ "fmt"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/userapi/storage/devices/postgres"
"github.com/matrix-org/dendrite/userapi/storage/devices/sqlite3"
"github.com/matrix-org/gomatrixserverlib"
@@ -27,17 +27,13 @@ import (
// NewDatabase opens a new Postgres or Sqlite database (based on dataSourceName scheme)
// and sets postgres connection parameters
-func NewDatabase(dataSourceName string, dbProperties sqlutil.DbProperties, serverName gomatrixserverlib.ServerName) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return postgres.NewDatabase(dataSourceName, dbProperties, serverName)
- }
- switch uri.Scheme {
- case "postgres":
- return postgres.NewDatabase(dataSourceName, dbProperties, serverName)
- case "file":
- return sqlite3.NewDatabase(dataSourceName, serverName)
+func NewDatabase(dbProperties *config.DatabaseOptions, serverName gomatrixserverlib.ServerName) (Database, error) {
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties, serverName)
+ case dbProperties.ConnectionString.IsPostgres():
+ return postgres.NewDatabase(dbProperties, serverName)
default:
- return postgres.NewDatabase(dataSourceName, dbProperties, serverName)
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/userapi/storage/devices/storage_wasm.go b/userapi/storage/devices/storage_wasm.go
index a5a515ef..e966c37f 100644
--- a/userapi/storage/devices/storage_wasm.go
+++ b/userapi/storage/devices/storage_wasm.go
@@ -16,28 +16,22 @@ package devices
import (
"fmt"
- "net/url"
- "github.com/matrix-org/dendrite/internal/sqlutil"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/userapi/storage/devices/sqlite3"
"github.com/matrix-org/gomatrixserverlib"
)
func NewDatabase(
- dataSourceName string,
- dbProperties sqlutil.DbProperties, // nolint:unparam
+ dbProperties *config.DatabaseOptions,
serverName gomatrixserverlib.ServerName,
) (Database, error) {
- uri, err := url.Parse(dataSourceName)
- if err != nil {
- return nil, fmt.Errorf("Cannot use postgres implementation")
- }
- switch uri.Scheme {
- case "postgres":
- return nil, fmt.Errorf("Cannot use postgres implementation")
- case "file":
- return sqlite3.NewDatabase(dataSourceName, serverName)
+ switch {
+ case dbProperties.ConnectionString.IsSQLite():
+ return sqlite3.NewDatabase(dbProperties, serverName)
+ case dbProperties.ConnectionString.IsPostgres():
+ return nil, fmt.Errorf("can't use Postgres implementation")
default:
- return nil, fmt.Errorf("Cannot use postgres implementation")
+ return nil, fmt.Errorf("unexpected database type")
}
}
diff --git a/userapi/userapi_test.go b/userapi/userapi_test.go
index dab1ec71..548148f2 100644
--- a/userapi/userapi_test.go
+++ b/userapi/userapi_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/gorilla/mux"
+ "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/test"
"github.com/matrix-org/dendrite/userapi"
@@ -23,11 +24,15 @@ const (
)
func MustMakeInternalAPI(t *testing.T) (api.UserInternalAPI, accounts.Database, devices.Database) {
- accountDB, err := accounts.NewDatabase("file::memory:", nil, serverName)
+ accountDB, err := accounts.NewDatabase(&config.DatabaseOptions{
+ ConnectionString: "file::memory:",
+ }, serverName)
if err != nil {
t.Fatalf("failed to create account DB: %s", err)
}
- deviceDB, err := devices.NewDatabase("file::memory:", nil, serverName)
+ deviceDB, err := devices.NewDatabase(&config.DatabaseOptions{
+ ConnectionString: "file::memory:",
+ }, serverName)
if err != nil {
t.Fatalf("failed to create device DB: %s", err)
}