mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-12 00:23:10 -06:00
Merge branch 'main' into patch-1
This commit is contained in:
commit
a492c98c54
6
.github/workflows/dendrite.yml
vendored
6
.github/workflows/dendrite.yml
vendored
|
|
@ -67,6 +67,8 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install libolm
|
||||
run: sudo apt-get install libolm-dev libolm3
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
|
|
@ -101,6 +103,8 @@ jobs:
|
|||
--health-retries 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install libolm
|
||||
run: sudo apt-get install libolm-dev libolm3
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
|
|
@ -232,6 +236,8 @@ jobs:
|
|||
--health-retries 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install libolm
|
||||
run: sudo apt-get install libolm-dev libolm3
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
"github.com/nats-io/nats.go"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||
"github.com/matrix-org/dendrite/setup/process"
|
||||
|
|
@ -104,7 +105,7 @@ func (s *OutputRoomEventConsumer) onMessage(
|
|||
ctx context.Context, state *appserviceState, msgs []*nats.Msg,
|
||||
) bool {
|
||||
log.WithField("appservice", state.ID).Tracef("Appservice worker received %d message(s) from roomserver", len(msgs))
|
||||
events := make([]*gomatrixserverlib.HeaderedEvent, 0, len(msgs))
|
||||
events := make([]*types.HeaderedEvent, 0, len(msgs))
|
||||
for _, msg := range msgs {
|
||||
// Only handle events we care about
|
||||
receivedType := api.OutputType(msg.Header.Get(jetstream.RoomEventType))
|
||||
|
|
@ -174,13 +175,13 @@ func (s *OutputRoomEventConsumer) onMessage(
|
|||
// endpoint. It will block for the backoff period if necessary.
|
||||
func (s *OutputRoomEventConsumer) sendEvents(
|
||||
ctx context.Context, state *appserviceState,
|
||||
events []*gomatrixserverlib.HeaderedEvent,
|
||||
events []*types.HeaderedEvent,
|
||||
txnID string,
|
||||
) error {
|
||||
// Create the transaction body.
|
||||
transaction, err := json.Marshal(
|
||||
ApplicationServiceTransaction{
|
||||
Events: synctypes.HeaderedToClientEvents(events, synctypes.FormatAll),
|
||||
Events: synctypes.ToClientEvents(gomatrixserverlib.ToPDUs(events), synctypes.FormatAll),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -231,7 +232,7 @@ func (s *appserviceState) backoffAndPause(err error) error {
|
|||
// event falls within one of a given application service's namespaces.
|
||||
//
|
||||
// TODO: This should be cached, see https://github.com/matrix-org/dendrite/issues/1682
|
||||
func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(ctx context.Context, event *gomatrixserverlib.HeaderedEvent, appservice *config.ApplicationService) bool {
|
||||
func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(ctx context.Context, event *types.HeaderedEvent, appservice *config.ApplicationService) bool {
|
||||
switch {
|
||||
case appservice.URL == "":
|
||||
return false
|
||||
|
|
@ -269,7 +270,7 @@ func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(ctx context.Cont
|
|||
|
||||
// appserviceJoinedAtEvent returns a boolean depending on whether a given
|
||||
// appservice has membership at the time a given event was created.
|
||||
func (s *OutputRoomEventConsumer) appserviceJoinedAtEvent(ctx context.Context, event *gomatrixserverlib.HeaderedEvent, appservice *config.ApplicationService) bool {
|
||||
func (s *OutputRoomEventConsumer) appserviceJoinedAtEvent(ctx context.Context, event *types.HeaderedEvent, appservice *config.ApplicationService) bool {
|
||||
// TODO: This is only checking the current room state, not the state at
|
||||
// the event in question. Pretty sure this is what Synapse does too, but
|
||||
// until we have a lighter way of checking the state before the event that
|
||||
|
|
|
|||
|
|
@ -142,8 +142,8 @@ func TestPurgeRoom(t *testing.T) {
|
|||
|
||||
// this starts the JetStream consumers
|
||||
syncapi.AddPublicRoutes(processCtx, routers, cfg, cm, &natsInstance, userAPI, rsAPI, caches, caching.DisableMetrics)
|
||||
federationapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, nil, rsAPI, caches, nil, true)
|
||||
rsAPI.SetFederationAPI(nil, nil)
|
||||
fsAPI := federationapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, nil, rsAPI, caches, nil, true)
|
||||
rsAPI.SetFederationAPI(fsAPI, nil)
|
||||
|
||||
// Create the room
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, room.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
|
|
|
|||
|
|
@ -13,19 +13,13 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/internal/pushrules"
|
||||
"github.com/matrix-org/gomatrix"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/matrix-org/dendrite/appservice"
|
||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||
"github.com/matrix-org/dendrite/clientapi/routing"
|
||||
"github.com/matrix-org/dendrite/clientapi/threepid"
|
||||
"github.com/matrix-org/dendrite/internal/caching"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/dendrite/internal/pushrules"
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/dendrite/roomserver"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
|
|
@ -37,6 +31,15 @@ import (
|
|||
"github.com/matrix-org/dendrite/test/testrig"
|
||||
"github.com/matrix-org/dendrite/userapi"
|
||||
uapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrix"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tidwall/gjson"
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/crypto"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
type userDevice struct {
|
||||
|
|
@ -1630,3 +1633,502 @@ func TestPushRules(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Tests the `/keys` endpoints.
|
||||
// Note that this only tests the happy path.
|
||||
func TestKeys(t *testing.T) {
|
||||
alice := test.NewUser(t)
|
||||
|
||||
ctx := context.Background()
|
||||
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
|
||||
cfg, processCtx, close := testrig.CreateConfig(t, dbType)
|
||||
cfg.ClientAPI.RateLimiting.Enabled = false
|
||||
caches := caching.NewRistrettoCache(128*1024*1024, time.Hour, caching.DisableMetrics)
|
||||
natsInstance := jetstream.NATSInstance{}
|
||||
defer close()
|
||||
|
||||
routers := httputil.NewRouters()
|
||||
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
|
||||
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, &natsInstance, caches, caching.DisableMetrics)
|
||||
userAPI := userapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, rsAPI, nil)
|
||||
|
||||
// We mostly need the rsAPI for this test, so nil for other APIs/caches etc.
|
||||
AddPublicRoutes(processCtx, routers, cfg, &natsInstance, nil, rsAPI, nil, nil, nil, userAPI, nil, nil, caching.DisableMetrics)
|
||||
|
||||
accessTokens := map[*test.User]userDevice{
|
||||
alice: {},
|
||||
}
|
||||
createAccessTokens(t, accessTokens, userAPI, processCtx.Context(), routers)
|
||||
|
||||
// Start a TLSServer with our client mux
|
||||
srv := httptest.NewTLSServer(routers.Client)
|
||||
defer srv.Close()
|
||||
|
||||
cl, err := mautrix.NewClient(srv.URL, id.UserID(alice.ID), accessTokens[alice].accessToken)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Set the client so the self-signed certificate is trusted
|
||||
cl.Client = srv.Client()
|
||||
cl.DeviceID = id.DeviceID(accessTokens[alice].deviceID)
|
||||
|
||||
cs := crypto.NewMemoryStore(nil)
|
||||
oc := crypto.NewOlmMachine(cl, nil, cs, dummyStore{})
|
||||
if err = oc.Load(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// tests `/keys/upload`
|
||||
if err = oc.ShareKeys(ctx, 0); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// tests `/keys/device_signing/upload`
|
||||
_, err = oc.GenerateAndUploadCrossSigningKeys(accessTokens[alice].password, "passphrase")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// tests `/keys/query`
|
||||
dev, err := oc.GetOrFetchDevice(ctx, id.UserID(alice.ID), id.DeviceID(accessTokens[alice].deviceID))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Validate that the keys returned from the server are what the client has stored
|
||||
oi := oc.OwnIdentity()
|
||||
if oi.SigningKey != dev.SigningKey {
|
||||
t.Fatalf("expected signing key '%s', got '%s'", oi.SigningKey, dev.SigningKey)
|
||||
}
|
||||
if oi.IdentityKey != dev.IdentityKey {
|
||||
t.Fatalf("expected identity '%s', got '%s'", oi.IdentityKey, dev.IdentityKey)
|
||||
}
|
||||
|
||||
// tests `/keys/signatures/upload`
|
||||
if err = oc.SignOwnMasterKey(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// tests `/keys/claim`
|
||||
otks := make(map[string]map[string]string)
|
||||
otks[alice.ID] = map[string]string{
|
||||
accessTokens[alice].deviceID: string(id.KeyAlgorithmSignedCurve25519),
|
||||
}
|
||||
|
||||
data, err := json.Marshal(claimKeysRequest{OneTimeKeys: otks})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req, err := http.NewRequest(http.MethodPost, srv.URL+"/_matrix/client/v3/keys/claim", bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req.Header.Set("Authorization", "Bearer "+accessTokens[alice].accessToken)
|
||||
resp, err := srv.Client().Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !gjson.GetBytes(respBody, "one_time_keys."+alice.ID+"."+string(dev.DeviceID)).Exists() {
|
||||
t.Fatalf("expected one time keys for alice, but didn't find any: %s", string(respBody))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type claimKeysRequest struct {
|
||||
// The keys to be claimed. A map from user ID, to a map from device ID to algorithm name.
|
||||
OneTimeKeys map[string]map[string]string `json:"one_time_keys"`
|
||||
}
|
||||
|
||||
type dummyStore struct{}
|
||||
|
||||
func (d dummyStore) IsEncrypted(roomID id.RoomID) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (d dummyStore) GetEncryptionEvent(roomID id.RoomID) *event.EncryptionEventContent {
|
||||
return &event.EncryptionEventContent{}
|
||||
}
|
||||
|
||||
func (d dummyStore) FindSharedRooms(userID id.UserID) []id.RoomID {
|
||||
return []id.RoomID{}
|
||||
}
|
||||
|
||||
func TestKeyBackup(t *testing.T) {
|
||||
alice := test.NewUser(t)
|
||||
|
||||
handleResponseCode := func(t *testing.T, rec *httptest.ResponseRecorder, expectedCode int) {
|
||||
t.Helper()
|
||||
if rec.Code != expectedCode {
|
||||
t.Fatalf("expected HTTP %d, but got %d: %s", expectedCode, rec.Code, rec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
request func(t *testing.T) *http.Request
|
||||
validate func(t *testing.T, rec *httptest.ResponseRecorder)
|
||||
}{
|
||||
{
|
||||
name: "can not create backup with invalid JSON",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := strings.NewReader(`{"algorithm":"m.megolm_backup.v1"`) // missing closing braces
|
||||
return httptest.NewRequest(http.MethodPost, "/_matrix/client/v3/room_keys/version", reqBody)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusBadRequest)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can not create backup with missing auth_data", // as this would result in MarshalJSON errors when querying again
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := strings.NewReader(`{"algorithm":"m.megolm_backup.v1"}`)
|
||||
return httptest.NewRequest(http.MethodPost, "/_matrix/client/v3/room_keys/version", reqBody)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusBadRequest)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can create backup",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := strings.NewReader(`{"algorithm":"m.megolm_backup.v1","auth_data":{"data":"random"}}`)
|
||||
return httptest.NewRequest(http.MethodPost, "/_matrix/client/v3/room_keys/version", reqBody)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
wantVersion := "1"
|
||||
if gotVersion := gjson.GetBytes(rec.Body.Bytes(), "version").Str; gotVersion != wantVersion {
|
||||
t.Fatalf("expected version '%s', got '%s'", wantVersion, gotVersion)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can not query backup for invalid version",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
return httptest.NewRequest(http.MethodGet, "/_matrix/client/v3/room_keys/version/1337", nil)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusNotFound)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can not query backup for invalid version string",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
return httptest.NewRequest(http.MethodGet, "/_matrix/client/v3/room_keys/version/notanumber", nil)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusNotFound)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can query backup",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
return httptest.NewRequest(http.MethodGet, "/_matrix/client/v3/room_keys/version", nil)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
wantVersion := "1"
|
||||
if gotVersion := gjson.GetBytes(rec.Body.Bytes(), "version").Str; gotVersion != wantVersion {
|
||||
t.Fatalf("expected version '%s', got '%s'", wantVersion, gotVersion)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can query backup without returning rooms",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
req := test.NewRequest(t, http.MethodGet, "/_matrix/client/v3/room_keys/keys", test.WithQueryParams(map[string]string{
|
||||
"version": "1",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
if gotRooms := gjson.GetBytes(rec.Body.Bytes(), "rooms").Map(); len(gotRooms) > 0 {
|
||||
t.Fatalf("expected no rooms in version, but got %#v", gotRooms)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can query backup for invalid room",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
req := test.NewRequest(t, http.MethodGet, "/_matrix/client/v3/room_keys/keys/!abc:test", test.WithQueryParams(map[string]string{
|
||||
"version": "1",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
if gotSessions := gjson.GetBytes(rec.Body.Bytes(), "sessions").Map(); len(gotSessions) > 0 {
|
||||
t.Fatalf("expected no sessions in version, but got %#v", gotSessions)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can not query backup for invalid session",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
req := test.NewRequest(t, http.MethodGet, "/_matrix/client/v3/room_keys/keys/!abc:test/doesnotexist", test.WithQueryParams(map[string]string{
|
||||
"version": "1",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusNotFound)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can not update backup with missing version",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
return test.NewRequest(t, http.MethodPut, "/_matrix/client/v3/room_keys/keys")
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusBadRequest)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can not update backup with invalid data",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := test.WithJSONBody(t, "")
|
||||
req := test.NewRequest(t, http.MethodPut, "/_matrix/client/v3/room_keys/keys", reqBody, test.WithQueryParams(map[string]string{
|
||||
"version": "0",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusBadRequest)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can not update backup with wrong version",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := test.WithJSONBody(t, map[string]interface{}{
|
||||
"rooms": map[string]interface{}{
|
||||
"!testroom:test": map[string]interface{}{
|
||||
"sessions": map[string]uapi.KeyBackupSession{},
|
||||
},
|
||||
},
|
||||
})
|
||||
req := test.NewRequest(t, http.MethodPut, "/_matrix/client/v3/room_keys/keys", reqBody, test.WithQueryParams(map[string]string{
|
||||
"version": "5",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusForbidden)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can update backup with correct version",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := test.WithJSONBody(t, map[string]interface{}{
|
||||
"rooms": map[string]interface{}{
|
||||
"!testroom:test": map[string]interface{}{
|
||||
"sessions": map[string]uapi.KeyBackupSession{
|
||||
"dummySession": {
|
||||
FirstMessageIndex: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
req := test.NewRequest(t, http.MethodPut, "/_matrix/client/v3/room_keys/keys", reqBody, test.WithQueryParams(map[string]string{
|
||||
"version": "1",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can update backup with correct version for specific room",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := test.WithJSONBody(t, map[string]interface{}{
|
||||
"sessions": map[string]uapi.KeyBackupSession{
|
||||
"dummySession": {
|
||||
FirstMessageIndex: 1,
|
||||
IsVerified: true,
|
||||
SessionData: json.RawMessage("{}"),
|
||||
},
|
||||
},
|
||||
})
|
||||
req := test.NewRequest(t, http.MethodPut, "/_matrix/client/v3/room_keys/keys/!testroom:test", reqBody, test.WithQueryParams(map[string]string{
|
||||
"version": "1",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
t.Logf("%#v", rec.Body.String())
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can update backup with correct version for specific room and session",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := test.WithJSONBody(t, uapi.KeyBackupSession{
|
||||
FirstMessageIndex: 1,
|
||||
SessionData: json.RawMessage("{}"),
|
||||
IsVerified: true,
|
||||
ForwardedCount: 0,
|
||||
})
|
||||
req := test.NewRequest(t, http.MethodPut, "/_matrix/client/v3/room_keys/keys/!testroom:test/dummySession", reqBody, test.WithQueryParams(map[string]string{
|
||||
"version": "1",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can update backup by version",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := test.WithJSONBody(t, uapi.KeyBackupSession{
|
||||
FirstMessageIndex: 1,
|
||||
SessionData: json.RawMessage("{}"),
|
||||
IsVerified: true,
|
||||
ForwardedCount: 0,
|
||||
})
|
||||
req := test.NewRequest(t, http.MethodPut, "/_matrix/client/v3/room_keys/version/1", reqBody, test.WithQueryParams(map[string]string{"version": "1"}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
t.Logf("%#v", rec.Body.String())
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can not update backup by version for invalid version",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
reqBody := test.WithJSONBody(t, uapi.KeyBackupSession{
|
||||
FirstMessageIndex: 1,
|
||||
SessionData: json.RawMessage("{}"),
|
||||
IsVerified: true,
|
||||
ForwardedCount: 0,
|
||||
})
|
||||
req := test.NewRequest(t, http.MethodPut, "/_matrix/client/v3/room_keys/version/2", reqBody, test.WithQueryParams(map[string]string{"version": "1"}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can query backup sessions",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
req := test.NewRequest(t, http.MethodGet, "/_matrix/client/v3/room_keys/keys", test.WithQueryParams(map[string]string{
|
||||
"version": "1",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
if gotRooms := gjson.GetBytes(rec.Body.Bytes(), "rooms").Map(); len(gotRooms) != 1 {
|
||||
t.Fatalf("expected one room in response, but got %#v", rec.Body.String())
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can query backup sessions by room",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
req := test.NewRequest(t, http.MethodGet, "/_matrix/client/v3/room_keys/keys/!testroom:test", test.WithQueryParams(map[string]string{
|
||||
"version": "1",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
if gotRooms := gjson.GetBytes(rec.Body.Bytes(), "sessions").Map(); len(gotRooms) != 1 {
|
||||
t.Fatalf("expected one session in response, but got %#v", rec.Body.String())
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can query backup sessions by room and sessionID",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
req := test.NewRequest(t, http.MethodGet, "/_matrix/client/v3/room_keys/keys/!testroom:test/dummySession", test.WithQueryParams(map[string]string{
|
||||
"version": "1",
|
||||
}))
|
||||
return req
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
if !gjson.GetBytes(rec.Body.Bytes(), "is_verified").Bool() {
|
||||
t.Fatalf("expected session to be verified, but wasn't: %#v", rec.Body.String())
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can not delete invalid version backup",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
return httptest.NewRequest(http.MethodDelete, "/_matrix/client/v3/room_keys/version/2", nil)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusNotFound)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can delete version backup",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
return httptest.NewRequest(http.MethodDelete, "/_matrix/client/v3/room_keys/version/1", nil)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "deleting the same backup version twice doesn't error",
|
||||
request: func(t *testing.T) *http.Request {
|
||||
return httptest.NewRequest(http.MethodDelete, "/_matrix/client/v3/room_keys/version/1", nil)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusOK)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "deleting an empty version doesn't work", // make sure we can't delete an empty backup version. Handled at the router level
|
||||
request: func(t *testing.T) *http.Request {
|
||||
return httptest.NewRequest(http.MethodDelete, "/_matrix/client/v3/room_keys/version/", nil)
|
||||
},
|
||||
validate: func(t *testing.T, rec *httptest.ResponseRecorder) {
|
||||
handleResponseCode(t, rec, http.StatusNotFound)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
|
||||
cfg, processCtx, close := testrig.CreateConfig(t, dbType)
|
||||
cfg.ClientAPI.RateLimiting.Enabled = false
|
||||
caches := caching.NewRistrettoCache(128*1024*1024, time.Hour, caching.DisableMetrics)
|
||||
natsInstance := jetstream.NATSInstance{}
|
||||
defer close()
|
||||
|
||||
routers := httputil.NewRouters()
|
||||
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
|
||||
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, &natsInstance, caches, caching.DisableMetrics)
|
||||
userAPI := userapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, rsAPI, nil)
|
||||
|
||||
// We mostly need the rsAPI for this test, so nil for other APIs/caches etc.
|
||||
AddPublicRoutes(processCtx, routers, cfg, &natsInstance, nil, rsAPI, nil, nil, nil, userAPI, nil, nil, caching.DisableMetrics)
|
||||
|
||||
accessTokens := map[*test.User]userDevice{
|
||||
alice: {},
|
||||
}
|
||||
createAccessTokens(t, accessTokens, userAPI, processCtx.Context(), routers)
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
rec := httptest.NewRecorder()
|
||||
req := tc.request(t)
|
||||
req.Header.Set("Authorization", "Bearer "+accessTokens[alice].accessToken)
|
||||
routers.Client.ServeHTTP(rec, req)
|
||||
tc.validate(t, rec)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,23 @@ func LeaveServerNoticeError() *MatrixError {
|
|||
}
|
||||
}
|
||||
|
||||
// ErrRoomKeysVersion is an error returned by `PUT /room_keys/keys`
|
||||
type ErrRoomKeysVersion struct {
|
||||
MatrixError
|
||||
CurrentVersion string `json:"current_version"`
|
||||
}
|
||||
|
||||
// WrongBackupVersionError is an error returned by `PUT /room_keys/keys`
|
||||
func WrongBackupVersionError(currentVersion string) *ErrRoomKeysVersion {
|
||||
return &ErrRoomKeysVersion{
|
||||
MatrixError: MatrixError{
|
||||
ErrCode: "M_WRONG_ROOM_KEYS_VERSION",
|
||||
Err: "Wrong backup version.",
|
||||
},
|
||||
CurrentVersion: currentVersion,
|
||||
}
|
||||
}
|
||||
|
||||
type IncompatibleRoomVersionError struct {
|
||||
RoomVersion string `json:"room_version"`
|
||||
Error string `json:"error"`
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ package routing
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/matrix-org/dendrite/internal"
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/matrix-org/util"
|
||||
|
|
@ -28,88 +30,60 @@ func AdminEvacuateRoom(req *http.Request, rsAPI roomserverAPI.ClientRoomserverAP
|
|||
if err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
res := &roomserverAPI.PerformAdminEvacuateRoomResponse{}
|
||||
if err := rsAPI.PerformAdminEvacuateRoom(
|
||||
req.Context(),
|
||||
&roomserverAPI.PerformAdminEvacuateRoomRequest{
|
||||
RoomID: vars["roomID"],
|
||||
},
|
||||
res,
|
||||
); err != nil {
|
||||
|
||||
affected, err := rsAPI.PerformAdminEvacuateRoom(req.Context(), vars["roomID"])
|
||||
switch err {
|
||||
case nil:
|
||||
case eventutil.ErrRoomNoExists:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
JSON: jsonerror.NotFound(err.Error()),
|
||||
}
|
||||
default:
|
||||
logrus.WithError(err).WithField("roomID", vars["roomID"]).Error("Failed to evacuate room")
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := res.Error; err != nil {
|
||||
return err.JSONResponse()
|
||||
}
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: map[string]interface{}{
|
||||
"affected": res.Affected,
|
||||
"affected": affected,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func AdminEvacuateUser(req *http.Request, cfg *config.ClientAPI, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse {
|
||||
func AdminEvacuateUser(req *http.Request, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse {
|
||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||
if err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
userID := vars["userID"]
|
||||
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', userID)
|
||||
affected, err := rsAPI.PerformAdminEvacuateUser(req.Context(), vars["userID"])
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("userID", vars["userID"]).Error("Failed to evacuate user")
|
||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if !cfg.Matrix.IsLocalServerName(domain) {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.MissingArgument("User ID must belong to this server."),
|
||||
}
|
||||
}
|
||||
res := &roomserverAPI.PerformAdminEvacuateUserResponse{}
|
||||
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()
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: map[string]interface{}{
|
||||
"affected": res.Affected,
|
||||
"affected": affected,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func AdminPurgeRoom(req *http.Request, cfg *config.ClientAPI, device *api.Device, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse {
|
||||
func AdminPurgeRoom(req *http.Request, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse {
|
||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||
if err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
roomID := vars["roomID"]
|
||||
|
||||
res := &roomserverAPI.PerformAdminPurgeRoomResponse{}
|
||||
if err := rsAPI.PerformAdminPurgeRoom(
|
||||
context.Background(),
|
||||
&roomserverAPI.PerformAdminPurgeRoomRequest{
|
||||
RoomID: roomID,
|
||||
},
|
||||
res,
|
||||
); err != nil {
|
||||
if err = rsAPI.PerformAdminPurgeRoom(context.Background(), vars["roomID"]); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if err := res.Error; err != nil {
|
||||
return err.JSONResponse()
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: res,
|
||||
JSON: struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,7 +212,7 @@ func AdminMarkAsStale(req *http.Request, cfg *config.ClientAPI, keyAPI api.Clien
|
|||
}
|
||||
}
|
||||
|
||||
func AdminDownloadState(req *http.Request, cfg *config.ClientAPI, device *api.Device, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse {
|
||||
func AdminDownloadState(req *http.Request, device *api.Device, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse {
|
||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||
if err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
|
|
@ -257,23 +231,22 @@ func AdminDownloadState(req *http.Request, cfg *config.ClientAPI, device *api.De
|
|||
JSON: jsonerror.MissingArgument("Expecting remote server name."),
|
||||
}
|
||||
}
|
||||
res := &roomserverAPI.PerformAdminDownloadStateResponse{}
|
||||
if err := rsAPI.PerformAdminDownloadState(
|
||||
req.Context(),
|
||||
&roomserverAPI.PerformAdminDownloadStateRequest{
|
||||
UserID: device.UserID,
|
||||
RoomID: roomID,
|
||||
ServerName: spec.ServerName(serverName),
|
||||
},
|
||||
res,
|
||||
); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if err := res.Error; err != nil {
|
||||
return err.JSONResponse()
|
||||
if err = rsAPI.PerformAdminDownloadState(req.Context(), roomID, device.UserID, spec.ServerName(serverName)); err != nil {
|
||||
if errors.Is(err, eventutil.ErrRoomNoExists) {
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: jsonerror.NotFound(eventutil.ErrRoomNoExists.Error()),
|
||||
}
|
||||
}
|
||||
logrus.WithError(err).WithFields(logrus.Fields{
|
||||
"userID": device.UserID,
|
||||
"serverName": serverName,
|
||||
"roomID": roomID,
|
||||
}).Error("failed to download state")
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: map[string]interface{}{},
|
||||
JSON: struct{}{},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
|
||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
roomserverVersion "github.com/matrix-org/dendrite/roomserver/version"
|
||||
"github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
|
|
@ -48,7 +50,6 @@ type createRoomRequest struct {
|
|||
CreationContent json.RawMessage `json:"creation_content"`
|
||||
InitialState []fledglingEvent `json:"initial_state"`
|
||||
RoomAliasName string `json:"room_alias_name"`
|
||||
GuestCanJoin bool `json:"guest_can_join"`
|
||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
PowerLevelContentOverride json.RawMessage `json:"power_level_content_override"`
|
||||
IsDirect bool `json:"is_direct"`
|
||||
|
|
@ -253,16 +254,19 @@ func createRoom(
|
|||
}
|
||||
}
|
||||
|
||||
var guestsCanJoin bool
|
||||
switch r.Preset {
|
||||
case presetPrivateChat:
|
||||
joinRuleContent.JoinRule = spec.Invite
|
||||
historyVisibilityContent.HistoryVisibility = historyVisibilityShared
|
||||
guestsCanJoin = true
|
||||
case presetTrustedPrivateChat:
|
||||
joinRuleContent.JoinRule = spec.Invite
|
||||
historyVisibilityContent.HistoryVisibility = historyVisibilityShared
|
||||
for _, invitee := range r.Invite {
|
||||
powerLevelContent.Users[invitee] = 100
|
||||
}
|
||||
guestsCanJoin = true
|
||||
case presetPublicChat:
|
||||
joinRuleContent.JoinRule = spec.Public
|
||||
historyVisibilityContent.HistoryVisibility = historyVisibilityShared
|
||||
|
|
@ -317,7 +321,7 @@ func createRoom(
|
|||
}
|
||||
}
|
||||
|
||||
if r.GuestCanJoin {
|
||||
if guestsCanJoin {
|
||||
guestAccessEvent = &fledglingEvent{
|
||||
Type: spec.MRoomGuestAccess,
|
||||
Content: eventutil.GuestAccessContent{
|
||||
|
|
@ -429,7 +433,7 @@ func createRoom(
|
|||
// TODO: invite events
|
||||
// TODO: 3pid invite events
|
||||
|
||||
var builtEvents []*gomatrixserverlib.HeaderedEvent
|
||||
var builtEvents []*types.HeaderedEvent
|
||||
authEvents := gomatrixserverlib.NewAuthEvents(nil)
|
||||
for i, e := range eventsToMake {
|
||||
depth := i + 1 // depth starts at 1
|
||||
|
|
@ -462,7 +466,7 @@ func createRoom(
|
|||
}
|
||||
|
||||
// Add the event to the list of auth events
|
||||
builtEvents = append(builtEvents, ev.Headered(roomVersion))
|
||||
builtEvents = append(builtEvents, &types.HeaderedEvent{Event: ev})
|
||||
err = authEvents.AddEvent(ev)
|
||||
if err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("authEvents.AddEvent failed")
|
||||
|
|
@ -541,9 +545,10 @@ func createRoom(
|
|||
}
|
||||
|
||||
// Process the invites.
|
||||
var inviteEvent *types.HeaderedEvent
|
||||
for _, invitee := range r.Invite {
|
||||
// Build the invite event.
|
||||
inviteEvent, err := buildMembershipEvent(
|
||||
inviteEvent, err = buildMembershipEvent(
|
||||
ctx, invitee, "", profileAPI, device, spec.Invite,
|
||||
roomID, r.IsDirect, cfg, evTime, rsAPI, asAPI,
|
||||
)
|
||||
|
|
@ -556,38 +561,44 @@ func createRoom(
|
|||
fclient.NewInviteV2StrippedState(inviteEvent.Event),
|
||||
)
|
||||
// Send the invite event to the roomserver.
|
||||
var inviteRes roomserverAPI.PerformInviteResponse
|
||||
event := inviteEvent.Headered(roomVersion)
|
||||
if err := rsAPI.PerformInvite(ctx, &roomserverAPI.PerformInviteRequest{
|
||||
event := inviteEvent
|
||||
err = rsAPI.PerformInvite(ctx, &roomserverAPI.PerformInviteRequest{
|
||||
Event: event,
|
||||
InviteRoomState: inviteStrippedState,
|
||||
RoomVersion: event.RoomVersion,
|
||||
RoomVersion: event.Version(),
|
||||
SendAsServer: string(userDomain),
|
||||
}, &inviteRes); err != nil {
|
||||
})
|
||||
switch e := err.(type) {
|
||||
case roomserverAPI.ErrInvalidID:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.Unknown(e.Error()),
|
||||
}
|
||||
case roomserverAPI.ErrNotAllowed:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden(e.Error()),
|
||||
}
|
||||
case nil:
|
||||
default:
|
||||
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
|
||||
sentry.CaptureException(err)
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
}
|
||||
}
|
||||
if inviteRes.Error != nil {
|
||||
return inviteRes.Error.JSONResponse()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if r.Visibility == "public" {
|
||||
if r.Visibility == spec.Public {
|
||||
// expose this room in the published room list
|
||||
var pubRes roomserverAPI.PerformPublishResponse
|
||||
if err := rsAPI.PerformPublish(ctx, &roomserverAPI.PerformPublishRequest{
|
||||
if err = rsAPI.PerformPublish(ctx, &roomserverAPI.PerformPublishRequest{
|
||||
RoomID: roomID,
|
||||
Visibility: "public",
|
||||
}, &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")
|
||||
Visibility: spec.Public,
|
||||
}); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("failed to publish room")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -304,16 +304,12 @@ func SetVisibility(
|
|||
return *reqErr
|
||||
}
|
||||
|
||||
var publishRes roomserverAPI.PerformPublishResponse
|
||||
if err := rsAPI.PerformPublish(req.Context(), &roomserverAPI.PerformPublishRequest{
|
||||
if err = rsAPI.PerformPublish(req.Context(), &roomserverAPI.PerformPublishRequest{
|
||||
RoomID: roomID,
|
||||
Visibility: v.Visibility,
|
||||
}, &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()
|
||||
}); err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Error("failed to publish room")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
|
|
@ -342,18 +338,14 @@ func SetVisibilityAS(
|
|||
return *reqErr
|
||||
}
|
||||
}
|
||||
var publishRes roomserverAPI.PerformPublishResponse
|
||||
if err := rsAPI.PerformPublish(req.Context(), &roomserverAPI.PerformPublishRequest{
|
||||
RoomID: roomID,
|
||||
Visibility: v.Visibility,
|
||||
NetworkID: networkID,
|
||||
AppserviceID: dev.AppserviceID,
|
||||
}, &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()
|
||||
}); err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Error("failed to publish room")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
|
|
|
|||
|
|
@ -15,14 +15,18 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
|
||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrix"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
|
@ -41,7 +45,6 @@ func JoinRoomByIDOrAlias(
|
|||
IsGuest: device.AccountType == api.AccountTypeGuest,
|
||||
Content: map[string]interface{}{},
|
||||
}
|
||||
joinRes := roomserverAPI.PerformJoinResponse{}
|
||||
|
||||
// Check to see if any ?server_name= query parameters were
|
||||
// given in the request.
|
||||
|
|
@ -81,37 +84,66 @@ func JoinRoomByIDOrAlias(
|
|||
done := make(chan util.JSONResponse, 1)
|
||||
go func() {
|
||||
defer close(done)
|
||||
if err := rsAPI.PerformJoin(req.Context(), &joinReq, &joinRes); err != nil {
|
||||
done <- jsonerror.InternalAPIError(req.Context(), err)
|
||||
} else if joinRes.Error != nil {
|
||||
if joinRes.Error.Code == roomserverAPI.PerformErrorNotAllowed && device.AccountType == api.AccountTypeGuest {
|
||||
done <- util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.GuestAccessForbidden(joinRes.Error.Msg),
|
||||
}
|
||||
} else {
|
||||
done <- joinRes.Error.JSONResponse()
|
||||
}
|
||||
} else {
|
||||
done <- util.JSONResponse{
|
||||
roomID, _, err := rsAPI.PerformJoin(req.Context(), &joinReq)
|
||||
var response util.JSONResponse
|
||||
|
||||
switch e := err.(type) {
|
||||
case nil: // success case
|
||||
response = util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
// TODO: Put the response struct somewhere internal.
|
||||
JSON: struct {
|
||||
RoomID string `json:"room_id"`
|
||||
}{joinRes.RoomID},
|
||||
}{roomID},
|
||||
}
|
||||
case roomserverAPI.ErrInvalidID:
|
||||
response = util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.Unknown(e.Error()),
|
||||
}
|
||||
case roomserverAPI.ErrNotAllowed:
|
||||
jsonErr := jsonerror.Forbidden(e.Error())
|
||||
if device.AccountType == api.AccountTypeGuest {
|
||||
jsonErr = jsonerror.GuestAccessForbidden(e.Error())
|
||||
}
|
||||
response = util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonErr,
|
||||
}
|
||||
case *gomatrix.HTTPError: // this ensures we proxy responses over federation to the client
|
||||
response = util.JSONResponse{
|
||||
Code: e.Code,
|
||||
JSON: json.RawMessage(e.Message),
|
||||
}
|
||||
default:
|
||||
response = util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
}
|
||||
if errors.Is(err, eventutil.ErrRoomNoExists) {
|
||||
response = util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
JSON: jsonerror.NotFound(e.Error()),
|
||||
}
|
||||
}
|
||||
}
|
||||
done <- response
|
||||
}()
|
||||
|
||||
// Wait either for the join to finish, or for us to hit a reasonable
|
||||
// timeout, at which point we'll just return a 200 to placate clients.
|
||||
timer := time.NewTimer(time.Second * 20)
|
||||
select {
|
||||
case <-time.After(time.Second * 20):
|
||||
case <-timer.C:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusAccepted,
|
||||
JSON: jsonerror.Unknown("The room join will continue in the background."),
|
||||
}
|
||||
case result := <-done:
|
||||
// Stop and drain the timer
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ func TestJoinRoomByIDOrAlias(t *testing.T) {
|
|||
Preset: presetPublicChat,
|
||||
RoomAliasName: "alias",
|
||||
Invite: []string{bob.ID},
|
||||
GuestCanJoin: false,
|
||||
}, aliceDev, &cfg.ClientAPI, userAPI, rsAPI, asAPI, time.Now())
|
||||
crResp, ok := resp.JSON.(createRoomResponse)
|
||||
if !ok {
|
||||
|
|
@ -75,13 +74,12 @@ func TestJoinRoomByIDOrAlias(t *testing.T) {
|
|||
|
||||
// create a room with guest access enabled and invite Charlie
|
||||
resp = createRoom(ctx, createRoomRequest{
|
||||
Name: "testing",
|
||||
IsDirect: true,
|
||||
Topic: "testing",
|
||||
Visibility: "public",
|
||||
Preset: presetPublicChat,
|
||||
Invite: []string{charlie.ID},
|
||||
GuestCanJoin: true,
|
||||
Name: "testing",
|
||||
IsDirect: true,
|
||||
Topic: "testing",
|
||||
Visibility: "public",
|
||||
Preset: presetPublicChat,
|
||||
Invite: []string{charlie.ID},
|
||||
}, aliceDev, &cfg.ClientAPI, userAPI, rsAPI, asAPI, time.Now())
|
||||
crRespWithGuestAccess, ok := resp.JSON.(createRoomResponse)
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -61,28 +61,26 @@ func CreateKeyBackupVersion(req *http.Request, userAPI userapi.ClientUserAPI, de
|
|||
if resErr != nil {
|
||||
return *resErr
|
||||
}
|
||||
var performKeyBackupResp userapi.PerformKeyBackupResponse
|
||||
if err := userAPI.PerformKeyBackup(req.Context(), &userapi.PerformKeyBackupRequest{
|
||||
if len(kb.AuthData) == 0 {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.BadJSON("missing auth_data"),
|
||||
}
|
||||
}
|
||||
version, err := userAPI.PerformKeyBackup(req.Context(), &userapi.PerformKeyBackupRequest{
|
||||
UserID: device.UserID,
|
||||
Version: "",
|
||||
AuthData: kb.AuthData,
|
||||
Algorithm: kb.Algorithm,
|
||||
}, &performKeyBackupResp); err != nil {
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
if performKeyBackupResp.Error != "" {
|
||||
if performKeyBackupResp.BadInput {
|
||||
return util.JSONResponse{
|
||||
Code: 400,
|
||||
JSON: jsonerror.InvalidArgumentValue(performKeyBackupResp.Error),
|
||||
}
|
||||
}
|
||||
return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %s", performKeyBackupResp.Error))
|
||||
})
|
||||
if err != nil {
|
||||
return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %w", err))
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: keyBackupVersionCreateResponse{
|
||||
Version: performKeyBackupResp.Version,
|
||||
Version: version,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -90,15 +88,12 @@ func CreateKeyBackupVersion(req *http.Request, userAPI userapi.ClientUserAPI, de
|
|||
// KeyBackupVersion returns the key backup version specified. If `version` is empty, the latest `keyBackupVersionResponse` is returned.
|
||||
// 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
|
||||
if err := userAPI.QueryKeyBackup(req.Context(), &userapi.QueryKeyBackupRequest{
|
||||
queryResp, err := userAPI.QueryKeyBackup(req.Context(), &userapi.QueryKeyBackupRequest{
|
||||
UserID: device.UserID,
|
||||
Version: version,
|
||||
}, &queryResp); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if queryResp.Error != "" {
|
||||
return util.ErrorResponse(fmt.Errorf("QueryKeyBackup: %s", queryResp.Error))
|
||||
})
|
||||
if err != nil {
|
||||
return util.ErrorResponse(fmt.Errorf("QueryKeyBackup: %s", err))
|
||||
}
|
||||
if !queryResp.Exists {
|
||||
return util.JSONResponse{
|
||||
|
|
@ -126,31 +121,29 @@ func ModifyKeyBackupVersionAuthData(req *http.Request, userAPI userapi.ClientUse
|
|||
if resErr != nil {
|
||||
return *resErr
|
||||
}
|
||||
var performKeyBackupResp userapi.PerformKeyBackupResponse
|
||||
if err := userAPI.PerformKeyBackup(req.Context(), &userapi.PerformKeyBackupRequest{
|
||||
performKeyBackupResp, err := userAPI.UpdateBackupKeyAuthData(req.Context(), &userapi.PerformKeyBackupRequest{
|
||||
UserID: device.UserID,
|
||||
Version: version,
|
||||
AuthData: kb.AuthData,
|
||||
Algorithm: kb.Algorithm,
|
||||
}, &performKeyBackupResp); err != nil {
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
if performKeyBackupResp.Error != "" {
|
||||
if performKeyBackupResp.BadInput {
|
||||
return util.JSONResponse{
|
||||
Code: 400,
|
||||
JSON: jsonerror.InvalidArgumentValue(performKeyBackupResp.Error),
|
||||
}
|
||||
})
|
||||
switch e := err.(type) {
|
||||
case *jsonerror.ErrRoomKeysVersion:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: e,
|
||||
}
|
||||
return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %s", performKeyBackupResp.Error))
|
||||
case nil:
|
||||
default:
|
||||
return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %w", e))
|
||||
}
|
||||
|
||||
if !performKeyBackupResp.Exists {
|
||||
return util.JSONResponse{
|
||||
Code: 404,
|
||||
JSON: jsonerror.NotFound("backup version not found"),
|
||||
}
|
||||
}
|
||||
// Unclear what the 200 body should be
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: keyBackupVersionCreateResponse{
|
||||
|
|
@ -162,35 +155,19 @@ func ModifyKeyBackupVersionAuthData(req *http.Request, userAPI userapi.ClientUse
|
|||
// Delete a version of key backup. Version must not be empty. If the key backup was previously deleted, will return 200 OK.
|
||||
// Implements DELETE /_matrix/client/r0/room_keys/version/{version}
|
||||
func DeleteKeyBackupVersion(req *http.Request, userAPI userapi.ClientUserAPI, device *userapi.Device, version string) util.JSONResponse {
|
||||
var performKeyBackupResp userapi.PerformKeyBackupResponse
|
||||
if err := userAPI.PerformKeyBackup(req.Context(), &userapi.PerformKeyBackupRequest{
|
||||
UserID: device.UserID,
|
||||
Version: version,
|
||||
DeleteBackup: true,
|
||||
}, &performKeyBackupResp); err != nil {
|
||||
return jsonerror.InternalServerError()
|
||||
exists, err := userAPI.DeleteKeyBackup(req.Context(), device.UserID, version)
|
||||
if err != nil {
|
||||
return util.ErrorResponse(fmt.Errorf("DeleteKeyBackup: %s", err))
|
||||
}
|
||||
if performKeyBackupResp.Error != "" {
|
||||
if performKeyBackupResp.BadInput {
|
||||
return util.JSONResponse{
|
||||
Code: 400,
|
||||
JSON: jsonerror.InvalidArgumentValue(performKeyBackupResp.Error),
|
||||
}
|
||||
}
|
||||
return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %s", performKeyBackupResp.Error))
|
||||
}
|
||||
if !performKeyBackupResp.Exists {
|
||||
if !exists {
|
||||
return util.JSONResponse{
|
||||
Code: 404,
|
||||
JSON: jsonerror.NotFound("backup version not found"),
|
||||
}
|
||||
}
|
||||
// Unclear what the 200 body should be
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: keyBackupVersionCreateResponse{
|
||||
Version: performKeyBackupResp.Version,
|
||||
},
|
||||
JSON: struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,22 +175,21 @@ func DeleteKeyBackupVersion(req *http.Request, userAPI userapi.ClientUserAPI, de
|
|||
func UploadBackupKeys(
|
||||
req *http.Request, userAPI userapi.ClientUserAPI, device *userapi.Device, version string, keys *keyBackupSessionRequest,
|
||||
) util.JSONResponse {
|
||||
var performKeyBackupResp userapi.PerformKeyBackupResponse
|
||||
if err := userAPI.PerformKeyBackup(req.Context(), &userapi.PerformKeyBackupRequest{
|
||||
performKeyBackupResp, err := userAPI.UpdateBackupKeyAuthData(req.Context(), &userapi.PerformKeyBackupRequest{
|
||||
UserID: device.UserID,
|
||||
Version: version,
|
||||
Keys: *keys,
|
||||
}, &performKeyBackupResp); err != nil && performKeyBackupResp.Error == "" {
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
if performKeyBackupResp.Error != "" {
|
||||
if performKeyBackupResp.BadInput {
|
||||
return util.JSONResponse{
|
||||
Code: 400,
|
||||
JSON: jsonerror.InvalidArgumentValue(performKeyBackupResp.Error),
|
||||
}
|
||||
})
|
||||
|
||||
switch e := err.(type) {
|
||||
case *jsonerror.ErrRoomKeysVersion:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: e,
|
||||
}
|
||||
return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %s", performKeyBackupResp.Error))
|
||||
case nil:
|
||||
default:
|
||||
return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %w", e))
|
||||
}
|
||||
if !performKeyBackupResp.Exists {
|
||||
return util.JSONResponse{
|
||||
|
|
@ -234,18 +210,15 @@ func UploadBackupKeys(
|
|||
func GetBackupKeys(
|
||||
req *http.Request, userAPI userapi.ClientUserAPI, device *userapi.Device, version, roomID, sessionID string,
|
||||
) util.JSONResponse {
|
||||
var queryResp userapi.QueryKeyBackupResponse
|
||||
if err := userAPI.QueryKeyBackup(req.Context(), &userapi.QueryKeyBackupRequest{
|
||||
queryResp, err := userAPI.QueryKeyBackup(req.Context(), &userapi.QueryKeyBackupRequest{
|
||||
UserID: device.UserID,
|
||||
Version: version,
|
||||
ReturnKeys: true,
|
||||
KeysForRoomID: roomID,
|
||||
KeysForSessionID: sessionID,
|
||||
}, &queryResp); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if queryResp.Error != "" {
|
||||
return util.ErrorResponse(fmt.Errorf("QueryKeyBackup: %s", queryResp.Error))
|
||||
})
|
||||
if err != nil {
|
||||
return util.ErrorResponse(fmt.Errorf("QueryKeyBackup: %w", err))
|
||||
}
|
||||
if !queryResp.Exists {
|
||||
return util.JSONResponse{
|
||||
|
|
@ -267,17 +240,20 @@ func GetBackupKeys(
|
|||
}
|
||||
} else if roomID != "" {
|
||||
roomData, ok := queryResp.Keys[roomID]
|
||||
if ok {
|
||||
// wrap response in "sessions"
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: struct {
|
||||
Sessions map[string]userapi.KeyBackupSession `json:"sessions"`
|
||||
}{
|
||||
Sessions: roomData,
|
||||
},
|
||||
}
|
||||
if !ok {
|
||||
// If no keys are found, then an object with an empty sessions property will be returned
|
||||
roomData = make(map[string]userapi.KeyBackupSession)
|
||||
}
|
||||
// wrap response in "sessions"
|
||||
return util.JSONResponse{
|
||||
Code: 200,
|
||||
JSON: struct {
|
||||
Sessions map[string]userapi.KeyBackupSession `json:"sessions"`
|
||||
}{
|
||||
Sessions: roomData,
|
||||
},
|
||||
}
|
||||
|
||||
} else {
|
||||
// response is the same as the upload request
|
||||
var resp keyBackupSessionRequest
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
|
||||
|
|
@ -31,6 +32,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
|
||||
|
|
@ -91,7 +93,7 @@ func sendMembership(ctx context.Context, profileAPI userapi.ClientUserAPI, devic
|
|||
if err = roomserverAPI.SendEvents(
|
||||
ctx, rsAPI,
|
||||
roomserverAPI.KindNew,
|
||||
[]*gomatrixserverlib.HeaderedEvent{event},
|
||||
[]*types.HeaderedEvent{event},
|
||||
device.UserDomain(),
|
||||
serverName,
|
||||
serverName,
|
||||
|
|
@ -264,22 +266,33 @@ func sendInvite(
|
|||
return jsonerror.InternalServerError(), err
|
||||
}
|
||||
|
||||
var inviteRes api.PerformInviteResponse
|
||||
if err := rsAPI.PerformInvite(ctx, &api.PerformInviteRequest{
|
||||
err = rsAPI.PerformInvite(ctx, &api.PerformInviteRequest{
|
||||
Event: event,
|
||||
InviteRoomState: nil, // ask the roomserver to draw up invite room state for us
|
||||
RoomVersion: event.RoomVersion,
|
||||
RoomVersion: event.Version(),
|
||||
SendAsServer: string(device.UserDomain()),
|
||||
}, &inviteRes); err != nil {
|
||||
})
|
||||
|
||||
switch e := err.(type) {
|
||||
case roomserverAPI.ErrInvalidID:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.Unknown(e.Error()),
|
||||
}, e
|
||||
case roomserverAPI.ErrNotAllowed:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden(e.Error()),
|
||||
}, e
|
||||
case nil:
|
||||
default:
|
||||
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
|
||||
sentry.CaptureException(err)
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
}, err
|
||||
}
|
||||
if inviteRes.Error != nil {
|
||||
return inviteRes.Error.JSONResponse(), inviteRes.Error
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
|
|
@ -294,7 +307,7 @@ func buildMembershipEvent(
|
|||
membership, roomID string, isDirect bool,
|
||||
cfg *config.ClientAPI, evTime time.Time,
|
||||
rsAPI roomserverAPI.ClientRoomserverAPI, asAPI appserviceAPI.AppServiceInternalAPI,
|
||||
) (*gomatrixserverlib.HeaderedEvent, error) {
|
||||
) (*types.HeaderedEvent, error) {
|
||||
profile, err := loadProfile(ctx, targetUserID, cfg, profileAPI, asAPI)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -15,13 +15,16 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"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/gomatrix"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func PeekRoomByIDOrAlias(
|
||||
|
|
@ -41,8 +44,6 @@ func PeekRoomByIDOrAlias(
|
|||
UserID: device.UserID,
|
||||
DeviceID: device.ID,
|
||||
}
|
||||
peekRes := roomserverAPI.PerformPeekResponse{}
|
||||
|
||||
// Check to see if any ?server_name= query parameters were
|
||||
// given in the request.
|
||||
if serverNames, ok := req.URL.Query()["server_name"]; ok {
|
||||
|
|
@ -55,11 +56,27 @@ func PeekRoomByIDOrAlias(
|
|||
}
|
||||
|
||||
// Ask the roomserver to perform the peek.
|
||||
if err := rsAPI.PerformPeek(req.Context(), &peekReq, &peekRes); err != nil {
|
||||
return util.ErrorResponse(err)
|
||||
}
|
||||
if peekRes.Error != nil {
|
||||
return peekRes.Error.JSONResponse()
|
||||
roomID, err := rsAPI.PerformPeek(req.Context(), &peekReq)
|
||||
switch e := err.(type) {
|
||||
case roomserverAPI.ErrInvalidID:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.Unknown(e.Error()),
|
||||
}
|
||||
case roomserverAPI.ErrNotAllowed:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden(e.Error()),
|
||||
}
|
||||
case *gomatrix.HTTPError:
|
||||
return util.JSONResponse{
|
||||
Code: e.Code,
|
||||
JSON: json.RawMessage(e.Message),
|
||||
}
|
||||
case nil:
|
||||
default:
|
||||
logrus.WithError(err).WithField("roomID", roomIDOrAlias).Errorf("Failed to peek room")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
// if this user is already joined to the room, we let them peek anyway
|
||||
|
|
@ -75,7 +92,7 @@ func PeekRoomByIDOrAlias(
|
|||
// TODO: Put the response struct somewhere internal.
|
||||
JSON: struct {
|
||||
RoomID string `json:"room_id"`
|
||||
}{peekRes.RoomID},
|
||||
}{roomID},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,18 +102,17 @@ func UnpeekRoomByID(
|
|||
rsAPI roomserverAPI.ClientRoomserverAPI,
|
||||
roomID string,
|
||||
) util.JSONResponse {
|
||||
unpeekReq := roomserverAPI.PerformUnpeekRequest{
|
||||
RoomID: roomID,
|
||||
UserID: device.UserID,
|
||||
DeviceID: device.ID,
|
||||
}
|
||||
unpeekRes := roomserverAPI.PerformUnpeekResponse{}
|
||||
|
||||
if err := rsAPI.PerformUnpeek(req.Context(), &unpeekReq, &unpeekRes); err != nil {
|
||||
return jsonerror.InternalAPIError(req.Context(), err)
|
||||
}
|
||||
if unpeekRes.Error != nil {
|
||||
return unpeekRes.Error.JSONResponse()
|
||||
err := rsAPI.PerformUnpeek(req.Context(), roomID, device.UserID, device.ID)
|
||||
switch e := err.(type) {
|
||||
case roomserverAPI.ErrInvalidID:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.Unknown(e.Error()),
|
||||
}
|
||||
case nil:
|
||||
default:
|
||||
logrus.WithError(err).WithField("roomID", roomID).Errorf("Failed to un-peek room")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import (
|
|||
"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/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
|
||||
|
|
@ -334,16 +335,10 @@ func buildMembershipEvents(
|
|||
roomIDs []string,
|
||||
newProfile authtypes.Profile, userID string, cfg *config.ClientAPI,
|
||||
evTime time.Time, rsAPI api.ClientRoomserverAPI,
|
||||
) ([]*gomatrixserverlib.HeaderedEvent, error) {
|
||||
evs := []*gomatrixserverlib.HeaderedEvent{}
|
||||
) ([]*types.HeaderedEvent, error) {
|
||||
evs := []*types.HeaderedEvent{}
|
||||
|
||||
for _, roomID := range roomIDs {
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := rsAPI.QueryRoomVersionForRoom(ctx, &verReq, &verRes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
builder := gomatrixserverlib.EventBuilder{
|
||||
Sender: userID,
|
||||
RoomID: roomID,
|
||||
|
|
@ -372,7 +367,7 @@ func buildMembershipEvents(
|
|||
return nil, err
|
||||
}
|
||||
|
||||
evs = append(evs, event.Headered(verRes.RoomVersion))
|
||||
evs = append(evs, event)
|
||||
}
|
||||
|
||||
return evs, nil
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/internal/transactions"
|
||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
)
|
||||
|
|
@ -138,7 +139,7 @@ func SendRedaction(
|
|||
}
|
||||
}
|
||||
domain := device.UserDomain()
|
||||
if err = roomserverAPI.SendEvents(context.Background(), rsAPI, roomserverAPI.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, device.UserDomain(), domain, domain, nil, false); err != nil {
|
||||
if err = roomserverAPI.SendEvents(context.Background(), rsAPI, roomserverAPI.KindNew, []*types.HeaderedEvent{e}, device.UserDomain(), domain, domain, nil, false); err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Errorf("failed to SendEvents")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,13 +162,13 @@ func Setup(
|
|||
|
||||
dendriteAdminRouter.Handle("/admin/evacuateUser/{userID}",
|
||||
httputil.MakeAdminAPI("admin_evacuate_user", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||
return AdminEvacuateUser(req, cfg, rsAPI)
|
||||
return AdminEvacuateUser(req, rsAPI)
|
||||
}),
|
||||
).Methods(http.MethodPost, http.MethodOptions)
|
||||
|
||||
dendriteAdminRouter.Handle("/admin/purgeRoom/{roomID}",
|
||||
httputil.MakeAdminAPI("admin_purge_room", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||
return AdminPurgeRoom(req, cfg, device, rsAPI)
|
||||
return AdminPurgeRoom(req, rsAPI)
|
||||
}),
|
||||
).Methods(http.MethodPost, http.MethodOptions)
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ func Setup(
|
|||
|
||||
dendriteAdminRouter.Handle("/admin/downloadState/{serverName}/{roomID}",
|
||||
httputil.MakeAdminAPI("admin_download_state", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||
return AdminDownloadState(req, cfg, device, rsAPI)
|
||||
return AdminDownloadState(req, device, rsAPI)
|
||||
}),
|
||||
).Methods(http.MethodGet, http.MethodOptions)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/internal/transactions"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
)
|
||||
|
|
@ -76,9 +77,8 @@ func SendEvent(
|
|||
rsAPI api.ClientRoomserverAPI,
|
||||
txnCache *transactions.Cache,
|
||||
) util.JSONResponse {
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := rsAPI.QueryRoomVersionForRoom(req.Context(), &verReq, &verRes); err != nil {
|
||||
roomVersion, err := rsAPI.QueryRoomVersionForRoom(req.Context(), roomID)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.UnsupportedRoomVersion(err.Error()),
|
||||
|
|
@ -184,8 +184,8 @@ func SendEvent(
|
|||
if err := api.SendEvents(
|
||||
req.Context(), rsAPI,
|
||||
api.KindNew,
|
||||
[]*gomatrixserverlib.HeaderedEvent{
|
||||
e.Headered(verRes.RoomVersion),
|
||||
[]*types.HeaderedEvent{
|
||||
&types.HeaderedEvent{Event: e},
|
||||
},
|
||||
device.UserDomain(),
|
||||
domain,
|
||||
|
|
@ -200,7 +200,7 @@ func SendEvent(
|
|||
util.GetLogger(req.Context()).WithFields(logrus.Fields{
|
||||
"event_id": e.EventID(),
|
||||
"room_id": roomID,
|
||||
"room_version": verRes.RoomVersion,
|
||||
"room_version": roomVersion,
|
||||
}).Info("Sent event to roomserver")
|
||||
|
||||
res := util.JSONResponse{
|
||||
|
|
@ -317,7 +317,7 @@ func generateSendEvent(
|
|||
for i := range queryRes.StateEvents {
|
||||
stateEvents[i] = queryRes.StateEvents[i].Event
|
||||
}
|
||||
provider := gomatrixserverlib.NewAuthEvents(stateEvents)
|
||||
provider := gomatrixserverlib.NewAuthEvents(gomatrixserverlib.ToPDUs(stateEvents))
|
||||
if err = gomatrixserverlib.Allowed(e.Event, &provider); err != nil {
|
||||
return nil, &util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/matrix-org/gomatrix"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/tokens"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/roomserver/version"
|
||||
|
||||
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
|
||||
|
|
@ -157,7 +157,6 @@ func SendServerNotice(
|
|||
Visibility: "private",
|
||||
Preset: presetPrivateChat,
|
||||
CreationContent: cc,
|
||||
GuestCanJoin: false,
|
||||
RoomVersion: roomVersion,
|
||||
PowerLevelContentOverride: pl,
|
||||
}
|
||||
|
|
@ -228,8 +227,8 @@ func SendServerNotice(
|
|||
if err := api.SendEvents(
|
||||
ctx, rsAPI,
|
||||
api.KindNew,
|
||||
[]*gomatrixserverlib.HeaderedEvent{
|
||||
e.Headered(roomVersion),
|
||||
[]*types.HeaderedEvent{
|
||||
&types.HeaderedEvent{Event: e},
|
||||
},
|
||||
device.UserDomain(),
|
||||
cfgClient.Matrix.ServerName,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/syncapi/synctypes"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
|
@ -133,7 +134,7 @@ func OnIncomingStateRequest(ctx context.Context, device *userapi.Device, rsAPI a
|
|||
for _, ev := range stateRes.StateEvents {
|
||||
stateEvents = append(
|
||||
stateEvents,
|
||||
synctypes.HeaderedToClientEvent(ev, synctypes.FormatAll),
|
||||
synctypes.ToClientEvent(ev, synctypes.FormatAll),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -152,7 +153,7 @@ func OnIncomingStateRequest(ctx context.Context, device *userapi.Device, rsAPI a
|
|||
for _, ev := range stateAfterRes.StateEvents {
|
||||
stateEvents = append(
|
||||
stateEvents,
|
||||
synctypes.HeaderedToClientEvent(ev, synctypes.FormatAll),
|
||||
synctypes.ToClientEvent(ev, synctypes.FormatAll),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -266,7 +267,7 @@ func OnIncomingStateTypeRequest(
|
|||
"state_at_event": !wantLatestState,
|
||||
}).Info("Fetching state")
|
||||
|
||||
var event *gomatrixserverlib.HeaderedEvent
|
||||
var event *types.HeaderedEvent
|
||||
if wantLatestState {
|
||||
// If we are happy to use the latest state, either because the user is
|
||||
// still in the room, or because the room is world-readable, then just
|
||||
|
|
@ -311,7 +312,7 @@ func OnIncomingStateTypeRequest(
|
|||
}
|
||||
|
||||
stateEvent := stateEventInStateResp{
|
||||
ClientEvent: synctypes.HeaderedToClientEvent(event, synctypes.FormatAll),
|
||||
ClientEvent: synctypes.ToClientEvent(event, synctypes.FormatAll),
|
||||
}
|
||||
|
||||
var res interface{}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,13 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
|
||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/version"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
|
|
@ -57,38 +59,28 @@ func UpgradeRoom(
|
|||
}
|
||||
}
|
||||
|
||||
upgradeReq := roomserverAPI.PerformRoomUpgradeRequest{
|
||||
UserID: device.UserID,
|
||||
RoomID: roomID,
|
||||
RoomVersion: gomatrixserverlib.RoomVersion(r.NewVersion),
|
||||
}
|
||||
upgradeResp := roomserverAPI.PerformRoomUpgradeResponse{}
|
||||
|
||||
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 {
|
||||
newRoomID, err := rsAPI.PerformRoomUpgrade(req.Context(), roomID, device.UserID, gomatrixserverlib.RoomVersion(r.NewVersion))
|
||||
switch e := err.(type) {
|
||||
case nil:
|
||||
case roomserverAPI.ErrNotAllowed:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden(e.Error()),
|
||||
}
|
||||
default:
|
||||
if errors.Is(err, eventutil.ErrRoomNoExists) {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
JSON: jsonerror.NotFound("Room does not exist"),
|
||||
}
|
||||
} else if upgradeResp.Error.Code == roomserverAPI.PerformErrorNotAllowed {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden(upgradeResp.Error.Msg),
|
||||
}
|
||||
} else {
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: upgradeRoomResponse{
|
||||
ReplacementRoom: upgradeResp.NewRoomID,
|
||||
ReplacementRoom: newRoomID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
|
@ -367,8 +368,8 @@ func emit3PIDInviteEvent(
|
|||
return api.SendEvents(
|
||||
ctx, rsAPI,
|
||||
api.KindNew,
|
||||
[]*gomatrixserverlib.HeaderedEvent{
|
||||
event.Headered(queryRes.RoomVersion),
|
||||
[]*types.HeaderedEvent{
|
||||
event,
|
||||
},
|
||||
device.UserDomain(),
|
||||
cfg.Matrix.ServerName,
|
||||
|
|
|
|||
|
|
@ -183,8 +183,8 @@ func main() {
|
|||
var resolved Events
|
||||
resolved, err = gomatrixserverlib.ResolveConflicts(
|
||||
gomatrixserverlib.RoomVersion(*roomVersion),
|
||||
events,
|
||||
authEvents,
|
||||
gomatrixserverlib.ToPDUs(events),
|
||||
gomatrixserverlib.ToPDUs(authEvents),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
|
@ -208,7 +208,7 @@ func main() {
|
|||
fmt.Println("Returned", count, "state events after filtering")
|
||||
}
|
||||
|
||||
type Events []*gomatrixserverlib.Event
|
||||
type Events []gomatrixserverlib.PDU
|
||||
|
||||
func (e Events) Len() int {
|
||||
return len(e)
|
||||
|
|
|
|||
|
|
@ -11,11 +11,13 @@ import (
|
|||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
|
||||
"github.com/matrix-org/dendrite/federationapi/types"
|
||||
rstypes "github.com/matrix-org/dendrite/roomserver/types"
|
||||
)
|
||||
|
||||
// FederationInternalAPI is used to query information from the federation sender.
|
||||
type FederationInternalAPI interface {
|
||||
gomatrixserverlib.FederatedStateClient
|
||||
gomatrixserverlib.FederatedJoinClient
|
||||
KeyserverFederationAPI
|
||||
gomatrixserverlib.KeyDatabase
|
||||
ClientFederationAPI
|
||||
|
|
@ -188,13 +190,13 @@ type PerformLeaveResponse struct {
|
|||
}
|
||||
|
||||
type PerformInviteRequest struct {
|
||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
Event *gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
InviteRoomState []fclient.InviteV2StrippedState `json:"invite_room_state"`
|
||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
Event *rstypes.HeaderedEvent `json:"event"`
|
||||
InviteRoomState []fclient.InviteV2StrippedState `json:"invite_room_state"`
|
||||
}
|
||||
|
||||
type PerformInviteResponse struct {
|
||||
Event *gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
Event *rstypes.HeaderedEvent `json:"event"`
|
||||
}
|
||||
|
||||
// QueryJoinedHostServerNamesInRoomRequest is a request to QueryJoinedHostServerNames
|
||||
|
|
|
|||
|
|
@ -187,7 +187,12 @@ func (s *OutputRoomEventConsumer) processMessage(ore api.OutputNewRoomEvent, rew
|
|||
addsStateEvents = append(addsStateEvents, eventsRes.Events...)
|
||||
}
|
||||
|
||||
addsJoinedHosts, err := JoinedHostsFromEvents(gomatrixserverlib.UnwrapEventHeaders(addsStateEvents))
|
||||
evs := make([]*gomatrixserverlib.Event, len(addsStateEvents))
|
||||
for i := range evs {
|
||||
evs[i] = addsStateEvents[i].Event
|
||||
}
|
||||
|
||||
addsJoinedHosts, err := JoinedHostsFromEvents(evs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/federationapi/api"
|
||||
"github.com/matrix-org/dendrite/federationapi/internal"
|
||||
rsapi "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||
"github.com/matrix-org/dendrite/test"
|
||||
"github.com/matrix-org/dendrite/test/testrig"
|
||||
|
|
@ -106,7 +107,9 @@ func (f *fedClient) GetServerKeys(ctx context.Context, matrixServer spec.ServerN
|
|||
return keys, nil
|
||||
}
|
||||
|
||||
func (f *fedClient) MakeJoin(ctx context.Context, origin, s spec.ServerName, roomID, userID string, roomVersions []gomatrixserverlib.RoomVersion) (res fclient.RespMakeJoin, err error) {
|
||||
func (f *fedClient) MakeJoin(ctx context.Context, origin, s spec.ServerName, roomID, userID string) (res fclient.RespMakeJoin, err error) {
|
||||
f.fedClientMutex.Lock()
|
||||
defer f.fedClientMutex.Unlock()
|
||||
for _, r := range f.allowJoins {
|
||||
if r.ID == roomID {
|
||||
res.RoomVersion = r.Version
|
||||
|
|
@ -135,10 +138,10 @@ func (f *fedClient) SendJoin(ctx context.Context, origin, s spec.ServerName, eve
|
|||
defer f.fedClientMutex.Unlock()
|
||||
for _, r := range f.allowJoins {
|
||||
if r.ID == event.RoomID() {
|
||||
r.InsertEvent(f.t, event.Headered(r.Version))
|
||||
r.InsertEvent(f.t, &types.HeaderedEvent{Event: event})
|
||||
f.t.Logf("Join event: %v", event.EventID())
|
||||
res.StateEvents = gomatrixserverlib.NewEventJSONsFromHeaderedEvents(r.CurrentState())
|
||||
res.AuthEvents = gomatrixserverlib.NewEventJSONsFromHeaderedEvents(r.Events())
|
||||
res.StateEvents = types.NewEventJSONsFromHeaderedEvents(r.CurrentState())
|
||||
res.AuthEvents = types.NewEventJSONsFromHeaderedEvents(r.Events())
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
@ -325,8 +328,7 @@ func TestRoomsV3URLEscapeDoNot404(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("failed to parse event: %s", err)
|
||||
}
|
||||
he := ev.Headered(tc.roomVer)
|
||||
invReq, err := fclient.NewInviteV2Request(he, nil)
|
||||
invReq, err := fclient.NewInviteV2Request(ev, nil)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create invite v2 request: %s", err)
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -9,14 +9,40 @@ import (
|
|||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
)
|
||||
|
||||
const defaultTimeout = time.Second * 30
|
||||
|
||||
// Functions here are "proxying" calls to the gomatrixserverlib federation
|
||||
// client.
|
||||
|
||||
func (a *FederationInternalAPI) MakeJoin(
|
||||
ctx context.Context, origin, s spec.ServerName, roomID, userID string,
|
||||
) (res gomatrixserverlib.MakeJoinResponse, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.federation.MakeJoin(ctx, origin, s, roomID, userID)
|
||||
if err != nil {
|
||||
return &fclient.RespMakeJoin{}, err
|
||||
}
|
||||
return &ires, nil
|
||||
}
|
||||
|
||||
func (a *FederationInternalAPI) SendJoin(
|
||||
ctx context.Context, origin, s spec.ServerName, event *gomatrixserverlib.Event,
|
||||
) (res gomatrixserverlib.SendJoinResponse, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.federation.SendJoin(ctx, origin, s, event)
|
||||
if err != nil {
|
||||
return &fclient.RespSendJoin{}, err
|
||||
}
|
||||
return &ires, nil
|
||||
}
|
||||
|
||||
func (a *FederationInternalAPI) GetEventAuth(
|
||||
ctx context.Context, origin, s spec.ServerName,
|
||||
roomVersion gomatrixserverlib.RoomVersion, roomID, eventID string,
|
||||
) (res fclient.RespEventAuth, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.doRequestIfNotBlacklisted(s, func() (interface{}, error) {
|
||||
return a.federation.GetEventAuth(ctx, origin, s, roomVersion, roomID, eventID)
|
||||
|
|
@ -30,7 +56,7 @@ func (a *FederationInternalAPI) GetEventAuth(
|
|||
func (a *FederationInternalAPI) GetUserDevices(
|
||||
ctx context.Context, origin, s spec.ServerName, userID string,
|
||||
) (fclient.RespUserDevices, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.doRequestIfNotBlacklisted(s, func() (interface{}, error) {
|
||||
return a.federation.GetUserDevices(ctx, origin, s, userID)
|
||||
|
|
@ -44,7 +70,7 @@ func (a *FederationInternalAPI) GetUserDevices(
|
|||
func (a *FederationInternalAPI) ClaimKeys(
|
||||
ctx context.Context, origin, s spec.ServerName, oneTimeKeys map[string]map[string]string,
|
||||
) (fclient.RespClaimKeys, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.doRequestIfNotBlacklisted(s, func() (interface{}, error) {
|
||||
return a.federation.ClaimKeys(ctx, origin, s, oneTimeKeys)
|
||||
|
|
@ -70,7 +96,7 @@ func (a *FederationInternalAPI) QueryKeys(
|
|||
func (a *FederationInternalAPI) Backfill(
|
||||
ctx context.Context, origin, s spec.ServerName, roomID string, limit int, eventIDs []string,
|
||||
) (res gomatrixserverlib.Transaction, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.doRequestIfNotBlacklisted(s, func() (interface{}, error) {
|
||||
return a.federation.Backfill(ctx, origin, s, roomID, limit, eventIDs)
|
||||
|
|
@ -84,7 +110,7 @@ func (a *FederationInternalAPI) Backfill(
|
|||
func (a *FederationInternalAPI) LookupState(
|
||||
ctx context.Context, origin, s spec.ServerName, roomID, eventID string, roomVersion gomatrixserverlib.RoomVersion,
|
||||
) (res gomatrixserverlib.StateResponse, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.doRequestIfNotBlacklisted(s, func() (interface{}, error) {
|
||||
return a.federation.LookupState(ctx, origin, s, roomID, eventID, roomVersion)
|
||||
|
|
@ -99,7 +125,7 @@ func (a *FederationInternalAPI) LookupState(
|
|||
func (a *FederationInternalAPI) LookupStateIDs(
|
||||
ctx context.Context, origin, s spec.ServerName, roomID, eventID string,
|
||||
) (res gomatrixserverlib.StateIDResponse, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.doRequestIfNotBlacklisted(s, func() (interface{}, error) {
|
||||
return a.federation.LookupStateIDs(ctx, origin, s, roomID, eventID)
|
||||
|
|
@ -114,7 +140,7 @@ func (a *FederationInternalAPI) LookupMissingEvents(
|
|||
ctx context.Context, origin, s spec.ServerName, roomID string,
|
||||
missing fclient.MissingEvents, roomVersion gomatrixserverlib.RoomVersion,
|
||||
) (res fclient.RespMissingEvents, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.doRequestIfNotBlacklisted(s, func() (interface{}, error) {
|
||||
return a.federation.LookupMissingEvents(ctx, origin, s, roomID, missing, roomVersion)
|
||||
|
|
@ -128,7 +154,7 @@ func (a *FederationInternalAPI) LookupMissingEvents(
|
|||
func (a *FederationInternalAPI) GetEvent(
|
||||
ctx context.Context, origin, s spec.ServerName, eventID string,
|
||||
) (res gomatrixserverlib.Transaction, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
|
||||
defer cancel()
|
||||
ires, err := a.doRequestIfNotBlacklisted(s, func() (interface{}, error) {
|
||||
return a.federation.GetEvent(ctx, origin, s, eventID)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/federationapi/consumers"
|
||||
"github.com/matrix-org/dendrite/federationapi/statistics"
|
||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/roomserver/version"
|
||||
)
|
||||
|
||||
|
|
@ -73,12 +74,6 @@ func (r *FederationInternalAPI) PerformJoin(
|
|||
r.joins.Store(j, nil)
|
||||
defer r.joins.Delete(j)
|
||||
|
||||
// Look up the supported room versions.
|
||||
var supportedVersions []gomatrixserverlib.RoomVersion
|
||||
for version := range version.SupportedRoomVersions() {
|
||||
supportedVersions = append(supportedVersions, version)
|
||||
}
|
||||
|
||||
// Deduplicate the server names we were provided but keep the ordering
|
||||
// as this encodes useful information about which servers are most likely
|
||||
// to respond.
|
||||
|
|
@ -103,7 +98,6 @@ func (r *FederationInternalAPI) PerformJoin(
|
|||
request.UserID,
|
||||
request.Content,
|
||||
serverName,
|
||||
supportedVersions,
|
||||
request.Unsigned,
|
||||
); err != nil {
|
||||
logrus.WithError(err).WithFields(logrus.Fields{
|
||||
|
|
@ -146,128 +140,45 @@ func (r *FederationInternalAPI) performJoinUsingServer(
|
|||
roomID, userID string,
|
||||
content map[string]interface{},
|
||||
serverName spec.ServerName,
|
||||
supportedVersions []gomatrixserverlib.RoomVersion,
|
||||
unsigned map[string]interface{},
|
||||
) error {
|
||||
if !r.shouldAttemptDirectFederation(serverName) {
|
||||
return fmt.Errorf("relay servers have no meaningful response for join.")
|
||||
}
|
||||
|
||||
_, origin, err := r.cfg.Matrix.SplitLocalID('@', userID)
|
||||
user, err := spec.NewUserID(userID, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
room, err := spec.NewRoomID(roomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Try to perform a make_join using the information supplied in the
|
||||
// request.
|
||||
respMakeJoin, err := r.federation.MakeJoin(
|
||||
ctx,
|
||||
origin,
|
||||
serverName,
|
||||
roomID,
|
||||
userID,
|
||||
supportedVersions,
|
||||
)
|
||||
if err != nil {
|
||||
// TODO: Check if the user was not allowed to join the room.
|
||||
r.statistics.ForServer(serverName).Failure()
|
||||
return fmt.Errorf("r.federation.MakeJoin: %w", err)
|
||||
joinInput := gomatrixserverlib.PerformJoinInput{
|
||||
UserID: user,
|
||||
RoomID: room,
|
||||
ServerName: serverName,
|
||||
Content: content,
|
||||
Unsigned: unsigned,
|
||||
PrivateKey: r.cfg.Matrix.PrivateKey,
|
||||
KeyID: r.cfg.Matrix.KeyID,
|
||||
KeyRing: r.keyRing,
|
||||
EventProvider: federatedEventProvider(ctx, r.federation, r.keyRing, user.Domain(), serverName),
|
||||
}
|
||||
r.statistics.ForServer(serverName).Success(statistics.SendDirect)
|
||||
response, joinErr := gomatrixserverlib.PerformJoin(ctx, r, joinInput)
|
||||
|
||||
// Set all the fields to be what they should be, this should be a no-op
|
||||
// but it's possible that the remote server returned us something "odd"
|
||||
respMakeJoin.JoinEvent.Type = spec.MRoomMember
|
||||
respMakeJoin.JoinEvent.Sender = userID
|
||||
respMakeJoin.JoinEvent.StateKey = &userID
|
||||
respMakeJoin.JoinEvent.RoomID = roomID
|
||||
respMakeJoin.JoinEvent.Redacts = ""
|
||||
if content == nil {
|
||||
content = map[string]interface{}{}
|
||||
}
|
||||
_ = json.Unmarshal(respMakeJoin.JoinEvent.Content, &content)
|
||||
content["membership"] = spec.Join
|
||||
if err = respMakeJoin.JoinEvent.SetContent(content); err != nil {
|
||||
return fmt.Errorf("respMakeJoin.JoinEvent.SetContent: %w", err)
|
||||
}
|
||||
if err = respMakeJoin.JoinEvent.SetUnsigned(struct{}{}); err != nil {
|
||||
return fmt.Errorf("respMakeJoin.JoinEvent.SetUnsigned: %w", err)
|
||||
}
|
||||
|
||||
// Work out if we support the room version that has been supplied in
|
||||
// the make_join response.
|
||||
// "If not provided, the room version is assumed to be either "1" or "2"."
|
||||
// https://matrix.org/docs/spec/server_server/unstable#get-matrix-federation-v1-make-join-roomid-userid
|
||||
if respMakeJoin.RoomVersion == "" {
|
||||
respMakeJoin.RoomVersion = setDefaultRoomVersionFromJoinEvent(respMakeJoin.JoinEvent)
|
||||
}
|
||||
verImpl, err := gomatrixserverlib.GetRoomVersion(respMakeJoin.RoomVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Build the join event.
|
||||
event, err := respMakeJoin.JoinEvent.Build(
|
||||
time.Now(),
|
||||
origin,
|
||||
r.cfg.Matrix.KeyID,
|
||||
r.cfg.Matrix.PrivateKey,
|
||||
respMakeJoin.RoomVersion,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("respMakeJoin.JoinEvent.Build: %w", err)
|
||||
}
|
||||
|
||||
// Try to perform a send_join using the newly built event.
|
||||
respSendJoin, err := r.federation.SendJoin(
|
||||
context.Background(),
|
||||
origin,
|
||||
serverName,
|
||||
event,
|
||||
)
|
||||
if err != nil {
|
||||
r.statistics.ForServer(serverName).Failure()
|
||||
return fmt.Errorf("r.federation.SendJoin: %w", err)
|
||||
}
|
||||
r.statistics.ForServer(serverName).Success(statistics.SendDirect)
|
||||
|
||||
// If the remote server returned an event in the "event" key of
|
||||
// the send_join request then we should use that instead. It may
|
||||
// contain signatures that we don't know about.
|
||||
if len(respSendJoin.Event) > 0 {
|
||||
var remoteEvent *gomatrixserverlib.Event
|
||||
remoteEvent, err = verImpl.NewEventFromUntrustedJSON(respSendJoin.Event)
|
||||
if err == nil && isWellFormedMembershipEvent(
|
||||
remoteEvent, roomID, userID,
|
||||
) {
|
||||
event = remoteEvent
|
||||
if joinErr != nil {
|
||||
if !joinErr.Reachable {
|
||||
r.statistics.ForServer(joinErr.ServerName).Failure()
|
||||
} else {
|
||||
r.statistics.ForServer(joinErr.ServerName).Success(statistics.SendDirect)
|
||||
}
|
||||
return joinErr.Err
|
||||
}
|
||||
|
||||
// Sanity-check the join response to ensure that it has a create
|
||||
// event, that the room version is known, etc.
|
||||
authEvents := respSendJoin.AuthEvents.UntrustedEvents(respMakeJoin.RoomVersion)
|
||||
if err = sanityCheckAuthChain(authEvents); err != nil {
|
||||
return fmt.Errorf("sanityCheckAuthChain: %w", err)
|
||||
}
|
||||
|
||||
// Process the join response in a goroutine. The idea here is
|
||||
// that we'll try and wait for as long as possible for the work
|
||||
// to complete, but if the client does give up waiting, we'll
|
||||
// still continue to process the join anyway so that we don't
|
||||
// waste the effort.
|
||||
// TODO: Can we expand Check here to return a list of missing auth
|
||||
// events rather than failing one at a time?
|
||||
var respState gomatrixserverlib.StateResponse
|
||||
respState, err = gomatrixserverlib.CheckSendJoinResponse(
|
||||
context.Background(),
|
||||
respMakeJoin.RoomVersion, &respSendJoin,
|
||||
r.keyRing,
|
||||
event,
|
||||
federatedAuthProvider(ctx, r.federation, r.keyRing, origin, serverName),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("respSendJoin.Check: %w", err)
|
||||
r.statistics.ForServer(serverName).Success(statistics.SendDirect)
|
||||
if response == nil {
|
||||
return fmt.Errorf("Received nil response from gomatrixserverlib.PerformJoin")
|
||||
}
|
||||
|
||||
// We need to immediately update our list of joined hosts for this room now as we are technically
|
||||
|
|
@ -276,60 +187,33 @@ func (r *FederationInternalAPI) performJoinUsingServer(
|
|||
// joining a room, waiting for 200 OK then changing device keys and have those keys not be sent
|
||||
// to other servers (this was a cause of a flakey sytest "Local device key changes get to remote servers")
|
||||
// The events are trusted now as we performed auth checks above.
|
||||
joinedHosts, err := consumers.JoinedHostsFromEvents(respState.GetStateEvents().TrustedEvents(respMakeJoin.RoomVersion, false))
|
||||
joinedHosts, err := consumers.JoinedHostsFromEvents(response.StateSnapshot.GetStateEvents().TrustedEvents(response.JoinEvent.Version(), false))
|
||||
if err != nil {
|
||||
return fmt.Errorf("JoinedHostsFromEvents: failed to get joined hosts: %s", err)
|
||||
}
|
||||
|
||||
logrus.WithField("room", roomID).Infof("Joined federated room with %d hosts", len(joinedHosts))
|
||||
if _, err = r.db.UpdateRoom(context.Background(), roomID, joinedHosts, nil, true); err != nil {
|
||||
return fmt.Errorf("UpdatedRoom: failed to update room with joined hosts: %s", err)
|
||||
}
|
||||
|
||||
// If we successfully performed a send_join above then the other
|
||||
// server now thinks we're a part of the room. Send the newly
|
||||
// returned state to the roomserver to update our local view.
|
||||
if unsigned != nil {
|
||||
event, err = event.SetUnsigned(unsigned)
|
||||
if err != nil {
|
||||
// non-fatal, log and continue
|
||||
logrus.WithError(err).Errorf("Failed to set unsigned content")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Can I change this to not take respState but instead just take an opaque list of events?
|
||||
if err = roomserverAPI.SendEventWithState(
|
||||
context.Background(),
|
||||
r.rsAPI,
|
||||
origin,
|
||||
user.Domain(),
|
||||
roomserverAPI.KindNew,
|
||||
respState,
|
||||
event.Headered(respMakeJoin.RoomVersion),
|
||||
response.StateSnapshot,
|
||||
&types.HeaderedEvent{Event: response.JoinEvent},
|
||||
serverName,
|
||||
nil,
|
||||
false,
|
||||
); err != nil {
|
||||
return fmt.Errorf("roomserverAPI.SendEventWithState: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isWellFormedMembershipEvent returns true if the event looks like a legitimate
|
||||
// membership event.
|
||||
func isWellFormedMembershipEvent(event *gomatrixserverlib.Event, roomID, userID string) bool {
|
||||
if membership, err := event.Membership(); err != nil {
|
||||
return false
|
||||
} else if membership != spec.Join {
|
||||
return false
|
||||
}
|
||||
if event.RoomID() != roomID {
|
||||
return false
|
||||
}
|
||||
if !event.StateKeyEquals(userID) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// PerformOutboundPeekRequest implements api.FederationInternalAPI
|
||||
func (r *FederationInternalAPI) PerformOutboundPeek(
|
||||
ctx context.Context,
|
||||
|
|
@ -475,12 +359,12 @@ func (r *FederationInternalAPI) performOutboundPeekUsingServer(
|
|||
// authenticate the state returned (check its auth events etc)
|
||||
// the equivalent of CheckSendJoinResponse()
|
||||
authEvents, stateEvents, err := gomatrixserverlib.CheckStateResponse(
|
||||
ctx, &respPeek, respPeek.RoomVersion, r.keyRing, federatedAuthProvider(ctx, r.federation, r.keyRing, r.cfg.Matrix.ServerName, serverName),
|
||||
ctx, &respPeek, respPeek.RoomVersion, r.keyRing, federatedEventProvider(ctx, r.federation, r.keyRing, r.cfg.Matrix.ServerName, serverName),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error checking state returned from peeking: %w", err)
|
||||
}
|
||||
if err = sanityCheckAuthChain(authEvents); err != nil {
|
||||
if err = checkEventsContainCreateEvent(authEvents); err != nil {
|
||||
return fmt.Errorf("sanityCheckAuthChain: %w", err)
|
||||
}
|
||||
|
||||
|
|
@ -505,7 +389,7 @@ func (r *FederationInternalAPI) performOutboundPeekUsingServer(
|
|||
StateEvents: gomatrixserverlib.NewEventJSONsFromEvents(stateEvents),
|
||||
AuthEvents: gomatrixserverlib.NewEventJSONsFromEvents(authEvents),
|
||||
},
|
||||
respPeek.LatestEvent.Headered(respPeek.RoomVersion),
|
||||
&types.HeaderedEvent{Event: respPeek.LatestEvent},
|
||||
serverName,
|
||||
nil,
|
||||
false,
|
||||
|
|
@ -652,7 +536,7 @@ func (r *FederationInternalAPI) PerformInvite(
|
|||
"destination": destination,
|
||||
}).Info("Sending invite")
|
||||
|
||||
inviteReq, err := fclient.NewInviteV2Request(request.Event, request.InviteRoomState)
|
||||
inviteReq, err := fclient.NewInviteV2Request(request.Event.Event, request.InviteRoomState)
|
||||
if err != nil {
|
||||
return fmt.Errorf("gomatrixserverlib.NewInviteV2Request: %w", err)
|
||||
}
|
||||
|
|
@ -670,7 +554,7 @@ func (r *FederationInternalAPI) PerformInvite(
|
|||
if err != nil {
|
||||
return fmt.Errorf("r.federation.SendInviteV2 failed to decode event response: %w", err)
|
||||
}
|
||||
response.Event = inviteEvent.Headered(request.RoomVersion)
|
||||
response.Event = &types.HeaderedEvent{Event: inviteEvent}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -719,9 +603,9 @@ func (r *FederationInternalAPI) MarkServersAlive(destinations []spec.ServerName)
|
|||
}
|
||||
}
|
||||
|
||||
func sanityCheckAuthChain(authChain []*gomatrixserverlib.Event) error {
|
||||
func checkEventsContainCreateEvent(events []*gomatrixserverlib.Event) error {
|
||||
// sanity check we have a create event and it has a known room version
|
||||
for _, ev := range authChain {
|
||||
for _, ev := range events {
|
||||
if ev.Type() == spec.MRoomCreate && ev.StateKeyEquals("") {
|
||||
// make sure the room version is known
|
||||
content := ev.Content()
|
||||
|
|
@ -739,52 +623,28 @@ func sanityCheckAuthChain(authChain []*gomatrixserverlib.Event) error {
|
|||
}
|
||||
knownVersions := gomatrixserverlib.RoomVersions()
|
||||
if _, ok := knownVersions[gomatrixserverlib.RoomVersion(verBody.Version)]; !ok {
|
||||
return fmt.Errorf("auth chain m.room.create event has an unknown room version: %s", verBody.Version)
|
||||
return fmt.Errorf("m.room.create event has an unknown room version: %s", verBody.Version)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("auth chain response is missing m.room.create event")
|
||||
return fmt.Errorf("response is missing m.room.create event")
|
||||
}
|
||||
|
||||
func setDefaultRoomVersionFromJoinEvent(
|
||||
joinEvent gomatrixserverlib.EventBuilder,
|
||||
) gomatrixserverlib.RoomVersion {
|
||||
// if auth events are not event references we know it must be v3+
|
||||
// we have to do these shenanigans to satisfy sytest, specifically for:
|
||||
// "Outbound federation rejects m.room.create events with an unknown room version"
|
||||
hasEventRefs := true
|
||||
authEvents, ok := joinEvent.AuthEvents.([]interface{})
|
||||
if ok {
|
||||
if len(authEvents) > 0 {
|
||||
_, ok = authEvents[0].(string)
|
||||
if ok {
|
||||
// event refs are objects, not strings, so we know we must be dealing with a v3+ room.
|
||||
hasEventRefs = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if hasEventRefs {
|
||||
return gomatrixserverlib.RoomVersionV1
|
||||
}
|
||||
return gomatrixserverlib.RoomVersionV4
|
||||
}
|
||||
|
||||
// FederatedAuthProvider is an auth chain provider which fetches events from the server provided
|
||||
func federatedAuthProvider(
|
||||
// federatedEventProvider is an event provider which fetches events from the server provided
|
||||
func federatedEventProvider(
|
||||
ctx context.Context, federation fclient.FederationClient,
|
||||
keyRing gomatrixserverlib.JSONVerifier, origin, server spec.ServerName,
|
||||
) gomatrixserverlib.AuthChainProvider {
|
||||
) gomatrixserverlib.EventProvider {
|
||||
// A list of events that we have retried, if they were not included in
|
||||
// the auth events supplied in the send_join.
|
||||
retries := map[string][]*gomatrixserverlib.Event{}
|
||||
retries := map[string][]gomatrixserverlib.PDU{}
|
||||
|
||||
// Define a function which we can pass to Check to retrieve missing
|
||||
// auth events inline. This greatly increases our chances of not having
|
||||
// to repeat the entire set of checks just for a missing event or two.
|
||||
return func(roomVersion gomatrixserverlib.RoomVersion, eventIDs []string) ([]*gomatrixserverlib.Event, error) {
|
||||
returning := []*gomatrixserverlib.Event{}
|
||||
return func(roomVersion gomatrixserverlib.RoomVersion, eventIDs []string) ([]gomatrixserverlib.PDU, error) {
|
||||
returning := []gomatrixserverlib.PDU{}
|
||||
verImpl, err := gomatrixserverlib.GetRoomVersion(roomVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -824,7 +684,7 @@ func federatedAuthProvider(
|
|||
}
|
||||
|
||||
// Check the signatures of the event.
|
||||
if err := ev.VerifyEventSignatures(ctx, keyRing); err != nil {
|
||||
if err := gomatrixserverlib.VerifyEventSignatures(ctx, ev, keyRing); err != nil {
|
||||
return nil, fmt.Errorf("missingAuth VerifyEventSignatures: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/federationapi/storage"
|
||||
"github.com/matrix-org/dendrite/federationapi/storage/shared/receipt"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/process"
|
||||
)
|
||||
|
||||
|
|
@ -71,7 +72,7 @@ type destinationQueue struct {
|
|||
// Send event adds the event to the pending queue for the destination.
|
||||
// If the queue is empty then it starts a background goroutine to
|
||||
// start sending events to that destination.
|
||||
func (oq *destinationQueue) sendEvent(event *gomatrixserverlib.HeaderedEvent, dbReceipt *receipt.Receipt) {
|
||||
func (oq *destinationQueue) sendEvent(event *types.HeaderedEvent, dbReceipt *receipt.Receipt) {
|
||||
if event == nil {
|
||||
logrus.Errorf("attempt to send nil PDU with destination %q", oq.destination)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/federationapi/storage"
|
||||
"github.com/matrix-org/dendrite/federationapi/storage/shared/receipt"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/process"
|
||||
)
|
||||
|
||||
|
|
@ -140,7 +141,7 @@ func NewOutgoingQueues(
|
|||
|
||||
type queuedPDU struct {
|
||||
dbReceipt *receipt.Receipt
|
||||
pdu *gomatrixserverlib.HeaderedEvent
|
||||
pdu *types.HeaderedEvent
|
||||
}
|
||||
|
||||
type queuedEDU struct {
|
||||
|
|
@ -187,7 +188,7 @@ func (oqs *OutgoingQueues) clearQueue(oq *destinationQueue) {
|
|||
|
||||
// SendEvent sends an event to the destinations
|
||||
func (oqs *OutgoingQueues) SendEvent(
|
||||
ev *gomatrixserverlib.HeaderedEvent, origin spec.ServerName,
|
||||
ev *types.HeaderedEvent, origin spec.ServerName,
|
||||
destinations []spec.ServerName,
|
||||
) error {
|
||||
if oqs.disabled {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/federationapi/statistics"
|
||||
"github.com/matrix-org/dendrite/federationapi/storage"
|
||||
rsapi "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/setup/process"
|
||||
"github.com/matrix-org/dendrite/test"
|
||||
|
|
@ -101,14 +102,14 @@ func (f *stubFederationClient) P2PSendTransactionToRelay(ctx context.Context, u
|
|||
return fclient.EmptyResp{}, result
|
||||
}
|
||||
|
||||
func mustCreatePDU(t *testing.T) *gomatrixserverlib.HeaderedEvent {
|
||||
func mustCreatePDU(t *testing.T) *types.HeaderedEvent {
|
||||
t.Helper()
|
||||
content := `{"type":"m.room.message"}`
|
||||
ev, err := gomatrixserverlib.MustGetRoomVersion(gomatrixserverlib.RoomVersionV10).NewEventFromTrustedJSON([]byte(content), false)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create event: %v", err)
|
||||
}
|
||||
return ev.Headered(gomatrixserverlib.RoomVersionV10)
|
||||
return &types.HeaderedEvent{Event: ev}
|
||||
}
|
||||
|
||||
func mustCreateEDU(t *testing.T) *gomatrixserverlib.EDU {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
|
|
@ -104,7 +105,7 @@ func Backfill(
|
|||
// Filter any event that's not from the requested room out.
|
||||
evs := make([]*gomatrixserverlib.Event, 0)
|
||||
|
||||
var ev *gomatrixserverlib.HeaderedEvent
|
||||
var ev *types.HeaderedEvent
|
||||
for _, ev = range res.Events {
|
||||
if ev.RoomID() == roomID {
|
||||
evs = append(evs, ev.Event)
|
||||
|
|
@ -113,7 +114,7 @@ func Backfill(
|
|||
|
||||
eventJSONs := []json.RawMessage{}
|
||||
for _, e := range gomatrixserverlib.ReverseTopologicalOrdering(
|
||||
evs,
|
||||
gomatrixserverlib.ToPDUs(evs),
|
||||
gomatrixserverlib.TopologicalOrderByPrevEvents,
|
||||
) {
|
||||
eventJSONs = append(eventJSONs, e.JSON())
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
|
@ -72,7 +72,7 @@ func GetEventAuth(
|
|||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: fclient.RespEventAuth{
|
||||
AuthEvents: gomatrixserverlib.NewEventJSONsFromHeaderedEvents(response.AuthChainEvents),
|
||||
AuthEvents: types.NewEventJSONsFromHeaderedEvents(response.AuthChainEvents),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
|
|
@ -196,25 +198,44 @@ func processInvite(
|
|||
)
|
||||
|
||||
// Add the invite event to the roomserver.
|
||||
inviteEvent := signedEvent.Headered(roomVer)
|
||||
inviteEvent := &types.HeaderedEvent{Event: &signedEvent}
|
||||
request := &api.PerformInviteRequest{
|
||||
Event: inviteEvent,
|
||||
InviteRoomState: strippedState,
|
||||
RoomVersion: inviteEvent.RoomVersion,
|
||||
RoomVersion: inviteEvent.Version(),
|
||||
SendAsServer: string(api.DoNotSendToOtherServers),
|
||||
TransactionID: nil,
|
||||
}
|
||||
response := &api.PerformInviteResponse{}
|
||||
if err := rsAPI.PerformInvite(ctx, request, response); err != nil {
|
||||
|
||||
if err = rsAPI.PerformInvite(ctx, request); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
}
|
||||
}
|
||||
if response.Error != nil {
|
||||
return response.Error.JSONResponse()
|
||||
|
||||
switch e := err.(type) {
|
||||
case api.ErrInvalidID:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.Unknown(e.Error()),
|
||||
}
|
||||
case api.ErrNotAllowed:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden(e.Error()),
|
||||
}
|
||||
case nil:
|
||||
default:
|
||||
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
|
||||
sentry.CaptureException(err)
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
}
|
||||
}
|
||||
|
||||
// Return the signed event to the originating server, it should then tell
|
||||
// the other servers in the room that we have been invited.
|
||||
if isInviteV2 {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
"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/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
)
|
||||
|
||||
|
|
@ -42,9 +43,8 @@ func MakeJoin(
|
|||
roomID, userID string,
|
||||
remoteVersions []gomatrixserverlib.RoomVersion,
|
||||
) util.JSONResponse {
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), &verReq, &verRes); err != nil {
|
||||
roomVersion, err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), roomID)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
|
|
@ -57,7 +57,7 @@ func MakeJoin(
|
|||
// https://matrix.org/docs/spec/server_server/r0.1.3#get-matrix-federation-v1-make-join-roomid-userid
|
||||
remoteSupportsVersion := false
|
||||
for _, v := range remoteVersions {
|
||||
if v == verRes.RoomVersion {
|
||||
if v == roomVersion {
|
||||
remoteSupportsVersion = true
|
||||
break
|
||||
}
|
||||
|
|
@ -66,7 +66,7 @@ func MakeJoin(
|
|||
if !remoteSupportsVersion {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.IncompatibleRoomVersion(verRes.RoomVersion),
|
||||
JSON: jsonerror.IncompatibleRoomVersion(roomVersion),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ func MakeJoin(
|
|||
|
||||
// Check if the restricted join is allowed. If the room doesn't
|
||||
// support restricted joins then this is effectively a no-op.
|
||||
res, authorisedVia, err := checkRestrictedJoin(httpReq, rsAPI, verRes.RoomVersion, roomID, userID)
|
||||
res, authorisedVia, err := checkRestrictedJoin(httpReq, rsAPI, roomVersion, roomID, userID)
|
||||
if err != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(err).Error("checkRestrictedJoin failed")
|
||||
return jsonerror.InternalServerError()
|
||||
|
|
@ -144,7 +144,7 @@ func MakeJoin(
|
|||
}
|
||||
|
||||
queryRes := api.QueryLatestEventsAndStateResponse{
|
||||
RoomVersion: verRes.RoomVersion,
|
||||
RoomVersion: roomVersion,
|
||||
}
|
||||
event, err := eventutil.QueryAndBuildEvent(httpReq.Context(), &builder, cfg.Matrix, identity, time.Now(), rsAPI, &queryRes)
|
||||
if err == eventutil.ErrRoomNoExists {
|
||||
|
|
@ -168,7 +168,7 @@ func MakeJoin(
|
|||
stateEvents[i] = queryRes.StateEvents[i].Event
|
||||
}
|
||||
|
||||
provider := gomatrixserverlib.NewAuthEvents(stateEvents)
|
||||
provider := gomatrixserverlib.NewAuthEvents(gomatrixserverlib.ToPDUs(stateEvents))
|
||||
if err = gomatrixserverlib.Allowed(event.Event, &provider); err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
|
|
@ -180,7 +180,7 @@ func MakeJoin(
|
|||
Code: http.StatusOK,
|
||||
JSON: map[string]interface{}{
|
||||
"event": builder,
|
||||
"room_version": verRes.RoomVersion,
|
||||
"room_version": roomVersion,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -197,21 +197,20 @@ func SendJoin(
|
|||
keys gomatrixserverlib.JSONVerifier,
|
||||
roomID, eventID string,
|
||||
) util.JSONResponse {
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), &verReq, &verRes); err != nil {
|
||||
roomVersion, err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), roomID)
|
||||
if err != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(err).Error("rsAPI.QueryRoomVersionForRoom failed")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
}
|
||||
}
|
||||
verImpl, err := gomatrixserverlib.GetRoomVersion(verRes.RoomVersion)
|
||||
verImpl, err := gomatrixserverlib.GetRoomVersion(roomVersion)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.UnsupportedRoomVersion(
|
||||
fmt.Sprintf("QueryRoomVersionForRoom returned unknown room version: %s", verRes.RoomVersion),
|
||||
fmt.Sprintf("QueryRoomVersionForRoom returned unknown room version: %s", roomVersion),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
@ -415,7 +414,7 @@ func SendJoin(
|
|||
InputRoomEvents: []api.InputRoomEvent{
|
||||
{
|
||||
Kind: api.KindNew,
|
||||
Event: signed.Headered(stateAndAuthChainResponse.RoomVersion),
|
||||
Event: &types.HeaderedEvent{Event: &signed},
|
||||
SendAsServer: string(cfg.Matrix.ServerName),
|
||||
TransactionID: nil,
|
||||
},
|
||||
|
|
@ -445,8 +444,8 @@ func SendJoin(
|
|||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: fclient.RespSendJoin{
|
||||
StateEvents: gomatrixserverlib.NewEventJSONsFromHeaderedEvents(stateAndAuthChainResponse.StateEvents),
|
||||
AuthEvents: gomatrixserverlib.NewEventJSONsFromHeaderedEvents(stateAndAuthChainResponse.AuthChainEvents),
|
||||
StateEvents: types.NewEventJSONsFromHeaderedEvents(stateAndAuthChainResponse.StateEvents),
|
||||
AuthEvents: types.NewEventJSONsFromHeaderedEvents(stateAndAuthChainResponse.AuthChainEvents),
|
||||
Origin: cfg.Matrix.ServerName,
|
||||
Event: signed.JSON(),
|
||||
},
|
||||
|
|
@ -521,7 +520,7 @@ func checkRestrictedJoin(
|
|||
}
|
||||
}
|
||||
|
||||
type eventsByDepth []*gomatrixserverlib.HeaderedEvent
|
||||
type eventsByDepth []*types.HeaderedEvent
|
||||
|
||||
func (e eventsByDepth) Len() int {
|
||||
return len(e)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"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/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
|
|
@ -101,7 +102,7 @@ func MakeLeave(
|
|||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: map[string]interface{}{
|
||||
"room_version": event.RoomVersion,
|
||||
"room_version": event.Version(),
|
||||
"event": state,
|
||||
},
|
||||
}
|
||||
|
|
@ -113,7 +114,7 @@ func MakeLeave(
|
|||
for i := range queryRes.StateEvents {
|
||||
stateEvents[i] = queryRes.StateEvents[i].Event
|
||||
}
|
||||
provider := gomatrixserverlib.NewAuthEvents(stateEvents)
|
||||
provider := gomatrixserverlib.NewAuthEvents(gomatrixserverlib.ToPDUs(stateEvents))
|
||||
if err = gomatrixserverlib.Allowed(event.Event, &provider); err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
|
|
@ -124,7 +125,7 @@ func MakeLeave(
|
|||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: map[string]interface{}{
|
||||
"room_version": event.RoomVersion,
|
||||
"room_version": event.Version(),
|
||||
"event": builder,
|
||||
},
|
||||
}
|
||||
|
|
@ -140,21 +141,20 @@ func SendLeave(
|
|||
keys gomatrixserverlib.JSONVerifier,
|
||||
roomID, eventID string,
|
||||
) util.JSONResponse {
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), &verReq, &verRes); err != nil {
|
||||
roomVersion, err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), roomID)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.UnsupportedRoomVersion(err.Error()),
|
||||
}
|
||||
}
|
||||
|
||||
verImpl, err := gomatrixserverlib.GetRoomVersion(verRes.RoomVersion)
|
||||
verImpl, err := gomatrixserverlib.GetRoomVersion(roomVersion)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.UnsupportedRoomVersion(
|
||||
fmt.Sprintf("QueryRoomVersionForRoom returned unknown version: %s", verRes.RoomVersion),
|
||||
fmt.Sprintf("QueryRoomVersionForRoom returned unknown version: %s", roomVersion),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
@ -313,7 +313,7 @@ func SendLeave(
|
|||
InputRoomEvents: []api.InputRoomEvent{
|
||||
{
|
||||
Kind: api.KindNew,
|
||||
Event: event.Headered(verRes.RoomVersion),
|
||||
Event: &types.HeaderedEvent{Event: event},
|
||||
SendAsServer: string(cfg.Matrix.ServerName),
|
||||
TransactionID: nil,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
|
@ -69,7 +69,7 @@ func GetMissingEvents(
|
|||
eventsResponse.Events = filterEvents(eventsResponse.Events, roomID)
|
||||
|
||||
resp := fclient.RespMissingEvents{
|
||||
Events: gomatrixserverlib.NewEventJSONsFromHeaderedEvents(eventsResponse.Events),
|
||||
Events: types.NewEventJSONsFromHeaderedEvents(eventsResponse.Events),
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
|
|
@ -80,8 +80,8 @@ func GetMissingEvents(
|
|||
|
||||
// filterEvents returns only those events with matching roomID
|
||||
func filterEvents(
|
||||
events []*gomatrixserverlib.HeaderedEvent, roomID string,
|
||||
) []*gomatrixserverlib.HeaderedEvent {
|
||||
events []*types.HeaderedEvent, roomID string,
|
||||
) []*types.HeaderedEvent {
|
||||
ref := events[:0]
|
||||
for _, ev := range events {
|
||||
if ev.RoomID() == roomID {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
|
|
@ -35,10 +36,8 @@ func Peek(
|
|||
remoteVersions []gomatrixserverlib.RoomVersion,
|
||||
) util.JSONResponse {
|
||||
// TODO: check if we're just refreshing an existing peek by querying the federationapi
|
||||
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), &verReq, &verRes); err != nil {
|
||||
roomVersion, err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), roomID)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: jsonerror.InternalServerError(),
|
||||
|
|
@ -50,7 +49,7 @@ func Peek(
|
|||
// the peek URL.
|
||||
remoteSupportsVersion := false
|
||||
for _, v := range remoteVersions {
|
||||
if v == verRes.RoomVersion {
|
||||
if v == roomVersion {
|
||||
remoteSupportsVersion = true
|
||||
break
|
||||
}
|
||||
|
|
@ -59,7 +58,7 @@ func Peek(
|
|||
if !remoteSupportsVersion {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.IncompatibleRoomVersion(verRes.RoomVersion),
|
||||
JSON: jsonerror.IncompatibleRoomVersion(roomVersion),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +68,7 @@ func Peek(
|
|||
renewalInterval := int64(60 * 60 * 1000 * 1000)
|
||||
|
||||
var response api.PerformInboundPeekResponse
|
||||
err := rsAPI.PerformInboundPeek(
|
||||
err = rsAPI.PerformInboundPeek(
|
||||
httpReq.Context(),
|
||||
&api.PerformInboundPeekRequest{
|
||||
RoomID: roomID,
|
||||
|
|
@ -89,10 +88,10 @@ func Peek(
|
|||
}
|
||||
|
||||
respPeek := fclient.RespPeek{
|
||||
StateEvents: gomatrixserverlib.NewEventJSONsFromHeaderedEvents(response.StateEvents),
|
||||
AuthEvents: gomatrixserverlib.NewEventJSONsFromHeaderedEvents(response.AuthChainEvents),
|
||||
StateEvents: types.NewEventJSONsFromHeaderedEvents(response.StateEvents),
|
||||
AuthEvents: types.NewEventJSONsFromHeaderedEvents(response.AuthChainEvents),
|
||||
RoomVersion: response.RoomVersion,
|
||||
LatestEvent: response.LatestEvent.Unwrap(),
|
||||
LatestEvent: response.LatestEvent.Event,
|
||||
RenewalInterval: renewalInterval,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
|
@ -42,8 +42,8 @@ func GetState(
|
|||
}
|
||||
|
||||
return util.JSONResponse{Code: http.StatusOK, JSON: &fclient.RespState{
|
||||
AuthEvents: gomatrixserverlib.NewEventJSONsFromHeaderedEvents(authChain),
|
||||
StateEvents: gomatrixserverlib.NewEventJSONsFromHeaderedEvents(stateEvents),
|
||||
AuthEvents: types.NewEventJSONsFromHeaderedEvents(authChain),
|
||||
StateEvents: types.NewEventJSONsFromHeaderedEvents(stateEvents),
|
||||
}}
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ func getState(
|
|||
rsAPI api.FederationRoomserverAPI,
|
||||
roomID string,
|
||||
eventID string,
|
||||
) (stateEvents, authEvents []*gomatrixserverlib.HeaderedEvent, errRes *util.JSONResponse) {
|
||||
) (stateEvents, authEvents []*types.HeaderedEvent, errRes *util.JSONResponse) {
|
||||
// If we don't think we belong to this room then don't waste the effort
|
||||
// responding to expensive requests for it.
|
||||
if err := ErrorIfLocalServerNotInRoom(ctx, rsAPI, roomID); err != nil {
|
||||
|
|
@ -157,7 +157,7 @@ func getState(
|
|||
return response.StateEvents, response.AuthChainEvents, nil
|
||||
}
|
||||
|
||||
func getIDsFromEvent(events []*gomatrixserverlib.HeaderedEvent) []string {
|
||||
func getIDsFromEvent(events []*types.HeaderedEvent) []string {
|
||||
IDs := make([]string, len(events))
|
||||
for i := range events {
|
||||
IDs[i] = events[i].EventID()
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
|
|
@ -67,11 +68,10 @@ func CreateInvitesFrom3PIDInvites(
|
|||
return *reqErr
|
||||
}
|
||||
|
||||
evs := []*gomatrixserverlib.HeaderedEvent{}
|
||||
evs := []*types.HeaderedEvent{}
|
||||
for _, inv := range body.Invites {
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: inv.RoomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := rsAPI.QueryRoomVersionForRoom(req.Context(), &verReq, &verRes); err != nil {
|
||||
_, err := rsAPI.QueryRoomVersionForRoom(req.Context(), inv.RoomID)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.UnsupportedRoomVersion(err.Error()),
|
||||
|
|
@ -86,7 +86,7 @@ func CreateInvitesFrom3PIDInvites(
|
|||
return jsonerror.InternalServerError()
|
||||
}
|
||||
if event != nil {
|
||||
evs = append(evs, event.Headered(verRes.RoomVersion))
|
||||
evs = append(evs, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -162,9 +162,8 @@ func ExchangeThirdPartyInvite(
|
|||
}
|
||||
}
|
||||
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err = rsAPI.QueryRoomVersionForRoom(httpReq.Context(), &verReq, &verRes); err != nil {
|
||||
roomVersion, err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), roomID)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.UnsupportedRoomVersion(err.Error()),
|
||||
|
|
@ -185,7 +184,7 @@ func ExchangeThirdPartyInvite(
|
|||
|
||||
// Ask the requesting server to sign the newly created event so we know it
|
||||
// acknowledged it
|
||||
inviteReq, err := fclient.NewInviteV2Request(event.Headered(verRes.RoomVersion), nil)
|
||||
inviteReq, err := fclient.NewInviteV2Request(event, nil)
|
||||
if err != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(err).Error("failed to make invite v2 request")
|
||||
return jsonerror.InternalServerError()
|
||||
|
|
@ -195,9 +194,9 @@ func ExchangeThirdPartyInvite(
|
|||
util.GetLogger(httpReq.Context()).WithError(err).Error("federation.SendInvite failed")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
verImpl, err := gomatrixserverlib.GetRoomVersion(verRes.RoomVersion)
|
||||
verImpl, err := gomatrixserverlib.GetRoomVersion(roomVersion)
|
||||
if err != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(err).Errorf("unknown room version: %s", verRes.RoomVersion)
|
||||
util.GetLogger(httpReq.Context()).WithError(err).Errorf("unknown room version: %s", roomVersion)
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
inviteEvent, err := verImpl.NewEventFromUntrustedJSON(signedEvent.Event)
|
||||
|
|
@ -210,8 +209,8 @@ func ExchangeThirdPartyInvite(
|
|||
if err = api.SendEvents(
|
||||
httpReq.Context(), rsAPI,
|
||||
api.KindNew,
|
||||
[]*gomatrixserverlib.HeaderedEvent{
|
||||
inviteEvent.Headered(verRes.RoomVersion),
|
||||
[]*types.HeaderedEvent{
|
||||
{Event: inviteEvent},
|
||||
},
|
||||
request.Destination(),
|
||||
request.Origin(),
|
||||
|
|
@ -239,12 +238,6 @@ func createInviteFrom3PIDInvite(
|
|||
inv invite, federation fclient.FederationClient,
|
||||
userAPI userapi.FederationUserAPI,
|
||||
) (*gomatrixserverlib.Event, error) {
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: inv.RoomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := rsAPI.QueryRoomVersionForRoom(ctx, &verReq, &verRes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, server, err := gomatrixserverlib.SplitID('@', inv.MXID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/federationapi/storage/shared/receipt"
|
||||
"github.com/matrix-org/dendrite/federationapi/types"
|
||||
rstypes "github.com/matrix-org/dendrite/roomserver/types"
|
||||
)
|
||||
|
||||
type Database interface {
|
||||
|
|
@ -38,7 +39,7 @@ type Database interface {
|
|||
|
||||
StoreJSON(ctx context.Context, js string) (*receipt.Receipt, error)
|
||||
|
||||
GetPendingPDUs(ctx context.Context, serverName spec.ServerName, limit int) (pdus map[*receipt.Receipt]*gomatrixserverlib.HeaderedEvent, err error)
|
||||
GetPendingPDUs(ctx context.Context, serverName spec.ServerName, limit int) (pdus map[*receipt.Receipt]*rstypes.HeaderedEvent, err error)
|
||||
GetPendingEDUs(ctx context.Context, serverName spec.ServerName, limit int) (edus map[*receipt.Receipt]*gomatrixserverlib.EDU, err error)
|
||||
|
||||
AssociatePDUWithDestinations(ctx context.Context, destinations map[spec.ServerName]struct{}, dbReceipt *receipt.Receipt) error
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/matrix-org/dendrite/federationapi/storage/shared/receipt"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
)
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ func (d *Database) GetPendingPDUs(
|
|||
serverName spec.ServerName,
|
||||
limit int,
|
||||
) (
|
||||
events map[*receipt.Receipt]*gomatrixserverlib.HeaderedEvent,
|
||||
events map[*receipt.Receipt]*types.HeaderedEvent,
|
||||
err error,
|
||||
) {
|
||||
// Strictly speaking this doesn't need to be using the writer
|
||||
|
|
@ -64,7 +64,7 @@ func (d *Database) GetPendingPDUs(
|
|||
// a guarantee of transactional isolation, it's actually useful
|
||||
// to know in SQLite mode that nothing else is trying to modify
|
||||
// the database.
|
||||
events = make(map[*receipt.Receipt]*gomatrixserverlib.HeaderedEvent)
|
||||
events = make(map[*receipt.Receipt]*types.HeaderedEvent)
|
||||
err = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||
nids, err := d.FederationQueuePDUs.SelectQueuePDUs(ctx, txn, serverName, limit)
|
||||
if err != nil {
|
||||
|
|
@ -87,7 +87,7 @@ func (d *Database) GetPendingPDUs(
|
|||
}
|
||||
|
||||
for nid, blob := range blobs {
|
||||
var event gomatrixserverlib.HeaderedEvent
|
||||
var event types.HeaderedEvent
|
||||
if err := json.Unmarshal(blob, &event); err != nil {
|
||||
return fmt.Errorf("json.Unmarshal: %w", err)
|
||||
}
|
||||
|
|
|
|||
10
go.mod
10
go.mod
|
|
@ -18,11 +18,11 @@ require (
|
|||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/kardianos/minwinsvc v1.0.2
|
||||
github.com/lib/pq v1.10.7
|
||||
github.com/lib/pq v1.10.8
|
||||
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-20220926102614-ceba4d9f7530
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20230424155704-8daeaebaa0bc
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20230428192809-ff52c27efdce
|
||||
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a
|
||||
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
|
|
@ -35,7 +35,7 @@ require (
|
|||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.13.0
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/tidwall/gjson v1.14.4
|
||||
github.com/tidwall/sjson v1.2.5
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible
|
||||
|
|
@ -49,6 +49,7 @@ require (
|
|||
gopkg.in/h2non/bimg.v1 v1.1.9
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gotest.tools/v3 v3.4.0
|
||||
maunium.net/go/mautrix v0.15.1
|
||||
modernc.org/sqlite v1.19.3
|
||||
nhooyr.io/websocket v1.8.7
|
||||
)
|
||||
|
|
@ -93,6 +94,7 @@ require (
|
|||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/klauspost/compress v1.16.0 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/minio/highwayhash v1.0.2 // indirect
|
||||
|
|
@ -117,6 +119,7 @@ require (
|
|||
github.com/quic-go/qtls-go1-20 v0.1.0 // indirect
|
||||
github.com/quic-go/quic-go v0.32.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa // indirect
|
||||
github.com/rs/zerolog v1.29.1 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
|
|
@ -131,6 +134,7 @@ require (
|
|||
gopkg.in/macaroon.v2 v2.1.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
maunium.net/go/maulogger/v2 v2.4.1 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8 // indirect
|
||||
modernc.org/libc v1.21.4 // indirect
|
||||
|
|
|
|||
27
go.sum
27
go.sum
|
|
@ -123,6 +123,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
|||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/codeclysm/extract v2.2.0+incompatible h1:q3wyckoA30bhUSiwdQezMqVhwd8+WGE64/GL//LtUhI=
|
||||
github.com/codeclysm/extract v2.2.0+incompatible/go.mod h1:2nhFMPHiU9At61hz+12bfrlpXSUrOnK+wR+KlGO4Uks=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
@ -188,6 +189,7 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm
|
|||
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
|
|
@ -313,21 +315,25 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.8 h1:3fdt97i/cwSU83+E0hZTC/Xpc9mTZxc6UWSCRcSbxiE=
|
||||
github.com/lib/pq v1.10.8/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e h1:DP5RC0Z3XdyBEW5dKt8YPeN6vZbm6OzVaGVp7f1BQRM=
|
||||
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e/go.mod h1:NgPCr+UavRGH6n5jmdX8DuqFZ4JiCWIJoZiuhTRLSUg=
|
||||
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 h1:s7fexw2QV3YD/fRrzEDPNGgTlJlvXY0EHHnT87wF3OA=
|
||||
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20230424155704-8daeaebaa0bc h1:F73iHhpTZxWVO6qbyGZxd7Ch44v1gK6xNQZ7QVos/Es=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20230424155704-8daeaebaa0bc/go.mod h1:7HTbSZe+CIdmeqVyFMekwD5dFU8khWQyngKATvd12FU=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20230428192809-ff52c27efdce h1:ZdNs5Qj1Cf42GfwUE01oPIZccSiaPJ/HcZP9qxHte8k=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20230428192809-ff52c27efdce/go.mod h1:7HTbSZe+CIdmeqVyFMekwD5dFU8khWQyngKATvd12FU=
|
||||
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a h1:awrPDf9LEFySxTLKYBMCiObelNx/cBuv/wzllvCCH3A=
|
||||
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a/go.mod h1:HchJX9oKMXaT2xYFs0Ha/6Zs06mxLU8k6F1ODnrGkeQ=
|
||||
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=
|
||||
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66/go.mod h1:iBI1foelCqA09JJgPV0FYz4qA5dUXYOxMi57FxKBdd4=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
|
|
@ -430,6 +436,9 @@ github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa/go.mod h1:qq
|
|||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
|
||||
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
|
|
@ -453,8 +462,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
|
|
@ -650,6 +659,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
@ -848,6 +859,10 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
|||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
maunium.net/go/maulogger/v2 v2.4.1 h1:N7zSdd0mZkB2m2JtFUsiGTQQAdP0YeFWT7YMc80yAL8=
|
||||
maunium.net/go/maulogger/v2 v2.4.1/go.mod h1:omPuYwYBILeVQobz8uO3XC8DIRuEb5rXYlQSuqrbCho=
|
||||
maunium.net/go/mautrix v0.15.1 h1:pmCtMjYRpd83+2UL+KTRFYQo5to0373yulimvLK+1k0=
|
||||
maunium.net/go/mautrix v0.15.1/go.mod h1:icQIrvz2NldkRLTuzSGzmaeuMUmw+fzO7UVycPeauN8=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8 h1:0+dsXf0zeLx9ixj4nilg6jKe5Bg1ilzBwSFq4kJmIUc=
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
package caching
|
||||
|
||||
import (
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
// FederationCache contains the subset of functions needed for
|
||||
// a federation event cache.
|
||||
type FederationCache interface {
|
||||
GetFederationQueuedPDU(eventNID int64) (event *gomatrixserverlib.HeaderedEvent, ok bool)
|
||||
StoreFederationQueuedPDU(eventNID int64, event *gomatrixserverlib.HeaderedEvent)
|
||||
GetFederationQueuedPDU(eventNID int64) (event *types.HeaderedEvent, ok bool)
|
||||
StoreFederationQueuedPDU(eventNID int64, event *types.HeaderedEvent)
|
||||
EvictFederationQueuedPDU(eventNID int64)
|
||||
|
||||
GetFederationQueuedEDU(eventNID int64) (event *gomatrixserverlib.EDU, ok bool)
|
||||
|
|
@ -16,11 +17,11 @@ type FederationCache interface {
|
|||
EvictFederationQueuedEDU(eventNID int64)
|
||||
}
|
||||
|
||||
func (c Caches) GetFederationQueuedPDU(eventNID int64) (*gomatrixserverlib.HeaderedEvent, bool) {
|
||||
func (c Caches) GetFederationQueuedPDU(eventNID int64) (*types.HeaderedEvent, bool) {
|
||||
return c.FederationPDUs.Get(eventNID)
|
||||
}
|
||||
|
||||
func (c Caches) StoreFederationQueuedPDU(eventNID int64, event *gomatrixserverlib.HeaderedEvent) {
|
||||
func (c Caches) StoreFederationQueuedPDU(eventNID int64, event *types.HeaderedEvent) {
|
||||
c.FederationPDUs.Set(eventNID, event)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ type Caches struct {
|
|||
RoomServerStateKeyNIDs Cache[string, types.EventStateKeyNID] // event state key -> eventStateKey NID
|
||||
RoomServerEventTypeNIDs Cache[string, types.EventTypeNID] // eventType -> eventType NID
|
||||
RoomServerEventTypes Cache[types.EventTypeNID, string] // eventType NID -> eventType
|
||||
FederationPDUs Cache[int64, *gomatrixserverlib.HeaderedEvent] // queue NID -> PDU
|
||||
FederationPDUs Cache[int64, *types.HeaderedEvent] // queue NID -> PDU
|
||||
FederationEDUs Cache[int64, *gomatrixserverlib.EDU] // queue NID -> EDU
|
||||
SpaceSummaryRooms Cache[string, fclient.MSC2946SpacesResponse] // room ID -> space response
|
||||
LazyLoading Cache[lazyLoadingCacheKey, string] // composite key -> event ID
|
||||
|
|
|
|||
|
|
@ -131,8 +131,8 @@ func NewRistrettoCache(maxCost config.DataUnit, maxAge time.Duration, enableProm
|
|||
Prefix: eventTypeNIDCache,
|
||||
MaxAge: maxAge,
|
||||
},
|
||||
FederationPDUs: &RistrettoCostedCachePartition[int64, *gomatrixserverlib.HeaderedEvent]{ // queue NID -> PDU
|
||||
&RistrettoCachePartition[int64, *gomatrixserverlib.HeaderedEvent]{
|
||||
FederationPDUs: &RistrettoCostedCachePartition[int64, *types.HeaderedEvent]{ // queue NID -> PDU
|
||||
&RistrettoCachePartition[int64, *types.HeaderedEvent]{
|
||||
cache: cache,
|
||||
Prefix: federationPDUsCache,
|
||||
Mutable: true,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
|
|
@ -43,7 +44,7 @@ func QueryAndBuildEvent(
|
|||
builder *gomatrixserverlib.EventBuilder, cfg *config.Global,
|
||||
identity *fclient.SigningIdentity, evTime time.Time,
|
||||
rsAPI api.QueryLatestEventsAndStateAPI, queryRes *api.QueryLatestEventsAndStateResponse,
|
||||
) (*gomatrixserverlib.HeaderedEvent, error) {
|
||||
) (*types.HeaderedEvent, error) {
|
||||
if queryRes == nil {
|
||||
queryRes = &api.QueryLatestEventsAndStateResponse{}
|
||||
}
|
||||
|
|
@ -63,7 +64,7 @@ func BuildEvent(
|
|||
builder *gomatrixserverlib.EventBuilder, cfg *config.Global,
|
||||
identity *fclient.SigningIdentity, evTime time.Time,
|
||||
eventsNeeded *gomatrixserverlib.StateNeeded, queryRes *api.QueryLatestEventsAndStateResponse,
|
||||
) (*gomatrixserverlib.HeaderedEvent, error) {
|
||||
) (*types.HeaderedEvent, error) {
|
||||
if err := addPrevEventsToEvent(builder, eventsNeeded, queryRes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -76,7 +77,7 @@ func BuildEvent(
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return event.Headered(queryRes.RoomVersion), nil
|
||||
return &types.HeaderedEvent{Event: event}, nil
|
||||
}
|
||||
|
||||
// queryRequiredEventsForBuilder queries the roomserver for auth/prev events needed for this builder.
|
||||
|
|
|
|||
|
|
@ -21,17 +21,17 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// KindNewEventPersisted is a hook which is called with *gomatrixserverlib.HeaderedEvent
|
||||
// KindNewEventPersisted is a hook which is called with *types.HeaderedEvent
|
||||
// It is run when a new event is persisted in the roomserver.
|
||||
// Usage:
|
||||
// hooks.Attach(hooks.KindNewEventPersisted, func(headeredEvent interface{}) { ... })
|
||||
KindNewEventPersisted = "new_event_persisted"
|
||||
// KindNewEventReceived is a hook which is called with *gomatrixserverlib.HeaderedEvent
|
||||
// KindNewEventReceived is a hook which is called with *types.HeaderedEvent
|
||||
// It is run before a new event is processed by the roomserver. This hook can be used
|
||||
// to modify the event before it is persisted by adding data to `unsigned`.
|
||||
// Usage:
|
||||
// hooks.Attach(hooks.KindNewEventReceived, func(headeredEvent interface{}) {
|
||||
// ev := headeredEvent.(*gomatrixserverlib.HeaderedEvent)
|
||||
// ev := headeredEvent.(*types.HeaderedEvent)
|
||||
// _ = ev.SetUnsignedField("key", "val")
|
||||
// })
|
||||
KindNewEventReceived = "new_event_received"
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func NewRuleSetEvaluator(ec EvaluationContext, ruleSet *RuleSet) *RuleSetEvaluat
|
|||
|
||||
// MatchEvent returns the first matching rule. Returns nil if there
|
||||
// was no match rule.
|
||||
func (rse *RuleSetEvaluator) MatchEvent(event *gomatrixserverlib.Event) (*Rule, error) {
|
||||
func (rse *RuleSetEvaluator) MatchEvent(event gomatrixserverlib.PDU) (*Rule, error) {
|
||||
// TODO: server-default rules have lower priority than user rules,
|
||||
// but they are stored together with the user rules. It's a bit
|
||||
// unclear what the specification (11.14.1.4 Predefined rules)
|
||||
|
|
@ -83,7 +83,7 @@ func (rse *RuleSetEvaluator) MatchEvent(event *gomatrixserverlib.Event) (*Rule,
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func ruleMatches(rule *Rule, kind Kind, event *gomatrixserverlib.Event, ec EvaluationContext) (bool, error) {
|
||||
func ruleMatches(rule *Rule, kind Kind, event gomatrixserverlib.PDU, ec EvaluationContext) (bool, error) {
|
||||
if !rule.Enabled {
|
||||
return false, nil
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ func ruleMatches(rule *Rule, kind Kind, event *gomatrixserverlib.Event, ec Evalu
|
|||
}
|
||||
}
|
||||
|
||||
func conditionMatches(cond *Condition, event *gomatrixserverlib.Event, ec EvaluationContext) (bool, error) {
|
||||
func conditionMatches(cond *Condition, event gomatrixserverlib.PDU, ec EvaluationContext) (bool, error) {
|
||||
switch cond.Kind {
|
||||
case EventMatchCondition:
|
||||
if cond.Pattern == nil {
|
||||
|
|
@ -150,7 +150,7 @@ func conditionMatches(cond *Condition, event *gomatrixserverlib.Event, ec Evalua
|
|||
}
|
||||
}
|
||||
|
||||
func patternMatches(key, pattern string, event *gomatrixserverlib.Event) (bool, error) {
|
||||
func patternMatches(key, pattern string, event gomatrixserverlib.PDU) (bool, error) {
|
||||
// It doesn't make sense for an empty pattern to match anything.
|
||||
if pattern == "" {
|
||||
return false, nil
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ func TestRuleSetEvaluatorMatchEvent(t *testing.T) {
|
|||
Name string
|
||||
RuleSet RuleSet
|
||||
Want *Rule
|
||||
Event *gomatrixserverlib.Event
|
||||
Event gomatrixserverlib.PDU
|
||||
}{
|
||||
{"empty", RuleSet{}, nil, ev},
|
||||
{"defaultCanWin", RuleSet{Override: []*Rule{defaultEnabled}}, defaultEnabled, ev},
|
||||
|
|
@ -188,7 +188,7 @@ func TestPatternMatches(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func mustEventFromJSON(t *testing.T, json string) *gomatrixserverlib.Event {
|
||||
func mustEventFromJSON(t *testing.T, json string) gomatrixserverlib.PDU {
|
||||
ev, err := gomatrixserverlib.MustGetRoomVersion(gomatrixserverlib.RoomVersionV7).NewEventFromTrustedJSON([]byte(json), false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/federationapi/producers"
|
||||
"github.com/matrix-org/dendrite/federationapi/types"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
rstypes "github.com/matrix-org/dendrite/roomserver/types"
|
||||
syncTypes "github.com/matrix-org/dendrite/syncapi/types"
|
||||
userAPI "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
|
@ -115,14 +116,13 @@ func (t *TxnReq) ProcessTransaction(ctx context.Context) (*fclient.RespSend, *ut
|
|||
if v, ok := roomVersions[roomID]; ok {
|
||||
return v
|
||||
}
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := t.rsAPI.QueryRoomVersionForRoom(ctx, &verReq, &verRes); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Debug("Transaction: Failed to query room version for room", verReq.RoomID)
|
||||
roomVersion, err := t.rsAPI.QueryRoomVersionForRoom(ctx, roomID)
|
||||
if err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Debug("Transaction: Failed to query room version for room", roomID)
|
||||
return ""
|
||||
}
|
||||
roomVersions[roomID] = verRes.RoomVersion
|
||||
return verRes.RoomVersion
|
||||
roomVersions[roomID] = roomVersion
|
||||
return roomVersion
|
||||
}
|
||||
|
||||
for _, pdu := range t.PDUs {
|
||||
|
|
@ -168,7 +168,7 @@ func (t *TxnReq) ProcessTransaction(ctx context.Context) (*fclient.RespSend, *ut
|
|||
}
|
||||
continue
|
||||
}
|
||||
if err = event.VerifyEventSignatures(ctx, t.keys); err != nil {
|
||||
if err = gomatrixserverlib.VerifyEventSignatures(ctx, event, t.keys); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Debugf("Transaction: Couldn't validate signature of event %q", event.EventID())
|
||||
results[event.EventID()] = fclient.PDUResult{
|
||||
Error: err.Error(),
|
||||
|
|
@ -183,8 +183,8 @@ func (t *TxnReq) ProcessTransaction(ctx context.Context) (*fclient.RespSend, *ut
|
|||
ctx,
|
||||
t.rsAPI,
|
||||
api.KindNew,
|
||||
[]*gomatrixserverlib.HeaderedEvent{
|
||||
event.Headered(roomVersion),
|
||||
[]*rstypes.HeaderedEvent{
|
||||
{Event: event},
|
||||
},
|
||||
t.Destination,
|
||||
t.Origin,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/federationapi/producers"
|
||||
rsAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
rstypes "github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||
"github.com/matrix-org/dendrite/setup/process"
|
||||
|
|
@ -59,8 +60,8 @@ var (
|
|||
}
|
||||
testEvent = []byte(`{"auth_events":["$x4MKEPRSF6OGlo0qpnsP3BfSmYX5HhVlykOsQH3ECyg","$BcEcbZnlFLB5rxSNSZNBn6fO3jU/TKAJ79wfKyCQLiU"],"content":{"body":"Test Message"},"depth":3917,"hashes":{"sha256":"cNAWtlHIegrji0mMA6x1rhpYCccY8W1NsWZqSpJFhjs"},"origin":"localhost","origin_server_ts":0,"prev_events":["$4GDB0bVjkWwS3G4noUZCq5oLWzpBYpwzdMcf7gj24CI"],"room_id":"!roomid:localhost","sender":"@userid:localhost","signatures":{"localhost":{"ed25519:auto":"NKym6Kcy3u9mGUr21Hjfe3h7DfDilDhN5PqztT0QZ4NTZ+8Y7owseLolQVXp+TvNjecvzdDywsXXVvGiuQiWAQ"}},"type":"m.room.message"}`)
|
||||
testRoomVersion = gomatrixserverlib.RoomVersionV1
|
||||
testEvents = []*gomatrixserverlib.HeaderedEvent{}
|
||||
testStateEvents = make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent)
|
||||
testEvents = []*rstypes.HeaderedEvent{}
|
||||
testStateEvents = make(map[gomatrixserverlib.StateKeyTuple]*rstypes.HeaderedEvent)
|
||||
)
|
||||
|
||||
type FakeRsAPI struct {
|
||||
|
|
@ -72,14 +73,12 @@ type FakeRsAPI struct {
|
|||
|
||||
func (r *FakeRsAPI) QueryRoomVersionForRoom(
|
||||
ctx context.Context,
|
||||
req *rsAPI.QueryRoomVersionForRoomRequest,
|
||||
res *rsAPI.QueryRoomVersionForRoomResponse,
|
||||
) error {
|
||||
roomID string,
|
||||
) (gomatrixserverlib.RoomVersion, error) {
|
||||
if r.shouldFailQuery {
|
||||
return fmt.Errorf("Failure")
|
||||
return "", fmt.Errorf("Failure")
|
||||
}
|
||||
res.RoomVersion = gomatrixserverlib.RoomVersionV10
|
||||
return nil
|
||||
return gomatrixserverlib.RoomVersionV10, nil
|
||||
}
|
||||
|
||||
func (r *FakeRsAPI) QueryServerBannedFromRoom(
|
||||
|
|
@ -637,7 +636,7 @@ func init() {
|
|||
if err != nil {
|
||||
panic("cannot load test data: " + err.Error())
|
||||
}
|
||||
h := e.Headered(testRoomVersion)
|
||||
h := &rstypes.HeaderedEvent{Event: e}
|
||||
testEvents = append(testEvents, h)
|
||||
if e.StateKey() != nil {
|
||||
testStateEvents[gomatrixserverlib.StateKeyTuple{
|
||||
|
|
@ -722,11 +721,9 @@ func (t *testRoomserverAPI) QueryServerJoinedToRoom(
|
|||
// Asks for the room version for a given room.
|
||||
func (t *testRoomserverAPI) QueryRoomVersionForRoom(
|
||||
ctx context.Context,
|
||||
request *rsAPI.QueryRoomVersionForRoomRequest,
|
||||
response *rsAPI.QueryRoomVersionForRoomResponse,
|
||||
) error {
|
||||
response.RoomVersion = testRoomVersion
|
||||
return nil
|
||||
roomID string,
|
||||
) (gomatrixserverlib.RoomVersion, error) {
|
||||
return testRoomVersion, nil
|
||||
}
|
||||
|
||||
func (t *testRoomserverAPI) QueryServerBannedFromRoom(
|
||||
|
|
@ -781,7 +778,7 @@ NextPDU:
|
|||
}
|
||||
}
|
||||
|
||||
func assertInputRoomEvents(t *testing.T, got []rsAPI.InputRoomEvent, want []*gomatrixserverlib.HeaderedEvent) {
|
||||
func assertInputRoomEvents(t *testing.T, got []rsAPI.InputRoomEvent, want []*rstypes.HeaderedEvent) {
|
||||
for _, g := range got {
|
||||
fmt.Println("GOT ", g.Event.EventID())
|
||||
}
|
||||
|
|
@ -805,7 +802,7 @@ func TestBasicTransaction(t *testing.T) {
|
|||
}
|
||||
txn := mustCreateTransaction(rsAPI, pdus)
|
||||
mustProcessTransaction(t, txn, nil)
|
||||
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []*gomatrixserverlib.HeaderedEvent{testEvents[len(testEvents)-1]})
|
||||
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []*rstypes.HeaderedEvent{testEvents[len(testEvents)-1]})
|
||||
}
|
||||
|
||||
// The purpose of this test is to check that if the event received fails auth checks the event is still sent to the roomserver
|
||||
|
|
@ -818,5 +815,5 @@ func TestTransactionFailAuthChecks(t *testing.T) {
|
|||
txn := mustCreateTransaction(rsAPI, pdus)
|
||||
mustProcessTransaction(t, txn, []string{})
|
||||
// expect message to be sent to the roomserver
|
||||
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []*gomatrixserverlib.HeaderedEvent{testEvents[len(testEvents)-1]})
|
||||
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []*rstypes.HeaderedEvent{testEvents[len(testEvents)-1]})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,11 +101,11 @@ func (r *RelayInternalAPI) QueryTransactions(
|
|||
userID spec.UserID,
|
||||
previousEntry fclient.RelayEntry,
|
||||
) (api.QueryRelayTransactionsResponse, error) {
|
||||
logrus.Infof("QueryTransactions for %s", userID.Raw())
|
||||
logrus.Infof("QueryTransactions for %s", userID.String())
|
||||
if previousEntry.EntryID > 0 {
|
||||
logrus.Infof("Cleaning previous entry (%v) from db for %s",
|
||||
previousEntry.EntryID,
|
||||
userID.Raw(),
|
||||
userID.String(),
|
||||
)
|
||||
prevReceipt := receipt.NewReceipt(previousEntry.EntryID)
|
||||
err := r.db.CleanTransactions(ctx, userID, []*receipt.Receipt{&prevReceipt})
|
||||
|
|
@ -123,12 +123,12 @@ func (r *RelayInternalAPI) QueryTransactions(
|
|||
|
||||
response := api.QueryRelayTransactionsResponse{}
|
||||
if transaction != nil && receipt != nil {
|
||||
logrus.Infof("Obtained transaction (%v) for %s", transaction.TransactionID, userID.Raw())
|
||||
logrus.Infof("Obtained transaction (%v) for %s", transaction.TransactionID, userID.String())
|
||||
response.Transaction = *transaction
|
||||
response.EntryID = receipt.GetNID()
|
||||
response.EntriesQueued = true
|
||||
} else {
|
||||
logrus.Infof("No more entries in the queue for %s", userID.Raw())
|
||||
logrus.Infof("No more entries in the queue for %s", userID.String())
|
||||
response.EntryID = 0
|
||||
response.EntriesQueued = false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func GetTransactionFromRelay(
|
|||
relayAPI api.RelayInternalAPI,
|
||||
userID spec.UserID,
|
||||
) util.JSONResponse {
|
||||
logrus.Infof("Processing relay_txn for %s", userID.Raw())
|
||||
logrus.Infof("Processing relay_txn for %s", userID.String())
|
||||
|
||||
var previousEntry fclient.RelayEntry
|
||||
if err := json.Unmarshal(fedReq.Content(), &previousEntry); err != nil {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ func createQuery(
|
|||
prevEntry fclient.RelayEntry,
|
||||
) fclient.FederationRequest {
|
||||
var federationPathPrefixV1 = "/_matrix/federation/v1"
|
||||
path := federationPathPrefixV1 + "/relay_txn/" + userID.Raw()
|
||||
path := federationPathPrefixV1 + "/relay_txn/" + userID.String()
|
||||
request := fclient.NewFederationRequest("GET", userID.Domain(), "relay", path)
|
||||
request.SetContent(prevEntry)
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ func SendTransactionToRelay(
|
|||
txnID gomatrixserverlib.TransactionID,
|
||||
userID spec.UserID,
|
||||
) util.JSONResponse {
|
||||
logrus.Infof("Processing send_relay for %s", userID.Raw())
|
||||
logrus.Infof("Processing send_relay for %s", userID.String())
|
||||
|
||||
var txnEvents fclient.RelayEvents
|
||||
if err := json.Unmarshal(fedReq.Content(), &txnEvents); err != nil {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func createFederationRequest(
|
|||
content interface{},
|
||||
) fclient.FederationRequest {
|
||||
var federationPathPrefixV1 = "/_matrix/federation/v1"
|
||||
path := federationPathPrefixV1 + "/send_relay/" + string(txnID) + "/" + userID.Raw()
|
||||
path := federationPathPrefixV1 + "/send_relay/" + string(txnID) + "/" + userID.String()
|
||||
request := fclient.NewFederationRequest("PUT", origin, destination, path)
|
||||
request.SetContent(content)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
|
@ -34,7 +35,7 @@ type ServerACLDatabase interface {
|
|||
// GetStateEvent returns the state event of a given type for a given room with a given state key
|
||||
// If no event could be found, returns nil
|
||||
// If there was an issue during the retrieval, returns an error
|
||||
GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error)
|
||||
GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*types.HeaderedEvent, error)
|
||||
}
|
||||
|
||||
type ServerACLs struct {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,25 @@ import (
|
|||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
)
|
||||
|
||||
// ErrInvalidID is an error returned if the userID is invalid
|
||||
type ErrInvalidID struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e ErrInvalidID) Error() string {
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
// ErrNotAllowed is an error returned if the user is not allowed
|
||||
// to execute some action (e.g. invite)
|
||||
type ErrNotAllowed struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e ErrNotAllowed) Error() string {
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
// RoomserverInputAPI is used to write events to the room server.
|
||||
type RoomserverInternalAPI interface {
|
||||
SyncRoomserverAPI
|
||||
|
|
@ -102,7 +121,7 @@ type SyncRoomserverAPI interface {
|
|||
) error
|
||||
|
||||
// QueryMembershipAtEvent queries the memberships at the given events.
|
||||
// Returns a map from eventID to a slice of gomatrixserverlib.HeaderedEvent.
|
||||
// Returns a map from eventID to a slice of types.HeaderedEvent.
|
||||
QueryMembershipAtEvent(
|
||||
ctx context.Context,
|
||||
request *QueryMembershipAtEventRequest,
|
||||
|
|
@ -143,24 +162,24 @@ type ClientRoomserverAPI interface {
|
|||
QueryStateAfterEvents(ctx context.Context, req *QueryStateAfterEventsRequest, res *QueryStateAfterEventsResponse) error
|
||||
// QueryKnownUsers returns a list of users that we know about from our joined rooms.
|
||||
QueryKnownUsers(ctx context.Context, req *QueryKnownUsersRequest, res *QueryKnownUsersResponse) error
|
||||
QueryRoomVersionForRoom(ctx context.Context, req *QueryRoomVersionForRoomRequest, res *QueryRoomVersionForRoomResponse) error
|
||||
QueryRoomVersionForRoom(ctx context.Context, roomID string) (gomatrixserverlib.RoomVersion, error)
|
||||
QueryPublishedRooms(ctx context.Context, req *QueryPublishedRoomsRequest, res *QueryPublishedRoomsResponse) error
|
||||
|
||||
GetRoomIDForAlias(ctx context.Context, req *GetRoomIDForAliasRequest, res *GetRoomIDForAliasResponse) error
|
||||
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) error
|
||||
PerformAdminEvacuateRoom(ctx context.Context, req *PerformAdminEvacuateRoomRequest, res *PerformAdminEvacuateRoomResponse) error
|
||||
PerformAdminEvacuateUser(ctx context.Context, req *PerformAdminEvacuateUserRequest, res *PerformAdminEvacuateUserResponse) error
|
||||
PerformAdminPurgeRoom(ctx context.Context, req *PerformAdminPurgeRoomRequest, res *PerformAdminPurgeRoomResponse) error
|
||||
PerformAdminDownloadState(ctx context.Context, req *PerformAdminDownloadStateRequest, res *PerformAdminDownloadStateResponse) 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) error
|
||||
PerformRoomUpgrade(ctx context.Context, roomID, userID string, roomVersion gomatrixserverlib.RoomVersion) (newRoomID string, err error)
|
||||
PerformAdminEvacuateRoom(ctx context.Context, roomID string) (affected []string, err error)
|
||||
PerformAdminEvacuateUser(ctx context.Context, userID string) (affected []string, err error)
|
||||
PerformAdminPurgeRoom(ctx context.Context, roomID string) error
|
||||
PerformAdminDownloadState(ctx context.Context, roomID, userID string, serverName spec.ServerName) error
|
||||
PerformPeek(ctx context.Context, req *PerformPeekRequest) (roomID string, err error)
|
||||
PerformUnpeek(ctx context.Context, roomID, userID, deviceID string) error
|
||||
PerformInvite(ctx context.Context, req *PerformInviteRequest) error
|
||||
PerformJoin(ctx context.Context, req *PerformJoinRequest) (roomID string, joinedVia spec.ServerName, err error)
|
||||
PerformLeave(ctx context.Context, req *PerformLeaveRequest, res *PerformLeaveResponse) error
|
||||
PerformPublish(ctx context.Context, req *PerformPublishRequest, res *PerformPublishResponse) error
|
||||
PerformPublish(ctx context.Context, req *PerformPublishRequest) 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
|
||||
|
|
@ -172,8 +191,8 @@ type UserRoomserverAPI interface {
|
|||
KeyserverRoomserverAPI
|
||||
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) error
|
||||
PerformJoin(ctx context.Context, req *PerformJoinRequest, res *PerformJoinResponse) error
|
||||
PerformAdminEvacuateUser(ctx context.Context, userID string) (affected []string, err error)
|
||||
PerformJoin(ctx context.Context, req *PerformJoinRequest) (roomID string, joinedVia spec.ServerName, err error)
|
||||
}
|
||||
|
||||
type FederationRoomserverAPI interface {
|
||||
|
|
@ -183,7 +202,7 @@ type FederationRoomserverAPI interface {
|
|||
// QueryServerBannedFromRoom returns whether a server is banned from a room by server ACLs.
|
||||
QueryServerBannedFromRoom(ctx context.Context, req *QueryServerBannedFromRoomRequest, res *QueryServerBannedFromRoomResponse) error
|
||||
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
|
||||
QueryRoomVersionForRoom(ctx context.Context, req *QueryRoomVersionForRoomRequest, res *QueryRoomVersionForRoomResponse) error
|
||||
QueryRoomVersionForRoom(ctx context.Context, roomID string) (gomatrixserverlib.RoomVersion, error)
|
||||
GetRoomIDForAlias(ctx context.Context, req *GetRoomIDForAliasRequest, res *GetRoomIDForAliasResponse) error
|
||||
// QueryEventsByID queries a list of events by event ID for one room. If no room is specified, it will try to determine
|
||||
// which room to use by querying the first events roomID.
|
||||
|
|
@ -202,7 +221,7 @@ type FederationRoomserverAPI interface {
|
|||
QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error
|
||||
QueryRestrictedJoinAllowed(ctx context.Context, req *QueryRestrictedJoinAllowedRequest, res *QueryRestrictedJoinAllowedResponse) error
|
||||
PerformInboundPeek(ctx context.Context, req *PerformInboundPeekRequest, res *PerformInboundPeekResponse) error
|
||||
PerformInvite(ctx context.Context, req *PerformInviteRequest, res *PerformInviteResponse) error
|
||||
PerformInvite(ctx context.Context, req *PerformInviteRequest) error
|
||||
// Query a given amount (or less) of events prior to a given set of events.
|
||||
PerformBackfill(ctx context.Context, req *PerformBackfillRequest, res *PerformBackfillResponse) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package api
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
)
|
||||
|
|
@ -67,7 +68,7 @@ type InputRoomEvent struct {
|
|||
// This controls how the event is processed.
|
||||
Kind Kind `json:"kind"`
|
||||
// The event JSON for the event to add.
|
||||
Event *gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
Event *types.HeaderedEvent `json:"event"`
|
||||
// Which server told us about this event.
|
||||
Origin spec.ServerName `json:"origin"`
|
||||
// Whether the state is supplied as a list of event IDs or whether it
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
)
|
||||
|
|
@ -107,7 +108,7 @@ const (
|
|||
// prev_events.
|
||||
type OutputNewRoomEvent struct {
|
||||
// The Event.
|
||||
Event *gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
Event *types.HeaderedEvent `json:"event"`
|
||||
// Does the event completely rewrite the room state? If so, then AddsStateEventIDs
|
||||
// will contain the entire room state.
|
||||
RewritesState bool `json:"rewrites_state,omitempty"`
|
||||
|
|
@ -170,8 +171,8 @@ type OutputNewRoomEvent struct {
|
|||
HistoryVisibility gomatrixserverlib.HistoryVisibility `json:"history_visibility"`
|
||||
}
|
||||
|
||||
func (o *OutputNewRoomEvent) NeededStateEventIDs() ([]*gomatrixserverlib.HeaderedEvent, []string) {
|
||||
addsStateEvents := make([]*gomatrixserverlib.HeaderedEvent, 0, 1)
|
||||
func (o *OutputNewRoomEvent) NeededStateEventIDs() ([]*types.HeaderedEvent, []string) {
|
||||
addsStateEvents := make([]*types.HeaderedEvent, 0, 1)
|
||||
missingEventIDs := make([]string, 0, len(o.AddsStateEventIDs))
|
||||
for _, eventID := range o.AddsStateEventIDs {
|
||||
if eventID != o.Event.EventID() {
|
||||
|
|
@ -194,7 +195,7 @@ func (o *OutputNewRoomEvent) NeededStateEventIDs() ([]*gomatrixserverlib.Headere
|
|||
// should build their current room state up from OutputNewRoomEvents only.
|
||||
type OutputOldRoomEvent struct {
|
||||
// The Event.
|
||||
Event *gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
Event *types.HeaderedEvent `json:"event"`
|
||||
HistoryVisibility gomatrixserverlib.HistoryVisibility `json:"history_visibility"`
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +206,7 @@ type OutputNewInviteEvent struct {
|
|||
// The room version of the invited room.
|
||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
// The "m.room.member" invite event.
|
||||
Event *gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
Event *types.HeaderedEvent `json:"event"`
|
||||
}
|
||||
|
||||
// An OutputRetireInviteEvent is written whenever an existing invite is no longer
|
||||
|
|
@ -232,7 +233,7 @@ type OutputRedactedEvent struct {
|
|||
// The event ID that was redacted
|
||||
RedactedEventID string
|
||||
// The value of `unsigned.redacted_because` - the redaction event itself
|
||||
RedactedBecause *gomatrixserverlib.HeaderedEvent
|
||||
RedactedBecause *types.HeaderedEvent
|
||||
}
|
||||
|
||||
// An OutputNewPeek is written whenever a user starts peeking into a room
|
||||
|
|
|
|||
|
|
@ -1,80 +1,11 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/matrix-org/util"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
)
|
||||
|
||||
type PerformErrorCode int
|
||||
|
||||
type PerformError struct {
|
||||
Msg string
|
||||
RemoteCode int // remote HTTP status code, for PerformErrRemote
|
||||
Code PerformErrorCode
|
||||
}
|
||||
|
||||
func (p *PerformError) Error() string {
|
||||
return fmt.Sprintf("%d : %s", p.Code, p.Msg)
|
||||
}
|
||||
|
||||
// JSONResponse maps error codes to suitable HTTP error codes, defaulting to 500.
|
||||
func (p *PerformError) JSONResponse() util.JSONResponse {
|
||||
switch p.Code {
|
||||
case PerformErrorBadRequest:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.Unknown(p.Msg),
|
||||
}
|
||||
case PerformErrorNoRoom:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
JSON: jsonerror.NotFound(p.Msg),
|
||||
}
|
||||
case PerformErrorNotAllowed:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden(p.Msg),
|
||||
}
|
||||
case PerformErrorNoOperation:
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden(p.Msg),
|
||||
}
|
||||
case PerformErrRemote:
|
||||
// if the code is 0 then something bad happened and it isn't
|
||||
// a remote HTTP error being encapsulated, e.g network error to remote.
|
||||
if p.RemoteCode == 0 {
|
||||
return util.ErrorResponse(fmt.Errorf("%s", p.Msg))
|
||||
}
|
||||
return util.JSONResponse{
|
||||
Code: p.RemoteCode,
|
||||
// TODO: Should we assert this is in fact JSON? E.g gjson parse?
|
||||
JSON: json.RawMessage(p.Msg),
|
||||
}
|
||||
default:
|
||||
return util.ErrorResponse(p)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
// PerformErrorNotAllowed means the user is not allowed to invite/join/etc this room (e.g join_rule:invite or banned)
|
||||
PerformErrorNotAllowed PerformErrorCode = 1
|
||||
// PerformErrorBadRequest means the request was wrong in some way (invalid user ID, wrong server, etc)
|
||||
PerformErrorBadRequest PerformErrorCode = 2
|
||||
// PerformErrorNoRoom means that the room being joined doesn't exist.
|
||||
PerformErrorNoRoom PerformErrorCode = 3
|
||||
// PerformErrorNoOperation means that the request resulted in nothing happening e.g invite->invite or leave->leave.
|
||||
PerformErrorNoOperation PerformErrorCode = 4
|
||||
// PerformErrRemote means that the request failed and the PerformError.Msg is the raw remote JSON error response
|
||||
PerformErrRemote PerformErrorCode = 5
|
||||
)
|
||||
|
||||
type PerformJoinRequest struct {
|
||||
|
|
@ -86,14 +17,6 @@ type PerformJoinRequest struct {
|
|||
Unsigned map[string]interface{} `json:"unsigned"`
|
||||
}
|
||||
|
||||
type PerformJoinResponse struct {
|
||||
// The room ID, populated on success.
|
||||
RoomID string `json:"room_id"`
|
||||
JoinedVia spec.ServerName
|
||||
// If non-nil, the join request failed. Contains more information why it failed.
|
||||
Error *PerformError
|
||||
}
|
||||
|
||||
type PerformLeaveRequest struct {
|
||||
RoomID string `json:"room_id"`
|
||||
UserID string `json:"user_id"`
|
||||
|
|
@ -105,15 +28,11 @@ type PerformLeaveResponse struct {
|
|||
}
|
||||
|
||||
type PerformInviteRequest struct {
|
||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
Event *gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
InviteRoomState []fclient.InviteV2StrippedState `json:"invite_room_state"`
|
||||
SendAsServer string `json:"send_as_server"`
|
||||
TransactionID *TransactionID `json:"transaction_id"`
|
||||
}
|
||||
|
||||
type PerformInviteResponse struct {
|
||||
Error *PerformError
|
||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
Event *types.HeaderedEvent `json:"event"`
|
||||
InviteRoomState []fclient.InviteV2StrippedState `json:"invite_room_state"`
|
||||
SendAsServer string `json:"send_as_server"`
|
||||
TransactionID *TransactionID `json:"transaction_id"`
|
||||
}
|
||||
|
||||
type PerformPeekRequest struct {
|
||||
|
|
@ -123,24 +42,6 @@ type PerformPeekRequest struct {
|
|||
ServerNames []spec.ServerName `json:"server_names"`
|
||||
}
|
||||
|
||||
type PerformPeekResponse struct {
|
||||
// The room ID, populated on success.
|
||||
RoomID string `json:"room_id"`
|
||||
// If non-nil, the join request failed. Contains more information why it failed.
|
||||
Error *PerformError
|
||||
}
|
||||
|
||||
type PerformUnpeekRequest struct {
|
||||
RoomID string `json:"room_id"`
|
||||
UserID string `json:"user_id"`
|
||||
DeviceID string `json:"device_id"`
|
||||
}
|
||||
|
||||
type PerformUnpeekResponse struct {
|
||||
// If non-nil, the join request failed. Contains more information why it failed.
|
||||
Error *PerformError
|
||||
}
|
||||
|
||||
// PerformBackfillRequest is a request to PerformBackfill.
|
||||
type PerformBackfillRequest struct {
|
||||
// The room to backfill
|
||||
|
|
@ -168,7 +69,7 @@ func (r *PerformBackfillRequest) PrevEventIDs() []string {
|
|||
// PerformBackfillResponse is a response to PerformBackfill.
|
||||
type PerformBackfillResponse struct {
|
||||
// Missing events, arbritrary order.
|
||||
Events []*gomatrixserverlib.HeaderedEvent `json:"events"`
|
||||
Events []*types.HeaderedEvent `json:"events"`
|
||||
HistoryVisibility gomatrixserverlib.HistoryVisibility `json:"history_visibility"`
|
||||
}
|
||||
|
||||
|
|
@ -179,11 +80,6 @@ type PerformPublishRequest struct {
|
|||
NetworkID string
|
||||
}
|
||||
|
||||
type PerformPublishResponse struct {
|
||||
// If non-nil, the publish request failed. Contains more information why it failed.
|
||||
Error *PerformError
|
||||
}
|
||||
|
||||
type PerformInboundPeekRequest struct {
|
||||
UserID string `json:"user_id"`
|
||||
RoomID string `json:"room_id"`
|
||||
|
|
@ -200,10 +96,10 @@ type PerformInboundPeekResponse struct {
|
|||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
// The current state and auth chain events.
|
||||
// The lists will be in an arbitrary order.
|
||||
StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"`
|
||||
AuthChainEvents []*gomatrixserverlib.HeaderedEvent `json:"auth_chain_events"`
|
||||
StateEvents []*types.HeaderedEvent `json:"state_events"`
|
||||
AuthChainEvents []*types.HeaderedEvent `json:"auth_chain_events"`
|
||||
// The event at which this state was captured
|
||||
LatestEvent *gomatrixserverlib.HeaderedEvent `json:"latest_event"`
|
||||
LatestEvent *types.HeaderedEvent `json:"latest_event"`
|
||||
}
|
||||
|
||||
// PerformForgetRequest is a request to PerformForget
|
||||
|
|
@ -213,50 +109,3 @@ type PerformForgetRequest struct {
|
|||
}
|
||||
|
||||
type PerformForgetResponse struct{}
|
||||
|
||||
type PerformRoomUpgradeRequest struct {
|
||||
RoomID string `json:"room_id"`
|
||||
UserID string `json:"user_id"`
|
||||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
}
|
||||
|
||||
type PerformRoomUpgradeResponse struct {
|
||||
NewRoomID string
|
||||
Error *PerformError
|
||||
}
|
||||
|
||||
type PerformAdminEvacuateRoomRequest struct {
|
||||
RoomID string `json:"room_id"`
|
||||
}
|
||||
|
||||
type PerformAdminEvacuateRoomResponse struct {
|
||||
Affected []string `json:"affected"`
|
||||
Error *PerformError
|
||||
}
|
||||
|
||||
type PerformAdminEvacuateUserRequest struct {
|
||||
UserID string `json:"user_id"`
|
||||
}
|
||||
|
||||
type PerformAdminEvacuateUserResponse struct {
|
||||
Affected []string `json:"affected"`
|
||||
Error *PerformError
|
||||
}
|
||||
|
||||
type PerformAdminPurgeRoomRequest struct {
|
||||
RoomID string `json:"room_id"`
|
||||
}
|
||||
|
||||
type PerformAdminPurgeRoomResponse struct {
|
||||
Error *PerformError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type PerformAdminDownloadStateRequest struct {
|
||||
RoomID string `json:"room_id"`
|
||||
UserID string `json:"user_id"`
|
||||
ServerName spec.ServerName `json:"server_name"`
|
||||
}
|
||||
|
||||
type PerformAdminDownloadStateResponse struct {
|
||||
Error *PerformError `json:"error,omitempty"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/syncapi/synctypes"
|
||||
)
|
||||
|
||||
|
|
@ -53,7 +54,7 @@ type QueryLatestEventsAndStateResponse struct {
|
|||
// This list will be in an arbitrary order.
|
||||
// These are used to set the auth_events when sending an event.
|
||||
// These are used to check whether the event is allowed.
|
||||
StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"`
|
||||
StateEvents []*types.HeaderedEvent `json:"state_events"`
|
||||
// The depth of the latest events.
|
||||
// This is one greater than the maximum depth of the latest events.
|
||||
// This is used to set the depth when sending an event.
|
||||
|
|
@ -83,7 +84,7 @@ type QueryStateAfterEventsResponse struct {
|
|||
PrevEventsExist bool `json:"prev_events_exist"`
|
||||
// The state events requested.
|
||||
// This list will be in an arbitrary order.
|
||||
StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"`
|
||||
StateEvents []*types.HeaderedEvent `json:"state_events"`
|
||||
}
|
||||
|
||||
// QueryEventsByIDRequest is a request to QueryEventsByID
|
||||
|
|
@ -104,7 +105,7 @@ type QueryEventsByIDResponse struct {
|
|||
// fails to read it from the database then it will fail
|
||||
// the entire request.
|
||||
// This list will be in an arbitrary order.
|
||||
Events []*gomatrixserverlib.HeaderedEvent `json:"events"`
|
||||
Events []*types.HeaderedEvent `json:"events"`
|
||||
}
|
||||
|
||||
// QueryMembershipForUserRequest is a request to QueryMembership
|
||||
|
|
@ -202,7 +203,7 @@ type QueryMissingEventsRequest struct {
|
|||
// QueryMissingEventsResponse is a response to QueryMissingEvents
|
||||
type QueryMissingEventsResponse struct {
|
||||
// Missing events, arbritrary order.
|
||||
Events []*gomatrixserverlib.HeaderedEvent `json:"events"`
|
||||
Events []*types.HeaderedEvent `json:"events"`
|
||||
}
|
||||
|
||||
// QueryStateAndAuthChainRequest is a request to QueryStateAndAuthChain
|
||||
|
|
@ -236,8 +237,8 @@ type QueryStateAndAuthChainResponse struct {
|
|||
StateKnown bool `json:"state_known"`
|
||||
// The state and auth chain events that were requested.
|
||||
// The lists will be in an arbitrary order.
|
||||
StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"`
|
||||
AuthChainEvents []*gomatrixserverlib.HeaderedEvent `json:"auth_chain_events"`
|
||||
StateEvents []*types.HeaderedEvent `json:"state_events"`
|
||||
AuthChainEvents []*types.HeaderedEvent `json:"auth_chain_events"`
|
||||
// True if the queried event was rejected earlier.
|
||||
IsRejected bool `json:"is_rejected"`
|
||||
}
|
||||
|
|
@ -269,7 +270,7 @@ type QueryAuthChainRequest struct {
|
|||
}
|
||||
|
||||
type QueryAuthChainResponse struct {
|
||||
AuthChain []*gomatrixserverlib.HeaderedEvent
|
||||
AuthChain []*types.HeaderedEvent
|
||||
}
|
||||
|
||||
type QuerySharedUsersRequest struct {
|
||||
|
|
@ -327,7 +328,7 @@ type QueryCurrentStateRequest struct {
|
|||
}
|
||||
|
||||
type QueryCurrentStateResponse struct {
|
||||
StateEvents map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent
|
||||
StateEvents map[gomatrixserverlib.StateKeyTuple]*types.HeaderedEvent
|
||||
}
|
||||
|
||||
type QueryKnownUsersRequest struct {
|
||||
|
|
@ -404,7 +405,7 @@ func (r *QueryBulkStateContentResponse) UnmarshalJSON(data []byte) error {
|
|||
|
||||
// MarshalJSON stringifies the StateKeyTuple keys so they can be sent over the wire in HTTP API mode.
|
||||
func (r *QueryCurrentStateResponse) MarshalJSON() ([]byte, error) {
|
||||
se := make(map[string]*gomatrixserverlib.HeaderedEvent, len(r.StateEvents))
|
||||
se := make(map[string]*types.HeaderedEvent, len(r.StateEvents))
|
||||
for k, v := range r.StateEvents {
|
||||
// use 0x1F (unit separator) as the delimiter between type/state key,
|
||||
se[fmt.Sprintf("%s\x1F%s", k.EventType, k.StateKey)] = v
|
||||
|
|
@ -413,12 +414,12 @@ func (r *QueryCurrentStateResponse) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
func (r *QueryCurrentStateResponse) UnmarshalJSON(data []byte) error {
|
||||
res := make(map[string]*gomatrixserverlib.HeaderedEvent)
|
||||
res := make(map[string]*types.HeaderedEvent)
|
||||
err := json.Unmarshal(data, &res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.StateEvents = make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent, len(res))
|
||||
r.StateEvents = make(map[gomatrixserverlib.StateKeyTuple]*types.HeaderedEvent, len(res))
|
||||
for k, v := range res {
|
||||
fields := strings.Split(k, "\x1F")
|
||||
r.StateEvents[gomatrixserverlib.StateKeyTuple{
|
||||
|
|
@ -442,7 +443,7 @@ type QueryMembershipAtEventResponse struct {
|
|||
// Membership is a map from eventID to membership event. Events that
|
||||
// do not have known state will return a nil event, resulting in a "leave" membership
|
||||
// when calculating history visibility.
|
||||
Membership map[string]*gomatrixserverlib.HeaderedEvent `json:"membership"`
|
||||
Membership map[string]*types.HeaderedEvent `json:"membership"`
|
||||
}
|
||||
|
||||
// QueryLeftUsersRequest is a request to calculate users that we (the server) don't share a
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ package api
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
|
|
@ -27,7 +28,7 @@ import (
|
|||
// SendEvents to the roomserver The events are written with KindNew.
|
||||
func SendEvents(
|
||||
ctx context.Context, rsAPI InputRoomEventsAPI,
|
||||
kind Kind, events []*gomatrixserverlib.HeaderedEvent,
|
||||
kind Kind, events []*types.HeaderedEvent,
|
||||
virtualHost, origin spec.ServerName,
|
||||
sendAsServer spec.ServerName, txnID *TransactionID,
|
||||
async bool,
|
||||
|
|
@ -51,10 +52,11 @@ func SendEvents(
|
|||
func SendEventWithState(
|
||||
ctx context.Context, rsAPI InputRoomEventsAPI,
|
||||
virtualHost spec.ServerName, kind Kind,
|
||||
state gomatrixserverlib.StateResponse, event *gomatrixserverlib.HeaderedEvent,
|
||||
state gomatrixserverlib.StateResponse, event *types.HeaderedEvent,
|
||||
origin spec.ServerName, haveEventIDs map[string]bool, async bool,
|
||||
) error {
|
||||
outliers := gomatrixserverlib.LineariseStateResponse(event.RoomVersion, state)
|
||||
outliersPDU := gomatrixserverlib.LineariseStateResponse(event.Version(), state)
|
||||
outliers := gomatrixserverlib.TempCastToEvents(outliersPDU)
|
||||
ires := make([]InputRoomEvent, 0, len(outliers))
|
||||
for _, outlier := range outliers {
|
||||
if haveEventIDs[outlier.EventID()] {
|
||||
|
|
@ -62,12 +64,12 @@ func SendEventWithState(
|
|||
}
|
||||
ires = append(ires, InputRoomEvent{
|
||||
Kind: KindOutlier,
|
||||
Event: outlier.Headered(event.RoomVersion),
|
||||
Event: &types.HeaderedEvent{Event: outlier},
|
||||
Origin: origin,
|
||||
})
|
||||
}
|
||||
|
||||
stateEvents := state.GetStateEvents().UntrustedEvents(event.RoomVersion)
|
||||
stateEvents := state.GetStateEvents().UntrustedEvents(event.Version())
|
||||
stateEventIDs := make([]string, len(stateEvents))
|
||||
for i := range stateEvents {
|
||||
stateEventIDs[i] = stateEvents[i].EventID()
|
||||
|
|
@ -110,7 +112,7 @@ func SendInputRoomEvents(
|
|||
}
|
||||
|
||||
// GetEvent returns the event or nil, even on errors.
|
||||
func GetEvent(ctx context.Context, rsAPI QueryEventsAPI, roomID, eventID string) *gomatrixserverlib.HeaderedEvent {
|
||||
func GetEvent(ctx context.Context, rsAPI QueryEventsAPI, roomID, eventID string) *types.HeaderedEvent {
|
||||
var res QueryEventsByIDResponse
|
||||
err := rsAPI.QueryEventsByID(ctx, &QueryEventsByIDRequest{
|
||||
RoomID: roomID,
|
||||
|
|
@ -127,7 +129,7 @@ func GetEvent(ctx context.Context, rsAPI QueryEventsAPI, roomID, eventID string)
|
|||
}
|
||||
|
||||
// GetStateEvent returns the current state event in the room or nil.
|
||||
func GetStateEvent(ctx context.Context, rsAPI QueryEventsAPI, roomID string, tuple gomatrixserverlib.StateKeyTuple) *gomatrixserverlib.HeaderedEvent {
|
||||
func GetStateEvent(ctx context.Context, rsAPI QueryEventsAPI, roomID string, tuple gomatrixserverlib.StateKeyTuple) *types.HeaderedEvent {
|
||||
var res QueryCurrentStateResponse
|
||||
err := rsAPI.QueryCurrentState(ctx, &QueryCurrentStateRequest{
|
||||
RoomID: roomID,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ func IsServerAllowed(
|
|||
serverCurrentlyInRoom bool,
|
||||
authEvents []*gomatrixserverlib.Event,
|
||||
) bool {
|
||||
// In practice should not happen, but avoids unneeded CPU cycles
|
||||
if serverName == "" || len(authEvents) == 0 {
|
||||
return false
|
||||
}
|
||||
historyVisibility := HistoryVisibilityForRoom(authEvents)
|
||||
|
||||
// 1. If the history_visibility was set to world_readable, allow.
|
||||
|
|
|
|||
85
roomserver/auth/auth_test.go
Normal file
85
roomserver/auth/auth_test.go
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/matrix-org/dendrite/test"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
)
|
||||
|
||||
func TestIsServerAllowed(t *testing.T) {
|
||||
alice := test.NewUser(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
want bool
|
||||
roomFunc func() *test.Room
|
||||
serverName spec.ServerName
|
||||
serverCurrentlyInRoom bool
|
||||
}{
|
||||
{
|
||||
name: "no servername specified",
|
||||
roomFunc: func() *test.Room { return test.NewRoom(t, alice) },
|
||||
},
|
||||
{
|
||||
name: "no authEvents specified",
|
||||
serverName: "test",
|
||||
roomFunc: func() *test.Room { return &test.Room{} },
|
||||
},
|
||||
{
|
||||
name: "default denied",
|
||||
serverName: "test2",
|
||||
roomFunc: func() *test.Room { return test.NewRoom(t, alice) },
|
||||
},
|
||||
{
|
||||
name: "world readable room",
|
||||
serverName: "test",
|
||||
roomFunc: func() *test.Room {
|
||||
return test.NewRoom(t, alice, test.RoomHistoryVisibility(gomatrixserverlib.HistoryVisibilityWorldReadable))
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "allowed due to alice being joined",
|
||||
serverName: "test",
|
||||
roomFunc: func() *test.Room { return test.NewRoom(t, alice) },
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "allowed due to 'serverCurrentlyInRoom'",
|
||||
serverName: "test2",
|
||||
roomFunc: func() *test.Room { return test.NewRoom(t, alice) },
|
||||
want: true,
|
||||
serverCurrentlyInRoom: true,
|
||||
},
|
||||
{
|
||||
name: "allowed due to pending invite",
|
||||
serverName: "test2",
|
||||
roomFunc: func() *test.Room {
|
||||
bob := test.User{ID: "@bob:test2"}
|
||||
r := test.NewRoom(t, alice, test.RoomHistoryVisibility(gomatrixserverlib.HistoryVisibilityInvited))
|
||||
r.CreateAndInsert(t, alice, spec.MRoomMember, map[string]interface{}{
|
||||
"membership": spec.Invite,
|
||||
}, test.WithStateKey(bob.ID))
|
||||
return r
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.roomFunc == nil {
|
||||
t.Fatalf("missing roomFunc")
|
||||
}
|
||||
var authEvents []*gomatrixserverlib.Event
|
||||
for _, ev := range tt.roomFunc().Events() {
|
||||
authEvents = append(authEvents, ev.Event)
|
||||
}
|
||||
|
||||
if got := IsServerAllowed(tt.serverName, tt.serverCurrentlyInRoom, authEvents); got != tt.want {
|
||||
t.Errorf("IsServerAllowed() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/tidwall/gjson"
|
||||
|
|
@ -140,7 +141,7 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias(
|
|||
}
|
||||
|
||||
if creatorID != request.UserID {
|
||||
var plEvent *gomatrixserverlib.HeaderedEvent
|
||||
var plEvent *types.HeaderedEvent
|
||||
var pls *gomatrixserverlib.PowerLevelContent
|
||||
|
||||
plEvent, err = r.DB.GetStateEvent(ctx, roomID, spec.MRoomPowerLevels, "")
|
||||
|
|
@ -212,7 +213,7 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias(
|
|||
return err
|
||||
}
|
||||
|
||||
err = api.SendEvents(ctx, r, api.KindNew, []*gomatrixserverlib.HeaderedEvent{newEvent}, virtualHost, r.ServerName, r.ServerName, nil, false)
|
||||
err = api.SendEvents(ctx, r, api.KindNew, []*types.HeaderedEvent{newEvent}, virtualHost, r.ServerName, r.ServerName, nil, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,11 +209,9 @@ func (r *RoomserverInternalAPI) SetAppserviceAPI(asAPI asAPI.AppServiceInternalA
|
|||
func (r *RoomserverInternalAPI) PerformInvite(
|
||||
ctx context.Context,
|
||||
req *api.PerformInviteRequest,
|
||||
res *api.PerformInviteResponse,
|
||||
) error {
|
||||
outputEvents, err := r.Inviter.PerformInvite(ctx, req, res)
|
||||
outputEvents, err := r.Inviter.PerformInvite(ctx, req)
|
||||
if err != nil {
|
||||
sentry.CaptureException(err)
|
||||
return err
|
||||
}
|
||||
if len(outputEvents) == 0 {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func CheckForSoftFail(
|
|||
ctx context.Context,
|
||||
db storage.RoomDatabase,
|
||||
roomInfo *types.RoomInfo,
|
||||
event *gomatrixserverlib.HeaderedEvent,
|
||||
event *types.HeaderedEvent,
|
||||
stateEventIDs []string,
|
||||
) (bool, error) {
|
||||
rewritesState := len(stateEventIDs) > 1
|
||||
|
|
@ -65,7 +65,9 @@ func CheckForSoftFail(
|
|||
}
|
||||
|
||||
// Work out which of the state events we actually need.
|
||||
stateNeeded := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{event.Unwrap()})
|
||||
stateNeeded := gomatrixserverlib.StateNeededForAuth(
|
||||
gomatrixserverlib.ToPDUs([]*gomatrixserverlib.Event{event.Event}),
|
||||
)
|
||||
|
||||
// Load the actual auth events from the database.
|
||||
authEvents, err := loadAuthEvents(ctx, db, roomInfo, stateNeeded, authStateEntries)
|
||||
|
|
@ -87,7 +89,7 @@ func CheckAuthEvents(
|
|||
ctx context.Context,
|
||||
db storage.RoomDatabase,
|
||||
roomInfo *types.RoomInfo,
|
||||
event *gomatrixserverlib.HeaderedEvent,
|
||||
event *types.HeaderedEvent,
|
||||
authEventIDs []string,
|
||||
) ([]types.EventNID, error) {
|
||||
// Grab the numeric IDs for the supplied auth state events from the database.
|
||||
|
|
@ -98,7 +100,7 @@ func CheckAuthEvents(
|
|||
authStateEntries = types.DeduplicateStateEntries(authStateEntries)
|
||||
|
||||
// Work out which of the state events we actually need.
|
||||
stateNeeded := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{event.Unwrap()})
|
||||
stateNeeded := gomatrixserverlib.StateNeededForAuth([]gomatrixserverlib.PDU{event.Event})
|
||||
|
||||
// Load the actual auth events from the database.
|
||||
authEvents, err := loadAuthEvents(ctx, db, roomInfo, stateNeeded, authStateEntries)
|
||||
|
|
@ -132,31 +134,31 @@ func (ae *authEvents) Valid() bool {
|
|||
}
|
||||
|
||||
// Create implements gomatrixserverlib.AuthEventProvider
|
||||
func (ae *authEvents) Create() (*gomatrixserverlib.Event, error) {
|
||||
func (ae *authEvents) Create() (gomatrixserverlib.PDU, error) {
|
||||
return ae.lookupEventWithEmptyStateKey(types.MRoomCreateNID), nil
|
||||
}
|
||||
|
||||
// PowerLevels implements gomatrixserverlib.AuthEventProvider
|
||||
func (ae *authEvents) PowerLevels() (*gomatrixserverlib.Event, error) {
|
||||
func (ae *authEvents) PowerLevels() (gomatrixserverlib.PDU, error) {
|
||||
return ae.lookupEventWithEmptyStateKey(types.MRoomPowerLevelsNID), nil
|
||||
}
|
||||
|
||||
// JoinRules implements gomatrixserverlib.AuthEventProvider
|
||||
func (ae *authEvents) JoinRules() (*gomatrixserverlib.Event, error) {
|
||||
func (ae *authEvents) JoinRules() (gomatrixserverlib.PDU, error) {
|
||||
return ae.lookupEventWithEmptyStateKey(types.MRoomJoinRulesNID), nil
|
||||
}
|
||||
|
||||
// Memmber implements gomatrixserverlib.AuthEventProvider
|
||||
func (ae *authEvents) Member(stateKey string) (*gomatrixserverlib.Event, error) {
|
||||
func (ae *authEvents) Member(stateKey string) (gomatrixserverlib.PDU, error) {
|
||||
return ae.lookupEvent(types.MRoomMemberNID, stateKey), nil
|
||||
}
|
||||
|
||||
// ThirdPartyInvite implements gomatrixserverlib.AuthEventProvider
|
||||
func (ae *authEvents) ThirdPartyInvite(stateKey string) (*gomatrixserverlib.Event, error) {
|
||||
func (ae *authEvents) ThirdPartyInvite(stateKey string) (gomatrixserverlib.PDU, error) {
|
||||
return ae.lookupEvent(types.MRoomThirdPartyInviteNID, stateKey), nil
|
||||
}
|
||||
|
||||
func (ae *authEvents) lookupEventWithEmptyStateKey(typeNID types.EventTypeNID) *gomatrixserverlib.Event {
|
||||
func (ae *authEvents) lookupEventWithEmptyStateKey(typeNID types.EventTypeNID) gomatrixserverlib.PDU {
|
||||
eventNID, ok := ae.state.lookup(types.StateKeyTuple{
|
||||
EventTypeNID: typeNID,
|
||||
EventStateKeyNID: types.EmptyStateKeyNID,
|
||||
|
|
@ -171,7 +173,7 @@ func (ae *authEvents) lookupEventWithEmptyStateKey(typeNID types.EventTypeNID) *
|
|||
return event.Event
|
||||
}
|
||||
|
||||
func (ae *authEvents) lookupEvent(typeNID types.EventTypeNID, stateKey string) *gomatrixserverlib.Event {
|
||||
func (ae *authEvents) lookupEvent(typeNID types.EventTypeNID, stateKey string) gomatrixserverlib.PDU {
|
||||
stateKeyNID, ok := ae.stateKeyNIDMap[stateKey]
|
||||
if !ok {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func UpdateToInviteMembership(
|
|||
updates = append(updates, api.OutputEvent{
|
||||
Type: api.OutputTypeNewInviteEvent,
|
||||
NewInviteEvent: &api.OutputNewInviteEvent{
|
||||
Event: add.Headered(roomVersion),
|
||||
Event: &types.HeaderedEvent{Event: add.Event},
|
||||
RoomVersion: roomVersion,
|
||||
},
|
||||
})
|
||||
|
|
@ -479,7 +479,7 @@ func QueryLatestEventsAndState(
|
|||
}
|
||||
|
||||
for _, event := range stateEvents {
|
||||
response.StateEvents = append(response.StateEvents, event.Headered(roomInfo.RoomVersion))
|
||||
response.StateEvents = append(response.StateEvents, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ func TestIsInvitePendingWithoutNID(t *testing.T) {
|
|||
var authNIDs []types.EventNID
|
||||
for _, x := range room.Events() {
|
||||
|
||||
roomInfo, err := db.GetOrCreateRoomInfo(context.Background(), x.Unwrap())
|
||||
roomInfo, err := db.GetOrCreateRoomInfo(context.Background(), x.Event)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, roomInfo)
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ func (r *Inputer) processRoomEvent(
|
|||
|
||||
// Parse and validate the event JSON
|
||||
headered := input.Event
|
||||
event := headered.Unwrap()
|
||||
event := headered.Event
|
||||
logger := util.GetLogger(ctx).WithFields(logrus.Fields{
|
||||
"event_id": event.EventID(),
|
||||
"room_id": event.RoomID(),
|
||||
|
|
@ -235,7 +235,7 @@ func (r *Inputer) processRoomEvent(
|
|||
haveEvents: map[string]*gomatrixserverlib.Event{},
|
||||
}
|
||||
var stateSnapshot *parsedRespState
|
||||
if stateSnapshot, err = missingState.processEventWithMissingState(ctx, event, headered.RoomVersion); err != nil {
|
||||
if stateSnapshot, err = missingState.processEventWithMissingState(ctx, event, headered.Version()); err != nil {
|
||||
// Something went wrong with retrieving the missing state, so we can't
|
||||
// really do anything with the event other than reject it at this point.
|
||||
isRejected = true
|
||||
|
|
@ -467,7 +467,7 @@ func (r *Inputer) processRoomEvent(
|
|||
Type: api.OutputTypeRedactedEvent,
|
||||
RedactedEvent: &api.OutputRedactedEvent{
|
||||
RedactedEventID: redactedEventID,
|
||||
RedactedBecause: redactionEvent.Headered(headered.RoomVersion),
|
||||
RedactedBecause: &types.HeaderedEvent{Event: redactionEvent},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
@ -478,7 +478,7 @@ func (r *Inputer) processRoomEvent(
|
|||
|
||||
// If guest_access changed and is not can_join, kick all guest users.
|
||||
if event.Type() == spec.MRoomGuestAccess && gjson.GetBytes(event.Content(), "guest_access").Str != "can_join" {
|
||||
if err = r.kickGuests(ctx, event, roomInfo); err != nil {
|
||||
if err = r.kickGuests(ctx, event, roomInfo); err != nil && err != sql.ErrNoRows {
|
||||
logrus.WithError(err).Error("failed to kick guest users on m.room.guest_access revocation")
|
||||
}
|
||||
}
|
||||
|
|
@ -509,7 +509,7 @@ func (r *Inputer) processStateBefore(
|
|||
missingPrev bool,
|
||||
) (historyVisibility gomatrixserverlib.HistoryVisibility, rejectionErr error, err error) {
|
||||
historyVisibility = gomatrixserverlib.HistoryVisibilityShared // Default to shared.
|
||||
event := input.Event.Unwrap()
|
||||
event := input.Event.Event
|
||||
isCreateEvent := event.Type() == spec.MRoomCreate && event.StateKeyEquals("")
|
||||
var stateBeforeEvent []*gomatrixserverlib.Event
|
||||
switch {
|
||||
|
|
@ -545,7 +545,7 @@ func (r *Inputer) processStateBefore(
|
|||
// will include the history visibility here even though we don't
|
||||
// actually need it for auth, because we want to send it in the
|
||||
// output events.
|
||||
tuplesNeeded := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{event}).Tuples()
|
||||
tuplesNeeded := gomatrixserverlib.StateNeededForAuth([]gomatrixserverlib.PDU{event}).Tuples()
|
||||
tuplesNeeded = append(tuplesNeeded, gomatrixserverlib.StateKeyTuple{
|
||||
EventType: spec.MRoomHistoryVisibility,
|
||||
StateKey: "",
|
||||
|
|
@ -567,14 +567,20 @@ func (r *Inputer) processStateBefore(
|
|||
rejectionErr = fmt.Errorf("prev events of %q are not known", event.EventID())
|
||||
return
|
||||
default:
|
||||
stateBeforeEvent = gomatrixserverlib.UnwrapEventHeaders(stateBeforeRes.StateEvents)
|
||||
stateBeforeEvent = make([]*gomatrixserverlib.Event, len(stateBeforeRes.StateEvents))
|
||||
for i := range stateBeforeRes.StateEvents {
|
||||
stateBeforeEvent[i] = stateBeforeRes.StateEvents[i].Event
|
||||
}
|
||||
}
|
||||
}
|
||||
// At this point, stateBeforeEvent should be populated either by
|
||||
// the supplied state in the input request, or from the prev events.
|
||||
// Check whether the event is allowed or not.
|
||||
stateBeforeAuth := gomatrixserverlib.NewAuthEvents(stateBeforeEvent)
|
||||
stateBeforeAuth := gomatrixserverlib.NewAuthEvents(
|
||||
gomatrixserverlib.ToPDUs(stateBeforeEvent),
|
||||
)
|
||||
if rejectionErr = gomatrixserverlib.Allowed(event, &stateBeforeAuth); rejectionErr != nil {
|
||||
rejectionErr = fmt.Errorf("Allowed() failed for stateBeforeEvent: %w", rejectionErr)
|
||||
return
|
||||
}
|
||||
// Work out what the history visibility was at the time of the
|
||||
|
|
@ -604,7 +610,7 @@ func (r *Inputer) fetchAuthEvents(
|
|||
logger *logrus.Entry,
|
||||
roomInfo *types.RoomInfo,
|
||||
virtualHost spec.ServerName,
|
||||
event *gomatrixserverlib.HeaderedEvent,
|
||||
event *types.HeaderedEvent,
|
||||
auth *gomatrixserverlib.AuthEvents,
|
||||
known map[string]*types.Event,
|
||||
servers []spec.ServerName,
|
||||
|
|
@ -654,7 +660,7 @@ func (r *Inputer) fetchAuthEvents(
|
|||
// Request the entire auth chain for the event in question. This should
|
||||
// contain all of the auth events — including ones that we already know —
|
||||
// so we'll need to filter through those in the next section.
|
||||
res, err = r.FSAPI.GetEventAuth(ctx, virtualHost, serverName, event.RoomVersion, event.RoomID(), event.EventID())
|
||||
res, err = r.FSAPI.GetEventAuth(ctx, virtualHost, serverName, event.Version(), event.RoomID(), event.EventID())
|
||||
if err != nil {
|
||||
logger.WithError(err).Warnf("Failed to get event auth from federation for %q: %s", event.EventID(), err)
|
||||
continue
|
||||
|
|
@ -671,7 +677,7 @@ func (r *Inputer) fetchAuthEvents(
|
|||
isRejected := false
|
||||
nextAuthEvent:
|
||||
for _, authEvent := range gomatrixserverlib.ReverseTopologicalOrdering(
|
||||
res.AuthEvents.UntrustedEvents(event.RoomVersion),
|
||||
gomatrixserverlib.ToPDUs(res.AuthEvents.UntrustedEvents(event.Version())),
|
||||
gomatrixserverlib.TopologicalOrderByAuthEvents,
|
||||
) {
|
||||
// If we already know about this event from the database then we don't
|
||||
|
|
@ -684,7 +690,7 @@ nextAuthEvent:
|
|||
// Check the signatures of the event. If this fails then we'll simply
|
||||
// skip it, because gomatrixserverlib.Allowed() will notice a problem
|
||||
// if a critical event is missing anyway.
|
||||
if err := authEvent.VerifyEventSignatures(ctx, r.FSAPI.KeyRing()); err != nil {
|
||||
if err := gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.FSAPI.KeyRing()); err != nil {
|
||||
continue nextAuthEvent
|
||||
}
|
||||
|
||||
|
|
@ -739,7 +745,7 @@ nextAuthEvent:
|
|||
// Now we know about this event, it was stored and the signatures were OK.
|
||||
known[authEvent.EventID()] = &types.Event{
|
||||
EventNID: eventNID,
|
||||
Event: authEvent,
|
||||
Event: authEvent.(*gomatrixserverlib.Event),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ func (u *latestEventsUpdater) makeOutputNewRoomEvent() (*api.OutputEvent, error)
|
|||
}
|
||||
|
||||
ore := api.OutputNewRoomEvent{
|
||||
Event: u.event.Headered(u.roomInfo.RoomVersion),
|
||||
Event: &types.HeaderedEvent{Event: u.event},
|
||||
RewritesState: u.rewritesState,
|
||||
LastSentEventID: u.lastEventIDSent,
|
||||
LatestEventIDs: latestEventIDs,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ type parsedRespState struct {
|
|||
StateEvents []*gomatrixserverlib.Event
|
||||
}
|
||||
|
||||
func (p *parsedRespState) Events() []*gomatrixserverlib.Event {
|
||||
func (p *parsedRespState) Events() []gomatrixserverlib.PDU {
|
||||
eventsByID := make(map[string]*gomatrixserverlib.Event, len(p.AuthEvents)+len(p.StateEvents))
|
||||
for i, event := range p.AuthEvents {
|
||||
eventsByID[event.EventID()] = p.AuthEvents[i]
|
||||
|
|
@ -38,7 +38,8 @@ func (p *parsedRespState) Events() []*gomatrixserverlib.Event {
|
|||
for _, event := range eventsByID {
|
||||
allEvents = append(allEvents, event)
|
||||
}
|
||||
return gomatrixserverlib.ReverseTopologicalOrdering(allEvents, gomatrixserverlib.TopologicalOrderByAuthEvents)
|
||||
return gomatrixserverlib.ReverseTopologicalOrdering(
|
||||
gomatrixserverlib.ToPDUs(allEvents), gomatrixserverlib.TopologicalOrderByAuthEvents)
|
||||
}
|
||||
|
||||
type missingStateReq struct {
|
||||
|
|
@ -106,7 +107,7 @@ func (t *missingStateReq) processEventWithMissingState(
|
|||
for _, newEvent := range newEvents {
|
||||
err = t.inputer.processRoomEvent(ctx, t.virtualHost, &api.InputRoomEvent{
|
||||
Kind: api.KindOld,
|
||||
Event: newEvent.Headered(roomVersion),
|
||||
Event: &types.HeaderedEvent{Event: newEvent},
|
||||
Origin: t.origin,
|
||||
SendAsServer: api.DoNotSendToOtherServers,
|
||||
})
|
||||
|
|
@ -155,7 +156,7 @@ func (t *missingStateReq) processEventWithMissingState(
|
|||
}
|
||||
outlierRoomEvents = append(outlierRoomEvents, api.InputRoomEvent{
|
||||
Kind: api.KindOutlier,
|
||||
Event: outlier.Headered(roomVersion),
|
||||
Event: &types.HeaderedEvent{Event: outlier.(*gomatrixserverlib.Event)},
|
||||
Origin: t.origin,
|
||||
})
|
||||
}
|
||||
|
|
@ -185,7 +186,7 @@ func (t *missingStateReq) processEventWithMissingState(
|
|||
|
||||
err = t.inputer.processRoomEvent(ctx, t.virtualHost, &api.InputRoomEvent{
|
||||
Kind: api.KindOld,
|
||||
Event: backwardsExtremity.Headered(roomVersion),
|
||||
Event: &types.HeaderedEvent{Event: backwardsExtremity},
|
||||
Origin: t.origin,
|
||||
HasState: true,
|
||||
StateEventIDs: stateIDs,
|
||||
|
|
@ -204,7 +205,7 @@ func (t *missingStateReq) processEventWithMissingState(
|
|||
for _, newEvent := range newEvents {
|
||||
err = t.inputer.processRoomEvent(ctx, t.virtualHost, &api.InputRoomEvent{
|
||||
Kind: api.KindOld,
|
||||
Event: newEvent.Headered(roomVersion),
|
||||
Event: &types.HeaderedEvent{Event: newEvent},
|
||||
Origin: t.origin,
|
||||
SendAsServer: api.DoNotSendToOtherServers,
|
||||
})
|
||||
|
|
@ -468,7 +469,9 @@ func (t *missingStateReq) resolveStatesAndCheck(ctx context.Context, roomVersion
|
|||
authEventList = append(authEventList, state.AuthEvents...)
|
||||
stateEventList = append(stateEventList, state.StateEvents...)
|
||||
}
|
||||
resolvedStateEvents, err := gomatrixserverlib.ResolveConflicts(roomVersion, stateEventList, authEventList)
|
||||
resolvedStateEvents, err := gomatrixserverlib.ResolveConflicts(
|
||||
roomVersion, gomatrixserverlib.ToPDUs(stateEventList), gomatrixserverlib.ToPDUs(authEventList),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -482,7 +485,7 @@ retryAllowedState:
|
|||
case verifySigError:
|
||||
return &parsedRespState{
|
||||
AuthEvents: authEventList,
|
||||
StateEvents: resolvedStateEvents,
|
||||
StateEvents: gomatrixserverlib.TempCastToEvents(resolvedStateEvents),
|
||||
}, nil
|
||||
case nil:
|
||||
// do nothing
|
||||
|
|
@ -498,7 +501,7 @@ retryAllowedState:
|
|||
}
|
||||
return &parsedRespState{
|
||||
AuthEvents: authEventList,
|
||||
StateEvents: resolvedStateEvents,
|
||||
StateEvents: gomatrixserverlib.TempCastToEvents(resolvedStateEvents),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -559,7 +562,7 @@ func (t *missingStateReq) getMissingEvents(ctx context.Context, e *gomatrixserve
|
|||
// will be added and duplicates will be removed.
|
||||
missingEvents := make([]*gomatrixserverlib.Event, 0, len(missingResp.Events))
|
||||
for _, ev := range missingResp.Events.UntrustedEvents(roomVersion) {
|
||||
if err = ev.VerifyEventSignatures(ctx, t.keys); err != nil {
|
||||
if err = gomatrixserverlib.VerifyEventSignatures(ctx, ev, t.keys); err != nil {
|
||||
continue
|
||||
}
|
||||
missingEvents = append(missingEvents, t.cacheAndReturn(ev))
|
||||
|
|
@ -567,7 +570,9 @@ func (t *missingStateReq) getMissingEvents(ctx context.Context, e *gomatrixserve
|
|||
logger.Debugf("get_missing_events returned %d events (%d passed signature checks)", len(missingResp.Events), len(missingEvents))
|
||||
|
||||
// topologically sort and sanity check that we are making forward progress
|
||||
newEvents = gomatrixserverlib.ReverseTopologicalOrdering(missingEvents, gomatrixserverlib.TopologicalOrderByPrevEvents)
|
||||
newEventsPDUs := gomatrixserverlib.ReverseTopologicalOrdering(
|
||||
gomatrixserverlib.ToPDUs(missingEvents), gomatrixserverlib.TopologicalOrderByPrevEvents)
|
||||
newEvents = gomatrixserverlib.TempCastToEvents(newEventsPDUs)
|
||||
shouldHaveSomeEventIDs := e.PrevEventIDs()
|
||||
hasPrevEvent := false
|
||||
Event:
|
||||
|
|
@ -882,14 +887,14 @@ func (t *missingStateReq) lookupEvent(ctx context.Context, roomVersion gomatrixs
|
|||
t.log.WithField("missing_event_id", missingEventID).Warnf("Failed to get missing /event for event ID from %d server(s)", len(t.servers))
|
||||
return nil, fmt.Errorf("wasn't able to find event via %d server(s)", len(t.servers))
|
||||
}
|
||||
if err := event.VerifyEventSignatures(ctx, t.keys); err != nil {
|
||||
if err := gomatrixserverlib.VerifyEventSignatures(ctx, event, t.keys); err != nil {
|
||||
t.log.WithError(err).Warnf("Couldn't validate signature of event %q from /event", event.EventID())
|
||||
return nil, verifySigError{event.EventID(), err}
|
||||
}
|
||||
return t.cacheAndReturn(event), nil
|
||||
}
|
||||
|
||||
func checkAllowedByState(e *gomatrixserverlib.Event, stateEvents []*gomatrixserverlib.Event) error {
|
||||
func checkAllowedByState(e *gomatrixserverlib.Event, stateEvents []gomatrixserverlib.PDU) error {
|
||||
authUsingState := gomatrixserverlib.NewAuthEvents(nil)
|
||||
for i := range stateEvents {
|
||||
err := authUsingState.AddEvent(stateEvents[i])
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/roomserver"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/internal/input"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||
"github.com/matrix-org/dendrite/test"
|
||||
"github.com/matrix-org/dendrite/test/testrig"
|
||||
|
|
@ -44,7 +45,7 @@ func TestSingleTransactionOnInput(t *testing.T) {
|
|||
}
|
||||
in := api.InputRoomEvent{
|
||||
Kind: api.KindOutlier, // don't panic if we generate an output event
|
||||
Event: event.Headered(gomatrixserverlib.RoomVersionV6),
|
||||
Event: &types.HeaderedEvent{Event: event},
|
||||
}
|
||||
|
||||
inputter := &input.Inputer{
|
||||
|
|
|
|||
|
|
@ -26,8 +26,10 @@ import (
|
|||
"github.com/matrix-org/dendrite/roomserver/internal/input"
|
||||
"github.com/matrix-org/dendrite/roomserver/internal/query"
|
||||
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
|
@ -40,61 +42,44 @@ type Admin struct {
|
|||
Leaver *Leaver
|
||||
}
|
||||
|
||||
// PerformEvacuateRoom will remove all local users from the given room.
|
||||
// PerformAdminEvacuateRoom will remove all local users from the given room.
|
||||
func (r *Admin) PerformAdminEvacuateRoom(
|
||||
ctx context.Context,
|
||||
req *api.PerformAdminEvacuateRoomRequest,
|
||||
res *api.PerformAdminEvacuateRoomResponse,
|
||||
) error {
|
||||
roomInfo, err := r.DB.RoomInfo(ctx, req.RoomID)
|
||||
roomID string,
|
||||
) (affected []string, err error) {
|
||||
roomInfo, err := r.DB.RoomInfo(ctx, roomID)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.RoomInfo: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
if roomInfo == nil || roomInfo.IsStub() {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorNoRoom,
|
||||
Msg: fmt.Sprintf("Room %s not found", req.RoomID),
|
||||
}
|
||||
return nil
|
||||
return nil, eventutil.ErrRoomNoExists
|
||||
}
|
||||
|
||||
memberNIDs, err := r.DB.GetMembershipEventNIDsForRoom(ctx, roomInfo.RoomNID, true, true)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.GetMembershipEventNIDsForRoom: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
memberEvents, err := r.DB.Events(ctx, roomInfo, memberNIDs)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.Events: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inputEvents := make([]api.InputRoomEvent, 0, len(memberEvents))
|
||||
res.Affected = make([]string, 0, len(memberEvents))
|
||||
affected = make([]string, 0, len(memberEvents))
|
||||
latestReq := &api.QueryLatestEventsAndStateRequest{
|
||||
RoomID: req.RoomID,
|
||||
RoomID: roomID,
|
||||
}
|
||||
latestRes := &api.QueryLatestEventsAndStateResponse{}
|
||||
if err = r.Queryer.QueryLatestEventsAndState(ctx, latestReq, latestRes); err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.Queryer.QueryLatestEventsAndState: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prevEvents := latestRes.LatestEvents
|
||||
var senderDomain spec.ServerName
|
||||
var eventsNeeded gomatrixserverlib.StateNeeded
|
||||
var identity *fclient.SigningIdentity
|
||||
var event *types.HeaderedEvent
|
||||
for _, memberEvent := range memberEvents {
|
||||
if memberEvent.StateKey() == nil {
|
||||
continue
|
||||
|
|
@ -102,57 +87,41 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
|
||||
var memberContent gomatrixserverlib.MemberContent
|
||||
if err = json.Unmarshal(memberEvent.Content(), &memberContent); err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("json.Unmarshal: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
memberContent.Membership = spec.Leave
|
||||
|
||||
stateKey := *memberEvent.StateKey()
|
||||
fledglingEvent := &gomatrixserverlib.EventBuilder{
|
||||
RoomID: req.RoomID,
|
||||
RoomID: roomID,
|
||||
Type: spec.MRoomMember,
|
||||
StateKey: &stateKey,
|
||||
Sender: stateKey,
|
||||
PrevEvents: prevEvents,
|
||||
}
|
||||
|
||||
_, senderDomain, err := gomatrixserverlib.SplitID('@', fledglingEvent.Sender)
|
||||
_, senderDomain, err = gomatrixserverlib.SplitID('@', fledglingEvent.Sender)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if fledglingEvent.Content, err = json.Marshal(memberContent); err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("json.Marshal: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(fledglingEvent)
|
||||
eventsNeeded, err = gomatrixserverlib.StateNeededForEventBuilder(fledglingEvent)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("gomatrixserverlib.StateNeededForEventBuilder: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
identity, err := r.Cfg.Matrix.SigningIdentityFor(senderDomain)
|
||||
identity, err = r.Cfg.Matrix.SigningIdentityFor(senderDomain)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
event, err := eventutil.BuildEvent(ctx, fledglingEvent, r.Cfg.Matrix, identity, time.Now(), &eventsNeeded, latestRes)
|
||||
event, err = eventutil.BuildEvent(ctx, fledglingEvent, r.Cfg.Matrix, identity, time.Now(), &eventsNeeded, latestRes)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("eventutil.BuildEvent: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inputEvents = append(inputEvents, api.InputRoomEvent{
|
||||
|
|
@ -161,7 +130,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Origin: senderDomain,
|
||||
SendAsServer: string(senderDomain),
|
||||
})
|
||||
res.Affected = append(res.Affected, stateKey)
|
||||
affected = append(affected, stateKey)
|
||||
prevEvents = []gomatrixserverlib.EventReference{
|
||||
event.EventReference(),
|
||||
}
|
||||
|
|
@ -172,108 +141,85 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
|||
Asynchronous: true,
|
||||
}
|
||||
inputRes := &api.InputRoomEventsResponse{}
|
||||
return r.Inputer.InputRoomEvents(ctx, inputReq, inputRes)
|
||||
err = r.Inputer.InputRoomEvents(ctx, inputReq, inputRes)
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// PerformAdminEvacuateUser will remove the given user from all rooms.
|
||||
func (r *Admin) PerformAdminEvacuateUser(
|
||||
ctx context.Context,
|
||||
req *api.PerformAdminEvacuateUserRequest,
|
||||
res *api.PerformAdminEvacuateUserResponse,
|
||||
) error {
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
||||
userID string,
|
||||
) (affected []string, err error) {
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', userID)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Malformed user ID: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: "Can only evacuate local users using this endpoint",
|
||||
}
|
||||
return nil
|
||||
return nil, fmt.Errorf("can only evacuate local users using this endpoint")
|
||||
}
|
||||
|
||||
roomIDs, err := r.DB.GetRoomsByMembership(ctx, req.UserID, spec.Join)
|
||||
roomIDs, err := r.DB.GetRoomsByMembership(ctx, userID, spec.Join)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inviteRoomIDs, err := r.DB.GetRoomsByMembership(ctx, userID, spec.Invite)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.GetRoomsByMembership: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inviteRoomIDs, err := r.DB.GetRoomsByMembership(ctx, req.UserID, spec.Invite)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.GetRoomsByMembership: %s", err),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, roomID := range append(roomIDs, inviteRoomIDs...) {
|
||||
allRooms := append(roomIDs, inviteRoomIDs...)
|
||||
affected = make([]string, 0, len(allRooms))
|
||||
for _, roomID := range allRooms {
|
||||
leaveReq := &api.PerformLeaveRequest{
|
||||
RoomID: roomID,
|
||||
UserID: req.UserID,
|
||||
UserID: userID,
|
||||
}
|
||||
leaveRes := &api.PerformLeaveResponse{}
|
||||
outputEvents, err := r.Leaver.PerformLeave(ctx, leaveReq, leaveRes)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.Leaver.PerformLeave: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
res.Affected = append(res.Affected, roomID)
|
||||
affected = append(affected, roomID)
|
||||
if len(outputEvents) == 0 {
|
||||
continue
|
||||
}
|
||||
if err := r.Inputer.OutputProducer.ProduceRoomEvents(roomID, outputEvents); err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.Inputer.WriteOutputEvents: %s", err),
|
||||
}
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return affected, nil
|
||||
}
|
||||
|
||||
// PerformAdminPurgeRoom removes all traces for the given room from the database.
|
||||
func (r *Admin) PerformAdminPurgeRoom(
|
||||
ctx context.Context,
|
||||
req *api.PerformAdminPurgeRoomRequest,
|
||||
res *api.PerformAdminPurgeRoomResponse,
|
||||
roomID string,
|
||||
) error {
|
||||
// Validate we actually got a room ID and nothing else
|
||||
if _, _, err := gomatrixserverlib.SplitID('!', req.RoomID); err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Malformed room ID: %s", err),
|
||||
}
|
||||
return nil
|
||||
if _, _, err := gomatrixserverlib.SplitID('!', roomID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.WithField("room_id", req.RoomID).Warn("Purging room from roomserver")
|
||||
if err := r.DB.PurgeRoom(ctx, req.RoomID); err != nil {
|
||||
logrus.WithField("room_id", req.RoomID).WithError(err).Warn("Failed to purge room from roomserver")
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
return nil
|
||||
// Evacuate the room before purging it from the database
|
||||
if _, err := r.PerformAdminEvacuateRoom(ctx, roomID); err != nil {
|
||||
logrus.WithField("room_id", roomID).WithError(err).Warn("Failed to evacuate room before purging")
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.WithField("room_id", req.RoomID).Warn("Room purged from roomserver")
|
||||
logrus.WithField("room_id", roomID).Warn("Purging room from roomserver")
|
||||
if err := r.DB.PurgeRoom(ctx, roomID); err != nil {
|
||||
logrus.WithField("room_id", roomID).WithError(err).Warn("Failed to purge room from roomserver")
|
||||
return err
|
||||
}
|
||||
|
||||
return r.Inputer.OutputProducer.ProduceRoomEvents(req.RoomID, []api.OutputEvent{
|
||||
logrus.WithField("room_id", roomID).Warn("Room purged from roomserver")
|
||||
|
||||
return r.Inputer.OutputProducer.ProduceRoomEvents(roomID, []api.OutputEvent{
|
||||
{
|
||||
Type: api.OutputTypePurgeRoom,
|
||||
PurgeRoom: &api.OutputPurgeRoom{
|
||||
RoomID: req.RoomID,
|
||||
RoomID: roomID,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
@ -281,42 +227,25 @@ func (r *Admin) PerformAdminPurgeRoom(
|
|||
|
||||
func (r *Admin) PerformAdminDownloadState(
|
||||
ctx context.Context,
|
||||
req *api.PerformAdminDownloadStateRequest,
|
||||
res *api.PerformAdminDownloadStateResponse,
|
||||
roomID, userID string, serverName spec.ServerName,
|
||||
) error {
|
||||
_, senderDomain, err := r.Cfg.Matrix.SplitLocalID('@', req.UserID)
|
||||
_, senderDomain, err := r.Cfg.Matrix.SplitLocalID('@', userID)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.Cfg.Matrix.SplitLocalID: %s", err),
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
roomInfo, err := r.DB.RoomInfo(ctx, req.RoomID)
|
||||
roomInfo, err := r.DB.RoomInfo(ctx, roomID)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.RoomInfo: %s", err),
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
if roomInfo == nil || roomInfo.IsStub() {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("room %q not found", req.RoomID),
|
||||
}
|
||||
return nil
|
||||
return eventutil.ErrRoomNoExists
|
||||
}
|
||||
|
||||
fwdExtremities, _, depth, err := r.DB.LatestEventIDs(ctx, roomInfo.RoomNID)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.DB.LatestEventIDs: %s", err),
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
authEventMap := map[string]*gomatrixserverlib.Event{}
|
||||
|
|
@ -324,54 +253,46 @@ func (r *Admin) PerformAdminDownloadState(
|
|||
|
||||
for _, fwdExtremity := range fwdExtremities {
|
||||
var state gomatrixserverlib.StateResponse
|
||||
state, err = r.Inputer.FSAPI.LookupState(ctx, r.Inputer.ServerName, req.ServerName, req.RoomID, fwdExtremity.EventID, roomInfo.RoomVersion)
|
||||
state, err = r.Inputer.FSAPI.LookupState(ctx, r.Inputer.ServerName, serverName, roomID, fwdExtremity.EventID, roomInfo.RoomVersion)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.Inputer.FSAPI.LookupState (%q): %s", fwdExtremity.EventID, err),
|
||||
}
|
||||
return nil
|
||||
return fmt.Errorf("r.Inputer.FSAPI.LookupState (%q): %s", fwdExtremity.EventID, err)
|
||||
}
|
||||
for _, authEvent := range state.GetAuthEvents().UntrustedEvents(roomInfo.RoomVersion) {
|
||||
if err = authEvent.VerifyEventSignatures(ctx, r.Inputer.KeyRing); err != nil {
|
||||
if err = gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.Inputer.KeyRing); err != nil {
|
||||
continue
|
||||
}
|
||||
authEventMap[authEvent.EventID()] = authEvent
|
||||
}
|
||||
for _, stateEvent := range state.GetStateEvents().UntrustedEvents(roomInfo.RoomVersion) {
|
||||
if err = stateEvent.VerifyEventSignatures(ctx, r.Inputer.KeyRing); err != nil {
|
||||
if err = gomatrixserverlib.VerifyEventSignatures(ctx, stateEvent, r.Inputer.KeyRing); err != nil {
|
||||
continue
|
||||
}
|
||||
stateEventMap[stateEvent.EventID()] = stateEvent
|
||||
}
|
||||
}
|
||||
|
||||
authEvents := make([]*gomatrixserverlib.HeaderedEvent, 0, len(authEventMap))
|
||||
stateEvents := make([]*gomatrixserverlib.HeaderedEvent, 0, len(stateEventMap))
|
||||
authEvents := make([]*types.HeaderedEvent, 0, len(authEventMap))
|
||||
stateEvents := make([]*types.HeaderedEvent, 0, len(stateEventMap))
|
||||
stateIDs := make([]string, 0, len(stateEventMap))
|
||||
|
||||
for _, authEvent := range authEventMap {
|
||||
authEvents = append(authEvents, authEvent.Headered(roomInfo.RoomVersion))
|
||||
authEvents = append(authEvents, &types.HeaderedEvent{Event: authEvent})
|
||||
}
|
||||
for _, stateEvent := range stateEventMap {
|
||||
stateEvents = append(stateEvents, stateEvent.Headered(roomInfo.RoomVersion))
|
||||
stateEvents = append(stateEvents, &types.HeaderedEvent{Event: stateEvent})
|
||||
stateIDs = append(stateIDs, stateEvent.EventID())
|
||||
}
|
||||
|
||||
builder := &gomatrixserverlib.EventBuilder{
|
||||
Type: "org.matrix.dendrite.state_download",
|
||||
Sender: req.UserID,
|
||||
RoomID: req.RoomID,
|
||||
Sender: userID,
|
||||
RoomID: roomID,
|
||||
Content: spec.RawJSON("{}"),
|
||||
}
|
||||
|
||||
eventsNeeded, err := gomatrixserverlib.StateNeededForEventBuilder(builder)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("gomatrixserverlib.StateNeededForEventBuilder: %s", err),
|
||||
}
|
||||
return nil
|
||||
return fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
|
||||
}
|
||||
|
||||
queryRes := &api.QueryLatestEventsAndStateResponse{
|
||||
|
|
@ -389,11 +310,7 @@ func (r *Admin) PerformAdminDownloadState(
|
|||
|
||||
ev, err := eventutil.BuildEvent(ctx, builder, r.Cfg.Matrix, identity, time.Now(), &eventsNeeded, queryRes)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("eventutil.BuildEvent: %s", err),
|
||||
}
|
||||
return nil
|
||||
return fmt.Errorf("eventutil.BuildEvent: %w", err)
|
||||
}
|
||||
|
||||
inputReq := &api.InputRoomEventsRequest{
|
||||
|
|
@ -417,19 +334,12 @@ func (r *Admin) PerformAdminDownloadState(
|
|||
SendAsServer: string(r.Cfg.Matrix.ServerName),
|
||||
})
|
||||
|
||||
if err := r.Inputer.InputRoomEvents(ctx, inputReq, inputRes); err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("r.Inputer.InputRoomEvents: %s", err),
|
||||
}
|
||||
return nil
|
||||
if err = r.Inputer.InputRoomEvents(ctx, inputReq, inputRes); err != nil {
|
||||
return fmt.Errorf("r.Inputer.InputRoomEvents: %w", err)
|
||||
}
|
||||
|
||||
if inputRes.ErrMsg != "" {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: inputRes.ErrMsg,
|
||||
}
|
||||
return inputRes.Err()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ func (r *Backfiller) PerformBackfill(
|
|||
if _, ok := redactEventIDs[event.EventID()]; ok {
|
||||
event.Redact()
|
||||
}
|
||||
response.Events = append(response.Events, event.Headered(info.RoomVersion))
|
||||
response.Events = append(response.Events, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
|
||||
return err
|
||||
|
|
@ -133,7 +133,7 @@ func (r *Backfiller) backfillViaFederation(ctx context.Context, req *api.Perform
|
|||
logrus.WithError(err).WithField("room_id", req.RoomID).Infof("backfilled %d events", len(events))
|
||||
|
||||
// persist these new events - auth checks have already been done
|
||||
roomNID, backfilledEventMap := persistEvents(ctx, r.DB, events)
|
||||
roomNID, backfilledEventMap := persistEvents(ctx, r.DB, gomatrixserverlib.TempCastToEvents(events))
|
||||
|
||||
for _, ev := range backfilledEventMap {
|
||||
// now add state for these events
|
||||
|
|
@ -168,7 +168,10 @@ func (r *Backfiller) backfillViaFederation(ctx context.Context, req *api.Perform
|
|||
|
||||
// TODO: update backwards extremities, as that should be moved from syncapi to roomserver at some point.
|
||||
|
||||
res.Events = events
|
||||
res.Events = make([]*types.HeaderedEvent, len(events))
|
||||
for i := range events {
|
||||
res.Events[i] = &types.HeaderedEvent{Event: events[i].(*gomatrixserverlib.Event)}
|
||||
}
|
||||
res.HistoryVisibility = requester.historyVisiblity
|
||||
return nil
|
||||
}
|
||||
|
|
@ -186,7 +189,7 @@ func (r *Backfiller) fetchAndStoreMissingEvents(ctx context.Context, roomVer gom
|
|||
util.GetLogger(ctx).WithError(err).Warn("cannot query missing events")
|
||||
return
|
||||
}
|
||||
missingMap := make(map[string]*gomatrixserverlib.HeaderedEvent) // id -> event
|
||||
missingMap := make(map[string]*types.HeaderedEvent) // id -> event
|
||||
for _, id := range stateIDs {
|
||||
if _, ok := nidMap[id]; !ok {
|
||||
missingMap[id] = nil
|
||||
|
|
@ -227,15 +230,15 @@ func (r *Backfiller) fetchAndStoreMissingEvents(ctx context.Context, roomVer gom
|
|||
logger.WithError(err).Warn("event failed PDU checks")
|
||||
continue
|
||||
}
|
||||
missingMap[id] = res.Event
|
||||
missingMap[id] = &types.HeaderedEvent{Event: res.Event.(*gomatrixserverlib.Event)}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var newEvents []*gomatrixserverlib.HeaderedEvent
|
||||
var newEvents []*gomatrixserverlib.Event
|
||||
for _, ev := range missingMap {
|
||||
if ev != nil {
|
||||
newEvents = append(newEvents, ev)
|
||||
newEvents = append(newEvents, ev.Event)
|
||||
}
|
||||
}
|
||||
util.GetLogger(ctx).Infof("Persisting %d new events", len(newEvents))
|
||||
|
|
@ -254,7 +257,7 @@ type backfillRequester struct {
|
|||
// per-request state
|
||||
servers []spec.ServerName
|
||||
eventIDToBeforeStateIDs map[string][]string
|
||||
eventIDMap map[string]*gomatrixserverlib.Event
|
||||
eventIDMap map[string]gomatrixserverlib.PDU
|
||||
historyVisiblity gomatrixserverlib.HistoryVisibility
|
||||
roomInfo types.RoomInfo
|
||||
}
|
||||
|
|
@ -275,15 +278,15 @@ func newBackfillRequester(
|
|||
virtualHost: virtualHost,
|
||||
isLocalServerName: isLocalServerName,
|
||||
eventIDToBeforeStateIDs: make(map[string][]string),
|
||||
eventIDMap: make(map[string]*gomatrixserverlib.Event),
|
||||
eventIDMap: make(map[string]gomatrixserverlib.PDU),
|
||||
bwExtrems: bwExtrems,
|
||||
preferServer: preferServer,
|
||||
historyVisiblity: gomatrixserverlib.HistoryVisibilityShared,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *backfillRequester) StateIDsBeforeEvent(ctx context.Context, targetEvent *gomatrixserverlib.HeaderedEvent) ([]string, error) {
|
||||
b.eventIDMap[targetEvent.EventID()] = targetEvent.Unwrap()
|
||||
func (b *backfillRequester) StateIDsBeforeEvent(ctx context.Context, targetEvent gomatrixserverlib.PDU) ([]string, error) {
|
||||
b.eventIDMap[targetEvent.EventID()] = targetEvent
|
||||
if ids, ok := b.eventIDToBeforeStateIDs[targetEvent.EventID()]; ok {
|
||||
return ids, nil
|
||||
}
|
||||
|
|
@ -305,7 +308,7 @@ func (b *backfillRequester) StateIDsBeforeEvent(ctx context.Context, targetEvent
|
|||
if !ok {
|
||||
goto FederationHit
|
||||
}
|
||||
newStateIDs := b.calculateNewStateIDs(targetEvent.Unwrap(), prevEvent, prevEventStateIDs)
|
||||
newStateIDs := b.calculateNewStateIDs(targetEvent, prevEvent, prevEventStateIDs)
|
||||
if newStateIDs != nil {
|
||||
b.eventIDToBeforeStateIDs[targetEvent.EventID()] = newStateIDs
|
||||
return newStateIDs, nil
|
||||
|
|
@ -334,7 +337,7 @@ FederationHit:
|
|||
return nil, lastErr
|
||||
}
|
||||
|
||||
func (b *backfillRequester) calculateNewStateIDs(targetEvent, prevEvent *gomatrixserverlib.Event, prevEventStateIDs []string) []string {
|
||||
func (b *backfillRequester) calculateNewStateIDs(targetEvent, prevEvent gomatrixserverlib.PDU, prevEventStateIDs []string) []string {
|
||||
newStateIDs := prevEventStateIDs[:]
|
||||
if prevEvent.StateKey() == nil {
|
||||
// state is the same as the previous event
|
||||
|
|
@ -372,7 +375,7 @@ func (b *backfillRequester) calculateNewStateIDs(targetEvent, prevEvent *gomatri
|
|||
}
|
||||
|
||||
func (b *backfillRequester) StateBeforeEvent(ctx context.Context, roomVer gomatrixserverlib.RoomVersion,
|
||||
event *gomatrixserverlib.HeaderedEvent, eventIDs []string) (map[string]*gomatrixserverlib.Event, error) {
|
||||
event gomatrixserverlib.PDU, eventIDs []string) (map[string]gomatrixserverlib.PDU, error) {
|
||||
|
||||
// try to fetch the events from the database first
|
||||
events, err := b.ProvideEvents(roomVer, eventIDs)
|
||||
|
|
@ -382,7 +385,7 @@ func (b *backfillRequester) StateBeforeEvent(ctx context.Context, roomVer gomatr
|
|||
} else {
|
||||
logrus.Infof("Fetched %d/%d events from the database", len(events), len(eventIDs))
|
||||
if len(events) == len(eventIDs) {
|
||||
result := make(map[string]*gomatrixserverlib.Event)
|
||||
result := make(map[string]gomatrixserverlib.PDU)
|
||||
for i := range events {
|
||||
result[events[i].EventID()] = events[i]
|
||||
b.eventIDMap[events[i].EventID()] = events[i]
|
||||
|
|
@ -513,7 +516,7 @@ func (b *backfillRequester) Backfill(ctx context.Context, origin, server spec.Se
|
|||
return tx, err
|
||||
}
|
||||
|
||||
func (b *backfillRequester) ProvideEvents(roomVer gomatrixserverlib.RoomVersion, eventIDs []string) ([]*gomatrixserverlib.Event, error) {
|
||||
func (b *backfillRequester) ProvideEvents(roomVer gomatrixserverlib.RoomVersion, eventIDs []string) ([]gomatrixserverlib.PDU, error) {
|
||||
ctx := context.Background()
|
||||
nidMap, err := b.db.EventNIDs(ctx, eventIDs)
|
||||
if err != nil {
|
||||
|
|
@ -535,7 +538,7 @@ func (b *backfillRequester) ProvideEvents(roomVer gomatrixserverlib.RoomVersion,
|
|||
logrus.WithError(err).WithField("event_nids", eventNIDs).Error("Failed to load events")
|
||||
return nil, err
|
||||
}
|
||||
events := make([]*gomatrixserverlib.Event, len(eventsWithNids))
|
||||
events := make([]gomatrixserverlib.PDU, len(eventsWithNids))
|
||||
for i := range eventsWithNids {
|
||||
events[i] = eventsWithNids[i].Event
|
||||
}
|
||||
|
|
@ -587,7 +590,7 @@ func joinEventsFromHistoryVisibility(
|
|||
return evs, visibility, err
|
||||
}
|
||||
|
||||
func persistEvents(ctx context.Context, db storage.Database, events []*gomatrixserverlib.HeaderedEvent) (types.RoomNID, map[string]types.Event) {
|
||||
func persistEvents(ctx context.Context, db storage.Database, events []*gomatrixserverlib.Event) (types.RoomNID, map[string]types.Event) {
|
||||
var roomNID types.RoomNID
|
||||
var eventNID types.EventNID
|
||||
backfilledEventMap := make(map[string]types.Event)
|
||||
|
|
@ -604,7 +607,7 @@ func persistEvents(ctx context.Context, db storage.Database, events []*gomatrixs
|
|||
i++
|
||||
}
|
||||
|
||||
roomInfo, err := db.GetOrCreateRoomInfo(ctx, ev.Unwrap())
|
||||
roomInfo, err := db.GetOrCreateRoomInfo(ctx, ev)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("failed to get or create roomNID")
|
||||
continue
|
||||
|
|
@ -623,7 +626,7 @@ func persistEvents(ctx context.Context, db storage.Database, events []*gomatrixs
|
|||
continue
|
||||
}
|
||||
|
||||
eventNID, _, err = db.StoreEvent(ctx, ev.Unwrap(), roomInfo, eventTypeNID, eventStateKeyNID, authNids, false)
|
||||
eventNID, _, err = db.StoreEvent(ctx, ev, roomInfo, eventTypeNID, eventStateKeyNID, authNids, false)
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("event_id", ev.EventID()).Error("Failed to persist event")
|
||||
continue
|
||||
|
|
@ -631,7 +634,7 @@ func persistEvents(ctx context.Context, db storage.Database, events []*gomatrixs
|
|||
|
||||
resolver := state.NewStateResolution(db, roomInfo)
|
||||
|
||||
_, redactedEvent, err := db.MaybeRedactEvent(ctx, roomInfo, eventNID, ev.Unwrap(), &resolver)
|
||||
_, redactedEvent, err := db.MaybeRedactEvent(ctx, roomInfo, eventNID, ev, &resolver)
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("event_id", ev.EventID()).Error("Failed to redact event")
|
||||
continue
|
||||
|
|
@ -640,12 +643,12 @@ func persistEvents(ctx context.Context, db storage.Database, events []*gomatrixs
|
|||
// It's also possible for this event to be a redaction which results in another event being
|
||||
// redacted, which we don't care about since we aren't returning it in this backfill.
|
||||
if redactedEvent != nil && redactedEvent.EventID() == ev.EventID() {
|
||||
ev = redactedEvent.Headered(ev.RoomVersion)
|
||||
ev = redactedEvent
|
||||
events[j] = ev
|
||||
}
|
||||
backfilledEventMap[ev.EventID()] = types.Event{
|
||||
EventNID: eventNID,
|
||||
Event: ev.Unwrap(),
|
||||
Event: ev,
|
||||
}
|
||||
}
|
||||
return roomNID, backfilledEventMap
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ func (r *InboundPeeker) PerformInboundPeek(
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var sortedLatestEvents []*gomatrixserverlib.Event
|
||||
var sortedLatestEvents []gomatrixserverlib.PDU
|
||||
for _, ev := range latestEvents {
|
||||
sortedLatestEvents = append(sortedLatestEvents, ev.Event)
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ func (r *InboundPeeker) PerformInboundPeek(
|
|||
sortedLatestEvents,
|
||||
gomatrixserverlib.TopologicalOrderByPrevEvents,
|
||||
)
|
||||
response.LatestEvent = sortedLatestEvents[0].Headered(info.RoomVersion)
|
||||
response.LatestEvent = &types.HeaderedEvent{Event: sortedLatestEvents[0].(*gomatrixserverlib.Event)}
|
||||
|
||||
// XXX: do we actually need to do a state resolution here?
|
||||
roomState := state.NewStateResolution(r.DB, info)
|
||||
|
|
@ -106,11 +106,11 @@ func (r *InboundPeeker) PerformInboundPeek(
|
|||
}
|
||||
|
||||
for _, event := range stateEvents {
|
||||
response.StateEvents = append(response.StateEvents, event.Headered(info.RoomVersion))
|
||||
response.StateEvents = append(response.StateEvents, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
|
||||
for _, event := range authEvents {
|
||||
response.AuthChainEvents = append(response.AuthChainEvents, event.Headered(info.RoomVersion))
|
||||
response.AuthChainEvents = append(response.AuthChainEvents, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
|
||||
err = r.Inputer.OutputProducer.ProduceRoomEvents(request.RoomID, []api.OutputEvent{
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ type Inviter struct {
|
|||
func (r *Inviter) PerformInvite(
|
||||
ctx context.Context,
|
||||
req *api.PerformInviteRequest,
|
||||
res *api.PerformInviteResponse,
|
||||
) ([]api.OutputEvent, error) {
|
||||
var outputUpdates []api.OutputEvent
|
||||
event := req.Event
|
||||
|
|
@ -66,20 +65,12 @@ func (r *Inviter) PerformInvite(
|
|||
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', targetUserID)
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("The user ID %q is invalid!", targetUserID),
|
||||
}
|
||||
return nil, nil
|
||||
return nil, api.ErrInvalidID{Err: fmt.Errorf("the user ID %s is invalid", targetUserID)}
|
||||
}
|
||||
isTargetLocal := r.Cfg.Matrix.IsLocalServerName(domain)
|
||||
isOriginLocal := r.Cfg.Matrix.IsLocalServerName(senderDomain)
|
||||
if !isOriginLocal && !isTargetLocal {
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: "The invite must be either from or to a local user",
|
||||
}
|
||||
return nil, nil
|
||||
return nil, api.ErrInvalidID{Err: fmt.Errorf("the invite must be either from or to a local user")}
|
||||
}
|
||||
|
||||
logger := util.GetLogger(ctx).WithFields(map[string]interface{}{
|
||||
|
|
@ -119,8 +110,8 @@ func (r *Inviter) PerformInvite(
|
|||
}
|
||||
outputUpdates, err = helpers.UpdateToInviteMembership(updater, &types.Event{
|
||||
EventNID: 0,
|
||||
Event: event.Unwrap(),
|
||||
}, outputUpdates, req.Event.RoomVersion)
|
||||
Event: event.Event,
|
||||
}, outputUpdates, req.Event.Version())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("updateToInviteMembership: %w", err)
|
||||
}
|
||||
|
|
@ -175,12 +166,8 @@ func (r *Inviter) PerformInvite(
|
|||
// For now we will implement option 2. Since in the abesence of a retry
|
||||
// mechanism it will be equivalent to option 1, and we don't have a
|
||||
// signalling mechanism to implement option 3.
|
||||
res.Error = &api.PerformError{
|
||||
Code: api.PerformErrorNotAllowed,
|
||||
Msg: "User is already joined to room",
|
||||
}
|
||||
logger.Debugf("user already joined")
|
||||
return nil, nil
|
||||
return nil, api.ErrNotAllowed{Err: fmt.Errorf("user is already joined to room")}
|
||||
}
|
||||
|
||||
// If the invite originated remotely then we can't send an
|
||||
|
|
@ -201,11 +188,7 @@ func (r *Inviter) PerformInvite(
|
|||
logger.WithError(err).WithField("event_id", event.EventID()).WithField("auth_event_ids", event.AuthEventIDs()).Error(
|
||||
"processInviteEvent.checkAuthEvents failed for event",
|
||||
)
|
||||
res.Error = &api.PerformError{
|
||||
Msg: err.Error(),
|
||||
Code: api.PerformErrorNotAllowed,
|
||||
}
|
||||
return nil, nil
|
||||
return nil, api.ErrNotAllowed{Err: err}
|
||||
}
|
||||
|
||||
// If the invite originated from us and the target isn't local then we
|
||||
|
|
@ -220,12 +203,8 @@ func (r *Inviter) PerformInvite(
|
|||
}
|
||||
fsRes := &federationAPI.PerformInviteResponse{}
|
||||
if err = r.FSAPI.PerformInvite(ctx, fsReq, fsRes); err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Msg: err.Error(),
|
||||
Code: api.PerformErrorNotAllowed,
|
||||
}
|
||||
logger.WithError(err).WithField("event_id", event.EventID()).Error("r.FSAPI.PerformInvite failed")
|
||||
return nil, nil
|
||||
return nil, api.ErrNotAllowed{Err: err}
|
||||
}
|
||||
event = fsRes.Event
|
||||
logger.Debugf("Federated PerformInvite success with event ID %s", event.EventID())
|
||||
|
|
@ -251,11 +230,8 @@ func (r *Inviter) PerformInvite(
|
|||
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()),
|
||||
Code: api.PerformErrorNotAllowed,
|
||||
}
|
||||
logger.WithError(err).WithField("event_id", event.EventID()).Error("r.InputRoomEvents failed")
|
||||
return nil, api.ErrNotAllowed{Err: err}
|
||||
}
|
||||
|
||||
// Don't notify the sync api of this event in the same way as a federated invite so the invitee
|
||||
|
|
@ -300,7 +276,7 @@ func buildInviteStrippedState(
|
|||
inviteState := []fclient.InviteV2StrippedState{
|
||||
fclient.NewInviteV2StrippedState(input.Event.Event),
|
||||
}
|
||||
stateEvents = append(stateEvents, types.Event{Event: input.Event.Unwrap()})
|
||||
stateEvents = append(stateEvents, types.Event{Event: input.Event.Event})
|
||||
for _, event := range stateEvents {
|
||||
inviteState = append(inviteState, fclient.NewInviteV2StrippedState(event.Event))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/roomserver/internal/input"
|
||||
"github.com/matrix-org/dendrite/roomserver/internal/query"
|
||||
"github.com/matrix-org/dendrite/roomserver/storage"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
)
|
||||
|
||||
|
|
@ -53,32 +54,22 @@ type Joiner struct {
|
|||
func (r *Joiner) PerformJoin(
|
||||
ctx context.Context,
|
||||
req *rsAPI.PerformJoinRequest,
|
||||
res *rsAPI.PerformJoinResponse,
|
||||
) error {
|
||||
) (roomID string, joinedVia spec.ServerName, err error) {
|
||||
logger := logrus.WithContext(ctx).WithFields(logrus.Fields{
|
||||
"room_id": req.RoomIDOrAlias,
|
||||
"user_id": req.UserID,
|
||||
"servers": req.ServerNames,
|
||||
})
|
||||
logger.Info("User requested to room join")
|
||||
roomID, joinedVia, err := r.performJoin(context.Background(), req)
|
||||
roomID, joinedVia, err = r.performJoin(context.Background(), req)
|
||||
if err != nil {
|
||||
logger.WithError(err).Error("Failed to join room")
|
||||
sentry.CaptureException(err)
|
||||
perr, ok := err.(*rsAPI.PerformError)
|
||||
if ok {
|
||||
res.Error = perr
|
||||
} else {
|
||||
res.Error = &rsAPI.PerformError{
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return "", "", err
|
||||
}
|
||||
logger.Info("User joined room successfully")
|
||||
res.RoomID = roomID
|
||||
res.JoinedVia = joinedVia
|
||||
return nil
|
||||
|
||||
return roomID, joinedVia, nil
|
||||
}
|
||||
|
||||
func (r *Joiner) performJoin(
|
||||
|
|
@ -87,16 +78,10 @@ func (r *Joiner) performJoin(
|
|||
) (string, spec.ServerName, error) {
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
||||
if err != nil {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
||||
}
|
||||
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("supplied user ID %q in incorrect format", req.UserID)}
|
||||
}
|
||||
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
||||
}
|
||||
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("user %q does not belong to this homeserver", req.UserID)}
|
||||
}
|
||||
if strings.HasPrefix(req.RoomIDOrAlias, "!") {
|
||||
return r.performJoinRoomByID(ctx, req)
|
||||
|
|
@ -104,10 +89,7 @@ func (r *Joiner) performJoin(
|
|||
if strings.HasPrefix(req.RoomIDOrAlias, "#") {
|
||||
return r.performJoinRoomByAlias(ctx, req)
|
||||
}
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Room ID or alias %q is invalid", req.RoomIDOrAlias),
|
||||
}
|
||||
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("room ID or alias %q is invalid", req.RoomIDOrAlias)}
|
||||
}
|
||||
|
||||
func (r *Joiner) performJoinRoomByAlias(
|
||||
|
|
@ -182,10 +164,7 @@ func (r *Joiner) performJoinRoomByID(
|
|||
// Get the domain part of the room ID.
|
||||
_, domain, err := gomatrixserverlib.SplitID('!', req.RoomIDOrAlias)
|
||||
if err != nil {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Room ID %q is invalid: %s", req.RoomIDOrAlias, err),
|
||||
}
|
||||
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("room ID %q is invalid: %w", req.RoomIDOrAlias, err)}
|
||||
}
|
||||
|
||||
// If the server name in the room ID isn't ours then it's a
|
||||
|
|
@ -199,10 +178,7 @@ func (r *Joiner) performJoinRoomByID(
|
|||
userID := req.UserID
|
||||
_, userDomain, err := r.Cfg.Matrix.SplitLocalID('@', userID)
|
||||
if err != nil {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("User ID %q is invalid: %s", userID, err),
|
||||
}
|
||||
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("user ID %q is invalid: %w", userID, err)}
|
||||
}
|
||||
eb := gomatrixserverlib.EventBuilder{
|
||||
Type: spec.MRoomMember,
|
||||
|
|
@ -273,7 +249,7 @@ func (r *Joiner) performJoinRoomByID(
|
|||
|
||||
// If a guest is trying to join a room, check that the room has a m.room.guest_access event
|
||||
if req.IsGuest {
|
||||
var guestAccessEvent *gomatrixserverlib.HeaderedEvent
|
||||
var guestAccessEvent *types.HeaderedEvent
|
||||
guestAccess := "forbidden"
|
||||
guestAccessEvent, err = r.DB.GetStateEvent(ctx, req.RoomIDOrAlias, spec.MRoomGuestAccess, "")
|
||||
if (err != nil && !errors.Is(err, sql.ErrNoRows)) || guestAccessEvent == nil {
|
||||
|
|
@ -286,10 +262,7 @@ func (r *Joiner) performJoinRoomByID(
|
|||
// Servers MUST only allow guest users to join rooms if the m.room.guest_access state event
|
||||
// is present on the room and has the guest_access value can_join.
|
||||
if guestAccess != "can_join" {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorNotAllowed,
|
||||
Msg: "Guest access is forbidden",
|
||||
}
|
||||
return "", "", rsAPI.ErrNotAllowed{Err: fmt.Errorf("guest access is forbidden")}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -334,23 +307,17 @@ func (r *Joiner) performJoinRoomByID(
|
|||
InputRoomEvents: []rsAPI.InputRoomEvent{
|
||||
{
|
||||
Kind: rsAPI.KindNew,
|
||||
Event: event.Headered(buildRes.RoomVersion),
|
||||
Event: event,
|
||||
SendAsServer: string(userDomain),
|
||||
},
|
||||
},
|
||||
}
|
||||
inputRes := rsAPI.InputRoomEventsResponse{}
|
||||
if err = r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes); err != nil {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorNoOperation,
|
||||
Msg: fmt.Sprintf("InputRoomEvents failed: %s", err),
|
||||
}
|
||||
return "", "", rsAPI.ErrNotAllowed{Err: err}
|
||||
}
|
||||
if err = inputRes.Err(); err != nil {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorNotAllowed,
|
||||
Msg: fmt.Sprintf("InputRoomEvents auth failed: %s", err),
|
||||
}
|
||||
return "", "", rsAPI.ErrNotAllowed{Err: err}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -363,10 +330,7 @@ func (r *Joiner) performJoinRoomByID(
|
|||
// Otherwise we'll try a federated join as normal, since it's quite
|
||||
// possible that the room still exists on other servers.
|
||||
if len(req.ServerNames) == 0 {
|
||||
return "", "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorNoRoom,
|
||||
Msg: fmt.Sprintf("room ID %q does not exist", req.RoomIDOrAlias),
|
||||
}
|
||||
return "", "", eventutil.ErrRoomNoExists
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -401,11 +365,7 @@ func (r *Joiner) performFederatedJoinRoomByID(
|
|||
fedRes := fsAPI.PerformJoinResponse{}
|
||||
r.FSAPI.PerformJoin(ctx, &fedReq, &fedRes)
|
||||
if fedRes.LastError != nil {
|
||||
return "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrRemote,
|
||||
Msg: fedRes.LastError.Message,
|
||||
RemoteCode: fedRes.LastError.Code,
|
||||
}
|
||||
return "", fedRes.LastError
|
||||
}
|
||||
return fedRes.JoinedVia, nil
|
||||
}
|
||||
|
|
@ -429,10 +389,7 @@ func (r *Joiner) populateAuthorisedViaUserForRestrictedJoin(
|
|||
return "", nil
|
||||
}
|
||||
if !res.Allowed {
|
||||
return "", &rsAPI.PerformError{
|
||||
Code: rsAPI.PerformErrorNotAllowed,
|
||||
Msg: fmt.Sprintf("The join to room %s was not allowed.", joinReq.RoomIDOrAlias),
|
||||
}
|
||||
return "", rsAPI.ErrNotAllowed{Err: fmt.Errorf("the join to room %s was not allowed", joinReq.RoomIDOrAlias)}
|
||||
}
|
||||
return res.AuthorisedVia, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ func (r *Leaver) performLeaveRoomByID(
|
|||
InputRoomEvents: []api.InputRoomEvent{
|
||||
{
|
||||
Kind: api.KindNew,
|
||||
Event: event.Headered(buildRes.RoomVersion),
|
||||
Event: event,
|
||||
Origin: senderDomain,
|
||||
SendAsServer: string(senderDomain),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -44,21 +44,8 @@ type Peeker struct {
|
|||
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)
|
||||
if ok {
|
||||
res.Error = perr
|
||||
} else {
|
||||
res.Error = &api.PerformError{
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
res.RoomID = roomID
|
||||
return nil
|
||||
) (roomID string, err error) {
|
||||
return r.performPeek(ctx, req)
|
||||
}
|
||||
|
||||
func (r *Peeker) performPeek(
|
||||
|
|
@ -68,16 +55,10 @@ func (r *Peeker) performPeek(
|
|||
// FIXME: there's way too much duplication with performJoin
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
||||
if err != nil {
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
||||
}
|
||||
return "", api.ErrInvalidID{Err: fmt.Errorf("supplied user ID %q in incorrect format", req.UserID)}
|
||||
}
|
||||
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
||||
}
|
||||
return "", api.ErrInvalidID{Err: fmt.Errorf("user %q does not belong to this homeserver", req.UserID)}
|
||||
}
|
||||
if strings.HasPrefix(req.RoomIDOrAlias, "!") {
|
||||
return r.performPeekRoomByID(ctx, req)
|
||||
|
|
@ -85,10 +66,7 @@ func (r *Peeker) performPeek(
|
|||
if strings.HasPrefix(req.RoomIDOrAlias, "#") {
|
||||
return r.performPeekRoomByAlias(ctx, req)
|
||||
}
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Room ID or alias %q is invalid", req.RoomIDOrAlias),
|
||||
}
|
||||
return "", api.ErrInvalidID{Err: fmt.Errorf("room ID or alias %q is invalid", req.RoomIDOrAlias)}
|
||||
}
|
||||
|
||||
func (r *Peeker) performPeekRoomByAlias(
|
||||
|
|
@ -98,7 +76,7 @@ func (r *Peeker) performPeekRoomByAlias(
|
|||
// Get the domain part of the room alias.
|
||||
_, domain, err := gomatrixserverlib.SplitID('#', req.RoomIDOrAlias)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("alias %q is not in the correct format", req.RoomIDOrAlias)
|
||||
return "", api.ErrInvalidID{Err: fmt.Errorf("alias %q is not in the correct format", req.RoomIDOrAlias)}
|
||||
}
|
||||
req.ServerNames = append(req.ServerNames, domain)
|
||||
|
||||
|
|
@ -147,10 +125,7 @@ func (r *Peeker) performPeekRoomByID(
|
|||
// Get the domain part of the room ID.
|
||||
_, domain, err := gomatrixserverlib.SplitID('!', roomID)
|
||||
if err != nil {
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Room ID %q is invalid: %s", roomID, err),
|
||||
}
|
||||
return "", api.ErrInvalidID{Err: fmt.Errorf("room ID %q is invalid: %w", roomID, err)}
|
||||
}
|
||||
|
||||
// handle federated peeks
|
||||
|
|
@ -169,11 +144,7 @@ func (r *Peeker) performPeekRoomByID(
|
|||
fedRes := fsAPI.PerformOutboundPeekResponse{}
|
||||
_ = r.FSAPI.PerformOutboundPeek(ctx, &fedReq, &fedRes)
|
||||
if fedRes.LastError != nil {
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrRemote,
|
||||
Msg: fedRes.LastError.Message,
|
||||
RemoteCode: fedRes.LastError.Code,
|
||||
}
|
||||
return "", fedRes.LastError
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,17 +165,11 @@ func (r *Peeker) performPeekRoomByID(
|
|||
}
|
||||
|
||||
if !worldReadable {
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrorNotAllowed,
|
||||
Msg: "Room is not world-readable",
|
||||
}
|
||||
return "", api.ErrNotAllowed{Err: fmt.Errorf("room is not world-readable")}
|
||||
}
|
||||
|
||||
if ev, _ := r.DB.GetStateEvent(ctx, roomID, "m.room.encryption", ""); ev != nil {
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrorNotAllowed,
|
||||
Msg: "Cannot peek into an encrypted room",
|
||||
}
|
||||
return "", api.ErrNotAllowed{Err: fmt.Errorf("Cannot peek into an encrypted room")}
|
||||
}
|
||||
|
||||
// TODO: handle federated peeks
|
||||
|
|
|
|||
|
|
@ -25,16 +25,10 @@ type Publisher struct {
|
|||
DB storage.Database
|
||||
}
|
||||
|
||||
// PerformPublish publishes or unpublishes a room from the room directory. Returns a database error, if any.
|
||||
func (r *Publisher) PerformPublish(
|
||||
ctx context.Context,
|
||||
req *api.PerformPublishRequest,
|
||||
res *api.PerformPublishResponse,
|
||||
) error {
|
||||
err := r.DB.PublishRoom(ctx, req.RoomID, req.AppserviceID, req.NetworkID, req.Visibility == "public")
|
||||
if err != nil {
|
||||
res.Error = &api.PerformError{
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return r.DB.PublishRoom(ctx, req.RoomID, req.AppserviceID, req.NetworkID, req.Visibility == "public")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,84 +34,48 @@ type Unpeeker struct {
|
|||
Inputer *input.Inputer
|
||||
}
|
||||
|
||||
// PerformPeek handles peeking into matrix rooms, including over federation by talking to the federationapi.
|
||||
// PerformUnpeek handles un-peeking matrix rooms, including over federation by talking to the federationapi.
|
||||
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 {
|
||||
res.Error = perr
|
||||
} else {
|
||||
res.Error = &api.PerformError{
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Unpeeker) performUnpeek(
|
||||
ctx context.Context,
|
||||
req *api.PerformUnpeekRequest,
|
||||
roomID, userID, deviceID string,
|
||||
) error {
|
||||
// FIXME: there's way too much duplication with performJoin
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
|
||||
_, domain, err := gomatrixserverlib.SplitID('@', userID)
|
||||
if err != nil {
|
||||
return &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
||||
}
|
||||
return api.ErrInvalidID{Err: fmt.Errorf("supplied user ID %q in incorrect format", userID)}
|
||||
}
|
||||
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||
return &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
||||
}
|
||||
return api.ErrInvalidID{Err: fmt.Errorf("user %q does not belong to this homeserver", userID)}
|
||||
}
|
||||
if strings.HasPrefix(req.RoomID, "!") {
|
||||
return r.performUnpeekRoomByID(ctx, req)
|
||||
}
|
||||
return &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Room ID %q is invalid", req.RoomID),
|
||||
if strings.HasPrefix(roomID, "!") {
|
||||
return r.performUnpeekRoomByID(ctx, roomID, userID, deviceID)
|
||||
}
|
||||
return api.ErrInvalidID{Err: fmt.Errorf("room ID %q is invalid", roomID)}
|
||||
}
|
||||
|
||||
func (r *Unpeeker) performUnpeekRoomByID(
|
||||
_ context.Context,
|
||||
req *api.PerformUnpeekRequest,
|
||||
roomID, userID, deviceID string,
|
||||
) (err error) {
|
||||
// Get the domain part of the room ID.
|
||||
_, _, err = gomatrixserverlib.SplitID('!', req.RoomID)
|
||||
_, _, err = gomatrixserverlib.SplitID('!', roomID)
|
||||
if err != nil {
|
||||
return &api.PerformError{
|
||||
Code: api.PerformErrorBadRequest,
|
||||
Msg: fmt.Sprintf("Room ID %q is invalid: %s", req.RoomID, err),
|
||||
}
|
||||
return api.ErrInvalidID{Err: fmt.Errorf("room ID %q is invalid: %w", roomID, err)}
|
||||
}
|
||||
|
||||
// TODO: handle federated peeks
|
||||
|
||||
err = r.Inputer.OutputProducer.ProduceRoomEvents(req.RoomID, []api.OutputEvent{
|
||||
{
|
||||
Type: api.OutputTypeRetirePeek,
|
||||
RetirePeek: &api.OutputRetirePeek{
|
||||
RoomID: req.RoomID,
|
||||
UserID: req.UserID,
|
||||
DeviceID: req.DeviceID,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// By this point, if req.RoomIDOrAlias contained an alias, then
|
||||
// it will have been overwritten with a room ID by performPeekRoomByAlias.
|
||||
// We should now include this in the response so that the CS API can
|
||||
// return the right room ID.
|
||||
return nil
|
||||
return r.Inputer.OutputProducer.ProduceRoomEvents(roomID, []api.OutputEvent{
|
||||
{
|
||||
Type: api.OutputTypeRetirePeek,
|
||||
RetirePeek: &api.OutputRetirePeek{
|
||||
RoomID: roomID,
|
||||
UserID: userID,
|
||||
DeviceID: deviceID,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
|
|
@ -44,46 +45,29 @@ type fledglingEvent struct {
|
|||
// PerformRoomUpgrade upgrades a room from one version to another
|
||||
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
|
||||
roomID, userID string, roomVersion gomatrixserverlib.RoomVersion,
|
||||
) (newRoomID string, err error) {
|
||||
return r.performRoomUpgrade(ctx, roomID, userID, roomVersion)
|
||||
}
|
||||
|
||||
func (r *Upgrader) performRoomUpgrade(
|
||||
ctx context.Context,
|
||||
req *api.PerformRoomUpgradeRequest,
|
||||
) (string, *api.PerformError) {
|
||||
roomID := req.RoomID
|
||||
userID := req.UserID
|
||||
roomID, userID string, roomVersion gomatrixserverlib.RoomVersion,
|
||||
) (string, error) {
|
||||
_, userDomain, err := r.Cfg.Matrix.SplitLocalID('@', userID)
|
||||
if err != nil {
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrorNotAllowed,
|
||||
Msg: "Error validating the user ID",
|
||||
}
|
||||
return "", api.ErrNotAllowed{Err: fmt.Errorf("error validating the user ID")}
|
||||
}
|
||||
evTime := time.Now()
|
||||
|
||||
// Return an immediate error if the room does not exist
|
||||
if err := r.validateRoomExists(ctx, roomID); err != nil {
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrorNoRoom,
|
||||
Msg: "Error validating that the room exists",
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 1. Check if the user is authorized to actually perform the upgrade (can send m.room.tombstone)
|
||||
if !r.userIsAuthorized(ctx, userID, roomID) {
|
||||
return "", &api.PerformError{
|
||||
Code: api.PerformErrorNotAllowed,
|
||||
Msg: "You don't have permission to upgrade the room, power level too low.",
|
||||
}
|
||||
return "", api.ErrNotAllowed{Err: fmt.Errorf("You don't have permission to upgrade the room, power level too low.")}
|
||||
}
|
||||
|
||||
// TODO (#267): Check room ID doesn't clash with an existing one, and we
|
||||
|
|
@ -96,9 +80,7 @@ func (r *Upgrader) performRoomUpgrade(
|
|||
}
|
||||
oldRoomRes := &api.QueryLatestEventsAndStateResponse{}
|
||||
if err := r.URSAPI.QueryLatestEventsAndState(ctx, oldRoomReq, oldRoomRes); err != nil {
|
||||
return "", &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to get latest state: %s", err),
|
||||
}
|
||||
return "", fmt.Errorf("Failed to get latest state: %s", err)
|
||||
}
|
||||
|
||||
// Make the tombstone event
|
||||
|
|
@ -109,13 +91,13 @@ func (r *Upgrader) performRoomUpgrade(
|
|||
|
||||
// Generate the initial events we need to send into the new room. This includes copied state events and bans
|
||||
// as well as the power level events needed to set up the room
|
||||
eventsToMake, pErr := r.generateInitialEvents(ctx, oldRoomRes, userID, roomID, string(req.RoomVersion), tombstoneEvent)
|
||||
eventsToMake, pErr := r.generateInitialEvents(ctx, oldRoomRes, userID, roomID, roomVersion, tombstoneEvent)
|
||||
if pErr != nil {
|
||||
return "", pErr
|
||||
}
|
||||
|
||||
// Send the setup events to the new room
|
||||
if pErr = r.sendInitialEvents(ctx, evTime, userID, userDomain, newRoomID, string(req.RoomVersion), eventsToMake); pErr != nil {
|
||||
if pErr = r.sendInitialEvents(ctx, evTime, userID, userDomain, newRoomID, roomVersion, eventsToMake); pErr != nil {
|
||||
return "", pErr
|
||||
}
|
||||
|
||||
|
|
@ -147,22 +129,15 @@ func (r *Upgrader) performRoomUpgrade(
|
|||
return newRoomID, nil
|
||||
}
|
||||
|
||||
func (r *Upgrader) getRoomPowerLevels(ctx context.Context, roomID string) (*gomatrixserverlib.PowerLevelContent, *api.PerformError) {
|
||||
func (r *Upgrader) getRoomPowerLevels(ctx context.Context, roomID string) (*gomatrixserverlib.PowerLevelContent, error) {
|
||||
oldPowerLevelsEvent := api.GetStateEvent(ctx, r.URSAPI, roomID, gomatrixserverlib.StateKeyTuple{
|
||||
EventType: spec.MRoomPowerLevels,
|
||||
StateKey: "",
|
||||
})
|
||||
powerLevelContent, err := oldPowerLevelsEvent.PowerLevels()
|
||||
if err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error()
|
||||
return nil, &api.PerformError{
|
||||
Msg: "Power level event was invalid or malformed",
|
||||
}
|
||||
}
|
||||
return powerLevelContent, nil
|
||||
return oldPowerLevelsEvent.PowerLevels()
|
||||
}
|
||||
|
||||
func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.Time, userID string, userDomain spec.ServerName, roomID string) *api.PerformError {
|
||||
func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.Time, userID string, userDomain spec.ServerName, roomID string) error {
|
||||
restrictedPowerLevelContent, pErr := r.getRoomPowerLevels(ctx, roomID)
|
||||
if pErr != nil {
|
||||
return pErr
|
||||
|
|
@ -184,54 +159,46 @@ func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.T
|
|||
StateKey: "",
|
||||
Content: restrictedPowerLevelContent,
|
||||
})
|
||||
if resErr != nil {
|
||||
if resErr.Code == api.PerformErrorNotAllowed {
|
||||
util.GetLogger(ctx).WithField(logrus.ErrorKey, resErr).Warn("UpgradeRoom: Could not restrict power levels in old room")
|
||||
} else {
|
||||
return resErr
|
||||
}
|
||||
} else {
|
||||
if resErr = r.sendHeaderedEvent(ctx, userDomain, restrictedPowerLevelsHeadered, api.DoNotSendToOtherServers); resErr != nil {
|
||||
return resErr
|
||||
}
|
||||
|
||||
switch resErr.(type) {
|
||||
case api.ErrNotAllowed:
|
||||
util.GetLogger(ctx).WithField(logrus.ErrorKey, resErr).Warn("UpgradeRoom: Could not restrict power levels in old room")
|
||||
case nil:
|
||||
return r.sendHeaderedEvent(ctx, userDomain, restrictedPowerLevelsHeadered, api.DoNotSendToOtherServers)
|
||||
default:
|
||||
return resErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func moveLocalAliases(ctx context.Context,
|
||||
roomID, newRoomID, userID string,
|
||||
URSAPI api.RoomserverInternalAPI) *api.PerformError {
|
||||
var err error
|
||||
URSAPI api.RoomserverInternalAPI,
|
||||
) (err error) {
|
||||
|
||||
aliasReq := api.GetAliasesForRoomIDRequest{RoomID: roomID}
|
||||
aliasRes := api.GetAliasesForRoomIDResponse{}
|
||||
if err = URSAPI.GetAliasesForRoomID(ctx, &aliasReq, &aliasRes); err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to get old room aliases: %s", err),
|
||||
}
|
||||
return fmt.Errorf("Failed to get old room aliases: %w", err)
|
||||
}
|
||||
|
||||
for _, alias := range aliasRes.Aliases {
|
||||
removeAliasReq := api.RemoveRoomAliasRequest{UserID: userID, Alias: alias}
|
||||
removeAliasRes := api.RemoveRoomAliasResponse{}
|
||||
if err = URSAPI.RemoveRoomAlias(ctx, &removeAliasReq, &removeAliasRes); err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to remove old room alias: %s", err),
|
||||
}
|
||||
return fmt.Errorf("Failed to remove old room alias: %w", err)
|
||||
}
|
||||
|
||||
setAliasReq := api.SetRoomAliasRequest{UserID: userID, Alias: alias, RoomID: newRoomID}
|
||||
setAliasRes := api.SetRoomAliasResponse{}
|
||||
if err = URSAPI.SetRoomAlias(ctx, &setAliasReq, &setAliasRes); err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to set new room alias: %s", err),
|
||||
}
|
||||
return fmt.Errorf("Failed to set new room alias: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api.QueryLatestEventsAndStateResponse, evTime time.Time, userID string, userDomain spec.ServerName, roomID string) *api.PerformError {
|
||||
func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api.QueryLatestEventsAndStateResponse, evTime time.Time, userID string, userDomain spec.ServerName, roomID string) error {
|
||||
for _, event := range oldRoom.StateEvents {
|
||||
if event.Type() != spec.MRoomCanonicalAlias || !event.StateKeyEquals("") {
|
||||
continue
|
||||
|
|
@ -241,9 +208,7 @@ func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api
|
|||
AltAliases []string `json:"alt_aliases"`
|
||||
}
|
||||
if err := json.Unmarshal(event.Content(), &aliasContent); err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to unmarshal canonical aliases: %s", err),
|
||||
}
|
||||
return fmt.Errorf("failed to unmarshal canonical aliases: %w", err)
|
||||
}
|
||||
if aliasContent.Alias == "" && len(aliasContent.AltAliases) == 0 {
|
||||
// There are no canonical aliases to clear, therefore do nothing.
|
||||
|
|
@ -255,30 +220,25 @@ func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api
|
|||
Type: spec.MRoomCanonicalAlias,
|
||||
Content: map[string]interface{}{},
|
||||
})
|
||||
if resErr != nil {
|
||||
if resErr.Code == api.PerformErrorNotAllowed {
|
||||
util.GetLogger(ctx).WithField(logrus.ErrorKey, resErr).Warn("UpgradeRoom: Could not set empty canonical alias event in old room")
|
||||
} else {
|
||||
return resErr
|
||||
}
|
||||
} else {
|
||||
if resErr = r.sendHeaderedEvent(ctx, userDomain, emptyCanonicalAliasEvent, api.DoNotSendToOtherServers); resErr != nil {
|
||||
return resErr
|
||||
}
|
||||
switch resErr.(type) {
|
||||
case api.ErrNotAllowed:
|
||||
util.GetLogger(ctx).WithField(logrus.ErrorKey, resErr).Warn("UpgradeRoom: Could not set empty canonical alias event in old room")
|
||||
case nil:
|
||||
return r.sendHeaderedEvent(ctx, userDomain, emptyCanonicalAliasEvent, api.DoNotSendToOtherServers)
|
||||
default:
|
||||
return resErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Upgrader) publishIfOldRoomWasPublic(ctx context.Context, roomID, newRoomID string) *api.PerformError {
|
||||
func (r *Upgrader) publishIfOldRoomWasPublic(ctx context.Context, roomID, newRoomID string) error {
|
||||
// check if the old room was published
|
||||
var pubQueryRes api.QueryPublishedRoomsResponse
|
||||
err := r.URSAPI.QueryPublishedRooms(ctx, &api.QueryPublishedRoomsRequest{
|
||||
RoomID: roomID,
|
||||
}, &pubQueryRes)
|
||||
if err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: "QueryPublishedRooms failed",
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// if the old room is published (was public), publish the new room
|
||||
|
|
@ -294,38 +254,27 @@ func publishNewRoomAndUnpublishOldRoom(
|
|||
oldRoomID, newRoomID string,
|
||||
) {
|
||||
// expose this room in the published room list
|
||||
var pubNewRoomRes api.PerformPublishResponse
|
||||
if err := URSAPI.PerformPublish(ctx, &api.PerformPublishRequest{
|
||||
RoomID: newRoomID,
|
||||
Visibility: "public",
|
||||
}, &pubNewRoomRes); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("failed to reach internal API")
|
||||
} else if pubNewRoomRes.Error != nil {
|
||||
Visibility: spec.Public,
|
||||
}); err != 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")
|
||||
util.GetLogger(ctx).WithError(err).Error("failed to publish room")
|
||||
}
|
||||
|
||||
var unpubOldRoomRes api.PerformPublishResponse
|
||||
// remove the old room from the published room list
|
||||
if err := URSAPI.PerformPublish(ctx, &api.PerformPublishRequest{
|
||||
RoomID: oldRoomID,
|
||||
Visibility: "private",
|
||||
}, &unpubOldRoomRes); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("failed to reach internal API")
|
||||
} else if unpubOldRoomRes.Error != nil {
|
||||
}); err != 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")
|
||||
util.GetLogger(ctx).WithError(err).Error("failed to un-publish room")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Upgrader) validateRoomExists(ctx context.Context, roomID string) error {
|
||||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
|
||||
verRes := api.QueryRoomVersionForRoomResponse{}
|
||||
if err := r.URSAPI.QueryRoomVersionForRoom(ctx, &verReq, &verRes); err != nil {
|
||||
return &api.PerformError{
|
||||
Code: api.PerformErrorNoRoom,
|
||||
Msg: "Room does not exist",
|
||||
}
|
||||
if _, err := r.URSAPI.QueryRoomVersionForRoom(ctx, roomID); err != nil {
|
||||
return eventutil.ErrRoomNoExists
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -349,15 +298,15 @@ func (r *Upgrader) userIsAuthorized(ctx context.Context, userID, roomID string,
|
|||
}
|
||||
|
||||
// nolint:gocyclo
|
||||
func (r *Upgrader) generateInitialEvents(ctx context.Context, oldRoom *api.QueryLatestEventsAndStateResponse, userID, roomID, newVersion string, tombstoneEvent *gomatrixserverlib.HeaderedEvent) ([]fledglingEvent, *api.PerformError) {
|
||||
state := make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent, len(oldRoom.StateEvents))
|
||||
func (r *Upgrader) generateInitialEvents(ctx context.Context, oldRoom *api.QueryLatestEventsAndStateResponse, userID, roomID string, newVersion gomatrixserverlib.RoomVersion, tombstoneEvent *types.HeaderedEvent) ([]fledglingEvent, error) {
|
||||
state := make(map[gomatrixserverlib.StateKeyTuple]*types.HeaderedEvent, len(oldRoom.StateEvents))
|
||||
for _, event := range oldRoom.StateEvents {
|
||||
if event.StateKey() == nil {
|
||||
// This shouldn't ever happen, but better to be safe than sorry.
|
||||
continue
|
||||
}
|
||||
if event.Type() == spec.MRoomMember && !event.StateKeyEquals(userID) {
|
||||
// With the exception of bans and invites which we do want to copy, we
|
||||
// With the exception of bans which we do want to copy, we
|
||||
// should ignore membership events that aren't our own, as event auth will
|
||||
// prevent us from being able to create membership events on behalf of other
|
||||
// users anyway unless they are invites or bans.
|
||||
|
|
@ -367,11 +316,15 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, oldRoom *api.Query
|
|||
}
|
||||
switch membership {
|
||||
case spec.Ban:
|
||||
case spec.Invite:
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
// skip events that rely on a specific user being present
|
||||
sKey := *event.StateKey()
|
||||
if event.Type() != spec.MRoomMember && len(sKey) > 0 && sKey[:1] == "@" {
|
||||
continue
|
||||
}
|
||||
state[gomatrixserverlib.StateKeyTuple{EventType: event.Type(), StateKey: *event.StateKey()}] = event
|
||||
}
|
||||
|
||||
|
|
@ -388,9 +341,7 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, oldRoom *api.Query
|
|||
// old room state. Check that they are there.
|
||||
for tuple := range override {
|
||||
if _, ok := state[tuple]; !ok {
|
||||
return nil, &api.PerformError{
|
||||
Msg: fmt.Sprintf("Essential event of type %q state key %q is missing", tuple.EventType, tuple.StateKey),
|
||||
}
|
||||
return nil, fmt.Errorf("essential event of type %q state key %q is missing", tuple.EventType, tuple.StateKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -437,9 +388,7 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, oldRoom *api.Query
|
|||
powerLevelContent, err := oldPowerLevelsEvent.PowerLevels()
|
||||
if err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error()
|
||||
return nil, &api.PerformError{
|
||||
Msg: "Power level event content was invalid",
|
||||
}
|
||||
return nil, fmt.Errorf("Power level event content was invalid")
|
||||
}
|
||||
tempPowerLevelsEvent, powerLevelsOverridden := createTemporaryPowerLevels(powerLevelContent, userID)
|
||||
|
||||
|
|
@ -503,9 +452,9 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, oldRoom *api.Query
|
|||
return eventsToMake, nil
|
||||
}
|
||||
|
||||
func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, userID string, userDomain spec.ServerName, newRoomID, newVersion string, eventsToMake []fledglingEvent) *api.PerformError {
|
||||
func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, userID string, userDomain spec.ServerName, newRoomID string, newVersion gomatrixserverlib.RoomVersion, eventsToMake []fledglingEvent) error {
|
||||
var err error
|
||||
var builtEvents []*gomatrixserverlib.HeaderedEvent
|
||||
var builtEvents []*types.HeaderedEvent
|
||||
authEvents := gomatrixserverlib.NewAuthEvents(nil)
|
||||
for i, e := range eventsToMake {
|
||||
depth := i + 1 // depth starts at 1
|
||||
|
|
@ -519,34 +468,27 @@ func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, user
|
|||
}
|
||||
err = builder.SetContent(e.Content)
|
||||
if err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to set content of new %q event: %s", builder.Type, err),
|
||||
}
|
||||
return fmt.Errorf("failed to set content of new %q event: %w", builder.Type, err)
|
||||
}
|
||||
if i > 0 {
|
||||
builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()}
|
||||
}
|
||||
var event *gomatrixserverlib.Event
|
||||
event, err = builder.AddAuthEventsAndBuild(userDomain, &authEvents, evTime, gomatrixserverlib.RoomVersion(newVersion), r.Cfg.Matrix.KeyID, r.Cfg.Matrix.PrivateKey)
|
||||
event, err = builder.AddAuthEventsAndBuild(userDomain, &authEvents, evTime, newVersion, r.Cfg.Matrix.KeyID, r.Cfg.Matrix.PrivateKey)
|
||||
if err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to build new %q event: %s", builder.Type, err),
|
||||
}
|
||||
return fmt.Errorf("failed to build new %q event: %w", builder.Type, err)
|
||||
|
||||
}
|
||||
|
||||
if err = gomatrixserverlib.Allowed(event, &authEvents); err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to auth new %q event: %s", builder.Type, err),
|
||||
}
|
||||
return fmt.Errorf("Failed to auth new %q event: %w", builder.Type, err)
|
||||
}
|
||||
|
||||
// Add the event to the list of auth events
|
||||
builtEvents = append(builtEvents, event.Headered(gomatrixserverlib.RoomVersion(newVersion)))
|
||||
builtEvents = append(builtEvents, &types.HeaderedEvent{Event: event})
|
||||
err = authEvents.AddEvent(event)
|
||||
if err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to add new %q event to auth set: %s", builder.Type, err),
|
||||
}
|
||||
return fmt.Errorf("failed to add new %q event to auth set: %w", builder.Type, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -560,9 +502,7 @@ func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, user
|
|||
})
|
||||
}
|
||||
if err = api.SendInputRoomEvents(ctx, r.URSAPI, userDomain, inputs, false); err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to send new room %q to roomserver: %s", newRoomID, err),
|
||||
}
|
||||
return fmt.Errorf("failed to send new room %q to roomserver: %w", newRoomID, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -571,7 +511,7 @@ func (r *Upgrader) makeTombstoneEvent(
|
|||
ctx context.Context,
|
||||
evTime time.Time,
|
||||
userID, roomID, newRoomID string,
|
||||
) (*gomatrixserverlib.HeaderedEvent, *api.PerformError) {
|
||||
) (*types.HeaderedEvent, error) {
|
||||
content := map[string]interface{}{
|
||||
"body": "This room has been replaced",
|
||||
"replacement_room": newRoomID,
|
||||
|
|
@ -583,7 +523,7 @@ func (r *Upgrader) makeTombstoneEvent(
|
|||
return r.makeHeaderedEvent(ctx, evTime, userID, roomID, event)
|
||||
}
|
||||
|
||||
func (r *Upgrader) makeHeaderedEvent(ctx context.Context, evTime time.Time, userID, roomID string, event fledglingEvent) (*gomatrixserverlib.HeaderedEvent, *api.PerformError) {
|
||||
func (r *Upgrader) makeHeaderedEvent(ctx context.Context, evTime time.Time, userID, roomID string, event fledglingEvent) (*types.HeaderedEvent, error) {
|
||||
builder := gomatrixserverlib.EventBuilder{
|
||||
Sender: userID,
|
||||
RoomID: roomID,
|
||||
|
|
@ -592,59 +532,36 @@ func (r *Upgrader) makeHeaderedEvent(ctx context.Context, evTime time.Time, user
|
|||
}
|
||||
err := builder.SetContent(event.Content)
|
||||
if err != nil {
|
||||
return nil, &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to set new %q event content: %s", builder.Type, err),
|
||||
}
|
||||
return nil, fmt.Errorf("failed to set new %q event content: %w", builder.Type, err)
|
||||
}
|
||||
// Get the sender domain.
|
||||
_, senderDomain, serr := r.Cfg.Matrix.SplitLocalID('@', builder.Sender)
|
||||
if serr != nil {
|
||||
return nil, &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to split user ID %q: %s", builder.Sender, err),
|
||||
}
|
||||
return nil, fmt.Errorf("Failed to split user ID %q: %w", builder.Sender, err)
|
||||
}
|
||||
identity, err := r.Cfg.Matrix.SigningIdentityFor(senderDomain)
|
||||
if err != nil {
|
||||
return nil, &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to get signing identity for %q: %s", senderDomain, err),
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get signing identity for %q: %w", senderDomain, err)
|
||||
}
|
||||
var queryRes api.QueryLatestEventsAndStateResponse
|
||||
headeredEvent, err := eventutil.QueryAndBuildEvent(ctx, &builder, r.Cfg.Matrix, identity, evTime, r.URSAPI, &queryRes)
|
||||
if err == eventutil.ErrRoomNoExists {
|
||||
return nil, &api.PerformError{
|
||||
Code: api.PerformErrorNoRoom,
|
||||
Msg: "Room does not exist",
|
||||
}
|
||||
return nil, err
|
||||
} else if e, ok := err.(gomatrixserverlib.BadJSONError); ok {
|
||||
return nil, &api.PerformError{
|
||||
Msg: e.Error(),
|
||||
}
|
||||
return nil, e
|
||||
} else if e, ok := err.(gomatrixserverlib.EventValidationError); ok {
|
||||
if e.Code == gomatrixserverlib.EventValidationTooLarge {
|
||||
return nil, &api.PerformError{
|
||||
Msg: e.Error(),
|
||||
}
|
||||
}
|
||||
return nil, &api.PerformError{
|
||||
Msg: e.Error(),
|
||||
}
|
||||
return nil, e
|
||||
} else if err != nil {
|
||||
return nil, &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to build new %q event: %s", builder.Type, err),
|
||||
}
|
||||
return nil, fmt.Errorf("failed to build new %q event: %w", builder.Type, err)
|
||||
}
|
||||
// check to see if this user can perform this operation
|
||||
stateEvents := make([]*gomatrixserverlib.Event, len(queryRes.StateEvents))
|
||||
for i := range queryRes.StateEvents {
|
||||
stateEvents[i] = queryRes.StateEvents[i].Event
|
||||
}
|
||||
provider := gomatrixserverlib.NewAuthEvents(stateEvents)
|
||||
provider := gomatrixserverlib.NewAuthEvents(gomatrixserverlib.ToPDUs(stateEvents))
|
||||
if err = gomatrixserverlib.Allowed(headeredEvent.Event, &provider); err != nil {
|
||||
return nil, &api.PerformError{
|
||||
Code: api.PerformErrorNotAllowed,
|
||||
Msg: fmt.Sprintf("Failed to auth new %q event: %s", builder.Type, err), // TODO: Is this error string comprehensible to the client?
|
||||
}
|
||||
return nil, api.ErrNotAllowed{Err: fmt.Errorf("failed to auth new %q event: %w", builder.Type, err)} // TODO: Is this error string comprehensible to the client?
|
||||
}
|
||||
|
||||
return headeredEvent, nil
|
||||
|
|
@ -690,9 +607,9 @@ func createTemporaryPowerLevels(powerLevelContent *gomatrixserverlib.PowerLevelC
|
|||
func (r *Upgrader) sendHeaderedEvent(
|
||||
ctx context.Context,
|
||||
serverName spec.ServerName,
|
||||
headeredEvent *gomatrixserverlib.HeaderedEvent,
|
||||
headeredEvent *types.HeaderedEvent,
|
||||
sendAsServer string,
|
||||
) *api.PerformError {
|
||||
) error {
|
||||
var inputs []api.InputRoomEvent
|
||||
inputs = append(inputs, api.InputRoomEvent{
|
||||
Kind: api.KindNew,
|
||||
|
|
@ -700,11 +617,5 @@ func (r *Upgrader) sendHeaderedEvent(
|
|||
Origin: serverName,
|
||||
SendAsServer: sendAsServer,
|
||||
})
|
||||
if err := api.SendInputRoomEvents(ctx, r.URSAPI, serverName, inputs, false); err != nil {
|
||||
return &api.PerformError{
|
||||
Msg: fmt.Sprintf("Failed to send new %q event to roomserver: %s", headeredEvent.Type(), err),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return api.SendInputRoomEvents(ctx, r.URSAPI, serverName, inputs, false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,14 +121,17 @@ func (r *Queryer) QueryStateAfterEvents(
|
|||
return fmt.Errorf("getAuthChain: %w", err)
|
||||
}
|
||||
|
||||
stateEvents, err = gomatrixserverlib.ResolveConflicts(info.RoomVersion, stateEvents, authEvents)
|
||||
stateEventsPDU, err := gomatrixserverlib.ResolveConflicts(
|
||||
info.RoomVersion, gomatrixserverlib.ToPDUs(stateEvents), gomatrixserverlib.ToPDUs(authEvents),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("state.ResolveConflictsAdhoc: %w", err)
|
||||
}
|
||||
stateEvents = gomatrixserverlib.TempCastToEvents(stateEventsPDU)
|
||||
}
|
||||
|
||||
for _, event := range stateEvents {
|
||||
response.StateEvents = append(response.StateEvents, event.Headered(info.RoomVersion))
|
||||
response.StateEvents = append(response.StateEvents, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -173,7 +176,7 @@ func (r *Queryer) QueryEventsByID(
|
|||
}
|
||||
|
||||
for _, event := range events {
|
||||
response.Events = append(response.Events, event.Headered(roomInfo.RoomVersion))
|
||||
response.Events = append(response.Events, &types.HeaderedEvent{Event: event.Event})
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -231,7 +234,7 @@ func (r *Queryer) QueryMembershipAtEvent(
|
|||
request *api.QueryMembershipAtEventRequest,
|
||||
response *api.QueryMembershipAtEventResponse,
|
||||
) error {
|
||||
response.Membership = make(map[string]*gomatrixserverlib.HeaderedEvent)
|
||||
response.Membership = make(map[string]*types.HeaderedEvent)
|
||||
|
||||
info, err := r.DB.RoomInfo(ctx, request.RoomID)
|
||||
if err != nil {
|
||||
|
|
@ -259,7 +262,7 @@ func (r *Queryer) QueryMembershipAtEvent(
|
|||
return err
|
||||
}
|
||||
|
||||
response.Membership = make(map[string]*gomatrixserverlib.HeaderedEvent)
|
||||
response.Membership = make(map[string]*types.HeaderedEvent)
|
||||
stateEntries, err := helpers.MembershipAtEvent(ctx, r.DB, nil, request.EventIDs, stateKeyNIDs[request.UserID])
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get state before event: %w", err)
|
||||
|
|
@ -307,7 +310,7 @@ func (r *Queryer) QueryMembershipAtEvent(
|
|||
for i := range memberships {
|
||||
ev := memberships[i]
|
||||
if ev.Type() == spec.MRoomMember && ev.StateKeyEquals(request.UserID) {
|
||||
response.Membership[eventID] = ev.Event.Headered(info.RoomVersion)
|
||||
response.Membership[eventID] = &types.HeaderedEvent{Event: ev.Event}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -518,17 +521,13 @@ func (r *Queryer) QueryMissingEvents(
|
|||
return err
|
||||
}
|
||||
|
||||
response.Events = make([]*gomatrixserverlib.HeaderedEvent, 0, len(loadedEvents)-len(eventsToFilter))
|
||||
response.Events = make([]*types.HeaderedEvent, 0, len(loadedEvents)-len(eventsToFilter))
|
||||
for _, event := range loadedEvents {
|
||||
if !eventsToFilter[event.EventID()] {
|
||||
roomVersion, verr := r.roomVersion(event.RoomID())
|
||||
if verr != nil {
|
||||
return verr
|
||||
}
|
||||
if _, ok := redactEventIDs[event.EventID()]; ok {
|
||||
event.Redact()
|
||||
}
|
||||
response.Events = append(response.Events, event.Headered(roomVersion))
|
||||
response.Events = append(response.Events, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -561,7 +560,7 @@ func (r *Queryer) QueryStateAndAuthChain(
|
|||
return err
|
||||
}
|
||||
for _, event := range authEvents {
|
||||
response.AuthChainEvents = append(response.AuthChainEvents, event.Headered(info.RoomVersion))
|
||||
response.AuthChainEvents = append(response.AuthChainEvents, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -589,19 +588,21 @@ func (r *Queryer) QueryStateAndAuthChain(
|
|||
}
|
||||
|
||||
if request.ResolveState {
|
||||
if stateEvents, err = gomatrixserverlib.ResolveConflicts(
|
||||
info.RoomVersion, stateEvents, authEvents,
|
||||
); err != nil {
|
||||
return err
|
||||
stateEventsPDU, err2 := gomatrixserverlib.ResolveConflicts(
|
||||
info.RoomVersion, gomatrixserverlib.ToPDUs(stateEvents), gomatrixserverlib.ToPDUs(authEvents),
|
||||
)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
stateEvents = gomatrixserverlib.TempCastToEvents(stateEventsPDU)
|
||||
}
|
||||
|
||||
for _, event := range stateEvents {
|
||||
response.StateEvents = append(response.StateEvents, event.Headered(info.RoomVersion))
|
||||
response.StateEvents = append(response.StateEvents, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
|
||||
for _, event := range authEvents {
|
||||
response.AuthChainEvents = append(response.AuthChainEvents, event.Headered(info.RoomVersion))
|
||||
response.AuthChainEvents = append(response.AuthChainEvents, &types.HeaderedEvent{Event: event})
|
||||
}
|
||||
|
||||
return err
|
||||
|
|
@ -696,34 +697,20 @@ func GetAuthChain(
|
|||
}
|
||||
|
||||
// QueryRoomVersionForRoom implements api.RoomserverInternalAPI
|
||||
func (r *Queryer) QueryRoomVersionForRoom(
|
||||
ctx context.Context,
|
||||
request *api.QueryRoomVersionForRoomRequest,
|
||||
response *api.QueryRoomVersionForRoomResponse,
|
||||
) error {
|
||||
if roomVersion, ok := r.Cache.GetRoomVersion(request.RoomID); ok {
|
||||
response.RoomVersion = roomVersion
|
||||
return nil
|
||||
func (r *Queryer) QueryRoomVersionForRoom(ctx context.Context, roomID string) (gomatrixserverlib.RoomVersion, error) {
|
||||
if roomVersion, ok := r.Cache.GetRoomVersion(roomID); ok {
|
||||
return roomVersion, nil
|
||||
}
|
||||
|
||||
info, err := r.DB.RoomInfo(ctx, request.RoomID)
|
||||
info, err := r.DB.RoomInfo(ctx, roomID)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
if info == nil {
|
||||
return fmt.Errorf("QueryRoomVersionForRoom: missing room info for room %s", request.RoomID)
|
||||
return "", fmt.Errorf("QueryRoomVersionForRoom: missing room info for room %s", roomID)
|
||||
}
|
||||
response.RoomVersion = info.RoomVersion
|
||||
r.Cache.StoreRoomVersion(request.RoomID, response.RoomVersion)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Queryer) roomVersion(roomID string) (gomatrixserverlib.RoomVersion, error) {
|
||||
var res api.QueryRoomVersionForRoomResponse
|
||||
err := r.QueryRoomVersionForRoom(context.Background(), &api.QueryRoomVersionForRoomRequest{
|
||||
RoomID: roomID,
|
||||
}, &res)
|
||||
return res.RoomVersion, err
|
||||
r.Cache.StoreRoomVersion(roomID, info.RoomVersion)
|
||||
return info.RoomVersion, nil
|
||||
}
|
||||
|
||||
func (r *Queryer) QueryPublishedRooms(
|
||||
|
|
@ -748,7 +735,7 @@ func (r *Queryer) QueryPublishedRooms(
|
|||
}
|
||||
|
||||
func (r *Queryer) QueryCurrentState(ctx context.Context, req *api.QueryCurrentStateRequest, res *api.QueryCurrentStateResponse) error {
|
||||
res.StateEvents = make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent)
|
||||
res.StateEvents = make(map[gomatrixserverlib.StateKeyTuple]*types.HeaderedEvent)
|
||||
for _, tuple := range req.StateTuples {
|
||||
if tuple.StateKey == "*" && req.AllowWildcards {
|
||||
events, err := r.DB.GetStateEventsWithEventType(ctx, req.RoomID, tuple.EventType)
|
||||
|
|
@ -865,9 +852,9 @@ func (r *Queryer) QueryAuthChain(ctx context.Context, req *api.QueryAuthChainReq
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hchain := make([]*gomatrixserverlib.HeaderedEvent, len(chain))
|
||||
hchain := make([]*types.HeaderedEvent, len(chain))
|
||||
for i := range chain {
|
||||
hchain[i] = chain[i].Headered(chain[i].Version())
|
||||
hchain[i] = &types.HeaderedEvent{Event: chain[i]}
|
||||
}
|
||||
res.AuthChain = hchain
|
||||
return nil
|
||||
|
|
@ -910,8 +897,8 @@ func (r *Queryer) QueryRestrictedJoinAllowed(ctx context.Context, req *api.Query
|
|||
if err = json.Unmarshal(joinRulesEvent.Content(), &joinRules); err != nil {
|
||||
return fmt.Errorf("json.Unmarshal: %w", err)
|
||||
}
|
||||
// If the join rule isn't "restricted" then there's nothing more to do.
|
||||
res.Restricted = joinRules.JoinRule == spec.Restricted
|
||||
// If the join rule isn't "restricted" or "knock_restricted" then there's nothing more to do.
|
||||
res.Restricted = joinRules.JoinRule == spec.Restricted || joinRules.JoinRule == spec.KnockRestricted
|
||||
if !res.Restricted {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -932,9 +919,9 @@ func (r *Queryer) QueryRestrictedJoinAllowed(ctx context.Context, req *api.Query
|
|||
if err != nil {
|
||||
return fmt.Errorf("r.DB.GetStateEvent: %w", err)
|
||||
}
|
||||
var powerLevels gomatrixserverlib.PowerLevelContent
|
||||
if err = json.Unmarshal(powerLevelsEvent.Content(), &powerLevels); err != nil {
|
||||
return fmt.Errorf("json.Unmarshal: %w", err)
|
||||
powerLevels, err := powerLevelsEvent.PowerLevels()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get powerlevels: %w", err)
|
||||
}
|
||||
// Step through the join rules and see if the user matches any of them.
|
||||
for _, rule := range joinRules.Allow {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func (r *RoomEventProducer) ProduceRoomEvents(roomID string, updates []api.Outpu
|
|||
}
|
||||
|
||||
if eventType == "m.room.server_acl" && update.NewRoomEvent.Event.StateKeyEquals("") {
|
||||
ev := update.NewRoomEvent.Event.Unwrap()
|
||||
ev := update.NewRoomEvent.Event.Event
|
||||
defer r.ACLs.OnServerACLUpdate(ev)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,13 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/internal/caching"
|
||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/version"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/state"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
|
|
@ -136,7 +139,7 @@ func testKickUsers(t *testing.T, rsAPI api.RoomserverInternalAPI, usrAPI userAPI
|
|||
|
||||
// revoke guest access
|
||||
revokeEvent := room.CreateAndInsert(t, alice, spec.MRoomGuestAccess, map[string]string{"guest_access": "forbidden"}, test.WithStateKey(""))
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, []*gomatrixserverlib.HeaderedEvent{revokeEvent}, "test", "test", "test", nil, false); err != nil {
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, []*types.HeaderedEvent{revokeEvent}, "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
|
|
@ -242,8 +245,8 @@ func TestPurgeRoom(t *testing.T) {
|
|||
|
||||
// this starts the JetStream consumers
|
||||
syncapi.AddPublicRoutes(processCtx, routers, cfg, cm, &natsInstance, userAPI, rsAPI, caches, caching.DisableMetrics)
|
||||
federationapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, nil, rsAPI, caches, nil, true)
|
||||
rsAPI.SetFederationAPI(nil, nil)
|
||||
fsAPI := federationapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, nil, rsAPI, caches, nil, true)
|
||||
rsAPI.SetFederationAPI(fsAPI, nil)
|
||||
|
||||
// Create the room
|
||||
if err = api.SendEvents(ctx, rsAPI, api.KindNew, room.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
|
|
@ -251,13 +254,9 @@ func TestPurgeRoom(t *testing.T) {
|
|||
}
|
||||
|
||||
// some dummy entries to validate after purging
|
||||
publishResp := &api.PerformPublishResponse{}
|
||||
if err = rsAPI.PerformPublish(ctx, &api.PerformPublishRequest{RoomID: room.ID, Visibility: "public"}, publishResp); err != nil {
|
||||
if err = rsAPI.PerformPublish(ctx, &api.PerformPublishRequest{RoomID: room.ID, Visibility: spec.Public}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if publishResp.Error != nil {
|
||||
t.Fatal(publishResp.Error)
|
||||
}
|
||||
|
||||
isPublished, err := db.GetPublishedRoom(ctx, room.ID)
|
||||
if err != nil {
|
||||
|
|
@ -325,8 +324,7 @@ func TestPurgeRoom(t *testing.T) {
|
|||
}
|
||||
|
||||
// purge the room from the database
|
||||
purgeResp := &api.PerformAdminPurgeRoomResponse{}
|
||||
if err = rsAPI.PerformAdminPurgeRoom(ctx, &api.PerformAdminPurgeRoomRequest{RoomID: room.ID}, purgeResp); err != nil {
|
||||
if err = rsAPI.PerformAdminPurgeRoom(ctx, room.ID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +399,7 @@ type fledglingEvent struct {
|
|||
PrevEvents []interface{}
|
||||
}
|
||||
|
||||
func mustCreateEvent(t *testing.T, ev fledglingEvent) (result *gomatrixserverlib.HeaderedEvent) {
|
||||
func mustCreateEvent(t *testing.T, ev fledglingEvent) (result *types.HeaderedEvent) {
|
||||
t.Helper()
|
||||
roomVer := gomatrixserverlib.RoomVersionV9
|
||||
seed := make([]byte, ed25519.SeedSize) // zero seed
|
||||
|
|
@ -423,7 +421,7 @@ func mustCreateEvent(t *testing.T, ev fledglingEvent) (result *gomatrixserverlib
|
|||
if err != nil {
|
||||
t.Fatalf("mustCreateEvent: failed to sign event: %s", err)
|
||||
}
|
||||
h := signedEvent.Headered(roomVer)
|
||||
h := &types.HeaderedEvent{Event: signedEvent}
|
||||
return h
|
||||
}
|
||||
|
||||
|
|
@ -451,7 +449,7 @@ func TestRedaction(t *testing.T) {
|
|||
Depth: redactedEvent.Depth() + 1,
|
||||
PrevEvents: []interface{}{redactedEvent.EventID()},
|
||||
})
|
||||
room.InsertEvent(t, builderEv.Headered(gomatrixserverlib.RoomVersionV9))
|
||||
room.InsertEvent(t, builderEv)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -468,7 +466,7 @@ func TestRedaction(t *testing.T) {
|
|||
Depth: redactedEvent.Depth() + 1,
|
||||
PrevEvents: []interface{}{redactedEvent.EventID()},
|
||||
})
|
||||
room.InsertEvent(t, builderEv.Headered(gomatrixserverlib.RoomVersionV9))
|
||||
room.InsertEvent(t, builderEv)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -485,7 +483,7 @@ func TestRedaction(t *testing.T) {
|
|||
Depth: redactedEvent.Depth() + 1,
|
||||
PrevEvents: []interface{}{redactedEvent.EventID()},
|
||||
})
|
||||
room.InsertEvent(t, builderEv.Headered(gomatrixserverlib.RoomVersionV9))
|
||||
room.InsertEvent(t, builderEv)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -501,7 +499,7 @@ func TestRedaction(t *testing.T) {
|
|||
Depth: redactedEvent.Depth() + 1,
|
||||
PrevEvents: []interface{}{redactedEvent.EventID()},
|
||||
})
|
||||
room.InsertEvent(t, builderEv.Headered(gomatrixserverlib.RoomVersionV9))
|
||||
room.InsertEvent(t, builderEv)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -582,3 +580,506 @@ func TestRedaction(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestQueryRestrictedJoinAllowed(t *testing.T) {
|
||||
alice := test.NewUser(t)
|
||||
bob := test.NewUser(t)
|
||||
|
||||
// a room we don't create in the database
|
||||
allowedByRoomNotExists := test.NewRoom(t, alice)
|
||||
|
||||
// a room we create in the database, used for authorisation
|
||||
allowedByRoomExists := test.NewRoom(t, alice)
|
||||
allowedByRoomExists.CreateAndInsert(t, bob, spec.MRoomMember, map[string]interface{}{
|
||||
"membership": spec.Join,
|
||||
}, test.WithStateKey(bob.ID))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
prepareRoomFunc func(t *testing.T) *test.Room
|
||||
wantResponse api.QueryRestrictedJoinAllowedResponse
|
||||
}{
|
||||
{
|
||||
name: "public room unrestricted",
|
||||
prepareRoomFunc: func(t *testing.T) *test.Room {
|
||||
return test.NewRoom(t, alice)
|
||||
},
|
||||
wantResponse: api.QueryRestrictedJoinAllowedResponse{
|
||||
Resident: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "room version without restrictions",
|
||||
prepareRoomFunc: func(t *testing.T) *test.Room {
|
||||
return test.NewRoom(t, alice, test.RoomVersion(gomatrixserverlib.RoomVersionV7))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "restricted only", // bob is not allowed to join
|
||||
prepareRoomFunc: func(t *testing.T) *test.Room {
|
||||
r := test.NewRoom(t, alice, test.RoomVersion(gomatrixserverlib.RoomVersionV8))
|
||||
r.CreateAndInsert(t, alice, spec.MRoomJoinRules, map[string]interface{}{
|
||||
"join_rule": spec.Restricted,
|
||||
}, test.WithStateKey(""))
|
||||
return r
|
||||
},
|
||||
wantResponse: api.QueryRestrictedJoinAllowedResponse{
|
||||
Resident: true,
|
||||
Restricted: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "knock_restricted",
|
||||
prepareRoomFunc: func(t *testing.T) *test.Room {
|
||||
r := test.NewRoom(t, alice, test.RoomVersion(gomatrixserverlib.RoomVersionV8))
|
||||
r.CreateAndInsert(t, alice, spec.MRoomJoinRules, map[string]interface{}{
|
||||
"join_rule": spec.KnockRestricted,
|
||||
}, test.WithStateKey(""))
|
||||
return r
|
||||
},
|
||||
wantResponse: api.QueryRestrictedJoinAllowedResponse{
|
||||
Resident: true,
|
||||
Restricted: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "restricted with pending invite", // bob should be allowed to join
|
||||
prepareRoomFunc: func(t *testing.T) *test.Room {
|
||||
r := test.NewRoom(t, alice, test.RoomVersion(gomatrixserverlib.RoomVersionV8))
|
||||
r.CreateAndInsert(t, alice, spec.MRoomJoinRules, map[string]interface{}{
|
||||
"join_rule": spec.Restricted,
|
||||
}, test.WithStateKey(""))
|
||||
r.CreateAndInsert(t, alice, spec.MRoomMember, map[string]interface{}{
|
||||
"membership": spec.Invite,
|
||||
}, test.WithStateKey(bob.ID))
|
||||
return r
|
||||
},
|
||||
wantResponse: api.QueryRestrictedJoinAllowedResponse{
|
||||
Resident: true,
|
||||
Restricted: true,
|
||||
Allowed: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "restricted with allowed room_id, but missing room", // bob should not be allowed to join, as we don't know about the room
|
||||
prepareRoomFunc: func(t *testing.T) *test.Room {
|
||||
r := test.NewRoom(t, alice, test.RoomVersion(gomatrixserverlib.RoomVersionV10))
|
||||
r.CreateAndInsert(t, alice, spec.MRoomJoinRules, map[string]interface{}{
|
||||
"join_rule": spec.KnockRestricted,
|
||||
"allow": []map[string]interface{}{
|
||||
{
|
||||
"room_id": allowedByRoomNotExists.ID,
|
||||
"type": spec.MRoomMembership,
|
||||
},
|
||||
},
|
||||
}, test.WithStateKey(""))
|
||||
r.CreateAndInsert(t, bob, spec.MRoomMember, map[string]interface{}{
|
||||
"membership": spec.Join,
|
||||
"join_authorised_via_users_server": alice.ID,
|
||||
}, test.WithStateKey(bob.ID))
|
||||
return r
|
||||
},
|
||||
wantResponse: api.QueryRestrictedJoinAllowedResponse{
|
||||
Restricted: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "restricted with allowed room_id", // bob should be allowed to join, as we know about the room
|
||||
prepareRoomFunc: func(t *testing.T) *test.Room {
|
||||
r := test.NewRoom(t, alice, test.RoomVersion(gomatrixserverlib.RoomVersionV10))
|
||||
r.CreateAndInsert(t, alice, spec.MRoomJoinRules, map[string]interface{}{
|
||||
"join_rule": spec.KnockRestricted,
|
||||
"allow": []map[string]interface{}{
|
||||
{
|
||||
"room_id": allowedByRoomExists.ID,
|
||||
"type": spec.MRoomMembership,
|
||||
},
|
||||
},
|
||||
}, test.WithStateKey(""))
|
||||
r.CreateAndInsert(t, bob, spec.MRoomMember, map[string]interface{}{
|
||||
"membership": spec.Join,
|
||||
"join_authorised_via_users_server": alice.ID,
|
||||
}, test.WithStateKey(bob.ID))
|
||||
return r
|
||||
},
|
||||
wantResponse: api.QueryRestrictedJoinAllowedResponse{
|
||||
Resident: true,
|
||||
Restricted: true,
|
||||
Allowed: true,
|
||||
AuthorisedVia: alice.ID,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
|
||||
cfg, processCtx, close := testrig.CreateConfig(t, dbType)
|
||||
natsInstance := jetstream.NATSInstance{}
|
||||
defer close()
|
||||
|
||||
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
|
||||
caches := caching.NewRistrettoCache(128*1024*1024, time.Hour, caching.DisableMetrics)
|
||||
|
||||
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, &natsInstance, caches, caching.DisableMetrics)
|
||||
rsAPI.SetFederationAPI(nil, nil)
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.prepareRoomFunc == nil {
|
||||
t.Fatal("missing prepareRoomFunc")
|
||||
}
|
||||
testRoom := tc.prepareRoomFunc(t)
|
||||
// Create the room
|
||||
if err := api.SendEvents(processCtx.Context(), rsAPI, api.KindNew, testRoom.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
if err := api.SendEvents(processCtx.Context(), rsAPI, api.KindNew, allowedByRoomExists.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
req := api.QueryRestrictedJoinAllowedRequest{
|
||||
UserID: bob.ID,
|
||||
RoomID: testRoom.ID,
|
||||
}
|
||||
res := api.QueryRestrictedJoinAllowedResponse{}
|
||||
if err := rsAPI.QueryRestrictedJoinAllowed(processCtx.Context(), &req, &res); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(tc.wantResponse, res) {
|
||||
t.Fatalf("unexpected response, want %#v - got %#v", tc.wantResponse, res)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpgrade(t *testing.T) {
|
||||
alice := test.NewUser(t)
|
||||
bob := test.NewUser(t)
|
||||
charlie := test.NewUser(t)
|
||||
ctx := context.Background()
|
||||
|
||||
spaceChild := test.NewRoom(t, alice)
|
||||
validateTuples := []gomatrixserverlib.StateKeyTuple{
|
||||
{EventType: spec.MRoomCreate},
|
||||
{EventType: spec.MRoomPowerLevels},
|
||||
{EventType: spec.MRoomJoinRules},
|
||||
{EventType: spec.MRoomName},
|
||||
{EventType: spec.MRoomCanonicalAlias},
|
||||
{EventType: "m.room.tombstone"},
|
||||
{EventType: "m.custom.event"},
|
||||
{EventType: "m.space.child", StateKey: spaceChild.ID},
|
||||
{EventType: "m.custom.event", StateKey: alice.ID},
|
||||
{EventType: spec.MRoomMember, StateKey: charlie.ID}, // ban should be transferred
|
||||
}
|
||||
|
||||
validate := func(t *testing.T, oldRoomID, newRoomID string, rsAPI api.RoomserverInternalAPI) {
|
||||
|
||||
oldRoomState := &api.QueryCurrentStateResponse{}
|
||||
if err := rsAPI.QueryCurrentState(ctx, &api.QueryCurrentStateRequest{
|
||||
RoomID: oldRoomID,
|
||||
StateTuples: validateTuples,
|
||||
}, oldRoomState); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
newRoomState := &api.QueryCurrentStateResponse{}
|
||||
if err := rsAPI.QueryCurrentState(ctx, &api.QueryCurrentStateRequest{
|
||||
RoomID: newRoomID,
|
||||
StateTuples: validateTuples,
|
||||
}, newRoomState); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// the old room should have a tombstone event
|
||||
ev := oldRoomState.StateEvents[gomatrixserverlib.StateKeyTuple{EventType: "m.room.tombstone"}]
|
||||
replacementRoom := gjson.GetBytes(ev.Content(), "replacement_room").Str
|
||||
if replacementRoom != newRoomID {
|
||||
t.Fatalf("tombstone event has replacement_room '%s', expected '%s'", replacementRoom, newRoomID)
|
||||
}
|
||||
|
||||
// the new room should have a predecessor equal to the old room
|
||||
ev = newRoomState.StateEvents[gomatrixserverlib.StateKeyTuple{EventType: spec.MRoomCreate}]
|
||||
predecessor := gjson.GetBytes(ev.Content(), "predecessor.room_id").Str
|
||||
if predecessor != oldRoomID {
|
||||
t.Fatalf("got predecessor room '%s', expected '%s'", predecessor, oldRoomID)
|
||||
}
|
||||
|
||||
for _, tuple := range validateTuples {
|
||||
// Skip create and powerlevel event (new room has e.g. predecessor event, old room has restricted powerlevels)
|
||||
switch tuple.EventType {
|
||||
case spec.MRoomCreate, spec.MRoomPowerLevels, spec.MRoomCanonicalAlias:
|
||||
continue
|
||||
}
|
||||
oldEv, ok := oldRoomState.StateEvents[tuple]
|
||||
if !ok {
|
||||
t.Logf("skipping tuple %#v as it doesn't exist in the old room", tuple)
|
||||
continue
|
||||
}
|
||||
newEv, ok := newRoomState.StateEvents[tuple]
|
||||
if !ok {
|
||||
t.Logf("skipping tuple %#v as it doesn't exist in the new room", tuple)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(oldEv.Content(), newEv.Content()) {
|
||||
t.Logf("OldEvent QueryCurrentState: %s", string(oldEv.Content()))
|
||||
t.Logf("NewEvent QueryCurrentState: %s", string(newEv.Content()))
|
||||
t.Errorf("event content mismatch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
upgradeUser string
|
||||
roomFunc func(rsAPI api.RoomserverInternalAPI) string
|
||||
validateFunc func(t *testing.T, oldRoomID, newRoomID string, rsAPI api.RoomserverInternalAPI)
|
||||
wantNewRoom bool
|
||||
}{
|
||||
{
|
||||
name: "invalid userID",
|
||||
upgradeUser: "!notvalid:test",
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
room := test.NewRoom(t, alice)
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, room.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
return room.ID
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid roomID",
|
||||
upgradeUser: alice.ID,
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
return "!doesnotexist:test"
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "powerlevel too low",
|
||||
upgradeUser: bob.ID,
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
room := test.NewRoom(t, alice)
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, room.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
return room.ID
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "successful upgrade on new room",
|
||||
upgradeUser: alice.ID,
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
room := test.NewRoom(t, alice)
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, room.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
return room.ID
|
||||
},
|
||||
wantNewRoom: true,
|
||||
validateFunc: validate,
|
||||
},
|
||||
{
|
||||
name: "successful upgrade on new room with other state events",
|
||||
upgradeUser: alice.ID,
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
r := test.NewRoom(t, alice)
|
||||
r.CreateAndInsert(t, alice, spec.MRoomName, map[string]interface{}{
|
||||
"name": "my new name",
|
||||
}, test.WithStateKey(""))
|
||||
r.CreateAndInsert(t, alice, spec.MRoomCanonicalAlias, eventutil.CanonicalAliasContent{
|
||||
Alias: "#myalias:test",
|
||||
}, test.WithStateKey(""))
|
||||
|
||||
// this will be transferred
|
||||
r.CreateAndInsert(t, alice, "m.custom.event", map[string]interface{}{
|
||||
"random": "i should exist",
|
||||
}, test.WithStateKey(""))
|
||||
|
||||
// the following will be ignored
|
||||
r.CreateAndInsert(t, alice, "m.custom.event", map[string]interface{}{
|
||||
"random": "i will be ignored",
|
||||
}, test.WithStateKey(alice.ID))
|
||||
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, r.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
return r.ID
|
||||
},
|
||||
wantNewRoom: true,
|
||||
validateFunc: validate,
|
||||
},
|
||||
{
|
||||
name: "with published room",
|
||||
upgradeUser: alice.ID,
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
r := test.NewRoom(t, alice)
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, r.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
if err := rsAPI.PerformPublish(ctx, &api.PerformPublishRequest{
|
||||
RoomID: r.ID,
|
||||
Visibility: spec.Public,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return r.ID
|
||||
},
|
||||
wantNewRoom: true,
|
||||
validateFunc: func(t *testing.T, oldRoomID, newRoomID string, rsAPI api.RoomserverInternalAPI) {
|
||||
validate(t, oldRoomID, newRoomID, rsAPI)
|
||||
// check that the new room is published
|
||||
res := &api.QueryPublishedRoomsResponse{}
|
||||
if err := rsAPI.QueryPublishedRooms(ctx, &api.QueryPublishedRoomsRequest{RoomID: newRoomID}, res); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(res.RoomIDs) == 0 {
|
||||
t.Fatalf("expected room to be published, but wasn't: %#v", res.RoomIDs)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with alias",
|
||||
upgradeUser: alice.ID,
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
r := test.NewRoom(t, alice)
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, r.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
if err := rsAPI.SetRoomAlias(ctx, &api.SetRoomAliasRequest{
|
||||
RoomID: r.ID,
|
||||
Alias: "#myroomalias:test",
|
||||
}, &api.SetRoomAliasResponse{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return r.ID
|
||||
},
|
||||
wantNewRoom: true,
|
||||
validateFunc: func(t *testing.T, oldRoomID, newRoomID string, rsAPI api.RoomserverInternalAPI) {
|
||||
validate(t, oldRoomID, newRoomID, rsAPI)
|
||||
// check that the old room has no aliases
|
||||
res := &api.GetAliasesForRoomIDResponse{}
|
||||
if err := rsAPI.GetAliasesForRoomID(ctx, &api.GetAliasesForRoomIDRequest{RoomID: oldRoomID}, res); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(res.Aliases) != 0 {
|
||||
t.Fatalf("expected old room aliases to be empty, but wasn't: %#v", res.Aliases)
|
||||
}
|
||||
|
||||
// check that the new room has aliases
|
||||
if err := rsAPI.GetAliasesForRoomID(ctx, &api.GetAliasesForRoomIDRequest{RoomID: newRoomID}, res); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(res.Aliases) == 0 {
|
||||
t.Fatalf("expected room aliases to be transferred, but wasn't: %#v", res.Aliases)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bans are transferred",
|
||||
upgradeUser: alice.ID,
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
r := test.NewRoom(t, alice)
|
||||
r.CreateAndInsert(t, alice, spec.MRoomMember, map[string]interface{}{
|
||||
"membership": spec.Ban,
|
||||
}, test.WithStateKey(charlie.ID))
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, r.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
return r.ID
|
||||
},
|
||||
wantNewRoom: true,
|
||||
validateFunc: validate,
|
||||
},
|
||||
{
|
||||
name: "space childs are transferred",
|
||||
upgradeUser: alice.ID,
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
r := test.NewRoom(t, alice)
|
||||
|
||||
r.CreateAndInsert(t, alice, "m.space.child", map[string]interface{}{}, test.WithStateKey(spaceChild.ID))
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, r.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
return r.ID
|
||||
},
|
||||
wantNewRoom: true,
|
||||
validateFunc: validate,
|
||||
},
|
||||
{
|
||||
name: "custom state is not taken to the new room", // https://github.com/matrix-org/dendrite/issues/2912
|
||||
upgradeUser: charlie.ID,
|
||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||
r := test.NewRoom(t, alice, test.RoomVersion(gomatrixserverlib.RoomVersionV6))
|
||||
// Bob and Charlie join
|
||||
r.CreateAndInsert(t, bob, spec.MRoomMember, map[string]interface{}{"membership": spec.Join}, test.WithStateKey(bob.ID))
|
||||
r.CreateAndInsert(t, charlie, spec.MRoomMember, map[string]interface{}{"membership": spec.Join}, test.WithStateKey(charlie.ID))
|
||||
|
||||
// make Charlie an admin so the room can be upgraded
|
||||
r.CreateAndInsert(t, alice, spec.MRoomPowerLevels, gomatrixserverlib.PowerLevelContent{
|
||||
Users: map[string]int64{
|
||||
charlie.ID: 100,
|
||||
},
|
||||
}, test.WithStateKey(""))
|
||||
|
||||
// Alice creates a custom event
|
||||
r.CreateAndInsert(t, alice, "m.custom.event", map[string]interface{}{
|
||||
"random": "data",
|
||||
}, test.WithStateKey(alice.ID))
|
||||
r.CreateAndInsert(t, alice, spec.MRoomMember, map[string]interface{}{"membership": spec.Leave}, test.WithStateKey(alice.ID))
|
||||
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, r.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
return r.ID
|
||||
},
|
||||
wantNewRoom: true,
|
||||
validateFunc: validate,
|
||||
},
|
||||
}
|
||||
|
||||
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
|
||||
cfg, processCtx, close := testrig.CreateConfig(t, dbType)
|
||||
natsInstance := jetstream.NATSInstance{}
|
||||
defer close()
|
||||
|
||||
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
|
||||
caches := caching.NewRistrettoCache(128*1024*1024, time.Hour, caching.DisableMetrics)
|
||||
|
||||
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, &natsInstance, caches, caching.DisableMetrics)
|
||||
userAPI := userapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, rsAPI, nil)
|
||||
rsAPI.SetFederationAPI(nil, nil)
|
||||
rsAPI.SetUserAPI(userAPI)
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.roomFunc == nil {
|
||||
t.Fatalf("missing roomFunc")
|
||||
}
|
||||
if tc.upgradeUser == "" {
|
||||
tc.upgradeUser = alice.ID
|
||||
}
|
||||
roomID := tc.roomFunc(rsAPI)
|
||||
|
||||
newRoomID, err := rsAPI.PerformRoomUpgrade(processCtx.Context(), roomID, tc.upgradeUser, version.DefaultRoomVersion())
|
||||
if err != nil && tc.wantNewRoom {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if tc.wantNewRoom && newRoomID == "" {
|
||||
t.Fatalf("expected a new room, but the upgrade failed")
|
||||
}
|
||||
if !tc.wantNewRoom && newRoomID != "" {
|
||||
t.Fatalf("expected no new room, but the upgrade succeeded")
|
||||
}
|
||||
if tc.validateFunc != nil {
|
||||
tc.validateFunc(t, roomID, newRoomID, rsAPI)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -996,7 +996,7 @@ func (v *StateResolution) resolveConflictsV2(
|
|||
// For each conflicted event, we will add a new set of auth events. Auth
|
||||
// events may be duplicated across these sets but that's OK.
|
||||
authSets := make(map[string][]*gomatrixserverlib.Event, len(conflicted))
|
||||
authEvents := make([]*gomatrixserverlib.Event, 0, estimate*3)
|
||||
authEvents := make([]gomatrixserverlib.PDU, 0, estimate*3)
|
||||
gotAuthEvents := make(map[string]struct{}, estimate*3)
|
||||
knownAuthEvents := make(map[string]types.Event, estimate*3)
|
||||
|
||||
|
|
@ -1046,7 +1046,7 @@ func (v *StateResolution) resolveConflictsV2(
|
|||
gotAuthEvents = nil // nolint:ineffassign
|
||||
|
||||
// Resolve the conflicts.
|
||||
resolvedEvents := func() []*gomatrixserverlib.Event {
|
||||
resolvedEvents := func() []gomatrixserverlib.PDU {
|
||||
resolvedTrace, _ := internal.StartRegion(ctx, "StateResolution.ResolveStateConflictsV2")
|
||||
defer resolvedTrace.EndRegion()
|
||||
|
||||
|
|
@ -1119,11 +1119,11 @@ func (v *StateResolution) stateKeyTuplesNeeded(stateKeyNIDMap map[string]types.E
|
|||
// Returns an error if there was a problem talking to the database.
|
||||
func (v *StateResolution) loadStateEvents(
|
||||
ctx context.Context, entries []types.StateEntry,
|
||||
) ([]*gomatrixserverlib.Event, map[string]types.StateEntry, error) {
|
||||
) ([]gomatrixserverlib.PDU, map[string]types.StateEntry, error) {
|
||||
trace, ctx := internal.StartRegion(ctx, "StateResolution.loadStateEvents")
|
||||
defer trace.EndRegion()
|
||||
|
||||
result := make([]*gomatrixserverlib.Event, 0, len(entries))
|
||||
result := make([]gomatrixserverlib.PDU, 0, len(entries))
|
||||
eventEntries := make([]types.StateEntry, 0, len(entries))
|
||||
eventNIDs := make(types.EventNIDs, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
|
|
@ -1163,7 +1163,7 @@ type authEventLoader struct {
|
|||
// loadAuthEvents loads all of the auth events for a given event recursively,
|
||||
// along with a map that contains state entries for all of the auth events.
|
||||
func (l *authEventLoader) loadAuthEvents(
|
||||
ctx context.Context, roomInfo *types.RoomInfo, event *gomatrixserverlib.Event, eventMap map[string]types.Event,
|
||||
ctx context.Context, roomInfo *types.RoomInfo, event gomatrixserverlib.PDU, eventMap map[string]types.Event,
|
||||
) ([]*gomatrixserverlib.Event, map[string]types.StateEntry, error) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ type Database interface {
|
|||
SnapshotNIDFromEventID(ctx context.Context, eventID string) (types.StateSnapshotNID, error)
|
||||
BulkSelectSnapshotsFromEventIDs(ctx context.Context, eventIDs []string) (map[types.StateSnapshotNID][]string, error)
|
||||
// Stores a matrix room event in the database. Returns the room NID, the state snapshot or an error.
|
||||
StoreEvent(ctx context.Context, event *gomatrixserverlib.Event, roomInfo *types.RoomInfo, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID, authEventNIDs []types.EventNID, isRejected bool) (types.EventNID, types.StateAtEvent, error)
|
||||
StoreEvent(ctx context.Context, event gomatrixserverlib.PDU, roomInfo *types.RoomInfo, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID, authEventNIDs []types.EventNID, isRejected bool) (types.EventNID, types.StateAtEvent, error)
|
||||
// Look up the state entries for a list of string event IDs
|
||||
// Returns an error if the there is an error talking to the database
|
||||
// Returns a types.MissingEventError if the event IDs aren't in the database.
|
||||
|
|
@ -139,7 +139,7 @@ type Database interface {
|
|||
// not found.
|
||||
// Returns an error if the retrieval went wrong.
|
||||
EventsFromIDs(ctx context.Context, roomInfo *types.RoomInfo, eventIDs []string) ([]types.Event, error)
|
||||
// Publish or unpublish a room from the room directory.
|
||||
// PerformPublish publishes or unpublishes a room from the room directory. Returns a database error, if any.
|
||||
PublishRoom(ctx context.Context, roomID, appserviceID, networkID string, publish bool) error
|
||||
// Returns a list of room IDs for rooms which are published.
|
||||
GetPublishedRooms(ctx context.Context, networkID string, includeAllNetworks bool) ([]string, error)
|
||||
|
|
@ -151,8 +151,8 @@ type Database interface {
|
|||
// GetStateEvent returns the state event of a given type for a given room with a given state key
|
||||
// If no event could be found, returns nil
|
||||
// If there was an issue during the retrieval, returns an error
|
||||
GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error)
|
||||
GetStateEventsWithEventType(ctx context.Context, roomID, evType string) ([]*gomatrixserverlib.HeaderedEvent, error)
|
||||
GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*types.HeaderedEvent, error)
|
||||
GetStateEventsWithEventType(ctx context.Context, roomID, evType string) ([]*types.HeaderedEvent, error)
|
||||
// GetRoomsByMembership returns a list of room IDs matching the provided membership and user ID (as state_key).
|
||||
GetRoomsByMembership(ctx context.Context, userID, membership string) ([]string, error)
|
||||
// GetBulkStateContent returns all state events which match a given room ID and a given state key tuple. Both must be satisfied for a match.
|
||||
|
|
@ -181,8 +181,8 @@ type Database interface {
|
|||
// a membership of "leave" when calculating history visibility.
|
||||
GetMembershipForHistoryVisibility(
|
||||
ctx context.Context, userNID types.EventStateKeyNID, info *types.RoomInfo, eventIDs ...string,
|
||||
) (map[string]*gomatrixserverlib.HeaderedEvent, error)
|
||||
GetOrCreateRoomInfo(ctx context.Context, event *gomatrixserverlib.Event) (*types.RoomInfo, error)
|
||||
) (map[string]*types.HeaderedEvent, error)
|
||||
GetOrCreateRoomInfo(ctx context.Context, event gomatrixserverlib.PDU) (*types.RoomInfo, error)
|
||||
GetOrCreateEventTypeNID(ctx context.Context, eventType string) (eventTypeNID types.EventTypeNID, err error)
|
||||
GetOrCreateEventStateKeyNID(ctx context.Context, eventStateKey *string) (types.EventStateKeyNID, error)
|
||||
MaybeRedactEvent(
|
||||
|
|
@ -207,10 +207,10 @@ type RoomDatabase interface {
|
|||
StateEntriesForTuples(ctx context.Context, stateBlockNIDs []types.StateBlockNID, stateKeyTuples []types.StateKeyTuple) ([]types.StateEntryList, error)
|
||||
AddState(ctx context.Context, roomNID types.RoomNID, stateBlockNIDs []types.StateBlockNID, state []types.StateEntry) (types.StateSnapshotNID, error)
|
||||
LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error)
|
||||
GetOrCreateRoomInfo(ctx context.Context, event *gomatrixserverlib.Event) (*types.RoomInfo, error)
|
||||
GetOrCreateRoomInfo(ctx context.Context, event gomatrixserverlib.PDU) (*types.RoomInfo, error)
|
||||
GetOrCreateEventTypeNID(ctx context.Context, eventType string) (eventTypeNID types.EventTypeNID, err error)
|
||||
GetOrCreateEventStateKeyNID(ctx context.Context, eventStateKey *string) (types.EventStateKeyNID, error)
|
||||
GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error)
|
||||
GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*types.HeaderedEvent, error)
|
||||
}
|
||||
|
||||
type EventDatabase interface {
|
||||
|
|
@ -230,5 +230,5 @@ type EventDatabase interface {
|
|||
MaybeRedactEvent(
|
||||
ctx context.Context, roomInfo *types.RoomInfo, eventNID types.EventNID, event *gomatrixserverlib.Event, plResolver state.PowerLevelResolver,
|
||||
) (*gomatrixserverlib.Event, *gomatrixserverlib.Event, error)
|
||||
StoreEvent(ctx context.Context, event *gomatrixserverlib.Event, roomInfo *types.RoomInfo, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID, authEventNIDs []types.EventNID, isRejected bool) (types.EventNID, types.StateAtEvent, error)
|
||||
StoreEvent(ctx context.Context, event gomatrixserverlib.PDU, roomInfo *types.RoomInfo, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID, authEventNIDs []types.EventNID, isRejected bool) (types.EventNID, types.StateAtEvent, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,19 +205,19 @@ func (s *stateSnapshotStatements) BulkSelectStateForHistoryVisibility(
|
|||
|
||||
func (s *stateSnapshotStatements) BulkSelectMembershipForHistoryVisibility(
|
||||
ctx context.Context, txn *sql.Tx, userNID types.EventStateKeyNID, roomInfo *types.RoomInfo, eventIDs ...string,
|
||||
) (map[string]*gomatrixserverlib.HeaderedEvent, error) {
|
||||
) (map[string]*types.HeaderedEvent, error) {
|
||||
stmt := sqlutil.TxStmt(txn, s.bulktSelectMembershipForHistoryVisibilityStmt)
|
||||
rows, err := stmt.QueryContext(ctx, userNID, pq.Array(eventIDs), roomInfo.RoomNID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close() // nolint: errcheck
|
||||
result := make(map[string]*gomatrixserverlib.HeaderedEvent, len(eventIDs))
|
||||
result := make(map[string]*types.HeaderedEvent, len(eventIDs))
|
||||
var evJson []byte
|
||||
var eventID string
|
||||
var membershipEventID string
|
||||
|
||||
knownEvents := make(map[string]*gomatrixserverlib.HeaderedEvent, len(eventIDs))
|
||||
knownEvents := make(map[string]*types.HeaderedEvent, len(eventIDs))
|
||||
verImpl, err := gomatrixserverlib.GetRoomVersion(roomInfo.RoomVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -228,7 +228,7 @@ func (s *stateSnapshotStatements) BulkSelectMembershipForHistoryVisibility(
|
|||
return nil, err
|
||||
}
|
||||
if len(evJson) == 0 {
|
||||
result[eventID] = &gomatrixserverlib.HeaderedEvent{}
|
||||
result[eventID] = &types.HeaderedEvent{}
|
||||
continue
|
||||
}
|
||||
// If we already know this event, don't try to marshal the json again
|
||||
|
|
@ -238,11 +238,11 @@ func (s *stateSnapshotStatements) BulkSelectMembershipForHistoryVisibility(
|
|||
}
|
||||
event, err := verImpl.NewEventFromTrustedJSON(evJson, false)
|
||||
if err != nil {
|
||||
result[eventID] = &gomatrixserverlib.HeaderedEvent{}
|
||||
result[eventID] = &types.HeaderedEvent{}
|
||||
// not fatal
|
||||
continue
|
||||
}
|
||||
he := event.Headered(roomInfo.RoomVersion)
|
||||
he := &types.HeaderedEvent{Event: event}
|
||||
result[eventID] = he
|
||||
knownEvents[membershipEventID] = he
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func (d *Database) SupportsConcurrentRoomInputs() bool {
|
|||
|
||||
func (d *Database) GetMembershipForHistoryVisibility(
|
||||
ctx context.Context, userNID types.EventStateKeyNID, roomInfo *types.RoomInfo, eventIDs ...string,
|
||||
) (map[string]*gomatrixserverlib.HeaderedEvent, error) {
|
||||
) (map[string]*types.HeaderedEvent, error) {
|
||||
return d.StateSnapshotTable.BulkSelectMembershipForHistoryVisibility(ctx, nil, userNID, roomInfo, eventIDs...)
|
||||
}
|
||||
|
||||
|
|
@ -658,7 +658,7 @@ func (d *Database) IsEventRejected(ctx context.Context, roomNID types.RoomNID, e
|
|||
}
|
||||
|
||||
// GetOrCreateRoomInfo gets or creates a new RoomInfo, which is only safe to use with functions only needing a roomVersion or roomNID.
|
||||
func (d *Database) GetOrCreateRoomInfo(ctx context.Context, event *gomatrixserverlib.Event) (roomInfo *types.RoomInfo, err error) {
|
||||
func (d *Database) GetOrCreateRoomInfo(ctx context.Context, event gomatrixserverlib.PDU) (roomInfo *types.RoomInfo, err error) {
|
||||
// Get the default room version. If the client doesn't supply a room_version
|
||||
// then we will use our configured default to create the room.
|
||||
// https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-createroom
|
||||
|
|
@ -669,13 +669,17 @@ func (d *Database) GetOrCreateRoomInfo(ctx context.Context, event *gomatrixserve
|
|||
if roomVersion, err = extractRoomVersionFromCreateEvent(event); err != nil {
|
||||
return nil, fmt.Errorf("extractRoomVersionFromCreateEvent: %w", err)
|
||||
}
|
||||
if roomVersion == "" {
|
||||
rv, ok := d.Cache.GetRoomVersion(event.RoomID())
|
||||
if ok {
|
||||
roomVersion = rv
|
||||
}
|
||||
|
||||
roomNID, nidOK := d.Cache.GetRoomServerRoomNID(event.RoomID())
|
||||
cachedRoomVersion, versionOK := d.Cache.GetRoomVersion(event.RoomID())
|
||||
// if we found both, the roomNID and version in our cache, no need to query the database
|
||||
if nidOK && versionOK {
|
||||
return &types.RoomInfo{
|
||||
RoomNID: roomNID,
|
||||
RoomVersion: cachedRoomVersion,
|
||||
}, nil
|
||||
}
|
||||
var roomNID types.RoomNID
|
||||
|
||||
err = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||
roomNID, err = d.assignRoomNID(ctx, txn, event.RoomID(), roomVersion)
|
||||
if err != nil {
|
||||
|
|
@ -721,7 +725,7 @@ func (d *Database) GetOrCreateEventStateKeyNID(ctx context.Context, eventStateKe
|
|||
}
|
||||
|
||||
func (d *EventDatabase) StoreEvent(
|
||||
ctx context.Context, event *gomatrixserverlib.Event,
|
||||
ctx context.Context, event gomatrixserverlib.PDU,
|
||||
roomInfo *types.RoomInfo, eventTypeNID types.EventTypeNID, eventStateKeyNID types.EventStateKeyNID,
|
||||
authEventNIDs []types.EventNID, isRejected bool,
|
||||
) (types.EventNID, types.StateAtEvent, error) {
|
||||
|
|
@ -905,7 +909,7 @@ func (d *EventDatabase) assignStateKeyNID(
|
|||
return eventStateKeyNID, err
|
||||
}
|
||||
|
||||
func extractRoomVersionFromCreateEvent(event *gomatrixserverlib.Event) (
|
||||
func extractRoomVersionFromCreateEvent(event gomatrixserverlib.PDU) (
|
||||
gomatrixserverlib.RoomVersion, error,
|
||||
) {
|
||||
var err error
|
||||
|
|
@ -1152,7 +1156,7 @@ func (d *Database) GetHistoryVisibilityState(ctx context.Context, roomInfo *type
|
|||
// GetStateEvent returns the current state event of a given type for a given room with a given state key
|
||||
// If no event could be found, returns nil
|
||||
// If there was an issue during the retrieval, returns an error
|
||||
func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error) {
|
||||
func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*types.HeaderedEvent, error) {
|
||||
roomInfo, err := d.roomInfo(ctx, nil, roomID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -1164,7 +1168,7 @@ func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey s
|
|||
if roomInfo.IsStub() {
|
||||
return nil, nil
|
||||
}
|
||||
eventTypeNID, err := d.EventTypesTable.SelectEventTypeNID(ctx, nil, evType)
|
||||
eventTypeNID, err := d.GetOrCreateEventTypeNID(ctx, evType)
|
||||
if err == sql.ErrNoRows {
|
||||
// No rooms have an event of this type, otherwise we'd have an event type NID
|
||||
return nil, nil
|
||||
|
|
@ -1172,7 +1176,7 @@ func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey s
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stateKeyNID, err := d.EventStateKeysTable.SelectEventStateKeyNID(ctx, nil, stateKey)
|
||||
stateKeyNID, err := d.GetOrCreateEventStateKeyNID(ctx, &stateKey)
|
||||
if err == sql.ErrNoRows {
|
||||
// No rooms have a state event with this state key, otherwise we'd have an state key NID
|
||||
return nil, nil
|
||||
|
|
@ -1201,6 +1205,10 @@ func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey s
|
|||
// return the event requested
|
||||
for _, e := range entries {
|
||||
if e.EventTypeNID == eventTypeNID && e.EventStateKeyNID == stateKeyNID {
|
||||
cachedEvent, ok := d.Cache.GetRoomServerEvent(e.EventNID)
|
||||
if ok {
|
||||
return &types.HeaderedEvent{Event: cachedEvent}, nil
|
||||
}
|
||||
data, err := d.EventJSONTable.BulkSelectEventJSON(ctx, nil, []types.EventNID{e.EventNID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -1212,7 +1220,7 @@ func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey s
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ev.Headered(roomInfo.RoomVersion), nil
|
||||
return &types.HeaderedEvent{Event: ev}, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1221,7 +1229,7 @@ func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey s
|
|||
|
||||
// Same as GetStateEvent but returns all matching state events with this event type. Returns no error
|
||||
// if there are no events with this event type.
|
||||
func (d *Database) GetStateEventsWithEventType(ctx context.Context, roomID, evType string) ([]*gomatrixserverlib.HeaderedEvent, error) {
|
||||
func (d *Database) GetStateEventsWithEventType(ctx context.Context, roomID, evType string) ([]*types.HeaderedEvent, error) {
|
||||
roomInfo, err := d.roomInfo(ctx, nil, roomID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -1267,13 +1275,13 @@ func (d *Database) GetStateEventsWithEventType(ctx context.Context, roomID, evTy
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result []*gomatrixserverlib.HeaderedEvent
|
||||
var result []*types.HeaderedEvent
|
||||
for _, pair := range eventPairs {
|
||||
ev, err := verImpl.NewEventFromTrustedJSONWithEventID(eventIDs[pair.EventNID], pair.EventJSON, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, ev.Headered(roomInfo.RoomVersion))
|
||||
result = append(result, &types.HeaderedEvent{Event: ev})
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
|
@ -1324,7 +1332,7 @@ func (d *Database) GetBulkStateContent(ctx context.Context, roomIDs []string, tu
|
|||
}
|
||||
// we don't bother failing the request if we get asked for event types we don't know about, as all that would result in is no matches which
|
||||
// isn't a failure.
|
||||
eventTypeNIDMap, err := d.EventTypesTable.BulkSelectEventTypeNID(ctx, nil, eventTypes)
|
||||
eventTypeNIDMap, err := d.eventTypeNIDs(ctx, nil, eventTypes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetBulkStateContent: failed to map event type nids: %w", err)
|
||||
}
|
||||
|
|
@ -1401,7 +1409,7 @@ func (d *Database) GetBulkStateContent(ctx context.Context, roomIDs []string, tu
|
|||
EventType: ev.Type(),
|
||||
RoomID: ev.RoomID(),
|
||||
StateKey: *ev.StateKey(),
|
||||
ContentValue: tables.ExtractContentValue(ev.Headered(roomVer)),
|
||||
ContentValue: tables.ExtractContentValue(&types.HeaderedEvent{Event: ev}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
|
|
@ -153,7 +152,7 @@ func (s *stateSnapshotStatements) BulkSelectStateForHistoryVisibility(
|
|||
return nil, tables.OptimisationNotSupportedError
|
||||
}
|
||||
|
||||
func (s *stateSnapshotStatements) BulkSelectMembershipForHistoryVisibility(ctx context.Context, txn *sql.Tx, userNID types.EventStateKeyNID, roomInfo *types.RoomInfo, eventIDs ...string) (map[string]*gomatrixserverlib.HeaderedEvent, error) {
|
||||
func (s *stateSnapshotStatements) BulkSelectMembershipForHistoryVisibility(ctx context.Context, txn *sql.Tx, userNID types.EventStateKeyNID, roomInfo *types.RoomInfo, eventIDs ...string) (map[string]*types.HeaderedEvent, error) {
|
||||
return nil, tables.OptimisationNotSupportedError
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ type StateSnapshot interface {
|
|||
|
||||
BulkSelectMembershipForHistoryVisibility(
|
||||
ctx context.Context, txn *sql.Tx, userNID types.EventStateKeyNID, roomInfo *types.RoomInfo, eventIDs ...string,
|
||||
) (map[string]*gomatrixserverlib.HeaderedEvent, error)
|
||||
) (map[string]*types.HeaderedEvent, error)
|
||||
}
|
||||
|
||||
type StateBlock interface {
|
||||
|
|
@ -196,7 +196,7 @@ type StrippedEvent struct {
|
|||
// ExtractContentValue from the given state event. For example, given an m.room.name event with:
|
||||
// content: { name: "Foo" }
|
||||
// this returns "Foo".
|
||||
func ExtractContentValue(ev *gomatrixserverlib.HeaderedEvent) string {
|
||||
func ExtractContentValue(ev *types.HeaderedEvent) string {
|
||||
content := ev.Content()
|
||||
key := ""
|
||||
switch ev.Type() {
|
||||
|
|
|
|||
47
roomserver/types/headered_event.go
Normal file
47
roomserver/types/headered_event.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2023 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 types
|
||||
|
||||
import (
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
// HeaderedEvent is an Event which serialises to the headered form, which includes
|
||||
// _room_version and _event_id fields.
|
||||
type HeaderedEvent struct {
|
||||
*gomatrixserverlib.Event
|
||||
Visibility gomatrixserverlib.HistoryVisibility
|
||||
}
|
||||
|
||||
func (h *HeaderedEvent) MarshalJSON() ([]byte, error) {
|
||||
return h.Event.ToHeaderedJSON()
|
||||
}
|
||||
|
||||
func (j *HeaderedEvent) UnmarshalJSON(data []byte) error {
|
||||
ev, err := gomatrixserverlib.NewEventFromHeaderedJSON(data, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
j.Event = ev
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewEventJSONsFromHeaderedEvents(hes []*HeaderedEvent) gomatrixserverlib.EventJSONs {
|
||||
result := make(gomatrixserverlib.EventJSONs, len(hes))
|
||||
for i := range hes {
|
||||
result[i] = hes[i].JSON()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
roomserver "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/syncapi/synctypes"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
|
|
@ -94,7 +95,7 @@ type MSC2836EventRelationshipsResponse struct {
|
|||
|
||||
func toClientResponse(res *MSC2836EventRelationshipsResponse) *EventRelationshipResponse {
|
||||
out := &EventRelationshipResponse{
|
||||
Events: synctypes.ToClientEvents(res.ParsedEvents, synctypes.FormatAll),
|
||||
Events: synctypes.ToClientEvents(gomatrixserverlib.ToPDUs(res.ParsedEvents), synctypes.FormatAll),
|
||||
Limited: res.Limited,
|
||||
NextBatch: res.NextBatch,
|
||||
}
|
||||
|
|
@ -112,7 +113,7 @@ func Enable(
|
|||
}
|
||||
hooks.Enable()
|
||||
hooks.Attach(hooks.KindNewEventPersisted, func(headeredEvent interface{}) {
|
||||
he := headeredEvent.(*gomatrixserverlib.HeaderedEvent)
|
||||
he := headeredEvent.(*types.HeaderedEvent)
|
||||
hookErr := db.StoreRelation(context.Background(), he)
|
||||
if hookErr != nil {
|
||||
util.GetLogger(context.Background()).WithError(hookErr).WithField("event_id", he.EventID()).Error(
|
||||
|
|
@ -255,7 +256,7 @@ func federatedEventRelationship(
|
|||
|
||||
func (rc *reqCtx) process() (*MSC2836EventRelationshipsResponse, *util.JSONResponse) {
|
||||
var res MSC2836EventRelationshipsResponse
|
||||
var returnEvents []*gomatrixserverlib.HeaderedEvent
|
||||
var returnEvents []*types.HeaderedEvent
|
||||
// Can the user see (according to history visibility) event_id? If no, reject the request, else continue.
|
||||
event := rc.getLocalEvent(rc.req.RoomID, rc.req.EventID)
|
||||
if event == nil {
|
||||
|
|
@ -299,7 +300,7 @@ func (rc *reqCtx) process() (*MSC2836EventRelationshipsResponse, *util.JSONRespo
|
|||
for _, ev := range returnEvents {
|
||||
included[ev.EventID()] = true
|
||||
}
|
||||
var events []*gomatrixserverlib.HeaderedEvent
|
||||
var events []*types.HeaderedEvent
|
||||
events, walkLimited = walkThread(
|
||||
rc.ctx, rc.db, rc, included, remaining,
|
||||
)
|
||||
|
|
@ -309,7 +310,7 @@ func (rc *reqCtx) process() (*MSC2836EventRelationshipsResponse, *util.JSONRespo
|
|||
for i, ev := range returnEvents {
|
||||
// for each event, extract the children_count | hash and add it as unsigned data.
|
||||
rc.addChildMetadata(ev)
|
||||
res.ParsedEvents[i] = ev.Unwrap()
|
||||
res.ParsedEvents[i] = ev.Event
|
||||
}
|
||||
res.Limited = remaining == 0 || walkLimited
|
||||
return &res, nil
|
||||
|
|
@ -318,17 +319,15 @@ func (rc *reqCtx) process() (*MSC2836EventRelationshipsResponse, *util.JSONRespo
|
|||
// fetchUnknownEvent retrieves an unknown event from the room specified. This server must
|
||||
// be joined to the room in question. This has the side effect of injecting surround threaded
|
||||
// events into the roomserver.
|
||||
func (rc *reqCtx) fetchUnknownEvent(eventID, roomID string) *gomatrixserverlib.HeaderedEvent {
|
||||
func (rc *reqCtx) fetchUnknownEvent(eventID, roomID string) *types.HeaderedEvent {
|
||||
if rc.isFederatedRequest || roomID == "" {
|
||||
// we don't do fed hits for fed requests, and we can't ask servers without a room ID!
|
||||
return nil
|
||||
}
|
||||
logger := util.GetLogger(rc.ctx).WithField("room_id", roomID)
|
||||
// if they supplied a room_id, check the room exists.
|
||||
var queryVerRes roomserver.QueryRoomVersionForRoomResponse
|
||||
err := rc.rsAPI.QueryRoomVersionForRoom(rc.ctx, &roomserver.QueryRoomVersionForRoomRequest{
|
||||
RoomID: roomID,
|
||||
}, &queryVerRes)
|
||||
|
||||
roomVersion, err := rc.rsAPI.QueryRoomVersionForRoom(rc.ctx, roomID)
|
||||
if err != nil {
|
||||
logger.WithError(err).Warn("failed to query room version for room, does this room exist?")
|
||||
return nil
|
||||
|
|
@ -367,14 +366,14 @@ func (rc *reqCtx) fetchUnknownEvent(eventID, roomID string) *gomatrixserverlib.H
|
|||
// Inject the response into the roomserver to remember the event across multiple calls and to set
|
||||
// unexplored flags correctly.
|
||||
for _, srv := range serversToQuery {
|
||||
res, err := rc.MSC2836EventRelationships(eventID, srv, queryVerRes.RoomVersion)
|
||||
res, err := rc.MSC2836EventRelationships(eventID, srv, roomVersion)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
rc.injectResponseToRoomserver(res)
|
||||
for _, ev := range res.ParsedEvents {
|
||||
if ev.EventID() == eventID {
|
||||
return ev.Headered(ev.Version())
|
||||
return &types.HeaderedEvent{Event: ev}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -384,7 +383,7 @@ func (rc *reqCtx) fetchUnknownEvent(eventID, roomID string) *gomatrixserverlib.H
|
|||
|
||||
// If include_parent: true and there is a valid m.relationship field in the event,
|
||||
// retrieve the referenced event. Apply history visibility check to that event and if it passes, add it to the response array.
|
||||
func (rc *reqCtx) includeParent(childEvent *gomatrixserverlib.HeaderedEvent) (parent *gomatrixserverlib.HeaderedEvent) {
|
||||
func (rc *reqCtx) includeParent(childEvent *types.HeaderedEvent) (parent *types.HeaderedEvent) {
|
||||
parentID, _, _ := parentChildEventIDs(childEvent)
|
||||
if parentID == "" {
|
||||
return nil
|
||||
|
|
@ -395,7 +394,7 @@ func (rc *reqCtx) includeParent(childEvent *gomatrixserverlib.HeaderedEvent) (pa
|
|||
// If include_children: true, lookup all events which have event_id as an m.relationship
|
||||
// Apply history visibility checks to all these events and add the ones which pass into the response array,
|
||||
// honouring the recent_first flag and the limit.
|
||||
func (rc *reqCtx) includeChildren(db Database, parentID string, limit int, recentFirst bool) ([]*gomatrixserverlib.HeaderedEvent, *util.JSONResponse) {
|
||||
func (rc *reqCtx) includeChildren(db Database, parentID string, limit int, recentFirst bool) ([]*types.HeaderedEvent, *util.JSONResponse) {
|
||||
if rc.hasUnexploredChildren(parentID) {
|
||||
// we need to do a remote request to pull in the children as we are missing them locally.
|
||||
serversToQuery := rc.getServersForEventID(parentID)
|
||||
|
|
@ -432,7 +431,7 @@ func (rc *reqCtx) includeChildren(db Database, parentID string, limit int, recen
|
|||
resErr := jsonerror.InternalServerError()
|
||||
return nil, &resErr
|
||||
}
|
||||
var childEvents []*gomatrixserverlib.HeaderedEvent
|
||||
var childEvents []*types.HeaderedEvent
|
||||
for _, child := range children {
|
||||
childEvent := rc.lookForEvent(child.EventID)
|
||||
if childEvent != nil {
|
||||
|
|
@ -449,8 +448,8 @@ func (rc *reqCtx) includeChildren(db Database, parentID string, limit int, recen
|
|||
// honouring the limit, max_depth and max_breadth values according to the following rules
|
||||
func walkThread(
|
||||
ctx context.Context, db Database, rc *reqCtx, included map[string]bool, limit int,
|
||||
) ([]*gomatrixserverlib.HeaderedEvent, bool) {
|
||||
var result []*gomatrixserverlib.HeaderedEvent
|
||||
) ([]*types.HeaderedEvent, bool) {
|
||||
var result []*types.HeaderedEvent
|
||||
eventWalker := walker{
|
||||
ctx: ctx,
|
||||
req: rc.req,
|
||||
|
|
@ -512,7 +511,7 @@ func (rc *reqCtx) MSC2836EventRelationships(eventID string, srv spec.ServerName,
|
|||
|
||||
// authorisedToSeeEvent checks that the user or server is allowed to see this event. Returns true if allowed to
|
||||
// see this request. This only needs to be done once per room at present as we just check for joined status.
|
||||
func (rc *reqCtx) authorisedToSeeEvent(event *gomatrixserverlib.HeaderedEvent) bool {
|
||||
func (rc *reqCtx) authorisedToSeeEvent(event *types.HeaderedEvent) bool {
|
||||
if rc.isFederatedRequest {
|
||||
// make sure the server is in this room
|
||||
var res fs.QueryJoinedHostServerNamesInRoomResponse
|
||||
|
|
@ -595,7 +594,7 @@ func (rc *reqCtx) remoteEventRelationships(eventID string) *MSC2836EventRelation
|
|||
|
||||
// lookForEvent returns the event for the event ID given, by trying to query remote servers
|
||||
// if the event ID is unknown via /event_relationships.
|
||||
func (rc *reqCtx) lookForEvent(eventID string) *gomatrixserverlib.HeaderedEvent {
|
||||
func (rc *reqCtx) lookForEvent(eventID string) *types.HeaderedEvent {
|
||||
event := rc.getLocalEvent(rc.req.RoomID, eventID)
|
||||
if event == nil {
|
||||
queryRes := rc.remoteEventRelationships(eventID)
|
||||
|
|
@ -604,7 +603,7 @@ func (rc *reqCtx) lookForEvent(eventID string) *gomatrixserverlib.HeaderedEvent
|
|||
rc.injectResponseToRoomserver(queryRes)
|
||||
for _, ev := range queryRes.ParsedEvents {
|
||||
if ev.EventID() == eventID && rc.req.RoomID == ev.RoomID() {
|
||||
return ev.Headered(ev.Version())
|
||||
return &types.HeaderedEvent{Event: ev}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -626,7 +625,7 @@ func (rc *reqCtx) lookForEvent(eventID string) *gomatrixserverlib.HeaderedEvent
|
|||
return nil
|
||||
}
|
||||
|
||||
func (rc *reqCtx) getLocalEvent(roomID, eventID string) *gomatrixserverlib.HeaderedEvent {
|
||||
func (rc *reqCtx) getLocalEvent(roomID, eventID string) *types.HeaderedEvent {
|
||||
var queryEventsRes roomserver.QueryEventsByIDResponse
|
||||
err := rc.rsAPI.QueryEventsByID(rc.ctx, &roomserver.QueryEventsByIDRequest{
|
||||
RoomID: roomID,
|
||||
|
|
@ -647,7 +646,7 @@ func (rc *reqCtx) getLocalEvent(roomID, eventID string) *gomatrixserverlib.Heade
|
|||
// into the roomserver as KindOutlier, with auth chains.
|
||||
func (rc *reqCtx) injectResponseToRoomserver(res *MSC2836EventRelationshipsResponse) {
|
||||
var stateEvents gomatrixserverlib.EventJSONs
|
||||
var messageEvents []*gomatrixserverlib.Event
|
||||
var messageEvents []gomatrixserverlib.PDU
|
||||
for _, ev := range res.ParsedEvents {
|
||||
if ev.StateKey() != nil {
|
||||
stateEvents = append(stateEvents, ev.JSON())
|
||||
|
|
@ -666,7 +665,7 @@ func (rc *reqCtx) injectResponseToRoomserver(res *MSC2836EventRelationshipsRespo
|
|||
for _, outlier := range append(eventsInOrder, messageEvents...) {
|
||||
ires = append(ires, roomserver.InputRoomEvent{
|
||||
Kind: roomserver.KindOutlier,
|
||||
Event: outlier.Headered(outlier.Version()),
|
||||
Event: &types.HeaderedEvent{Event: outlier.(*gomatrixserverlib.Event)},
|
||||
})
|
||||
}
|
||||
// we've got the data by this point so use a background context
|
||||
|
|
@ -685,7 +684,7 @@ func (rc *reqCtx) injectResponseToRoomserver(res *MSC2836EventRelationshipsRespo
|
|||
}
|
||||
}
|
||||
|
||||
func (rc *reqCtx) addChildMetadata(ev *gomatrixserverlib.HeaderedEvent) {
|
||||
func (rc *reqCtx) addChildMetadata(ev *types.HeaderedEvent) {
|
||||
count, hash := rc.getChildMetadata(ev.EventID())
|
||||
if count == 0 {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
roomserver "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/setup/mscs/msc2836"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
|
|
@ -171,7 +172,7 @@ func TestMSC2836(t *testing.T) {
|
|||
bob: {roomID},
|
||||
charlie: {roomID},
|
||||
},
|
||||
events: map[string]*gomatrixserverlib.HeaderedEvent{
|
||||
events: map[string]*types.HeaderedEvent{
|
||||
eventA.EventID(): eventA,
|
||||
eventB.EventID(): eventB,
|
||||
eventC.EventID(): eventC,
|
||||
|
|
@ -182,7 +183,7 @@ func TestMSC2836(t *testing.T) {
|
|||
eventH.EventID(): eventH,
|
||||
},
|
||||
}
|
||||
router := injectEvents(t, nopUserAPI, nopRsAPI, []*gomatrixserverlib.HeaderedEvent{
|
||||
router := injectEvents(t, nopUserAPI, nopRsAPI, []*types.HeaderedEvent{
|
||||
eventA, eventB, eventC, eventD, eventE, eventF, eventG, eventH,
|
||||
})
|
||||
cancel := runServer(t, router)
|
||||
|
|
@ -521,7 +522,7 @@ type testRoomserverAPI struct {
|
|||
// We'll override the functions we care about.
|
||||
roomserver.RoomserverInternalAPI
|
||||
userToJoinedRooms map[string][]string
|
||||
events map[string]*gomatrixserverlib.HeaderedEvent
|
||||
events map[string]*types.HeaderedEvent
|
||||
}
|
||||
|
||||
func (r *testRoomserverAPI) QueryEventsByID(ctx context.Context, req *roomserver.QueryEventsByIDRequest, res *roomserver.QueryEventsByIDResponse) error {
|
||||
|
|
@ -547,7 +548,7 @@ func (r *testRoomserverAPI) QueryMembershipForUser(ctx context.Context, req *roo
|
|||
return nil
|
||||
}
|
||||
|
||||
func injectEvents(t *testing.T, userAPI userapi.UserInternalAPI, rsAPI roomserver.RoomserverInternalAPI, events []*gomatrixserverlib.HeaderedEvent) *mux.Router {
|
||||
func injectEvents(t *testing.T, userAPI userapi.UserInternalAPI, rsAPI roomserver.RoomserverInternalAPI, events []*types.HeaderedEvent) *mux.Router {
|
||||
t.Helper()
|
||||
cfg := &config.Dendrite{}
|
||||
cfg.Defaults(config.DefaultOpts{
|
||||
|
|
@ -579,7 +580,7 @@ type fledglingEvent struct {
|
|||
RoomID string
|
||||
}
|
||||
|
||||
func mustCreateEvent(t *testing.T, ev fledglingEvent) (result *gomatrixserverlib.HeaderedEvent) {
|
||||
func mustCreateEvent(t *testing.T, ev fledglingEvent) (result *types.HeaderedEvent) {
|
||||
t.Helper()
|
||||
roomVer := gomatrixserverlib.RoomVersionV6
|
||||
seed := make([]byte, ed25519.SeedSize) // zero seed
|
||||
|
|
@ -601,6 +602,6 @@ func mustCreateEvent(t *testing.T, ev fledglingEvent) (result *gomatrixserverlib
|
|||
if err != nil {
|
||||
t.Fatalf("mustCreateEvent: failed to sign event: %s", err)
|
||||
}
|
||||
h := signedEvent.Headered(roomVer)
|
||||
h := &types.HeaderedEvent{Event: signedEvent}
|
||||
return h
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
|
@ -23,7 +23,7 @@ type eventInfo struct {
|
|||
type Database interface {
|
||||
// StoreRelation stores the parent->child and child->parent relationship for later querying.
|
||||
// Also stores the event metadata e.g timestamp
|
||||
StoreRelation(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent) error
|
||||
StoreRelation(ctx context.Context, ev *types.HeaderedEvent) error
|
||||
// ChildrenForParent returns the events who have the given `eventID` as an m.relationship with the
|
||||
// provided `relType`. The returned slice is sorted by origin_server_ts according to whether
|
||||
// `recentFirst` is true or false.
|
||||
|
|
@ -35,7 +35,7 @@ type Database interface {
|
|||
// UpdateChildMetadata persists the children_count and children_hash from this event if and only if
|
||||
// the count is greater than what was previously there. If the count is updated, the event will be
|
||||
// updated to be unexplored.
|
||||
UpdateChildMetadata(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent) error
|
||||
UpdateChildMetadata(ctx context.Context, ev *types.HeaderedEvent) error
|
||||
// ChildMetadata returns the children_count and children_hash for the event ID in question.
|
||||
// Also returns the `explored` flag, which is set to true when MarkChildrenExplored is called and is set
|
||||
// back to `false` when a larger count is inserted via UpdateChildMetadata.
|
||||
|
|
@ -222,7 +222,7 @@ func newSQLiteDatabase(conMan sqlutil.Connections, dbOpts *config.DatabaseOption
|
|||
return &d, nil
|
||||
}
|
||||
|
||||
func (p *DB) StoreRelation(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent) error {
|
||||
func (p *DB) StoreRelation(ctx context.Context, ev *types.HeaderedEvent) error {
|
||||
parent, child, relType := parentChildEventIDs(ev)
|
||||
if parent == "" || child == "" {
|
||||
return nil
|
||||
|
|
@ -244,7 +244,7 @@ func (p *DB) StoreRelation(ctx context.Context, ev *gomatrixserverlib.HeaderedEv
|
|||
})
|
||||
}
|
||||
|
||||
func (p *DB) UpdateChildMetadata(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent) error {
|
||||
func (p *DB) UpdateChildMetadata(ctx context.Context, ev *types.HeaderedEvent) error {
|
||||
eventCount, eventHash := extractChildMetadata(ev)
|
||||
if eventCount == 0 {
|
||||
return nil // nothing to update with
|
||||
|
|
@ -315,7 +315,7 @@ func (p *DB) ParentForChild(ctx context.Context, eventID, relType string) (*even
|
|||
return &ei, nil
|
||||
}
|
||||
|
||||
func parentChildEventIDs(ev *gomatrixserverlib.HeaderedEvent) (parent, child, relType string) {
|
||||
func parentChildEventIDs(ev *types.HeaderedEvent) (parent, child, relType string) {
|
||||
if ev == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -334,7 +334,7 @@ func parentChildEventIDs(ev *gomatrixserverlib.HeaderedEvent) (parent, child, re
|
|||
return body.Relationship.EventID, ev.EventID(), body.Relationship.RelType
|
||||
}
|
||||
|
||||
func roomIDAndServers(ev *gomatrixserverlib.HeaderedEvent) (roomID string, servers []string) {
|
||||
func roomIDAndServers(ev *types.HeaderedEvent) (roomID string, servers []string) {
|
||||
servers = []string{}
|
||||
if ev == nil {
|
||||
return
|
||||
|
|
@ -349,7 +349,7 @@ func roomIDAndServers(ev *gomatrixserverlib.HeaderedEvent) (roomID string, serve
|
|||
return body.RoomID, body.Servers
|
||||
}
|
||||
|
||||
func extractChildMetadata(ev *gomatrixserverlib.HeaderedEvent) (count int, hash []byte) {
|
||||
func extractChildMetadata(ev *types.HeaderedEvent) (count int, hash []byte) {
|
||||
unsigned := struct {
|
||||
Counts map[string]int `json:"children"`
|
||||
Hash spec.Base64Bytes `json:"children_hash"`
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/caching"
|
||||
"github.com/matrix-org/dendrite/internal/httputil"
|
||||
roomserver "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
|
@ -388,7 +389,7 @@ func (w *walker) walk() util.JSONResponse {
|
|||
}
|
||||
}
|
||||
|
||||
func (w *walker) stateEvent(roomID, evType, stateKey string) *gomatrixserverlib.HeaderedEvent {
|
||||
func (w *walker) stateEvent(roomID, evType, stateKey string) *types.HeaderedEvent {
|
||||
var queryRes roomserver.QueryCurrentStateResponse
|
||||
tuple := gomatrixserverlib.StateKeyTuple{
|
||||
EventType: evType,
|
||||
|
|
@ -636,7 +637,7 @@ func (w *walker) authorisedUser(roomID, parentRoomID string) (authed bool, isJoi
|
|||
return false, false
|
||||
}
|
||||
|
||||
func (w *walker) restrictedJoinRuleAllowedRooms(joinRuleEv *gomatrixserverlib.HeaderedEvent, allowType string) (allows []string) {
|
||||
func (w *walker) restrictedJoinRuleAllowedRooms(joinRuleEv *types.HeaderedEvent, allowType string) (allows []string) {
|
||||
rule, _ := joinRuleEv.JoinRule()
|
||||
if rule != spec.Restricted {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
|
@ -31,6 +30,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/internal/fulltext"
|
||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
rstypes "github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||
"github.com/matrix-org/dendrite/setup/process"
|
||||
|
|
@ -318,7 +318,7 @@ func (s *OutputRoomEventConsumer) onOldRoomEvent(
|
|||
pduPos, err := s.db.WriteEvent(
|
||||
ctx,
|
||||
ev,
|
||||
[]*gomatrixserverlib.HeaderedEvent{},
|
||||
[]*rstypes.HeaderedEvent{},
|
||||
[]string{}, // adds no state
|
||||
[]string{}, // removes no state
|
||||
nil, // no transaction
|
||||
|
|
@ -362,7 +362,7 @@ func (s *OutputRoomEventConsumer) onOldRoomEvent(
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *OutputRoomEventConsumer) notifyJoinedPeeks(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent, sp types.StreamPosition) (types.StreamPosition, error) {
|
||||
func (s *OutputRoomEventConsumer) notifyJoinedPeeks(ctx context.Context, ev *rstypes.HeaderedEvent, sp types.StreamPosition) (types.StreamPosition, error) {
|
||||
if ev.Type() != spec.MRoomMember {
|
||||
return sp, nil
|
||||
}
|
||||
|
|
@ -496,7 +496,7 @@ func (s *OutputRoomEventConsumer) onPurgeRoom(
|
|||
}
|
||||
}
|
||||
|
||||
func (s *OutputRoomEventConsumer) updateStateEvent(event *gomatrixserverlib.HeaderedEvent) (*gomatrixserverlib.HeaderedEvent, error) {
|
||||
func (s *OutputRoomEventConsumer) updateStateEvent(event *rstypes.HeaderedEvent) (*rstypes.HeaderedEvent, error) {
|
||||
if event.StateKey() == nil {
|
||||
return event, nil
|
||||
}
|
||||
|
|
@ -531,7 +531,7 @@ func (s *OutputRoomEventConsumer) updateStateEvent(event *gomatrixserverlib.Head
|
|||
return event, err
|
||||
}
|
||||
|
||||
func (s *OutputRoomEventConsumer) writeFTS(ev *gomatrixserverlib.HeaderedEvent, pduPosition types.StreamPosition) error {
|
||||
func (s *OutputRoomEventConsumer) writeFTS(ev *rstypes.HeaderedEvent, pduPosition types.StreamPosition) error {
|
||||
if !s.cfg.Fulltext.Enabled {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue