Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge branch 'matrix-org:develop' into oidc-soft-logout
Browse files Browse the repository at this point in the history
  • Loading branch information
hachem2001 authored Aug 11, 2023
2 parents b5002b5 + 614efc4 commit a2ae60b
Show file tree
Hide file tree
Showing 25 changed files with 364 additions and 113 deletions.
1 change: 1 addition & 0 deletions changelog.d/15870.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implements an admin API to lock an user without deactivating them. Based on [MSC3939](https://github.com/matrix-org/matrix-spec-proposals/pull/3939).
1 change: 1 addition & 0 deletions changelog.d/16052.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix long-standing bug where concurrent requests to change a user's push rules could cause a deadlock. Contributed by Nick @ Beeper (@fizzadar).
1 change: 1 addition & 0 deletions changelog.d/16089.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix the type annotation on `run_db_interaction` in the Module API.
1 change: 1 addition & 0 deletions changelog.d/16092.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Clean-up the presence code.
1 change: 1 addition & 0 deletions docs/admin_api/user_admin_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ Body parameters:
- `admin` - **bool**, optional, defaults to `false`. Whether the user is a homeserver administrator,
granting them access to the Admin API, among other things.
- `deactivated` - **bool**, optional. If unspecified, deactivation state will be left unchanged.
- `locked` - **bool**, optional. If unspecified, locked state will be left unchanged.

Note: the `password` field must also be set if both of the following are true:
- `deactivated` is set to `false` and the user was previously deactivated (you are reactivating this user)
Expand Down
2 changes: 2 additions & 0 deletions docs/usage/configuration/config_documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3637,13 +3637,15 @@ This option has the following sub-options:
* `prefer_local_users`: Defines whether to prefer local users in search query results.
If set to true, local users are more likely to appear above remote users when searching the
user directory. Defaults to false.
* `show_locked_users`: Defines whether to show locked users in search query results. Defaults to false.

Example configuration:
```yaml
user_directory:
enabled: false
search_all_users: true
prefer_local_users: true
show_locked_users: true
```
---
### `user_consent`
Expand Down
2 changes: 1 addition & 1 deletion synapse/_scripts/synapse_port_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
"redactions": ["have_censored"],
"room_stats_state": ["is_federatable"],
"rooms": ["is_public", "has_auth_chain_index"],
"users": ["shadow_banned", "approved"],
"users": ["shadow_banned", "approved", "locked"],
"un_partial_stated_event_stream": ["rejection_status_changed"],
"users_who_share_rooms": ["share_private"],
"per_user_experimental_features": ["enabled"],
Expand Down
1 change: 1 addition & 0 deletions synapse/api/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async def get_user_by_req(
request: SynapseRequest,
allow_guest: bool = False,
allow_expired: bool = False,
allow_locked: bool = False,
) -> Requester:
"""Get a registered user's ID.
Expand Down
15 changes: 14 additions & 1 deletion synapse/api/auth/internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ async def get_user_by_req(
request: SynapseRequest,
allow_guest: bool = False,
allow_expired: bool = False,
allow_locked: bool = False,
) -> Requester:
"""Get a registered user's ID.
Expand All @@ -79,7 +80,7 @@ async def get_user_by_req(
parent_span = active_span()
with start_active_span("get_user_by_req"):
requester = await self._wrapped_get_user_by_req(
request, allow_guest, allow_expired
request, allow_guest, allow_expired, allow_locked
)

if parent_span:
Expand Down Expand Up @@ -107,6 +108,7 @@ async def _wrapped_get_user_by_req(
request: SynapseRequest,
allow_guest: bool,
allow_expired: bool,
allow_locked: bool,
) -> Requester:
"""Helper for get_user_by_req
Expand All @@ -126,6 +128,17 @@ async def _wrapped_get_user_by_req(
access_token, allow_expired=allow_expired
)

# Deny the request if the user account is locked.
if not allow_locked and await self.store.get_user_locked_status(
requester.user.to_string()
):
raise AuthError(
401,
"User account has been locked",
errcode=Codes.USER_LOCKED,
additional_fields={"soft_logout": True},
)

# Deny the request if the user account has expired.
# This check is only done for regular users, not appservice ones.
if not allow_expired:
Expand Down
13 changes: 13 additions & 0 deletions synapse/api/auth/msc3861_delegated.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from synapse.api.auth.base import BaseAuth
from synapse.api.errors import (
AuthError,
Codes,
HttpResponseException,
InvalidClientTokenError,
OAuthInsufficientScopeError,
Expand Down Expand Up @@ -196,6 +197,7 @@ async def get_user_by_req(
request: SynapseRequest,
allow_guest: bool = False,
allow_expired: bool = False,
allow_locked: bool = False,
) -> Requester:
access_token = self.get_access_token_from_request(request)

Expand All @@ -205,6 +207,17 @@ async def get_user_by_req(
# so that we don't provision the user if they don't have enough permission:
requester = await self.get_user_by_access_token(access_token, allow_expired)

# Deny the request if the user account is locked.
if not allow_locked and await self.store.get_user_locked_status(
requester.user.to_string()
):
raise AuthError(
401,
"User account has been locked",
errcode=Codes.USER_LOCKED,
additional_fields={"soft_logout": True},
)

if not allow_guest and requester.is_guest:
raise OAuthInsufficientScopeError([SCOPE_MATRIX_API])

Expand Down
2 changes: 2 additions & 0 deletions synapse/api/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class Codes(str, Enum):
WEAK_PASSWORD = "M_WEAK_PASSWORD"
INVALID_SIGNATURE = "M_INVALID_SIGNATURE"
USER_DEACTIVATED = "M_USER_DEACTIVATED"
# USER_LOCKED = "M_USER_LOCKED"
USER_LOCKED = "ORG_MATRIX_MSC3939_USER_LOCKED"

# Part of MSC3848
# https://github.com/matrix-org/matrix-spec-proposals/pull/3848
Expand Down
1 change: 1 addition & 0 deletions synapse/config/user_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
self.user_directory_search_prefer_local_users = user_directory_config.get(
"prefer_local_users", False
)
self.show_locked_users = user_directory_config.get("show_locked_users", False)
1 change: 1 addition & 0 deletions synapse/handlers/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ async def get_user(self, user: UserID) -> Optional[JsonDict]:
"name",
"admin",
"deactivated",
"locked",
"shadow_banned",
"creation_ts",
"appservice_id",
Expand Down
Loading

0 comments on commit a2ae60b

Please sign in to comment.