Skip to content
Snippets Groups Projects
  1. Mar 07, 2025
  2. Mar 04, 2025
    • Quentin Gliech's avatar
      Support getting the device ID explicitly from MAS (#18174) · 08c56c3a
      Quentin Gliech authored
      The context for this is that the Matrix spec allows basically anything
      in the device ID. With MSC3861, we're restricting this to strings that
      can be represented as scopes.
      Whilst this works well for next-gen auth sessions, compatibility/legacy
      sessions still can have characters that can't be encoded (mainly spaces)
      in them.
      
      To work around that, we added in MAS a behaviour where the device_id is
      given as an explicit property of the token introspection response, and
      remove it from the scope.
      Because we don't expect users to rollout new Synapse and MAS versions in
      sync, we needed a way to 'advertise' support for this behaviour: the
      easiest way to do that was through an extra header in the introspection
      response.
      
      On the longer term, I expect MAS and Synapse to move away from the
      introspection endpoint, and instead define a specific API for Synapse ->
      MAS communication.
      
      PR on the MAS side:
      https://github.com/element-hq/matrix-authentication-service/pull/4067
      08c56c3a
  3. Mar 03, 2025
    • Andrew Morgan's avatar
      Add `redirect_uri` option to `oidc_providers` entries (#18197) · 154e23f6
      Andrew Morgan authored
      
      Allows overriding the `redirect_uri` parameter sent to both the
      authorization and token endpoints of the IdP. Typically this parameter
      is hardcoded to `<public_baseurl>/_synapse/client/oidc/callback`.
      
      Yet it can be useful in certain contexts to allow a different callback
      URL. For instance, if you would like to intercept the authorization code
      returned from the IdP and do something with it, before eventually
      calling Synapse's OIDC callback URL yourself.
      
      This change enables enterprise use cases but does not change the default
      behaviour.
      
      ---
      
      Best reviewed commit-by-commit.
      
      ---------
      
      Co-authored-by: default avatarEric Eastwood <erice@element.io>
      154e23f6
  4. Feb 26, 2025
  5. Feb 25, 2025
  6. Feb 24, 2025
  7. Feb 21, 2025
  8. Feb 20, 2025
  9. Feb 18, 2025
  10. Feb 10, 2025
  11. Feb 07, 2025
  12. Feb 04, 2025
    • V02460's avatar
      Add MSC3861 config options admin_token_path and client_secret_path (#18004) · e41174ca
      V02460 authored
      Another PR on my quest to a `*_path` variant for every secret. Adds two
      config options `admin_token_path` and `client_secret_path` to the
      experimental config under `experimental_features.msc3861`. Also includes
      tests.
      
      I tried to be a good citizen here by following `attrs` conventions and
      not rewriting the corresponding non-path variants in the class, but
      instead adding methods to retrieve the value.
      
      Reading secrets from files has the security advantage of separating the
      secrets from the config. It also simplifies secrets management in
      Kubernetes. Also useful to NixOS users.
      e41174ca
  13. Feb 03, 2025
    • Erik Johnston's avatar
      Fix bug where purging history could lead to increase in disk space usage (#18131) · c46d452c
      Erik Johnston authored
      When purging history, we try and delete any state groups that become
      unreferenced (i.e. there are no longer any events that directly
      reference them). When we delete a state group that is referenced by
      another state group, we "de-delta" that state group so that it no longer
      refers to the state group that is deleted.
      
      There are two bugs with this approach that we fix here:
      1. There is a common pattern where we end up storing two state groups
      when persisting a state event: the state before and after the new state
      event, where the latter is stored as a delta to the former. When
      deleting state groups we only deleted the "new" state and left (and
      potentially de-deltaed) the old state. This was due to a bug/typo when
      trying to find referenced state groups.
      2. There are times where we store unreferenced state groups in the DB,
      during the purging of history these would not get rechecked and instead
      always de-deltaed. Instead, we should check for this case and delete any
      unreferenced state groups rather than de-deltaing them.
      
      The effect of the above bugs is that when purging history we'd end up
      with lots of unreferenced state groups that had been de-deltaed (i.e.
      stored as the full state). This can lead to dramatic increases in
      storage space used.
      c46d452c
    • Erik Johnston's avatar
      Add locking to more safely delete state groups: Part 2 (#18130) · 27dbb1b4
      Erik Johnston authored
      This actually makes it so that deleting state groups goes via the new
      mechanism.
      
      c.f. #18107
      27dbb1b4
    • Erik Johnston's avatar
      Add locking to more safely delete state groups: Part 1 (#18107) · aa6e5c2e
      Erik Johnston authored
      
      Currently we don't really have anything that stops us from deleting
      state groups when an in-flight event references it. This is a fairly
      rare race currently, but we want to be able to more aggressively delete
      state groups so it is important to address this to ensure that the
      database remains valid.
      
      This implements the locking, but doesn't actually use it.
      
      See the class docstring of the new data store for an explanation for how
      this works.
      
      ---------
      
      Co-authored-by: default avatarDevon Hudson <devon.dmytro@gmail.com>
      aa6e5c2e
  14. Jan 28, 2025
  15. Jan 27, 2025
    • Eric Eastwood's avatar
      Fix join being denied after being invited over federation (#18075) · 6ec5e13e
      Eric Eastwood authored
      This also happens for rejecting an invite. Basically, any out-of-band membership transition where we first get the membership as an `outlier` and then rely on federation filling us in to de-outlier it.
      
      This PR mainly addresses automated test flakiness, bots/scripts, and options within Synapse like [`auto_accept_invites`](https://element-hq.github.io/synapse/v1.122/usage/configuration/config_documentation.html#auto_accept_invites) that are able to react quickly (before federation is able to push us events), but also helps in generic scenarios where federation is lagging.
      
      I initially thought this might be a Synapse consistency issue (see issues labeled with [`Z-Read-After-Write`](https://github.com/matrix-org/synapse/labels/Z-Read-After-Write)) but it seems to be an event auth logic problem. Workers probably do increase the number of possible race condition scenarios that make this visible though (replication and cache invalidation lag).
      
      Fix https://github.com/element-hq/synapse/issues/15012
      (probably fixes https://github.com/matrix-org/synapse/issues/15012 (https://github.com/element-hq/synapse/issues/15012))
      Related to https://github.com/matrix-org/matrix-spec/issues/2062
      
      Problems:
      
       1. We don't consider [out-of-band membership](https://github.com/element-hq/synapse/blob/develop/docs/development/room-dag-concepts.md#out-of-band-membership-events) (outliers) in our `event_auth` logic even though we expose them in `/sync`.
       1. (This PR doesn't address this point) Perhaps we should consider authing events in the persistence queue as events already in the queue could allow subsequent events to be allowed (events come through many channels: federation transaction, remote invite, remote join, local send). But this doesn't save us in the case where the event is more delayed over federation.
      
      
      ### What happened before?
      
      I wrote some Complement test that stresses this exact scenario and reproduces the problem: https://github.com/matrix-org/complement/pull/757
      
      ```
      COMPLEMENT_ALWAYS_PRINT_SERVER_LOGS=1 COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -run TestSynapseConsistency
      ```
      
      
      We have `hs1` and `hs2` running in monolith mode (no workers):
      
       1. `@charlie1:hs2` is invited and joins the room:
           1. `hs1` invites `@charlie1:hs2` to a room which we receive on `hs2` as `PUT /_matrix/federation/v1/invite/{roomId}/{eventId}` (`on_invite_request(...)`) and the invite membership is persisted as an outlier. The `room_memberships` and `local_current_membership` database tables are also updated which means they are visible down `/sync` at this point.
           1. `@charlie1:hs2` decides to join because it saw the invite down `/sync`. Because `hs2` is not yet in the room, this happens as a remote join `make_join`/`send_join` which comes back with all of the auth events needed to auth successfully and now `@charlie1:hs2` is successfully joined to the room.
       1. `@charlie2:hs2` is invited and and tries to join the room:
           1. `hs1` invites `@charlie2:hs2` to the room which we receive on `hs2` as `PUT /_matrix/federation/v1/invite/{roomId}/{eventId}` (`on_invite_request(...)`) and the invite membership is persisted as an outlier. The `room_memberships` and `local_current_membership` database tables are also updated which means they are visible down `/sync` at this point.
           1. Because `hs2` is already participating in the room, we also see the invite come over federation in a transaction and we start processing it (not done yet, see below)
           1. `@charlie2:hs2` decides to join because it saw the invite down `/sync`. Because `hs2`, is already in the room, this happens as a local join but we deny the event because our `event_auth` logic thinks that we have no membership in the room :x: (expected to be able to join because we saw the invite down `/sync`)
           1. We finally finish processing the `@charlie2:hs2` invite event from and de-outlier it.
               - If this finished before we tried to join we would have been fine but this is the race condition that makes this situation visible.
      
      
      Logs for `hs2`:
      
      ```
      :ballot_box: on_invite_request: handling event <FrozenEventV3 event_id=$PRPCvdXdcqyjdUKP_NxGF2CcukmwOaoK0ZR1WiVOZVk, type=m.room.member, state_key=@user-2-charlie1:hs2, membership=invite, outlier=False>
      :flashlight: _store_room_members_txn update room_memberships: <FrozenEventV3 event_id=$PRPCvdXdcqyjdUKP_NxGF2CcukmwOaoK0ZR1WiVOZVk, type=m.room.member, state_key=@user-2-charlie1:hs2, membership=invite, outlier=True>
      :flashlight: _store_room_members_txn update local_current_membership: <FrozenEventV3 event_id=$PRPCvdXdcqyjdUKP_NxGF2CcukmwOaoK0ZR1WiVOZVk, type=m.room.member, state_key=@user-2-charlie1:hs2, membership=invite, outlier=True>
      :incoming_envelope: Notifying about new event <FrozenEventV3 event_id=$PRPCvdXdcqyjdUKP_NxGF2CcukmwOaoK0ZR1WiVOZVk, type=m.room.member, state_key=@user-2-charlie1:hs2, membership=invite, outlier=True>
      :white_check_mark: on_invite_request: handled event <FrozenEventV3 event_id=$PRPCvdXdcqyjdUKP_NxGF2CcukmwOaoK0ZR1WiVOZVk, type=m.room.member, state_key=@user-2-charlie1:hs2, membership=invite, outlier=True>
      :magnet: do_invite_join for @user-2-charlie1:hs2 in !sfZVBdLUezpPWetrol:hs1
      :flashlight: _store_room_members_txn update room_memberships: <FrozenEventV3 event_id=$bwv8LxFnqfpsw_rhR7OrTjtz09gaJ23MqstKOcs7ygA, type=m.room.member, state_key=@user-1-alice:hs1, membership=join, outlier=True>
      :flashlight: _store_room_members_txn update room_memberships: <FrozenEventV3 event_id=$oju1ts3G3pz5O62IesrxX5is4LxAwU3WPr4xvid5ijI, type=m.room.member, state_key=@user-2-charlie1:hs2, membership=join, outlier=False>
      :incoming_envelope: Notifying about new event <FrozenEventV3 event_id=$oju1ts3G3pz5O62IesrxX5is4LxAwU3WPr4xvid5ijI, type=m.room.member, state_key=@user-2-charlie1:hs2, membership=join, outlier=False>
      
      ...
      
      :ballot_box: on_invite_request: handling event <FrozenEventV3 event_id=$O_54j7O--6xMsegY5EVZ9SA-mI4_iHJOIoRwYyeWIPY, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=invite, outlier=False>
      :flashlight: _store_room_members_txn update room_memberships: <FrozenEventV3 event_id=$O_54j7O--6xMsegY5EVZ9SA-mI4_iHJOIoRwYyeWIPY, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=invite, outlier=True>
      :flashlight: _store_room_members_txn update local_current_membership: <FrozenEventV3 event_id=$O_54j7O--6xMsegY5EVZ9SA-mI4_iHJOIoRwYyeWIPY, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=invite, outlier=True>
      :incoming_envelope: Notifying about new event <FrozenEventV3 event_id=$O_54j7O--6xMsegY5EVZ9SA-mI4_iHJOIoRwYyeWIPY, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=invite, outlier=True>
      :white_check_mark: on_invite_request: handled event <FrozenEventV3 event_id=$O_54j7O--6xMsegY5EVZ9SA-mI4_iHJOIoRwYyeWIPY, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=invite, outlier=True>
      :mailbox_with_mail: handling received PDU in room !sfZVBdLUezpPWetrol:hs1: <FrozenEventV3 event_id=$O_54j7O--6xMsegY5EVZ9SA-mI4_iHJOIoRwYyeWIPY, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=invite, outlier=False>
      :postbox: handle_new_client_event: handling <FrozenEventV3 event_id=$WNVDTQrxy5tCdPQHMyHyIn7tE4NWqKsZ8Bn8R4WbBSA, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=join, outlier=False>
      :x: Denying new event <FrozenEventV3 event_id=$WNVDTQrxy5tCdPQHMyHyIn7tE4NWqKsZ8Bn8R4WbBSA, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=join, outlier=False> because 403: You are not invited to this room.
      synapse.http.server - 130 - INFO - POST-16 - <SynapseRequest at 0x7f460c91fbf0 method='POST' uri='/_matrix/client/v3/join/%21sfZVBdLUezpPWetrol:hs1?server_name=hs1' clientproto='HTTP/1.0' site='8080'> SynapseError: 403 - You are not invited to this room.
      :incoming_envelope: Notifying about new event <FrozenEventV3 event_id=$O_54j7O--6xMsegY5EVZ9SA-mI4_iHJOIoRwYyeWIPY, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=invite, outlier=False>
      :white_check_mark: handled received PDU in room !sfZVBdLUezpPWetrol:hs1: <FrozenEventV3 event_id=$O_54j7O--6xMsegY5EVZ9SA-mI4_iHJOIoRwYyeWIPY, type=m.room.member, state_key=@user-3-charlie2:hs2, membership=invite, outlier=False>
      ```
      6ec5e13e
  16. Jan 24, 2025
  17. Jan 21, 2025
  18. Jan 08, 2025
  19. Jan 06, 2025
  20. Jan 03, 2025
  21. Dec 18, 2024
    • Andrew Morgan's avatar
      Fix mypy errors on Twisted 24.11.0 (#17998) · 3eb92369
      Andrew Morgan authored
      Fixes various `mypy` errors associated with Twisted `24.11.0`.
      
      Hopefully addresses https://github.com/element-hq/synapse/issues/17075,
      though I've yet to test against `trunk`.
      
      Changes should be compatible with our currently pinned Twisted version
      of `24.7.0`.
      3eb92369
    • Andrew Morgan's avatar
      Bump mypy from 1.11.2 to 1.12.1 and fix new typechecking errors (#17999) · f1b0f9a4
      Andrew Morgan authored
      Supersedes https://github.com/element-hq/synapse/pull/17958.
      
      Awkwardly, the changes made to fix the mypy errors in 1.12.1 cause
      errors in 1.11.2. So you'll need to update your mypy version to 1.12.1
      to eliminate typechecking errors during developing.
      f1b0f9a4
    • cynhr's avatar
      Add email.tlsname config option (#17849) · f1ecf466
      cynhr authored
      The existing `email.smtp_host` config option is used for two distinct
      purposes: it is resolved into the IP address to connect to, and used to
      (request via SNI and) validate the server's certificate if TLS is
      enabled. This new option allows specifying a different name for the
      second purpose.
      
      This is especially helpful, if `email.smtp_host` isn't a global FQDN,
      but something that resolves only locally (e.g. "localhost" to connect
      through the loopback interface, or some other internally routed name),
      that one cannot get a valid certificate for.
      Alternatives would of course be to specify a global FQDN as
      `email.smtp_host`, or to disable TLS entirely, both of which might be
      undesirable, depending on the SMTP server configuration.
      f1ecf466
  22. Dec 17, 2024
    • V02460's avatar
      Add `macaroon_secret_key_path` config option (#17983) · 57bf4494
      V02460 authored
      Another config option on my quest to a `*_path` variant for every
      secret. This time it’s `macaroon_secret_key_path`.
      
      Reading secrets from files has the security advantage of separating the secrets from the config. It also simplifies secrets management in Kubernetes. Also useful to NixOS users.
      57bf4494
  23. Dec 16, 2024
    • Shay's avatar
      Add some useful endpoints to Admin API (#17948) · 8208186e
      Shay authored
      - Fetch the number of invites the provided user has sent after a given
      timestamp
      - Fetch the number of rooms the provided user has joined after a given
      timestamp, regardless if they have left/been banned from the rooms
      subsequently
      - Get report IDs of event reports where the provided user was the sender
      of the reported event
      8208186e
  24. Dec 13, 2024
  25. Dec 04, 2024
  26. Dec 03, 2024
Loading