mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-09 15:13:12 -06:00
Merge branch 'main' of github.com:matrix-org/dendrite into s7evink/userdirectory
This commit is contained in:
commit
00ba67d825
2
.github/workflows/dendrite.yml
vendored
2
.github/workflows/dendrite.yml
vendored
|
|
@ -67,7 +67,7 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
|
||||
# run go test with different go versions
|
||||
test:
|
||||
|
|
|
|||
59
README.md
59
README.md
|
|
@ -21,8 +21,7 @@ As of October 2020 (current [progress below](#progress)), Dendrite has now enter
|
|||
This does not mean:
|
||||
|
||||
- Dendrite is bug-free. It has not yet been battle-tested in the real world and so will be error prone initially.
|
||||
- All of the CS/Federation APIs are implemented. We are tracking progress via a script called 'Are We Synapse Yet?'. In particular,
|
||||
presence and push notifications are entirely missing from Dendrite. See [CHANGES.md](CHANGES.md) for updates.
|
||||
- Dendrite is feature-complete. There may be client or federation APIs that are not implemented.
|
||||
- Dendrite is ready for massive homeserver deployments. You cannot shard each microservice, only run each one on a different machine.
|
||||
|
||||
Currently, we expect Dendrite to function well for small (10s/100s of users) homeserver deployments as well as P2P Matrix nodes in-browser or on mobile devices.
|
||||
|
|
@ -36,6 +35,9 @@ If you have further questions, please take a look at [our FAQ](docs/FAQ.md) or j
|
|||
|
||||
## Requirements
|
||||
|
||||
See the [Planning your Installation](https://matrix-org.github.io/dendrite/installation/planning) page for
|
||||
more information on requirements.
|
||||
|
||||
To build Dendrite, you will need Go 1.18 or later.
|
||||
|
||||
For a usable federating Dendrite deployment, you will also need:
|
||||
|
|
@ -83,11 +85,11 @@ $ ./bin/create-account --config dendrite.yaml -username alice
|
|||
|
||||
Then point your favourite Matrix client at `http://localhost:8008` or `https://localhost:8448`.
|
||||
|
||||
## <a id="progress"></a> Progress
|
||||
## Progress
|
||||
|
||||
We use a script called Are We Synapse Yet which checks Sytest compliance rates. Sytest is a black-box homeserver
|
||||
test rig with around 900 tests. The script works out how many of these tests are passing on Dendrite and it
|
||||
updates with CI. As of April 2022 we're at around 83% CS API coverage and 95% Federation coverage, though check
|
||||
updates with CI. As of August 2022 we're at around 83% CS API coverage and 95% Federation coverage, though check
|
||||
CI for the latest numbers. In practice, this means you can communicate locally and via federation with Synapse
|
||||
servers such as matrix.org reasonably well, although there are still some missing features (like Search).
|
||||
|
||||
|
|
@ -119,53 +121,8 @@ We would be grateful for any help on issues marked as
|
|||
all have related Sytests which need to pass in order for the issue to be closed. Once you've written your
|
||||
code, you can quickly run Sytest to ensure that the test names are now passing.
|
||||
|
||||
For example, if the test `Local device key changes get to remote servers` was marked as failing, find the
|
||||
test file (e.g via `grep` or via the
|
||||
[CI log output](https://buildkite.com/matrix-dot-org/dendrite/builds/2826#39cff5de-e032-4ad0-ad26-f819e6919c42)
|
||||
it's `tests/50federation/40devicelists.pl` ) then to run Sytest:
|
||||
|
||||
```
|
||||
docker run --rm --name sytest
|
||||
-v "/Users/kegan/github/sytest:/sytest"
|
||||
-v "/Users/kegan/github/dendrite:/src"
|
||||
-v "/Users/kegan/logs:/logs"
|
||||
-v "/Users/kegan/go/:/gopath"
|
||||
-e "POSTGRES=1" -e "DENDRITE_TRACE_HTTP=1"
|
||||
matrixdotorg/sytest-dendrite:latest tests/50federation/40devicelists.pl
|
||||
```
|
||||
|
||||
See [sytest.md](docs/sytest.md) for the full description of these flags.
|
||||
|
||||
You can try running sytest outside of docker for faster runs, but the dependencies can be temperamental
|
||||
and we recommend using docker where possible.
|
||||
|
||||
```
|
||||
cd sytest
|
||||
export PERL5LIB=$HOME/lib/perl5
|
||||
export PERL_MB_OPT=--install_base=$HOME
|
||||
export PERL_MM_OPT=INSTALL_BASE=$HOME
|
||||
./install-deps.pl
|
||||
|
||||
./run-tests.pl -I Dendrite::Monolith -d $PATH_TO_DENDRITE_BINARIES
|
||||
```
|
||||
|
||||
Sometimes Sytest is testing the wrong thing or is flakey, so it will need to be patched.
|
||||
Ask on `#dendrite-dev:matrix.org` if you think this is the case for you and we'll be happy to help.
|
||||
|
||||
If you're new to the project, see [CONTRIBUTING.md](docs/CONTRIBUTING.md) to get up to speed then
|
||||
If you're new to the project, see our
|
||||
[Contributing page](https://matrix-org.github.io/dendrite/development/contributing) to get up to speed, then
|
||||
look for [Good First Issues](https://github.com/matrix-org/dendrite/labels/good%20first%20issue). If you're
|
||||
familiar with the project, look for [Help Wanted](https://github.com/matrix-org/dendrite/labels/help-wanted)
|
||||
issues.
|
||||
|
||||
## Hardware requirements
|
||||
|
||||
Dendrite in Monolith + SQLite works in a range of environments including iOS and in-browser via WASM.
|
||||
|
||||
For small homeserver installations joined on ~10s rooms on matrix.org with ~100s of users in those rooms, including some
|
||||
encrypted rooms:
|
||||
|
||||
- Memory: uses around 100MB of RAM, with peaks at around 200MB.
|
||||
- Disk space: After a few months of usage, the database grew to around 2GB (in Monolith mode).
|
||||
- CPU: Brief spikes when processing events, typically idles at 1% CPU.
|
||||
|
||||
This means Dendrite should comfortably work on things like Raspberry Pis.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/appservice/api"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
)
|
||||
|
||||
// HTTP paths for the internal HTTP APIs
|
||||
|
|
@ -42,11 +41,10 @@ func (h *httpAppServiceQueryAPI) RoomAliasExists(
|
|||
request *api.RoomAliasExistsRequest,
|
||||
response *api.RoomAliasExistsResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "appserviceRoomAliasExists")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.appserviceURL + AppServiceRoomAliasExistsPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"RoomAliasExists", h.appserviceURL+AppServiceRoomAliasExistsPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// UserIDExists implements AppServiceQueryAPI
|
||||
|
|
@ -55,9 +53,8 @@ func (h *httpAppServiceQueryAPI) UserIDExists(
|
|||
request *api.UserIDExistsRequest,
|
||||
response *api.UserIDExistsResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "appserviceUserIDExists")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.appserviceURL + AppServiceUserIDExistsPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"UserIDExists", h.appserviceURL+AppServiceUserIDExistsPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +1,20 @@
|
|||
package inthttp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/matrix-org/dendrite/appservice/api"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
// AddRoutes adds the AppServiceQueryAPI handlers to the http.ServeMux.
|
||||
func AddRoutes(a api.AppServiceInternalAPI, internalAPIMux *mux.Router) {
|
||||
internalAPIMux.Handle(
|
||||
AppServiceRoomAliasExistsPath,
|
||||
httputil.MakeInternalAPI("appserviceRoomAliasExists", func(req *http.Request) util.JSONResponse {
|
||||
var request api.RoomAliasExistsRequest
|
||||
var response api.RoomAliasExistsResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := a.RoomAliasExists(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("AppserviceRoomAliasExists", a.RoomAliasExists),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
AppServiceUserIDExistsPath,
|
||||
httputil.MakeInternalAPI("appserviceUserIDExists", func(req *http.Request) util.JSONResponse {
|
||||
var request api.UserIDExistsRequest
|
||||
var response api.UserIDExistsResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := a.UserIDExists(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("AppserviceUserIDExists", a.UserIDExists),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,4 +13,4 @@ go build ./cmd/...
|
|||
./build/scripts/find-lint.sh
|
||||
|
||||
echo "Testing..."
|
||||
go test -v ./...
|
||||
go test --race -v ./...
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||
|
|
@ -34,7 +33,7 @@ import (
|
|||
// If the final return value is non-nil, an error occurred and the cleanup function
|
||||
// is nil.
|
||||
func LoginFromJSONReader(ctx context.Context, r io.Reader, useraccountAPI uapi.UserLoginAPI, userAPI UserInternalAPIForLogin, cfg *config.ClientAPI) (*Login, LoginCleanupFunc, *util.JSONResponse) {
|
||||
reqBytes, err := ioutil.ReadAll(r)
|
||||
reqBytes, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
err := &util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ package httputil
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"unicode/utf8"
|
||||
|
||||
|
|
@ -29,9 +29,9 @@ import (
|
|||
func UnmarshalJSONRequest(req *http.Request, iface interface{}) *util.JSONResponse {
|
||||
// encoding/json allows invalid utf-8, matrix does not
|
||||
// https://matrix.org/docs/spec/client_server/r0.6.1#api-standards
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
body, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Error("ioutil.ReadAll failed")
|
||||
util.GetLogger(req.Context()).WithError(err).Error("io.ReadAll failed")
|
||||
resp := jsonerror.InternalServerError()
|
||||
return &resp
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,13 @@
|
|||
package jsonerror
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// MatrixError represents the "standard error response" in Matrix.
|
||||
|
|
@ -213,3 +215,15 @@ func NotTrusted(serverName string) *MatrixError {
|
|||
Err: fmt.Sprintf("Untrusted server '%s'", serverName),
|
||||
}
|
||||
}
|
||||
|
||||
// InternalAPIError is returned when Dendrite failed to reach an internal API.
|
||||
func InternalAPIError(ctx context.Context, err error) util.JSONResponse {
|
||||
logrus.WithContext(ctx).WithError(err).Error("Error reaching an internal API")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: &MatrixError{
|
||||
ErrCode: "M_INTERNAL_SERVER_ERROR",
|
||||
Err: "Dendrite encountered an error reaching an internal API.",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ package routing
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||
|
|
@ -101,9 +101,9 @@ func SaveAccountData(
|
|||
}
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
body, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Error("ioutil.ReadAll failed")
|
||||
util.GetLogger(req.Context()).WithError(err).Error("io.ReadAll failed")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,13 +30,15 @@ func AdminEvacuateRoom(req *http.Request, device *userapi.Device, rsAPI roomserv
|
|||
}
|
||||
}
|
||||
res := &roomserverAPI.PerformAdminEvacuateRoomResponse{}
|
||||
rsAPI.PerformAdminEvacuateRoom(
|
||||
if err := rsAPI.PerformAdminEvacuateRoom(
|
||||
req.Context(),
|
||||
&roomserverAPI.PerformAdminEvacuateRoomRequest{
|
||||
RoomID: roomID,
|
||||
},
|
||||
res,
|
||||
)
|
||||
); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := res.Error; err != nil {
|
||||
return err.JSONResponse()
|
||||
}
|
||||
|
|
@ -67,13 +69,15 @@ func AdminEvacuateUser(req *http.Request, device *userapi.Device, rsAPI roomserv
|
|||
}
|
||||
}
|
||||
res := &roomserverAPI.PerformAdminEvacuateUserResponse{}
|
||||
rsAPI.PerformAdminEvacuateUser(
|
||||
if err := rsAPI.PerformAdminEvacuateUser(
|
||||
req.Context(),
|
||||
&roomserverAPI.PerformAdminEvacuateUserRequest{
|
||||
UserID: userID,
|
||||
},
|
||||
res,
|
||||
)
|
||||
); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if err := res.Error; err != nil {
|
||||
return err.JSONResponse()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -556,10 +556,12 @@ func createRoom(
|
|||
if r.Visibility == "public" {
|
||||
// expose this room in the published room list
|
||||
var pubRes roomserverAPI.PerformPublishResponse
|
||||
rsAPI.PerformPublish(ctx, &roomserverAPI.PerformPublishRequest{
|
||||
if err := rsAPI.PerformPublish(ctx, &roomserverAPI.PerformPublishRequest{
|
||||
RoomID: roomID,
|
||||
Visibility: "public",
|
||||
}, &pubRes)
|
||||
}, &pubRes); err != nil {
|
||||
return jsonerror.InternalAPIError(ctx, err)
|
||||
}
|
||||
if pubRes.Error != nil {
|
||||
// treat as non-fatal since the room is already made by this point
|
||||
util.GetLogger(ctx).WithError(pubRes.Error).Error("failed to visibility:public")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/auth"
|
||||
|
|
@ -20,7 +20,7 @@ func Deactivate(
|
|||
) util.JSONResponse {
|
||||
ctx := req.Context()
|
||||
defer req.Body.Close() // nolint:errcheck
|
||||
bodyBytes, err := ioutil.ReadAll(req.Body)
|
||||
bodyBytes, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ func DeleteDeviceById(
|
|||
}()
|
||||
ctx := req.Context()
|
||||
defer req.Body.Close() // nolint:errcheck
|
||||
bodyBytes, err := ioutil.ReadAll(req.Body)
|
||||
bodyBytes, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
|
|
|
|||
|
|
@ -302,10 +302,12 @@ func SetVisibility(
|
|||
}
|
||||
|
||||
var publishRes roomserverAPI.PerformPublishResponse
|
||||
rsAPI.PerformPublish(req.Context(), &roomserverAPI.PerformPublishRequest{
|
||||
if err := rsAPI.PerformPublish(req.Context(), &roomserverAPI.PerformPublishRequest{
|
||||
RoomID: roomID,
|
||||
Visibility: v.Visibility,
|
||||
}, &publishRes)
|
||||
}, &publishRes); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if publishRes.Error != nil {
|
||||
util.GetLogger(req.Context()).WithError(publishRes.Error).Error("PerformPublish failed")
|
||||
return publishRes.Error.JSONResponse()
|
||||
|
|
|
|||
|
|
@ -23,13 +23,14 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/api"
|
||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -196,14 +197,14 @@ func fillPublicRoomsReq(httpReq *http.Request, request *PublicRoomReq) *util.JSO
|
|||
|
||||
// sliceInto returns a subslice of `slice` which honours the since/limit values given.
|
||||
//
|
||||
// 0 1 2 3 4 5 6 index
|
||||
// [A, B, C, D, E, F, G] slice
|
||||
// 0 1 2 3 4 5 6 index
|
||||
// [A, B, C, D, E, F, G] slice
|
||||
//
|
||||
// limit=3 => A,B,C (prev='', next='3')
|
||||
// limit=3&since=3 => D,E,F (prev='0', next='6')
|
||||
// limit=3&since=6 => G (prev='3', next='')
|
||||
// limit=3 => A,B,C (prev='', next='3')
|
||||
// limit=3&since=3 => D,E,F (prev='0', next='6')
|
||||
// limit=3&since=6 => G (prev='3', next='')
|
||||
//
|
||||
// A value of '-1' for prev/next indicates no position.
|
||||
// A value of '-1' for prev/next indicates no position.
|
||||
func sliceInto(slice []gomatrixserverlib.PublicRoom, since int64, limit int16) (subset []gomatrixserverlib.PublicRoom, prev, next int) {
|
||||
prev = -1
|
||||
next = -1
|
||||
|
|
|
|||
|
|
@ -81,8 +81,9 @@ func JoinRoomByIDOrAlias(
|
|||
done := make(chan util.JSONResponse, 1)
|
||||
go func() {
|
||||
defer close(done)
|
||||
rsAPI.PerformJoin(req.Context(), &joinReq, &joinRes)
|
||||
if joinRes.Error != nil {
|
||||
if err := rsAPI.PerformJoin(req.Context(), &joinReq, &joinRes); err != nil {
|
||||
done <- jsonerror.InternalAPIError(req.Context(), err)
|
||||
} else if joinRes.Error != nil {
|
||||
done <- joinRes.Error.JSONResponse()
|
||||
} else {
|
||||
done <- util.JSONResponse{
|
||||
|
|
|
|||
|
|
@ -91,10 +91,12 @@ func CreateKeyBackupVersion(req *http.Request, userAPI userapi.ClientUserAPI, de
|
|||
// Implements GET /_matrix/client/r0/room_keys/version and GET /_matrix/client/r0/room_keys/version/{version}
|
||||
func KeyBackupVersion(req *http.Request, userAPI userapi.ClientUserAPI, device *userapi.Device, version string) util.JSONResponse {
|
||||
var queryResp userapi.QueryKeyBackupResponse
|
||||
userAPI.QueryKeyBackup(req.Context(), &userapi.QueryKeyBackupRequest{
|
||||
if err := userAPI.QueryKeyBackup(req.Context(), &userapi.QueryKeyBackupRequest{
|
||||
UserID: device.UserID,
|
||||
Version: version,
|
||||
}, &queryResp)
|
||||
}, &queryResp); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if queryResp.Error != "" {
|
||||
return util.ErrorResponse(fmt.Errorf("QueryKeyBackup: %s", queryResp.Error))
|
||||
}
|
||||
|
|
@ -233,13 +235,15 @@ func GetBackupKeys(
|
|||
req *http.Request, userAPI userapi.ClientUserAPI, device *userapi.Device, version, roomID, sessionID string,
|
||||
) util.JSONResponse {
|
||||
var queryResp userapi.QueryKeyBackupResponse
|
||||
userAPI.QueryKeyBackup(req.Context(), &userapi.QueryKeyBackupRequest{
|
||||
if err := userAPI.QueryKeyBackup(req.Context(), &userapi.QueryKeyBackupRequest{
|
||||
UserID: device.UserID,
|
||||
Version: version,
|
||||
ReturnKeys: true,
|
||||
KeysForRoomID: roomID,
|
||||
KeysForSessionID: sessionID,
|
||||
}, &queryResp)
|
||||
}, &queryResp); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if queryResp.Error != "" {
|
||||
return util.ErrorResponse(fmt.Errorf("QueryKeyBackup: %s", queryResp.Error))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,9 @@ func UploadCrossSigningDeviceKeys(
|
|||
sessions.addCompletedSessionStage(sessionID, authtypes.LoginTypePassword)
|
||||
|
||||
uploadReq.UserID = device.UserID
|
||||
keyserverAPI.PerformUploadDeviceKeys(req.Context(), &uploadReq.PerformUploadDeviceKeysRequest, uploadRes)
|
||||
if err := keyserverAPI.PerformUploadDeviceKeys(req.Context(), &uploadReq.PerformUploadDeviceKeysRequest, uploadRes); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
|
||||
if err := uploadRes.Error; err != nil {
|
||||
switch {
|
||||
|
|
@ -114,7 +116,9 @@ func UploadCrossSigningDeviceSignatures(req *http.Request, keyserverAPI api.Clie
|
|||
}
|
||||
|
||||
uploadReq.UserID = device.UserID
|
||||
keyserverAPI.PerformUploadDeviceSignatures(req.Context(), uploadReq, uploadRes)
|
||||
if err := keyserverAPI.PerformUploadDeviceSignatures(req.Context(), uploadReq, uploadRes); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
|
||||
if err := uploadRes.Error; err != nil {
|
||||
switch {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ func UploadKeys(req *http.Request, keyAPI api.ClientKeyAPI, device *userapi.Devi
|
|||
}
|
||||
|
||||
var uploadRes api.PerformUploadKeysResponse
|
||||
keyAPI.PerformUploadKeys(req.Context(), uploadReq, &uploadRes)
|
||||
if err := keyAPI.PerformUploadKeys(req.Context(), uploadReq, &uploadRes); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if uploadRes.Error != nil {
|
||||
util.GetLogger(req.Context()).WithError(uploadRes.Error).Error("Failed to PerformUploadKeys")
|
||||
return jsonerror.InternalServerError()
|
||||
|
|
@ -107,12 +109,14 @@ func QueryKeys(req *http.Request, keyAPI api.ClientKeyAPI, device *userapi.Devic
|
|||
return *resErr
|
||||
}
|
||||
queryRes := api.QueryKeysResponse{}
|
||||
keyAPI.QueryKeys(req.Context(), &api.QueryKeysRequest{
|
||||
if err := keyAPI.QueryKeys(req.Context(), &api.QueryKeysRequest{
|
||||
UserID: device.UserID,
|
||||
UserToDevices: r.DeviceKeys,
|
||||
Timeout: r.GetTimeout(),
|
||||
// TODO: Token?
|
||||
}, &queryRes)
|
||||
}, &queryRes); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: map[string]interface{}{
|
||||
|
|
@ -145,10 +149,12 @@ func ClaimKeys(req *http.Request, keyAPI api.ClientKeyAPI) util.JSONResponse {
|
|||
return *resErr
|
||||
}
|
||||
claimRes := api.PerformClaimKeysResponse{}
|
||||
keyAPI.PerformClaimKeys(req.Context(), &api.PerformClaimKeysRequest{
|
||||
if err := keyAPI.PerformClaimKeys(req.Context(), &api.PerformClaimKeysRequest{
|
||||
OneTimeKeys: r.OneTimeKeys,
|
||||
Timeout: r.GetTimeout(),
|
||||
}, &claimRes)
|
||||
}, &claimRes); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if claimRes.Error != nil {
|
||||
util.GetLogger(req.Context()).WithError(claimRes.Error).Error("failed to PerformClaimKeys")
|
||||
return jsonerror.InternalServerError()
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ package routing
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
|
@ -54,7 +55,9 @@ func PeekRoomByIDOrAlias(
|
|||
}
|
||||
|
||||
// Ask the roomserver to perform the peek.
|
||||
rsAPI.PerformPeek(req.Context(), &peekReq, &peekRes)
|
||||
if err := rsAPI.PerformPeek(req.Context(), &peekReq, &peekRes); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if peekRes.Error != nil {
|
||||
return peekRes.Error.JSONResponse()
|
||||
}
|
||||
|
|
@ -89,7 +92,9 @@ func UnpeekRoomByID(
|
|||
}
|
||||
unpeekRes := roomserverAPI.PerformUnpeekResponse{}
|
||||
|
||||
rsAPI.PerformUnpeek(req.Context(), &unpeekReq, &unpeekRes)
|
||||
if err := rsAPI.PerformUnpeek(req.Context(), &unpeekReq, &unpeekRes); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if unpeekRes.Error != nil {
|
||||
return unpeekRes.Error.JSONResponse()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
|
|
@ -371,7 +371,7 @@ func validateRecaptcha(
|
|||
|
||||
// Grab the body of the response from the captcha server
|
||||
var r recaptchaResponse
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return &util.JSONResponse{
|
||||
Code: http.StatusGatewayTimeout,
|
||||
|
|
@ -539,7 +539,7 @@ func Register(
|
|||
cfg *config.ClientAPI,
|
||||
) util.JSONResponse {
|
||||
defer req.Body.Close() // nolint: errcheck
|
||||
reqBody, err := ioutil.ReadAll(req.Body)
|
||||
reqBody, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package routing
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/patrickmn/go-cache"
|
||||
|
|
@ -13,7 +13,7 @@ func TestSharedSecretRegister(t *testing.T) {
|
|||
jsonStr := []byte(`{"admin":false,"mac":"f1ba8d37123866fd659b40de4bad9b0f8965c565","nonce":"759f047f312b99ff428b21d581256f8592b8976e58bc1b543972dc6147e529a79657605b52d7becd160ff5137f3de11975684319187e06901955f79e5a6c5a79","password":"wonderland","username":"alice"}`)
|
||||
sharedSecret := "dendritetest"
|
||||
|
||||
req, err := NewSharedSecretRegistrationRequest(ioutil.NopCloser(bytes.NewBuffer(jsonStr)))
|
||||
req, err := NewSharedSecretRegistrationRequest(io.NopCloser(bytes.NewBuffer(jsonStr)))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read request: %s", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,9 +63,10 @@ var sendEventDuration = prometheus.NewHistogramVec(
|
|||
)
|
||||
|
||||
// SendEvent implements:
|
||||
// /rooms/{roomID}/send/{eventType}
|
||||
// /rooms/{roomID}/send/{eventType}/{txnID}
|
||||
// /rooms/{roomID}/state/{eventType}/{stateKey}
|
||||
//
|
||||
// /rooms/{roomID}/send/{eventType}
|
||||
// /rooms/{roomID}/send/{eventType}/{txnID}
|
||||
// /rooms/{roomID}/state/{eventType}/{stateKey}
|
||||
func SendEvent(
|
||||
req *http.Request,
|
||||
device *userapi.Device,
|
||||
|
|
|
|||
|
|
@ -38,8 +38,9 @@ type threePIDsResponse struct {
|
|||
}
|
||||
|
||||
// RequestEmailToken implements:
|
||||
// POST /account/3pid/email/requestToken
|
||||
// POST /register/email/requestToken
|
||||
//
|
||||
// POST /account/3pid/email/requestToken
|
||||
// POST /register/email/requestToken
|
||||
func RequestEmailToken(req *http.Request, threePIDAPI api.ClientUserAPI, cfg *config.ClientAPI) util.JSONResponse {
|
||||
var body threepid.EmailAssociationRequest
|
||||
if reqErr := httputil.UnmarshalJSONRequest(req, &body); reqErr != nil {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,9 @@ func UpgradeRoom(
|
|||
}
|
||||
upgradeResp := roomserverAPI.PerformRoomUpgradeResponse{}
|
||||
|
||||
rsAPI.PerformRoomUpgrade(req.Context(), &upgradeReq, &upgradeResp)
|
||||
if err := rsAPI.PerformRoomUpgrade(req.Context(), &upgradeReq, &upgradeResp); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
|
||||
if upgradeResp.Error != nil {
|
||||
if upgradeResp.Error.Code == roomserverAPI.PerformErrorNoRoom {
|
||||
|
|
|
|||
|
|
@ -22,15 +22,17 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/gomatrix"
|
||||
"github.com/matrix-org/util"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrix"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
// RequestTurnServer implements:
|
||||
// GET /voip/turnServer
|
||||
//
|
||||
// GET /voip/turnServer
|
||||
func RequestTurnServer(req *http.Request, device *api.Device, cfg *config.ClientAPI) util.JSONResponse {
|
||||
turnConfig := cfg.TURN
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
|
@ -157,7 +156,7 @@ func main() {
|
|||
func getPassword(password, pwdFile string, pwdStdin bool, r io.Reader) (string, error) {
|
||||
// read password from file
|
||||
if pwdFile != "" {
|
||||
pw, err := ioutil.ReadFile(pwdFile)
|
||||
pw, err := os.ReadFile(pwdFile)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unable to read password from file: %v", err)
|
||||
}
|
||||
|
|
@ -166,7 +165,7 @@ func getPassword(password, pwdFile string, pwdStdin bool, r io.Reader) (string,
|
|||
|
||||
// read password from stdin
|
||||
if pwdStdin {
|
||||
data, err := ioutil.ReadAll(r)
|
||||
data, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unable to read password from stdin: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import (
|
|||
"encoding/hex"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
|
@ -76,11 +75,11 @@ func main() {
|
|||
if pk, sk, err = ed25519.GenerateKey(nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err = ioutil.WriteFile(keyfile, sk, 0644); err != nil {
|
||||
if err = os.WriteFile(keyfile, sk, 0644); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else if err == nil {
|
||||
if sk, err = ioutil.ReadFile(keyfile); err != nil {
|
||||
if sk, err = os.ReadFile(keyfile); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(sk) != ed25519.PrivateKeySize {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import (
|
|||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
|
|
@ -69,7 +68,7 @@ func Setup(instanceName, storageDirectory, peerURI string) (*Node, error) {
|
|||
|
||||
yggfile := fmt.Sprintf("%s/%s-yggdrasil.conf", storageDirectory, instanceName)
|
||||
if _, err := os.Stat(yggfile); !os.IsNotExist(err) {
|
||||
yggconf, e := ioutil.ReadFile(yggfile)
|
||||
yggconf, e := os.ReadFile(yggfile)
|
||||
if e != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -88,7 +87,7 @@ func Setup(instanceName, storageDirectory, peerURI string) (*Node, error) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if e := ioutil.WriteFile(yggfile, j, 0600); e != nil {
|
||||
if e := os.WriteFile(yggfile, j, 0600); e != nil {
|
||||
n.log.Printf("Couldn't write private key to file '%s': %s\n", yggfile, e)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
|
@ -47,7 +47,7 @@ const HEAD = "HEAD"
|
|||
// We cannot use the dockerfile associated with the repo with each version sadly due to changes in
|
||||
// Docker versions. Specifically, earlier Dendrite versions are incompatible with newer Docker clients
|
||||
// due to the error:
|
||||
// When using COPY with more than one source file, the destination must be a directory and end with a /
|
||||
// When using COPY with more than one source file, the destination must be a directory and end with a /
|
||||
// We need to run a postgres anyway, so use the dockerfile associated with Complement instead.
|
||||
const Dockerfile = `FROM golang:1.18-stretch as build
|
||||
RUN apt-get update && apt-get install -y postgresql
|
||||
|
|
@ -95,7 +95,9 @@ CMD /build/run_dendrite.sh `
|
|||
const dendriteUpgradeTestLabel = "dendrite_upgrade_test"
|
||||
|
||||
// downloadArchive downloads an arbitrary github archive of the form:
|
||||
// https://github.com/matrix-org/dendrite/archive/v0.3.11.tar.gz
|
||||
//
|
||||
// https://github.com/matrix-org/dendrite/archive/v0.3.11.tar.gz
|
||||
//
|
||||
// and re-tarballs it without the top-level directory which contains branch information. It inserts
|
||||
// the contents of `dockerfile` as a root file `Dockerfile` in the re-tarballed directory such that
|
||||
// you can directly feed the retarballed archive to `ImageBuild` to have it run said dockerfile.
|
||||
|
|
@ -126,7 +128,7 @@ func downloadArchive(cli *http.Client, tmpDir, archiveURL string, dockerfile []b
|
|||
return nil, err
|
||||
}
|
||||
// add top level Dockerfile
|
||||
err = ioutil.WriteFile(path.Join(tmpDir, "Dockerfile"), dockerfile, os.ModePerm)
|
||||
err = os.WriteFile(path.Join(tmpDir, "Dockerfile"), dockerfile, os.ModePerm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to inject /Dockerfile: %w", err)
|
||||
}
|
||||
|
|
@ -148,7 +150,7 @@ func buildDendrite(httpClient *http.Client, dockerClient *client.Client, tmpDir,
|
|||
if branchOrTagName == HEAD && *flagHead != "" {
|
||||
log.Printf("%s: Using %s as HEAD", branchOrTagName, *flagHead)
|
||||
// add top level Dockerfile
|
||||
err = ioutil.WriteFile(path.Join(*flagHead, "Dockerfile"), []byte(Dockerfile), os.ModePerm)
|
||||
err = os.WriteFile(path.Join(*flagHead, "Dockerfile"), []byte(Dockerfile), os.ModePerm)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("custom HEAD: failed to inject /Dockerfile: %w", err)
|
||||
}
|
||||
|
|
@ -386,7 +388,7 @@ func runImage(dockerClient *client.Client, volumeName, version, imageID string)
|
|||
})
|
||||
// ignore errors when cannot get logs, it's just for debugging anyways
|
||||
if err == nil {
|
||||
logbody, err := ioutil.ReadAll(logs)
|
||||
logbody, err := io.ReadAll(logs)
|
||||
if err == nil {
|
||||
log.Printf("Container logs:\n\n%s\n\n", string(logbody))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ type user struct {
|
|||
}
|
||||
|
||||
// runTests performs the following operations:
|
||||
// - register alice and bob with branch name muxed into the localpart
|
||||
// - create a DM room for the 2 users and exchange messages
|
||||
// - create/join a public #global room and exchange messages
|
||||
// - register alice and bob with branch name muxed into the localpart
|
||||
// - create a DM room for the 2 users and exchange messages
|
||||
// - create/join a public #global room and exchange messages
|
||||
func runTests(baseURL, branchName string) error {
|
||||
// register 2 users
|
||||
users := []user{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import (
|
|||
"encoding/pem"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
|
|
@ -30,7 +29,7 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(*requestKey)
|
||||
data, err := os.ReadFile(*requestKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,13 +178,16 @@ client_api:
|
|||
|
||||
# TURN server information that this homeserver should send to clients.
|
||||
turn:
|
||||
turn_user_lifetime: ""
|
||||
turn_user_lifetime: "5m"
|
||||
turn_uris:
|
||||
# - turn:turn.server.org?transport=udp
|
||||
# - turn:turn.server.org?transport=tcp
|
||||
turn_shared_secret: ""
|
||||
turn_username: ""
|
||||
turn_password: ""
|
||||
# If your TURN server requires static credentials, then you will need to enter
|
||||
# them here instead of supplying a shared secret. Note that these credentials
|
||||
# will be visible to clients!
|
||||
# turn_username: ""
|
||||
# turn_password: ""
|
||||
|
||||
# Settings for rate-limited endpoints. Rate limiting kicks in after the threshold
|
||||
# number of "slots" have been taken by requests from a specific host. Each "slot"
|
||||
|
|
|
|||
|
|
@ -181,13 +181,16 @@ client_api:
|
|||
|
||||
# TURN server information that this homeserver should send to clients.
|
||||
turn:
|
||||
turn_user_lifetime: ""
|
||||
turn_user_lifetime: "5m"
|
||||
turn_uris:
|
||||
# - turn:turn.server.org?transport=udp
|
||||
# - turn:turn.server.org?transport=tcp
|
||||
turn_shared_secret: ""
|
||||
turn_username: ""
|
||||
turn_password: ""
|
||||
# If your TURN server requires static credentials, then you will need to enter
|
||||
# them here instead of supplying a shared secret. Note that these credentials
|
||||
# will be visible to clients!
|
||||
# turn_username: ""
|
||||
# turn_password: ""
|
||||
|
||||
# Settings for rate-limited endpoints. Rate limiting kicks in after the threshold
|
||||
# number of "slots" have been taken by requests from a specific host. Each "slot"
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ comment. Please avoid doing this if you can.
|
|||
We also have unit tests which we run via:
|
||||
|
||||
```bash
|
||||
go test ./...
|
||||
go test --race ./...
|
||||
```
|
||||
|
||||
In general, we like submissions that come with tests. Anything that proves that the
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ type FederationClientError struct {
|
|||
Blacklisted bool
|
||||
}
|
||||
|
||||
func (e *FederationClientError) Error() string {
|
||||
func (e FederationClientError) Error() string {
|
||||
return fmt.Sprintf("%s - (retry_after=%s, blacklisted=%v)", e.Err, e.RetryAfter.String(), e.Blacklisted)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -208,9 +208,11 @@ func (s *OutputRoomEventConsumer) processMessage(ore api.OutputNewRoomEvent, rew
|
|||
// joinedHostsAtEvent works out a list of matrix servers that were joined to
|
||||
// the room at the event (including peeking ones)
|
||||
// It is important to use the state at the event for sending messages because:
|
||||
// 1) We shouldn't send messages to servers that weren't in the room.
|
||||
// 2) If a server is kicked from the rooms it should still be told about the
|
||||
// kick event,
|
||||
//
|
||||
// 1. We shouldn't send messages to servers that weren't in the room.
|
||||
// 2. If a server is kicked from the rooms it should still be told about the
|
||||
// kick event.
|
||||
//
|
||||
// Usually the list can be calculated locally, but sometimes it will need fetch
|
||||
// events from the room server.
|
||||
// Returns an error if there was a problem talking to the room server.
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
package federationapi
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/matrix-org/dendrite/federationapi/api"
|
||||
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
|
||||
|
|
@ -167,5 +169,16 @@ func NewInternalAPI(
|
|||
if err = presenceConsumer.Start(); err != nil {
|
||||
logrus.WithError(err).Panic("failed to start presence consumer")
|
||||
}
|
||||
|
||||
var cleanExpiredEDUs func()
|
||||
cleanExpiredEDUs = func() {
|
||||
logrus.Infof("Cleaning expired EDUs")
|
||||
if err := federationDB.DeleteExpiredEDUs(base.Context()); err != nil {
|
||||
logrus.WithError(err).Error("Failed to clean expired EDUs")
|
||||
}
|
||||
time.AfterFunc(time.Hour, cleanExpiredEDUs)
|
||||
}
|
||||
time.AfterFunc(time.Minute, cleanExpiredEDUs)
|
||||
|
||||
return internal.NewFederationInternalAPI(federationDB, cfg, rsAPI, federation, stats, caches, queues, keyRing)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
"crypto/ed25519"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
|
@ -66,7 +66,7 @@ func TestMain(m *testing.M) {
|
|||
s.cache = caching.NewRistrettoCache(8*1024*1024, time.Hour, false)
|
||||
|
||||
// Create a temporary directory for JetStream.
|
||||
d, err := ioutil.TempDir("./", "jetstream*")
|
||||
d, err := os.MkdirTemp("./", "jetstream*")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -136,7 +136,7 @@ func (m *MockRoundTripper) RoundTrip(req *http.Request) (res *http.Response, err
|
|||
// And respond.
|
||||
res = &http.Response{
|
||||
StatusCode: 200,
|
||||
Body: ioutil.NopCloser(bytes.NewReader(body)),
|
||||
Body: io.NopCloser(bytes.NewReader(body)),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -31,11 +32,12 @@ type fedRoomserverAPI struct {
|
|||
}
|
||||
|
||||
// PerformJoin will call this function
|
||||
func (f *fedRoomserverAPI) InputRoomEvents(ctx context.Context, req *rsapi.InputRoomEventsRequest, res *rsapi.InputRoomEventsResponse) {
|
||||
func (f *fedRoomserverAPI) InputRoomEvents(ctx context.Context, req *rsapi.InputRoomEventsRequest, res *rsapi.InputRoomEventsResponse) error {
|
||||
if f.inputRoomEvents == nil {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
f.inputRoomEvents(ctx, req, res)
|
||||
return nil
|
||||
}
|
||||
|
||||
// keychange consumer calls this
|
||||
|
|
@ -48,6 +50,7 @@ func (f *fedRoomserverAPI) QueryRoomsForUser(ctx context.Context, req *rsapi.Que
|
|||
|
||||
// TODO: This struct isn't generic, only works for TestFederationAPIJoinThenKeyUpdate
|
||||
type fedClient struct {
|
||||
fedClientMutex sync.Mutex
|
||||
api.FederationClient
|
||||
allowJoins []*test.Room
|
||||
keys map[gomatrixserverlib.ServerName]struct {
|
||||
|
|
@ -59,6 +62,8 @@ type fedClient struct {
|
|||
}
|
||||
|
||||
func (f *fedClient) GetServerKeys(ctx context.Context, matrixServer gomatrixserverlib.ServerName) (gomatrixserverlib.ServerKeys, error) {
|
||||
f.fedClientMutex.Lock()
|
||||
defer f.fedClientMutex.Unlock()
|
||||
fmt.Println("GetServerKeys:", matrixServer)
|
||||
var keys gomatrixserverlib.ServerKeys
|
||||
var keyID gomatrixserverlib.KeyID
|
||||
|
|
@ -122,6 +127,8 @@ func (f *fedClient) MakeJoin(ctx context.Context, s gomatrixserverlib.ServerName
|
|||
return
|
||||
}
|
||||
func (f *fedClient) SendJoin(ctx context.Context, s gomatrixserverlib.ServerName, event *gomatrixserverlib.Event) (res gomatrixserverlib.RespSendJoin, err error) {
|
||||
f.fedClientMutex.Lock()
|
||||
defer f.fedClientMutex.Unlock()
|
||||
for _, r := range f.allowJoins {
|
||||
if r.ID == event.RoomID() {
|
||||
r.InsertEvent(f.t, event.Headered(r.Version))
|
||||
|
|
@ -134,6 +141,8 @@ func (f *fedClient) SendJoin(ctx context.Context, s gomatrixserverlib.ServerName
|
|||
}
|
||||
|
||||
func (f *fedClient) SendTransaction(ctx context.Context, t gomatrixserverlib.Transaction) (res gomatrixserverlib.RespSend, err error) {
|
||||
f.fedClientMutex.Lock()
|
||||
defer f.fedClientMutex.Unlock()
|
||||
for _, edu := range t.EDUs {
|
||||
if edu.Type == gomatrixserverlib.MDeviceListUpdate {
|
||||
f.sentTxn = true
|
||||
|
|
@ -242,6 +251,8 @@ func testFederationAPIJoinThenKeyUpdate(t *testing.T, dbType test.DBType) {
|
|||
|
||||
testrig.MustPublishMsgs(t, jsctx, msg)
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
fc.fedClientMutex.Lock()
|
||||
defer fc.fedClientMutex.Unlock()
|
||||
if !fc.sentTxn {
|
||||
t.Fatalf("did not send device list update")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/gomatrix"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
)
|
||||
|
||||
// HTTP paths for the internal HTTP API
|
||||
|
|
@ -48,7 +47,11 @@ func NewFederationAPIClient(federationSenderURL string, httpClient *http.Client,
|
|||
if httpClient == nil {
|
||||
return nil, errors.New("NewFederationInternalAPIHTTP: httpClient is <nil>")
|
||||
}
|
||||
return &httpFederationInternalAPI{federationSenderURL, httpClient, cache}, nil
|
||||
return &httpFederationInternalAPI{
|
||||
federationAPIURL: federationSenderURL,
|
||||
httpClient: httpClient,
|
||||
cache: cache,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type httpFederationInternalAPI struct {
|
||||
|
|
@ -63,11 +66,10 @@ func (h *httpFederationInternalAPI) PerformLeave(
|
|||
request *api.PerformLeaveRequest,
|
||||
response *api.PerformLeaveResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformLeaveRequest")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.federationAPIURL + FederationAPIPerformLeaveRequestPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformLeave", h.federationAPIURL+FederationAPIPerformLeaveRequestPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// Handle sending an invite to a remote server.
|
||||
|
|
@ -76,11 +78,10 @@ func (h *httpFederationInternalAPI) PerformInvite(
|
|||
request *api.PerformInviteRequest,
|
||||
response *api.PerformInviteResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformInviteRequest")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.federationAPIURL + FederationAPIPerformInviteRequestPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformInvite", h.federationAPIURL+FederationAPIPerformInviteRequestPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// Handle starting a peek on a remote server.
|
||||
|
|
@ -89,11 +90,10 @@ func (h *httpFederationInternalAPI) PerformOutboundPeek(
|
|||
request *api.PerformOutboundPeekRequest,
|
||||
response *api.PerformOutboundPeekResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformOutboundPeekRequest")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.federationAPIURL + FederationAPIPerformOutboundPeekRequestPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformOutboundPeek", h.federationAPIURL+FederationAPIPerformOutboundPeekRequestPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryJoinedHostServerNamesInRoom implements FederationInternalAPI
|
||||
|
|
@ -102,11 +102,10 @@ func (h *httpFederationInternalAPI) QueryJoinedHostServerNamesInRoom(
|
|||
request *api.QueryJoinedHostServerNamesInRoomRequest,
|
||||
response *api.QueryJoinedHostServerNamesInRoomResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryJoinedHostServerNamesInRoom")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.federationAPIURL + FederationAPIQueryJoinedHostServerNamesInRoomPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryJoinedHostServerNamesInRoom", h.federationAPIURL+FederationAPIQueryJoinedHostServerNamesInRoomPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// Handle an instruction to make_join & send_join with a remote server.
|
||||
|
|
@ -115,12 +114,10 @@ func (h *httpFederationInternalAPI) PerformJoin(
|
|||
request *api.PerformJoinRequest,
|
||||
response *api.PerformJoinResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformJoinRequest")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.federationAPIURL + FederationAPIPerformJoinRequestPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
if err := httputil.CallInternalRPCAPI(
|
||||
"PerformJoinRequest", h.federationAPIURL+FederationAPIPerformJoinRequestPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
); err != nil {
|
||||
response.LastError = &gomatrix.HTTPError{
|
||||
Message: err.Error(),
|
||||
Code: 0,
|
||||
|
|
@ -135,11 +132,10 @@ func (h *httpFederationInternalAPI) PerformDirectoryLookup(
|
|||
request *api.PerformDirectoryLookupRequest,
|
||||
response *api.PerformDirectoryLookupResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformDirectoryLookup")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.federationAPIURL + FederationAPIPerformDirectoryLookupRequestPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformDirectoryLookup", h.federationAPIURL+FederationAPIPerformDirectoryLookupRequestPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// Handle an instruction to broadcast an EDU to all servers in rooms we are joined to.
|
||||
|
|
@ -148,101 +144,61 @@ func (h *httpFederationInternalAPI) PerformBroadcastEDU(
|
|||
request *api.PerformBroadcastEDURequest,
|
||||
response *api.PerformBroadcastEDUResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformBroadcastEDU")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.federationAPIURL + FederationAPIPerformBroadcastEDUPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformBroadcastEDU", h.federationAPIURL+FederationAPIPerformBroadcastEDUPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
type getUserDevices struct {
|
||||
S gomatrixserverlib.ServerName
|
||||
UserID string
|
||||
Res *gomatrixserverlib.RespUserDevices
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) GetUserDevices(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, userID string,
|
||||
) (gomatrixserverlib.RespUserDevices, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "GetUserDevices")
|
||||
defer span.Finish()
|
||||
|
||||
var result gomatrixserverlib.RespUserDevices
|
||||
request := getUserDevices{
|
||||
S: s,
|
||||
UserID: userID,
|
||||
}
|
||||
var response getUserDevices
|
||||
apiURL := h.federationAPIURL + FederationAPIGetUserDevicesPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return result, response.Err
|
||||
}
|
||||
return *response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[getUserDevices, gomatrixserverlib.RespUserDevices, *api.FederationClientError](
|
||||
"GetUserDevices", h.federationAPIURL+FederationAPIGetUserDevicesPath, h.httpClient,
|
||||
ctx, &getUserDevices{
|
||||
S: s,
|
||||
UserID: userID,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type claimKeys struct {
|
||||
S gomatrixserverlib.ServerName
|
||||
OneTimeKeys map[string]map[string]string
|
||||
Res *gomatrixserverlib.RespClaimKeys
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) ClaimKeys(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, oneTimeKeys map[string]map[string]string,
|
||||
) (gomatrixserverlib.RespClaimKeys, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "ClaimKeys")
|
||||
defer span.Finish()
|
||||
|
||||
var result gomatrixserverlib.RespClaimKeys
|
||||
request := claimKeys{
|
||||
S: s,
|
||||
OneTimeKeys: oneTimeKeys,
|
||||
}
|
||||
var response claimKeys
|
||||
apiURL := h.federationAPIURL + FederationAPIClaimKeysPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return result, response.Err
|
||||
}
|
||||
return *response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[claimKeys, gomatrixserverlib.RespClaimKeys, *api.FederationClientError](
|
||||
"ClaimKeys", h.federationAPIURL+FederationAPIClaimKeysPath, h.httpClient,
|
||||
ctx, &claimKeys{
|
||||
S: s,
|
||||
OneTimeKeys: oneTimeKeys,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type queryKeys struct {
|
||||
S gomatrixserverlib.ServerName
|
||||
Keys map[string][]string
|
||||
Res *gomatrixserverlib.RespQueryKeys
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) QueryKeys(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, keys map[string][]string,
|
||||
) (gomatrixserverlib.RespQueryKeys, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryKeys")
|
||||
defer span.Finish()
|
||||
|
||||
var result gomatrixserverlib.RespQueryKeys
|
||||
request := queryKeys{
|
||||
S: s,
|
||||
Keys: keys,
|
||||
}
|
||||
var response queryKeys
|
||||
apiURL := h.federationAPIURL + FederationAPIQueryKeysPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return result, response.Err
|
||||
}
|
||||
return *response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[queryKeys, gomatrixserverlib.RespQueryKeys, *api.FederationClientError](
|
||||
"QueryKeys", h.federationAPIURL+FederationAPIQueryKeysPath, h.httpClient,
|
||||
ctx, &queryKeys{
|
||||
S: s,
|
||||
Keys: keys,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type backfill struct {
|
||||
|
|
@ -250,32 +206,20 @@ type backfill struct {
|
|||
RoomID string
|
||||
Limit int
|
||||
EventIDs []string
|
||||
Res *gomatrixserverlib.Transaction
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) Backfill(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, roomID string, limit int, eventIDs []string,
|
||||
) (gomatrixserverlib.Transaction, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "Backfill")
|
||||
defer span.Finish()
|
||||
|
||||
request := backfill{
|
||||
S: s,
|
||||
RoomID: roomID,
|
||||
Limit: limit,
|
||||
EventIDs: eventIDs,
|
||||
}
|
||||
var response backfill
|
||||
apiURL := h.federationAPIURL + FederationAPIBackfillPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return gomatrixserverlib.Transaction{}, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return gomatrixserverlib.Transaction{}, response.Err
|
||||
}
|
||||
return *response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[backfill, gomatrixserverlib.Transaction, *api.FederationClientError](
|
||||
"Backfill", h.federationAPIURL+FederationAPIBackfillPath, h.httpClient,
|
||||
ctx, &backfill{
|
||||
S: s,
|
||||
RoomID: roomID,
|
||||
Limit: limit,
|
||||
EventIDs: eventIDs,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type lookupState struct {
|
||||
|
|
@ -283,63 +227,39 @@ type lookupState struct {
|
|||
RoomID string
|
||||
EventID string
|
||||
RoomVersion gomatrixserverlib.RoomVersion
|
||||
Res *gomatrixserverlib.RespState
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) LookupState(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, roomID, eventID string, roomVersion gomatrixserverlib.RoomVersion,
|
||||
) (gomatrixserverlib.RespState, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "LookupState")
|
||||
defer span.Finish()
|
||||
|
||||
request := lookupState{
|
||||
S: s,
|
||||
RoomID: roomID,
|
||||
EventID: eventID,
|
||||
RoomVersion: roomVersion,
|
||||
}
|
||||
var response lookupState
|
||||
apiURL := h.federationAPIURL + FederationAPILookupStatePath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return gomatrixserverlib.RespState{}, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return gomatrixserverlib.RespState{}, response.Err
|
||||
}
|
||||
return *response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[lookupState, gomatrixserverlib.RespState, *api.FederationClientError](
|
||||
"LookupState", h.federationAPIURL+FederationAPILookupStatePath, h.httpClient,
|
||||
ctx, &lookupState{
|
||||
S: s,
|
||||
RoomID: roomID,
|
||||
EventID: eventID,
|
||||
RoomVersion: roomVersion,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type lookupStateIDs struct {
|
||||
S gomatrixserverlib.ServerName
|
||||
RoomID string
|
||||
EventID string
|
||||
Res *gomatrixserverlib.RespStateIDs
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) LookupStateIDs(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, roomID, eventID string,
|
||||
) (gomatrixserverlib.RespStateIDs, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "LookupStateIDs")
|
||||
defer span.Finish()
|
||||
|
||||
request := lookupStateIDs{
|
||||
S: s,
|
||||
RoomID: roomID,
|
||||
EventID: eventID,
|
||||
}
|
||||
var response lookupStateIDs
|
||||
apiURL := h.federationAPIURL + FederationAPILookupStateIDsPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return gomatrixserverlib.RespStateIDs{}, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return gomatrixserverlib.RespStateIDs{}, response.Err
|
||||
}
|
||||
return *response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[lookupStateIDs, gomatrixserverlib.RespStateIDs, *api.FederationClientError](
|
||||
"LookupStateIDs", h.federationAPIURL+FederationAPILookupStateIDsPath, h.httpClient,
|
||||
ctx, &lookupStateIDs{
|
||||
S: s,
|
||||
RoomID: roomID,
|
||||
EventID: eventID,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type lookupMissingEvents struct {
|
||||
|
|
@ -347,64 +267,38 @@ type lookupMissingEvents struct {
|
|||
RoomID string
|
||||
Missing gomatrixserverlib.MissingEvents
|
||||
RoomVersion gomatrixserverlib.RoomVersion
|
||||
Res struct {
|
||||
Events []gomatrixserverlib.RawJSON `json:"events"`
|
||||
}
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) LookupMissingEvents(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, roomID string,
|
||||
missing gomatrixserverlib.MissingEvents, roomVersion gomatrixserverlib.RoomVersion,
|
||||
) (res gomatrixserverlib.RespMissingEvents, err error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "LookupMissingEvents")
|
||||
defer span.Finish()
|
||||
|
||||
request := lookupMissingEvents{
|
||||
S: s,
|
||||
RoomID: roomID,
|
||||
Missing: missing,
|
||||
RoomVersion: roomVersion,
|
||||
}
|
||||
apiURL := h.federationAPIURL + FederationAPILookupMissingEventsPath
|
||||
err = httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &request)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
if request.Err != nil {
|
||||
return res, request.Err
|
||||
}
|
||||
res.Events = request.Res.Events
|
||||
return res, nil
|
||||
return httputil.CallInternalProxyAPI[lookupMissingEvents, gomatrixserverlib.RespMissingEvents, *api.FederationClientError](
|
||||
"LookupMissingEvents", h.federationAPIURL+FederationAPILookupMissingEventsPath, h.httpClient,
|
||||
ctx, &lookupMissingEvents{
|
||||
S: s,
|
||||
RoomID: roomID,
|
||||
Missing: missing,
|
||||
RoomVersion: roomVersion,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type getEvent struct {
|
||||
S gomatrixserverlib.ServerName
|
||||
EventID string
|
||||
Res *gomatrixserverlib.Transaction
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) GetEvent(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, eventID string,
|
||||
) (gomatrixserverlib.Transaction, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "GetEvent")
|
||||
defer span.Finish()
|
||||
|
||||
request := getEvent{
|
||||
S: s,
|
||||
EventID: eventID,
|
||||
}
|
||||
var response getEvent
|
||||
apiURL := h.federationAPIURL + FederationAPIGetEventPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return gomatrixserverlib.Transaction{}, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return gomatrixserverlib.Transaction{}, response.Err
|
||||
}
|
||||
return *response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[getEvent, gomatrixserverlib.Transaction, *api.FederationClientError](
|
||||
"GetEvent", h.federationAPIURL+FederationAPIGetEventPath, h.httpClient,
|
||||
ctx, &getEvent{
|
||||
S: s,
|
||||
EventID: eventID,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type getEventAuth struct {
|
||||
|
|
@ -412,135 +306,86 @@ type getEventAuth struct {
|
|||
RoomVersion gomatrixserverlib.RoomVersion
|
||||
RoomID string
|
||||
EventID string
|
||||
Res *gomatrixserverlib.RespEventAuth
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) GetEventAuth(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName,
|
||||
roomVersion gomatrixserverlib.RoomVersion, roomID, eventID string,
|
||||
) (gomatrixserverlib.RespEventAuth, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "GetEventAuth")
|
||||
defer span.Finish()
|
||||
|
||||
request := getEventAuth{
|
||||
S: s,
|
||||
RoomVersion: roomVersion,
|
||||
RoomID: roomID,
|
||||
EventID: eventID,
|
||||
}
|
||||
var response getEventAuth
|
||||
apiURL := h.federationAPIURL + FederationAPIGetEventAuthPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return gomatrixserverlib.RespEventAuth{}, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return gomatrixserverlib.RespEventAuth{}, response.Err
|
||||
}
|
||||
return *response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[getEventAuth, gomatrixserverlib.RespEventAuth, *api.FederationClientError](
|
||||
"GetEventAuth", h.federationAPIURL+FederationAPIGetEventAuthPath, h.httpClient,
|
||||
ctx, &getEventAuth{
|
||||
S: s,
|
||||
RoomVersion: roomVersion,
|
||||
RoomID: roomID,
|
||||
EventID: eventID,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) QueryServerKeys(
|
||||
ctx context.Context, req *api.QueryServerKeysRequest, res *api.QueryServerKeysResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerKeys")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.federationAPIURL + FederationAPIQueryServerKeysPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryServerKeys", h.federationAPIURL+FederationAPIQueryServerKeysPath,
|
||||
h.httpClient, ctx, req, res,
|
||||
)
|
||||
}
|
||||
|
||||
type lookupServerKeys struct {
|
||||
S gomatrixserverlib.ServerName
|
||||
KeyRequests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp
|
||||
ServerKeys []gomatrixserverlib.ServerKeys
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) LookupServerKeys(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, keyRequests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
|
||||
) ([]gomatrixserverlib.ServerKeys, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "LookupServerKeys")
|
||||
defer span.Finish()
|
||||
|
||||
request := lookupServerKeys{
|
||||
S: s,
|
||||
KeyRequests: keyRequests,
|
||||
}
|
||||
var response lookupServerKeys
|
||||
apiURL := h.federationAPIURL + FederationAPILookupServerKeysPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return []gomatrixserverlib.ServerKeys{}, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return []gomatrixserverlib.ServerKeys{}, response.Err
|
||||
}
|
||||
return response.ServerKeys, nil
|
||||
return httputil.CallInternalProxyAPI[lookupServerKeys, []gomatrixserverlib.ServerKeys, *api.FederationClientError](
|
||||
"LookupServerKeys", h.federationAPIURL+FederationAPILookupServerKeysPath, h.httpClient,
|
||||
ctx, &lookupServerKeys{
|
||||
S: s,
|
||||
KeyRequests: keyRequests,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type eventRelationships struct {
|
||||
S gomatrixserverlib.ServerName
|
||||
Req gomatrixserverlib.MSC2836EventRelationshipsRequest
|
||||
RoomVer gomatrixserverlib.RoomVersion
|
||||
Res gomatrixserverlib.MSC2836EventRelationshipsResponse
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) MSC2836EventRelationships(
|
||||
ctx context.Context, s gomatrixserverlib.ServerName, r gomatrixserverlib.MSC2836EventRelationshipsRequest,
|
||||
roomVersion gomatrixserverlib.RoomVersion,
|
||||
) (res gomatrixserverlib.MSC2836EventRelationshipsResponse, err error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "MSC2836EventRelationships")
|
||||
defer span.Finish()
|
||||
|
||||
request := eventRelationships{
|
||||
S: s,
|
||||
Req: r,
|
||||
RoomVer: roomVersion,
|
||||
}
|
||||
var response eventRelationships
|
||||
apiURL := h.federationAPIURL + FederationAPIEventRelationshipsPath
|
||||
err = httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return res, response.Err
|
||||
}
|
||||
return response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[eventRelationships, gomatrixserverlib.MSC2836EventRelationshipsResponse, *api.FederationClientError](
|
||||
"MSC2836EventRelationships", h.federationAPIURL+FederationAPIEventRelationshipsPath, h.httpClient,
|
||||
ctx, &eventRelationships{
|
||||
S: s,
|
||||
Req: r,
|
||||
RoomVer: roomVersion,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type spacesReq struct {
|
||||
S gomatrixserverlib.ServerName
|
||||
SuggestedOnly bool
|
||||
RoomID string
|
||||
Res gomatrixserverlib.MSC2946SpacesResponse
|
||||
Err *api.FederationClientError
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) MSC2946Spaces(
|
||||
ctx context.Context, dst gomatrixserverlib.ServerName, roomID string, suggestedOnly bool,
|
||||
) (res gomatrixserverlib.MSC2946SpacesResponse, err error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "MSC2946Spaces")
|
||||
defer span.Finish()
|
||||
|
||||
request := spacesReq{
|
||||
S: dst,
|
||||
SuggestedOnly: suggestedOnly,
|
||||
RoomID: roomID,
|
||||
}
|
||||
var response spacesReq
|
||||
apiURL := h.federationAPIURL + FederationAPISpacesSummaryPath
|
||||
err = httputil.PostJSON(ctx, span, h.httpClient, apiURL, &request, &response)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
if response.Err != nil {
|
||||
return res, response.Err
|
||||
}
|
||||
return response.Res, nil
|
||||
return httputil.CallInternalProxyAPI[spacesReq, gomatrixserverlib.MSC2946SpacesResponse, *api.FederationClientError](
|
||||
"MSC2836EventRelationships", h.federationAPIURL+FederationAPISpacesSummaryPath, h.httpClient,
|
||||
ctx, &spacesReq{
|
||||
S: dst,
|
||||
SuggestedOnly: suggestedOnly,
|
||||
RoomID: roomID,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (s *httpFederationInternalAPI) KeyRing() *gomatrixserverlib.KeyRing {
|
||||
|
|
@ -614,11 +459,10 @@ func (h *httpFederationInternalAPI) InputPublicKeys(
|
|||
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)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"InputPublicKey", h.federationAPIURL+FederationAPIInputPublicKeyPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpFederationInternalAPI) QueryPublicKeys(
|
||||
|
|
@ -626,9 +470,8 @@ func (h *httpFederationInternalAPI) QueryPublicKeys(
|
|||
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)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryPublicKeys", h.federationAPIURL+FederationAPIQueryPublicKeyPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
package inthttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/matrix-org/dendrite/federationapi/api"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
|
|
@ -15,372 +17,180 @@ import (
|
|||
func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIQueryJoinedHostServerNamesInRoomPath,
|
||||
httputil.MakeInternalAPI("QueryJoinedHostServerNamesInRoom", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryJoinedHostServerNamesInRoomRequest
|
||||
var response api.QueryJoinedHostServerNamesInRoomResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := intAPI.QueryJoinedHostServerNamesInRoom(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
)
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIPerformJoinRequestPath,
|
||||
httputil.MakeInternalAPI("PerformJoinRequest", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformJoinRequest
|
||||
var response api.PerformJoinResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
intAPI.PerformJoin(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
)
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIPerformLeaveRequestPath,
|
||||
httputil.MakeInternalAPI("PerformLeaveRequest", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformLeaveRequest
|
||||
var response api.PerformLeaveResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := intAPI.PerformLeave(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("FederationAPIQueryJoinedHostServerNamesInRoom", intAPI.QueryJoinedHostServerNamesInRoom),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIPerformInviteRequestPath,
|
||||
httputil.MakeInternalAPI("PerformInviteRequest", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformInviteRequest
|
||||
var response api.PerformInviteResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := intAPI.PerformInvite(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("FederationAPIPerformInvite", intAPI.PerformInvite),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIPerformLeaveRequestPath,
|
||||
httputil.MakeInternalRPCAPI("FederationAPIPerformLeave", intAPI.PerformLeave),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIPerformDirectoryLookupRequestPath,
|
||||
httputil.MakeInternalAPI("PerformDirectoryLookupRequest", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformDirectoryLookupRequest
|
||||
var response api.PerformDirectoryLookupResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := intAPI.PerformDirectoryLookup(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("FederationAPIPerformDirectoryLookupRequest", intAPI.PerformDirectoryLookup),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIPerformBroadcastEDUPath,
|
||||
httputil.MakeInternalAPI("PerformBroadcastEDU", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformBroadcastEDURequest
|
||||
var response api.PerformBroadcastEDUResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := intAPI.PerformBroadcastEDU(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("FederationAPIPerformBroadcastEDU", intAPI.PerformBroadcastEDU),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIPerformJoinRequestPath,
|
||||
httputil.MakeInternalRPCAPI(
|
||||
"FederationAPIPerformJoinRequest",
|
||||
func(ctx context.Context, req *api.PerformJoinRequest, res *api.PerformJoinResponse) error {
|
||||
intAPI.PerformJoin(ctx, req, res)
|
||||
return nil
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIGetUserDevicesPath,
|
||||
httputil.MakeInternalAPI("GetUserDevices", func(req *http.Request) util.JSONResponse {
|
||||
var request getUserDevices
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.GetUserDevices(req.Context(), request.S, request.UserID)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = &res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPIGetUserDevices",
|
||||
func(ctx context.Context, req *getUserDevices) (*gomatrixserverlib.RespUserDevices, error) {
|
||||
res, err := intAPI.GetUserDevices(ctx, req.S, req.UserID)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIClaimKeysPath,
|
||||
httputil.MakeInternalAPI("ClaimKeys", func(req *http.Request) util.JSONResponse {
|
||||
var request claimKeys
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.ClaimKeys(req.Context(), request.S, request.OneTimeKeys)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = &res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPIClaimKeys",
|
||||
func(ctx context.Context, req *claimKeys) (*gomatrixserverlib.RespClaimKeys, error) {
|
||||
res, err := intAPI.ClaimKeys(ctx, req.S, req.OneTimeKeys)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIQueryKeysPath,
|
||||
httputil.MakeInternalAPI("QueryKeys", func(req *http.Request) util.JSONResponse {
|
||||
var request queryKeys
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.QueryKeys(req.Context(), request.S, request.Keys)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = &res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPIQueryKeys",
|
||||
func(ctx context.Context, req *queryKeys) (*gomatrixserverlib.RespQueryKeys, error) {
|
||||
res, err := intAPI.QueryKeys(ctx, req.S, req.Keys)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIBackfillPath,
|
||||
httputil.MakeInternalAPI("Backfill", func(req *http.Request) util.JSONResponse {
|
||||
var request backfill
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.Backfill(req.Context(), request.S, request.RoomID, request.Limit, request.EventIDs)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = &res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPIBackfill",
|
||||
func(ctx context.Context, req *backfill) (*gomatrixserverlib.Transaction, error) {
|
||||
res, err := intAPI.Backfill(ctx, req.S, req.RoomID, req.Limit, req.EventIDs)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPILookupStatePath,
|
||||
httputil.MakeInternalAPI("LookupState", func(req *http.Request) util.JSONResponse {
|
||||
var request lookupState
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.LookupState(req.Context(), request.S, request.RoomID, request.EventID, request.RoomVersion)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = &res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPILookupState",
|
||||
func(ctx context.Context, req *lookupState) (*gomatrixserverlib.RespState, error) {
|
||||
res, err := intAPI.LookupState(ctx, req.S, req.RoomID, req.EventID, req.RoomVersion)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPILookupStateIDsPath,
|
||||
httputil.MakeInternalAPI("LookupStateIDs", func(req *http.Request) util.JSONResponse {
|
||||
var request lookupStateIDs
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.LookupStateIDs(req.Context(), request.S, request.RoomID, request.EventID)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = &res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPILookupStateIDs",
|
||||
func(ctx context.Context, req *lookupStateIDs) (*gomatrixserverlib.RespStateIDs, error) {
|
||||
res, err := intAPI.LookupStateIDs(ctx, req.S, req.RoomID, req.EventID)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPILookupMissingEventsPath,
|
||||
httputil.MakeInternalAPI("LookupMissingEvents", func(req *http.Request) util.JSONResponse {
|
||||
var request lookupMissingEvents
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.LookupMissingEvents(req.Context(), request.S, request.RoomID, request.Missing, request.RoomVersion)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, event := range res.Events {
|
||||
js, err := json.Marshal(event)
|
||||
if err != nil {
|
||||
return util.MessageResponse(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
request.Res.Events = append(request.Res.Events, js)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPILookupMissingEvents",
|
||||
func(ctx context.Context, req *lookupMissingEvents) (*gomatrixserverlib.RespMissingEvents, error) {
|
||||
res, err := intAPI.LookupMissingEvents(ctx, req.S, req.RoomID, req.Missing, req.RoomVersion)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIGetEventPath,
|
||||
httputil.MakeInternalAPI("GetEvent", func(req *http.Request) util.JSONResponse {
|
||||
var request getEvent
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.GetEvent(req.Context(), request.S, request.EventID)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = &res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPIGetEvent",
|
||||
func(ctx context.Context, req *getEvent) (*gomatrixserverlib.Transaction, error) {
|
||||
res, err := intAPI.GetEvent(ctx, req.S, req.EventID)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIGetEventAuthPath,
|
||||
httputil.MakeInternalAPI("GetEventAuth", func(req *http.Request) util.JSONResponse {
|
||||
var request getEventAuth
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.GetEventAuth(req.Context(), request.S, request.RoomVersion, request.RoomID, request.EventID)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = &res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPIGetEventAuth",
|
||||
func(ctx context.Context, req *getEventAuth) (*gomatrixserverlib.RespEventAuth, error) {
|
||||
res, err := intAPI.GetEventAuth(ctx, req.S, req.RoomVersion, req.RoomID, req.EventID)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIQueryServerKeysPath,
|
||||
httputil.MakeInternalAPI("QueryServerKeys", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryServerKeysRequest
|
||||
var response api.QueryServerKeysResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := intAPI.QueryServerKeys(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("FederationAPIQueryServerKeys", intAPI.QueryServerKeys),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPILookupServerKeysPath,
|
||||
httputil.MakeInternalAPI("LookupServerKeys", func(req *http.Request) util.JSONResponse {
|
||||
var request lookupServerKeys
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.LookupServerKeys(req.Context(), request.S, request.KeyRequests)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.ServerKeys = res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPILookupServerKeys",
|
||||
func(ctx context.Context, req *lookupServerKeys) (*[]gomatrixserverlib.ServerKeys, error) {
|
||||
res, err := intAPI.LookupServerKeys(ctx, req.S, req.KeyRequests)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPIEventRelationshipsPath,
|
||||
httputil.MakeInternalAPI("MSC2836EventRelationships", func(req *http.Request) util.JSONResponse {
|
||||
var request eventRelationships
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.MSC2836EventRelationships(req.Context(), request.S, request.Req, request.RoomVer)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPIMSC2836EventRelationships",
|
||||
func(ctx context.Context, req *eventRelationships) (*gomatrixserverlib.MSC2836EventRelationshipsResponse, error) {
|
||||
res, err := intAPI.MSC2836EventRelationships(ctx, req.S, req.Req, req.RoomVer)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
FederationAPISpacesSummaryPath,
|
||||
httputil.MakeInternalAPI("MSC2946SpacesSummary", func(req *http.Request) util.JSONResponse {
|
||||
var request spacesReq
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
res, err := intAPI.MSC2946Spaces(req.Context(), request.S, request.RoomID, request.SuggestedOnly)
|
||||
if err != nil {
|
||||
ferr, ok := err.(*api.FederationClientError)
|
||||
if ok {
|
||||
request.Err = ferr
|
||||
} else {
|
||||
request.Err = &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Res = res
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: request}
|
||||
}),
|
||||
httputil.MakeInternalProxyAPI(
|
||||
"FederationAPIMSC2946SpacesSummary",
|
||||
func(ctx context.Context, req *spacesReq) (*gomatrixserverlib.MSC2946SpacesResponse, error) {
|
||||
res, err := intAPI.MSC2946Spaces(ctx, req.S, req.RoomID, req.SuggestedOnly)
|
||||
return &res, federationClientError(err)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
// TODO: Look at this shape
|
||||
internalAPIMux.Handle(FederationAPIQueryPublicKeyPath,
|
||||
httputil.MakeInternalAPI("queryPublicKeys", func(req *http.Request) util.JSONResponse {
|
||||
httputil.MakeInternalAPI("FederationAPIQueryPublicKeys", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryPublicKeysRequest{}
|
||||
response := api.QueryPublicKeysResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
|
|
@ -394,8 +204,10 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
|||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
)
|
||||
|
||||
// TODO: Look at this shape
|
||||
internalAPIMux.Handle(FederationAPIInputPublicKeyPath,
|
||||
httputil.MakeInternalAPI("inputPublicKeys", func(req *http.Request) util.JSONResponse {
|
||||
httputil.MakeInternalAPI("FederationAPIInputPublicKeys", func(req *http.Request) util.JSONResponse {
|
||||
request := api.InputPublicKeysRequest{}
|
||||
response := api.InputPublicKeysResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
|
|
@ -408,3 +220,18 @@ func AddRoutes(intAPI api.FederationInternalAPI, internalAPIMux *mux.Router) {
|
|||
}),
|
||||
)
|
||||
}
|
||||
|
||||
func federationClientError(err error) error {
|
||||
switch ferr := err.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case api.FederationClientError:
|
||||
return &ferr
|
||||
case *api.FederationClientError:
|
||||
return ferr
|
||||
default:
|
||||
return &api.FederationClientError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ func (oq *destinationQueue) sendEDU(event *gomatrixserverlib.EDU, receipt *share
|
|||
oq.destination, // the destination server name
|
||||
receipt, // NIDs from federationapi_queue_json table
|
||||
event.Type,
|
||||
nil, // this will use the default expireEDUTypes map
|
||||
); err != nil {
|
||||
logrus.WithError(err).Errorf("failed to associate EDU with destination %q", oq.destination)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ func (oqs *OutgoingQueues) getQueue(destination gomatrixserverlib.ServerName) *d
|
|||
oqs.queuesMutex.Lock()
|
||||
defer oqs.queuesMutex.Unlock()
|
||||
oq, ok := oqs.queues[destination]
|
||||
if !ok || oq != nil {
|
||||
if !ok || oq == nil {
|
||||
destinationQueueTotal.Inc()
|
||||
oq = &destinationQueue{
|
||||
queues: oqs,
|
||||
|
|
|
|||
|
|
@ -30,9 +30,11 @@ func GetUserDevices(
|
|||
userID string,
|
||||
) util.JSONResponse {
|
||||
var res keyapi.QueryDeviceMessagesResponse
|
||||
keyAPI.QueryDeviceMessages(req.Context(), &keyapi.QueryDeviceMessagesRequest{
|
||||
if err := keyAPI.QueryDeviceMessages(req.Context(), &keyapi.QueryDeviceMessagesRequest{
|
||||
UserID: userID,
|
||||
}, &res)
|
||||
}, &res); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if res.Error != nil {
|
||||
util.GetLogger(req.Context()).WithError(res.Error).Error("keyAPI.QueryDeviceMessages failed")
|
||||
return jsonerror.InternalServerError()
|
||||
|
|
@ -47,7 +49,9 @@ func GetUserDevices(
|
|||
for _, dev := range res.Devices {
|
||||
sigReq.TargetIDs[userID] = append(sigReq.TargetIDs[userID], gomatrixserverlib.KeyID(dev.DeviceID))
|
||||
}
|
||||
keyAPI.QuerySignatures(req.Context(), sigReq, sigRes)
|
||||
if err := keyAPI.QuerySignatures(req.Context(), sigReq, sigRes); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
|
||||
response := gomatrixserverlib.RespUserDevices{
|
||||
UserID: userID,
|
||||
|
|
|
|||
|
|
@ -21,13 +21,14 @@ import (
|
|||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// MakeJoin implements the /make_join API
|
||||
|
|
@ -391,7 +392,7 @@ func SendJoin(
|
|||
// the room, so set SendAsServer to cfg.Matrix.ServerName
|
||||
if !alreadyJoined {
|
||||
var response api.InputRoomEventsResponse
|
||||
rsAPI.InputRoomEvents(httpReq.Context(), &api.InputRoomEventsRequest{
|
||||
if err := rsAPI.InputRoomEvents(httpReq.Context(), &api.InputRoomEventsRequest{
|
||||
InputRoomEvents: []api.InputRoomEvent{
|
||||
{
|
||||
Kind: api.KindNew,
|
||||
|
|
@ -400,7 +401,9 @@ func SendJoin(
|
|||
TransactionID: nil,
|
||||
},
|
||||
},
|
||||
}, &response)
|
||||
}, &response); err != nil {
|
||||
return jsonerror.InternalAPIError(httpReq.Context(), err)
|
||||
}
|
||||
if response.ErrMsg != "" {
|
||||
util.GetLogger(httpReq.Context()).WithField(logrus.ErrorKey, response.ErrMsg).Error("SendEvents failed")
|
||||
if response.NotAllowed {
|
||||
|
|
@ -435,13 +438,13 @@ func SendJoin(
|
|||
// a restricted room join. If the room version does not support restricted
|
||||
// joins then this function returns with no side effects. This returns three
|
||||
// values:
|
||||
// * an optional JSON response body (i.e. M_UNABLE_TO_AUTHORISE_JOIN) which
|
||||
// should always be sent back to the client if one is specified
|
||||
// * a user ID of an authorising user, typically a user that has power to
|
||||
// issue invites in the room, if one has been found
|
||||
// * an error if there was a problem finding out if this was allowable,
|
||||
// like if the room version isn't known or a problem happened talking to
|
||||
// the roomserver
|
||||
// - an optional JSON response body (i.e. M_UNABLE_TO_AUTHORISE_JOIN) which
|
||||
// should always be sent back to the client if one is specified
|
||||
// - a user ID of an authorising user, typically a user that has power to
|
||||
// issue invites in the room, if one has been found
|
||||
// - an error if there was a problem finding out if this was allowable,
|
||||
// like if the room version isn't known or a problem happened talking to
|
||||
// the roomserver
|
||||
func checkRestrictedJoin(
|
||||
httpReq *http.Request,
|
||||
rsAPI api.FederationRoomserverAPI,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||
clienthttputil "github.com/matrix-org/dendrite/clientapi/httputil"
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
|
||||
"github.com/matrix-org/dendrite/keyserver/api"
|
||||
|
|
@ -61,9 +61,11 @@ func QueryDeviceKeys(
|
|||
}
|
||||
|
||||
var queryRes api.QueryKeysResponse
|
||||
keyAPI.QueryKeys(httpReq.Context(), &api.QueryKeysRequest{
|
||||
if err := keyAPI.QueryKeys(httpReq.Context(), &api.QueryKeysRequest{
|
||||
UserToDevices: qkr.DeviceKeys,
|
||||
}, &queryRes)
|
||||
}, &queryRes); err != nil {
|
||||
return jsonerror.InternalAPIError(httpReq.Context(), err)
|
||||
}
|
||||
if queryRes.Error != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(queryRes.Error).Error("Failed to QueryKeys")
|
||||
return jsonerror.InternalServerError()
|
||||
|
|
@ -113,9 +115,11 @@ func ClaimOneTimeKeys(
|
|||
}
|
||||
|
||||
var claimRes api.PerformClaimKeysResponse
|
||||
keyAPI.PerformClaimKeys(httpReq.Context(), &api.PerformClaimKeysRequest{
|
||||
if err := keyAPI.PerformClaimKeys(httpReq.Context(), &api.PerformClaimKeysRequest{
|
||||
OneTimeKeys: cor.OneTimeKeys,
|
||||
}, &claimRes)
|
||||
}, &claimRes); err != nil {
|
||||
return jsonerror.InternalAPIError(httpReq.Context(), err)
|
||||
}
|
||||
if claimRes.Error != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(claimRes.Error).Error("Failed to PerformClaimKeys")
|
||||
return jsonerror.InternalServerError()
|
||||
|
|
@ -184,7 +188,7 @@ func NotaryKeys(
|
|||
) util.JSONResponse {
|
||||
if req == nil {
|
||||
req = &gomatrixserverlib.PublicKeyNotaryLookupRequest{}
|
||||
if reqErr := httputil.UnmarshalJSONRequest(httpReq, &req); reqErr != nil {
|
||||
if reqErr := clienthttputil.UnmarshalJSONRequest(httpReq, &req); reqErr != nil {
|
||||
return *reqErr
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ func SendLeave(
|
|||
// We are responsible for notifying other servers that the user has left
|
||||
// the room, so set SendAsServer to cfg.Matrix.ServerName
|
||||
var response api.InputRoomEventsResponse
|
||||
rsAPI.InputRoomEvents(httpReq.Context(), &api.InputRoomEventsRequest{
|
||||
if err := rsAPI.InputRoomEvents(httpReq.Context(), &api.InputRoomEventsRequest{
|
||||
InputRoomEvents: []api.InputRoomEvent{
|
||||
{
|
||||
Kind: api.KindNew,
|
||||
|
|
@ -286,7 +286,9 @@ func SendLeave(
|
|||
TransactionID: nil,
|
||||
},
|
||||
},
|
||||
}, &response)
|
||||
}, &response); err != nil {
|
||||
return jsonerror.InternalAPIError(httpReq.Context(), err)
|
||||
}
|
||||
|
||||
if response.ErrMsg != "" {
|
||||
util.GetLogger(httpReq.Context()).WithField(logrus.ErrorKey, response.ErrMsg).WithField("not_allowed", response.NotAllowed).Error("producer.SendEvents failed")
|
||||
|
|
|
|||
|
|
@ -458,7 +458,9 @@ func (t *txnReq) processSigningKeyUpdate(ctx context.Context, e gomatrixserverli
|
|||
UserID: updatePayload.UserID,
|
||||
}
|
||||
uploadRes := &keyapi.PerformUploadDeviceKeysResponse{}
|
||||
t.keyAPI.PerformUploadDeviceKeys(ctx, uploadReq, uploadRes)
|
||||
if err := t.keyAPI.PerformUploadDeviceKeys(ctx, uploadReq, uploadRes); err != nil {
|
||||
return err
|
||||
}
|
||||
if uploadRes.Error != nil {
|
||||
return uploadRes.Error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,11 +64,12 @@ func (t *testRoomserverAPI) InputRoomEvents(
|
|||
ctx context.Context,
|
||||
request *api.InputRoomEventsRequest,
|
||||
response *api.InputRoomEventsResponse,
|
||||
) {
|
||||
) error {
|
||||
t.inputRoomEvents = append(t.inputRoomEvents, request.InputRoomEvents...)
|
||||
for _, ire := range request.InputRoomEvents {
|
||||
fmt.Println("InputRoomEvents: ", ire.Event.EventID())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Query the latest events and state for a room from the room server.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ package storage
|
|||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/federationapi/storage/shared"
|
||||
"github.com/matrix-org/dendrite/federationapi/types"
|
||||
|
|
@ -38,7 +39,7 @@ type Database interface {
|
|||
GetPendingEDUs(ctx context.Context, serverName gomatrixserverlib.ServerName, limit int) (edus map[*shared.Receipt]*gomatrixserverlib.EDU, err error)
|
||||
|
||||
AssociatePDUWithDestination(ctx context.Context, transactionID gomatrixserverlib.TransactionID, serverName gomatrixserverlib.ServerName, receipt *shared.Receipt) error
|
||||
AssociateEDUWithDestination(ctx context.Context, serverName gomatrixserverlib.ServerName, receipt *shared.Receipt, eduType string) error
|
||||
AssociateEDUWithDestination(ctx context.Context, serverName gomatrixserverlib.ServerName, receipt *shared.Receipt, eduType string, expireEDUTypes map[string]time.Duration) error
|
||||
|
||||
CleanPDUs(ctx context.Context, serverName gomatrixserverlib.ServerName, receipts []*shared.Receipt) error
|
||||
CleanEDUs(ctx context.Context, serverName gomatrixserverlib.ServerName, receipts []*shared.Receipt) error
|
||||
|
|
@ -70,4 +71,6 @@ type Database interface {
|
|||
// 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))
|
||||
// such that the combination of all server keys will include all the `optKeyIDs`.
|
||||
GetNotaryKeys(ctx context.Context, serverName gomatrixserverlib.ServerName, optKeyIDs []gomatrixserverlib.KeyID) ([]gomatrixserverlib.ServerKeys, error)
|
||||
// DeleteExpiredEDUs cleans up expired EDUs
|
||||
DeleteExpiredEDUs(ctx context.Context) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2022 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 deltas
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
func UpAddexpiresat(ctx context.Context, tx *sql.Tx) error {
|
||||
_, err := tx.ExecContext(ctx, "ALTER TABLE federationsender_queue_edus ADD COLUMN IF NOT EXISTS expires_at BIGINT NOT NULL DEFAULT 0;")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute upgrade: %w", err)
|
||||
}
|
||||
_, err = tx.ExecContext(ctx, "UPDATE federationsender_queue_edus SET expires_at = $1 WHERE edu_type != 'm.direct_to_device'", gomatrixserverlib.AsTimestamp(time.Now().Add(time.Hour*24)))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update queue_edus: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DownAddexpiresat(ctx context.Context, tx *sql.Tx) error {
|
||||
_, err := tx.ExecContext(ctx, "ALTER TABLE federationsender_queue_edus DROP COLUMN expires_at;")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute downgrade: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -19,9 +19,11 @@ import (
|
|||
"database/sql"
|
||||
|
||||
"github.com/lib/pq"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
||||
"github.com/matrix-org/dendrite/federationapi/storage/postgres/deltas"
|
||||
"github.com/matrix-org/dendrite/internal"
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
const queueEDUsSchema = `
|
||||
|
|
@ -31,7 +33,9 @@ CREATE TABLE IF NOT EXISTS federationsender_queue_edus (
|
|||
-- The domain part of the user ID the EDU event is for.
|
||||
server_name TEXT NOT NULL,
|
||||
-- The JSON NID from the federationsender_queue_edus_json table.
|
||||
json_nid BIGINT NOT NULL
|
||||
json_nid BIGINT NOT NULL,
|
||||
-- The expiry time of this edu, if any.
|
||||
expires_at BIGINT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS federationsender_queue_edus_json_nid_idx
|
||||
|
|
@ -43,8 +47,8 @@ CREATE INDEX IF NOT EXISTS federationsender_queue_edus_server_name_idx
|
|||
`
|
||||
|
||||
const insertQueueEDUSQL = "" +
|
||||
"INSERT INTO federationsender_queue_edus (edu_type, server_name, json_nid)" +
|
||||
" VALUES ($1, $2, $3)"
|
||||
"INSERT INTO federationsender_queue_edus (edu_type, server_name, json_nid, expires_at)" +
|
||||
" VALUES ($1, $2, $3, $4)"
|
||||
|
||||
const deleteQueueEDUSQL = "" +
|
||||
"DELETE FROM federationsender_queue_edus WHERE server_name = $1 AND json_nid = ANY($2)"
|
||||
|
|
@ -65,6 +69,12 @@ const selectQueueEDUCountSQL = "" +
|
|||
const selectQueueServerNamesSQL = "" +
|
||||
"SELECT DISTINCT server_name FROM federationsender_queue_edus"
|
||||
|
||||
const selectExpiredEDUsSQL = "" +
|
||||
"SELECT DISTINCT json_nid FROM federationsender_queue_edus WHERE expires_at > 0 AND expires_at <= $1"
|
||||
|
||||
const deleteExpiredEDUsSQL = "" +
|
||||
"DELETE FROM federationsender_queue_edus WHERE expires_at > 0 AND expires_at <= $1"
|
||||
|
||||
type queueEDUsStatements struct {
|
||||
db *sql.DB
|
||||
insertQueueEDUStmt *sql.Stmt
|
||||
|
|
@ -73,6 +83,8 @@ type queueEDUsStatements struct {
|
|||
selectQueueEDUReferenceJSONCountStmt *sql.Stmt
|
||||
selectQueueEDUCountStmt *sql.Stmt
|
||||
selectQueueEDUServerNamesStmt *sql.Stmt
|
||||
selectExpiredEDUsStmt *sql.Stmt
|
||||
deleteExpiredEDUsStmt *sql.Stmt
|
||||
}
|
||||
|
||||
func NewPostgresQueueEDUsTable(db *sql.DB) (s *queueEDUsStatements, err error) {
|
||||
|
|
@ -81,27 +93,34 @@ func NewPostgresQueueEDUsTable(db *sql.DB) (s *queueEDUsStatements, err error) {
|
|||
}
|
||||
_, err = s.db.Exec(queueEDUsSchema)
|
||||
if err != nil {
|
||||
return
|
||||
return s, err
|
||||
}
|
||||
if s.insertQueueEDUStmt, err = s.db.Prepare(insertQueueEDUSQL); err != nil {
|
||||
return
|
||||
|
||||
m := sqlutil.NewMigrator(db)
|
||||
m.AddMigrations(
|
||||
sqlutil.Migration{
|
||||
Version: "federationapi: add expiresat column",
|
||||
Up: deltas.UpAddexpiresat,
|
||||
},
|
||||
)
|
||||
if err := m.Up(context.Background()); err != nil {
|
||||
return s, err
|
||||
}
|
||||
if s.deleteQueueEDUStmt, err = s.db.Prepare(deleteQueueEDUSQL); err != nil {
|
||||
return
|
||||
}
|
||||
if s.selectQueueEDUStmt, err = s.db.Prepare(selectQueueEDUSQL); err != nil {
|
||||
return
|
||||
}
|
||||
if s.selectQueueEDUReferenceJSONCountStmt, err = s.db.Prepare(selectQueueEDUReferenceJSONCountSQL); err != nil {
|
||||
return
|
||||
}
|
||||
if s.selectQueueEDUCountStmt, err = s.db.Prepare(selectQueueEDUCountSQL); err != nil {
|
||||
return
|
||||
}
|
||||
if s.selectQueueEDUServerNamesStmt, err = s.db.Prepare(selectQueueServerNamesSQL); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) Prepare() error {
|
||||
return sqlutil.StatementList{
|
||||
{&s.insertQueueEDUStmt, insertQueueEDUSQL},
|
||||
{&s.deleteQueueEDUStmt, deleteQueueEDUSQL},
|
||||
{&s.selectQueueEDUStmt, selectQueueEDUSQL},
|
||||
{&s.selectQueueEDUReferenceJSONCountStmt, selectQueueEDUReferenceJSONCountSQL},
|
||||
{&s.selectQueueEDUCountStmt, selectQueueEDUCountSQL},
|
||||
{&s.selectQueueEDUServerNamesStmt, selectQueueServerNamesSQL},
|
||||
{&s.selectExpiredEDUsStmt, selectExpiredEDUsSQL},
|
||||
{&s.deleteExpiredEDUsStmt, deleteExpiredEDUsSQL},
|
||||
}.Prepare(s.db)
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) InsertQueueEDU(
|
||||
|
|
@ -110,6 +129,7 @@ func (s *queueEDUsStatements) InsertQueueEDU(
|
|||
eduType string,
|
||||
serverName gomatrixserverlib.ServerName,
|
||||
nid int64,
|
||||
expiresAt gomatrixserverlib.Timestamp,
|
||||
) error {
|
||||
stmt := sqlutil.TxStmt(txn, s.insertQueueEDUStmt)
|
||||
_, err := stmt.ExecContext(
|
||||
|
|
@ -117,6 +137,7 @@ func (s *queueEDUsStatements) InsertQueueEDU(
|
|||
eduType, // the EDU type
|
||||
serverName, // destination server name
|
||||
nid, // JSON blob NID
|
||||
expiresAt, // timestamp of expiry
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
|
@ -150,7 +171,7 @@ func (s *queueEDUsStatements) SelectQueueEDUs(
|
|||
}
|
||||
result = append(result, nid)
|
||||
}
|
||||
return result, nil
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) SelectQueueEDUReferenceJSONCount(
|
||||
|
|
@ -200,3 +221,33 @@ func (s *queueEDUsStatements) SelectQueueEDUServerNames(
|
|||
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) SelectExpiredEDUs(
|
||||
ctx context.Context, txn *sql.Tx,
|
||||
expiredBefore gomatrixserverlib.Timestamp,
|
||||
) ([]int64, error) {
|
||||
stmt := sqlutil.TxStmt(txn, s.selectExpiredEDUsStmt)
|
||||
rows, err := stmt.QueryContext(ctx, expiredBefore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer internal.CloseAndLogIfError(ctx, rows, "SelectExpiredEDUs: rows.close() failed")
|
||||
var result []int64
|
||||
var nid int64
|
||||
for rows.Next() {
|
||||
if err = rows.Scan(&nid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, nid)
|
||||
}
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) DeleteExpiredEDUs(
|
||||
ctx context.Context, txn *sql.Tx,
|
||||
expiredBefore gomatrixserverlib.Timestamp,
|
||||
) error {
|
||||
stmt := sqlutil.TxStmt(txn, s.deleteExpiredEDUsStmt)
|
||||
_, err := stmt.ExecContext(ctx, expiredBefore)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = queueEDUs.Prepare(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.Database = shared.Database{
|
||||
DB: d.db,
|
||||
ServerName: serverName,
|
||||
|
|
|
|||
|
|
@ -20,10 +20,21 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
// defaultExpiry for EDUs if not listed below
|
||||
var defaultExpiry = time.Hour * 24
|
||||
|
||||
// defaultExpireEDUTypes contains EDUs which can/should be expired after a given time
|
||||
// if the target server isn't reachable for some reason.
|
||||
var defaultExpireEDUTypes = map[string]time.Duration{
|
||||
gomatrixserverlib.MTyping: time.Minute,
|
||||
gomatrixserverlib.MPresence: time.Minute * 10,
|
||||
}
|
||||
|
||||
// AssociateEDUWithDestination creates an association that the
|
||||
// destination queues will use to determine which JSON blobs to send
|
||||
// to which servers.
|
||||
|
|
@ -32,7 +43,21 @@ func (d *Database) AssociateEDUWithDestination(
|
|||
serverName gomatrixserverlib.ServerName,
|
||||
receipt *Receipt,
|
||||
eduType string,
|
||||
expireEDUTypes map[string]time.Duration,
|
||||
) error {
|
||||
if expireEDUTypes == nil {
|
||||
expireEDUTypes = defaultExpireEDUTypes
|
||||
}
|
||||
expiresAt := gomatrixserverlib.AsTimestamp(time.Now().Add(defaultExpiry))
|
||||
if duration, ok := expireEDUTypes[eduType]; ok {
|
||||
// Keep EDUs for at least x minutes before deleting them
|
||||
expiresAt = gomatrixserverlib.AsTimestamp(time.Now().Add(duration))
|
||||
}
|
||||
// We forcibly set m.direct_to_device events to 0, as we always want them
|
||||
// to be delivered. (required for E2EE)
|
||||
if eduType == gomatrixserverlib.MDirectToDevice {
|
||||
expiresAt = 0
|
||||
}
|
||||
return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||
if err := d.FederationQueueEDUs.InsertQueueEDU(
|
||||
ctx, // context
|
||||
|
|
@ -40,6 +65,7 @@ func (d *Database) AssociateEDUWithDestination(
|
|||
eduType, // EDU type for coalescing
|
||||
serverName, // destination server name
|
||||
receipt.nid, // NID from the federationapi_queue_json table
|
||||
expiresAt, // The timestamp this EDU will expire
|
||||
); err != nil {
|
||||
return fmt.Errorf("InsertQueueEDU: %w", err)
|
||||
}
|
||||
|
|
@ -150,3 +176,26 @@ func (d *Database) GetPendingEDUServerNames(
|
|||
) ([]gomatrixserverlib.ServerName, error) {
|
||||
return d.FederationQueueEDUs.SelectQueueEDUServerNames(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteExpiredEDUs deletes expired EDUs
|
||||
func (d *Database) DeleteExpiredEDUs(ctx context.Context) error {
|
||||
return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||
expiredBefore := gomatrixserverlib.AsTimestamp(time.Now())
|
||||
jsonNIDs, err := d.FederationQueueEDUs.SelectExpiredEDUs(ctx, txn, expiredBefore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(jsonNIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
for i := range jsonNIDs {
|
||||
d.Cache.EvictFederationQueuedEDU(jsonNIDs[i])
|
||||
}
|
||||
|
||||
if err = d.FederationQueueJSON.DeleteQueueJSON(ctx, txn, jsonNIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return d.FederationQueueEDUs.DeleteExpiredEDUs(ctx, txn, expiredBefore)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2022 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 deltas
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
func UpAddexpiresat(ctx context.Context, tx *sql.Tx) error {
|
||||
_, err := tx.ExecContext(ctx, "ALTER TABLE federationsender_queue_edus RENAME TO federationsender_queue_edus_old;")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to rename table: %w", err)
|
||||
}
|
||||
|
||||
_, err = tx.ExecContext(ctx, `
|
||||
CREATE TABLE IF NOT EXISTS federationsender_queue_edus (
|
||||
edu_type TEXT NOT NULL,
|
||||
server_name TEXT NOT NULL,
|
||||
json_nid BIGINT NOT NULL,
|
||||
expires_at BIGINT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS federationsender_queue_edus_json_nid_idx
|
||||
ON federationsender_queue_edus (json_nid, server_name);
|
||||
`)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create new table: %w", err)
|
||||
}
|
||||
_, err = tx.ExecContext(ctx, `
|
||||
INSERT
|
||||
INTO federationsender_queue_edus (
|
||||
edu_type, server_name, json_nid, expires_at
|
||||
) SELECT edu_type, server_name, json_nid, 0 FROM federationsender_queue_edus_old;
|
||||
`)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update queue_edus: %w", err)
|
||||
}
|
||||
_, err = tx.ExecContext(ctx, "UPDATE federationsender_queue_edus SET expires_at = $1 WHERE edu_type != 'm.direct_to_device'", gomatrixserverlib.AsTimestamp(time.Now().Add(time.Hour*24)))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update queue_edus: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DownAddexpiresat(ctx context.Context, tx *sql.Tx) error {
|
||||
_, err := tx.ExecContext(ctx, "ALTER TABLE federationsender_queue_edus DROP COLUMN expires_at;")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to rename table: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -20,9 +20,11 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
||||
"github.com/matrix-org/dendrite/federationapi/storage/sqlite3/deltas"
|
||||
"github.com/matrix-org/dendrite/internal"
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
const queueEDUsSchema = `
|
||||
|
|
@ -32,7 +34,9 @@ CREATE TABLE IF NOT EXISTS federationsender_queue_edus (
|
|||
-- The domain part of the user ID the EDU event is for.
|
||||
server_name TEXT NOT NULL,
|
||||
-- The JSON NID from the federationsender_queue_edus_json table.
|
||||
json_nid BIGINT NOT NULL
|
||||
json_nid BIGINT NOT NULL,
|
||||
-- The expiry time of this edu, if any.
|
||||
expires_at BIGINT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS federationsender_queue_edus_json_nid_idx
|
||||
|
|
@ -44,8 +48,8 @@ CREATE INDEX IF NOT EXISTS federationsender_queue_edus_server_name_idx
|
|||
`
|
||||
|
||||
const insertQueueEDUSQL = "" +
|
||||
"INSERT INTO federationsender_queue_edus (edu_type, server_name, json_nid)" +
|
||||
" VALUES ($1, $2, $3)"
|
||||
"INSERT INTO federationsender_queue_edus (edu_type, server_name, json_nid, expires_at)" +
|
||||
" VALUES ($1, $2, $3, $4)"
|
||||
|
||||
const deleteQueueEDUsSQL = "" +
|
||||
"DELETE FROM federationsender_queue_edus WHERE server_name = $1 AND json_nid IN ($2)"
|
||||
|
|
@ -66,13 +70,22 @@ const selectQueueEDUCountSQL = "" +
|
|||
const selectQueueServerNamesSQL = "" +
|
||||
"SELECT DISTINCT server_name FROM federationsender_queue_edus"
|
||||
|
||||
const selectExpiredEDUsSQL = "" +
|
||||
"SELECT DISTINCT json_nid FROM federationsender_queue_edus WHERE expires_at > 0 AND expires_at <= $1"
|
||||
|
||||
const deleteExpiredEDUsSQL = "" +
|
||||
"DELETE FROM federationsender_queue_edus WHERE expires_at > 0 AND expires_at <= $1"
|
||||
|
||||
type queueEDUsStatements struct {
|
||||
db *sql.DB
|
||||
insertQueueEDUStmt *sql.Stmt
|
||||
db *sql.DB
|
||||
insertQueueEDUStmt *sql.Stmt
|
||||
// deleteQueueEDUStmt *sql.Stmt - prepared at runtime due to variadic
|
||||
selectQueueEDUStmt *sql.Stmt
|
||||
selectQueueEDUReferenceJSONCountStmt *sql.Stmt
|
||||
selectQueueEDUCountStmt *sql.Stmt
|
||||
selectQueueEDUServerNamesStmt *sql.Stmt
|
||||
selectExpiredEDUsStmt *sql.Stmt
|
||||
deleteExpiredEDUsStmt *sql.Stmt
|
||||
}
|
||||
|
||||
func NewSQLiteQueueEDUsTable(db *sql.DB) (s *queueEDUsStatements, err error) {
|
||||
|
|
@ -81,24 +94,33 @@ func NewSQLiteQueueEDUsTable(db *sql.DB) (s *queueEDUsStatements, err error) {
|
|||
}
|
||||
_, err = db.Exec(queueEDUsSchema)
|
||||
if err != nil {
|
||||
return
|
||||
return s, err
|
||||
}
|
||||
if s.insertQueueEDUStmt, err = db.Prepare(insertQueueEDUSQL); err != nil {
|
||||
return
|
||||
|
||||
m := sqlutil.NewMigrator(db)
|
||||
m.AddMigrations(
|
||||
sqlutil.Migration{
|
||||
Version: "federationapi: add expiresat column",
|
||||
Up: deltas.UpAddexpiresat,
|
||||
},
|
||||
)
|
||||
if err := m.Up(context.Background()); err != nil {
|
||||
return s, err
|
||||
}
|
||||
if s.selectQueueEDUStmt, err = db.Prepare(selectQueueEDUSQL); err != nil {
|
||||
return
|
||||
}
|
||||
if s.selectQueueEDUReferenceJSONCountStmt, err = db.Prepare(selectQueueEDUReferenceJSONCountSQL); err != nil {
|
||||
return
|
||||
}
|
||||
if s.selectQueueEDUCountStmt, err = db.Prepare(selectQueueEDUCountSQL); err != nil {
|
||||
return
|
||||
}
|
||||
if s.selectQueueEDUServerNamesStmt, err = db.Prepare(selectQueueServerNamesSQL); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) Prepare() error {
|
||||
return sqlutil.StatementList{
|
||||
{&s.insertQueueEDUStmt, insertQueueEDUSQL},
|
||||
{&s.selectQueueEDUStmt, selectQueueEDUSQL},
|
||||
{&s.selectQueueEDUReferenceJSONCountStmt, selectQueueEDUReferenceJSONCountSQL},
|
||||
{&s.selectQueueEDUCountStmt, selectQueueEDUCountSQL},
|
||||
{&s.selectQueueEDUServerNamesStmt, selectQueueServerNamesSQL},
|
||||
{&s.selectExpiredEDUsStmt, selectExpiredEDUsSQL},
|
||||
{&s.deleteExpiredEDUsStmt, deleteExpiredEDUsSQL},
|
||||
}.Prepare(s.db)
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) InsertQueueEDU(
|
||||
|
|
@ -107,6 +129,7 @@ func (s *queueEDUsStatements) InsertQueueEDU(
|
|||
eduType string,
|
||||
serverName gomatrixserverlib.ServerName,
|
||||
nid int64,
|
||||
expiresAt gomatrixserverlib.Timestamp,
|
||||
) error {
|
||||
stmt := sqlutil.TxStmt(txn, s.insertQueueEDUStmt)
|
||||
_, err := stmt.ExecContext(
|
||||
|
|
@ -114,6 +137,7 @@ func (s *queueEDUsStatements) InsertQueueEDU(
|
|||
eduType, // the EDU type
|
||||
serverName, // destination server name
|
||||
nid, // JSON blob NID
|
||||
expiresAt, // timestamp of expiry
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
|
@ -159,7 +183,7 @@ func (s *queueEDUsStatements) SelectQueueEDUs(
|
|||
}
|
||||
result = append(result, nid)
|
||||
}
|
||||
return result, nil
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) SelectQueueEDUReferenceJSONCount(
|
||||
|
|
@ -209,3 +233,33 @@ func (s *queueEDUsStatements) SelectQueueEDUServerNames(
|
|||
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) SelectExpiredEDUs(
|
||||
ctx context.Context, txn *sql.Tx,
|
||||
expiredBefore gomatrixserverlib.Timestamp,
|
||||
) ([]int64, error) {
|
||||
stmt := sqlutil.TxStmt(txn, s.selectExpiredEDUsStmt)
|
||||
rows, err := stmt.QueryContext(ctx, expiredBefore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer internal.CloseAndLogIfError(ctx, rows, "SelectExpiredEDUs: rows.close() failed")
|
||||
var result []int64
|
||||
var nid int64
|
||||
for rows.Next() {
|
||||
if err = rows.Scan(&nid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, nid)
|
||||
}
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
func (s *queueEDUsStatements) DeleteExpiredEDUs(
|
||||
ctx context.Context, txn *sql.Tx,
|
||||
expiredBefore gomatrixserverlib.Timestamp,
|
||||
) error {
|
||||
stmt := sqlutil.TxStmt(txn, s.deleteExpiredEDUsStmt)
|
||||
_, err := stmt.ExecContext(ctx, expiredBefore)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = queueEDUs.Prepare(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.Database = shared.Database{
|
||||
DB: d.db,
|
||||
ServerName: serverName,
|
||||
|
|
|
|||
81
federationapi/storage/storage_test.go
Normal file
81
federationapi/storage/storage_test.go
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
package storage_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/matrix-org/dendrite/federationapi/storage"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/test"
|
||||
"github.com/matrix-org/dendrite/test/testrig"
|
||||
)
|
||||
|
||||
func mustCreateFederationDatabase(t *testing.T, dbType test.DBType) (storage.Database, func()) {
|
||||
b, baseClose := testrig.CreateBaseDendrite(t, dbType)
|
||||
connStr, dbClose := test.PrepareDBConnectionString(t, dbType)
|
||||
db, err := storage.NewDatabase(b, &config.DatabaseOptions{
|
||||
ConnectionString: config.DataSource(connStr),
|
||||
}, b.Caches, b.Cfg.Global.ServerName)
|
||||
if err != nil {
|
||||
t.Fatalf("NewDatabase returned %s", err)
|
||||
}
|
||||
return db, func() {
|
||||
dbClose()
|
||||
baseClose()
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpireEDUs(t *testing.T) {
|
||||
var expireEDUTypes = map[string]time.Duration{
|
||||
gomatrixserverlib.MReceipt: time.Millisecond,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
|
||||
db, close := mustCreateFederationDatabase(t, dbType)
|
||||
defer close()
|
||||
// insert some data
|
||||
for i := 0; i < 100; i++ {
|
||||
receipt, err := db.StoreJSON(ctx, "{}")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = db.AssociateEDUWithDestination(ctx, "localhost", receipt, gomatrixserverlib.MReceipt, expireEDUTypes)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
// add data without expiry
|
||||
receipt, err := db.StoreJSON(ctx, "{}")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// m.read_marker gets the default expiry of 24h, so won't be deleted further down in this test
|
||||
err = db.AssociateEDUWithDestination(ctx, "localhost", receipt, "m.read_marker", expireEDUTypes)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Delete expired EDUs
|
||||
err = db.DeleteExpiredEDUs(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// verify the data is gone
|
||||
data, err := db.GetPendingEDUs(ctx, "localhost", 100)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(data))
|
||||
|
||||
// check that m.direct_to_device is never expired
|
||||
receipt, err = db.StoreJSON(ctx, "{}")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = db.AssociateEDUWithDestination(ctx, "localhost", receipt, gomatrixserverlib.MDirectToDevice, expireEDUTypes)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = db.DeleteExpiredEDUs(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// We should get two EDUs, the m.read_marker and the m.direct_to_device
|
||||
data, err = db.GetPendingEDUs(ctx, "localhost", 100)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 2, len(data))
|
||||
})
|
||||
}
|
||||
|
|
@ -34,12 +34,15 @@ type FederationQueuePDUs interface {
|
|||
}
|
||||
|
||||
type FederationQueueEDUs interface {
|
||||
InsertQueueEDU(ctx context.Context, txn *sql.Tx, eduType string, serverName gomatrixserverlib.ServerName, nid int64) error
|
||||
InsertQueueEDU(ctx context.Context, txn *sql.Tx, eduType string, serverName gomatrixserverlib.ServerName, nid int64, expiresAt gomatrixserverlib.Timestamp) error
|
||||
DeleteQueueEDUs(ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName, jsonNIDs []int64) error
|
||||
SelectQueueEDUs(ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName, limit int) ([]int64, error)
|
||||
SelectQueueEDUReferenceJSONCount(ctx context.Context, txn *sql.Tx, jsonNID int64) (int64, error)
|
||||
SelectQueueEDUCount(ctx context.Context, txn *sql.Tx, serverName gomatrixserverlib.ServerName) (int64, error)
|
||||
SelectQueueEDUServerNames(ctx context.Context, txn *sql.Tx) ([]gomatrixserverlib.ServerName, error)
|
||||
SelectExpiredEDUs(ctx context.Context, txn *sql.Tx, expiredBefore gomatrixserverlib.Timestamp) ([]int64, error)
|
||||
DeleteExpiredEDUs(ctx context.Context, txn *sql.Tx, expiredBefore gomatrixserverlib.Timestamp) error
|
||||
Prepare() error
|
||||
}
|
||||
|
||||
type FederationQueueJSON interface {
|
||||
|
|
|
|||
8
go.mod
8
go.mod
|
|
@ -21,7 +21,7 @@ require (
|
|||
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
|
||||
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91
|
||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20220725104114-b6003e522771
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20220801083850-5ff38e2c2839
|
||||
github.com/matrix-org/pinecone v0.0.0-20220803093810-b7a830c08fb9
|
||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
|
||||
github.com/mattn/go-sqlite3 v1.14.13
|
||||
|
|
@ -34,7 +34,7 @@ require (
|
|||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.12.2
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/tidwall/gjson v1.14.1
|
||||
github.com/tidwall/sjson v1.2.4
|
||||
|
|
@ -42,7 +42,7 @@ require (
|
|||
github.com/uber/jaeger-lib v2.4.1+incompatible
|
||||
github.com/yggdrasil-network/yggdrasil-go v0.4.3
|
||||
go.uber.org/atomic v1.9.0
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
|
||||
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9
|
||||
golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd
|
||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e
|
||||
|
|
@ -99,7 +99,7 @@ require (
|
|||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d // indirect
|
||||
golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b // indirect
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
|
||||
golang.org/x/tools v0.1.10 // indirect
|
||||
|
|
|
|||
16
go.sum
16
go.sum
|
|
@ -343,8 +343,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1
|
|||
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5dLDCud4r0r55eP4j9FuUNpl60Gmntcop4=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20220725104114-b6003e522771 h1:ZIPHFIPNDS9dmEbPEiJbNmyCGJtn9exfpLC7JOcn/bE=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20220725104114-b6003e522771/go.mod h1:jX38yp3SSLJNftBg3PXU1ayd0PCLIiDHQ4xAc9DIixk=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20220801083850-5ff38e2c2839 h1:QEFxKWH8PlEt3ZQKl31yJNAm8lvpNUwT51IMNTl9v1k=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20220801083850-5ff38e2c2839/go.mod h1:jX38yp3SSLJNftBg3PXU1ayd0PCLIiDHQ4xAc9DIixk=
|
||||
github.com/matrix-org/pinecone v0.0.0-20220803093810-b7a830c08fb9 h1:ed8yvWhTLk7+sNeK/eOZRTvESFTOHDRevoRoyeqPtvY=
|
||||
github.com/matrix-org/pinecone v0.0.0-20220803093810-b7a830c08fb9/go.mod h1:P4MqPf+u83OPulPJ+XTbSDbbWrdFYNY4LZ/B1PIduFE=
|
||||
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
|
||||
|
|
@ -493,8 +493,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
|||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
|
|
@ -569,8 +569,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
|
@ -748,8 +748,10 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d h1:Sv5ogFZatcgIMMtBSTTAgMYsicp25MXBubjXNDKwm80=
|
||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM=
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ type lazyLoadingCacheKey struct {
|
|||
type LazyLoadCache interface {
|
||||
StoreLazyLoadedUser(device *userapi.Device, roomID, userID, eventID string)
|
||||
IsLazyLoadedUserCached(device *userapi.Device, roomID, userID string) (string, bool)
|
||||
InvalidateLazyLoadedUser(device *userapi.Device, roomID, userID string)
|
||||
}
|
||||
|
||||
func (c Caches) StoreLazyLoadedUser(device *userapi.Device, roomID, userID, eventID string) {
|
||||
|
|
@ -33,3 +34,12 @@ func (c Caches) IsLazyLoadedUserCached(device *userapi.Device, roomID, userID st
|
|||
TargetUserID: userID,
|
||||
})
|
||||
}
|
||||
|
||||
func (c Caches) InvalidateLazyLoadedUser(device *userapi.Device, roomID, userID string) {
|
||||
c.LazyLoading.Unset(lazyLoadingCacheKey{
|
||||
UserID: device.UserID,
|
||||
DeviceID: device.ID,
|
||||
RoomID: roomID,
|
||||
TargetUserID: userID,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,19 +19,21 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/matrix-org/dendrite/userapi/api"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
"github.com/opentracing/opentracing-go/ext"
|
||||
)
|
||||
|
||||
// PostJSON performs a POST request with JSON on an internal HTTP API
|
||||
func PostJSON(
|
||||
// PostJSON performs a POST request with JSON on an internal HTTP API.
|
||||
// The error will match the errtype if returned from the remote API, or
|
||||
// will be a different type if there was a problem reaching the API.
|
||||
func PostJSON[reqtype, restype any, errtype error](
|
||||
ctx context.Context, span opentracing.Span, httpClient *http.Client,
|
||||
apiURL string, request, response interface{},
|
||||
apiURL string, request *reqtype, response *restype,
|
||||
) error {
|
||||
jsonBytes, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
|
|
@ -69,17 +71,23 @@ func PostJSON(
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if res.StatusCode != http.StatusOK {
|
||||
var errorBody struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
if _, ok := response.(*api.PerformKeyBackupResponse); ok { // TODO: remove this, once cross-boundary errors are a thing
|
||||
return nil
|
||||
}
|
||||
if msgerr := json.NewDecoder(res.Body).Decode(&errorBody); msgerr == nil {
|
||||
return fmt.Errorf("internal API: %d from %s: %s", res.StatusCode, apiURL, errorBody.Message)
|
||||
}
|
||||
return fmt.Errorf("internal API: %d from %s", res.StatusCode, apiURL)
|
||||
var body []byte
|
||||
body, err = io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.NewDecoder(res.Body).Decode(response)
|
||||
if res.StatusCode != http.StatusOK {
|
||||
if len(body) == 0 {
|
||||
return fmt.Errorf("HTTP %d from %s (no response body)", res.StatusCode, apiURL)
|
||||
}
|
||||
var reserr errtype
|
||||
if err = json.Unmarshal(body, reserr); err != nil {
|
||||
return fmt.Errorf("HTTP %d from %s", res.StatusCode, apiURL)
|
||||
}
|
||||
return reserr
|
||||
}
|
||||
if err = json.Unmarshal(body, response); err != nil {
|
||||
return fmt.Errorf("json.Unmarshal: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
93
internal/httputil/internalapi.go
Normal file
93
internal/httputil/internalapi.go
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
// Copyright 2022 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 httputil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/matrix-org/util"
|
||||
opentracing "github.com/opentracing/opentracing-go"
|
||||
)
|
||||
|
||||
type InternalAPIError struct {
|
||||
Type string
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e InternalAPIError) Error() string {
|
||||
return fmt.Sprintf("internal API returned %q error: %s", e.Type, e.Message)
|
||||
}
|
||||
|
||||
func MakeInternalRPCAPI[reqtype, restype any](metricsName string, f func(context.Context, *reqtype, *restype) error) http.Handler {
|
||||
return MakeInternalAPI(metricsName, func(req *http.Request) util.JSONResponse {
|
||||
var request reqtype
|
||||
var response restype
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := f(req.Context(), &request, &response); err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: &InternalAPIError{
|
||||
Type: reflect.TypeOf(err).String(),
|
||||
Message: fmt.Sprintf("%s", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: &response,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func MakeInternalProxyAPI[reqtype, restype any](metricsName string, f func(context.Context, *reqtype) (*restype, error)) http.Handler {
|
||||
return MakeInternalAPI(metricsName, func(req *http.Request) util.JSONResponse {
|
||||
var request reqtype
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
response, err := f(req.Context(), &request)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: err,
|
||||
}
|
||||
}
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: response,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func CallInternalRPCAPI[reqtype, restype any](name, url string, client *http.Client, ctx context.Context, request *reqtype, response *restype) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, name)
|
||||
defer span.Finish()
|
||||
|
||||
return PostJSON[reqtype, restype, InternalAPIError](ctx, span, client, url, request, response)
|
||||
}
|
||||
|
||||
func CallInternalProxyAPI[reqtype, restype any, errtype error](name, url string, client *http.Client, ctx context.Context, request *reqtype) (restype, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, name)
|
||||
defer span.Finish()
|
||||
|
||||
var response restype
|
||||
return response, PostJSON[reqtype, restype, errtype](ctx, span, client, url, request, &response)
|
||||
}
|
||||
|
|
@ -27,9 +27,10 @@ import (
|
|||
|
||||
"github.com/matrix-org/util"
|
||||
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dugong"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
)
|
||||
|
||||
type utcFormatter struct {
|
||||
|
|
@ -145,7 +146,7 @@ func setupFileHook(hook config.LogrusHook, level logrus.Level, componentName str
|
|||
})
|
||||
}
|
||||
|
||||
//CloseAndLogIfError Closes io.Closer and logs the error if any
|
||||
// CloseAndLogIfError Closes io.Closer and logs the error if any
|
||||
func CloseAndLogIfError(ctx context.Context, closer io.Closer, message string) {
|
||||
if closer == nil {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"log/syslog"
|
||||
|
||||
"github.com/MFAshby/stdemuxerhook"
|
||||
|
|
@ -63,7 +63,7 @@ func SetupHookLogging(hooks []config.LogrusHook, componentName string) {
|
|||
setupStdLogHook(logrus.InfoLevel)
|
||||
}
|
||||
// Hooks are now configured for stdout/err, so throw away the default logger output
|
||||
logrus.SetOutput(ioutil.Discard)
|
||||
logrus.SetOutput(io.Discard)
|
||||
}
|
||||
|
||||
func checkSyslogHookParams(params map[string]interface{}) {
|
||||
|
|
|
|||
|
|
@ -38,32 +38,32 @@ type KeyInternalAPI interface {
|
|||
|
||||
// API functions required by the clientapi
|
||||
type ClientKeyAPI interface {
|
||||
QueryKeys(ctx context.Context, req *QueryKeysRequest, res *QueryKeysResponse)
|
||||
PerformUploadKeys(ctx context.Context, req *PerformUploadKeysRequest, res *PerformUploadKeysResponse)
|
||||
PerformUploadDeviceKeys(ctx context.Context, req *PerformUploadDeviceKeysRequest, res *PerformUploadDeviceKeysResponse)
|
||||
PerformUploadDeviceSignatures(ctx context.Context, req *PerformUploadDeviceSignaturesRequest, res *PerformUploadDeviceSignaturesResponse)
|
||||
QueryKeys(ctx context.Context, req *QueryKeysRequest, res *QueryKeysResponse) error
|
||||
PerformUploadKeys(ctx context.Context, req *PerformUploadKeysRequest, res *PerformUploadKeysResponse) error
|
||||
PerformUploadDeviceKeys(ctx context.Context, req *PerformUploadDeviceKeysRequest, res *PerformUploadDeviceKeysResponse) error
|
||||
PerformUploadDeviceSignatures(ctx context.Context, req *PerformUploadDeviceSignaturesRequest, res *PerformUploadDeviceSignaturesResponse) error
|
||||
// PerformClaimKeys claims one-time keys for use in pre-key messages
|
||||
PerformClaimKeys(ctx context.Context, req *PerformClaimKeysRequest, res *PerformClaimKeysResponse)
|
||||
PerformClaimKeys(ctx context.Context, req *PerformClaimKeysRequest, res *PerformClaimKeysResponse) error
|
||||
}
|
||||
|
||||
// API functions required by the userapi
|
||||
type UserKeyAPI interface {
|
||||
PerformUploadKeys(ctx context.Context, req *PerformUploadKeysRequest, res *PerformUploadKeysResponse)
|
||||
PerformDeleteKeys(ctx context.Context, req *PerformDeleteKeysRequest, res *PerformDeleteKeysResponse)
|
||||
PerformUploadKeys(ctx context.Context, req *PerformUploadKeysRequest, res *PerformUploadKeysResponse) error
|
||||
PerformDeleteKeys(ctx context.Context, req *PerformDeleteKeysRequest, res *PerformDeleteKeysResponse) error
|
||||
}
|
||||
|
||||
// API functions required by the syncapi
|
||||
type SyncKeyAPI interface {
|
||||
QueryKeyChanges(ctx context.Context, req *QueryKeyChangesRequest, res *QueryKeyChangesResponse)
|
||||
QueryOneTimeKeys(ctx context.Context, req *QueryOneTimeKeysRequest, res *QueryOneTimeKeysResponse)
|
||||
QueryKeyChanges(ctx context.Context, req *QueryKeyChangesRequest, res *QueryKeyChangesResponse) error
|
||||
QueryOneTimeKeys(ctx context.Context, req *QueryOneTimeKeysRequest, res *QueryOneTimeKeysResponse) error
|
||||
}
|
||||
|
||||
type FederationKeyAPI interface {
|
||||
QueryKeys(ctx context.Context, req *QueryKeysRequest, res *QueryKeysResponse)
|
||||
QuerySignatures(ctx context.Context, req *QuerySignaturesRequest, res *QuerySignaturesResponse)
|
||||
QueryDeviceMessages(ctx context.Context, req *QueryDeviceMessagesRequest, res *QueryDeviceMessagesResponse)
|
||||
PerformUploadDeviceKeys(ctx context.Context, req *PerformUploadDeviceKeysRequest, res *PerformUploadDeviceKeysResponse)
|
||||
PerformClaimKeys(ctx context.Context, req *PerformClaimKeysRequest, res *PerformClaimKeysResponse)
|
||||
QueryKeys(ctx context.Context, req *QueryKeysRequest, res *QueryKeysResponse) error
|
||||
QuerySignatures(ctx context.Context, req *QuerySignaturesRequest, res *QuerySignaturesResponse) error
|
||||
QueryDeviceMessages(ctx context.Context, req *QueryDeviceMessagesRequest, res *QueryDeviceMessagesResponse) error
|
||||
PerformUploadDeviceKeys(ctx context.Context, req *PerformUploadDeviceKeysRequest, res *PerformUploadDeviceKeysResponse) error
|
||||
PerformClaimKeys(ctx context.Context, req *PerformClaimKeysRequest, res *PerformClaimKeysResponse) error
|
||||
}
|
||||
|
||||
// KeyError is returned if there was a problem performing/querying the server
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ func sanityCheckKey(key gomatrixserverlib.CrossSigningKey, userID string, purpos
|
|||
}
|
||||
|
||||
// nolint:gocyclo
|
||||
func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.PerformUploadDeviceKeysRequest, res *api.PerformUploadDeviceKeysResponse) {
|
||||
func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.PerformUploadDeviceKeysRequest, res *api.PerformUploadDeviceKeysResponse) error {
|
||||
// Find the keys to store.
|
||||
byPurpose := map[gomatrixserverlib.CrossSigningKeyPurpose]gomatrixserverlib.CrossSigningKey{}
|
||||
toStore := types.CrossSigningKeyMap{}
|
||||
|
|
@ -115,7 +115,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
Err: "Master key sanity check failed: " + err.Error(),
|
||||
IsInvalidParam: true,
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
byPurpose[gomatrixserverlib.CrossSigningKeyPurposeMaster] = req.MasterKey
|
||||
|
|
@ -131,7 +131,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
Err: "Self-signing key sanity check failed: " + err.Error(),
|
||||
IsInvalidParam: true,
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
byPurpose[gomatrixserverlib.CrossSigningKeyPurposeSelfSigning] = req.SelfSigningKey
|
||||
|
|
@ -146,7 +146,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
Err: "User-signing key sanity check failed: " + err.Error(),
|
||||
IsInvalidParam: true,
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
byPurpose[gomatrixserverlib.CrossSigningKeyPurposeUserSigning] = req.UserSigningKey
|
||||
|
|
@ -161,7 +161,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
Err: "No keys were supplied in the request",
|
||||
IsMissingParam: true,
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// We can't have a self-signing or user-signing key without a master
|
||||
|
|
@ -174,7 +174,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
res.Error = &api.KeyError{
|
||||
Err: "Retrieving cross-signing keys from database failed: " + err.Error(),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// If we still can't find a master key for the user then stop the upload.
|
||||
|
|
@ -185,7 +185,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
Err: "No master key was found",
|
||||
IsMissingParam: true,
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
}
|
||||
}
|
||||
if !changed {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// Store the keys.
|
||||
|
|
@ -220,7 +220,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("a.DB.StoreCrossSigningKeysForUser: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// Now upload any signatures that were included with the keys.
|
||||
|
|
@ -238,7 +238,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("a.DB.StoreCrossSigningSigsForTarget: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -255,17 +255,18 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
|
|||
update.SelfSigningKey = &ssk
|
||||
}
|
||||
if update.MasterKey == nil && update.SelfSigningKey == nil {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if err := a.Producer.ProduceSigningKeyUpdate(update); err != nil {
|
||||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("a.Producer.ProduceSigningKeyUpdate: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) PerformUploadDeviceSignatures(ctx context.Context, req *api.PerformUploadDeviceSignaturesRequest, res *api.PerformUploadDeviceSignaturesResponse) {
|
||||
func (a *KeyInternalAPI) PerformUploadDeviceSignatures(ctx context.Context, req *api.PerformUploadDeviceSignaturesRequest, res *api.PerformUploadDeviceSignaturesResponse) error {
|
||||
// Before we do anything, we need the master and self-signing keys for this user.
|
||||
// Then we can verify the signatures make sense.
|
||||
queryReq := &api.QueryKeysRequest{
|
||||
|
|
@ -276,7 +277,7 @@ func (a *KeyInternalAPI) PerformUploadDeviceSignatures(ctx context.Context, req
|
|||
for userID := range req.Signatures {
|
||||
queryReq.UserToDevices[userID] = []string{}
|
||||
}
|
||||
a.QueryKeys(ctx, queryReq, queryRes)
|
||||
_ = a.QueryKeys(ctx, queryReq, queryRes)
|
||||
|
||||
selfSignatures := map[string]map[gomatrixserverlib.KeyID]gomatrixserverlib.CrossSigningForKeyOrDevice{}
|
||||
otherSignatures := map[string]map[gomatrixserverlib.KeyID]gomatrixserverlib.CrossSigningForKeyOrDevice{}
|
||||
|
|
@ -322,14 +323,14 @@ func (a *KeyInternalAPI) PerformUploadDeviceSignatures(ctx context.Context, req
|
|||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("a.processSelfSignatures: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := a.processOtherSignatures(ctx, req.UserID, queryRes, otherSignatures); err != nil {
|
||||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("a.processOtherSignatures: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// Finally, generate a notification that we updated the signatures.
|
||||
|
|
@ -345,9 +346,10 @@ func (a *KeyInternalAPI) PerformUploadDeviceSignatures(ctx context.Context, req
|
|||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("a.Producer.ProduceSigningKeyUpdate: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) processSelfSignatures(
|
||||
|
|
@ -520,7 +522,7 @@ func (a *KeyInternalAPI) crossSigningKeysFromDatabase(
|
|||
}
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) QuerySignatures(ctx context.Context, req *api.QuerySignaturesRequest, res *api.QuerySignaturesResponse) {
|
||||
func (a *KeyInternalAPI) QuerySignatures(ctx context.Context, req *api.QuerySignaturesRequest, res *api.QuerySignaturesResponse) error {
|
||||
for targetUserID, forTargetUser := range req.TargetIDs {
|
||||
keyMap, err := a.DB.CrossSigningKeysForUser(ctx, targetUserID)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
|
|
@ -559,7 +561,7 @@ func (a *KeyInternalAPI) QuerySignatures(ctx context.Context, req *api.QuerySign
|
|||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("a.DB.CrossSigningSigsForTarget: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
for sourceUserID, forSourceUser := range sigMap {
|
||||
|
|
@ -581,4 +583,5 @@ func (a *KeyInternalAPI) QuerySignatures(ctx context.Context, req *api.QuerySign
|
|||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,12 +22,13 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
fedsenderapi "github.com/matrix-org/dendrite/federationapi/api"
|
||||
"github.com/matrix-org/dendrite/keyserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
fedsenderapi "github.com/matrix-org/dendrite/federationapi/api"
|
||||
"github.com/matrix-org/dendrite/keyserver/api"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -66,12 +67,14 @@ func init() {
|
|||
// - We don't have unbounded growth in proportion to the number of servers (this is more important in a P2P world where
|
||||
// we have many many servers)
|
||||
// - We can adjust concurrency (at the cost of memory usage) by tuning N, to accommodate mobile devices vs servers.
|
||||
//
|
||||
// The downsides are that:
|
||||
// - Query requests can get queued behind other servers if they hash to the same worker, even if there are other free
|
||||
// workers elsewhere. Whilst suboptimal, provided we cap how long a single request can last (e.g using context timeouts)
|
||||
// we guarantee we will get around to it. Also, more users on a given server does not increase the number of requests
|
||||
// (as /keys/query allows multiple users to be specified) so being stuck behind matrix.org won't materially be any worse
|
||||
// than being stuck behind foo.bar
|
||||
//
|
||||
// In the event that the query fails, a lock is acquired and the server name along with the time to wait before retrying is
|
||||
// set in a map. A restarter goroutine periodically probes this map and injects servers which are ready to be retried.
|
||||
type DeviceListUpdater struct {
|
||||
|
|
@ -116,7 +119,7 @@ type DeviceListUpdaterDatabase interface {
|
|||
}
|
||||
|
||||
type DeviceListUpdaterAPI interface {
|
||||
PerformUploadDeviceKeys(ctx context.Context, req *api.PerformUploadDeviceKeysRequest, res *api.PerformUploadDeviceKeysResponse)
|
||||
PerformUploadDeviceKeys(ctx context.Context, req *api.PerformUploadDeviceKeysRequest, res *api.PerformUploadDeviceKeysResponse) error
|
||||
}
|
||||
|
||||
// KeyChangeProducer is the interface for producers.KeyChange useful for testing.
|
||||
|
|
@ -418,7 +421,7 @@ func (u *DeviceListUpdater) processServer(serverName gomatrixserverlib.ServerNam
|
|||
uploadReq.SelfSigningKey = *res.SelfSigningKey
|
||||
}
|
||||
}
|
||||
u.api.PerformUploadDeviceKeys(ctx, uploadReq, uploadRes)
|
||||
_ = u.api.PerformUploadDeviceKeys(ctx, uploadReq, uploadRes)
|
||||
}
|
||||
err = u.updateDeviceList(&res)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import (
|
|||
"context"
|
||||
"crypto/ed25519"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
|
|
@ -27,8 +27,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/keyserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
||||
"github.com/matrix-org/dendrite/keyserver/api"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -112,8 +113,8 @@ func (d *mockDeviceListUpdaterDatabase) DeviceKeysJSON(ctx context.Context, keys
|
|||
type mockDeviceListUpdaterAPI struct {
|
||||
}
|
||||
|
||||
func (d *mockDeviceListUpdaterAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.PerformUploadDeviceKeysRequest, res *api.PerformUploadDeviceKeysResponse) {
|
||||
|
||||
func (d *mockDeviceListUpdaterAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.PerformUploadDeviceKeysRequest, res *api.PerformUploadDeviceKeysResponse) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type roundTripper struct {
|
||||
|
|
@ -202,7 +203,7 @@ func TestUpdateNoPrevID(t *testing.T) {
|
|||
}
|
||||
return &http.Response{
|
||||
StatusCode: 200,
|
||||
Body: ioutil.NopCloser(strings.NewReader(`
|
||||
Body: io.NopCloser(strings.NewReader(`
|
||||
{
|
||||
"user_id": "` + remoteUserID + `",
|
||||
"stream_id": 5,
|
||||
|
|
@ -317,7 +318,7 @@ func TestDebounce(t *testing.T) {
|
|||
// now send the response over federation
|
||||
fedCh <- &http.Response{
|
||||
StatusCode: 200,
|
||||
Body: ioutil.NopCloser(strings.NewReader(`
|
||||
Body: io.NopCloser(strings.NewReader(`
|
||||
{
|
||||
"user_id": "` + userID + `",
|
||||
"stream_id": 5,
|
||||
|
|
|
|||
|
|
@ -48,18 +48,20 @@ func (a *KeyInternalAPI) SetUserAPI(i userapi.KeyserverUserAPI) {
|
|||
a.UserAPI = i
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) QueryKeyChanges(ctx context.Context, req *api.QueryKeyChangesRequest, res *api.QueryKeyChangesResponse) {
|
||||
func (a *KeyInternalAPI) QueryKeyChanges(ctx context.Context, req *api.QueryKeyChangesRequest, res *api.QueryKeyChangesResponse) error {
|
||||
userIDs, latest, err := a.DB.KeyChanges(ctx, req.Offset, req.ToOffset)
|
||||
if err != nil {
|
||||
res.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
res.Offset = latest
|
||||
res.UserIDs = userIDs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) PerformUploadKeys(ctx context.Context, req *api.PerformUploadKeysRequest, res *api.PerformUploadKeysResponse) {
|
||||
func (a *KeyInternalAPI) PerformUploadKeys(ctx context.Context, req *api.PerformUploadKeysRequest, res *api.PerformUploadKeysResponse) error {
|
||||
res.KeyErrors = make(map[string]map[string]*api.KeyError)
|
||||
if len(req.DeviceKeys) > 0 {
|
||||
a.uploadLocalDeviceKeys(ctx, req, res)
|
||||
|
|
@ -67,9 +69,10 @@ func (a *KeyInternalAPI) PerformUploadKeys(ctx context.Context, req *api.Perform
|
|||
if len(req.OneTimeKeys) > 0 {
|
||||
a.uploadOneTimeKeys(ctx, req, res)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) PerformClaimKeys(ctx context.Context, req *api.PerformClaimKeysRequest, res *api.PerformClaimKeysResponse) {
|
||||
func (a *KeyInternalAPI) PerformClaimKeys(ctx context.Context, req *api.PerformClaimKeysRequest, res *api.PerformClaimKeysResponse) error {
|
||||
res.OneTimeKeys = make(map[string]map[string]map[string]json.RawMessage)
|
||||
res.Failures = make(map[string]interface{})
|
||||
// wrap request map in a top-level by-domain map
|
||||
|
|
@ -113,6 +116,7 @@ func (a *KeyInternalAPI) PerformClaimKeys(ctx context.Context, req *api.PerformC
|
|||
if len(domainToDeviceKeys) > 0 {
|
||||
a.claimRemoteKeys(ctx, req.Timeout, res, domainToDeviceKeys)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) claimRemoteKeys(
|
||||
|
|
@ -172,32 +176,34 @@ func (a *KeyInternalAPI) claimRemoteKeys(
|
|||
util.GetLogger(ctx).WithField("num_keys", keysClaimed).Info("Claimed remote keys")
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) PerformDeleteKeys(ctx context.Context, req *api.PerformDeleteKeysRequest, res *api.PerformDeleteKeysResponse) {
|
||||
func (a *KeyInternalAPI) PerformDeleteKeys(ctx context.Context, req *api.PerformDeleteKeysRequest, res *api.PerformDeleteKeysResponse) error {
|
||||
if err := a.DB.DeleteDeviceKeys(ctx, req.UserID, req.KeyIDs); err != nil {
|
||||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("Failed to delete device keys: %s", err),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) QueryOneTimeKeys(ctx context.Context, req *api.QueryOneTimeKeysRequest, res *api.QueryOneTimeKeysResponse) {
|
||||
func (a *KeyInternalAPI) QueryOneTimeKeys(ctx context.Context, req *api.QueryOneTimeKeysRequest, res *api.QueryOneTimeKeysResponse) error {
|
||||
count, err := a.DB.OneTimeKeysCount(ctx, req.UserID, req.DeviceID)
|
||||
if err != nil {
|
||||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("Failed to query OTK counts: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
res.Count = *count
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) QueryDeviceMessages(ctx context.Context, req *api.QueryDeviceMessagesRequest, res *api.QueryDeviceMessagesResponse) {
|
||||
func (a *KeyInternalAPI) QueryDeviceMessages(ctx context.Context, req *api.QueryDeviceMessagesRequest, res *api.QueryDeviceMessagesResponse) error {
|
||||
msgs, err := a.DB.DeviceKeysForUser(ctx, req.UserID, nil, false)
|
||||
if err != nil {
|
||||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("failed to query DB for device keys: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
maxStreamID := int64(0)
|
||||
for _, m := range msgs {
|
||||
|
|
@ -215,10 +221,11 @@ func (a *KeyInternalAPI) QueryDeviceMessages(ctx context.Context, req *api.Query
|
|||
}
|
||||
res.Devices = result
|
||||
res.StreamID = maxStreamID
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint:gocyclo
|
||||
func (a *KeyInternalAPI) QueryKeys(ctx context.Context, req *api.QueryKeysRequest, res *api.QueryKeysResponse) {
|
||||
func (a *KeyInternalAPI) QueryKeys(ctx context.Context, req *api.QueryKeysRequest, res *api.QueryKeysResponse) error {
|
||||
res.DeviceKeys = make(map[string]map[string]json.RawMessage)
|
||||
res.MasterKeys = make(map[string]gomatrixserverlib.CrossSigningKey)
|
||||
res.SelfSigningKeys = make(map[string]gomatrixserverlib.CrossSigningKey)
|
||||
|
|
@ -244,7 +251,7 @@ func (a *KeyInternalAPI) QueryKeys(ctx context.Context, req *api.QueryKeysReques
|
|||
res.Error = &api.KeyError{
|
||||
Err: fmt.Sprintf("failed to query local device keys: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// pull out display names after we have the keys so we handle wildcards correctly
|
||||
|
|
@ -318,7 +325,7 @@ func (a *KeyInternalAPI) QueryKeys(ctx context.Context, req *api.QueryKeysReques
|
|||
// Stop executing the function if the context was canceled/the deadline was exceeded,
|
||||
// as we can't continue without a valid context.
|
||||
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
logrus.WithError(err).Errorf("a.DB.CrossSigningSigsForTarget failed")
|
||||
continue
|
||||
|
|
@ -344,7 +351,7 @@ func (a *KeyInternalAPI) QueryKeys(ctx context.Context, req *api.QueryKeysReques
|
|||
// Stop executing the function if the context was canceled/the deadline was exceeded,
|
||||
// as we can't continue without a valid context.
|
||||
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
logrus.WithError(err).Errorf("a.DB.CrossSigningSigsForTarget failed")
|
||||
continue
|
||||
|
|
@ -372,6 +379,7 @@ func (a *KeyInternalAPI) QueryKeys(ctx context.Context, req *api.QueryKeysReques
|
|||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *KeyInternalAPI) remoteKeysFromDatabase(
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/dendrite/keyserver/api"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
)
|
||||
|
||||
// HTTP paths for the internal HTTP APIs
|
||||
|
|
@ -68,168 +67,108 @@ func (h *httpKeyInternalAPI) PerformClaimKeys(
|
|||
ctx context.Context,
|
||||
request *api.PerformClaimKeysRequest,
|
||||
response *api.PerformClaimKeysResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformClaimKeys")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + PerformClaimKeysPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformClaimKeys", h.apiURL+PerformClaimKeysPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpKeyInternalAPI) PerformDeleteKeys(
|
||||
ctx context.Context,
|
||||
request *api.PerformDeleteKeysRequest,
|
||||
response *api.PerformDeleteKeysResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformClaimKeys")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + PerformClaimKeysPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformDeleteKeys", h.apiURL+PerformDeleteKeysPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpKeyInternalAPI) PerformUploadKeys(
|
||||
ctx context.Context,
|
||||
request *api.PerformUploadKeysRequest,
|
||||
response *api.PerformUploadKeysResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformUploadKeys")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + PerformUploadKeysPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformUploadKeys", h.apiURL+PerformUploadKeysPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpKeyInternalAPI) QueryKeys(
|
||||
ctx context.Context,
|
||||
request *api.QueryKeysRequest,
|
||||
response *api.QueryKeysResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryKeys")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + QueryKeysPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryKeys", h.apiURL+QueryKeysPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpKeyInternalAPI) QueryOneTimeKeys(
|
||||
ctx context.Context,
|
||||
request *api.QueryOneTimeKeysRequest,
|
||||
response *api.QueryOneTimeKeysResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryOneTimeKeys")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + QueryOneTimeKeysPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryOneTimeKeys", h.apiURL+QueryOneTimeKeysPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpKeyInternalAPI) QueryDeviceMessages(
|
||||
ctx context.Context,
|
||||
request *api.QueryDeviceMessagesRequest,
|
||||
response *api.QueryDeviceMessagesResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryDeviceMessages")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + QueryDeviceMessagesPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryDeviceMessages", h.apiURL+QueryDeviceMessagesPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpKeyInternalAPI) QueryKeyChanges(
|
||||
ctx context.Context,
|
||||
request *api.QueryKeyChangesRequest,
|
||||
response *api.QueryKeyChangesResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryKeyChanges")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + QueryKeyChangesPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryKeyChanges", h.apiURL+QueryKeyChangesPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpKeyInternalAPI) PerformUploadDeviceKeys(
|
||||
ctx context.Context,
|
||||
request *api.PerformUploadDeviceKeysRequest,
|
||||
response *api.PerformUploadDeviceKeysResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformUploadDeviceKeys")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + PerformUploadDeviceKeysPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformUploadDeviceKeys", h.apiURL+PerformUploadDeviceKeysPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpKeyInternalAPI) PerformUploadDeviceSignatures(
|
||||
ctx context.Context,
|
||||
request *api.PerformUploadDeviceSignaturesRequest,
|
||||
response *api.PerformUploadDeviceSignaturesResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformUploadDeviceSignatures")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + PerformUploadDeviceSignaturesPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformUploadDeviceSignatures", h.apiURL+PerformUploadDeviceSignaturesPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpKeyInternalAPI) QuerySignatures(
|
||||
ctx context.Context,
|
||||
request *api.QuerySignaturesRequest,
|
||||
response *api.QuerySignaturesResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QuerySignatures")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.apiURL + QuerySignaturesPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.KeyError{
|
||||
Err: err.Error(),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QuerySignatures", h.apiURL+QuerySignaturesPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,124 +15,59 @@
|
|||
package inthttp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/dendrite/keyserver/api"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
func AddRoutes(internalAPIMux *mux.Router, s api.KeyInternalAPI) {
|
||||
internalAPIMux.Handle(PerformClaimKeysPath,
|
||||
httputil.MakeInternalAPI("performClaimKeys", func(req *http.Request) util.JSONResponse {
|
||||
request := api.PerformClaimKeysRequest{}
|
||||
response := api.PerformClaimKeysResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.PerformClaimKeys(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
internalAPIMux.Handle(
|
||||
PerformClaimKeysPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverPerformClaimKeys", s.PerformClaimKeys),
|
||||
)
|
||||
internalAPIMux.Handle(PerformDeleteKeysPath,
|
||||
httputil.MakeInternalAPI("performDeleteKeys", func(req *http.Request) util.JSONResponse {
|
||||
request := api.PerformDeleteKeysRequest{}
|
||||
response := api.PerformDeleteKeysResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.PerformDeleteKeys(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
PerformDeleteKeysPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverPerformDeleteKeys", s.PerformDeleteKeys),
|
||||
)
|
||||
internalAPIMux.Handle(PerformUploadKeysPath,
|
||||
httputil.MakeInternalAPI("performUploadKeys", func(req *http.Request) util.JSONResponse {
|
||||
request := api.PerformUploadKeysRequest{}
|
||||
response := api.PerformUploadKeysResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.PerformUploadKeys(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
PerformUploadKeysPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverPerformUploadKeys", s.PerformUploadKeys),
|
||||
)
|
||||
internalAPIMux.Handle(PerformUploadDeviceKeysPath,
|
||||
httputil.MakeInternalAPI("performUploadDeviceKeys", func(req *http.Request) util.JSONResponse {
|
||||
request := api.PerformUploadDeviceKeysRequest{}
|
||||
response := api.PerformUploadDeviceKeysResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.PerformUploadDeviceKeys(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
PerformUploadDeviceKeysPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverPerformUploadDeviceKeys", s.PerformUploadDeviceKeys),
|
||||
)
|
||||
internalAPIMux.Handle(PerformUploadDeviceSignaturesPath,
|
||||
httputil.MakeInternalAPI("performUploadDeviceSignatures", func(req *http.Request) util.JSONResponse {
|
||||
request := api.PerformUploadDeviceSignaturesRequest{}
|
||||
response := api.PerformUploadDeviceSignaturesResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.PerformUploadDeviceSignatures(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
PerformUploadDeviceSignaturesPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverPerformUploadDeviceSignatures", s.PerformUploadDeviceSignatures),
|
||||
)
|
||||
internalAPIMux.Handle(QueryKeysPath,
|
||||
httputil.MakeInternalAPI("queryKeys", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryKeysRequest{}
|
||||
response := api.QueryKeysResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.QueryKeys(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
QueryKeysPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverQueryKeys", s.QueryKeys),
|
||||
)
|
||||
internalAPIMux.Handle(QueryOneTimeKeysPath,
|
||||
httputil.MakeInternalAPI("queryOneTimeKeys", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryOneTimeKeysRequest{}
|
||||
response := api.QueryOneTimeKeysResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.QueryOneTimeKeys(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
QueryOneTimeKeysPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverQueryOneTimeKeys", s.QueryOneTimeKeys),
|
||||
)
|
||||
internalAPIMux.Handle(QueryDeviceMessagesPath,
|
||||
httputil.MakeInternalAPI("queryDeviceMessages", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryDeviceMessagesRequest{}
|
||||
response := api.QueryDeviceMessagesResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.QueryDeviceMessages(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
QueryDeviceMessagesPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverQueryDeviceMessages", s.QueryDeviceMessages),
|
||||
)
|
||||
internalAPIMux.Handle(QueryKeyChangesPath,
|
||||
httputil.MakeInternalAPI("queryKeyChanges", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryKeyChangesRequest{}
|
||||
response := api.QueryKeyChangesResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.QueryKeyChanges(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
QueryKeyChangesPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverQueryKeyChanges", s.QueryKeyChanges),
|
||||
)
|
||||
internalAPIMux.Handle(QuerySignaturesPath,
|
||||
httputil.MakeInternalAPI("querySignatures", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QuerySignaturesRequest{}
|
||||
response := api.QuerySignaturesResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
s.QuerySignatures(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
QuerySignaturesPath,
|
||||
httputil.MakeInternalRPCAPI("KeyserverQuerySignatures", s.QuerySignatures),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import (
|
|||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/lib/pq"
|
||||
|
||||
"github.com/matrix-org/dendrite/internal"
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/dendrite/keyserver/storage/postgres/deltas"
|
||||
|
|
@ -64,7 +66,8 @@ func NewPostgresKeyChangesTable(db *sql.DB) (tables.KeyChanges, error) {
|
|||
// TODO: Remove when we are sure we are not having goose artefacts in the db
|
||||
// This forces an error, which indicates the migration is already applied, since the
|
||||
// column partition was removed from the table
|
||||
err = db.QueryRow("SELECT partition FROM keyserver_key_changes LIMIT 1;").Scan()
|
||||
var count int
|
||||
err = db.QueryRow("SELECT partition FROM keyserver_key_changes LIMIT 1;").Scan(&count)
|
||||
if err == nil {
|
||||
m := sqlutil.NewMigrator(db)
|
||||
m.AddMigrations(sqlutil.Migration{
|
||||
|
|
@ -72,6 +75,16 @@ func NewPostgresKeyChangesTable(db *sql.DB) (tables.KeyChanges, error) {
|
|||
Up: deltas.UpRefactorKeyChanges,
|
||||
})
|
||||
return s, m.Up(context.Background())
|
||||
} else {
|
||||
switch e := err.(type) {
|
||||
case *pq.Error:
|
||||
// ignore undefined_column (42703) errors, as this is expected at this point
|
||||
if e.Code != "42703" {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ func NewSqliteKeyChangesTable(db *sql.DB) (tables.KeyChanges, error) {
|
|||
// TODO: Remove when we are sure we are not having goose artefacts in the db
|
||||
// This forces an error, which indicates the migration is already applied, since the
|
||||
// column partition was removed from the table
|
||||
err = db.QueryRow("SELECT partition FROM keyserver_key_changes LIMIT 1;").Scan()
|
||||
var count int
|
||||
err = db.QueryRow("SELECT partition FROM keyserver_key_changes LIMIT 1;").Scan(&count)
|
||||
if err == nil {
|
||||
m := sqlutil.NewMigrator(db)
|
||||
m.AddMigrations(sqlutil.Migration{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package storage_test
|
|||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/matrix-org/dendrite/keyserver/api"
|
||||
|
|
@ -103,6 +104,9 @@ func TestKeyChangesUpperLimit(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
var dbLock sync.Mutex
|
||||
var deviceArray = []string{"AAA", "another_device"}
|
||||
|
||||
// The purpose of this test is to make sure that the storage layer is generating sequential stream IDs per user,
|
||||
// and that they are returned correctly when querying for device keys.
|
||||
func TestDeviceKeysStreamIDGeneration(t *testing.T) {
|
||||
|
|
@ -169,8 +173,11 @@ func TestDeviceKeysStreamIDGeneration(t *testing.T) {
|
|||
t.Fatalf("Expected StoreLocalDeviceKeys to set StreamID=3 (new key same device) but got %d", msgs[0].StreamID)
|
||||
}
|
||||
|
||||
dbLock.Lock()
|
||||
defer dbLock.Unlock()
|
||||
// Querying for device keys returns the latest stream IDs
|
||||
msgs, err = db.DeviceKeysForUser(ctx, alice, []string{"AAA", "another_device"}, false)
|
||||
msgs, err = db.DeviceKeysForUser(ctx, alice, deviceArray, false)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("DeviceKeysForUser returned error: %s", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import (
|
|||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
|
@ -180,7 +179,7 @@ func createTempDir(baseDirectory config.Path) (types.Path, error) {
|
|||
if err := os.MkdirAll(baseTmpDir, 0770); err != nil {
|
||||
return "", fmt.Errorf("failed to create base temp dir: %w", err)
|
||||
}
|
||||
tmpDir, err := ioutil.TempDir(baseTmpDir, "")
|
||||
tmpDir, err := os.MkdirTemp(baseTmpDir, "")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create temp dir: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
|
@ -695,7 +694,7 @@ func (r *downloadRequest) GetContentLengthAndReader(contentLengthHeader string,
|
|||
|
||||
// We successfully parsed the Content-Length, so we'll return a limited
|
||||
// reader that restricts us to reading only up to this size.
|
||||
reader = ioutil.NopCloser(io.LimitReader(*body, parsedLength))
|
||||
reader = io.NopCloser(io.LimitReader(*body, parsedLength))
|
||||
contentLength = parsedLength
|
||||
} else {
|
||||
// Content-Length header is missing. If we have a maximum file size
|
||||
|
|
@ -704,7 +703,7 @@ func (r *downloadRequest) GetContentLengthAndReader(contentLengthHeader string,
|
|||
// ultimately it will get rewritten later when the temp file is written
|
||||
// to disk.
|
||||
if maxFileSizeBytes > 0 {
|
||||
reader = ioutil.NopCloser(io.LimitReader(*body, int64(maxFileSizeBytes)))
|
||||
reader = io.NopCloser(io.LimitReader(*body, int64(maxFileSizeBytes)))
|
||||
}
|
||||
contentLength = 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ type InputRoomEventsAPI interface {
|
|||
ctx context.Context,
|
||||
req *InputRoomEventsRequest,
|
||||
res *InputRoomEventsResponse,
|
||||
)
|
||||
) error
|
||||
}
|
||||
|
||||
// Query the latest events and state for a room from the room server.
|
||||
|
|
@ -97,6 +97,14 @@ type SyncRoomserverAPI interface {
|
|||
req *PerformBackfillRequest,
|
||||
res *PerformBackfillResponse,
|
||||
) error
|
||||
|
||||
// QueryMembershipAtEvent queries the memberships at the given events.
|
||||
// Returns a map from eventID to a slice of gomatrixserverlib.HeaderedEvent.
|
||||
QueryMembershipAtEvent(
|
||||
ctx context.Context,
|
||||
request *QueryMembershipAtEventRequest,
|
||||
response *QueryMembershipAtEventResponse,
|
||||
) error
|
||||
}
|
||||
|
||||
type AppserviceRoomserverAPI interface {
|
||||
|
|
@ -139,15 +147,15 @@ type ClientRoomserverAPI interface {
|
|||
GetAliasesForRoomID(ctx context.Context, req *GetAliasesForRoomIDRequest, res *GetAliasesForRoomIDResponse) error
|
||||
|
||||
// PerformRoomUpgrade upgrades a room to a newer version
|
||||
PerformRoomUpgrade(ctx context.Context, req *PerformRoomUpgradeRequest, resp *PerformRoomUpgradeResponse)
|
||||
PerformAdminEvacuateRoom(ctx context.Context, req *PerformAdminEvacuateRoomRequest, res *PerformAdminEvacuateRoomResponse)
|
||||
PerformAdminEvacuateUser(ctx context.Context, req *PerformAdminEvacuateUserRequest, res *PerformAdminEvacuateUserResponse)
|
||||
PerformPeek(ctx context.Context, req *PerformPeekRequest, res *PerformPeekResponse)
|
||||
PerformUnpeek(ctx context.Context, req *PerformUnpeekRequest, res *PerformUnpeekResponse)
|
||||
PerformRoomUpgrade(ctx context.Context, req *PerformRoomUpgradeRequest, resp *PerformRoomUpgradeResponse) error
|
||||
PerformAdminEvacuateRoom(ctx context.Context, req *PerformAdminEvacuateRoomRequest, res *PerformAdminEvacuateRoomResponse) error
|
||||
PerformAdminEvacuateUser(ctx context.Context, req *PerformAdminEvacuateUserRequest, res *PerformAdminEvacuateUserResponse) error
|
||||
PerformPeek(ctx context.Context, req *PerformPeekRequest, res *PerformPeekResponse) error
|
||||
PerformUnpeek(ctx context.Context, req *PerformUnpeekRequest, res *PerformUnpeekResponse) error
|
||||
PerformInvite(ctx context.Context, req *PerformInviteRequest, res *PerformInviteResponse) error
|
||||
PerformJoin(ctx context.Context, req *PerformJoinRequest, res *PerformJoinResponse)
|
||||
PerformJoin(ctx context.Context, req *PerformJoinRequest, res *PerformJoinResponse) error
|
||||
PerformLeave(ctx context.Context, req *PerformLeaveRequest, res *PerformLeaveResponse) error
|
||||
PerformPublish(ctx context.Context, req *PerformPublishRequest, res *PerformPublishResponse)
|
||||
PerformPublish(ctx context.Context, req *PerformPublishRequest, res *PerformPublishResponse) error
|
||||
// PerformForget forgets a rooms history for a specific user
|
||||
PerformForget(ctx context.Context, req *PerformForgetRequest, resp *PerformForgetResponse) error
|
||||
SetRoomAlias(ctx context.Context, req *SetRoomAliasRequest, res *SetRoomAliasResponse) error
|
||||
|
|
@ -158,7 +166,7 @@ type UserRoomserverAPI interface {
|
|||
QueryLatestEventsAndStateAPI
|
||||
QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error
|
||||
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
|
||||
PerformAdminEvacuateUser(ctx context.Context, req *PerformAdminEvacuateUserRequest, res *PerformAdminEvacuateUserResponse)
|
||||
PerformAdminEvacuateUser(ctx context.Context, req *PerformAdminEvacuateUserRequest, res *PerformAdminEvacuateUserResponse) error
|
||||
}
|
||||
|
||||
type FederationRoomserverAPI interface {
|
||||
|
|
|
|||
|
|
@ -35,9 +35,10 @@ func (t *RoomserverInternalAPITrace) InputRoomEvents(
|
|||
ctx context.Context,
|
||||
req *InputRoomEventsRequest,
|
||||
res *InputRoomEventsResponse,
|
||||
) {
|
||||
t.Impl.InputRoomEvents(ctx, req, res)
|
||||
util.GetLogger(ctx).Infof("InputRoomEvents req=%+v res=%+v", js(req), js(res))
|
||||
) error {
|
||||
err := t.Impl.InputRoomEvents(ctx, req, res)
|
||||
util.GetLogger(ctx).WithError(err).Infof("InputRoomEvents req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) PerformInvite(
|
||||
|
|
@ -45,44 +46,49 @@ func (t *RoomserverInternalAPITrace) PerformInvite(
|
|||
req *PerformInviteRequest,
|
||||
res *PerformInviteResponse,
|
||||
) error {
|
||||
util.GetLogger(ctx).Infof("PerformInvite req=%+v res=%+v", js(req), js(res))
|
||||
return t.Impl.PerformInvite(ctx, req, res)
|
||||
err := t.Impl.PerformInvite(ctx, req, res)
|
||||
util.GetLogger(ctx).WithError(err).Infof("PerformInvite req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) PerformPeek(
|
||||
ctx context.Context,
|
||||
req *PerformPeekRequest,
|
||||
res *PerformPeekResponse,
|
||||
) {
|
||||
t.Impl.PerformPeek(ctx, req, res)
|
||||
util.GetLogger(ctx).Infof("PerformPeek req=%+v res=%+v", js(req), js(res))
|
||||
) error {
|
||||
err := t.Impl.PerformPeek(ctx, req, res)
|
||||
util.GetLogger(ctx).WithError(err).Infof("PerformPeek req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) PerformUnpeek(
|
||||
ctx context.Context,
|
||||
req *PerformUnpeekRequest,
|
||||
res *PerformUnpeekResponse,
|
||||
) {
|
||||
t.Impl.PerformUnpeek(ctx, req, res)
|
||||
util.GetLogger(ctx).Infof("PerformUnpeek req=%+v res=%+v", js(req), js(res))
|
||||
) error {
|
||||
err := t.Impl.PerformUnpeek(ctx, req, res)
|
||||
util.GetLogger(ctx).WithError(err).Infof("PerformUnpeek req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) PerformRoomUpgrade(
|
||||
ctx context.Context,
|
||||
req *PerformRoomUpgradeRequest,
|
||||
res *PerformRoomUpgradeResponse,
|
||||
) {
|
||||
t.Impl.PerformRoomUpgrade(ctx, req, res)
|
||||
util.GetLogger(ctx).Infof("PerformRoomUpgrade req=%+v res=%+v", js(req), js(res))
|
||||
) error {
|
||||
err := t.Impl.PerformRoomUpgrade(ctx, req, res)
|
||||
util.GetLogger(ctx).WithError(err).Infof("PerformRoomUpgrade req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) PerformJoin(
|
||||
ctx context.Context,
|
||||
req *PerformJoinRequest,
|
||||
res *PerformJoinResponse,
|
||||
) {
|
||||
t.Impl.PerformJoin(ctx, req, res)
|
||||
util.GetLogger(ctx).Infof("PerformJoin req=%+v res=%+v", js(req), js(res))
|
||||
) error {
|
||||
err := t.Impl.PerformJoin(ctx, req, res)
|
||||
util.GetLogger(ctx).WithError(err).Infof("PerformJoin req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) PerformLeave(
|
||||
|
|
@ -99,27 +105,30 @@ func (t *RoomserverInternalAPITrace) PerformPublish(
|
|||
ctx context.Context,
|
||||
req *PerformPublishRequest,
|
||||
res *PerformPublishResponse,
|
||||
) {
|
||||
t.Impl.PerformPublish(ctx, req, res)
|
||||
util.GetLogger(ctx).Infof("PerformPublish req=%+v res=%+v", js(req), js(res))
|
||||
) error {
|
||||
err := t.Impl.PerformPublish(ctx, req, res)
|
||||
util.GetLogger(ctx).WithError(err).Infof("PerformPublish req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) PerformAdminEvacuateRoom(
|
||||
ctx context.Context,
|
||||
req *PerformAdminEvacuateRoomRequest,
|
||||
res *PerformAdminEvacuateRoomResponse,
|
||||
) {
|
||||
t.Impl.PerformAdminEvacuateRoom(ctx, req, res)
|
||||
util.GetLogger(ctx).Infof("PerformAdminEvacuateRoom req=%+v res=%+v", js(req), js(res))
|
||||
) error {
|
||||
err := t.Impl.PerformAdminEvacuateRoom(ctx, req, res)
|
||||
util.GetLogger(ctx).WithError(err).Infof("PerformAdminEvacuateRoom req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) PerformAdminEvacuateUser(
|
||||
ctx context.Context,
|
||||
req *PerformAdminEvacuateUserRequest,
|
||||
res *PerformAdminEvacuateUserResponse,
|
||||
) {
|
||||
t.Impl.PerformAdminEvacuateUser(ctx, req, res)
|
||||
util.GetLogger(ctx).Infof("PerformAdminEvacuateUser req=%+v res=%+v", js(req), js(res))
|
||||
) error {
|
||||
err := t.Impl.PerformAdminEvacuateUser(ctx, req, res)
|
||||
util.GetLogger(ctx).WithError(err).Infof("PerformAdminEvacuateUser req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) PerformInboundPeek(
|
||||
|
|
@ -128,7 +137,7 @@ func (t *RoomserverInternalAPITrace) PerformInboundPeek(
|
|||
res *PerformInboundPeekResponse,
|
||||
) error {
|
||||
err := t.Impl.PerformInboundPeek(ctx, req, res)
|
||||
util.GetLogger(ctx).Infof("PerformInboundPeek req=%+v res=%+v", js(req), js(res))
|
||||
util.GetLogger(ctx).WithError(err).Infof("PerformInboundPeek req=%+v res=%+v", js(req), js(res))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -373,6 +382,16 @@ func (t *RoomserverInternalAPITrace) QueryRestrictedJoinAllowed(
|
|||
return err
|
||||
}
|
||||
|
||||
func (t *RoomserverInternalAPITrace) QueryMembershipAtEvent(
|
||||
ctx context.Context,
|
||||
request *QueryMembershipAtEventRequest,
|
||||
response *QueryMembershipAtEventResponse,
|
||||
) error {
|
||||
err := t.Impl.QueryMembershipAtEvent(ctx, request, response)
|
||||
util.GetLogger(ctx).WithError(err).Infof("QueryMembershipAtEvent req=%+v res=%+v", js(request), js(response))
|
||||
return err
|
||||
}
|
||||
|
||||
func js(thing interface{}) string {
|
||||
b, err := json.Marshal(thing)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -427,3 +427,17 @@ func (r *QueryCurrentStateResponse) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// QueryMembershipAtEventRequest requests the membership events for a user
|
||||
// for a list of eventIDs.
|
||||
type QueryMembershipAtEventRequest struct {
|
||||
RoomID string
|
||||
EventIDs []string
|
||||
UserID string
|
||||
}
|
||||
|
||||
// QueryMembershipAtEventResponse is the response to QueryMembershipAtEventRequest.
|
||||
type QueryMembershipAtEventResponse struct {
|
||||
// Memberships is a map from eventID to a list of events (if any).
|
||||
Memberships map[string][]*gomatrixserverlib.HeaderedEvent `json:"memberships"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,9 @@ func SendInputRoomEvents(
|
|||
Asynchronous: async,
|
||||
}
|
||||
var response InputRoomEventsResponse
|
||||
rsAPI.InputRoomEvents(ctx, &request, &response)
|
||||
if err := rsAPI.InputRoomEvents(ctx, &request, &response); err != nil {
|
||||
return err
|
||||
}
|
||||
return response.Err()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,12 @@ func StateBeforeEvent(ctx context.Context, db storage.Database, info *types.Room
|
|||
return roomState.LoadCombinedStateAfterEvents(ctx, prevState)
|
||||
}
|
||||
|
||||
func MembershipAtEvent(ctx context.Context, db storage.Database, info *types.RoomInfo, eventIDs []string, stateKeyNID types.EventStateKeyNID) (map[string][]types.StateEntry, error) {
|
||||
roomState := state.NewStateResolution(db, info)
|
||||
// Fetch the state as it was when this event was fired
|
||||
return roomState.LoadMembershipAtEvent(ctx, eventIDs, stateKeyNID)
|
||||
}
|
||||
|
||||
func LoadEvents(
|
||||
ctx context.Context, db storage.Database, eventNIDs []types.EventNID,
|
||||
) ([]*gomatrixserverlib.Event, error) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ import (
|
|||
|
||||
"github.com/Arceliar/phony"
|
||||
"github.com/getsentry/sentry-go"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
fedapi "github.com/matrix-org/dendrite/federationapi/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/acls"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
|
|
@ -35,10 +40,6 @@ import (
|
|||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||
"github.com/matrix-org/dendrite/setup/process"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Inputer is responsible for consuming from the roomserver input
|
||||
|
|
@ -60,9 +61,9 @@ import (
|
|||
// per-room durable consumers will only progress through the stream
|
||||
// as events are processed.
|
||||
//
|
||||
// A BC * -> positions of each consumer (* = ephemeral)
|
||||
// ⌄ ⌄⌄ ⌄
|
||||
// ABAABCAABCAA -> newest (letter = subject for each message)
|
||||
// A BC * -> positions of each consumer (* = ephemeral)
|
||||
// ⌄ ⌄⌄ ⌄
|
||||
// ABAABCAABCAA -> newest (letter = subject for each message)
|
||||
//
|
||||
// In this example, A is still processing an event but has two
|
||||
// pending events to process afterwards. Both B and C are caught
|
||||
|
|
@ -336,18 +337,18 @@ func (r *Inputer) InputRoomEvents(
|
|||
ctx context.Context,
|
||||
request *api.InputRoomEventsRequest,
|
||||
response *api.InputRoomEventsResponse,
|
||||
) {
|
||||
) error {
|
||||
// Queue up the event into the roomserver.
|
||||
replySub, err := r.queueInputRoomEvents(ctx, request)
|
||||
if err != nil {
|
||||
response.ErrMsg = err.Error()
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// If we aren't waiting for synchronous responses then we can
|
||||
// give up here, there is nothing further to do.
|
||||
if replySub == nil {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise, we'll want to sit and wait for the responses
|
||||
|
|
@ -359,12 +360,14 @@ func (r *Inputer) InputRoomEvents(
|
|||
msg, err := replySub.NextMsgWithContext(ctx)
|
||||
if err != nil {
|
||||
response.ErrMsg = err.Error()
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if len(msg.Data) > 0 {
|
||||
response.ErrMsg = string(msg.Data)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var roomserverInputBackpressure = prometheus.NewGaugeVec(
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ func (r *Inputer) processRoomEvent(
|
|||
// allowed at the time, and also to get the history visibility. We won't
|
||||
// bother doing this if the event was already rejected as it just ends up
|
||||
// burning CPU time.
|
||||
historyVisibility := gomatrixserverlib.HistoryVisibilityJoined // Default to restrictive.
|
||||
historyVisibility := gomatrixserverlib.HistoryVisibilityShared // Default to shared.
|
||||
if rejectionErr == nil && !isRejected && !softfail {
|
||||
var err error
|
||||
historyVisibility, rejectionErr, err = r.processStateBefore(ctx, input, missingPrev)
|
||||
|
|
@ -429,7 +429,7 @@ func (r *Inputer) processStateBefore(
|
|||
input *api.InputRoomEvent,
|
||||
missingPrev bool,
|
||||
) (historyVisibility gomatrixserverlib.HistoryVisibility, rejectionErr error, err error) {
|
||||
historyVisibility = gomatrixserverlib.HistoryVisibilityJoined // Default to restrictive.
|
||||
historyVisibility = gomatrixserverlib.HistoryVisibilityShared // Default to shared.
|
||||
event := input.Event.Unwrap()
|
||||
isCreateEvent := event.Type() == gomatrixserverlib.MRoomCreate && event.StateKeyEquals("")
|
||||
var stateBeforeEvent []*gomatrixserverlib.Event
|
||||
|
|
|
|||
|
|
@ -20,32 +20,32 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/state"
|
||||
"github.com/matrix-org/dendrite/roomserver/storage/shared"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// updateLatestEvents updates the list of latest events for this room in the database and writes the
|
||||
// event to the output log.
|
||||
// The latest events are the events that aren't referenced by another event in the database:
|
||||
//
|
||||
// Time goes down the page. 1 is the m.room.create event (root).
|
||||
//
|
||||
// 1 After storing 1 the latest events are {1}
|
||||
// | After storing 2 the latest events are {2}
|
||||
// 2 After storing 3 the latest events are {3}
|
||||
// / \ After storing 4 the latest events are {3,4}
|
||||
// 3 4 After storing 5 the latest events are {5,4}
|
||||
// | | After storing 6 the latest events are {5,6}
|
||||
// 5 6 <--- latest After storing 7 the latest events are {6,7}
|
||||
// |
|
||||
// 7 <----- latest
|
||||
// Time goes down the page. 1 is the m.room.create event (root).
|
||||
// 1 After storing 1 the latest events are {1}
|
||||
// | After storing 2 the latest events are {2}
|
||||
// 2 After storing 3 the latest events are {3}
|
||||
// / \ After storing 4 the latest events are {3,4}
|
||||
// 3 4 After storing 5 the latest events are {5,4}
|
||||
// | | After storing 6 the latest events are {5,6}
|
||||
// 5 6 <--- latest After storing 7 the latest events are {6,7}
|
||||
// |
|
||||
// 7 <----- latest
|
||||
//
|
||||
// Can only be called once at a time
|
||||
func (r *Inputer) updateLatestEvents(
|
||||
|
|
|
|||
|
|
@ -43,21 +43,21 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
ctx context.Context,
|
||||
req *api.PerformAdminEvacuateRoomRequest,
|
||||
res *api.PerformAdminEvacuateRoomResponse,
|
||||
) {
|
||||
) error {
|
||||
roomInfo, err := r.DB.RoomInfo(ctx, req.RoomID)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.RoomInfo: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if roomInfo == nil || roomInfo.IsStub() {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorNoRoom,
|
||||
Msg: fmt.Sprintf("Room %s not found", req.RoomID),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
memberNIDs, err := r.DB.GetMembershipEventNIDsForRoom(ctx, roomInfo.RoomNID, true, true)
|
||||
|
|
@ -66,7 +66,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.GetMembershipEventNIDsForRoom: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
memberEvents, err := r.DB.Events(ctx, memberNIDs)
|
||||
|
|
@ -75,7 +75,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.Events: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
inputEvents := make([]api.InputRoomEvent, 0, len(memberEvents))
|
||||
|
|
@ -89,7 +89,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.Queryer.QueryLatestEventsAndState: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
prevEvents := latestRes.LatestEvents
|
||||
|
|
@ -104,7 +104,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("json.Unmarshal: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
memberContent.Membership = gomatrixserverlib.Leave
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("json.Marshal: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(fledglingEvent)
|
||||
|
|
@ -131,7 +131,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("gomatrixserverlib.StateNeededForEventBuilder: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
event, err := eventutil.BuildEvent(ctx, fledglingEvent, r.Cfg.Matrix, time.Now(), &eventsNeeded, latestRes)
|
||||
|
|
@ -140,7 +140,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("eventutil.BuildEvent: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
inputEvents = append(inputEvents, api.InputRoomEvent{
|
||||
|
|
@ -160,28 +160,28 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Asynchronous: true,
|
||||
}
|
||||
inputRes := &api.InputRoomEventsResponse{}
|
||||
r.Inputer.InputRoomEvents(ctx, inputReq, inputRes)
|
||||
return r.Inputer.InputRoomEvents(ctx, inputReq, inputRes)
|
||||
}
|
||||
|
||||
func (r *Admin) PerformAdminEvacuateUser(
|
||||
ctx context.Context,
|
||||
req *api.PerformAdminEvacuateUserRequest,
|
||||
res *api.PerformAdminEvacuateUserResponse,
|
||||
) {
|
||||
) error {
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Malformed user ID: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if domain != r.Cfg.Matrix.ServerName {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: "Can only evacuate local users using this endpoint",
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
roomIDs, err := r.DB.GetRoomsByMembership(ctx, req.UserID, gomatrixserverlib.Join)
|
||||
|
|
@ -190,7 +190,7 @@ func (r *Admin) PerformAdminEvacuateUser(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.GetRoomsByMembership: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
inviteRoomIDs, err := r.DB.GetRoomsByMembership(ctx, req.UserID, gomatrixserverlib.Invite)
|
||||
|
|
@ -199,7 +199,7 @@ func (r *Admin) PerformAdminEvacuateUser(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.GetRoomsByMembership: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, roomID := range append(roomIDs, inviteRoomIDs...) {
|
||||
|
|
@ -214,7 +214,7 @@ func (r *Admin) PerformAdminEvacuateUser(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.Leaver.PerformLeave: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if len(outputEvents) == 0 {
|
||||
continue
|
||||
|
|
@ -224,9 +224,10 @@ func (r *Admin) PerformAdminEvacuateUser(
|
|||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.Inputer.WriteOutputEvents: %s", err),
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
res.Affected = append(res.Affected, roomID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
|
|
@ -26,9 +30,6 @@ import (
|
|||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// the max number of servers to backfill from per request. If this is too low we may fail to backfill when
|
||||
|
|
@ -522,8 +523,9 @@ func (b *backfillRequester) ProvideEvents(roomVer gomatrixserverlib.RoomVersion,
|
|||
}
|
||||
|
||||
// joinEventsFromHistoryVisibility returns all CURRENTLY joined members if our server can read the room history
|
||||
//
|
||||
// TODO: Long term we probably want a history_visibility table which stores eventNID | visibility_enum so we can just
|
||||
// pull all events and then filter by that table.
|
||||
// pull all events and then filter by that table.
|
||||
func joinEventsFromHistoryVisibility(
|
||||
ctx context.Context, db storage.Database, roomID string, stateEntries []types.StateEntry,
|
||||
thisServer gomatrixserverlib.ServerName) ([]types.Event, error) {
|
||||
|
|
|
|||
|
|
@ -241,7 +241,9 @@ func (r *Inviter) PerformInvite(
|
|||
},
|
||||
}
|
||||
inputRes := &api.InputRoomEventsResponse{}
|
||||
r.Inputer.InputRoomEvents(context.Background(), inputReq, inputRes)
|
||||
if err = r.Inputer.InputRoomEvents(context.Background(), inputReq, inputRes); err != nil {
|
||||
return nil, fmt.Errorf("r.Inputer.InputRoomEvents: %w", err)
|
||||
}
|
||||
if err = inputRes.Err(); err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Msg: fmt.Sprintf("r.InputRoomEvents: %s", err.Error()),
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (r *Joiner) PerformJoin(
|
|||
ctx context.Context,
|
||||
req *rsAPI.PerformJoinRequest,
|
||||
res *rsAPI.PerformJoinResponse,
|
||||
) {
|
||||
) error {
|
||||
logger := logrus.WithContext(ctx).WithFields(logrus.Fields{
|
||||
"room_id": req.RoomIDOrAlias,
|
||||
"user_id": req.UserID,
|
||||
|
|
@ -71,11 +71,12 @@ func (r *Joiner) PerformJoin(
|
|||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
logger.Info("User joined room successfully")
|
||||
res.RoomID = roomID
|
||||
res.JoinedVia = joinedVia
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Joiner) performJoin(
|
||||
|
|
@ -291,7 +292,12 @@ func (r *Joiner) performJoinRoomByID(
|
|||
},
|
||||
}
|
||||
inputRes := rsAPI.InputRoomEventsResponse{}
|
||||
r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes)
|
||||
if err = r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes); err != nil {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorNoOperation,
|
||||
Msg: fmt.Sprintf("InputRoomEvents failed: %s", err),
|
||||
}
|
||||
}
|
||||
if err = inputRes.Err(); err != nil {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorNotAllowed,
|
||||
|
|
|
|||
|
|
@ -186,7 +186,9 @@ func (r *Leaver) performLeaveRoomByID(
|
|||
},
|
||||
}
|
||||
inputRes := api.InputRoomEventsResponse{}
|
||||
r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes)
|
||||
if err = r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes); err != nil {
|
||||
return nil, fmt.Errorf("r.Inputer.InputRoomEvents: %w", err)
|
||||
}
|
||||
if err = inputRes.Err(); err != nil {
|
||||
return nil, fmt.Errorf("r.InputRoomEvents: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ func (r *Peeker) PerformPeek(
|
|||
ctx context.Context,
|
||||
req *api.PerformPeekRequest,
|
||||
res *api.PerformPeekResponse,
|
||||
) {
|
||||
) error {
|
||||
roomID, err := r.performPeek(ctx, req)
|
||||
if err != nil {
|
||||
perr, ok := err.(*api.PerformError)
|
||||
|
|
@ -57,6 +57,7 @@ func (r *Peeker) PerformPeek(
|
|||
}
|
||||
}
|
||||
res.RoomID = roomID
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Peeker) performPeek(
|
||||
|
|
|
|||
|
|
@ -29,11 +29,12 @@ func (r *Publisher) PerformPublish(
|
|||
ctx context.Context,
|
||||
req *api.PerformPublishRequest,
|
||||
res *api.PerformPublishResponse,
|
||||
) {
|
||||
) error {
|
||||
err := r.DB.PublishRoom(ctx, req.RoomID, req.Visibility == "public")
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ func (r *Unpeeker) PerformUnpeek(
|
|||
ctx context.Context,
|
||||
req *api.PerformUnpeekRequest,
|
||||
res *api.PerformUnpeekResponse,
|
||||
) {
|
||||
) error {
|
||||
if err := r.performUnpeek(ctx, req); err != nil {
|
||||
perr, ok := err.(*api.PerformError)
|
||||
if ok {
|
||||
|
|
@ -52,6 +52,7 @@ func (r *Unpeeker) PerformUnpeek(
|
|||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Unpeeker) performUnpeek(
|
||||
|
|
|
|||
|
|
@ -45,12 +45,13 @@ func (r *Upgrader) PerformRoomUpgrade(
|
|||
ctx context.Context,
|
||||
req *api.PerformRoomUpgradeRequest,
|
||||
res *api.PerformRoomUpgradeResponse,
|
||||
) {
|
||||
) error {
|
||||
res.NewRoomID, res.Error = r.performRoomUpgrade(ctx, req)
|
||||
if res.Error != nil {
|
||||
res.NewRoomID = ""
|
||||
logrus.WithContext(ctx).WithError(res.Error).Error("Room upgrade failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Upgrader) performRoomUpgrade(
|
||||
|
|
@ -286,22 +287,24 @@ func publishNewRoomAndUnpublishOldRoom(
|
|||
) {
|
||||
// expose this room in the published room list
|
||||
var pubNewRoomRes api.PerformPublishResponse
|
||||
URSAPI.PerformPublish(ctx, &api.PerformPublishRequest{
|
||||
if err := URSAPI.PerformPublish(ctx, &api.PerformPublishRequest{
|
||||
RoomID: newRoomID,
|
||||
Visibility: "public",
|
||||
}, &pubNewRoomRes)
|
||||
if pubNewRoomRes.Error != nil {
|
||||
}, &pubNewRoomRes); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("failed to reach internal API")
|
||||
} else if pubNewRoomRes.Error != nil {
|
||||
// treat as non-fatal since the room is already made by this point
|
||||
util.GetLogger(ctx).WithError(pubNewRoomRes.Error).Error("failed to visibility:public")
|
||||
}
|
||||
|
||||
var unpubOldRoomRes api.PerformPublishResponse
|
||||
// remove the old room from the published room list
|
||||
URSAPI.PerformPublish(ctx, &api.PerformPublishRequest{
|
||||
if err := URSAPI.PerformPublish(ctx, &api.PerformPublishRequest{
|
||||
RoomID: oldRoomID,
|
||||
Visibility: "private",
|
||||
}, &unpubOldRoomRes)
|
||||
if unpubOldRoomRes.Error != nil {
|
||||
}, &unpubOldRoomRes); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("failed to reach internal API")
|
||||
} else if unpubOldRoomRes.Error != nil {
|
||||
// treat as non-fatal since the room is already made by this point
|
||||
util.GetLogger(ctx).WithError(unpubOldRoomRes.Error).Error("failed to visibility:private")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,6 +204,54 @@ func (r *Queryer) QueryMembershipForUser(
|
|||
return err
|
||||
}
|
||||
|
||||
func (r *Queryer) QueryMembershipAtEvent(
|
||||
ctx context.Context,
|
||||
request *api.QueryMembershipAtEventRequest,
|
||||
response *api.QueryMembershipAtEventResponse,
|
||||
) error {
|
||||
response.Memberships = make(map[string][]*gomatrixserverlib.HeaderedEvent)
|
||||
info, err := r.DB.RoomInfo(ctx, request.RoomID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get roomInfo: %w", err)
|
||||
}
|
||||
if info == nil {
|
||||
return fmt.Errorf("no roomInfo found")
|
||||
}
|
||||
|
||||
// get the users stateKeyNID
|
||||
stateKeyNIDs, err := r.DB.EventStateKeyNIDs(ctx, []string{request.UserID})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get stateKeyNIDs for %s: %w", request.UserID, err)
|
||||
}
|
||||
if _, ok := stateKeyNIDs[request.UserID]; !ok {
|
||||
return fmt.Errorf("requested stateKeyNID for %s was not found", request.UserID)
|
||||
}
|
||||
|
||||
stateEntries, err := helpers.MembershipAtEvent(ctx, r.DB, info, request.EventIDs, stateKeyNIDs[request.UserID])
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get state before event: %w", err)
|
||||
}
|
||||
|
||||
for _, eventID := range request.EventIDs {
|
||||
stateEntry := stateEntries[eventID]
|
||||
memberships, err := helpers.GetMembershipsAtState(ctx, r.DB, stateEntry, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get memberships at state: %w", err)
|
||||
}
|
||||
res := make([]*gomatrixserverlib.HeaderedEvent, 0, len(memberships))
|
||||
|
||||
for i := range memberships {
|
||||
ev := memberships[i]
|
||||
if ev.Type() == gomatrixserverlib.MRoomMember && ev.StateKeyEquals(request.UserID) {
|
||||
res = append(res, ev.Headered(info.RoomVersion))
|
||||
}
|
||||
}
|
||||
response.Memberships[eventID] = res
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// QueryMembershipsForRoom implements api.RoomserverInternalAPI
|
||||
func (r *Queryer) QueryMembershipsForRoom(
|
||||
ctx context.Context,
|
||||
|
|
|
|||
|
|
@ -3,18 +3,16 @@ package inthttp
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
||||
asAPI "github.com/matrix-org/dendrite/appservice/api"
|
||||
fsInputAPI "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/roomserver/api"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -63,6 +61,7 @@ const (
|
|||
RoomserverQueryServerBannedFromRoomPath = "/roomserver/queryServerBannedFromRoom"
|
||||
RoomserverQueryAuthChainPath = "/roomserver/queryAuthChain"
|
||||
RoomserverQueryRestrictedJoinAllowed = "/roomserver/queryRestrictedJoinAllowed"
|
||||
RoomserverQueryMembershipAtEventPath = "/roomserver/queryMembershipAtEvent"
|
||||
)
|
||||
|
||||
type httpRoomserverInternalAPI struct {
|
||||
|
|
@ -106,11 +105,10 @@ func (h *httpRoomserverInternalAPI) SetRoomAlias(
|
|||
request *api.SetRoomAliasRequest,
|
||||
response *api.SetRoomAliasResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "SetRoomAlias")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverSetRoomAliasPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"SetRoomAlias", h.roomserverURL+RoomserverSetRoomAliasPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// GetRoomIDForAlias implements RoomserverAliasAPI
|
||||
|
|
@ -119,11 +117,10 @@ func (h *httpRoomserverInternalAPI) GetRoomIDForAlias(
|
|||
request *api.GetRoomIDForAliasRequest,
|
||||
response *api.GetRoomIDForAliasResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "GetRoomIDForAlias")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverGetRoomIDForAliasPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"GetRoomIDForAlias", h.roomserverURL+RoomserverGetRoomIDForAliasPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// GetAliasesForRoomID implements RoomserverAliasAPI
|
||||
|
|
@ -132,11 +129,10 @@ func (h *httpRoomserverInternalAPI) GetAliasesForRoomID(
|
|||
request *api.GetAliasesForRoomIDRequest,
|
||||
response *api.GetAliasesForRoomIDResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "GetAliasesForRoomID")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverGetAliasesForRoomIDPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"GetAliasesForRoomID", h.roomserverURL+RoomserverGetAliasesForRoomIDPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// RemoveRoomAlias implements RoomserverAliasAPI
|
||||
|
|
@ -145,11 +141,10 @@ func (h *httpRoomserverInternalAPI) RemoveRoomAlias(
|
|||
request *api.RemoveRoomAliasRequest,
|
||||
response *api.RemoveRoomAliasResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "RemoveRoomAlias")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverRemoveRoomAliasPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"RemoveRoomAlias", h.roomserverURL+RoomserverRemoveRoomAliasPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// InputRoomEvents implements RoomserverInputAPI
|
||||
|
|
@ -157,15 +152,14 @@ func (h *httpRoomserverInternalAPI) InputRoomEvents(
|
|||
ctx context.Context,
|
||||
request *api.InputRoomEventsRequest,
|
||||
response *api.InputRoomEventsResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "InputRoomEvents")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverInputRoomEventsPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
) error {
|
||||
if err := httputil.CallInternalRPCAPI(
|
||||
"InputRoomEvents", h.roomserverURL+RoomserverInputRoomEventsPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
); err != nil {
|
||||
response.ErrMsg = err.Error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformInvite(
|
||||
|
|
@ -173,45 +167,32 @@ func (h *httpRoomserverInternalAPI) PerformInvite(
|
|||
request *api.PerformInviteRequest,
|
||||
response *api.PerformInviteResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformInvite")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformInvitePath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformInvite", h.roomserverURL+RoomserverPerformInvitePath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformJoin(
|
||||
ctx context.Context,
|
||||
request *api.PerformJoinRequest,
|
||||
response *api.PerformJoinResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformJoin")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformJoinPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.PerformError{
|
||||
Msg: fmt.Sprintf("failed to communicate with roomserver: %s", err),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformJoin", h.roomserverURL+RoomserverPerformJoinPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformPeek(
|
||||
ctx context.Context,
|
||||
request *api.PerformPeekRequest,
|
||||
response *api.PerformPeekResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformPeek")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformPeekPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.PerformError{
|
||||
Msg: fmt.Sprintf("failed to communicate with roomserver: %s", err),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformPeek", h.roomserverURL+RoomserverPerformPeekPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformInboundPeek(
|
||||
|
|
@ -219,45 +200,32 @@ func (h *httpRoomserverInternalAPI) PerformInboundPeek(
|
|||
request *api.PerformInboundPeekRequest,
|
||||
response *api.PerformInboundPeekResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformInboundPeek")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformInboundPeekPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformInboundPeek", h.roomserverURL+RoomserverPerformInboundPeekPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformUnpeek(
|
||||
ctx context.Context,
|
||||
request *api.PerformUnpeekRequest,
|
||||
response *api.PerformUnpeekResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformUnpeek")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformUnpeekPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.PerformError{
|
||||
Msg: fmt.Sprintf("failed to communicate with roomserver: %s", err),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformUnpeek", h.roomserverURL+RoomserverPerformUnpeekPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformRoomUpgrade(
|
||||
ctx context.Context,
|
||||
request *api.PerformRoomUpgradeRequest,
|
||||
response *api.PerformRoomUpgradeResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformRoomUpgrade")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformRoomUpgradePath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
if err != nil {
|
||||
response.Error = &api.PerformError{
|
||||
Msg: fmt.Sprintf("failed to communicate with roomserver: %s", err),
|
||||
}
|
||||
}
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformRoomUpgrade", h.roomserverURL+RoomserverPerformRoomUpgradePath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformLeave(
|
||||
|
|
@ -265,62 +233,43 @@ func (h *httpRoomserverInternalAPI) PerformLeave(
|
|||
request *api.PerformLeaveRequest,
|
||||
response *api.PerformLeaveResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformLeave")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformLeavePath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformLeave", h.roomserverURL+RoomserverPerformLeavePath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformPublish(
|
||||
ctx context.Context,
|
||||
req *api.PerformPublishRequest,
|
||||
res *api.PerformPublishResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformPublish")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformPublishPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Msg: fmt.Sprintf("failed to communicate with roomserver: %s", err),
|
||||
}
|
||||
}
|
||||
request *api.PerformPublishRequest,
|
||||
response *api.PerformPublishResponse,
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformPublish", h.roomserverURL+RoomserverPerformPublishPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformAdminEvacuateRoom(
|
||||
ctx context.Context,
|
||||
req *api.PerformAdminEvacuateRoomRequest,
|
||||
res *api.PerformAdminEvacuateRoomResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformAdminEvacuateRoom")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformAdminEvacuateRoomPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Msg: fmt.Sprintf("failed to communicate with roomserver: %s", err),
|
||||
}
|
||||
}
|
||||
request *api.PerformAdminEvacuateRoomRequest,
|
||||
response *api.PerformAdminEvacuateRoomResponse,
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformAdminEvacuateRoom", h.roomserverURL+RoomserverPerformAdminEvacuateRoomPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformAdminEvacuateUser(
|
||||
ctx context.Context,
|
||||
req *api.PerformAdminEvacuateUserRequest,
|
||||
res *api.PerformAdminEvacuateUserResponse,
|
||||
) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformAdminEvacuateUser")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformAdminEvacuateUserPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Msg: fmt.Sprintf("failed to communicate with roomserver: %s", err),
|
||||
}
|
||||
}
|
||||
request *api.PerformAdminEvacuateUserRequest,
|
||||
response *api.PerformAdminEvacuateUserResponse,
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformAdminEvacuateUser", h.roomserverURL+RoomserverPerformAdminEvacuateUserPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryLatestEventsAndState implements RoomserverQueryAPI
|
||||
|
|
@ -329,11 +278,10 @@ func (h *httpRoomserverInternalAPI) QueryLatestEventsAndState(
|
|||
request *api.QueryLatestEventsAndStateRequest,
|
||||
response *api.QueryLatestEventsAndStateResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryLatestEventsAndState")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryLatestEventsAndStatePath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryLatestEventsAndState", h.roomserverURL+RoomserverQueryLatestEventsAndStatePath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryStateAfterEvents implements RoomserverQueryAPI
|
||||
|
|
@ -342,11 +290,10 @@ func (h *httpRoomserverInternalAPI) QueryStateAfterEvents(
|
|||
request *api.QueryStateAfterEventsRequest,
|
||||
response *api.QueryStateAfterEventsResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryStateAfterEvents")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryStateAfterEventsPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryStateAfterEvents", h.roomserverURL+RoomserverQueryStateAfterEventsPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryEventsByID implements RoomserverQueryAPI
|
||||
|
|
@ -355,11 +302,10 @@ func (h *httpRoomserverInternalAPI) QueryEventsByID(
|
|||
request *api.QueryEventsByIDRequest,
|
||||
response *api.QueryEventsByIDResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryEventsByID")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryEventsByIDPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryEventsByID", h.roomserverURL+RoomserverQueryEventsByIDPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) QueryPublishedRooms(
|
||||
|
|
@ -367,11 +313,10 @@ func (h *httpRoomserverInternalAPI) QueryPublishedRooms(
|
|||
request *api.QueryPublishedRoomsRequest,
|
||||
response *api.QueryPublishedRoomsResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryPublishedRooms")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryPublishedRoomsPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryPublishedRooms", h.roomserverURL+RoomserverQueryPublishedRoomsPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryMembershipForUser implements RoomserverQueryAPI
|
||||
|
|
@ -380,11 +325,10 @@ func (h *httpRoomserverInternalAPI) QueryMembershipForUser(
|
|||
request *api.QueryMembershipForUserRequest,
|
||||
response *api.QueryMembershipForUserResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryMembershipForUser")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryMembershipForUserPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryMembershipForUser", h.roomserverURL+RoomserverQueryMembershipForUserPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryMembershipsForRoom implements RoomserverQueryAPI
|
||||
|
|
@ -393,11 +337,10 @@ func (h *httpRoomserverInternalAPI) QueryMembershipsForRoom(
|
|||
request *api.QueryMembershipsForRoomRequest,
|
||||
response *api.QueryMembershipsForRoomResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryMembershipsForRoom")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryMembershipsForRoomPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryMembershipsForRoom", h.roomserverURL+RoomserverQueryMembershipsForRoomPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryMembershipsForRoom implements RoomserverQueryAPI
|
||||
|
|
@ -406,11 +349,10 @@ func (h *httpRoomserverInternalAPI) QueryServerJoinedToRoom(
|
|||
request *api.QueryServerJoinedToRoomRequest,
|
||||
response *api.QueryServerJoinedToRoomResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerJoinedToRoom")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryServerJoinedToRoomPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryServerJoinedToRoom", h.roomserverURL+RoomserverQueryServerJoinedToRoomPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryServerAllowedToSeeEvent implements RoomserverQueryAPI
|
||||
|
|
@ -419,11 +361,10 @@ func (h *httpRoomserverInternalAPI) QueryServerAllowedToSeeEvent(
|
|||
request *api.QueryServerAllowedToSeeEventRequest,
|
||||
response *api.QueryServerAllowedToSeeEventResponse,
|
||||
) (err error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerAllowedToSeeEvent")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryServerAllowedToSeeEventPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryServerAllowedToSeeEvent", h.roomserverURL+RoomserverQueryServerAllowedToSeeEventPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryMissingEvents implements RoomServerQueryAPI
|
||||
|
|
@ -432,11 +373,10 @@ func (h *httpRoomserverInternalAPI) QueryMissingEvents(
|
|||
request *api.QueryMissingEventsRequest,
|
||||
response *api.QueryMissingEventsResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryMissingEvents")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryMissingEventsPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryMissingEvents", h.roomserverURL+RoomserverQueryMissingEventsPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryStateAndAuthChain implements RoomserverQueryAPI
|
||||
|
|
@ -445,11 +385,10 @@ func (h *httpRoomserverInternalAPI) QueryStateAndAuthChain(
|
|||
request *api.QueryStateAndAuthChainRequest,
|
||||
response *api.QueryStateAndAuthChainResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryStateAndAuthChain")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryStateAndAuthChainPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryStateAndAuthChain", h.roomserverURL+RoomserverQueryStateAndAuthChainPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// PerformBackfill implements RoomServerQueryAPI
|
||||
|
|
@ -458,11 +397,10 @@ func (h *httpRoomserverInternalAPI) PerformBackfill(
|
|||
request *api.PerformBackfillRequest,
|
||||
response *api.PerformBackfillResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformBackfill")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformBackfillPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformBackfill", h.roomserverURL+RoomserverPerformBackfillPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryRoomVersionCapabilities implements RoomServerQueryAPI
|
||||
|
|
@ -471,11 +409,10 @@ func (h *httpRoomserverInternalAPI) QueryRoomVersionCapabilities(
|
|||
request *api.QueryRoomVersionCapabilitiesRequest,
|
||||
response *api.QueryRoomVersionCapabilitiesResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryRoomVersionCapabilities")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryRoomVersionCapabilitiesPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryRoomVersionCapabilities", h.roomserverURL+RoomserverQueryRoomVersionCapabilitiesPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
// QueryRoomVersionForRoom implements RoomServerQueryAPI
|
||||
|
|
@ -488,12 +425,10 @@ func (h *httpRoomserverInternalAPI) QueryRoomVersionForRoom(
|
|||
response.RoomVersion = roomVersion
|
||||
return nil
|
||||
}
|
||||
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryRoomVersionForRoom")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryRoomVersionForRoomPath
|
||||
err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
err := httputil.CallInternalRPCAPI(
|
||||
"QueryRoomVersionForRoom", h.roomserverURL+RoomserverQueryRoomVersionForRoomPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
if err == nil {
|
||||
h.cache.StoreRoomVersion(request.RoomID, response.RoomVersion)
|
||||
}
|
||||
|
|
@ -505,11 +440,10 @@ func (h *httpRoomserverInternalAPI) QueryCurrentState(
|
|||
request *api.QueryCurrentStateRequest,
|
||||
response *api.QueryCurrentStateResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryCurrentState")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryCurrentStatePath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryCurrentState", h.roomserverURL+RoomserverQueryCurrentStatePath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) QueryRoomsForUser(
|
||||
|
|
@ -517,11 +451,10 @@ func (h *httpRoomserverInternalAPI) QueryRoomsForUser(
|
|||
request *api.QueryRoomsForUserRequest,
|
||||
response *api.QueryRoomsForUserResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryRoomsForUser")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryRoomsForUserPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryRoomsForUser", h.roomserverURL+RoomserverQueryRoomsForUserPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) QueryBulkStateContent(
|
||||
|
|
@ -529,68 +462,82 @@ func (h *httpRoomserverInternalAPI) QueryBulkStateContent(
|
|||
request *api.QueryBulkStateContentRequest,
|
||||
response *api.QueryBulkStateContentResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryBulkStateContent")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryBulkStateContentPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryBulkStateContent", h.roomserverURL+RoomserverQueryBulkStateContentPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) QuerySharedUsers(
|
||||
ctx context.Context, req *api.QuerySharedUsersRequest, res *api.QuerySharedUsersResponse,
|
||||
ctx context.Context,
|
||||
request *api.QuerySharedUsersRequest,
|
||||
response *api.QuerySharedUsersResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QuerySharedUsers")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQuerySharedUsersPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QuerySharedUsers", h.roomserverURL+RoomserverQuerySharedUsersPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) QueryKnownUsers(
|
||||
ctx context.Context, req *api.QueryKnownUsersRequest, res *api.QueryKnownUsersResponse,
|
||||
ctx context.Context,
|
||||
request *api.QueryKnownUsersRequest,
|
||||
response *api.QueryKnownUsersResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryKnownUsers")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryKnownUsersPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryKnownUsers", h.roomserverURL+RoomserverQueryKnownUsersPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) QueryAuthChain(
|
||||
ctx context.Context, req *api.QueryAuthChainRequest, res *api.QueryAuthChainResponse,
|
||||
ctx context.Context,
|
||||
request *api.QueryAuthChainRequest,
|
||||
response *api.QueryAuthChainResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryAuthChain")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryAuthChainPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryAuthChain", h.roomserverURL+RoomserverQueryAuthChainPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) QueryServerBannedFromRoom(
|
||||
ctx context.Context, req *api.QueryServerBannedFromRoomRequest, res *api.QueryServerBannedFromRoomResponse,
|
||||
ctx context.Context,
|
||||
request *api.QueryServerBannedFromRoomRequest,
|
||||
response *api.QueryServerBannedFromRoomResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryServerBannedFromRoom")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryServerBannedFromRoomPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryServerBannedFromRoom", h.roomserverURL+RoomserverQueryServerBannedFromRoomPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) QueryRestrictedJoinAllowed(
|
||||
ctx context.Context, req *api.QueryRestrictedJoinAllowedRequest, res *api.QueryRestrictedJoinAllowedResponse,
|
||||
ctx context.Context,
|
||||
request *api.QueryRestrictedJoinAllowedRequest,
|
||||
response *api.QueryRestrictedJoinAllowedResponse,
|
||||
) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "QueryRestrictedJoinAllowed")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverQueryRestrictedJoinAllowed
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryRestrictedJoinAllowed", h.roomserverURL+RoomserverQueryRestrictedJoinAllowed,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) PerformForget(ctx context.Context, req *api.PerformForgetRequest, res *api.PerformForgetResponse) error {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "PerformForget")
|
||||
defer span.Finish()
|
||||
|
||||
apiURL := h.roomserverURL + RoomserverPerformForgetPath
|
||||
return httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
|
||||
func (h *httpRoomserverInternalAPI) PerformForget(
|
||||
ctx context.Context,
|
||||
request *api.PerformForgetRequest,
|
||||
response *api.PerformForgetResponse,
|
||||
) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"PerformForget", h.roomserverURL+RoomserverPerformForgetPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
func (h *httpRoomserverInternalAPI) QueryMembershipAtEvent(ctx context.Context, request *api.QueryMembershipAtEventRequest, response *api.QueryMembershipAtEventResponse) error {
|
||||
return httputil.CallInternalRPCAPI(
|
||||
"QueryMembershiptAtEvent", h.roomserverURL+RoomserverQueryMembershipAtEventPath,
|
||||
h.httpClient, ctx, request, response,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,499 +1,201 @@
|
|||
package inthttp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
// AddRoutes adds the RoomserverInternalAPI handlers to the http.ServeMux.
|
||||
// nolint: gocyclo
|
||||
func AddRoutes(r api.RoomserverInternalAPI, internalAPIMux *mux.Router) {
|
||||
internalAPIMux.Handle(RoomserverInputRoomEventsPath,
|
||||
httputil.MakeInternalAPI("inputRoomEvents", func(req *http.Request) util.JSONResponse {
|
||||
var request api.InputRoomEventsRequest
|
||||
var response api.InputRoomEventsResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
r.InputRoomEvents(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
internalAPIMux.Handle(
|
||||
RoomserverInputRoomEventsPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverInputRoomEvents", r.InputRoomEvents),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformInvitePath,
|
||||
httputil.MakeInternalAPI("performInvite", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformInviteRequest
|
||||
var response api.PerformInviteResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.PerformInvite(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformInvitePath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformInvite", r.PerformInvite),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformJoinPath,
|
||||
httputil.MakeInternalAPI("performJoin", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformJoinRequest
|
||||
var response api.PerformJoinResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
r.PerformJoin(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformJoinPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformJoin", r.PerformJoin),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformLeavePath,
|
||||
httputil.MakeInternalAPI("performLeave", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformLeaveRequest
|
||||
var response api.PerformLeaveResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.PerformLeave(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformLeavePath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformLeave", r.PerformLeave),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformPeekPath,
|
||||
httputil.MakeInternalAPI("performPeek", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformPeekRequest
|
||||
var response api.PerformPeekResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
r.PerformPeek(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformPeekPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformPeek", r.PerformPeek),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformInboundPeekPath,
|
||||
httputil.MakeInternalAPI("performInboundPeek", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformInboundPeekRequest
|
||||
var response api.PerformInboundPeekResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.PerformInboundPeek(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformInboundPeekPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformInboundPeek", r.PerformInboundPeek),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformPeekPath,
|
||||
httputil.MakeInternalAPI("performUnpeek", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformUnpeekRequest
|
||||
var response api.PerformUnpeekResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
r.PerformUnpeek(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformUnpeekPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformUnpeek", r.PerformUnpeek),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformRoomUpgradePath,
|
||||
httputil.MakeInternalAPI("performRoomUpgrade", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformRoomUpgradeRequest
|
||||
var response api.PerformRoomUpgradeResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
r.PerformRoomUpgrade(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformRoomUpgradePath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformRoomUpgrade", r.PerformRoomUpgrade),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformPublishPath,
|
||||
httputil.MakeInternalAPI("performPublish", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformPublishRequest
|
||||
var response api.PerformPublishResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
r.PerformPublish(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformPublishPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformPublish", r.PerformPublish),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformAdminEvacuateRoomPath,
|
||||
httputil.MakeInternalAPI("performAdminEvacuateRoom", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformAdminEvacuateRoomRequest
|
||||
var response api.PerformAdminEvacuateRoomResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
r.PerformAdminEvacuateRoom(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformAdminEvacuateRoomPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformAdminEvacuateRoom", r.PerformAdminEvacuateRoom),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverPerformAdminEvacuateUserPath,
|
||||
httputil.MakeInternalAPI("performAdminEvacuateUser", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformAdminEvacuateUserRequest
|
||||
var response api.PerformAdminEvacuateUserResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
r.PerformAdminEvacuateUser(req.Context(), &request, &response)
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformAdminEvacuateUserPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformAdminEvacuateUser", r.PerformAdminEvacuateUser),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryPublishedRoomsPath,
|
||||
httputil.MakeInternalAPI("queryPublishedRooms", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryPublishedRoomsRequest
|
||||
var response api.QueryPublishedRoomsResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryPublishedRooms(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryPublishedRooms", r.QueryPublishedRooms),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryLatestEventsAndStatePath,
|
||||
httputil.MakeInternalAPI("queryLatestEventsAndState", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryLatestEventsAndStateRequest
|
||||
var response api.QueryLatestEventsAndStateResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryLatestEventsAndState(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryLatestEventsAndState", r.QueryLatestEventsAndState),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryStateAfterEventsPath,
|
||||
httputil.MakeInternalAPI("queryStateAfterEvents", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryStateAfterEventsRequest
|
||||
var response api.QueryStateAfterEventsResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryStateAfterEvents(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryStateAfterEvents", r.QueryStateAfterEvents),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryEventsByIDPath,
|
||||
httputil.MakeInternalAPI("queryEventsByID", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryEventsByIDRequest
|
||||
var response api.QueryEventsByIDResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryEventsByID(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryEventsByID", r.QueryEventsByID),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryMembershipForUserPath,
|
||||
httputil.MakeInternalAPI("QueryMembershipForUser", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryMembershipForUserRequest
|
||||
var response api.QueryMembershipForUserResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryMembershipForUser(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryMembershipForUser", r.QueryMembershipForUser),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryMembershipsForRoomPath,
|
||||
httputil.MakeInternalAPI("queryMembershipsForRoom", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryMembershipsForRoomRequest
|
||||
var response api.QueryMembershipsForRoomResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryMembershipsForRoom(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryMembershipsForRoom", r.QueryMembershipsForRoom),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryServerJoinedToRoomPath,
|
||||
httputil.MakeInternalAPI("queryServerJoinedToRoom", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryServerJoinedToRoomRequest
|
||||
var response api.QueryServerJoinedToRoomResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryServerJoinedToRoom(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryServerJoinedToRoom", r.QueryServerJoinedToRoom),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryServerAllowedToSeeEventPath,
|
||||
httputil.MakeInternalAPI("queryServerAllowedToSeeEvent", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryServerAllowedToSeeEventRequest
|
||||
var response api.QueryServerAllowedToSeeEventResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryServerAllowedToSeeEvent(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryServerAllowedToSeeEvent", r.QueryServerAllowedToSeeEvent),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryMissingEventsPath,
|
||||
httputil.MakeInternalAPI("queryMissingEvents", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryMissingEventsRequest
|
||||
var response api.QueryMissingEventsResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryMissingEvents(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryMissingEvents", r.QueryMissingEvents),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryStateAndAuthChainPath,
|
||||
httputil.MakeInternalAPI("queryStateAndAuthChain", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryStateAndAuthChainRequest
|
||||
var response api.QueryStateAndAuthChainResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryStateAndAuthChain(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryStateAndAuthChain", r.QueryStateAndAuthChain),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformBackfillPath,
|
||||
httputil.MakeInternalAPI("PerformBackfill", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformBackfillRequest
|
||||
var response api.PerformBackfillResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.PerformBackfill(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformBackfill", r.PerformBackfill),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverPerformForgetPath,
|
||||
httputil.MakeInternalAPI("PerformForget", func(req *http.Request) util.JSONResponse {
|
||||
var request api.PerformForgetRequest
|
||||
var response api.PerformForgetResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.PerformForget(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverPerformForget", r.PerformForget),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryRoomVersionCapabilitiesPath,
|
||||
httputil.MakeInternalAPI("QueryRoomVersionCapabilities", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryRoomVersionCapabilitiesRequest
|
||||
var response api.QueryRoomVersionCapabilitiesResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryRoomVersionCapabilities(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryRoomVersionCapabilities", r.QueryRoomVersionCapabilities),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryRoomVersionForRoomPath,
|
||||
httputil.MakeInternalAPI("QueryRoomVersionForRoom", func(req *http.Request) util.JSONResponse {
|
||||
var request api.QueryRoomVersionForRoomRequest
|
||||
var response api.QueryRoomVersionForRoomResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.QueryRoomVersionForRoom(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryRoomVersionForRoom", r.QueryRoomVersionForRoom),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverSetRoomAliasPath,
|
||||
httputil.MakeInternalAPI("setRoomAlias", func(req *http.Request) util.JSONResponse {
|
||||
var request api.SetRoomAliasRequest
|
||||
var response api.SetRoomAliasResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.SetRoomAlias(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverSetRoomAlias", r.SetRoomAlias),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverGetRoomIDForAliasPath,
|
||||
httputil.MakeInternalAPI("GetRoomIDForAlias", func(req *http.Request) util.JSONResponse {
|
||||
var request api.GetRoomIDForAliasRequest
|
||||
var response api.GetRoomIDForAliasResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.GetRoomIDForAlias(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverGetRoomIDForAlias", r.GetRoomIDForAlias),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverGetAliasesForRoomIDPath,
|
||||
httputil.MakeInternalAPI("getAliasesForRoomID", func(req *http.Request) util.JSONResponse {
|
||||
var request api.GetAliasesForRoomIDRequest
|
||||
var response api.GetAliasesForRoomIDResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.GetAliasesForRoomID(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverGetAliasesForRoomID", r.GetAliasesForRoomID),
|
||||
)
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverRemoveRoomAliasPath,
|
||||
httputil.MakeInternalAPI("removeRoomAlias", func(req *http.Request) util.JSONResponse {
|
||||
var request api.RemoveRoomAliasRequest
|
||||
var response api.RemoveRoomAliasResponse
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := r.RemoveRoomAlias(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
httputil.MakeInternalRPCAPI("RoomserverRemoveRoomAlias", r.RemoveRoomAlias),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverQueryCurrentStatePath,
|
||||
httputil.MakeInternalAPI("queryCurrentState", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryCurrentStateRequest{}
|
||||
response := api.QueryCurrentStateResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.QueryCurrentState(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryCurrentStatePath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryCurrentState", r.QueryCurrentState),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverQueryRoomsForUserPath,
|
||||
httputil.MakeInternalAPI("queryRoomsForUser", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryRoomsForUserRequest{}
|
||||
response := api.QueryRoomsForUserResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.QueryRoomsForUser(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryRoomsForUserPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryRoomsForUser", r.QueryRoomsForUser),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverQueryBulkStateContentPath,
|
||||
httputil.MakeInternalAPI("queryBulkStateContent", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryBulkStateContentRequest{}
|
||||
response := api.QueryBulkStateContentResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.QueryBulkStateContent(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryBulkStateContentPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryBulkStateContent", r.QueryBulkStateContent),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverQuerySharedUsersPath,
|
||||
httputil.MakeInternalAPI("querySharedUsers", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QuerySharedUsersRequest{}
|
||||
response := api.QuerySharedUsersResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.QuerySharedUsers(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQuerySharedUsersPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverQuerySharedUsers", r.QuerySharedUsers),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverQueryKnownUsersPath,
|
||||
httputil.MakeInternalAPI("queryKnownUsers", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryKnownUsersRequest{}
|
||||
response := api.QueryKnownUsersResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.QueryKnownUsers(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryKnownUsersPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryKnownUsers", r.QueryKnownUsers),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverQueryServerBannedFromRoomPath,
|
||||
httputil.MakeInternalAPI("queryServerBannedFromRoom", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryServerBannedFromRoomRequest{}
|
||||
response := api.QueryServerBannedFromRoomResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.QueryServerBannedFromRoom(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryServerBannedFromRoomPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryServerBannedFromRoom", r.QueryServerBannedFromRoom),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverQueryAuthChainPath,
|
||||
httputil.MakeInternalAPI("queryAuthChain", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryAuthChainRequest{}
|
||||
response := api.QueryAuthChainResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.QueryAuthChain(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryAuthChainPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryAuthChain", r.QueryAuthChain),
|
||||
)
|
||||
internalAPIMux.Handle(RoomserverQueryRestrictedJoinAllowed,
|
||||
httputil.MakeInternalAPI("queryRestrictedJoinAllowed", func(req *http.Request) util.JSONResponse {
|
||||
request := api.QueryRestrictedJoinAllowedRequest{}
|
||||
response := api.QueryRestrictedJoinAllowedResponse{}
|
||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err := r.QueryRestrictedJoinAllowed(req.Context(), &request, &response); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||
}),
|
||||
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryRestrictedJoinAllowed,
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryRestrictedJoinAllowed", r.QueryRestrictedJoinAllowed),
|
||||
)
|
||||
internalAPIMux.Handle(
|
||||
RoomserverQueryMembershipAtEventPath,
|
||||
httputil.MakeInternalRPCAPI("RoomserverQueryMembershipAtEventPath", r.QueryMembershipAtEvent),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,12 +23,11 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
type StateResolutionStorage interface {
|
||||
|
|
@ -124,6 +123,61 @@ func (v *StateResolution) LoadStateAtEvent(
|
|||
return stateEntries, nil
|
||||
}
|
||||
|
||||
func (v *StateResolution) LoadMembershipAtEvent(
|
||||
ctx context.Context, eventIDs []string, stateKeyNID types.EventStateKeyNID,
|
||||
) (map[string][]types.StateEntry, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "StateResolution.LoadMembershipAtEvent")
|
||||
defer span.Finish()
|
||||
|
||||
// De-dupe snapshotNIDs
|
||||
snapshotNIDMap := make(map[types.StateSnapshotNID][]string) // map from snapshot NID to eventIDs
|
||||
for i := range eventIDs {
|
||||
eventID := eventIDs[i]
|
||||
snapshotNID, err := v.db.SnapshotNIDFromEventID(ctx, eventID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("LoadStateAtEvent.SnapshotNIDFromEventID failed for event %s : %w", eventID, err)
|
||||
}
|
||||
if snapshotNID == 0 {
|
||||
return nil, fmt.Errorf("LoadStateAtEvent.SnapshotNIDFromEventID(%s) returned 0 NID, was this event stored?", eventID)
|
||||
}
|
||||
snapshotNIDMap[snapshotNID] = append(snapshotNIDMap[snapshotNID], eventID)
|
||||
}
|
||||
|
||||
snapshotNIDs := make([]types.StateSnapshotNID, 0, len(snapshotNIDMap))
|
||||
for nid := range snapshotNIDMap {
|
||||
snapshotNIDs = append(snapshotNIDs, nid)
|
||||
}
|
||||
|
||||
stateBlockNIDLists, err := v.db.StateBlockNIDs(ctx, snapshotNIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make(map[string][]types.StateEntry)
|
||||
for _, stateBlockNIDList := range stateBlockNIDLists {
|
||||
// Query the membership event for the user at the given stateblocks
|
||||
stateEntryLists, err := v.db.StateEntriesForTuples(ctx, stateBlockNIDList.StateBlockNIDs, []types.StateKeyTuple{
|
||||
{
|
||||
EventTypeNID: types.MRoomMemberNID,
|
||||
EventStateKeyNID: stateKeyNID,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
evIDs := snapshotNIDMap[stateBlockNIDList.StateSnapshotNID]
|
||||
|
||||
for _, evID := range evIDs {
|
||||
for _, x := range stateEntryLists {
|
||||
result[evID] = append(result[evID], x.StateEntries...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// LoadStateAtEvent loads the full state of a room before a particular event.
|
||||
func (v *StateResolution) LoadStateAtEventForHistoryVisibility(
|
||||
ctx context.Context, eventID string,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue