From 424df14000abcba6103ca457a9677dbfe418bf6e Mon Sep 17 00:00:00 2001 From: Tak Wai Wong <64229756+tak-hntlabs@users.noreply.github.com> Date: Tue, 1 Nov 2022 11:09:34 -0700 Subject: [PATCH] Sync dendrite fork changes for gating, and single chain support (#778) * Latest dendrite main (8c7b274e4e223cbb888c1eb892767e46a25381aa) * Gating implementation from John and Tak Fixes for https://github.com/matrix-org/dendrite/issues/2838 and https://github.com/matrix-org/dendrite/issues/2842 Co-authored-by: Tak Wai Wong --- .github/workflows/dendrite.yml | 7 +- .github/workflows/schedules.yaml | 128 ++ CHANGES.md | 38 + build/docker/Dockerfile.demo-yggdrasil | 25 + build/gobind-pinecone/monolith.go | 52 +- build/scripts/Complement.Dockerfile | 2 +- build/scripts/ComplementLocal.Dockerfile | 2 +- build/scripts/ComplementPostgres.Dockerfile | 2 +- clientapi/auth/login_publickey_ethereum.go | 13 +- .../auth/login_publickey_ethereum_test.go | 31 +- clientapi/auth/login_publickey_test.go | 6 +- clientapi/auth/password.go | 2 +- clientapi/authorization/authorization.go | 4 +- clientapi/routing/admin.go | 44 +- clientapi/routing/auth_fallback.go | 18 +- clientapi/routing/createroom.go | 25 +- clientapi/routing/directory.go | 49 +- clientapi/routing/directory_public.go | 43 +- clientapi/routing/directory_public_test.go | 2 +- clientapi/routing/joined_rooms.go | 52 + clientapi/routing/keys.go | 6 +- clientapi/routing/login.go | 6 +- clientapi/routing/membership.go | 9 +- clientapi/routing/openid.go | 2 +- clientapi/routing/profile.go | 155 ++- clientapi/routing/redaction.go | 12 +- clientapi/routing/register.go | 6 +- clientapi/routing/register_publickey_test.go | 39 +- clientapi/routing/routing.go | 52 +- clientapi/routing/sendevent.go | 9 +- clientapi/routing/sendtodevice.go | 7 +- clientapi/routing/server_notices.go | 38 +- clientapi/threepid/invites.go | 2 +- clientapi/userutil/userutil.go | 13 +- clientapi/userutil/userutil_test.go | 25 +- cmd/create-account/main.go | 5 +- cmd/dendrite-demo-yggdrasil/yggconn/node.go | 86 +- dendrite-sample.monolith.yaml | 19 +- dendrite-sample.polylith.yaml | 19 +- dendrite-zion.yaml | 387 ++++++ docs/Gemfile.lock | 4 +- docs/caddy/polylith/Caddyfile | 2 +- docs/hiawatha/polylith-sample.conf | 4 +- docs/nginx/polylith-sample.conf | 4 +- federationapi/consumers/keychange.go | 44 +- federationapi/consumers/presence.go | 10 +- federationapi/consumers/receipts.go | 34 +- federationapi/consumers/sendtodevice.go | 36 +- federationapi/consumers/typing.go | 32 +- federationapi/federationapi.go | 13 +- federationapi/federationapi_keys_test.go | 2 +- federationapi/federationapi_test.go | 1 + federationapi/internal/federationclient.go | 2 +- federationapi/internal/keys.go | 2 +- federationapi/internal/perform.go | 2 +- federationapi/producers/syncapi.go | 5 +- federationapi/queue/destinationqueue.go | 406 ++++--- federationapi/queue/queue.go | 79 +- federationapi/queue/queue_test.go | 1060 ++++++++++++++++ federationapi/routing/publicrooms.go | 25 +- federationapi/routing/routing.go | 50 +- federationapi/statistics/statistics.go | 131 +- federationapi/statistics/statistics_test.go | 19 +- federationapi/storage/interface.go | 7 +- federationapi/storage/postgres/storage.go | 4 +- federationapi/storage/shared/storage.go | 8 +- federationapi/storage/shared/storage_edus.go | 25 +- federationapi/storage/shared/storage_pdus.go | 24 +- federationapi/storage/sqlite3/storage.go | 4 +- federationapi/storage/storage.go | 6 +- federationapi/storage/storage_test.go | 9 +- go.mod | 28 +- go.sum | 124 +- internal/transactions/transactions.go | 16 +- internal/transactions/transactions_test.go | 42 +- internal/version.go | 2 +- keyserver/internal/internal.go | 100 +- .../postgres/cross_signing_sigs_table.go | 2 +- .../sqlite3/cross_signing_sigs_table.go | 4 +- roomserver/api/api.go | 2 + roomserver/api/api_trace.go | 10 + roomserver/api/perform.go | 16 +- roomserver/api/query.go | 7 +- roomserver/internal/perform/perform_admin.go | 153 ++- .../internal/perform/perform_backfill.go | 2 + roomserver/internal/perform/perform_invite.go | 4 +- roomserver/internal/perform/perform_join.go | 23 +- roomserver/internal/perform/perform_leave.go | 6 +- roomserver/internal/perform/perform_peek.go | 6 +- .../internal/perform/perform_publish.go | 2 +- roomserver/internal/perform/perform_unpeek.go | 2 +- .../internal/perform/perform_upgrade.go | 37 +- roomserver/internal/query/query.go | 2 +- roomserver/inthttp/client.go | 36 +- roomserver/inthttp/server.go | 5 + roomserver/storage/interface.go | 4 +- .../20221027084407_published_appservice.go | 45 + .../storage/postgres/published_table.go | 55 +- roomserver/storage/shared/storage.go | 8 +- .../20221027084407_published_appservice.go | 64 + roomserver/storage/sqlite3/published_table.go | 55 +- roomserver/storage/tables/interface.go | 4 +- .../storage/tables/published_table_test.go | 33 +- setup/config/config.go | 42 +- setup/config/config_clientapi.go | 18 + setup/config/config_global.go | 17 +- setup/config/config_publickey.go | 54 +- setup/config/config_userapi.go | 4 + setup/mscs/msc2836/msc2836.go | 2 +- setup/mscs/msc2946/msc2946.go | 2 +- syncapi/consumers/roomserver.go | 7 + {clientapi => syncapi}/routing/memberships.go | 109 +- syncapi/routing/messages.go | 33 +- syncapi/routing/routing.go | 33 + syncapi/storage/interface.go | 5 + syncapi/storage/postgres/memberships_table.go | 35 +- .../postgres/output_room_events_table.go | 77 +- syncapi/storage/shared/storage_consumer.go | 8 + syncapi/storage/shared/storage_sync.go | 30 +- syncapi/storage/sqlite3/memberships_table.go | 32 +- .../sqlite3/output_room_events_table.go | 45 +- syncapi/storage/tables/interface.go | 5 + syncapi/storage/tables/memberships_test.go | 198 +++ syncapi/streams/stream_invite.go | 26 +- syncapi/streams/stream_pdu.go | 81 +- syncapi/streams/stream_presence.go | 3 +- syncapi/sync/request.go | 19 +- syncapi/types/provider.go | 5 +- syncapi/types/types.go | 6 +- sytest-blacklist | 22 +- sytest-whitelist | 20 +- test/publickey_utils.go | 4 +- test/testrig/base.go | 2 + userapi/api/api.go | 43 +- userapi/api/api_trace.go | 2 +- userapi/consumers/clientapi.go | 2 +- userapi/consumers/roomserver_test.go | 9 +- userapi/internal/api.go | 114 +- userapi/internal/api_logintoken.go | 8 +- userapi/inthttp/client.go | 2 +- userapi/storage/interface.go | 4 +- .../storage/postgres/account_data_table.go | 8 +- userapi/storage/postgres/accounts_table.go | 14 +- .../deltas/20200929203058_is_active.go | 4 +- .../deltas/20201001204705_last_seen_ts_ip.go | 12 +- .../2022021013023800_add_account_type.go | 10 +- .../deltas/2022101711000000_rename_tables.go | 102 ++ userapi/storage/postgres/devices_table.go | 28 +- userapi/storage/postgres/key_backup_table.go | 18 +- .../postgres/key_backup_version_table.go | 20 +- userapi/storage/postgres/logintoken_table.go | 12 +- userapi/storage/postgres/openid_table.go | 6 +- userapi/storage/postgres/profile_table.go | 44 +- userapi/storage/postgres/stats_table.go | 16 +- userapi/storage/postgres/storage.go | 11 + userapi/storage/postgres/threepid_table.go | 12 +- userapi/storage/shared/storage.go | 16 +- userapi/storage/sqlite3/account_data_table.go | 8 +- userapi/storage/sqlite3/accounts_table.go | 14 +- .../deltas/20200929203058_is_active.go | 20 +- .../deltas/20201001204705_last_seen_ts_ip.go | 20 +- .../2022021012490600_add_account_type.go | 16 +- .../deltas/2022101711000000_rename_tables.go | 109 ++ userapi/storage/sqlite3/devices_table.go | 24 +- userapi/storage/sqlite3/key_backup_table.go | 18 +- .../sqlite3/key_backup_version_table.go | 16 +- userapi/storage/sqlite3/logintoken_table.go | 12 +- userapi/storage/sqlite3/openid_table.go | 6 +- userapi/storage/sqlite3/profile_table.go | 48 +- userapi/storage/sqlite3/stats_table.go | 16 +- userapi/storage/sqlite3/storage.go | 11 + userapi/storage/sqlite3/threepid_table.go | 12 +- userapi/storage/storage_test.go | 33 +- userapi/storage/tables/interface.go | 4 +- userapi/storage/tables/stats_table_test.go | 5 +- userapi/userapi.go | 3 +- userapi/userapi_test.go | 27 +- zion/README.md | 2 +- zion/contracts/goerli/addresses/council.json | 2 +- .../goerli/addresses/space-manager.json | 2 +- .../localhost/addresses/council.json | 2 +- .../localhost/addresses/space-manager.json | 2 +- zion/zion_authorization.go | 50 +- zion/zion_space_manager_localhost.go | 1077 ----------------- 184 files changed, 4903 insertions(+), 2512 deletions(-) create mode 100644 .github/workflows/schedules.yaml create mode 100644 build/docker/Dockerfile.demo-yggdrasil create mode 100644 clientapi/routing/joined_rooms.go create mode 100644 dendrite-zion.yaml create mode 100644 federationapi/queue/queue_test.go create mode 100644 roomserver/storage/postgres/deltas/20221027084407_published_appservice.go create mode 100644 roomserver/storage/sqlite3/deltas/20221027084407_published_appservice.go rename {clientapi => syncapi}/routing/memberships.go (51%) create mode 100644 syncapi/storage/tables/memberships_test.go create mode 100644 userapi/storage/postgres/deltas/2022101711000000_rename_tables.go create mode 100644 userapi/storage/sqlite3/deltas/2022101711000000_rename_tables.go delete mode 100644 zion/zion_space_manager_localhost.go diff --git a/.github/workflows/dendrite.yml b/.github/workflows/dendrite.yml index 4c53a6137..fef351de2 100644 --- a/.github/workflows/dendrite.yml +++ b/.github/workflows/dendrite.yml @@ -109,6 +109,11 @@ jobs: uses: actions/setup-go@v3 with: go-version: ${{ matrix.go }} + - name: Set up gotestfmt + uses: gotesttools/gotestfmt-action@v2 + with: + # Optional: pass GITHUB_TOKEN to avoid rate limiting. + token: ${{ secrets.GITHUB_TOKEN }} - uses: actions/cache@v3 with: path: | @@ -117,7 +122,7 @@ jobs: key: ${{ runner.os }}-go${{ matrix.go }}-test-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go${{ matrix.go }}-test- - - run: go test ./... + - run: go test -json -v ./... 2>&1 | gotestfmt env: POSTGRES_HOST: localhost POSTGRES_USER: postgres diff --git a/.github/workflows/schedules.yaml b/.github/workflows/schedules.yaml new file mode 100644 index 000000000..c07917248 --- /dev/null +++ b/.github/workflows/schedules.yaml @@ -0,0 +1,128 @@ +name: Scheduled + +on: + schedule: + - cron: '0 0 * * *' # every day at midnight + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # run go test with different go versions + test: + timeout-minutes: 20 + name: Unit tests (Go ${{ matrix.go }}) + runs-on: ubuntu-latest + # Service containers to run with `container-job` + services: + # Label used to access the service container + postgres: + # Docker Hub image + image: postgres:13-alpine + # Provide the password for postgres + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: dendrite + ports: + # Maps tcp port 5432 on service container to the host + - 5432:5432 + # Set health checks to wait until postgres has started + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + strategy: + fail-fast: false + matrix: + go: ["1.18", "1.19"] + steps: + - uses: actions/checkout@v3 + - name: Setup go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go }} + - uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go${{ matrix.go }}-test-race-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go${{ matrix.go }}-test-race- + - run: go test -race ./... + env: + POSTGRES_HOST: localhost + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: dendrite + + # Dummy step to gate other tests on without repeating the whole list + initial-tests-done: + name: Initial tests passed + needs: [test] + runs-on: ubuntu-latest + if: ${{ !cancelled() }} # Run this even if prior jobs were skipped + steps: + - name: Check initial tests passed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} + + # run Sytest in different variations + sytest: + timeout-minutes: 60 + needs: initial-tests-done + name: "Sytest (${{ matrix.label }})" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - label: SQLite + + - label: SQLite, full HTTP APIs + api: full-http + + - label: PostgreSQL + postgres: postgres + + - label: PostgreSQL, full HTTP APIs + postgres: postgres + api: full-http + container: + image: matrixdotorg/sytest-dendrite:latest + volumes: + - ${{ github.workspace }}:/src + env: + POSTGRES: ${{ matrix.postgres && 1}} + API: ${{ matrix.api && 1 }} + SYTEST_BRANCH: ${{ github.head_ref }} + RACE_DETECTION: 1 + steps: + - uses: actions/checkout@v2 + - name: Run Sytest + run: /bootstrap.sh dendrite + working-directory: /src + - name: Summarise results.tap + if: ${{ always() }} + run: /sytest/scripts/tap_to_gha.pl /logs/results.tap + - name: Sytest List Maintenance + if: ${{ always() }} + run: /src/show-expected-fail-tests.sh /logs/results.tap /src/sytest-whitelist /src/sytest-blacklist + continue-on-error: true # not fatal + - name: Are We Synapse Yet? + if: ${{ always() }} + run: /src/are-we-synapse-yet.py /logs/results.tap -v + continue-on-error: true # not fatal + - name: Upload Sytest logs + uses: actions/upload-artifact@v2 + if: ${{ always() }} + with: + name: Sytest Logs - ${{ job.status }} - (Dendrite, ${{ join(matrix.*, ', ') }}) + path: | + /logs/results.tap + /logs/**/*.log* diff --git a/CHANGES.md b/CHANGES.md index eea2c3c7c..ba14dd07a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,43 @@ # Changelog +## Dendrite 0.10.5 (2022-10-31) + +### Features + +* It is now possible to use hCaptcha instead of reCAPTCHA for protecting registration +* A new `auto_join_rooms` configuration option has been added for automatically joining new users to a set of rooms +* A new `/_dendrite/admin/downloadState/{serverName}/{roomID}` endpoint has been added, which allows a server administrator to attempt to repair a room with broken room state by downloading a state snapshot from another federated server in the room + +### Fixes + +* Querying cross-signing keys for users should now be considerably faster +* A bug in state resolution where some events were not correctly selected for third-party invites has been fixed +* A bug in state resolution which could result in `not in room` event rejections has been fixed +* When accepting a DM invite, it should now be possible to see messages that were sent before the invite was accepted +* Claiming remote E2EE one-time keys has been refactored and should be more reliable now +* Various fixes have been made to the `/members` endpoint, which may help with E2EE reliability and clients rendering memberships +* A race condition in the federation API destination queues has been fixed when associating queued events with remote server destinations +* A bug in the sync API where too many events were selected resulting in high CPU usage has been fixed +* Configuring the avatar URL for the Server Notices user should work correctly now + +## Dendrite 0.10.4 (2022-10-21) + +### Features + +* Various tables belonging to the user API will be renamed so that they are namespaced with the `userapi_` prefix + * Note that, after upgrading to this version, you should not revert to an older version of Dendrite as the database changes **will not** be reverted automatically +* The backoff and retry behaviour in the federation API has been refactored and improved + +### Fixes + +* Private read receipt support is now advertised in the client `/versions` endpoint +* Private read receipts will now clear notification counts properly +* A bug where a false `leave` membership transition was inserted into the timeline after accepting an invite has been fixed +* Some panics caused by concurrent map writes in the key server have been fixed +* The sync API now calculates membership transitions from state deltas more accurately +* Transaction IDs are now scoped to endpoints, which should fix some bugs where transaction ID reuse could cause nonsensical cached responses from some endpoints +* The length of the `type`, `sender`, `state_key` and `room_id` fields in events are now verified by number of bytes rather than codepoints after a spec clarification, reverting a change made in Dendrite 0.9.6 + ## Dendrite 0.10.3 (2022-10-14) ### Features diff --git a/build/docker/Dockerfile.demo-yggdrasil b/build/docker/Dockerfile.demo-yggdrasil new file mode 100644 index 000000000..76bf35823 --- /dev/null +++ b/build/docker/Dockerfile.demo-yggdrasil @@ -0,0 +1,25 @@ +FROM docker.io/golang:1.19-alpine AS base + +RUN apk --update --no-cache add bash build-base + +WORKDIR /build + +COPY . /build + +RUN mkdir -p bin +RUN go build -trimpath -o bin/ ./cmd/dendrite-demo-yggdrasil +RUN go build -trimpath -o bin/ ./cmd/create-account +RUN go build -trimpath -o bin/ ./cmd/generate-keys + +FROM alpine:latest +LABEL org.opencontainers.image.title="Dendrite (Yggdrasil demo)" +LABEL org.opencontainers.image.description="Next-generation Matrix homeserver written in Go" +LABEL org.opencontainers.image.source="https://github.com/matrix-org/dendrite" +LABEL org.opencontainers.image.licenses="Apache-2.0" + +COPY --from=base /build/bin/* /usr/bin/ + +VOLUME /etc/dendrite +WORKDIR /etc/dendrite + +ENTRYPOINT ["/usr/bin/dendrite-demo-yggdrasil"] diff --git a/build/gobind-pinecone/monolith.go b/build/gobind-pinecone/monolith.go index 4a96e4bef..adb4e40a6 100644 --- a/build/gobind-pinecone/monolith.go +++ b/build/gobind-pinecone/monolith.go @@ -101,18 +101,46 @@ func (m *DendriteMonolith) SessionCount() int { return len(m.PineconeQUIC.Protocol("matrix").Sessions()) } -func (m *DendriteMonolith) RegisterNetworkInterface(name string, index int, mtu int, up bool, broadcast bool, loopback bool, pointToPoint bool, multicast bool, addrs string) { - m.PineconeMulticast.RegisterInterface(pineconeMulticast.InterfaceInfo{ - Name: name, - Index: index, - Mtu: mtu, - Up: up, - Broadcast: broadcast, - Loopback: loopback, - PointToPoint: pointToPoint, - Multicast: multicast, - Addrs: addrs, - }) +type InterfaceInfo struct { + Name string + Index int + Mtu int + Up bool + Broadcast bool + Loopback bool + PointToPoint bool + Multicast bool + Addrs string +} + +type InterfaceRetriever interface { + CacheCurrentInterfaces() int + GetCachedInterface(index int) *InterfaceInfo +} + +func (m *DendriteMonolith) RegisterNetworkCallback(intfCallback InterfaceRetriever) { + callback := func() []pineconeMulticast.InterfaceInfo { + count := intfCallback.CacheCurrentInterfaces() + intfs := []pineconeMulticast.InterfaceInfo{} + for i := 0; i < count; i++ { + iface := intfCallback.GetCachedInterface(i) + if iface != nil { + intfs = append(intfs, pineconeMulticast.InterfaceInfo{ + Name: iface.Name, + Index: iface.Index, + Mtu: iface.Mtu, + Up: iface.Up, + Broadcast: iface.Broadcast, + Loopback: iface.Loopback, + PointToPoint: iface.PointToPoint, + Multicast: iface.Multicast, + Addrs: iface.Addrs, + }) + } + } + return intfs + } + m.PineconeMulticast.RegisterNetworkCallback(callback) } func (m *DendriteMonolith) SetMulticastEnabled(enabled bool) { diff --git a/build/scripts/Complement.Dockerfile b/build/scripts/Complement.Dockerfile index 9936c7416..14b28498b 100644 --- a/build/scripts/Complement.Dockerfile +++ b/build/scripts/Complement.Dockerfile @@ -1,6 +1,6 @@ #syntax=docker/dockerfile:1.2 -FROM golang:1.19-buster as build +FROM golang:1.18-stretch as build RUN apt-get update && apt-get install -y sqlite3 WORKDIR /build diff --git a/build/scripts/ComplementLocal.Dockerfile b/build/scripts/ComplementLocal.Dockerfile index 2b84c4798..3a019fc20 100644 --- a/build/scripts/ComplementLocal.Dockerfile +++ b/build/scripts/ComplementLocal.Dockerfile @@ -8,7 +8,7 @@ # # Use these mounts to make use of this dockerfile: # COMPLEMENT_HOST_MOUNTS='/your/local/dendrite:/dendrite:ro;/your/go/path:/go:ro' -FROM golang:1.19-buster +FROM golang:1.18-stretch RUN apt-get update && apt-get install -y sqlite3 ENV SERVER_NAME=localhost diff --git a/build/scripts/ComplementPostgres.Dockerfile b/build/scripts/ComplementPostgres.Dockerfile index 48af2339b..99f27abce 100644 --- a/build/scripts/ComplementPostgres.Dockerfile +++ b/build/scripts/ComplementPostgres.Dockerfile @@ -50,4 +50,4 @@ CMD /build/run_postgres.sh && ./generate-keys --keysize 1024 --server $SERVER_NA # Bump max_open_conns up here in the global database config sed -i 's/max_open_conns:.*$/max_open_conns: 1990/g' dendrite.yaml && \ cp /complement/ca/ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates && \ - exec ./dendrite-monolith-server --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml -api=${API:-0} \ No newline at end of file + exec ./dendrite-monolith-server --really-enable-open-registration --tls-cert server.crt --tls-key server.key --config dendrite.yaml -api=${API:-0} diff --git a/clientapi/auth/login_publickey_ethereum.go b/clientapi/auth/login_publickey_ethereum.go index 90de33d2b..33c0a16d4 100644 --- a/clientapi/auth/login_publickey_ethereum.go +++ b/clientapi/auth/login_publickey_ethereum.go @@ -67,7 +67,7 @@ func (pk LoginPublicKeyEthereum) GetType() string { } func (pk LoginPublicKeyEthereum) AccountExists(ctx context.Context) (string, *jsonerror.MatrixError) { - localPart, err := userutil.ParseUsernameParam(pk.UserId, &pk.config.Matrix.ServerName) + localPart, _, err := userutil.ParseUsernameParam(pk.UserId, pk.config.Matrix) if err != nil { // userId does not exist return "", jsonerror.Forbidden("the address is incorrect, or the account does not exist.") @@ -129,7 +129,7 @@ func (pk LoginPublicKeyEthereum) ValidateLoginResponse() (bool, *jsonerror.Matri } // Error if the chainId is not supported by the server. - if !contains(pk.config.PublicKeyAuthentication.Ethereum.ChainIDs, message.GetChainID()) { + if pk.config.PublicKeyAuthentication.Ethereum.GetChainID() != message.GetChainID() { return false, jsonerror.Forbidden("chainId") } @@ -156,12 +156,3 @@ func (pk LoginPublicKeyEthereum) verifyMessageUserId(message *siwe.Message) bool // one derived from the signed message. return pk.UserId == strings.ToLower(expectedUserId) } - -func contains(list []int, element int) bool { - for _, i := range list { - if i == element { - return true - } - } - return false -} diff --git a/clientapi/auth/login_publickey_ethereum_test.go b/clientapi/auth/login_publickey_ethereum_test.go index 73842f9a0..cd7db05b2 100644 --- a/clientapi/auth/login_publickey_ethereum_test.go +++ b/clientapi/auth/login_publickey_ethereum_test.go @@ -18,13 +18,14 @@ import ( "context" "fmt" "net/http" + "strconv" "strings" "testing" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/internal/mapsutil" "github.com/matrix-org/dendrite/setup/config" - "github.com/matrix-org/dendrite/test" + testutil "github.com/matrix-org/dendrite/test" uapi "github.com/matrix-org/dendrite/userapi/api" "github.com/stretchr/testify/assert" ) @@ -35,19 +36,17 @@ type loginContext struct { } func createLoginContext(_ *testing.T) *loginContext { - chainIds := []int{4} - cfg := &config.ClientAPI{ Matrix: &config.Global{ - ServerName: test.TestServerName, + ServerName: testutil.TestServerName, }, Derived: &config.Derived{}, PasswordAuthenticationDisabled: true, PublicKeyAuthentication: config.PublicKeyAuthentication{ Ethereum: config.EthereumAuthConfig{ - Enabled: true, - Version: 1, - ChainIDs: chainIds, + Enabled: true, + Version: 1, + ConfigChainID: strconv.Itoa(testutil.EthereumTestNetworkId), }, }, } @@ -154,9 +153,9 @@ func TestLoginPublicKeyEthereum(t *testing.T) { var userAPI fakePublicKeyUserApi ctx := context.Background() loginContext := createLoginContext(t) - wallet, _ := test.CreateTestAccount() - message, _ := test.CreateEip4361TestMessage(wallet.PublicAddress) - signature, _ := test.SignMessage(message.String(), wallet.PrivateKey) + wallet, _ := testutil.CreateTestAccount() + message, _ := testutil.CreateEip4361TestMessage(wallet.PublicAddress) + signature, _ := testutil.SignMessage(message.String(), wallet.PrivateKey) sessionId := publicKeyTestSession( &ctx, loginContext.config, @@ -165,7 +164,7 @@ func TestLoginPublicKeyEthereum(t *testing.T) { ) // Escape \t and \n. Work around for marshalling and unmarshalling message. - msgStr := test.FromEip4361MessageToString(message) + msgStr := testutil.FromEip4361MessageToString(message) body := fmt.Sprintf(`{ "type": "m.login.publickey", "auth": { @@ -219,8 +218,8 @@ func TestLoginPublicKeyEthereumMissingSignature(t *testing.T) { var userAPI fakePublicKeyUserApi ctx := context.Background() loginContext := createLoginContext(t) - wallet, _ := test.CreateTestAccount() - message, _ := test.CreateEip4361TestMessage(wallet.PublicAddress) + wallet, _ := testutil.CreateTestAccount() + message, _ := testutil.CreateEip4361TestMessage(wallet.PublicAddress) sessionId := publicKeyTestSession( &ctx, loginContext.config, @@ -229,7 +228,7 @@ func TestLoginPublicKeyEthereumMissingSignature(t *testing.T) { ) // Escape \t and \n. Work around for marshalling and unmarshalling message. - msgStr := test.FromEip4361MessageToString(message) + msgStr := testutil.FromEip4361MessageToString(message) body := fmt.Sprintf(`{ "type": "m.login.publickey", "auth": { @@ -280,7 +279,7 @@ func TestLoginPublicKeyEthereumEmptyMessage(t *testing.T) { var userAPI fakePublicKeyUserApi ctx := context.Background() loginContext := createLoginContext(t) - wallet, _ := test.CreateTestAccount() + wallet, _ := testutil.CreateTestAccount() sessionId := publicKeyTestSession( &ctx, loginContext.config, @@ -333,7 +332,7 @@ func TestLoginPublicKeyEthereumWrongUserId(t *testing.T) { var userAPI fakePublicKeyUserApi ctx := context.Background() loginContext := createLoginContext(t) - wallet, _ := test.CreateTestAccount() + wallet, _ := testutil.CreateTestAccount() sessionId := publicKeyTestSession( &ctx, loginContext.config, diff --git a/clientapi/auth/login_publickey_test.go b/clientapi/auth/login_publickey_test.go index 6b95c5553..513616486 100644 --- a/clientapi/auth/login_publickey_test.go +++ b/clientapi/auth/login_publickey_test.go @@ -22,6 +22,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/setup/config" + testutil "github.com/matrix-org/dendrite/test" "github.com/stretchr/testify/assert" ) @@ -72,7 +73,10 @@ func TestLoginPublicKeyNewSession(t *testing.T) { params, "[object]") ethParams := params.(config.EthereumAuthParams) - assert.NotEmptyf(ethParams.ChainIDs, "ChainIDs actual: empty, expected not empty") + assert.Equalf( + testutil.EthereumTestNetworkId, + ethParams.ChainID, + "ChainID actual: %d, expected %d", ethParams.ChainID, testutil.EthereumTestNetworkId) assert.NotEmptyf(ethParams.Version, "Version actual: \"\", expected: not empty") } diff --git a/clientapi/auth/password.go b/clientapi/auth/password.go index 3bd77eb3d..1c8540e41 100644 --- a/clientapi/auth/password.go +++ b/clientapi/auth/password.go @@ -74,7 +74,7 @@ func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login, JSON: jsonerror.BadJSON("A password must be supplied."), } } - localpart, err := userutil.ParseUsernameParam(username, &t.Config.Matrix.ServerName) + localpart, _, err := userutil.ParseUsernameParam(username, t.Config.Matrix) if err != nil { return nil, &util.JSONResponse{ Code: http.StatusUnauthorized, diff --git a/clientapi/authorization/authorization.go b/clientapi/authorization/authorization.go index f37f4becd..f81513d76 100644 --- a/clientapi/authorization/authorization.go +++ b/clientapi/authorization/authorization.go @@ -10,8 +10,8 @@ import ( func NewAuthorization(cfg *config.ClientAPI, rsAPI roomserver.ClientRoomserverAPI) authorization.Authorization { // Load authorization manager for Zion - if cfg.PublicKeyAuthentication.Ethereum.EnableAuthz { - auth, err := zion.NewZionAuthorization(rsAPI) + if cfg.PublicKeyAuthentication.Ethereum.GetEnableAuthZ() { + auth, err := zion.NewZionAuthorization(cfg, rsAPI) if err != nil { log.Errorln("Failed to initialise Zion authorization manager. Using default.", err) diff --git a/clientapi/routing/admin.go b/clientapi/routing/admin.go index 89c269f1a..9088f7716 100644 --- a/clientapi/routing/admin.go +++ b/clientapi/routing/admin.go @@ -70,7 +70,7 @@ func AdminEvacuateUser(req *http.Request, cfg *config.ClientAPI, device *userapi if err != nil { return util.MessageResponse(http.StatusBadRequest, err.Error()) } - if domain != cfg.Matrix.ServerName { + if !cfg.Matrix.IsLocalServerName(domain) { return util.JSONResponse{ Code: http.StatusBadRequest, JSON: jsonerror.MissingArgument("User ID must belong to this server."), @@ -169,7 +169,7 @@ func AdminMarkAsStale(req *http.Request, cfg *config.ClientAPI, keyAPI api.Clien if err != nil { return util.MessageResponse(http.StatusBadRequest, err.Error()) } - if domain == cfg.Matrix.ServerName { + if cfg.Matrix.IsLocalServerName(domain) { return util.JSONResponse{ Code: http.StatusBadRequest, JSON: jsonerror.InvalidParam("Can not mark local device list as stale"), @@ -191,3 +191,43 @@ func AdminMarkAsStale(req *http.Request, cfg *config.ClientAPI, keyAPI api.Clien JSON: struct{}{}, } } + +func AdminDownloadState(req *http.Request, cfg *config.ClientAPI, device *userapi.Device, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse { + vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) + if err != nil { + return util.ErrorResponse(err) + } + roomID, ok := vars["roomID"] + if !ok { + return util.JSONResponse{ + Code: http.StatusBadRequest, + JSON: jsonerror.MissingArgument("Expecting room ID."), + } + } + serverName, ok := vars["serverName"] + if !ok { + return util.JSONResponse{ + Code: http.StatusBadRequest, + JSON: jsonerror.MissingArgument("Expecting remote server name."), + } + } + res := &roomserverAPI.PerformAdminDownloadStateResponse{} + if err := rsAPI.PerformAdminDownloadState( + req.Context(), + &roomserverAPI.PerformAdminDownloadStateRequest{ + UserID: device.UserID, + RoomID: roomID, + ServerName: gomatrixserverlib.ServerName(serverName), + }, + 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{}{}, + } +} diff --git a/clientapi/routing/auth_fallback.go b/clientapi/routing/auth_fallback.go index abfe830fb..ad870993e 100644 --- a/clientapi/routing/auth_fallback.go +++ b/clientapi/routing/auth_fallback.go @@ -31,8 +31,7 @@ const recaptchaTemplate = ` Authentication - +