mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-29 01:33:10 -06:00
Try to fold signing key server into federation API
This commit is contained in:
parent
59852a28ae
commit
0d156daf14
|
|
@ -271,9 +271,8 @@ func (m *DendriteMonolith) Start() {
|
||||||
cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-mediaapi.db", m.CacheDirectory, prefix))
|
cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-mediaapi.db", m.CacheDirectory, prefix))
|
||||||
cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-syncapi.db", m.StorageDirectory, prefix))
|
cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-syncapi.db", m.StorageDirectory, prefix))
|
||||||
cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-roomserver.db", m.StorageDirectory, prefix))
|
cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-roomserver.db", m.StorageDirectory, prefix))
|
||||||
cfg.SigningKeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-signingkeyserver.db", m.StorageDirectory, prefix))
|
|
||||||
cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-keyserver.db", m.StorageDirectory, prefix))
|
cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-keyserver.db", m.StorageDirectory, prefix))
|
||||||
cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-federationapi.db", m.StorageDirectory, prefix))
|
cfg.FederationAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-federationapi.db", m.StorageDirectory, prefix))
|
||||||
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-appservice.db", m.StorageDirectory, prefix))
|
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/%s-appservice.db", m.StorageDirectory, prefix))
|
||||||
cfg.MediaAPI.BasePath = config.Path(fmt.Sprintf("%s/media", m.CacheDirectory))
|
cfg.MediaAPI.BasePath = config.Path(fmt.Sprintf("%s/media", m.CacheDirectory))
|
||||||
cfg.MediaAPI.AbsBasePath = config.Path(fmt.Sprintf("%s/media", m.CacheDirectory))
|
cfg.MediaAPI.AbsBasePath = config.Path(fmt.Sprintf("%s/media", m.CacheDirectory))
|
||||||
|
|
@ -291,12 +290,10 @@ func (m *DendriteMonolith) Start() {
|
||||||
serverKeyAPI := &signing.YggdrasilKeys{}
|
serverKeyAPI := &signing.YggdrasilKeys{}
|
||||||
keyRing := serverKeyAPI.KeyRing()
|
keyRing := serverKeyAPI.KeyRing()
|
||||||
|
|
||||||
rsAPI := roomserver.NewInternalAPI(
|
rsAPI := roomserver.NewInternalAPI(base)
|
||||||
base, keyRing,
|
|
||||||
)
|
|
||||||
|
|
||||||
fsAPI := federationapi.NewInternalAPI(
|
fsAPI := federationapi.NewInternalAPI(
|
||||||
base, federation, rsAPI, keyRing, true,
|
base, federation, rsAPI, base.Caches, true,
|
||||||
)
|
)
|
||||||
|
|
||||||
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI)
|
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI)
|
||||||
|
|
@ -312,6 +309,7 @@ func (m *DendriteMonolith) Start() {
|
||||||
// The underlying roomserver implementation needs to be able to call the fedsender.
|
// The underlying roomserver implementation needs to be able to call the fedsender.
|
||||||
// This is different to rsAPI which can be the http client which doesn't need this dependency
|
// This is different to rsAPI which can be the http client which doesn't need this dependency
|
||||||
rsAPI.SetFederationSenderAPI(fsAPI)
|
rsAPI.SetFederationSenderAPI(fsAPI)
|
||||||
|
rsAPI.SetKeyring(keyRing)
|
||||||
|
|
||||||
monolith := setup.Monolith{
|
monolith := setup.Monolith{
|
||||||
Config: base.Cfg,
|
Config: base.Cfg,
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,8 @@ func (m *DendriteMonolith) Start() {
|
||||||
cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-mediaapi.db", m.StorageDirectory))
|
cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-mediaapi.db", m.StorageDirectory))
|
||||||
cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-syncapi.db", m.StorageDirectory))
|
cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-syncapi.db", m.StorageDirectory))
|
||||||
cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-roomserver.db", m.StorageDirectory))
|
cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-roomserver.db", m.StorageDirectory))
|
||||||
cfg.SigningKeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-signingkeyserver.db", m.StorageDirectory))
|
|
||||||
cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-keyserver.db", m.StorageDirectory))
|
cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-keyserver.db", m.StorageDirectory))
|
||||||
cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-federationapi.db", m.StorageDirectory))
|
cfg.FederationAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-federationapi.db", m.StorageDirectory))
|
||||||
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-appservice.db", m.StorageDirectory))
|
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s/dendrite-p2p-appservice.db", m.StorageDirectory))
|
||||||
cfg.MediaAPI.BasePath = config.Path(fmt.Sprintf("%s/tmp", 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.MediaAPI.AbsBasePath = config.Path(fmt.Sprintf("%s/tmp", m.StorageDirectory))
|
||||||
|
|
@ -112,12 +111,10 @@ func (m *DendriteMonolith) Start() {
|
||||||
serverKeyAPI := &signing.YggdrasilKeys{}
|
serverKeyAPI := &signing.YggdrasilKeys{}
|
||||||
keyRing := serverKeyAPI.KeyRing()
|
keyRing := serverKeyAPI.KeyRing()
|
||||||
|
|
||||||
rsAPI := roomserver.NewInternalAPI(
|
rsAPI := roomserver.NewInternalAPI(base)
|
||||||
base, keyRing,
|
|
||||||
)
|
|
||||||
|
|
||||||
fsAPI := federationapi.NewInternalAPI(
|
fsAPI := federationapi.NewInternalAPI(
|
||||||
base, federation, rsAPI, keyRing, true,
|
base, federation, rsAPI, base.Caches, true,
|
||||||
)
|
)
|
||||||
|
|
||||||
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, federation)
|
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, federation)
|
||||||
|
|
@ -134,6 +131,7 @@ func (m *DendriteMonolith) Start() {
|
||||||
// The underlying roomserver implementation needs to be able to call the fedsender.
|
// The underlying roomserver implementation needs to be able to call the fedsender.
|
||||||
// This is different to rsAPI which can be the http client which doesn't need this dependency
|
// This is different to rsAPI which can be the http client which doesn't need this dependency
|
||||||
rsAPI.SetFederationSenderAPI(fsAPI)
|
rsAPI.SetFederationSenderAPI(fsAPI)
|
||||||
|
rsAPI.SetKeyring(keyRing)
|
||||||
|
|
||||||
monolith := setup.Monolith{
|
monolith := setup.Monolith{
|
||||||
Config: base.Cfg,
|
Config: base.Cfg,
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/setup"
|
"github.com/matrix-org/dendrite/setup"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/setup/mscs"
|
"github.com/matrix-org/dendrite/setup/mscs"
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver"
|
|
||||||
"github.com/matrix-org/dendrite/userapi"
|
"github.com/matrix-org/dendrite/userapi"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
|
||||||
|
|
@ -125,14 +124,13 @@ func main() {
|
||||||
cfg.Global.PrivateKey = privKey
|
cfg.Global.PrivateKey = privKey
|
||||||
cfg.Global.KeyID = gomatrixserverlib.KeyID(fmt.Sprintf("ed25519:%s", *instanceName))
|
cfg.Global.KeyID = gomatrixserverlib.KeyID(fmt.Sprintf("ed25519:%s", *instanceName))
|
||||||
cfg.Global.Kafka.UseNaffka = true
|
cfg.Global.Kafka.UseNaffka = true
|
||||||
cfg.FederationSender.FederationMaxRetries = 6
|
cfg.FederationAPI.FederationMaxRetries = 6
|
||||||
cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName))
|
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.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.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.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.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName))
|
||||||
cfg.SigningKeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-signingkeyserver.db", *instanceName))
|
cfg.FederationAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationapi.db", *instanceName))
|
||||||
cfg.FederationSender.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationapi.db", *instanceName))
|
|
||||||
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
|
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
|
||||||
cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.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))
|
cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-e2ekey.db", *instanceName))
|
||||||
|
|
@ -151,16 +149,8 @@ func main() {
|
||||||
userAPI := userapi.NewInternalAPI(accountDB, &cfg.UserAPI, nil, keyAPI)
|
userAPI := userapi.NewInternalAPI(accountDB, &cfg.UserAPI, nil, keyAPI)
|
||||||
keyAPI.SetUserAPI(userAPI)
|
keyAPI.SetUserAPI(userAPI)
|
||||||
|
|
||||||
serverKeyAPI := signingkeyserver.NewInternalAPI(
|
|
||||||
&base.Base.Cfg.SigningKeyServer, federation, base.Base.Caches,
|
|
||||||
)
|
|
||||||
keyRing := serverKeyAPI.KeyRing()
|
|
||||||
createKeyDB(
|
|
||||||
base, serverKeyAPI,
|
|
||||||
)
|
|
||||||
|
|
||||||
rsAPI := roomserver.NewInternalAPI(
|
rsAPI := roomserver.NewInternalAPI(
|
||||||
&base.Base, keyRing,
|
&base.Base,
|
||||||
)
|
)
|
||||||
eduInputAPI := eduserver.NewInternalAPI(
|
eduInputAPI := eduserver.NewInternalAPI(
|
||||||
&base.Base, cache.New(), userAPI,
|
&base.Base, cache.New(), userAPI,
|
||||||
|
|
@ -168,8 +158,9 @@ func main() {
|
||||||
asAPI := appservice.NewInternalAPI(&base.Base, userAPI, rsAPI)
|
asAPI := appservice.NewInternalAPI(&base.Base, userAPI, rsAPI)
|
||||||
rsAPI.SetAppserviceAPI(asAPI)
|
rsAPI.SetAppserviceAPI(asAPI)
|
||||||
fsAPI := federationapi.NewInternalAPI(
|
fsAPI := federationapi.NewInternalAPI(
|
||||||
&base.Base, federation, rsAPI, keyRing, true,
|
&base.Base, federation, rsAPI, base.Base.Caches, true,
|
||||||
)
|
)
|
||||||
|
keyRing := fsAPI.KeyRing()
|
||||||
rsAPI.SetFederationSenderAPI(fsAPI)
|
rsAPI.SetFederationSenderAPI(fsAPI)
|
||||||
provider := newPublicRoomsProvider(base.LibP2PPubsub, rsAPI)
|
provider := newPublicRoomsProvider(base.LibP2PPubsub, rsAPI)
|
||||||
err = provider.Start()
|
err = provider.Start()
|
||||||
|
|
@ -177,6 +168,12 @@ func main() {
|
||||||
panic("failed to create new public rooms provider: " + err.Error())
|
panic("failed to create new public rooms provider: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
createKeyDB(
|
||||||
|
base, keyRing,
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
|
||||||
monolith := setup.Monolith{
|
monolith := setup.Monolith{
|
||||||
Config: base.Base.Cfg,
|
Config: base.Base.Cfg,
|
||||||
AccountDB: accountDB,
|
AccountDB: accountDB,
|
||||||
|
|
@ -188,7 +185,6 @@ func main() {
|
||||||
EDUInternalAPI: eduInputAPI,
|
EDUInternalAPI: eduInputAPI,
|
||||||
FederationAPI: fsAPI,
|
FederationAPI: fsAPI,
|
||||||
RoomserverAPI: rsAPI,
|
RoomserverAPI: rsAPI,
|
||||||
ServerKeyAPI: serverKeyAPI,
|
|
||||||
UserAPI: userAPI,
|
UserAPI: userAPI,
|
||||||
KeyAPI: keyAPI,
|
KeyAPI: keyAPI,
|
||||||
ExtPublicRoomsProvider: provider,
|
ExtPublicRoomsProvider: provider,
|
||||||
|
|
|
||||||
|
|
@ -152,9 +152,8 @@ func main() {
|
||||||
cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-mediaapi.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.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.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName))
|
||||||
cfg.SigningKeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-signingkeyserver.db", *instanceName))
|
|
||||||
cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-keyserver.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-federationapi.db", *instanceName))
|
cfg.FederationAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationapi.db", *instanceName))
|
||||||
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
|
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
|
||||||
cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName))
|
cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName))
|
||||||
cfg.MSCs.MSCs = []string{"msc2836", "msc2946"}
|
cfg.MSCs.MSCs = []string{"msc2836", "msc2946"}
|
||||||
|
|
@ -171,12 +170,10 @@ func main() {
|
||||||
serverKeyAPI := &signing.YggdrasilKeys{}
|
serverKeyAPI := &signing.YggdrasilKeys{}
|
||||||
keyRing := serverKeyAPI.KeyRing()
|
keyRing := serverKeyAPI.KeyRing()
|
||||||
|
|
||||||
rsComponent := roomserver.NewInternalAPI(
|
rsComponent := roomserver.NewInternalAPI(base)
|
||||||
base, keyRing,
|
|
||||||
)
|
|
||||||
rsAPI := rsComponent
|
rsAPI := rsComponent
|
||||||
fsAPI := federationapi.NewInternalAPI(
|
fsAPI := federationapi.NewInternalAPI(
|
||||||
base, federation, rsAPI, keyRing, true,
|
base, federation, rsAPI, base.Caches, true,
|
||||||
)
|
)
|
||||||
|
|
||||||
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI)
|
keyAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI)
|
||||||
|
|
@ -190,6 +187,7 @@ func main() {
|
||||||
asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
|
asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
|
||||||
|
|
||||||
rsComponent.SetFederationSenderAPI(fsAPI)
|
rsComponent.SetFederationSenderAPI(fsAPI)
|
||||||
|
rsComponent.SetKeyring(keyRing)
|
||||||
|
|
||||||
monolith := setup.Monolith{
|
monolith := setup.Monolith{
|
||||||
Config: base.Cfg,
|
Config: base.Cfg,
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,8 @@ func main() {
|
||||||
cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-mediaapi.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.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.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName))
|
||||||
cfg.SigningKeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-signingkeyserver.db", *instanceName))
|
|
||||||
cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-keyserver.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-federationapi.db", *instanceName))
|
cfg.FederationAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationapi.db", *instanceName))
|
||||||
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
|
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
|
||||||
cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName))
|
cfg.Global.Kafka.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-naffka.db", *instanceName))
|
||||||
cfg.MSCs.MSCs = []string{"msc2836"}
|
cfg.MSCs.MSCs = []string{"msc2836"}
|
||||||
|
|
@ -108,7 +107,7 @@ func main() {
|
||||||
keyAPI.SetUserAPI(userAPI)
|
keyAPI.SetUserAPI(userAPI)
|
||||||
|
|
||||||
rsComponent := roomserver.NewInternalAPI(
|
rsComponent := roomserver.NewInternalAPI(
|
||||||
base, keyRing,
|
base,
|
||||||
)
|
)
|
||||||
rsAPI := rsComponent
|
rsAPI := rsComponent
|
||||||
|
|
||||||
|
|
@ -119,10 +118,11 @@ func main() {
|
||||||
asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
|
asAPI := appservice.NewInternalAPI(base, userAPI, rsAPI)
|
||||||
rsAPI.SetAppserviceAPI(asAPI)
|
rsAPI.SetAppserviceAPI(asAPI)
|
||||||
fsAPI := federationapi.NewInternalAPI(
|
fsAPI := federationapi.NewInternalAPI(
|
||||||
base, federation, rsAPI, keyRing, true,
|
base, federation, rsAPI, base.Caches, true,
|
||||||
)
|
)
|
||||||
|
|
||||||
rsComponent.SetFederationSenderAPI(fsAPI)
|
rsComponent.SetFederationSenderAPI(fsAPI)
|
||||||
|
rsComponent.SetKeyring(keyRing)
|
||||||
|
|
||||||
monolith := setup.Monolith{
|
monolith := setup.Monolith{
|
||||||
Config: base.Cfg,
|
Config: base.Cfg,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import (
|
||||||
basepkg "github.com/matrix-org/dendrite/setup/base"
|
basepkg "github.com/matrix-org/dendrite/setup/base"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/setup/mscs"
|
"github.com/matrix-org/dendrite/setup/mscs"
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver"
|
|
||||||
"github.com/matrix-org/dendrite/userapi"
|
"github.com/matrix-org/dendrite/userapi"
|
||||||
uapi "github.com/matrix-org/dendrite/userapi/api"
|
uapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
@ -64,11 +63,9 @@ func main() {
|
||||||
cfg.ClientAPI.InternalAPI.Connect = httpAPIAddr
|
cfg.ClientAPI.InternalAPI.Connect = httpAPIAddr
|
||||||
cfg.EDUServer.InternalAPI.Connect = httpAPIAddr
|
cfg.EDUServer.InternalAPI.Connect = httpAPIAddr
|
||||||
cfg.FederationAPI.InternalAPI.Connect = httpAPIAddr
|
cfg.FederationAPI.InternalAPI.Connect = httpAPIAddr
|
||||||
cfg.FederationSender.InternalAPI.Connect = httpAPIAddr
|
|
||||||
cfg.KeyServer.InternalAPI.Connect = httpAPIAddr
|
cfg.KeyServer.InternalAPI.Connect = httpAPIAddr
|
||||||
cfg.MediaAPI.InternalAPI.Connect = httpAPIAddr
|
cfg.MediaAPI.InternalAPI.Connect = httpAPIAddr
|
||||||
cfg.RoomServer.InternalAPI.Connect = httpAPIAddr
|
cfg.RoomServer.InternalAPI.Connect = httpAPIAddr
|
||||||
cfg.SigningKeyServer.InternalAPI.Connect = httpAPIAddr
|
|
||||||
cfg.SyncAPI.InternalAPI.Connect = httpAPIAddr
|
cfg.SyncAPI.InternalAPI.Connect = httpAPIAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,18 +75,7 @@ func main() {
|
||||||
accountDB := base.CreateAccountsDB()
|
accountDB := base.CreateAccountsDB()
|
||||||
federation := base.CreateFederationClient()
|
federation := base.CreateFederationClient()
|
||||||
|
|
||||||
skAPI := signingkeyserver.NewInternalAPI(
|
rsImpl := roomserver.NewInternalAPI(base)
|
||||||
&base.Cfg.SigningKeyServer, federation, base.Caches,
|
|
||||||
)
|
|
||||||
if base.UseHTTPAPIs {
|
|
||||||
signingkeyserver.AddInternalRoutes(base.InternalAPIMux, skAPI, base.Caches)
|
|
||||||
skAPI = base.SigningKeyServerHTTPClient()
|
|
||||||
}
|
|
||||||
keyRing := skAPI.KeyRing()
|
|
||||||
|
|
||||||
rsImpl := roomserver.NewInternalAPI(
|
|
||||||
base, keyRing,
|
|
||||||
)
|
|
||||||
// call functions directly on the impl unless running in HTTP mode
|
// call functions directly on the impl unless running in HTTP mode
|
||||||
rsAPI := rsImpl
|
rsAPI := rsImpl
|
||||||
if base.UseHTTPAPIs {
|
if base.UseHTTPAPIs {
|
||||||
|
|
@ -103,12 +89,14 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fsAPI := federationapi.NewInternalAPI(
|
fsAPI := federationapi.NewInternalAPI(
|
||||||
base, federation, rsAPI, keyRing, false,
|
base, federation, rsAPI, base.Caches, false,
|
||||||
)
|
)
|
||||||
if base.UseHTTPAPIs {
|
if base.UseHTTPAPIs {
|
||||||
federationapi.AddInternalRoutes(base.InternalAPIMux, fsAPI)
|
federationapi.AddInternalRoutes(base.InternalAPIMux, fsAPI)
|
||||||
fsAPI = base.FederationSenderHTTPClient()
|
fsAPI = base.FederationAPIHTTPClient()
|
||||||
}
|
}
|
||||||
|
keyRing := fsAPI.KeyRing()
|
||||||
|
|
||||||
// The underlying roomserver implementation needs to be able to call the fedsender.
|
// The underlying roomserver implementation needs to be able to call the fedsender.
|
||||||
// This is different to rsAPI which can be the http client which doesn't need this dependency
|
// This is different to rsAPI which can be the http client which doesn't need this dependency
|
||||||
rsImpl.SetFederationSenderAPI(fsAPI)
|
rsImpl.SetFederationSenderAPI(fsAPI)
|
||||||
|
|
@ -153,7 +141,6 @@ func main() {
|
||||||
EDUInternalAPI: eduInputAPI,
|
EDUInternalAPI: eduInputAPI,
|
||||||
FederationAPI: fsAPI,
|
FederationAPI: fsAPI,
|
||||||
RoomserverAPI: rsAPI,
|
RoomserverAPI: rsAPI,
|
||||||
ServerKeyAPI: skAPI,
|
|
||||||
UserAPI: userAPI,
|
UserAPI: userAPI,
|
||||||
KeyAPI: keyAPI,
|
KeyAPI: keyAPI,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,16 +41,15 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
components := map[string]entrypoint{
|
components := map[string]entrypoint{
|
||||||
"appservice": personalities.Appservice,
|
"appservice": personalities.Appservice,
|
||||||
"clientapi": personalities.ClientAPI,
|
"clientapi": personalities.ClientAPI,
|
||||||
"eduserver": personalities.EDUServer,
|
"eduserver": personalities.EDUServer,
|
||||||
"federationapi": personalities.FederationAPI,
|
"federationapi": personalities.FederationAPI,
|
||||||
"keyserver": personalities.KeyServer,
|
"keyserver": personalities.KeyServer,
|
||||||
"mediaapi": personalities.MediaAPI,
|
"mediaapi": personalities.MediaAPI,
|
||||||
"roomserver": personalities.RoomServer,
|
"roomserver": personalities.RoomServer,
|
||||||
"signingkeyserver": personalities.SigningKeyServer,
|
"syncapi": personalities.SyncAPI,
|
||||||
"syncapi": personalities.SyncAPI,
|
"userapi": personalities.UserAPI,
|
||||||
"userapi": personalities.UserAPI,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start, ok := components[component]
|
start, ok := components[component]
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ func ClientAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
|
||||||
|
|
||||||
asQuery := base.AppserviceHTTPClient()
|
asQuery := base.AppserviceHTTPClient()
|
||||||
rsAPI := base.RoomserverHTTPClient()
|
rsAPI := base.RoomserverHTTPClient()
|
||||||
fsAPI := base.FederationSenderHTTPClient()
|
fsAPI := base.FederationAPIHTTPClient()
|
||||||
eduInputAPI := base.EDUServerClient()
|
eduInputAPI := base.EDUServerClient()
|
||||||
userAPI := base.UserAPIClient()
|
userAPI := base.UserAPIClient()
|
||||||
keyAPI := base.KeyServerHTTPClient()
|
keyAPI := base.KeyServerHTTPClient()
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,8 @@ import (
|
||||||
func FederationAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
|
func FederationAPI(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
|
||||||
userAPI := base.UserAPIClient()
|
userAPI := base.UserAPIClient()
|
||||||
federation := base.CreateFederationClient()
|
federation := base.CreateFederationClient()
|
||||||
serverKeyAPI := base.SigningKeyServerHTTPClient()
|
fsAPI := base.FederationAPIHTTPClient()
|
||||||
keyRing := serverKeyAPI.KeyRing()
|
keyRing := fsAPI.KeyRing()
|
||||||
fsAPI := base.FederationSenderHTTPClient()
|
|
||||||
rsAPI := base.RoomserverHTTPClient()
|
rsAPI := base.RoomserverHTTPClient()
|
||||||
keyAPI := base.KeyServerHTTPClient()
|
keyAPI := base.KeyServerHTTPClient()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func KeyServer(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
|
func KeyServer(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
|
||||||
fsAPI := base.FederationSenderHTTPClient()
|
fsAPI := base.FederationAPIHTTPClient()
|
||||||
intAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI)
|
intAPI := keyserver.NewInternalAPI(base, &base.Cfg.KeyServer, fsAPI)
|
||||||
intAPI.SetUserAPI(base.UserAPIClient())
|
intAPI.SetUserAPI(base.UserAPIClient())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func RoomServer(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
|
func RoomServer(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
|
||||||
serverKeyAPI := base.SigningKeyServerHTTPClient()
|
|
||||||
keyRing := serverKeyAPI.KeyRing()
|
|
||||||
|
|
||||||
asAPI := base.AppserviceHTTPClient()
|
asAPI := base.AppserviceHTTPClient()
|
||||||
fsAPI := base.FederationSenderHTTPClient()
|
fsAPI := base.FederationAPIHTTPClient()
|
||||||
rsAPI := roomserver.NewInternalAPI(base, keyRing)
|
rsAPI := roomserver.NewInternalAPI(base)
|
||||||
rsAPI.SetFederationSenderAPI(fsAPI)
|
rsAPI.SetFederationSenderAPI(fsAPI)
|
||||||
rsAPI.SetAppserviceAPI(asAPI)
|
rsAPI.SetAppserviceAPI(asAPI)
|
||||||
roomserver.AddInternalRoutes(base.InternalAPIMux, rsAPI)
|
roomserver.AddInternalRoutes(base.InternalAPIMux, rsAPI)
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package personalities
|
|
||||||
|
|
||||||
import (
|
|
||||||
basepkg "github.com/matrix-org/dendrite/setup/base"
|
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SigningKeyServer(base *basepkg.BaseDendrite, cfg *config.Dendrite) {
|
|
||||||
federation := base.CreateFederationClient()
|
|
||||||
|
|
||||||
intAPI := signingkeyserver.NewInternalAPI(&base.Cfg.SigningKeyServer, federation, base.Caches)
|
|
||||||
signingkeyserver.AddInternalRoutes(base.InternalAPIMux, intAPI, base.Caches)
|
|
||||||
|
|
||||||
base.SetupAndServeHTTP(
|
|
||||||
base.Cfg.SigningKeyServer.InternalAPI.Listen,
|
|
||||||
basepkg.NoListener,
|
|
||||||
nil, nil,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -24,12 +24,11 @@ func main() {
|
||||||
if *dbURI != "" {
|
if *dbURI != "" {
|
||||||
cfg.Global.Kafka.Database.ConnectionString = config.DataSource(*dbURI)
|
cfg.Global.Kafka.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
cfg.FederationSender.Database.ConnectionString = config.DataSource(*dbURI)
|
cfg.FederationAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
cfg.KeyServer.Database.ConnectionString = config.DataSource(*dbURI)
|
cfg.KeyServer.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
cfg.MSCs.Database.ConnectionString = config.DataSource(*dbURI)
|
cfg.MSCs.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
cfg.MediaAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
cfg.MediaAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
cfg.RoomServer.Database.ConnectionString = config.DataSource(*dbURI)
|
cfg.RoomServer.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
cfg.SigningKeyServer.Database.ConnectionString = config.DataSource(*dbURI)
|
|
||||||
cfg.SyncAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
cfg.SyncAPI.Database.ConnectionString = config.DataSource(*dbURI)
|
||||||
cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(*dbURI)
|
cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(*dbURI)
|
||||||
cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(*dbURI)
|
cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(*dbURI)
|
||||||
|
|
@ -47,7 +46,7 @@ func main() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cfg.SigningKeyServer.KeyPerspectives = config.KeyPerspectives{
|
cfg.FederationAPI.KeyPerspectives = config.KeyPerspectives{
|
||||||
{
|
{
|
||||||
ServerName: "matrix.org",
|
ServerName: "matrix.org",
|
||||||
Keys: []config.KeyPerspectiveTrustKey{
|
Keys: []config.KeyPerspectiveTrustKey{
|
||||||
|
|
@ -83,11 +82,11 @@ func main() {
|
||||||
if *defaultsForCI {
|
if *defaultsForCI {
|
||||||
cfg.AppServiceAPI.DisableTLSValidation = true
|
cfg.AppServiceAPI.DisableTLSValidation = true
|
||||||
cfg.ClientAPI.RateLimiting.Enabled = false
|
cfg.ClientAPI.RateLimiting.Enabled = false
|
||||||
cfg.FederationSender.DisableTLSValidation = true
|
cfg.FederationAPI.DisableTLSValidation = true
|
||||||
|
// don't hit matrix.org when running tests!!!
|
||||||
|
cfg.FederationAPI.KeyPerspectives = config.KeyPerspectives{}
|
||||||
cfg.MSCs.MSCs = []string{"msc2836", "msc2946", "msc2444", "msc2753"}
|
cfg.MSCs.MSCs = []string{"msc2836", "msc2946", "msc2444", "msc2753"}
|
||||||
cfg.Logging[0].Level = "trace"
|
cfg.Logging[0].Level = "trace"
|
||||||
// don't hit matrix.org when running tests!!!
|
|
||||||
cfg.SigningKeyServer.KeyPerspectives = config.KeyPerspectives{}
|
|
||||||
cfg.UserAPI.BCryptCost = bcrypt.MinCost
|
cfg.UserAPI.BCryptCost = bcrypt.MinCost
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,10 @@ func (e *FederationClientError) Error() string {
|
||||||
// FederationInternalAPI is used to query information from the federation sender.
|
// FederationInternalAPI is used to query information from the federation sender.
|
||||||
type FederationInternalAPI interface {
|
type FederationInternalAPI interface {
|
||||||
FederationClient
|
FederationClient
|
||||||
|
gomatrixserverlib.KeyDatabase
|
||||||
|
gomatrixserverlib.KeyFetcher
|
||||||
|
|
||||||
|
KeyRing() *gomatrixserverlib.KeyRing
|
||||||
|
|
||||||
QueryServerKeys(ctx context.Context, request *QueryServerKeysRequest, response *QueryServerKeysResponse) error
|
QueryServerKeys(ctx context.Context, request *QueryServerKeysRequest, response *QueryServerKeysResponse) error
|
||||||
|
|
||||||
|
|
@ -114,6 +118,14 @@ type QueryServerKeysResponse struct {
|
||||||
ServerKeys []gomatrixserverlib.ServerKeys
|
ServerKeys []gomatrixserverlib.ServerKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type QueryPublicKeysRequest struct {
|
||||||
|
Requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp `json:"requests"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryPublicKeysResponse struct {
|
||||||
|
Results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"results"`
|
||||||
|
}
|
||||||
|
|
||||||
type PerformDirectoryLookupRequest struct {
|
type PerformDirectoryLookupRequest struct {
|
||||||
RoomAlias string `json:"room_alias"`
|
RoomAlias string `json:"room_alias"`
|
||||||
ServerName gomatrixserverlib.ServerName `json:"server_name"`
|
ServerName gomatrixserverlib.ServerName `json:"server_name"`
|
||||||
|
|
@ -188,3 +200,10 @@ type PerformBroadcastEDURequest struct {
|
||||||
|
|
||||||
type PerformBroadcastEDUResponse struct {
|
type PerformBroadcastEDUResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InputPublicKeysRequest struct {
|
||||||
|
Keys map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"keys"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InputPublicKeysResponse struct {
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ type OutputEDUConsumer struct {
|
||||||
// NewOutputEDUConsumer creates a new OutputEDUConsumer. Call Start() to begin consuming from EDU servers.
|
// NewOutputEDUConsumer creates a new OutputEDUConsumer. Call Start() to begin consuming from EDU servers.
|
||||||
func NewOutputEDUConsumer(
|
func NewOutputEDUConsumer(
|
||||||
process *process.ProcessContext,
|
process *process.ProcessContext,
|
||||||
cfg *config.FederationSender,
|
cfg *config.FederationAPI,
|
||||||
kafkaConsumer sarama.Consumer,
|
kafkaConsumer sarama.Consumer,
|
||||||
queues *queue.OutgoingQueues,
|
queues *queue.OutgoingQueues,
|
||||||
store storage.Database,
|
store storage.Database,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import (
|
||||||
|
|
||||||
// OutputRoomEventConsumer consumes events that originated in the room server.
|
// OutputRoomEventConsumer consumes events that originated in the room server.
|
||||||
type OutputRoomEventConsumer struct {
|
type OutputRoomEventConsumer struct {
|
||||||
cfg *config.FederationSender
|
cfg *config.FederationAPI
|
||||||
rsAPI api.RoomserverInternalAPI
|
rsAPI api.RoomserverInternalAPI
|
||||||
rsConsumer *internal.ContinualConsumer
|
rsConsumer *internal.ContinualConsumer
|
||||||
db storage.Database
|
db storage.Database
|
||||||
|
|
@ -43,7 +43,7 @@ type OutputRoomEventConsumer struct {
|
||||||
// NewOutputRoomEventConsumer creates a new OutputRoomEventConsumer. Call Start() to begin consuming from room servers.
|
// NewOutputRoomEventConsumer creates a new OutputRoomEventConsumer. Call Start() to begin consuming from room servers.
|
||||||
func NewOutputRoomEventConsumer(
|
func NewOutputRoomEventConsumer(
|
||||||
process *process.ProcessContext,
|
process *process.ProcessContext,
|
||||||
cfg *config.FederationSender,
|
cfg *config.FederationAPI,
|
||||||
kafkaConsumer sarama.Consumer,
|
kafkaConsumer sarama.Consumer,
|
||||||
queues *queue.OutgoingQueues,
|
queues *queue.OutgoingQueues,
|
||||||
store storage.Database,
|
store storage.Database,
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/federationapi/queue"
|
"github.com/matrix-org/dendrite/federationapi/queue"
|
||||||
"github.com/matrix-org/dendrite/federationapi/statistics"
|
"github.com/matrix-org/dendrite/federationapi/statistics"
|
||||||
"github.com/matrix-org/dendrite/federationapi/storage"
|
"github.com/matrix-org/dendrite/federationapi/storage"
|
||||||
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
keyserverAPI "github.com/matrix-org/dendrite/keyserver/api"
|
keyserverAPI "github.com/matrix-org/dendrite/keyserver/api"
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/setup/base"
|
"github.com/matrix-org/dendrite/setup/base"
|
||||||
|
|
@ -71,29 +72,29 @@ func NewInternalAPI(
|
||||||
base *base.BaseDendrite,
|
base *base.BaseDendrite,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
rsAPI roomserverAPI.RoomserverInternalAPI,
|
rsAPI roomserverAPI.RoomserverInternalAPI,
|
||||||
keyRing *gomatrixserverlib.KeyRing,
|
caches *caching.Caches,
|
||||||
resetBlacklist bool,
|
resetBlacklist bool,
|
||||||
) api.FederationInternalAPI {
|
) api.FederationInternalAPI {
|
||||||
cfg := &base.Cfg.FederationSender
|
cfg := &base.Cfg.FederationAPI
|
||||||
|
|
||||||
federationSenderDB, err := storage.NewDatabase(&cfg.Database, base.Caches)
|
federationDB, err := storage.NewDatabase(&cfg.Database, base.Caches)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Panic("failed to connect to federation sender db")
|
logrus.WithError(err).Panic("failed to connect to federation sender db")
|
||||||
}
|
}
|
||||||
|
|
||||||
if resetBlacklist {
|
if resetBlacklist {
|
||||||
_ = federationSenderDB.RemoveAllServersFromBlacklist()
|
_ = federationDB.RemoveAllServersFromBlacklist()
|
||||||
}
|
}
|
||||||
|
|
||||||
stats := &statistics.Statistics{
|
stats := &statistics.Statistics{
|
||||||
DB: federationSenderDB,
|
DB: federationDB,
|
||||||
FailuresUntilBlacklist: cfg.FederationMaxRetries,
|
FailuresUntilBlacklist: cfg.FederationMaxRetries,
|
||||||
}
|
}
|
||||||
|
|
||||||
consumer, _ := kafka.SetupConsumerProducer(&cfg.Matrix.Kafka)
|
consumer, _ := kafka.SetupConsumerProducer(&cfg.Matrix.Kafka)
|
||||||
|
|
||||||
queues := queue.NewOutgoingQueues(
|
queues := queue.NewOutgoingQueues(
|
||||||
federationSenderDB, base.ProcessContext,
|
federationDB, base.ProcessContext,
|
||||||
cfg.Matrix.DisableFederation,
|
cfg.Matrix.DisableFederation,
|
||||||
cfg.Matrix.ServerName, federation, rsAPI, stats,
|
cfg.Matrix.ServerName, federation, rsAPI, stats,
|
||||||
&queue.SigningInfo{
|
&queue.SigningInfo{
|
||||||
|
|
@ -105,24 +106,24 @@ func NewInternalAPI(
|
||||||
|
|
||||||
rsConsumer := consumers.NewOutputRoomEventConsumer(
|
rsConsumer := consumers.NewOutputRoomEventConsumer(
|
||||||
base.ProcessContext, cfg, consumer, queues,
|
base.ProcessContext, cfg, consumer, queues,
|
||||||
federationSenderDB, rsAPI,
|
federationDB, rsAPI,
|
||||||
)
|
)
|
||||||
if err = rsConsumer.Start(); err != nil {
|
if err = rsConsumer.Start(); err != nil {
|
||||||
logrus.WithError(err).Panic("failed to start room server consumer")
|
logrus.WithError(err).Panic("failed to start room server consumer")
|
||||||
}
|
}
|
||||||
|
|
||||||
tsConsumer := consumers.NewOutputEDUConsumer(
|
tsConsumer := consumers.NewOutputEDUConsumer(
|
||||||
base.ProcessContext, cfg, consumer, queues, federationSenderDB,
|
base.ProcessContext, cfg, consumer, queues, federationDB,
|
||||||
)
|
)
|
||||||
if err := tsConsumer.Start(); err != nil {
|
if err := tsConsumer.Start(); err != nil {
|
||||||
logrus.WithError(err).Panic("failed to start typing server consumer")
|
logrus.WithError(err).Panic("failed to start typing server consumer")
|
||||||
}
|
}
|
||||||
keyConsumer := consumers.NewKeyChangeConsumer(
|
keyConsumer := consumers.NewKeyChangeConsumer(
|
||||||
base.ProcessContext, &base.Cfg.KeyServer, consumer, queues, federationSenderDB, rsAPI,
|
base.ProcessContext, &base.Cfg.KeyServer, consumer, queues, federationDB, rsAPI,
|
||||||
)
|
)
|
||||||
if err := keyConsumer.Start(); err != nil {
|
if err := keyConsumer.Start(); err != nil {
|
||||||
logrus.WithError(err).Panic("failed to start key server consumer")
|
logrus.WithError(err).Panic("failed to start key server consumer")
|
||||||
}
|
}
|
||||||
|
|
||||||
return internal.NewFederationInternalAPI(federationSenderDB, cfg, rsAPI, federation, keyRing, stats, queues)
|
return internal.NewFederationInternalAPI(federationDB, cfg, rsAPI, federation, stats, caches, queues)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ func TestRoomsV3URLEscapeDoNot404(t *testing.T) {
|
||||||
cfg.Global.PrivateKey = privKey
|
cfg.Global.PrivateKey = privKey
|
||||||
cfg.Global.Kafka.UseNaffka = true
|
cfg.Global.Kafka.UseNaffka = true
|
||||||
cfg.Global.Kafka.Database.ConnectionString = config.DataSource("file::memory:")
|
cfg.Global.Kafka.Database.ConnectionString = config.DataSource("file::memory:")
|
||||||
cfg.FederationSender.Database.ConnectionString = config.DataSource("file::memory:")
|
cfg.FederationAPI.Database.ConnectionString = config.DataSource("file::memory:")
|
||||||
base := base.NewBaseDendrite(cfg, "Monolith", false)
|
base := base.NewBaseDendrite(cfg, "Monolith", false)
|
||||||
keyRing := &test.NopJSONVerifier{}
|
keyRing := &test.NopJSONVerifier{}
|
||||||
fsAPI := base.FederationSenderHTTPClient()
|
fsAPI := base.FederationAPIHTTPClient()
|
||||||
// TODO: This is pretty fragile, as if anything calls anything on these nils this test will break.
|
// 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.
|
// Unfortunately, it makes little sense to instantiate these dependencies when we just want to test routing.
|
||||||
federationapi.AddPublicRoutes(base.PublicFederationAPIMux, base.PublicKeyAPIMux, base.PublicWellKnownAPIMux, &cfg.FederationAPI, nil, nil, keyRing, nil, fsAPI, nil, nil, &cfg.MSCs, nil)
|
federationapi.AddPublicRoutes(base.PublicFederationAPIMux, base.PublicKeyAPIMux, base.PublicWellKnownAPIMux, &cfg.FederationAPI, nil, nil, keyRing, nil, fsAPI, nil, nil, &cfg.MSCs, nil)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"encoding/base64"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -9,16 +11,19 @@ import (
|
||||||
"github.com/matrix-org/dendrite/federationapi/queue"
|
"github.com/matrix-org/dendrite/federationapi/queue"
|
||||||
"github.com/matrix-org/dendrite/federationapi/statistics"
|
"github.com/matrix-org/dendrite/federationapi/statistics"
|
||||||
"github.com/matrix-org/dendrite/federationapi/storage"
|
"github.com/matrix-org/dendrite/federationapi/storage"
|
||||||
|
"github.com/matrix-org/dendrite/federationapi/storage/cache"
|
||||||
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/gomatrix"
|
"github.com/matrix-org/gomatrix"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FederationInternalAPI is an implementation of api.FederationInternalAPI
|
// FederationInternalAPI is an implementation of api.FederationInternalAPI
|
||||||
type FederationInternalAPI struct {
|
type FederationInternalAPI struct {
|
||||||
db storage.Database
|
db storage.Database
|
||||||
cfg *config.FederationSender
|
cfg *config.FederationAPI
|
||||||
statistics *statistics.Statistics
|
statistics *statistics.Statistics
|
||||||
rsAPI roomserverAPI.RoomserverInternalAPI
|
rsAPI roomserverAPI.RoomserverInternalAPI
|
||||||
federation *gomatrixserverlib.FederationClient
|
federation *gomatrixserverlib.FederationClient
|
||||||
|
|
@ -28,19 +33,72 @@ type FederationInternalAPI struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFederationInternalAPI(
|
func NewFederationInternalAPI(
|
||||||
db storage.Database, cfg *config.FederationSender,
|
db storage.Database, cfg *config.FederationAPI,
|
||||||
rsAPI roomserverAPI.RoomserverInternalAPI,
|
rsAPI roomserverAPI.RoomserverInternalAPI,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
keyRing *gomatrixserverlib.KeyRing,
|
|
||||||
statistics *statistics.Statistics,
|
statistics *statistics.Statistics,
|
||||||
|
caches *caching.Caches,
|
||||||
queues *queue.OutgoingQueues,
|
queues *queue.OutgoingQueues,
|
||||||
) *FederationInternalAPI {
|
) *FederationInternalAPI {
|
||||||
|
serverKeyDB, err := cache.NewKeyDatabase(db, caches)
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).Panicf("failed to set up caching wrapper for server key database")
|
||||||
|
}
|
||||||
|
|
||||||
|
keyRing := &gomatrixserverlib.KeyRing{
|
||||||
|
KeyFetchers: []gomatrixserverlib.KeyFetcher{},
|
||||||
|
KeyDatabase: serverKeyDB,
|
||||||
|
}
|
||||||
|
|
||||||
|
addDirectFetcher := func() {
|
||||||
|
keyRing.KeyFetchers = append(
|
||||||
|
keyRing.KeyFetchers,
|
||||||
|
&gomatrixserverlib.DirectKeyFetcher{
|
||||||
|
Client: federation,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.PreferDirectFetch {
|
||||||
|
addDirectFetcher()
|
||||||
|
} else {
|
||||||
|
defer addDirectFetcher()
|
||||||
|
}
|
||||||
|
|
||||||
|
var b64e = base64.StdEncoding.WithPadding(base64.NoPadding)
|
||||||
|
for _, ps := range cfg.KeyPerspectives {
|
||||||
|
perspective := &gomatrixserverlib.PerspectiveKeyFetcher{
|
||||||
|
PerspectiveServerName: ps.ServerName,
|
||||||
|
PerspectiveServerKeys: map[gomatrixserverlib.KeyID]ed25519.PublicKey{},
|
||||||
|
Client: federation,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, key := range ps.Keys {
|
||||||
|
rawkey, err := b64e.DecodeString(key.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).WithFields(logrus.Fields{
|
||||||
|
"server_name": ps.ServerName,
|
||||||
|
"public_key": key.PublicKey,
|
||||||
|
}).Warn("Couldn't parse perspective key")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
perspective.PerspectiveServerKeys[key.KeyID] = rawkey
|
||||||
|
}
|
||||||
|
|
||||||
|
keyRing.KeyFetchers = append(keyRing.KeyFetchers, perspective)
|
||||||
|
|
||||||
|
logrus.WithFields(logrus.Fields{
|
||||||
|
"server_name": ps.ServerName,
|
||||||
|
"num_public_keys": len(ps.Keys),
|
||||||
|
}).Info("Enabled perspective key fetcher")
|
||||||
|
}
|
||||||
|
|
||||||
return &FederationInternalAPI{
|
return &FederationInternalAPI{
|
||||||
db: db,
|
db: db,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
rsAPI: rsAPI,
|
rsAPI: rsAPI,
|
||||||
federation: federation,
|
|
||||||
keyRing: keyRing,
|
keyRing: keyRing,
|
||||||
|
federation: federation,
|
||||||
statistics: statistics,
|
statistics: statistics,
|
||||||
queues: queues,
|
queues: queues,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,26 +6,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/api"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerKeyAPI struct {
|
func (s *FederationInternalAPI) KeyRing() *gomatrixserverlib.KeyRing {
|
||||||
api.SigningKeyServerAPI
|
|
||||||
|
|
||||||
ServerName gomatrixserverlib.ServerName
|
|
||||||
ServerPublicKey ed25519.PublicKey
|
|
||||||
ServerKeyID gomatrixserverlib.KeyID
|
|
||||||
ServerKeyValidity time.Duration
|
|
||||||
OldServerKeys []config.OldVerifyKeys
|
|
||||||
|
|
||||||
OurKeyRing gomatrixserverlib.KeyRing
|
|
||||||
FedClient gomatrixserverlib.KeyClient
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ServerKeyAPI) KeyRing() *gomatrixserverlib.KeyRing {
|
|
||||||
// Return a keyring that forces requests to be proxied through the
|
// Return a keyring that forces requests to be proxied through the
|
||||||
// below functions. That way we can enforce things like validity
|
// below functions. That way we can enforce things like validity
|
||||||
// and keeping the cache up-to-date.
|
// and keeping the cache up-to-date.
|
||||||
|
|
@ -35,7 +20,7 @@ func (s *ServerKeyAPI) KeyRing() *gomatrixserverlib.KeyRing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServerKeyAPI) StoreKeys(
|
func (s *FederationInternalAPI) StoreKeys(
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
||||||
) error {
|
) error {
|
||||||
|
|
@ -44,10 +29,10 @@ func (s *ServerKeyAPI) StoreKeys(
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
// Store any keys that we were given in our database.
|
// Store any keys that we were given in our database.
|
||||||
return s.OurKeyRing.KeyDatabase.StoreKeys(ctx, results)
|
return s.keyRing.KeyDatabase.StoreKeys(ctx, results)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServerKeyAPI) FetchKeys(
|
func (s *FederationInternalAPI) FetchKeys(
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
||||||
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
|
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
|
||||||
|
|
@ -75,7 +60,7 @@ func (s *ServerKeyAPI) FetchKeys(
|
||||||
// For any key requests that we still have outstanding, next try to
|
// For any key requests that we still have outstanding, next try to
|
||||||
// fetch them directly. We'll go through each of the key fetchers to
|
// fetch them directly. We'll go through each of the key fetchers to
|
||||||
// ask for the remaining keys
|
// ask for the remaining keys
|
||||||
for _, fetcher := range s.OurKeyRing.KeyFetchers {
|
for _, fetcher := range s.keyRing.KeyFetchers {
|
||||||
// If there are no more keys to look up then stop.
|
// If there are no more keys to look up then stop.
|
||||||
if len(requests) == 0 {
|
if len(requests) == 0 {
|
||||||
break
|
break
|
||||||
|
|
@ -105,22 +90,22 @@ func (s *ServerKeyAPI) FetchKeys(
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServerKeyAPI) FetcherName() string {
|
func (s *FederationInternalAPI) FetcherName() string {
|
||||||
return fmt.Sprintf("ServerKeyAPI (wrapping %q)", s.OurKeyRing.KeyDatabase.FetcherName())
|
return fmt.Sprintf("FederationInternalAPI (wrapping %q)", s.keyRing.KeyDatabase.FetcherName())
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleLocalKeys handles cases where the key request contains
|
// handleLocalKeys handles cases where the key request contains
|
||||||
// a request for our own server keys, either current or old.
|
// a request for our own server keys, either current or old.
|
||||||
func (s *ServerKeyAPI) handleLocalKeys(
|
func (s *FederationInternalAPI) handleLocalKeys(
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
||||||
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
||||||
) {
|
) {
|
||||||
for req := range requests {
|
for req := range requests {
|
||||||
if req.ServerName != s.ServerName {
|
if req.ServerName != s.cfg.Matrix.ServerName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if req.KeyID == s.ServerKeyID {
|
if req.KeyID == s.cfg.Matrix.KeyID {
|
||||||
// We found a key request that is supposed to be for our own
|
// We found a key request that is supposed to be for our own
|
||||||
// keys. Remove it from the request list so we don't hit the
|
// keys. Remove it from the request list so we don't hit the
|
||||||
// database or the fetchers for it.
|
// database or the fetchers for it.
|
||||||
|
|
@ -129,15 +114,15 @@ func (s *ServerKeyAPI) handleLocalKeys(
|
||||||
// Insert our own key into the response.
|
// Insert our own key into the response.
|
||||||
results[req] = gomatrixserverlib.PublicKeyLookupResult{
|
results[req] = gomatrixserverlib.PublicKeyLookupResult{
|
||||||
VerifyKey: gomatrixserverlib.VerifyKey{
|
VerifyKey: gomatrixserverlib.VerifyKey{
|
||||||
Key: gomatrixserverlib.Base64Bytes(s.ServerPublicKey),
|
Key: gomatrixserverlib.Base64Bytes(s.cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey)),
|
||||||
},
|
},
|
||||||
ExpiredTS: gomatrixserverlib.PublicKeyNotExpired,
|
ExpiredTS: gomatrixserverlib.PublicKeyNotExpired,
|
||||||
ValidUntilTS: gomatrixserverlib.AsTimestamp(time.Now().Add(s.ServerKeyValidity)),
|
ValidUntilTS: gomatrixserverlib.AsTimestamp(time.Now().Add(s.cfg.Matrix.KeyValidityPeriod)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The key request doesn't match our current key. Let's see
|
// The key request doesn't match our current key. Let's see
|
||||||
// if it matches any of our old verify keys.
|
// if it matches any of our old verify keys.
|
||||||
for _, oldVerifyKey := range s.OldServerKeys {
|
for _, oldVerifyKey := range s.cfg.Matrix.OldVerifyKeys {
|
||||||
if req.KeyID == oldVerifyKey.KeyID {
|
if req.KeyID == oldVerifyKey.KeyID {
|
||||||
// We found a key request that is supposed to be an expired
|
// We found a key request that is supposed to be an expired
|
||||||
// key.
|
// key.
|
||||||
|
|
@ -162,14 +147,14 @@ func (s *ServerKeyAPI) handleLocalKeys(
|
||||||
|
|
||||||
// handleDatabaseKeys handles cases where the key requests can be
|
// handleDatabaseKeys handles cases where the key requests can be
|
||||||
// satisfied from our local database/cache.
|
// satisfied from our local database/cache.
|
||||||
func (s *ServerKeyAPI) handleDatabaseKeys(
|
func (s *FederationInternalAPI) handleDatabaseKeys(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
now gomatrixserverlib.Timestamp,
|
now gomatrixserverlib.Timestamp,
|
||||||
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
||||||
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
||||||
) error {
|
) error {
|
||||||
// Ask the database/cache for the keys.
|
// Ask the database/cache for the keys.
|
||||||
dbResults, err := s.OurKeyRing.KeyDatabase.FetchKeys(ctx, requests)
|
dbResults, err := s.keyRing.KeyDatabase.FetchKeys(ctx, requests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +181,7 @@ func (s *ServerKeyAPI) handleDatabaseKeys(
|
||||||
|
|
||||||
// handleFetcherKeys handles cases where a fetcher can satisfy
|
// handleFetcherKeys handles cases where a fetcher can satisfy
|
||||||
// the remaining requests.
|
// the remaining requests.
|
||||||
func (s *ServerKeyAPI) handleFetcherKeys(
|
func (s *FederationInternalAPI) handleFetcherKeys(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
_ gomatrixserverlib.Timestamp,
|
_ gomatrixserverlib.Timestamp,
|
||||||
fetcher gomatrixserverlib.KeyFetcher,
|
fetcher gomatrixserverlib.KeyFetcher,
|
||||||
|
|
@ -248,10 +233,10 @@ func (s *ServerKeyAPI) handleFetcherKeys(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the keys from our store map.
|
// Store the keys from our store map.
|
||||||
if err = s.OurKeyRing.KeyDatabase.StoreKeys(context.Background(), storeResults); err != nil {
|
if err = s.keyRing.KeyDatabase.StoreKeys(context.Background(), storeResults); err != nil {
|
||||||
logrus.WithError(err).WithFields(logrus.Fields{
|
logrus.WithError(err).WithFields(logrus.Fields{
|
||||||
"fetcher_name": fetcher.FetcherName(),
|
"fetcher_name": fetcher.FetcherName(),
|
||||||
"database_name": s.OurKeyRing.KeyDatabase.FetcherName(),
|
"database_name": s.keyRing.KeyDatabase.FetcherName(),
|
||||||
}).Errorf("Failed to store keys in the database")
|
}).Errorf("Failed to store keys in the database")
|
||||||
return fmt.Errorf("server key API failed to store retrieved keys: %w", err)
|
return fmt.Errorf("server key API failed to store retrieved keys: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/federationapi/api"
|
"github.com/matrix-org/dendrite/federationapi/api"
|
||||||
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/internal/httputil"
|
"github.com/matrix-org/dendrite/internal/httputil"
|
||||||
"github.com/matrix-org/gomatrix"
|
"github.com/matrix-org/gomatrix"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
|
@ -14,41 +15,45 @@ import (
|
||||||
|
|
||||||
// HTTP paths for the internal HTTP API
|
// HTTP paths for the internal HTTP API
|
||||||
const (
|
const (
|
||||||
FederationSenderQueryJoinedHostServerNamesInRoomPath = "/federationapi/queryJoinedHostServerNamesInRoom"
|
FederationAPIQueryJoinedHostServerNamesInRoomPath = "/federationapi/queryJoinedHostServerNamesInRoom"
|
||||||
FederationSenderQueryServerKeysPath = "/federationapi/queryServerKeys"
|
FederationAPIQueryServerKeysPath = "/federationapi/queryServerKeys"
|
||||||
|
|
||||||
FederationSenderPerformDirectoryLookupRequestPath = "/federationapi/performDirectoryLookup"
|
FederationAPIPerformDirectoryLookupRequestPath = "/federationapi/performDirectoryLookup"
|
||||||
FederationSenderPerformJoinRequestPath = "/federationapi/performJoinRequest"
|
FederationAPIPerformJoinRequestPath = "/federationapi/performJoinRequest"
|
||||||
FederationSenderPerformLeaveRequestPath = "/federationapi/performLeaveRequest"
|
FederationAPIPerformLeaveRequestPath = "/federationapi/performLeaveRequest"
|
||||||
FederationSenderPerformInviteRequestPath = "/federationapi/performInviteRequest"
|
FederationAPIPerformInviteRequestPath = "/federationapi/performInviteRequest"
|
||||||
FederationSenderPerformOutboundPeekRequestPath = "/federationapi/performOutboundPeekRequest"
|
FederationAPIPerformOutboundPeekRequestPath = "/federationapi/performOutboundPeekRequest"
|
||||||
FederationSenderPerformServersAlivePath = "/federationapi/performServersAlive"
|
FederationAPIPerformServersAlivePath = "/federationapi/performServersAlive"
|
||||||
FederationSenderPerformBroadcastEDUPath = "/federationapi/performBroadcastEDU"
|
FederationAPIPerformBroadcastEDUPath = "/federationapi/performBroadcastEDU"
|
||||||
|
|
||||||
FederationSenderGetUserDevicesPath = "/federationapi/client/getUserDevices"
|
FederationAPIGetUserDevicesPath = "/federationapi/client/getUserDevices"
|
||||||
FederationSenderClaimKeysPath = "/federationapi/client/claimKeys"
|
FederationAPIClaimKeysPath = "/federationapi/client/claimKeys"
|
||||||
FederationSenderQueryKeysPath = "/federationapi/client/queryKeys"
|
FederationAPIQueryKeysPath = "/federationapi/client/queryKeys"
|
||||||
FederationSenderBackfillPath = "/federationapi/client/backfill"
|
FederationAPIBackfillPath = "/federationapi/client/backfill"
|
||||||
FederationSenderLookupStatePath = "/federationapi/client/lookupState"
|
FederationAPILookupStatePath = "/federationapi/client/lookupState"
|
||||||
FederationSenderLookupStateIDsPath = "/federationapi/client/lookupStateIDs"
|
FederationAPILookupStateIDsPath = "/federationapi/client/lookupStateIDs"
|
||||||
FederationSenderGetEventPath = "/federationapi/client/getEvent"
|
FederationAPIGetEventPath = "/federationapi/client/getEvent"
|
||||||
FederationSenderLookupServerKeysPath = "/federationapi/client/lookupServerKeys"
|
FederationAPILookupServerKeysPath = "/federationapi/client/lookupServerKeys"
|
||||||
FederationSenderEventRelationshipsPath = "/federationapi/client/msc2836eventRelationships"
|
FederationAPIEventRelationshipsPath = "/federationapi/client/msc2836eventRelationships"
|
||||||
FederationSenderSpacesSummaryPath = "/federationapi/client/msc2946spacesSummary"
|
FederationAPISpacesSummaryPath = "/federationapi/client/msc2946spacesSummary"
|
||||||
|
|
||||||
|
FederationAPIInputPublicKeyPath = "/federationapi/inputPublicKey"
|
||||||
|
FederationAPIQueryPublicKeyPath = "/federationapi/queryPublicKey"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewFederationSenderClient creates a FederationInternalAPI implemented by talking to a HTTP POST API.
|
// NewFederationAPIClient creates a FederationInternalAPI implemented by talking to a HTTP POST API.
|
||||||
// If httpClient is nil an error is returned
|
// If httpClient is nil an error is returned
|
||||||
func NewFederationSenderClient(federationSenderURL string, httpClient *http.Client) (api.FederationInternalAPI, error) {
|
func NewFederationAPIClient(federationSenderURL string, httpClient *http.Client, cache caching.ServerKeyCache) (api.FederationInternalAPI, error) {
|
||||||
if httpClient == nil {
|
if httpClient == nil {
|
||||||
return nil, errors.New("NewFederationInternalAPIHTTP: httpClient is <nil>")
|
return nil, errors.New("NewFederationInternalAPIHTTP: httpClient is <nil>")
|
||||||
}
|
}
|
||||||
return &httpFederationInternalAPI{federationSenderURL, httpClient}, nil
|
return &httpFederationInternalAPI{federationSenderURL, httpClient, cache}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type httpFederationInternalAPI struct {
|
type httpFederationInternalAPI struct {
|
||||||
federationSenderURL string
|
federationAPIURL string
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
|
cache caching.ServerKeyCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle an instruction to make_leave & send_leave with a remote server.
|
// Handle an instruction to make_leave & send_leave with a remote server.
|
||||||
|
|
@ -60,7 +65,7 @@ func (h *httpFederationInternalAPI) PerformLeave(
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformLeaveRequest")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformLeaveRequest")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.federationSenderURL + FederationSenderPerformLeaveRequestPath
|
apiURL := h.federationAPIURL + FederationAPIPerformLeaveRequestPath
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,7 +78,7 @@ func (h *httpFederationInternalAPI) PerformInvite(
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformInviteRequest")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformInviteRequest")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.federationSenderURL + FederationSenderPerformInviteRequestPath
|
apiURL := h.federationAPIURL + FederationAPIPerformInviteRequestPath
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +91,7 @@ func (h *httpFederationInternalAPI) PerformOutboundPeek(
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformOutboundPeekRequest")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformOutboundPeekRequest")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.federationSenderURL + FederationSenderPerformOutboundPeekRequestPath
|
apiURL := h.federationAPIURL + FederationAPIPerformOutboundPeekRequestPath
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,7 +103,7 @@ func (h *httpFederationInternalAPI) PerformServersAlive(
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformServersAlive")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformServersAlive")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.federationSenderURL + FederationSenderPerformServersAlivePath
|
apiURL := h.federationAPIURL + FederationAPIPerformServersAlivePath
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +116,7 @@ func (h *httpFederationInternalAPI) QueryJoinedHostServerNamesInRoom(
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryJoinedHostServerNamesInRoom")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryJoinedHostServerNamesInRoom")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.federationSenderURL + FederationSenderQueryJoinedHostServerNamesInRoomPath
|
apiURL := h.federationAPIURL + FederationAPIQueryJoinedHostServerNamesInRoomPath
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,7 +129,7 @@ func (h *httpFederationInternalAPI) PerformJoin(
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformJoinRequest")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformJoinRequest")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.federationSenderURL + FederationSenderPerformJoinRequestPath
|
apiURL := h.federationAPIURL + FederationAPIPerformJoinRequestPath
|
||||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.LastError = &gomatrix.HTTPError{
|
response.LastError = &gomatrix.HTTPError{
|
||||||
|
|
@ -144,7 +149,7 @@ func (h *httpFederationInternalAPI) PerformDirectoryLookup(
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformDirectoryLookup")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformDirectoryLookup")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.federationSenderURL + FederationSenderPerformDirectoryLookupRequestPath
|
apiURL := h.federationAPIURL + FederationAPIPerformDirectoryLookupRequestPath
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +162,7 @@ func (h *httpFederationInternalAPI) PerformBroadcastEDU(
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformBroadcastEDU")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformBroadcastEDU")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.federationSenderURL + FederationSenderPerformBroadcastEDUPath
|
apiURL := h.federationAPIURL + FederationAPIPerformBroadcastEDUPath
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,7 +185,7 @@ func (h *httpFederationInternalAPI) GetUserDevices(
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
}
|
}
|
||||||
var response getUserDevices
|
var response getUserDevices
|
||||||
apiURL := h.federationSenderURL + FederationSenderGetUserDevicesPath
|
apiURL := h.federationAPIURL + FederationAPIGetUserDevicesPath
|
||||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
|
|
@ -210,7 +215,7 @@ func (h *httpFederationInternalAPI) ClaimKeys(
|
||||||
OneTimeKeys: oneTimeKeys,
|
OneTimeKeys: oneTimeKeys,
|
||||||
}
|
}
|
||||||
var response claimKeys
|
var response claimKeys
|
||||||
apiURL := h.federationSenderURL + FederationSenderClaimKeysPath
|
apiURL := h.federationAPIURL + FederationAPIClaimKeysPath
|
||||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
|
|
@ -240,7 +245,7 @@ func (h *httpFederationInternalAPI) QueryKeys(
|
||||||
Keys: keys,
|
Keys: keys,
|
||||||
}
|
}
|
||||||
var response queryKeys
|
var response queryKeys
|
||||||
apiURL := h.federationSenderURL + FederationSenderQueryKeysPath
|
apiURL := h.federationAPIURL + FederationAPIQueryKeysPath
|
||||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
|
|
@ -273,7 +278,7 @@ func (h *httpFederationInternalAPI) Backfill(
|
||||||
EventIDs: eventIDs,
|
EventIDs: eventIDs,
|
||||||
}
|
}
|
||||||
var response backfill
|
var response backfill
|
||||||
apiURL := h.federationSenderURL + FederationSenderBackfillPath
|
apiURL := h.federationAPIURL + FederationAPIBackfillPath
|
||||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gomatrixserverlib.Transaction{}, err
|
return gomatrixserverlib.Transaction{}, err
|
||||||
|
|
@ -306,7 +311,7 @@ func (h *httpFederationInternalAPI) LookupState(
|
||||||
RoomVersion: roomVersion,
|
RoomVersion: roomVersion,
|
||||||
}
|
}
|
||||||
var response lookupState
|
var response lookupState
|
||||||
apiURL := h.federationSenderURL + FederationSenderLookupStatePath
|
apiURL := h.federationAPIURL + FederationAPILookupStatePath
|
||||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gomatrixserverlib.RespState{}, err
|
return gomatrixserverlib.RespState{}, err
|
||||||
|
|
@ -337,7 +342,7 @@ func (h *httpFederationInternalAPI) LookupStateIDs(
|
||||||
EventID: eventID,
|
EventID: eventID,
|
||||||
}
|
}
|
||||||
var response lookupStateIDs
|
var response lookupStateIDs
|
||||||
apiURL := h.federationSenderURL + FederationSenderLookupStateIDsPath
|
apiURL := h.federationAPIURL + FederationAPILookupStateIDsPath
|
||||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gomatrixserverlib.RespStateIDs{}, err
|
return gomatrixserverlib.RespStateIDs{}, err
|
||||||
|
|
@ -366,7 +371,7 @@ func (h *httpFederationInternalAPI) GetEvent(
|
||||||
EventID: eventID,
|
EventID: eventID,
|
||||||
}
|
}
|
||||||
var response getEvent
|
var response getEvent
|
||||||
apiURL := h.federationSenderURL + FederationSenderGetEventPath
|
apiURL := h.federationAPIURL + FederationAPIGetEventPath
|
||||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gomatrixserverlib.Transaction{}, err
|
return gomatrixserverlib.Transaction{}, err
|
||||||
|
|
@ -383,7 +388,7 @@ func (h *httpFederationInternalAPI) QueryServerKeys(
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerKeys")
|
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerKeys")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
apiURL := h.federationSenderURL + FederationSenderQueryServerKeysPath
|
apiURL := h.federationAPIURL + FederationAPIQueryServerKeysPath
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -405,7 +410,7 @@ func (h *httpFederationInternalAPI) LookupServerKeys(
|
||||||
KeyRequests: keyRequests,
|
KeyRequests: keyRequests,
|
||||||
}
|
}
|
||||||
var response lookupServerKeys
|
var response lookupServerKeys
|
||||||
apiURL := h.federationSenderURL + FederationSenderLookupServerKeysPath
|
apiURL := h.federationAPIURL + FederationAPILookupServerKeysPath
|
||||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []gomatrixserverlib.ServerKeys{}, err
|
return []gomatrixserverlib.ServerKeys{}, err
|
||||||
|
|
@ -437,7 +442,7 @@ func (h *httpFederationInternalAPI) MSC2836EventRelationships(
|
||||||
RoomVer: roomVersion,
|
RoomVer: roomVersion,
|
||||||
}
|
}
|
||||||
var response eventRelationships
|
var response eventRelationships
|
||||||
apiURL := h.federationSenderURL + FederationSenderEventRelationshipsPath
|
apiURL := h.federationAPIURL + FederationAPIEventRelationshipsPath
|
||||||
err = httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err = httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
|
|
@ -468,7 +473,7 @@ func (h *httpFederationInternalAPI) MSC2946Spaces(
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
}
|
}
|
||||||
var response spacesReq
|
var response spacesReq
|
||||||
apiURL := h.federationSenderURL + FederationSenderSpacesSummaryPath
|
apiURL := h.federationAPIURL + FederationAPISpacesSummaryPath
|
||||||
err = httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
err = httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
|
|
@ -478,3 +483,93 @@ func (h *httpFederationInternalAPI) MSC2946Spaces(
|
||||||
}
|
}
|
||||||
return response.Res, nil
|
return response.Res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *httpFederationInternalAPI) KeyRing() *gomatrixserverlib.KeyRing {
|
||||||
|
// This is a bit of a cheat - we tell gomatrixserverlib that this API is
|
||||||
|
// both the key database and the key fetcher. While this does have the
|
||||||
|
// rather unfortunate effect of preventing gomatrixserverlib from handling
|
||||||
|
// key fetchers directly, we can at least reimplement this behaviour on
|
||||||
|
// the other end of the API.
|
||||||
|
return &gomatrixserverlib.KeyRing{
|
||||||
|
KeyDatabase: s,
|
||||||
|
KeyFetchers: []gomatrixserverlib.KeyFetcher{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *httpFederationInternalAPI) FetcherName() string {
|
||||||
|
return "httpServerKeyInternalAPI"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *httpFederationInternalAPI) StoreKeys(
|
||||||
|
_ context.Context,
|
||||||
|
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
||||||
|
) error {
|
||||||
|
// Run in a background context - we don't want to stop this work just
|
||||||
|
// because the caller gives up waiting.
|
||||||
|
ctx := context.Background()
|
||||||
|
request := api.InputPublicKeysRequest{
|
||||||
|
Keys: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult),
|
||||||
|
}
|
||||||
|
response := api.InputPublicKeysResponse{}
|
||||||
|
for req, res := range results {
|
||||||
|
request.Keys[req] = res
|
||||||
|
s.cache.StoreServerKey(req, res)
|
||||||
|
}
|
||||||
|
return s.InputPublicKeys(ctx, &request, &response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *httpFederationInternalAPI) FetchKeys(
|
||||||
|
_ context.Context,
|
||||||
|
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
||||||
|
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
|
||||||
|
// Run in a background context - we don't want to stop this work just
|
||||||
|
// because the caller gives up waiting.
|
||||||
|
ctx := context.Background()
|
||||||
|
result := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult)
|
||||||
|
request := api.QueryPublicKeysRequest{
|
||||||
|
Requests: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp),
|
||||||
|
}
|
||||||
|
response := api.QueryPublicKeysResponse{
|
||||||
|
Results: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult),
|
||||||
|
}
|
||||||
|
for req, ts := range requests {
|
||||||
|
if res, ok := s.cache.GetServerKey(req, ts); ok {
|
||||||
|
result[req] = res
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
request.Requests[req] = ts
|
||||||
|
}
|
||||||
|
err := s.QueryPublicKeys(ctx, &request, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for req, res := range response.Results {
|
||||||
|
result[req] = res
|
||||||
|
s.cache.StoreServerKey(req, res)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *httpFederationInternalAPI) InputPublicKeys(
|
||||||
|
ctx context.Context,
|
||||||
|
request *api.InputPublicKeysRequest,
|
||||||
|
response *api.InputPublicKeysResponse,
|
||||||
|
) error {
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "InputPublicKey")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
apiURL := h.federationAPIURL + FederationAPIInputPublicKeyPath
|
||||||
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *httpFederationInternalAPI) QueryPublicKeys(
|
||||||
|
ctx context.Context,
|
||||||
|
request *api.QueryPublicKeysRequest,
|
||||||
|
response *api.QueryPublicKeysResponse,
|
||||||
|
) error {
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryPublicKey")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
apiURL := h.federationAPIURL + FederationAPIQueryPublicKeyPath
|
||||||
|
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
// nolint:gocyclo
|
// nolint:gocyclo
|
||||||
func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderQueryJoinedHostServerNamesInRoomPath,
|
FederationAPIQueryJoinedHostServerNamesInRoomPath,
|
||||||
httputil.MakeInternalAPI("QueryJoinedHostServerNamesInRoom", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("QueryJoinedHostServerNamesInRoom", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.QueryJoinedHostServerNamesInRoomRequest
|
var request api.QueryJoinedHostServerNamesInRoomRequest
|
||||||
var response api.QueryJoinedHostServerNamesInRoomResponse
|
var response api.QueryJoinedHostServerNamesInRoomResponse
|
||||||
|
|
@ -28,7 +28,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderPerformJoinRequestPath,
|
FederationAPIPerformJoinRequestPath,
|
||||||
httputil.MakeInternalAPI("PerformJoinRequest", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("PerformJoinRequest", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.PerformJoinRequest
|
var request api.PerformJoinRequest
|
||||||
var response api.PerformJoinResponse
|
var response api.PerformJoinResponse
|
||||||
|
|
@ -40,7 +40,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderPerformLeaveRequestPath,
|
FederationAPIPerformLeaveRequestPath,
|
||||||
httputil.MakeInternalAPI("PerformLeaveRequest", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("PerformLeaveRequest", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.PerformLeaveRequest
|
var request api.PerformLeaveRequest
|
||||||
var response api.PerformLeaveResponse
|
var response api.PerformLeaveResponse
|
||||||
|
|
@ -54,7 +54,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderPerformInviteRequestPath,
|
FederationAPIPerformInviteRequestPath,
|
||||||
httputil.MakeInternalAPI("PerformInviteRequest", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("PerformInviteRequest", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.PerformInviteRequest
|
var request api.PerformInviteRequest
|
||||||
var response api.PerformInviteResponse
|
var response api.PerformInviteResponse
|
||||||
|
|
@ -68,7 +68,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderPerformDirectoryLookupRequestPath,
|
FederationAPIPerformDirectoryLookupRequestPath,
|
||||||
httputil.MakeInternalAPI("PerformDirectoryLookupRequest", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("PerformDirectoryLookupRequest", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.PerformDirectoryLookupRequest
|
var request api.PerformDirectoryLookupRequest
|
||||||
var response api.PerformDirectoryLookupResponse
|
var response api.PerformDirectoryLookupResponse
|
||||||
|
|
@ -82,7 +82,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderPerformServersAlivePath,
|
FederationAPIPerformServersAlivePath,
|
||||||
httputil.MakeInternalAPI("PerformServersAliveRequest", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("PerformServersAliveRequest", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.PerformServersAliveRequest
|
var request api.PerformServersAliveRequest
|
||||||
var response api.PerformServersAliveResponse
|
var response api.PerformServersAliveResponse
|
||||||
|
|
@ -96,7 +96,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderPerformBroadcastEDUPath,
|
FederationAPIPerformBroadcastEDUPath,
|
||||||
httputil.MakeInternalAPI("PerformBroadcastEDU", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("PerformBroadcastEDU", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.PerformBroadcastEDURequest
|
var request api.PerformBroadcastEDURequest
|
||||||
var response api.PerformBroadcastEDUResponse
|
var response api.PerformBroadcastEDUResponse
|
||||||
|
|
@ -110,7 +110,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderGetUserDevicesPath,
|
FederationAPIGetUserDevicesPath,
|
||||||
httputil.MakeInternalAPI("GetUserDevices", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("GetUserDevices", func(req *http.Request) util.JSONResponse {
|
||||||
var request getUserDevices
|
var request getUserDevices
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -132,7 +132,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderClaimKeysPath,
|
FederationAPIClaimKeysPath,
|
||||||
httputil.MakeInternalAPI("ClaimKeys", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("ClaimKeys", func(req *http.Request) util.JSONResponse {
|
||||||
var request claimKeys
|
var request claimKeys
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -154,7 +154,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderQueryKeysPath,
|
FederationAPIQueryKeysPath,
|
||||||
httputil.MakeInternalAPI("QueryKeys", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("QueryKeys", func(req *http.Request) util.JSONResponse {
|
||||||
var request queryKeys
|
var request queryKeys
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -176,7 +176,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderBackfillPath,
|
FederationAPIBackfillPath,
|
||||||
httputil.MakeInternalAPI("Backfill", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("Backfill", func(req *http.Request) util.JSONResponse {
|
||||||
var request backfill
|
var request backfill
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -198,7 +198,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderLookupStatePath,
|
FederationAPILookupStatePath,
|
||||||
httputil.MakeInternalAPI("LookupState", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("LookupState", func(req *http.Request) util.JSONResponse {
|
||||||
var request lookupState
|
var request lookupState
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -220,7 +220,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderLookupStateIDsPath,
|
FederationAPILookupStateIDsPath,
|
||||||
httputil.MakeInternalAPI("LookupStateIDs", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("LookupStateIDs", func(req *http.Request) util.JSONResponse {
|
||||||
var request lookupStateIDs
|
var request lookupStateIDs
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -242,7 +242,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderGetEventPath,
|
FederationAPIGetEventPath,
|
||||||
httputil.MakeInternalAPI("GetEvent", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("GetEvent", func(req *http.Request) util.JSONResponse {
|
||||||
var request getEvent
|
var request getEvent
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -264,7 +264,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderQueryServerKeysPath,
|
FederationAPIQueryServerKeysPath,
|
||||||
httputil.MakeInternalAPI("QueryServerKeys", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("QueryServerKeys", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.QueryServerKeysRequest
|
var request api.QueryServerKeysRequest
|
||||||
var response api.QueryServerKeysResponse
|
var response api.QueryServerKeysResponse
|
||||||
|
|
@ -278,7 +278,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderLookupServerKeysPath,
|
FederationAPILookupServerKeysPath,
|
||||||
httputil.MakeInternalAPI("LookupServerKeys", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("LookupServerKeys", func(req *http.Request) util.JSONResponse {
|
||||||
var request lookupServerKeys
|
var request lookupServerKeys
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -300,7 +300,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderEventRelationshipsPath,
|
FederationAPIEventRelationshipsPath,
|
||||||
httputil.MakeInternalAPI("MSC2836EventRelationships", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("MSC2836EventRelationships", func(req *http.Request) util.JSONResponse {
|
||||||
var request eventRelationships
|
var request eventRelationships
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -322,7 +322,7 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
internalAPIMux.Handle(
|
internalAPIMux.Handle(
|
||||||
FederationSenderSpacesSummaryPath,
|
FederationAPISpacesSummaryPath,
|
||||||
httputil.MakeInternalAPI("MSC2946SpacesSummary", func(req *http.Request) util.JSONResponse {
|
httputil.MakeInternalAPI("MSC2946SpacesSummary", func(req *http.Request) util.JSONResponse {
|
||||||
var request spacesReq
|
var request spacesReq
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
|
@ -343,4 +343,32 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
internalAPIMux.Handle(FederationAPIQueryPublicKeyPath,
|
||||||
|
httputil.MakeInternalAPI("queryPublicKeys", func(req *http.Request) util.JSONResponse {
|
||||||
|
request := api.QueryPublicKeysRequest{}
|
||||||
|
response := api.QueryPublicKeysResponse{}
|
||||||
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||||
|
}
|
||||||
|
keys, err := intAPI.FetchKeys(req.Context(), request.Requests)
|
||||||
|
if err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
response.Results = keys
|
||||||
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
internalAPIMux.Handle(FederationAPIInputPublicKeyPath,
|
||||||
|
httputil.MakeInternalAPI("inputPublicKeys", func(req *http.Request) util.JSONResponse {
|
||||||
|
request := api.InputPublicKeysRequest{}
|
||||||
|
response := api.InputPublicKeysResponse{}
|
||||||
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||||
|
}
|
||||||
|
if err := intAPI.StoreKeys(req.Context(), request.Keys); err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package signingkeyserver
|
package federationapi
|
||||||
|
|
||||||
|
/*
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -13,21 +14,20 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/federationapi/api"
|
||||||
"github.com/matrix-org/dendrite/federationapi/routing"
|
"github.com/matrix-org/dendrite/federationapi/routing"
|
||||||
"github.com/matrix-org/dendrite/internal/caching"
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/api"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type server struct {
|
type server struct {
|
||||||
name gomatrixserverlib.ServerName // server name
|
name gomatrixserverlib.ServerName // server name
|
||||||
validity time.Duration // key validity duration from now
|
validity time.Duration // key validity duration from now
|
||||||
config *config.SigningKeyServer // skeleton config, from TestMain
|
config *config.FederationAPI // skeleton config, from TestMain
|
||||||
fedconfig *config.FederationAPI //
|
|
||||||
fedclient *gomatrixserverlib.FederationClient // uses MockRoundTripper
|
fedclient *gomatrixserverlib.FederationClient // uses MockRoundTripper
|
||||||
cache *caching.Caches // server-specific cache
|
cache *caching.Caches // server-specific cache
|
||||||
api api.SigningKeyServerAPI // server-specific server key API
|
api api.FederationInternalAPI // server-specific server key API
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) renew() {
|
func (s *server) renew() {
|
||||||
|
|
@ -76,9 +76,8 @@ func TestMain(m *testing.M) {
|
||||||
cfg.Global.PrivateKey = testPriv
|
cfg.Global.PrivateKey = testPriv
|
||||||
cfg.Global.KeyID = serverKeyID
|
cfg.Global.KeyID = serverKeyID
|
||||||
cfg.Global.KeyValidityPeriod = s.validity
|
cfg.Global.KeyValidityPeriod = s.validity
|
||||||
cfg.SigningKeyServer.Database.ConnectionString = config.DataSource("file::memory:")
|
cfg.FederationAPI.Database.ConnectionString = config.DataSource("file::memory:")
|
||||||
s.config = &cfg.SigningKeyServer
|
s.config = &cfg.FederationAPI
|
||||||
s.fedconfig = &cfg.FederationAPI
|
|
||||||
|
|
||||||
// Create a transport which redirects federation requests to
|
// Create a transport which redirects federation requests to
|
||||||
// the mock round tripper. Since we're not *really* listening for
|
// the mock round tripper. Since we're not *really* listening for
|
||||||
|
|
@ -93,7 +92,7 @@ func TestMain(m *testing.M) {
|
||||||
)
|
)
|
||||||
|
|
||||||
// Finally, build the server key APIs.
|
// Finally, build the server key APIs.
|
||||||
s.api = NewInternalAPI(s.config, s.fedclient, s.cache)
|
s.api = NewInternalAPI(s.config, s.fedclient, s.cache, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we have built our server key APIs, start the
|
// Now that we have built our server key APIs, start the
|
||||||
|
|
@ -119,7 +118,7 @@ func (m *MockRoundTripper) RoundTrip(req *http.Request) (res *http.Response, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the keys and JSON-ify them.
|
// Get the keys and JSON-ify them.
|
||||||
keys := routing.LocalKeys(s.fedconfig)
|
keys := routing.LocalKeys(s.config)
|
||||||
body, err := json.MarshalIndent(keys.JSON, "", " ")
|
body, err := json.MarshalIndent(keys.JSON, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -317,3 +316,4 @@ func TestRenewalBehaviour(t *testing.T) {
|
||||||
}
|
}
|
||||||
t.Log(res)
|
t.Log(res)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
@ -88,11 +88,10 @@ func MakeConfig(configDir, kafkaURI, database, host string, startPort int) (*con
|
||||||
// the table names are globally unique. But we might not want to
|
// the table names are globally unique. But we might not want to
|
||||||
// rely on that in the future.
|
// rely on that in the future.
|
||||||
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(database)
|
cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(database)
|
||||||
cfg.FederationSender.Database.ConnectionString = config.DataSource(database)
|
cfg.FederationAPI.Database.ConnectionString = config.DataSource(database)
|
||||||
cfg.KeyServer.Database.ConnectionString = config.DataSource(database)
|
cfg.KeyServer.Database.ConnectionString = config.DataSource(database)
|
||||||
cfg.MediaAPI.Database.ConnectionString = config.DataSource(database)
|
cfg.MediaAPI.Database.ConnectionString = config.DataSource(database)
|
||||||
cfg.RoomServer.Database.ConnectionString = config.DataSource(database)
|
cfg.RoomServer.Database.ConnectionString = config.DataSource(database)
|
||||||
cfg.SigningKeyServer.Database.ConnectionString = config.DataSource(database)
|
|
||||||
cfg.SyncAPI.Database.ConnectionString = config.DataSource(database)
|
cfg.SyncAPI.Database.ConnectionString = config.DataSource(database)
|
||||||
cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(database)
|
cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(database)
|
||||||
cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(database)
|
cfg.UserAPI.DeviceDatabase.ConnectionString = config.DataSource(database)
|
||||||
|
|
@ -100,22 +99,18 @@ func MakeConfig(configDir, kafkaURI, database, host string, startPort int) (*con
|
||||||
cfg.AppServiceAPI.InternalAPI.Listen = assignAddress()
|
cfg.AppServiceAPI.InternalAPI.Listen = assignAddress()
|
||||||
cfg.EDUServer.InternalAPI.Listen = assignAddress()
|
cfg.EDUServer.InternalAPI.Listen = assignAddress()
|
||||||
cfg.FederationAPI.InternalAPI.Listen = assignAddress()
|
cfg.FederationAPI.InternalAPI.Listen = assignAddress()
|
||||||
cfg.FederationSender.InternalAPI.Listen = assignAddress()
|
|
||||||
cfg.KeyServer.InternalAPI.Listen = assignAddress()
|
cfg.KeyServer.InternalAPI.Listen = assignAddress()
|
||||||
cfg.MediaAPI.InternalAPI.Listen = assignAddress()
|
cfg.MediaAPI.InternalAPI.Listen = assignAddress()
|
||||||
cfg.RoomServer.InternalAPI.Listen = assignAddress()
|
cfg.RoomServer.InternalAPI.Listen = assignAddress()
|
||||||
cfg.SigningKeyServer.InternalAPI.Listen = assignAddress()
|
|
||||||
cfg.SyncAPI.InternalAPI.Listen = assignAddress()
|
cfg.SyncAPI.InternalAPI.Listen = assignAddress()
|
||||||
cfg.UserAPI.InternalAPI.Listen = assignAddress()
|
cfg.UserAPI.InternalAPI.Listen = assignAddress()
|
||||||
|
|
||||||
cfg.AppServiceAPI.InternalAPI.Connect = cfg.AppServiceAPI.InternalAPI.Listen
|
cfg.AppServiceAPI.InternalAPI.Connect = cfg.AppServiceAPI.InternalAPI.Listen
|
||||||
cfg.EDUServer.InternalAPI.Connect = cfg.EDUServer.InternalAPI.Listen
|
cfg.EDUServer.InternalAPI.Connect = cfg.EDUServer.InternalAPI.Listen
|
||||||
cfg.FederationAPI.InternalAPI.Connect = cfg.FederationAPI.InternalAPI.Listen
|
cfg.FederationAPI.InternalAPI.Connect = cfg.FederationAPI.InternalAPI.Listen
|
||||||
cfg.FederationSender.InternalAPI.Connect = cfg.FederationSender.InternalAPI.Listen
|
|
||||||
cfg.KeyServer.InternalAPI.Connect = cfg.KeyServer.InternalAPI.Listen
|
cfg.KeyServer.InternalAPI.Connect = cfg.KeyServer.InternalAPI.Listen
|
||||||
cfg.MediaAPI.InternalAPI.Connect = cfg.MediaAPI.InternalAPI.Listen
|
cfg.MediaAPI.InternalAPI.Connect = cfg.MediaAPI.InternalAPI.Listen
|
||||||
cfg.RoomServer.InternalAPI.Connect = cfg.RoomServer.InternalAPI.Listen
|
cfg.RoomServer.InternalAPI.Connect = cfg.RoomServer.InternalAPI.Listen
|
||||||
cfg.SigningKeyServer.InternalAPI.Connect = cfg.SigningKeyServer.InternalAPI.Listen
|
|
||||||
cfg.SyncAPI.InternalAPI.Connect = cfg.SyncAPI.InternalAPI.Listen
|
cfg.SyncAPI.InternalAPI.Connect = cfg.SyncAPI.InternalAPI.Listen
|
||||||
cfg.UserAPI.InternalAPI.Connect = cfg.UserAPI.InternalAPI.Listen
|
cfg.UserAPI.InternalAPI.Connect = cfg.UserAPI.InternalAPI.Listen
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
asAPI "github.com/matrix-org/dendrite/appservice/api"
|
asAPI "github.com/matrix-org/dendrite/appservice/api"
|
||||||
fsAPI "github.com/matrix-org/dendrite/federationapi/api"
|
fsAPI "github.com/matrix-org/dendrite/federationapi/api"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RoomserverInputAPI is used to write events to the room server.
|
// RoomserverInputAPI is used to write events to the room server.
|
||||||
|
|
@ -13,6 +14,7 @@ type RoomserverInternalAPI interface {
|
||||||
// interdependencies between the roomserver and other input APIs
|
// interdependencies between the roomserver and other input APIs
|
||||||
SetFederationSenderAPI(fsAPI fsAPI.FederationInternalAPI)
|
SetFederationSenderAPI(fsAPI fsAPI.FederationInternalAPI)
|
||||||
SetAppserviceAPI(asAPI asAPI.AppServiceQueryAPI)
|
SetAppserviceAPI(asAPI asAPI.AppServiceQueryAPI)
|
||||||
|
SetKeyring(keyRing *gomatrixserverlib.KeyRing)
|
||||||
|
|
||||||
InputRoomEvents(
|
InputRoomEvents(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
asAPI "github.com/matrix-org/dendrite/appservice/api"
|
asAPI "github.com/matrix-org/dendrite/appservice/api"
|
||||||
fsAPI "github.com/matrix-org/dendrite/federationapi/api"
|
fsAPI "github.com/matrix-org/dendrite/federationapi/api"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -16,6 +17,10 @@ type RoomserverInternalAPITrace struct {
|
||||||
Impl RoomserverInternalAPI
|
Impl RoomserverInternalAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *RoomserverInternalAPITrace) SetKeyring(keyRing *gomatrixserverlib.KeyRing) {
|
||||||
|
t.Impl.SetKeyring(keyRing)
|
||||||
|
}
|
||||||
|
|
||||||
func (t *RoomserverInternalAPITrace) SetFederationSenderAPI(fsAPI fsAPI.FederationInternalAPI) {
|
func (t *RoomserverInternalAPITrace) SetFederationSenderAPI(fsAPI fsAPI.FederationInternalAPI) {
|
||||||
t.Impl.SetFederationSenderAPI(fsAPI)
|
t.Impl.SetFederationSenderAPI(fsAPI)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ type RoomserverInternalAPI struct {
|
||||||
func NewRoomserverAPI(
|
func NewRoomserverAPI(
|
||||||
cfg *config.RoomServer, roomserverDB storage.Database, producer sarama.SyncProducer,
|
cfg *config.RoomServer, roomserverDB storage.Database, producer sarama.SyncProducer,
|
||||||
outputRoomEventTopic string, caches caching.RoomServerCaches,
|
outputRoomEventTopic string, caches caching.RoomServerCaches,
|
||||||
keyRing gomatrixserverlib.JSONVerifier, perspectiveServerNames []gomatrixserverlib.ServerName,
|
perspectiveServerNames []gomatrixserverlib.ServerName,
|
||||||
) *RoomserverInternalAPI {
|
) *RoomserverInternalAPI {
|
||||||
serverACLs := acls.NewServerACLs(roomserverDB)
|
serverACLs := acls.NewServerACLs(roomserverDB)
|
||||||
a := &RoomserverInternalAPI{
|
a := &RoomserverInternalAPI{
|
||||||
|
|
@ -55,7 +55,6 @@ func NewRoomserverAPI(
|
||||||
Cache: caches,
|
Cache: caches,
|
||||||
ServerName: cfg.Matrix.ServerName,
|
ServerName: cfg.Matrix.ServerName,
|
||||||
PerspectiveServerNames: perspectiveServerNames,
|
PerspectiveServerNames: perspectiveServerNames,
|
||||||
KeyRing: keyRing,
|
|
||||||
Queryer: &query.Queryer{
|
Queryer: &query.Queryer{
|
||||||
DB: roomserverDB,
|
DB: roomserverDB,
|
||||||
Cache: caches,
|
Cache: caches,
|
||||||
|
|
@ -74,11 +73,18 @@ func NewRoomserverAPI(
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetKeyring sets the keyring to a given keyring. This is only useful for the P2P
|
||||||
|
// demos and must be called after SetFederationSenderInputAPI.
|
||||||
|
func (r *RoomserverInternalAPI) SetKeyring(keyRing *gomatrixserverlib.KeyRing) {
|
||||||
|
r.KeyRing = keyRing
|
||||||
|
}
|
||||||
|
|
||||||
// SetFederationSenderInputAPI passes in a federation sender input API reference
|
// SetFederationSenderInputAPI passes in a federation sender input API reference
|
||||||
// so that we can avoid the chicken-and-egg problem of both the roomserver input API
|
// so that we can avoid the chicken-and-egg problem of both the roomserver input API
|
||||||
// and the federation sender input API being interdependent.
|
// and the federation sender input API being interdependent.
|
||||||
func (r *RoomserverInternalAPI) SetFederationSenderAPI(fsAPI fsAPI.FederationInternalAPI) {
|
func (r *RoomserverInternalAPI) SetFederationSenderAPI(fsAPI fsAPI.FederationInternalAPI) {
|
||||||
r.fsAPI = fsAPI
|
r.fsAPI = fsAPI
|
||||||
|
r.SetKeyring(fsAPI.KeyRing())
|
||||||
|
|
||||||
r.Inviter = &perform.Inviter{
|
r.Inviter = &perform.Inviter{
|
||||||
DB: r.DB,
|
DB: r.DB,
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/internal/caching"
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/internal/httputil"
|
"github.com/matrix-org/dendrite/internal/httputil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/opentracing/opentracing-go"
|
"github.com/opentracing/opentracing-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -82,6 +83,10 @@ func NewRoomserverClient(
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetKeyring no-ops in HTTP client mode as there is no chicken/egg scenario
|
||||||
|
func (h *httpRoomserverInternalAPI) SetKeyring(keyRing *gomatrixserverlib.KeyRing) {
|
||||||
|
}
|
||||||
|
|
||||||
// SetFederationSenderInputAPI no-ops in HTTP client mode as there is no chicken/egg scenario
|
// SetFederationSenderInputAPI no-ops in HTTP client mode as there is no chicken/egg scenario
|
||||||
func (h *httpRoomserverInternalAPI) SetFederationSenderAPI(fsAPI fsInputAPI.FederationInternalAPI) {
|
func (h *httpRoomserverInternalAPI) SetFederationSenderAPI(fsAPI fsInputAPI.FederationInternalAPI) {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,14 +38,13 @@ func AddInternalRoutes(router *mux.Router, intAPI api.RoomserverInternalAPI) {
|
||||||
// can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
|
// can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
|
||||||
func NewInternalAPI(
|
func NewInternalAPI(
|
||||||
base *base.BaseDendrite,
|
base *base.BaseDendrite,
|
||||||
keyRing gomatrixserverlib.JSONVerifier,
|
|
||||||
) api.RoomserverInternalAPI {
|
) api.RoomserverInternalAPI {
|
||||||
cfg := &base.Cfg.RoomServer
|
cfg := &base.Cfg.RoomServer
|
||||||
|
|
||||||
_, producer := kafka.SetupConsumerProducer(&cfg.Matrix.Kafka)
|
_, producer := kafka.SetupConsumerProducer(&cfg.Matrix.Kafka)
|
||||||
|
|
||||||
var perspectiveServerNames []gomatrixserverlib.ServerName
|
var perspectiveServerNames []gomatrixserverlib.ServerName
|
||||||
for _, kp := range base.Cfg.SigningKeyServer.KeyPerspectives {
|
for _, kp := range base.Cfg.FederationAPI.KeyPerspectives {
|
||||||
perspectiveServerNames = append(perspectiveServerNames, kp.ServerName)
|
perspectiveServerNames = append(perspectiveServerNames, kp.ServerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,6 +55,6 @@ func NewInternalAPI(
|
||||||
|
|
||||||
return internal.NewRoomserverAPI(
|
return internal.NewRoomserverAPI(
|
||||||
cfg, roomserverDB, producer, string(cfg.Matrix.Kafka.TopicFor(config.TopicOutputRoomEvent)),
|
cfg, roomserverDB, producer, string(cfg.Matrix.Kafka.TopicFor(config.TopicOutputRoomEvent)),
|
||||||
base.Caches, keyRing, perspectiveServerNames,
|
base.Caches, perspectiveServerNames,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import (
|
||||||
|
|
||||||
"github.com/Shopify/sarama"
|
"github.com/Shopify/sarama"
|
||||||
"github.com/matrix-org/dendrite/internal/caching"
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/internal/test"
|
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/roomserver/internal"
|
"github.com/matrix-org/dendrite/roomserver/internal"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage"
|
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||||
|
|
@ -182,7 +181,7 @@ func mustCreateRoomserverAPI(t *testing.T) (api.RoomserverInternalAPI, *dummyPro
|
||||||
}
|
}
|
||||||
return internal.NewRoomserverAPI(
|
return internal.NewRoomserverAPI(
|
||||||
&cfg.RoomServer, roomserverDB, dp, string(cfg.Global.Kafka.TopicFor(config.TopicOutputRoomEvent)),
|
&cfg.RoomServer, roomserverDB, dp, string(cfg.Global.Kafka.TopicFor(config.TopicOutputRoomEvent)),
|
||||||
base.Caches, &test.NopJSONVerifier{}, nil,
|
base.Caches, nil,
|
||||||
), dp
|
), dp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,12 @@ import (
|
||||||
eduServerAPI "github.com/matrix-org/dendrite/eduserver/api"
|
eduServerAPI "github.com/matrix-org/dendrite/eduserver/api"
|
||||||
eduinthttp "github.com/matrix-org/dendrite/eduserver/inthttp"
|
eduinthttp "github.com/matrix-org/dendrite/eduserver/inthttp"
|
||||||
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
|
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
|
||||||
fsinthttp "github.com/matrix-org/dendrite/federationapi/inthttp"
|
federationIntHTTP "github.com/matrix-org/dendrite/federationapi/inthttp"
|
||||||
keyserverAPI "github.com/matrix-org/dendrite/keyserver/api"
|
keyserverAPI "github.com/matrix-org/dendrite/keyserver/api"
|
||||||
keyinthttp "github.com/matrix-org/dendrite/keyserver/inthttp"
|
keyinthttp "github.com/matrix-org/dendrite/keyserver/inthttp"
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
rsinthttp "github.com/matrix-org/dendrite/roomserver/inthttp"
|
rsinthttp "github.com/matrix-org/dendrite/roomserver/inthttp"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
skapi "github.com/matrix-org/dendrite/signingkeyserver/api"
|
|
||||||
skinthttp "github.com/matrix-org/dendrite/signingkeyserver/inthttp"
|
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
userapiinthttp "github.com/matrix-org/dendrite/userapi/inthttp"
|
userapiinthttp "github.com/matrix-org/dendrite/userapi/inthttp"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
@ -168,10 +166,10 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs boo
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client := http.Client{Timeout: HTTPClientTimeout}
|
client := http.Client{Timeout: HTTPClientTimeout}
|
||||||
if cfg.FederationSender.Proxy.Enabled {
|
if cfg.FederationAPI.Proxy.Enabled {
|
||||||
client.Transport = &http.Transport{Proxy: http.ProxyURL(&url.URL{
|
client.Transport = &http.Transport{Proxy: http.ProxyURL(&url.URL{
|
||||||
Scheme: cfg.FederationSender.Proxy.Protocol,
|
Scheme: cfg.FederationAPI.Proxy.Protocol,
|
||||||
Host: fmt.Sprintf("%s:%d", cfg.FederationSender.Proxy.Host, cfg.FederationSender.Proxy.Port),
|
Host: fmt.Sprintf("%s:%d", cfg.FederationAPI.Proxy.Host, cfg.FederationAPI.Proxy.Port),
|
||||||
})}
|
})}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,25 +246,12 @@ func (b *BaseDendrite) EDUServerClient() eduServerAPI.EDUServerInputAPI {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// FederationSenderHTTPClient returns FederationInternalAPI for hitting
|
// FederationAPIHTTPClient returns FederationInternalAPI for hitting
|
||||||
// the federation sender over HTTP
|
// the federation API server over HTTP
|
||||||
func (b *BaseDendrite) FederationSenderHTTPClient() federationAPI.FederationInternalAPI {
|
func (b *BaseDendrite) FederationAPIHTTPClient() federationAPI.FederationInternalAPI {
|
||||||
f, err := fsinthttp.NewFederationSenderClient(b.Cfg.FederationSenderURL(), b.apiHttpClient)
|
f, err := federationIntHTTP.NewFederationAPIClient(b.Cfg.FederationAPIURL(), b.apiHttpClient, b.Caches)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Panic("FederationSenderHTTPClient failed", b.apiHttpClient)
|
logrus.WithError(err).Panic("FederationAPIHTTPClient failed", b.apiHttpClient)
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
// SigningKeyServerHTTPClient returns SigningKeyServer for hitting the signing key server over HTTP
|
|
||||||
func (b *BaseDendrite) SigningKeyServerHTTPClient() skapi.SigningKeyServerAPI {
|
|
||||||
f, err := skinthttp.NewSigningKeyServerClient(
|
|
||||||
b.Cfg.SigningKeyServerURL(),
|
|
||||||
b.apiHttpClient,
|
|
||||||
b.Caches,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
logrus.WithError(err).Panic("SigningKeyServerHTTPClient failed", b.httpClient)
|
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
@ -300,7 +285,7 @@ func (b *BaseDendrite) CreateClient() *gomatrixserverlib.Client {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
opts := []gomatrixserverlib.ClientOption{
|
opts := []gomatrixserverlib.ClientOption{
|
||||||
gomatrixserverlib.WithSkipVerify(b.Cfg.FederationSender.DisableTLSValidation),
|
gomatrixserverlib.WithSkipVerify(b.Cfg.FederationAPI.DisableTLSValidation),
|
||||||
}
|
}
|
||||||
if b.Cfg.Global.DNSCache.Enabled {
|
if b.Cfg.Global.DNSCache.Enabled {
|
||||||
opts = append(opts, gomatrixserverlib.WithDNSCache(b.DNSCache))
|
opts = append(opts, gomatrixserverlib.WithDNSCache(b.DNSCache))
|
||||||
|
|
@ -321,7 +306,7 @@ func (b *BaseDendrite) CreateFederationClient() *gomatrixserverlib.FederationCli
|
||||||
}
|
}
|
||||||
opts := []gomatrixserverlib.ClientOption{
|
opts := []gomatrixserverlib.ClientOption{
|
||||||
gomatrixserverlib.WithTimeout(time.Minute * 5),
|
gomatrixserverlib.WithTimeout(time.Minute * 5),
|
||||||
gomatrixserverlib.WithSkipVerify(b.Cfg.FederationSender.DisableTLSValidation),
|
gomatrixserverlib.WithSkipVerify(b.Cfg.FederationAPI.DisableTLSValidation),
|
||||||
}
|
}
|
||||||
if b.Cfg.Global.DNSCache.Enabled {
|
if b.Cfg.Global.DNSCache.Enabled {
|
||||||
opts = append(opts, gomatrixserverlib.WithDNSCache(b.DNSCache))
|
opts = append(opts, gomatrixserverlib.WithDNSCache(b.DNSCache))
|
||||||
|
|
|
||||||
|
|
@ -53,18 +53,16 @@ type Dendrite struct {
|
||||||
// been a breaking change to the config file format.
|
// been a breaking change to the config file format.
|
||||||
Version int `yaml:"version"`
|
Version int `yaml:"version"`
|
||||||
|
|
||||||
Global Global `yaml:"global"`
|
Global Global `yaml:"global"`
|
||||||
AppServiceAPI AppServiceAPI `yaml:"app_service_api"`
|
AppServiceAPI AppServiceAPI `yaml:"app_service_api"`
|
||||||
ClientAPI ClientAPI `yaml:"client_api"`
|
ClientAPI ClientAPI `yaml:"client_api"`
|
||||||
EDUServer EDUServer `yaml:"edu_server"`
|
EDUServer EDUServer `yaml:"edu_server"`
|
||||||
FederationAPI FederationAPI `yaml:"federation_api"`
|
FederationAPI FederationAPI `yaml:"federation_api"`
|
||||||
FederationSender FederationSender `yaml:"federation_sender"`
|
KeyServer KeyServer `yaml:"key_server"`
|
||||||
KeyServer KeyServer `yaml:"key_server"`
|
MediaAPI MediaAPI `yaml:"media_api"`
|
||||||
MediaAPI MediaAPI `yaml:"media_api"`
|
RoomServer RoomServer `yaml:"room_server"`
|
||||||
RoomServer RoomServer `yaml:"room_server"`
|
SyncAPI SyncAPI `yaml:"sync_api"`
|
||||||
SigningKeyServer SigningKeyServer `yaml:"signing_key_server"`
|
UserAPI UserAPI `yaml:"user_api"`
|
||||||
SyncAPI SyncAPI `yaml:"sync_api"`
|
|
||||||
UserAPI UserAPI `yaml:"user_api"`
|
|
||||||
|
|
||||||
MSCs MSCs `yaml:"mscs"`
|
MSCs MSCs `yaml:"mscs"`
|
||||||
|
|
||||||
|
|
@ -300,11 +298,9 @@ func (c *Dendrite) Defaults() {
|
||||||
c.ClientAPI.Defaults()
|
c.ClientAPI.Defaults()
|
||||||
c.EDUServer.Defaults()
|
c.EDUServer.Defaults()
|
||||||
c.FederationAPI.Defaults()
|
c.FederationAPI.Defaults()
|
||||||
c.FederationSender.Defaults()
|
|
||||||
c.KeyServer.Defaults()
|
c.KeyServer.Defaults()
|
||||||
c.MediaAPI.Defaults()
|
c.MediaAPI.Defaults()
|
||||||
c.RoomServer.Defaults()
|
c.RoomServer.Defaults()
|
||||||
c.SigningKeyServer.Defaults()
|
|
||||||
c.SyncAPI.Defaults()
|
c.SyncAPI.Defaults()
|
||||||
c.UserAPI.Defaults()
|
c.UserAPI.Defaults()
|
||||||
c.AppServiceAPI.Defaults()
|
c.AppServiceAPI.Defaults()
|
||||||
|
|
@ -319,9 +315,9 @@ func (c *Dendrite) Verify(configErrs *ConfigErrors, isMonolith bool) {
|
||||||
}
|
}
|
||||||
for _, c := range []verifiable{
|
for _, c := range []verifiable{
|
||||||
&c.Global, &c.ClientAPI,
|
&c.Global, &c.ClientAPI,
|
||||||
&c.EDUServer, &c.FederationAPI, &c.FederationSender,
|
&c.EDUServer, &c.FederationAPI,
|
||||||
&c.KeyServer, &c.MediaAPI, &c.RoomServer,
|
&c.KeyServer, &c.MediaAPI, &c.RoomServer,
|
||||||
&c.SigningKeyServer, &c.SyncAPI, &c.UserAPI,
|
&c.SyncAPI, &c.UserAPI,
|
||||||
&c.AppServiceAPI, &c.MSCs,
|
&c.AppServiceAPI, &c.MSCs,
|
||||||
} {
|
} {
|
||||||
c.Verify(configErrs, isMonolith)
|
c.Verify(configErrs, isMonolith)
|
||||||
|
|
@ -332,11 +328,9 @@ func (c *Dendrite) Wiring() {
|
||||||
c.ClientAPI.Matrix = &c.Global
|
c.ClientAPI.Matrix = &c.Global
|
||||||
c.EDUServer.Matrix = &c.Global
|
c.EDUServer.Matrix = &c.Global
|
||||||
c.FederationAPI.Matrix = &c.Global
|
c.FederationAPI.Matrix = &c.Global
|
||||||
c.FederationSender.Matrix = &c.Global
|
|
||||||
c.KeyServer.Matrix = &c.Global
|
c.KeyServer.Matrix = &c.Global
|
||||||
c.MediaAPI.Matrix = &c.Global
|
c.MediaAPI.Matrix = &c.Global
|
||||||
c.RoomServer.Matrix = &c.Global
|
c.RoomServer.Matrix = &c.Global
|
||||||
c.SigningKeyServer.Matrix = &c.Global
|
|
||||||
c.SyncAPI.Matrix = &c.Global
|
c.SyncAPI.Matrix = &c.Global
|
||||||
c.UserAPI.Matrix = &c.Global
|
c.UserAPI.Matrix = &c.Global
|
||||||
c.AppServiceAPI.Matrix = &c.Global
|
c.AppServiceAPI.Matrix = &c.Global
|
||||||
|
|
@ -493,6 +487,15 @@ func (config *Dendrite) AppServiceURL() string {
|
||||||
return string(config.AppServiceAPI.InternalAPI.Connect)
|
return string(config.AppServiceAPI.InternalAPI.Connect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FederationAPIURL returns an HTTP URL for where the federation API is listening.
|
||||||
|
func (config *Dendrite) FederationAPIURL() string {
|
||||||
|
// Hard code the federationapi to talk HTTP for now.
|
||||||
|
// If we support HTTPS we need to think of a practical way to do certificate validation.
|
||||||
|
// People setting up servers shouldn't need to get a certificate valid for the public
|
||||||
|
// internet for an internal API.
|
||||||
|
return string(config.FederationAPI.InternalAPI.Connect)
|
||||||
|
}
|
||||||
|
|
||||||
// RoomServerURL returns an HTTP URL for where the roomserver is listening.
|
// RoomServerURL returns an HTTP URL for where the roomserver is listening.
|
||||||
func (config *Dendrite) RoomServerURL() string {
|
func (config *Dendrite) RoomServerURL() string {
|
||||||
// Hard code the roomserver to talk HTTP for now.
|
// Hard code the roomserver to talk HTTP for now.
|
||||||
|
|
@ -520,24 +523,6 @@ func (config *Dendrite) EDUServerURL() string {
|
||||||
return string(config.EDUServer.InternalAPI.Connect)
|
return string(config.EDUServer.InternalAPI.Connect)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FederationSenderURL returns an HTTP URL for where the federation sender is listening.
|
|
||||||
func (config *Dendrite) FederationSenderURL() string {
|
|
||||||
// Hard code the federation sender server to talk HTTP for now.
|
|
||||||
// If we support HTTPS we need to think of a practical way to do certificate validation.
|
|
||||||
// People setting up servers shouldn't need to get a certificate valid for the public
|
|
||||||
// internet for an internal API.
|
|
||||||
return string(config.FederationSender.InternalAPI.Connect)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SigningKeyServerURL returns an HTTP URL for where the signing key server is listening.
|
|
||||||
func (config *Dendrite) SigningKeyServerURL() string {
|
|
||||||
// Hard code the signing key server to talk HTTP for now.
|
|
||||||
// If we support HTTPS we need to think of a practical way to do certificate validation.
|
|
||||||
// People setting up servers shouldn't need to get a certificate valid for the public
|
|
||||||
// internet for an internal API.
|
|
||||||
return string(config.SigningKeyServer.InternalAPI.Connect)
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeyServerURL returns an HTTP URL for where the key server is listening.
|
// KeyServerURL returns an HTTP URL for where the key server is listening.
|
||||||
func (config *Dendrite) KeyServerURL() string {
|
func (config *Dendrite) KeyServerURL() string {
|
||||||
// Hard code the key server to talk HTTP for now.
|
// Hard code the key server to talk HTTP for now.
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,55 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
|
import "github.com/matrix-org/gomatrixserverlib"
|
||||||
|
|
||||||
type FederationAPI struct {
|
type FederationAPI struct {
|
||||||
Matrix *Global `yaml:"-"`
|
Matrix *Global `yaml:"-"`
|
||||||
|
|
||||||
InternalAPI InternalAPIOptions `yaml:"internal_api"`
|
InternalAPI InternalAPIOptions `yaml:"internal_api"`
|
||||||
ExternalAPI ExternalAPIOptions `yaml:"external_api"`
|
ExternalAPI ExternalAPIOptions `yaml:"external_api"`
|
||||||
|
|
||||||
|
// The database stores information used by the federation destination queues to
|
||||||
|
// send transactions to remote servers.
|
||||||
|
Database DatabaseOptions `yaml:"database"`
|
||||||
|
|
||||||
// List of paths to X509 certificates used by the external federation listeners.
|
// 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.
|
// 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
|
// Other matrix servers talking to this server will expect the x509 certificate
|
||||||
// to match one of these certificates.
|
// to match one of these certificates.
|
||||||
// The certificates should be in PEM format.
|
// The certificates should be in PEM format.
|
||||||
FederationCertificatePaths []Path `yaml:"federation_certificates"`
|
FederationCertificatePaths []Path `yaml:"federation_certificates"`
|
||||||
|
|
||||||
|
// 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"`
|
||||||
|
|
||||||
|
// Perspective keyservers, to use as a backup when direct key fetch
|
||||||
|
// requests don't succeed
|
||||||
|
KeyPerspectives KeyPerspectives `yaml:"key_perspectives"`
|
||||||
|
|
||||||
|
// Should we prefer direct key fetches over perspective ones?
|
||||||
|
PreferDirectFetch bool `yaml:"prefer_direct_fetch"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FederationAPI) Defaults() {
|
func (c *FederationAPI) Defaults() {
|
||||||
c.InternalAPI.Listen = "http://localhost:7772"
|
c.InternalAPI.Listen = "http://localhost:7772"
|
||||||
c.InternalAPI.Connect = "http://localhost:7772"
|
c.InternalAPI.Connect = "http://localhost:7772"
|
||||||
c.ExternalAPI.Listen = "http://[::]:8072"
|
c.ExternalAPI.Listen = "http://[::]:8072"
|
||||||
|
c.Database.Defaults(10)
|
||||||
|
c.Database.ConnectionString = "file:federationapi.db"
|
||||||
|
|
||||||
|
c.FederationMaxRetries = 16
|
||||||
|
c.DisableTLSValidation = false
|
||||||
|
|
||||||
|
c.Proxy.Defaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FederationAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
|
func (c *FederationAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
|
||||||
|
|
@ -26,6 +58,48 @@ func (c *FederationAPI) Verify(configErrs *ConfigErrors, isMonolith bool) {
|
||||||
if !isMonolith {
|
if !isMonolith {
|
||||||
checkURL(configErrs, "federation_api.external_api.listen", string(c.ExternalAPI.Listen))
|
checkURL(configErrs, "federation_api.external_api.listen", string(c.ExternalAPI.Listen))
|
||||||
}
|
}
|
||||||
|
checkNotEmpty(configErrs, "federation_api.database.connection_string", string(c.Database.ConnectionString))
|
||||||
// TODO: not applicable always, e.g. in demos
|
// TODO: not applicable always, e.g. in demos
|
||||||
//checkNotZero(configErrs, "federation_api.federation_certificates", int64(len(c.FederationCertificatePaths)))
|
//checkNotZero(configErrs, "federation_api.federation_certificates", int64(len(c.FederationCertificatePaths)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyPerspectives are used to configure perspective key servers for
|
||||||
|
// retrieving server keys.
|
||||||
|
type KeyPerspectives []KeyPerspective
|
||||||
|
|
||||||
|
type KeyPerspective struct {
|
||||||
|
// The server name of the perspective key server
|
||||||
|
ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
|
||||||
|
// Server keys for the perspective user, used to verify the
|
||||||
|
// keys have been signed by the perspective server
|
||||||
|
Keys []KeyPerspectiveTrustKey `yaml:"keys"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeyPerspectiveTrustKey struct {
|
||||||
|
// The key ID, e.g. ed25519:auto
|
||||||
|
KeyID gomatrixserverlib.KeyID `yaml:"key_id"`
|
||||||
|
// The public key in base64 unpadded format
|
||||||
|
PublicKey string `yaml:"public_key"`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
package config
|
|
||||||
|
|
||||||
type FederationSender struct {
|
|
||||||
Matrix *Global `yaml:"-"`
|
|
||||||
|
|
||||||
InternalAPI InternalAPIOptions `yaml:"internal_api"`
|
|
||||||
|
|
||||||
// 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.InternalAPI.Listen = "http://localhost:7775"
|
|
||||||
c.InternalAPI.Connect = "http://localhost:7775"
|
|
||||||
c.Database.Defaults(10)
|
|
||||||
c.Database.ConnectionString = "file:federationapi.db"
|
|
||||||
|
|
||||||
c.FederationMaxRetries = 16
|
|
||||||
c.DisableTLSValidation = false
|
|
||||||
|
|
||||||
c.Proxy.Defaults()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FederationSender) Verify(configErrs *ConfigErrors, isMonolith bool) {
|
|
||||||
checkURL(configErrs, "federation_sender.internal_api.listen", string(c.InternalAPI.Listen))
|
|
||||||
checkURL(configErrs, "federation_sender.internal_api.connect", string(c.InternalAPI.Connect))
|
|
||||||
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) {
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
package config
|
|
||||||
|
|
||||||
import "github.com/matrix-org/gomatrixserverlib"
|
|
||||||
|
|
||||||
type SigningKeyServer struct {
|
|
||||||
Matrix *Global `yaml:"-"`
|
|
||||||
|
|
||||||
InternalAPI InternalAPIOptions `yaml:"internal_api"`
|
|
||||||
|
|
||||||
// The SigningKeyServer 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"`
|
|
||||||
|
|
||||||
// Should we prefer direct key fetches over perspective ones?
|
|
||||||
PreferDirectFetch bool `yaml:"prefer_direct_fetch"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *SigningKeyServer) Defaults() {
|
|
||||||
c.InternalAPI.Listen = "http://localhost:7780"
|
|
||||||
c.InternalAPI.Connect = "http://localhost:7780"
|
|
||||||
c.Database.Defaults(10)
|
|
||||||
c.Database.ConnectionString = "file:signingkeyserver.db"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *SigningKeyServer) Verify(configErrs *ConfigErrors, isMonolith bool) {
|
|
||||||
checkURL(configErrs, "signing_key_server.internal_api.listen", string(c.InternalAPI.Listen))
|
|
||||||
checkURL(configErrs, "signing_key_server.internal_api.bind", string(c.InternalAPI.Connect))
|
|
||||||
checkNotEmpty(configErrs, "signing_key_server.database.connection_string", string(c.Database.ConnectionString))
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeyPerspectives are used to configure perspective key servers for
|
|
||||||
// retrieving server keys.
|
|
||||||
type KeyPerspectives []KeyPerspective
|
|
||||||
|
|
||||||
type KeyPerspective struct {
|
|
||||||
// The server name of the perspective key server
|
|
||||||
ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
|
|
||||||
// Server keys for the perspective user, used to verify the
|
|
||||||
// keys have been signed by the perspective server
|
|
||||||
Keys []KeyPerspectiveTrustKey `yaml:"keys"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type KeyPerspectiveTrustKey struct {
|
|
||||||
// The key ID, e.g. ed25519:auto
|
|
||||||
KeyID gomatrixserverlib.KeyID `yaml:"key_id"`
|
|
||||||
// The public key in base64 unpadded format
|
|
||||||
PublicKey string `yaml:"public_key"`
|
|
||||||
}
|
|
||||||
|
|
@ -28,7 +28,6 @@ import (
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/setup/process"
|
"github.com/matrix-org/dendrite/setup/process"
|
||||||
serverKeyAPI "github.com/matrix-org/dendrite/signingkeyserver/api"
|
|
||||||
"github.com/matrix-org/dendrite/syncapi"
|
"github.com/matrix-org/dendrite/syncapi"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
||||||
|
|
@ -48,7 +47,6 @@ type Monolith struct {
|
||||||
EDUInternalAPI eduServerAPI.EDUServerInputAPI
|
EDUInternalAPI eduServerAPI.EDUServerInputAPI
|
||||||
FederationAPI federationAPI.FederationInternalAPI
|
FederationAPI federationAPI.FederationInternalAPI
|
||||||
RoomserverAPI roomserverAPI.RoomserverInternalAPI
|
RoomserverAPI roomserverAPI.RoomserverInternalAPI
|
||||||
ServerKeyAPI serverKeyAPI.SigningKeyServerAPI
|
|
||||||
UserAPI userapi.UserInternalAPI
|
UserAPI userapi.UserInternalAPI
|
||||||
KeyAPI keyAPI.KeyInternalAPI
|
KeyAPI keyAPI.KeyInternalAPI
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SigningKeyServerAPI interface {
|
|
||||||
gomatrixserverlib.KeyDatabase
|
|
||||||
|
|
||||||
KeyRing() *gomatrixserverlib.KeyRing
|
|
||||||
|
|
||||||
InputPublicKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
request *InputPublicKeysRequest,
|
|
||||||
response *InputPublicKeysResponse,
|
|
||||||
) error
|
|
||||||
|
|
||||||
QueryPublicKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
request *QueryPublicKeysRequest,
|
|
||||||
response *QueryPublicKeysResponse,
|
|
||||||
) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryPublicKeysRequest struct {
|
|
||||||
Requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp `json:"requests"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryPublicKeysResponse struct {
|
|
||||||
Results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"results"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type InputPublicKeysRequest struct {
|
|
||||||
Keys map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"keys"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type InputPublicKeysResponse struct {
|
|
||||||
}
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
package inthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/caching"
|
|
||||||
"github.com/matrix-org/dendrite/internal/httputil"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/api"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
"github.com/opentracing/opentracing-go"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HTTP paths for the internal HTTP APIs
|
|
||||||
const (
|
|
||||||
ServerKeyInputPublicKeyPath = "/signingkeyserver/inputPublicKey"
|
|
||||||
ServerKeyQueryPublicKeyPath = "/signingkeyserver/queryPublicKey"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewSigningKeyServerClient creates a SigningKeyServerAPI implemented by talking to a HTTP POST API.
|
|
||||||
// If httpClient is nil an error is returned
|
|
||||||
func NewSigningKeyServerClient(
|
|
||||||
serverKeyAPIURL string,
|
|
||||||
httpClient *http.Client,
|
|
||||||
cache caching.ServerKeyCache,
|
|
||||||
) (api.SigningKeyServerAPI, error) {
|
|
||||||
if httpClient == nil {
|
|
||||||
return nil, errors.New("NewSigningKeyServerClient: httpClient is <nil>")
|
|
||||||
}
|
|
||||||
return &httpServerKeyInternalAPI{
|
|
||||||
serverKeyAPIURL: serverKeyAPIURL,
|
|
||||||
httpClient: httpClient,
|
|
||||||
cache: cache,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type httpServerKeyInternalAPI struct {
|
|
||||||
serverKeyAPIURL string
|
|
||||||
httpClient *http.Client
|
|
||||||
cache caching.ServerKeyCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *httpServerKeyInternalAPI) KeyRing() *gomatrixserverlib.KeyRing {
|
|
||||||
// This is a bit of a cheat - we tell gomatrixserverlib that this API is
|
|
||||||
// both the key database and the key fetcher. While this does have the
|
|
||||||
// rather unfortunate effect of preventing gomatrixserverlib from handling
|
|
||||||
// key fetchers directly, we can at least reimplement this behaviour on
|
|
||||||
// the other end of the API.
|
|
||||||
return &gomatrixserverlib.KeyRing{
|
|
||||||
KeyDatabase: s,
|
|
||||||
KeyFetchers: []gomatrixserverlib.KeyFetcher{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *httpServerKeyInternalAPI) FetcherName() string {
|
|
||||||
return "httpServerKeyInternalAPI"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *httpServerKeyInternalAPI) StoreKeys(
|
|
||||||
_ context.Context,
|
|
||||||
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
|
||||||
) error {
|
|
||||||
// Run in a background context - we don't want to stop this work just
|
|
||||||
// because the caller gives up waiting.
|
|
||||||
ctx := context.Background()
|
|
||||||
request := api.InputPublicKeysRequest{
|
|
||||||
Keys: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult),
|
|
||||||
}
|
|
||||||
response := api.InputPublicKeysResponse{}
|
|
||||||
for req, res := range results {
|
|
||||||
request.Keys[req] = res
|
|
||||||
s.cache.StoreServerKey(req, res)
|
|
||||||
}
|
|
||||||
return s.InputPublicKeys(ctx, &request, &response)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *httpServerKeyInternalAPI) FetchKeys(
|
|
||||||
_ context.Context,
|
|
||||||
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
|
||||||
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
|
|
||||||
// Run in a background context - we don't want to stop this work just
|
|
||||||
// because the caller gives up waiting.
|
|
||||||
ctx := context.Background()
|
|
||||||
result := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult)
|
|
||||||
request := api.QueryPublicKeysRequest{
|
|
||||||
Requests: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp),
|
|
||||||
}
|
|
||||||
response := api.QueryPublicKeysResponse{
|
|
||||||
Results: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult),
|
|
||||||
}
|
|
||||||
for req, ts := range requests {
|
|
||||||
if res, ok := s.cache.GetServerKey(req, ts); ok {
|
|
||||||
result[req] = res
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
request.Requests[req] = ts
|
|
||||||
}
|
|
||||||
err := s.QueryPublicKeys(ctx, &request, &response)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for req, res := range response.Results {
|
|
||||||
result[req] = res
|
|
||||||
s.cache.StoreServerKey(req, res)
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *httpServerKeyInternalAPI) InputPublicKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
request *api.InputPublicKeysRequest,
|
|
||||||
response *api.InputPublicKeysResponse,
|
|
||||||
) error {
|
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "InputPublicKey")
|
|
||||||
defer span.Finish()
|
|
||||||
|
|
||||||
apiURL := h.serverKeyAPIURL + ServerKeyInputPublicKeyPath
|
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *httpServerKeyInternalAPI) QueryPublicKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
request *api.QueryPublicKeysRequest,
|
|
||||||
response *api.QueryPublicKeysResponse,
|
|
||||||
) error {
|
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryPublicKey")
|
|
||||||
defer span.Finish()
|
|
||||||
|
|
||||||
apiURL := h.serverKeyAPIURL + ServerKeyQueryPublicKeyPath
|
|
||||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
package inthttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/matrix-org/dendrite/internal/caching"
|
|
||||||
"github.com/matrix-org/dendrite/internal/httputil"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/api"
|
|
||||||
"github.com/matrix-org/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
func AddRoutes(s api.SigningKeyServerAPI, internalAPIMux *mux.Router, cache caching.ServerKeyCache) {
|
|
||||||
internalAPIMux.Handle(ServerKeyQueryPublicKeyPath,
|
|
||||||
httputil.MakeInternalAPI("queryPublicKeys", func(req *http.Request) util.JSONResponse {
|
|
||||||
request := api.QueryPublicKeysRequest{}
|
|
||||||
response := api.QueryPublicKeysResponse{}
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
|
||||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
|
||||||
}
|
|
||||||
keys, err := s.FetchKeys(req.Context(), request.Requests)
|
|
||||||
if err != nil {
|
|
||||||
return util.ErrorResponse(err)
|
|
||||||
}
|
|
||||||
response.Results = keys
|
|
||||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
internalAPIMux.Handle(ServerKeyInputPublicKeyPath,
|
|
||||||
httputil.MakeInternalAPI("inputPublicKeys", func(req *http.Request) util.JSONResponse {
|
|
||||||
request := api.InputPublicKeysRequest{}
|
|
||||||
response := api.InputPublicKeysResponse{}
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
|
||||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
|
||||||
}
|
|
||||||
if err := s.StoreKeys(req.Context(), request.Keys); err != nil {
|
|
||||||
return util.ErrorResponse(err)
|
|
||||||
}
|
|
||||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
package signingkeyserver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ed25519"
|
|
||||||
"encoding/base64"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/matrix-org/dendrite/internal/caching"
|
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/api"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/internal"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/inthttp"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/storage"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/storage/cache"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddInternalRoutes registers HTTP handlers for the internal API. Invokes functions
|
|
||||||
// on the given input API.
|
|
||||||
func AddInternalRoutes(router *mux.Router, intAPI api.SigningKeyServerAPI, caches *caching.Caches) {
|
|
||||||
inthttp.AddRoutes(intAPI, router, caches)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.SigningKeyServer,
|
|
||||||
fedClient gomatrixserverlib.KeyClient,
|
|
||||||
caches *caching.Caches,
|
|
||||||
) api.SigningKeyServerAPI {
|
|
||||||
innerDB, err := storage.NewDatabase(
|
|
||||||
&cfg.Database,
|
|
||||||
cfg.Matrix.ServerName,
|
|
||||||
cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey),
|
|
||||||
cfg.Matrix.KeyID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
logrus.WithError(err).Panicf("failed to connect to server key database")
|
|
||||||
}
|
|
||||||
|
|
||||||
serverKeyDB, err := cache.NewKeyDatabase(innerDB, caches)
|
|
||||||
if err != nil {
|
|
||||||
logrus.WithError(err).Panicf("failed to set up caching wrapper for server key database")
|
|
||||||
}
|
|
||||||
|
|
||||||
internalAPI := internal.ServerKeyAPI{
|
|
||||||
ServerName: cfg.Matrix.ServerName,
|
|
||||||
ServerPublicKey: cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey),
|
|
||||||
ServerKeyID: cfg.Matrix.KeyID,
|
|
||||||
ServerKeyValidity: cfg.Matrix.KeyValidityPeriod,
|
|
||||||
OldServerKeys: cfg.Matrix.OldVerifyKeys,
|
|
||||||
FedClient: fedClient,
|
|
||||||
OurKeyRing: gomatrixserverlib.KeyRing{
|
|
||||||
KeyFetchers: []gomatrixserverlib.KeyFetcher{},
|
|
||||||
KeyDatabase: serverKeyDB,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
addDirectFetcher := func() {
|
|
||||||
internalAPI.OurKeyRing.KeyFetchers = append(
|
|
||||||
internalAPI.OurKeyRing.KeyFetchers,
|
|
||||||
&gomatrixserverlib.DirectKeyFetcher{
|
|
||||||
Client: fedClient,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.PreferDirectFetch {
|
|
||||||
addDirectFetcher()
|
|
||||||
} else {
|
|
||||||
defer addDirectFetcher()
|
|
||||||
}
|
|
||||||
|
|
||||||
var b64e = base64.StdEncoding.WithPadding(base64.NoPadding)
|
|
||||||
for _, ps := range cfg.KeyPerspectives {
|
|
||||||
perspective := &gomatrixserverlib.PerspectiveKeyFetcher{
|
|
||||||
PerspectiveServerName: ps.ServerName,
|
|
||||||
PerspectiveServerKeys: map[gomatrixserverlib.KeyID]ed25519.PublicKey{},
|
|
||||||
Client: fedClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, key := range ps.Keys {
|
|
||||||
rawkey, err := b64e.DecodeString(key.PublicKey)
|
|
||||||
if err != nil {
|
|
||||||
logrus.WithError(err).WithFields(logrus.Fields{
|
|
||||||
"server_name": ps.ServerName,
|
|
||||||
"public_key": key.PublicKey,
|
|
||||||
}).Warn("Couldn't parse perspective key")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
perspective.PerspectiveServerKeys[key.KeyID] = rawkey
|
|
||||||
}
|
|
||||||
|
|
||||||
internalAPI.OurKeyRing.KeyFetchers = append(
|
|
||||||
internalAPI.OurKeyRing.KeyFetchers,
|
|
||||||
perspective,
|
|
||||||
)
|
|
||||||
|
|
||||||
logrus.WithFields(logrus.Fields{
|
|
||||||
"server_name": ps.ServerName,
|
|
||||||
"num_public_keys": len(ps.Keys),
|
|
||||||
}).Info("Enabled perspective key fetcher")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &internalAPI
|
|
||||||
}
|
|
||||||
68
signingkeyserver/storage/cache/keydb.go
vendored
68
signingkeyserver/storage/cache/keydb.go
vendored
|
|
@ -1,68 +0,0 @@
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/caching"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Database implements gomatrixserverlib.KeyDatabase and is used to store
|
|
||||||
// the public keys for other matrix servers.
|
|
||||||
type KeyDatabase struct {
|
|
||||||
inner gomatrixserverlib.KeyDatabase
|
|
||||||
cache caching.ServerKeyCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewKeyDatabase(inner gomatrixserverlib.KeyDatabase, cache caching.ServerKeyCache) (*KeyDatabase, error) {
|
|
||||||
if inner == nil {
|
|
||||||
return nil, errors.New("inner database can't be nil")
|
|
||||||
}
|
|
||||||
if cache == nil {
|
|
||||||
return nil, errors.New("cache can't be nil")
|
|
||||||
}
|
|
||||||
return &KeyDatabase{
|
|
||||||
inner: inner,
|
|
||||||
cache: cache,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetcherName implements KeyFetcher
|
|
||||||
func (d KeyDatabase) FetcherName() string {
|
|
||||||
return "InMemoryKeyCache"
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchKeys implements gomatrixserverlib.KeyDatabase
|
|
||||||
func (d *KeyDatabase) FetchKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
|
||||||
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
|
|
||||||
results := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult)
|
|
||||||
for req, ts := range requests {
|
|
||||||
if res, cached := d.cache.GetServerKey(req, ts); cached {
|
|
||||||
results[req] = res
|
|
||||||
delete(requests, req)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fromDB, err := d.inner.FetchKeys(ctx, requests)
|
|
||||||
if err != nil {
|
|
||||||
return results, err
|
|
||||||
}
|
|
||||||
for req, res := range fromDB {
|
|
||||||
results[req] = res
|
|
||||||
d.cache.StoreServerKey(req, res)
|
|
||||||
}
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StoreKeys implements gomatrixserverlib.KeyDatabase
|
|
||||||
func (d *KeyDatabase) StoreKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
keyMap map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
|
||||||
) error {
|
|
||||||
for req, res := range keyMap {
|
|
||||||
d.cache.StoreServerKey(req, res)
|
|
||||||
}
|
|
||||||
return d.inner.StoreKeys(ctx, keyMap)
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Database interface {
|
|
||||||
FetcherName() string
|
|
||||||
FetchKeys(ctx context.Context, requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error)
|
|
||||||
StoreKeys(ctx context.Context, keyMap map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult) error
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
//go:build !wasm
|
|
||||||
// +build !wasm
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/ed25519"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/storage/postgres"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/storage/sqlite3"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewDatabase opens a database connection.
|
|
||||||
func NewDatabase(
|
|
||||||
dbProperties *config.DatabaseOptions,
|
|
||||||
serverName gomatrixserverlib.ServerName,
|
|
||||||
serverKey ed25519.PublicKey,
|
|
||||||
serverKeyID gomatrixserverlib.KeyID,
|
|
||||||
) (Database, error) {
|
|
||||||
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 nil, fmt.Errorf("unexpected database type")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
//go:build wasm
|
|
||||||
// +build wasm
|
|
||||||
|
|
||||||
package storage
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/ed25519"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
|
||||||
"github.com/matrix-org/dendrite/signingkeyserver/storage/sqlite3"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewDatabase opens a database connection.
|
|
||||||
func NewDatabase(
|
|
||||||
dataSourceName string,
|
|
||||||
dbProperties sqlutil.DbProperties, // nolint:unparam
|
|
||||||
serverName gomatrixserverlib.ServerName,
|
|
||||||
serverKey ed25519.PublicKey,
|
|
||||||
serverKeyID gomatrixserverlib.KeyID,
|
|
||||||
) (Database, error) {
|
|
||||||
uri, err := url.Parse(dataSourceName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch uri.Scheme {
|
|
||||||
case "postgres":
|
|
||||||
return nil, fmt.Errorf("Cannot use postgres implementation")
|
|
||||||
case "file":
|
|
||||||
return sqlite3.NewDatabase(dataSourceName, serverName, serverKey, serverKeyID)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("Cannot use postgres implementation")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
// Copyright 2017-2018 New Vector Ltd
|
|
||||||
// Copyright 2019-2020 The Matrix.org Foundation C.I.C.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/ed25519"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Database implements gomatrixserverlib.KeyDatabase and is used to store
|
|
||||||
// the public keys for other matrix servers.
|
|
||||||
type Database struct {
|
|
||||||
statements serverKeyStatements
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDatabase prepares a new key database.
|
|
||||||
// It creates the necessary tables if they don't already exist.
|
|
||||||
// It prepares all the SQL statements that it will use.
|
|
||||||
// Returns an error if there was a problem talking to the database.
|
|
||||||
func NewDatabase(
|
|
||||||
dbProperties *config.DatabaseOptions,
|
|
||||||
serverName gomatrixserverlib.ServerName,
|
|
||||||
serverKey ed25519.PublicKey,
|
|
||||||
serverKeyID gomatrixserverlib.KeyID,
|
|
||||||
) (*Database, error) {
|
|
||||||
db, err := sqlutil.Open(dbProperties)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
d := &Database{}
|
|
||||||
err = d.statements.prepare(db)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return d, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetcherName implements KeyFetcher
|
|
||||||
func (d Database) FetcherName() string {
|
|
||||||
return "PostgresKeyDatabase"
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchKeys implements gomatrixserverlib.KeyDatabase
|
|
||||||
func (d *Database) FetchKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
|
||||||
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
|
|
||||||
return d.statements.bulkSelectServerKeys(ctx, requests)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StoreKeys implements gomatrixserverlib.KeyDatabase
|
|
||||||
func (d *Database) StoreKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
keyMap map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
|
||||||
) error {
|
|
||||||
// TODO: Inserting all the keys within a single transaction may
|
|
||||||
// be more efficient since the transaction overhead can be quite
|
|
||||||
// high for a single insert statement.
|
|
||||||
var lastErr error
|
|
||||||
for request, keys := range keyMap {
|
|
||||||
if err := d.statements.upsertServerKeys(ctx, request, keys); err != nil {
|
|
||||||
// Rather than returning immediately on error we try to insert the
|
|
||||||
// remaining keys.
|
|
||||||
// Since we are inserting the keys outside of a transaction it is
|
|
||||||
// possible for some of the inserts to succeed even though some
|
|
||||||
// of the inserts have failed.
|
|
||||||
// Ensuring that we always insert all the keys we can means that
|
|
||||||
// this behaviour won't depend on the iteration order of the map.
|
|
||||||
lastErr = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lastErr
|
|
||||||
}
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
// Copyright 2017-2018 New Vector Ltd
|
|
||||||
// Copyright 2019-2020 The Matrix.org Foundation C.I.C.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package postgres
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
|
|
||||||
"github.com/lib/pq"
|
|
||||||
"github.com/matrix-org/dendrite/internal"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
const serverKeysSchema = `
|
|
||||||
-- A cache of signing keys downloaded from remote servers.
|
|
||||||
CREATE TABLE IF NOT EXISTS keydb_server_keys (
|
|
||||||
-- The name of the matrix server the key is for.
|
|
||||||
server_name TEXT NOT NULL,
|
|
||||||
-- The ID of the server key.
|
|
||||||
server_key_id TEXT NOT NULL,
|
|
||||||
-- Combined server name and key ID separated by the ASCII unit separator
|
|
||||||
-- to make it easier to run bulk queries.
|
|
||||||
server_name_and_key_id TEXT NOT NULL,
|
|
||||||
-- When the key is valid until as a millisecond timestamp.
|
|
||||||
-- 0 if this is an expired key (in which case expired_ts will be non-zero)
|
|
||||||
valid_until_ts BIGINT NOT NULL,
|
|
||||||
-- When the key expired as a millisecond timestamp.
|
|
||||||
-- 0 if this is an active key (in which case valid_until_ts will be non-zero)
|
|
||||||
expired_ts BIGINT NOT NULL,
|
|
||||||
-- The base64-encoded public key.
|
|
||||||
server_key TEXT NOT NULL,
|
|
||||||
CONSTRAINT keydb_server_keys_unique UNIQUE (server_name, server_key_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS keydb_server_name_and_key_id ON keydb_server_keys (server_name_and_key_id);
|
|
||||||
`
|
|
||||||
|
|
||||||
const bulkSelectServerKeysSQL = "" +
|
|
||||||
"SELECT server_name, server_key_id, valid_until_ts, expired_ts, " +
|
|
||||||
" server_key FROM keydb_server_keys" +
|
|
||||||
" WHERE server_name_and_key_id = ANY($1)"
|
|
||||||
|
|
||||||
const upsertServerKeysSQL = "" +
|
|
||||||
"INSERT INTO keydb_server_keys (server_name, server_key_id," +
|
|
||||||
" server_name_and_key_id, valid_until_ts, expired_ts, server_key)" +
|
|
||||||
" VALUES ($1, $2, $3, $4, $5, $6)" +
|
|
||||||
" ON CONFLICT ON CONSTRAINT keydb_server_keys_unique" +
|
|
||||||
" DO UPDATE SET valid_until_ts = $4, expired_ts = $5, server_key = $6"
|
|
||||||
|
|
||||||
type serverKeyStatements struct {
|
|
||||||
bulkSelectServerKeysStmt *sql.Stmt
|
|
||||||
upsertServerKeysStmt *sql.Stmt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *serverKeyStatements) prepare(db *sql.DB) (err error) {
|
|
||||||
_, err = db.Exec(serverKeysSchema)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if s.bulkSelectServerKeysStmt, err = db.Prepare(bulkSelectServerKeysSQL); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if s.upsertServerKeysStmt, err = db.Prepare(upsertServerKeysSQL); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *serverKeyStatements) bulkSelectServerKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
|
||||||
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
|
|
||||||
var nameAndKeyIDs []string
|
|
||||||
for request := range requests {
|
|
||||||
nameAndKeyIDs = append(nameAndKeyIDs, nameAndKeyID(request))
|
|
||||||
}
|
|
||||||
stmt := s.bulkSelectServerKeysStmt
|
|
||||||
rows, err := stmt.QueryContext(ctx, pq.StringArray(nameAndKeyIDs))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer internal.CloseAndLogIfError(ctx, rows, "bulkSelectServerKeys: rows.close() failed")
|
|
||||||
results := map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult{}
|
|
||||||
for rows.Next() {
|
|
||||||
var serverName string
|
|
||||||
var keyID string
|
|
||||||
var key string
|
|
||||||
var validUntilTS int64
|
|
||||||
var expiredTS int64
|
|
||||||
if err = rows.Scan(&serverName, &keyID, &validUntilTS, &expiredTS, &key); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
r := gomatrixserverlib.PublicKeyLookupRequest{
|
|
||||||
ServerName: gomatrixserverlib.ServerName(serverName),
|
|
||||||
KeyID: gomatrixserverlib.KeyID(keyID),
|
|
||||||
}
|
|
||||||
vk := gomatrixserverlib.VerifyKey{}
|
|
||||||
err = vk.Key.Decode(key)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
results[r] = gomatrixserverlib.PublicKeyLookupResult{
|
|
||||||
VerifyKey: vk,
|
|
||||||
ValidUntilTS: gomatrixserverlib.Timestamp(validUntilTS),
|
|
||||||
ExpiredTS: gomatrixserverlib.Timestamp(expiredTS),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results, rows.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *serverKeyStatements) upsertServerKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
request gomatrixserverlib.PublicKeyLookupRequest,
|
|
||||||
key gomatrixserverlib.PublicKeyLookupResult,
|
|
||||||
) error {
|
|
||||||
_, err := s.upsertServerKeysStmt.ExecContext(
|
|
||||||
ctx,
|
|
||||||
string(request.ServerName),
|
|
||||||
string(request.KeyID),
|
|
||||||
nameAndKeyID(request),
|
|
||||||
key.ValidUntilTS,
|
|
||||||
key.ExpiredTS,
|
|
||||||
key.Key.Encode(),
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func nameAndKeyID(request gomatrixserverlib.PublicKeyLookupRequest) string {
|
|
||||||
return string(request.ServerName) + "\x1F" + string(request.KeyID)
|
|
||||||
}
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
// Copyright 2017-2018 New Vector Ltd
|
|
||||||
// Copyright 2019-2020 The Matrix.org Foundation C.I.C.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package sqlite3
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/ed25519"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Database implements gomatrixserverlib.KeyDatabase and is used to store
|
|
||||||
// the public keys for other matrix servers.
|
|
||||||
type Database struct {
|
|
||||||
writer sqlutil.Writer
|
|
||||||
statements serverKeyStatements
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDatabase prepares a new key database.
|
|
||||||
// It creates the necessary tables if they don't already exist.
|
|
||||||
// It prepares all the SQL statements that it will use.
|
|
||||||
// Returns an error if there was a problem talking to the database.
|
|
||||||
func NewDatabase(
|
|
||||||
dbProperties *config.DatabaseOptions,
|
|
||||||
serverName gomatrixserverlib.ServerName,
|
|
||||||
serverKey ed25519.PublicKey,
|
|
||||||
serverKeyID gomatrixserverlib.KeyID,
|
|
||||||
) (*Database, error) {
|
|
||||||
db, err := sqlutil.Open(dbProperties)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
d := &Database{
|
|
||||||
writer: sqlutil.NewExclusiveWriter(),
|
|
||||||
}
|
|
||||||
err = d.statements.prepare(db, d.writer)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return d, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetcherName implements KeyFetcher
|
|
||||||
func (d Database) FetcherName() string {
|
|
||||||
return "SqliteKeyDatabase"
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchKeys implements gomatrixserverlib.KeyDatabase
|
|
||||||
func (d *Database) FetchKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
|
||||||
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
|
|
||||||
return d.statements.bulkSelectServerKeys(ctx, requests)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StoreKeys implements gomatrixserverlib.KeyDatabase
|
|
||||||
func (d *Database) StoreKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
keyMap map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
|
||||||
) error {
|
|
||||||
// TODO: Inserting all the keys within a single transaction may
|
|
||||||
// be more efficient since the transaction overhead can be quite
|
|
||||||
// high for a single insert statement.
|
|
||||||
var lastErr error
|
|
||||||
for request, keys := range keyMap {
|
|
||||||
if err := d.statements.upsertServerKeys(ctx, request, keys); err != nil {
|
|
||||||
// Rather than returning immediately on error we try to insert the
|
|
||||||
// remaining keys.
|
|
||||||
// Since we are inserting the keys outside of a transaction it is
|
|
||||||
// possible for some of the inserts to succeed even though some
|
|
||||||
// of the inserts have failed.
|
|
||||||
// Ensuring that we always insert all the keys we can means that
|
|
||||||
// this behaviour won't depend on the iteration order of the map.
|
|
||||||
lastErr = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lastErr
|
|
||||||
}
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
// Copyright 2017-2018 New Vector Ltd
|
|
||||||
// Copyright 2019-2020 The Matrix.org Foundation C.I.C.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package sqlite3
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
|
||||||
|
|
||||||
const serverKeysSchema = `
|
|
||||||
-- A cache of signing keys downloaded from remote servers.
|
|
||||||
CREATE TABLE IF NOT EXISTS keydb_server_keys (
|
|
||||||
-- The name of the matrix server the key is for.
|
|
||||||
server_name TEXT NOT NULL,
|
|
||||||
-- The ID of the server key.
|
|
||||||
server_key_id TEXT NOT NULL,
|
|
||||||
-- Combined server name and key ID separated by the ASCII unit separator
|
|
||||||
-- to make it easier to run bulk queries.
|
|
||||||
server_name_and_key_id TEXT NOT NULL,
|
|
||||||
-- When the key is valid until as a millisecond timestamp.
|
|
||||||
-- 0 if this is an expired key (in which case expired_ts will be non-zero)
|
|
||||||
valid_until_ts BIGINT NOT NULL,
|
|
||||||
-- When the key expired as a millisecond timestamp.
|
|
||||||
-- 0 if this is an active key (in which case valid_until_ts will be non-zero)
|
|
||||||
expired_ts BIGINT NOT NULL,
|
|
||||||
-- The base64-encoded public key.
|
|
||||||
server_key TEXT NOT NULL,
|
|
||||||
UNIQUE (server_name, server_key_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS keydb_server_name_and_key_id ON keydb_server_keys (server_name_and_key_id);
|
|
||||||
`
|
|
||||||
|
|
||||||
const bulkSelectServerKeysSQL = "" +
|
|
||||||
"SELECT server_name, server_key_id, valid_until_ts, expired_ts, " +
|
|
||||||
" server_key FROM keydb_server_keys" +
|
|
||||||
" WHERE server_name_and_key_id IN ($1)"
|
|
||||||
|
|
||||||
const upsertServerKeysSQL = "" +
|
|
||||||
"INSERT INTO keydb_server_keys (server_name, server_key_id," +
|
|
||||||
" server_name_and_key_id, valid_until_ts, expired_ts, server_key)" +
|
|
||||||
" VALUES ($1, $2, $3, $4, $5, $6)" +
|
|
||||||
" ON CONFLICT (server_name, server_key_id)" +
|
|
||||||
" DO UPDATE SET valid_until_ts = $4, expired_ts = $5, server_key = $6"
|
|
||||||
|
|
||||||
type serverKeyStatements struct {
|
|
||||||
db *sql.DB
|
|
||||||
writer sqlutil.Writer
|
|
||||||
bulkSelectServerKeysStmt *sql.Stmt
|
|
||||||
upsertServerKeysStmt *sql.Stmt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *serverKeyStatements) prepare(db *sql.DB, writer sqlutil.Writer) (err error) {
|
|
||||||
s.db = db
|
|
||||||
s.writer = writer
|
|
||||||
_, err = db.Exec(serverKeysSchema)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if s.bulkSelectServerKeysStmt, err = db.Prepare(bulkSelectServerKeysSQL); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if s.upsertServerKeysStmt, err = db.Prepare(upsertServerKeysSQL); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *serverKeyStatements) bulkSelectServerKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
|
||||||
) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
|
|
||||||
nameAndKeyIDs := make([]string, 0, len(requests))
|
|
||||||
for request := range requests {
|
|
||||||
nameAndKeyIDs = append(nameAndKeyIDs, nameAndKeyID(request))
|
|
||||||
}
|
|
||||||
results := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, len(requests))
|
|
||||||
iKeyIDs := make([]interface{}, len(nameAndKeyIDs))
|
|
||||||
for i, v := range nameAndKeyIDs {
|
|
||||||
iKeyIDs[i] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
err := sqlutil.RunLimitedVariablesQuery(
|
|
||||||
ctx, bulkSelectServerKeysSQL, s.db, iKeyIDs, sqlutil.SQLite3MaxVariables,
|
|
||||||
func(rows *sql.Rows) error {
|
|
||||||
for rows.Next() {
|
|
||||||
var serverName string
|
|
||||||
var keyID string
|
|
||||||
var key string
|
|
||||||
var validUntilTS int64
|
|
||||||
var expiredTS int64
|
|
||||||
if err := rows.Scan(&serverName, &keyID, &validUntilTS, &expiredTS, &key); err != nil {
|
|
||||||
return fmt.Errorf("bulkSelectServerKeys: %v", err)
|
|
||||||
}
|
|
||||||
r := gomatrixserverlib.PublicKeyLookupRequest{
|
|
||||||
ServerName: gomatrixserverlib.ServerName(serverName),
|
|
||||||
KeyID: gomatrixserverlib.KeyID(keyID),
|
|
||||||
}
|
|
||||||
vk := gomatrixserverlib.VerifyKey{}
|
|
||||||
err := vk.Key.Decode(key)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("bulkSelectServerKeys: %v", err)
|
|
||||||
}
|
|
||||||
results[r] = gomatrixserverlib.PublicKeyLookupResult{
|
|
||||||
VerifyKey: vk,
|
|
||||||
ValidUntilTS: gomatrixserverlib.Timestamp(validUntilTS),
|
|
||||||
ExpiredTS: gomatrixserverlib.Timestamp(expiredTS),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *serverKeyStatements) upsertServerKeys(
|
|
||||||
ctx context.Context,
|
|
||||||
request gomatrixserverlib.PublicKeyLookupRequest,
|
|
||||||
key gomatrixserverlib.PublicKeyLookupResult,
|
|
||||||
) error {
|
|
||||||
return s.writer.Do(s.db, nil, func(txn *sql.Tx) error {
|
|
||||||
stmt := sqlutil.TxStmt(txn, s.upsertServerKeysStmt)
|
|
||||||
_, err := stmt.ExecContext(
|
|
||||||
ctx,
|
|
||||||
string(request.ServerName),
|
|
||||||
string(request.KeyID),
|
|
||||||
nameAndKeyID(request),
|
|
||||||
key.ValidUntilTS,
|
|
||||||
key.ExpiredTS,
|
|
||||||
key.Key.Encode(),
|
|
||||||
)
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func nameAndKeyID(request gomatrixserverlib.PublicKeyLookupRequest) string {
|
|
||||||
return string(request.ServerName) + "\x1F" + string(request.KeyID)
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue