This commit is contained in:
Till 2025-08-15 15:40:10 +02:00 committed by GitHub
commit af6fcc10e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 25 additions and 77 deletions

View file

@ -46,14 +46,14 @@ func (a *FederationInternalAPI) fetchServerKeysFromCache(
// We got a request for _all_ server keys, return them. // We got a request for _all_ server keys, return them.
if len(req.KeyIDToCriteria) == 0 { if len(req.KeyIDToCriteria) == 0 {
serverKeysResponses, _ := a.db.GetNotaryKeys(ctx, req.ServerName, []gomatrixserverlib.KeyID{}) serverKeysResponses, _ := a.db.GetNotaryKeys(ctx, req.ServerName)
if len(serverKeysResponses) == 0 { if len(serverKeysResponses) == 0 {
return nil, fmt.Errorf("failed to find server key response for server %s", req.ServerName) return nil, fmt.Errorf("failed to find server key response for server %s", req.ServerName)
} }
return serverKeysResponses, nil return serverKeysResponses, nil
} }
for keyID, criteria := range req.KeyIDToCriteria { for keyID, criteria := range req.KeyIDToCriteria {
serverKeysResponses, _ := a.db.GetNotaryKeys(ctx, req.ServerName, []gomatrixserverlib.KeyID{keyID}) serverKeysResponses, _ := a.db.GetNotaryKeys(ctx, req.ServerName)
if len(serverKeysResponses) == 0 { if len(serverKeysResponses) == 0 {
return nil, fmt.Errorf("failed to find server key response for key ID %s", keyID) return nil, fmt.Errorf("failed to find server key response for key ID %s", keyID)
} }
@ -90,7 +90,7 @@ func (a *FederationInternalAPI) QueryServerKeys(
if err != nil { if err != nil {
// try to load as much as we can from the cache in a best effort basis // try to load as much as we can from the cache in a best effort basis
util.GetLogger(ctx).WithField("server", req.ServerName).WithError(err).Warn("notary: failed to ask server for keys, returning best effort keys") util.GetLogger(ctx).WithField("server", req.ServerName).WithError(err).Warn("notary: failed to ask server for keys, returning best effort keys")
serverKeysResponses, dbErr := a.db.GetNotaryKeys(ctx, req.ServerName, req.KeyIDs()) serverKeysResponses, dbErr := a.db.GetNotaryKeys(ctx, req.ServerName)
if dbErr != nil { if dbErr != nil {
return fmt.Errorf("notary: server returned %s, and db returned %s", err, dbErr) return fmt.Errorf("notary: server returned %s, and db returned %s", err, dbErr)
} }

View file

@ -77,10 +77,6 @@ func Setup(
FsAPI: fsAPI, FsAPI: fsAPI,
} }
localKeys := httputil.MakeExternalAPI("localkeys", func(req *http.Request) util.JSONResponse {
return LocalKeys(cfg, spec.ServerName(req.Host))
})
notaryKeys := httputil.MakeExternalAPI("notarykeys", func(req *http.Request) util.JSONResponse { notaryKeys := httputil.MakeExternalAPI("notarykeys", func(req *http.Request) util.JSONResponse {
vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil { if err != nil {
@ -88,13 +84,10 @@ func Setup(
} }
var pkReq *gomatrixserverlib.PublicKeyNotaryLookupRequest var pkReq *gomatrixserverlib.PublicKeyNotaryLookupRequest
serverName := spec.ServerName(vars["serverName"]) serverName := spec.ServerName(vars["serverName"])
keyID := gomatrixserverlib.KeyID(vars["keyID"]) if serverName != "" {
if serverName != "" && keyID != "" {
pkReq = &gomatrixserverlib.PublicKeyNotaryLookupRequest{ pkReq = &gomatrixserverlib.PublicKeyNotaryLookupRequest{
ServerKeys: map[spec.ServerName]map[gomatrixserverlib.KeyID]gomatrixserverlib.PublicKeyNotaryQueryCriteria{ ServerKeys: map[spec.ServerName]map[gomatrixserverlib.KeyID]gomatrixserverlib.PublicKeyNotaryQueryCriteria{
serverName: { serverName: {},
keyID: gomatrixserverlib.PublicKeyNotaryQueryCriteria{},
},
}, },
} }
} }
@ -120,11 +113,11 @@ func Setup(
// return that key. // return that key.
// Even if we had more than one server key, we would probably still ignore the // Even if we had more than one server key, we would probably still ignore the
// {keyID} argument and always return a response containing all of the keys. // {keyID} argument and always return a response containing all of the keys.
v2keysmux.Handle("/server/{keyID}", localKeys).Methods(http.MethodGet) v2keysmux.Handle("/server", httputil.MakeExternalAPI("localkeys", func(req *http.Request) util.JSONResponse {
v2keysmux.Handle("/server/", localKeys).Methods(http.MethodGet) return LocalKeys(cfg, spec.ServerName(req.Host))
v2keysmux.Handle("/server", localKeys).Methods(http.MethodGet) })).Methods(http.MethodGet)
v2keysmux.Handle("/query", notaryKeys).Methods(http.MethodPost) v2keysmux.Handle("/query", notaryKeys).Methods(http.MethodPost)
v2keysmux.Handle("/query/{serverName}/{keyID}", notaryKeys).Methods(http.MethodGet) v2keysmux.Handle("/query/{serverName}", notaryKeys).Methods(http.MethodGet)
mu := internal.NewMutexByRoom() mu := internal.NewMutexByRoom()
v1fedmux.Handle("/send/{txnID}", MakeFedAPI( v1fedmux.Handle("/send/{txnID}", MakeFedAPI(

View file

@ -73,9 +73,8 @@ type Database interface {
// Update the notary with the given server keys from the given server name. // Update the notary with the given server keys from the given server name.
UpdateNotaryKeys(ctx context.Context, serverName spec.ServerName, serverKeys gomatrixserverlib.ServerKeys) error UpdateNotaryKeys(ctx context.Context, serverName spec.ServerName, serverKeys gomatrixserverlib.ServerKeys) error
// Query the notary for the server keys for the given server. If `optKeyIDs` is not empty, multiple server keys may be returned (between 1 - len(optKeyIDs)) // Query the notary for the server keys for the given server.
// such that the combination of all server keys will include all the `optKeyIDs`. GetNotaryKeys(ctx context.Context, serverName spec.ServerName) ([]gomatrixserverlib.ServerKeys, error)
GetNotaryKeys(ctx context.Context, serverName spec.ServerName, optKeyIDs []gomatrixserverlib.KeyID) ([]gomatrixserverlib.ServerKeys, error)
// DeleteExpiredEDUs cleans up expired EDUs // DeleteExpiredEDUs cleans up expired EDUs
DeleteExpiredEDUs(ctx context.Context) error DeleteExpiredEDUs(ctx context.Context) error

View file

@ -14,7 +14,6 @@ import (
"github.com/element-hq/dendrite/federationapi/storage/tables" "github.com/element-hq/dendrite/federationapi/storage/tables"
"github.com/element-hq/dendrite/internal" "github.com/element-hq/dendrite/internal"
"github.com/element-hq/dendrite/internal/sqlutil" "github.com/element-hq/dendrite/internal/sqlutil"
"github.com/lib/pq"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/gomatrixserverlib/spec"
) )
@ -50,16 +49,6 @@ const selectNotaryKeyResponsesSQL = `
) )
` `
// select the responses which have the given key IDs
// JOINs with the json table
const selectNotaryKeyResponsesWithKeyIDsSQL = `
SELECT response_json FROM federationsender_notary_server_keys_json
JOIN federationsender_notary_server_keys_metadata ON
federationsender_notary_server_keys_metadata.notary_id = federationsender_notary_server_keys_json.notary_id
WHERE federationsender_notary_server_keys_json.server_name = $1 AND federationsender_notary_server_keys_metadata.key_id = ANY ($2)
GROUP BY federationsender_notary_server_keys_json.notary_id
`
// JOINs with the metadata table // JOINs with the metadata table
const deleteUnusedServerKeysJSONSQL = ` const deleteUnusedServerKeysJSONSQL = `
DELETE FROM federationsender_notary_server_keys_json WHERE federationsender_notary_server_keys_json.notary_id NOT IN ( DELETE FROM federationsender_notary_server_keys_json WHERE federationsender_notary_server_keys_json.notary_id NOT IN (
@ -68,12 +57,11 @@ const deleteUnusedServerKeysJSONSQL = `
` `
type notaryServerKeysMetadataStatements struct { type notaryServerKeysMetadataStatements struct {
db *sql.DB db *sql.DB
upsertServerKeysStmt *sql.Stmt upsertServerKeysStmt *sql.Stmt
selectNotaryKeyResponsesStmt *sql.Stmt selectNotaryKeyResponsesStmt *sql.Stmt
selectNotaryKeyResponsesWithKeyIDsStmt *sql.Stmt selectNotaryKeyMetadataStmt *sql.Stmt
selectNotaryKeyMetadataStmt *sql.Stmt deleteUnusedServerKeysJSONStmt *sql.Stmt
deleteUnusedServerKeysJSONStmt *sql.Stmt
} }
func NewPostgresNotaryServerKeysMetadataTable(db *sql.DB) (s *notaryServerKeysMetadataStatements, err error) { func NewPostgresNotaryServerKeysMetadataTable(db *sql.DB) (s *notaryServerKeysMetadataStatements, err error) {
@ -88,7 +76,6 @@ func NewPostgresNotaryServerKeysMetadataTable(db *sql.DB) (s *notaryServerKeysMe
return s, sqlutil.StatementList{ return s, sqlutil.StatementList{
{&s.upsertServerKeysStmt, upsertServerKeysSQL}, {&s.upsertServerKeysStmt, upsertServerKeysSQL},
{&s.selectNotaryKeyResponsesStmt, selectNotaryKeyResponsesSQL}, {&s.selectNotaryKeyResponsesStmt, selectNotaryKeyResponsesSQL},
{&s.selectNotaryKeyResponsesWithKeyIDsStmt, selectNotaryKeyResponsesWithKeyIDsSQL},
{&s.selectNotaryKeyMetadataStmt, selectNotaryKeyMetadataSQL}, {&s.selectNotaryKeyMetadataStmt, selectNotaryKeyMetadataSQL},
{&s.deleteUnusedServerKeysJSONStmt, deleteUnusedServerKeysJSONSQL}, {&s.deleteUnusedServerKeysJSONStmt, deleteUnusedServerKeysJSONSQL},
}.Prepare(db) }.Prepare(db)
@ -115,18 +102,11 @@ func (s *notaryServerKeysMetadataStatements) UpsertKey(
return notaryID, err return notaryID, err
} }
func (s *notaryServerKeysMetadataStatements) SelectKeys(ctx context.Context, txn *sql.Tx, serverName spec.ServerName, keyIDs []gomatrixserverlib.KeyID) ([]gomatrixserverlib.ServerKeys, error) { func (s *notaryServerKeysMetadataStatements) SelectKeys(ctx context.Context, txn *sql.Tx, serverName spec.ServerName) ([]gomatrixserverlib.ServerKeys, error) {
var rows *sql.Rows var rows *sql.Rows
var err error var err error
if len(keyIDs) == 0 {
rows, err = txn.Stmt(s.selectNotaryKeyResponsesStmt).QueryContext(ctx, string(serverName)) rows, err = txn.Stmt(s.selectNotaryKeyResponsesStmt).QueryContext(ctx, string(serverName))
} else {
keyIDstr := make([]string, len(keyIDs))
for i := range keyIDs {
keyIDstr[i] = string(keyIDs[i])
}
rows, err = txn.Stmt(s.selectNotaryKeyResponsesWithKeyIDsStmt).QueryContext(ctx, string(serverName), pq.StringArray(keyIDstr))
}
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -358,10 +358,9 @@ func (d *Database) UpdateNotaryKeys(
func (d *Database) GetNotaryKeys( func (d *Database) GetNotaryKeys(
ctx context.Context, ctx context.Context,
serverName spec.ServerName, serverName spec.ServerName,
optKeyIDs []gomatrixserverlib.KeyID,
) (sks []gomatrixserverlib.ServerKeys, err error) { ) (sks []gomatrixserverlib.ServerKeys, err error) {
err = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error { err = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
sks, err = d.NotaryServerKeysMetadata.SelectKeys(ctx, txn, serverName, optKeyIDs) sks, err = d.NotaryServerKeysMetadata.SelectKeys(ctx, txn, serverName)
return err return err
}) })
return sks, err return sks, err

View file

@ -10,8 +10,6 @@ import (
"context" "context"
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt"
"strings"
"github.com/element-hq/dendrite/federationapi/storage/tables" "github.com/element-hq/dendrite/federationapi/storage/tables"
"github.com/element-hq/dendrite/internal" "github.com/element-hq/dendrite/internal"
@ -51,16 +49,6 @@ const selectNotaryKeyResponsesSQL = `
) )
` `
// select the responses which have the given key IDs
// JOINs with the json table
const selectNotaryKeyResponsesWithKeyIDsSQL = `
SELECT response_json FROM federationsender_notary_server_keys_json
JOIN federationsender_notary_server_keys_metadata ON
federationsender_notary_server_keys_metadata.notary_id = federationsender_notary_server_keys_json.notary_id
WHERE federationsender_notary_server_keys_json.server_name = $1 AND federationsender_notary_server_keys_metadata.key_id IN ($2)
GROUP BY federationsender_notary_server_keys_json.notary_id
`
// JOINs with the metadata table // JOINs with the metadata table
const deleteUnusedServerKeysJSONSQL = ` const deleteUnusedServerKeysJSONSQL = `
DELETE FROM federationsender_notary_server_keys_json WHERE federationsender_notary_server_keys_json.notary_id NOT IN ( DELETE FROM federationsender_notary_server_keys_json WHERE federationsender_notary_server_keys_json.notary_id NOT IN (
@ -114,22 +102,11 @@ func (s *notaryServerKeysMetadataStatements) UpsertKey(
return notaryID, err return notaryID, err
} }
func (s *notaryServerKeysMetadataStatements) SelectKeys(ctx context.Context, txn *sql.Tx, serverName spec.ServerName, keyIDs []gomatrixserverlib.KeyID) ([]gomatrixserverlib.ServerKeys, error) { func (s *notaryServerKeysMetadataStatements) SelectKeys(ctx context.Context, txn *sql.Tx, serverName spec.ServerName) ([]gomatrixserverlib.ServerKeys, error) {
var rows *sql.Rows var rows *sql.Rows
var err error var err error
if len(keyIDs) == 0 {
rows, err = txn.Stmt(s.selectNotaryKeyResponsesStmt).QueryContext(ctx, string(serverName)) rows, err = txn.Stmt(s.selectNotaryKeyResponsesStmt).QueryContext(ctx, string(serverName))
} else {
iKeyIDs := make([]interface{}, len(keyIDs)+1)
iKeyIDs[0] = serverName
for i := range keyIDs {
iKeyIDs[i+1] = string(keyIDs[i])
}
sql := strings.Replace(selectNotaryKeyResponsesWithKeyIDsSQL, "($2)", sqlutil.QueryVariadicOffset(len(keyIDs), 1), 1)
fmt.Println(sql)
fmt.Println(iKeyIDs...)
rows, err = s.db.QueryContext(ctx, sql, iKeyIDs...)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -121,7 +121,7 @@ type FederationNotaryServerKeysMetadata interface {
UpsertKey(ctx context.Context, txn *sql.Tx, serverName spec.ServerName, keyID gomatrixserverlib.KeyID, newNotaryID NotaryID, newValidUntil spec.Timestamp) (NotaryID, error) UpsertKey(ctx context.Context, txn *sql.Tx, serverName spec.ServerName, keyID gomatrixserverlib.KeyID, newNotaryID NotaryID, newValidUntil spec.Timestamp) (NotaryID, error)
// SelectKeys returns the signed JSON objects which contain the given key IDs. This will be at most the length of `keyIDs` and at least 1 (assuming // SelectKeys returns the signed JSON objects which contain the given key IDs. This will be at most the length of `keyIDs` and at least 1 (assuming
// the keys exist in the first place). If `keyIDs` is empty, the signed JSON object with the longest valid_until_ts will be returned. // the keys exist in the first place). If `keyIDs` is empty, the signed JSON object with the longest valid_until_ts will be returned.
SelectKeys(ctx context.Context, txn *sql.Tx, serverName spec.ServerName, keyIDs []gomatrixserverlib.KeyID) ([]gomatrixserverlib.ServerKeys, error) SelectKeys(ctx context.Context, txn *sql.Tx, serverName spec.ServerName) ([]gomatrixserverlib.ServerKeys, error)
// DeleteOldJSONResponses removes all responses which are not referenced in FederationNotaryServerKeysMetadata // DeleteOldJSONResponses removes all responses which are not referenced in FederationNotaryServerKeysMetadata
DeleteOldJSONResponses(ctx context.Context, txn *sql.Tx) error DeleteOldJSONResponses(ctx context.Context, txn *sql.Tx) error
} }

View file

@ -492,7 +492,7 @@ func (d *InMemoryFederationDatabase) UpdateNotaryKeys(ctx context.Context, serve
return nil return nil
} }
func (d *InMemoryFederationDatabase) GetNotaryKeys(ctx context.Context, serverName spec.ServerName, optKeyIDs []gomatrixserverlib.KeyID) ([]gomatrixserverlib.ServerKeys, error) { func (d *InMemoryFederationDatabase) GetNotaryKeys(ctx context.Context, serverName spec.ServerName) ([]gomatrixserverlib.ServerKeys, error) {
return nil, nil return nil, nil
} }