Skip to content

Comments

Fall back to checking power levels when sourcing local restricted join users#19321

Merged
MadLittleMods merged 4 commits intoelement-hq:developfrom
nexy7574:nexy7574/fix/v12-creatorless-local-joins
Jan 12, 2026
Merged

Fall back to checking power levels when sourcing local restricted join users#19321
MadLittleMods merged 4 commits intoelement-hq:developfrom
nexy7574:nexy7574/fix/v12-creatorless-local-joins

Conversation

@nexy7574
Copy link
Contributor

@nexy7574 nexy7574 commented Dec 22, 2025

Fix #19120 by always falling back to checking power levels for local users if a local creator cannot be found in a v12 room.

Complement tests: matrix-org/complement#836

Pull Request Checklist

  • Pull request is based on the develop branch
  • Pull request includes a changelog file. The entry should:
    • Be a short description of your change which makes sense to users. "Fixed a bug that prevented receiving messages from other servers." instead of "Moved X method from EventStore to EventWorkerStore.".
    • Use markdown where necessary, mostly for code blocks.
    • End with either a period (.) or an exclamation mark (!).
    • Start with a capital letter.
    • Feel free to credit yourself, by adding a sentence "Contributed by @github_username." or "Contributed by [Your Name]." to the end of the entry.
  • Code style is correct (run the linters)

… users

Signed-off-by: timedout <git@nexy7574.co.uk>
@nexy7574 nexy7574 requested a review from a team as a code owner December 22, 2025 19:25
Signed-off-by: timedout <git@nexy7574.co.uk>
chosen_user = local_creators.pop() # random creator
user_power_level = CREATOR_POWER_LEVEL
else:
if chosen_user is None:
Copy link
Contributor

@MadLittleMods MadLittleMods Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of change deserves a test of some sort to ensure we don't regress into the future. It's probably easiest to write a Complement test to setup this kind of scenario. Is this something you'd be comfortable with tackling?

Probably something in tests/restricted_rooms_test.go

As an example of running Complement tests for the Synapse project, here is how to run a single test:

COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh ./tests -run TestRestrictedRoomsLocalJoin

(checkout the complement repo as a sibling to the synapse repo)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll give it a shot

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened matrix-org/complement#836, let me know if I missed a step or anything.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Complement tests look good 👍. Thank you for creating a PR there as well. We will just wait to merge this PR until the Complement side is close to merge as well ⏩

chosen_user = local_creators.pop() # random creator
user_power_level = CREATOR_POWER_LEVEL
else:
if chosen_user is None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix itself looks good 👍

In terms of the surrounding context, it's weird that we use both get_users_which_can_issue_invite(...) and get_user_which_could_invite(...) as the disparity between them is what's causing the problem in the first place. As a follow-up PR, it would probably be good to settle one direction or the other.

# If the local host has a user who can issue invites, then a local
# join can be done.
#
# If not, generate a new list of remote hosts based on which
# can issue invites.
event_map = await self.store.get_events(state_before_join.values())
current_state = {
state_key: event_map[event_id]
for state_key, event_id in state_before_join.items()
}
allowed_servers = get_servers_from_users(
get_users_which_can_issue_invite(current_state)
)
# If the local server is not one of allowed servers, then a remote
# join must be done. Return the list of prospective servers based on
# which can issue invites.
if self.hs.hostname not in allowed_servers:
return True, list(allowed_servers)
# Ensure the member should be allowed access via membership in a room.
await self.event_auth_handler.check_restricted_join_rules(
state_before_join, room_version, user_id, previous_membership
)
# If this is going to be a local join, additional information must
# be included in the event content in order to efficiently validate
# the event.
content[
EventContentFields.AUTHORISING_USER
] = await self.event_auth_handler.get_user_which_could_invite(
room_id,
state_before_join,
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracked by #19374

MadLittleMods pushed a commit to matrix-org/complement that referenced this pull request Jan 12, 2026
@MadLittleMods MadLittleMods merged commit 6e80f2c into element-hq:develop Jan 12, 2026
41 checks passed
alexlebens pushed a commit to alexlebens/infrastructure that referenced this pull request Jan 27, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [element-hq/synapse](https://github.com/element-hq/synapse) | minor | `1.145.0` → `1.146.0` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the Dependency Dashboard for more information.

---

### Release Notes

<details>
<summary>element-hq/synapse (element-hq/synapse)</summary>

### [`v1.146.0`](https://github.com/element-hq/synapse/releases/tag/v1.146.0)

[Compare Source](element-hq/synapse@v1.145.0...v1.146.0rc1)

### Synapse 1.146.0 (2026-01-27)

No significant changes since 1.146.0rc1.

#### Deprecations and Removals

- [MSC2697](matrix-org/matrix-spec-proposals#2697) (Dehydrated devices) has been removed, as the MSC is closed. Developers should migrate to [MSC3814](matrix-org/matrix-spec-proposals#3814). ([#&#8203;19346](element-hq/synapse#19346))
- Support for Ubuntu 25.04 (Plucky Puffin) has been dropped. Synapse no longer builds debian packages for Ubuntu 25.04.

### Synapse 1.146.0rc1 (2026-01-20)

#### Features

- Add a new config option [`enable_local_media_storage`](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_local_media_storage) which controls whether media is additionally stored locally when using configured `media_storage_providers`. Setting this to `false` allows off-site media storage without a local cache. Contributed by Patrice Brend'amour [@&#8203;dr](https://github.com/dr).allgood. ([#&#8203;19204](element-hq/synapse#19204))
- Stabilise support for [MSC4312](matrix-org/matrix-spec-proposals#4312 `m.oauth` User-Interactive Auth stage for resetting cross-signing identity with the OAuth 2.0 API. The old, unstable name (`org.matrix.cross_signing_reset`) is now deprecated and will be removed in a future release. ([#&#8203;19273](element-hq/synapse#19273))
- Refactor Grafana dashboard to use `server_name` label (instead of `instance`). ([#&#8203;19337](element-hq/synapse#19337))

#### Bugfixes

- Fix joining a restricted v12 room locally when no local room creator is present but local users with sufficient power levels are. Contributed by [@&#8203;nexy7574](https://github.com/nexy7574). ([#&#8203;19321](element-hq/synapse#19321))
- Fixed parallel calls to `/_matrix/media/v1/create` being ratelimited for appservices even if `rate_limited: false` was set in the registration. Contributed by [@&#8203;tulir](https://github.com/tulir) @&#8203; Beeper. ([#&#8203;19335](element-hq/synapse#19335))
- Fix a bug introduced in 1.61.0 where a user's membership in a room was accidentally ignored when considering access to historical state events in rooms with the "shared" history visibility. Contributed by Lukas Tautz. ([#&#8203;19353](element-hq/synapse#19353))
- [MSC4140](matrix-org/matrix-spec-proposals#4140): Store the JSON content of scheduled delayed events as text instead of a byte array. This fixes the inability to schedule a delayed event with non-ASCII characters in its content. ([#&#8203;19360](element-hq/synapse#19360))
- Always rollback database transactions when retrying (avoid orphaned connections). ([#&#8203;19372](element-hq/synapse#19372))
- Fix `InFlightGauge` typing to allow upgrading to `prometheus_client` 0.24. ([#&#8203;19379](element-hq/synapse#19379))

#### Updates to the Docker image

- Add [Prometheus HTTP service discovery](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config) endpoint for easy discovery of all workers when using the `docker/Dockerfile-workers` image (see the [*Metrics* section of our Docker testing docs](docker/README-testing.md#metrics)). ([#&#8203;19336](element-hq/synapse#19336))

#### Improved Documentation

- Remove docs on legacy metric names (no longer in the codebase since 2022-12-06). ([#&#8203;19341](element-hq/synapse#19341))
- Clarify how the estimated value of room complexity is calculated internally. ([#&#8203;19384](element-hq/synapse#19384))

#### Internal Changes

- Add an internal `cancel_task` API to the task scheduler. ([#&#8203;19310](element-hq/synapse#19310))
- Tweak docstrings and signatures of `auth_types_for_event` and `get_catchup_room_event_ids`. ([#&#8203;19320](element-hq/synapse#19320))
- Replace usage of deprecated `assertEquals` with `assertEqual` in unit test code. ([#&#8203;19345](element-hq/synapse#19345))
- Drop support for Ubuntu 25.04 'Plucky Puffin', add support for Ubuntu 25.10 'Questing Quokka'. ([#&#8203;19348](element-hq/synapse#19348))
- Revert "Add an Admin API endpoint for listing quarantined media ([#&#8203;19268](element-hq/synapse#19268))". ([#&#8203;19351](element-hq/synapse#19351))
- Bump `mdbook` from 0.4.17 to 0.5.2 and remove our custom table-of-contents plugin in favour of the new default functionality. ([#&#8203;19356](element-hq/synapse#19356))
- Replace deprecated usage of PyGitHub's `GitRelease.title` with `.name` in release script. ([#&#8203;19358](element-hq/synapse#19358))
- Update the Element logo in Synapse's README to be an absolute URL, allowing it to render on other sites (such as PyPI). ([#&#8203;19368](element-hq/synapse#19368))
- Apply minor tweaks to v1.145.0 changelog. ([#&#8203;19376](element-hq/synapse#19376))
- Update Grafana dashboard syntax to use the latest from importing/exporting with Grafana 12.3.1. ([#&#8203;19381](element-hq/synapse#19381))
- Warn about skipping reactor metrics when using unknown reactor type. ([#&#8203;19383](element-hq/synapse#19383))
- Add support for reactor metrics with the `ProxiedReactor` used in worker Complement tests. ([#&#8203;19385](element-hq/synapse#19385))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi42OS4yIiwidXBkYXRlZEluVmVyIjoiNDIuNjkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/3533
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Attempting to join a restricted v12 room created by a remote user fails

2 participants