mirror of https://github.com/watcha-fr/synapse
Remove user-visible groups/communities code (#12553)
Makes it so that groups/communities no longer exist from a user-POV. E.g. we remove: * All API endpoints (including Client-Server, Server-Server, and admin). * Documented configuration options (and the experimental flag, which is now unused). * Special handling during room upgrades. * The `groups` section of the `/sync` response.code_spécifique_watcha
parent
759f9c09e1
commit
a8db8c6eba
@ -0,0 +1 @@ |
||||
Remove support for the non-standard groups/communities feature from Synapse. |
@ -1,115 +0,0 @@ |
||||
# Copyright 2021 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. |
||||
from typing import TYPE_CHECKING, Dict, List, Tuple, Type |
||||
|
||||
from synapse.api.errors import SynapseError |
||||
from synapse.federation.transport.server._base import ( |
||||
Authenticator, |
||||
BaseFederationServlet, |
||||
) |
||||
from synapse.handlers.groups_local import GroupsLocalHandler |
||||
from synapse.types import JsonDict, get_domain_from_id |
||||
from synapse.util.ratelimitutils import FederationRateLimiter |
||||
|
||||
if TYPE_CHECKING: |
||||
from synapse.server import HomeServer |
||||
|
||||
|
||||
class BaseGroupsLocalServlet(BaseFederationServlet): |
||||
"""Abstract base class for federation servlet classes which provides a groups local handler. |
||||
|
||||
See BaseFederationServlet for more information. |
||||
""" |
||||
|
||||
def __init__( |
||||
self, |
||||
hs: "HomeServer", |
||||
authenticator: Authenticator, |
||||
ratelimiter: FederationRateLimiter, |
||||
server_name: str, |
||||
): |
||||
super().__init__(hs, authenticator, ratelimiter, server_name) |
||||
self.handler = hs.get_groups_local_handler() |
||||
|
||||
|
||||
class FederationGroupsLocalInviteServlet(BaseGroupsLocalServlet): |
||||
"""A group server has invited a local user""" |
||||
|
||||
PATH = "/groups/local/(?P<group_id>[^/]*)/users/(?P<user_id>[^/]*)/invite" |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
user_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
if get_domain_from_id(group_id) != origin: |
||||
raise SynapseError(403, "group_id doesn't match origin") |
||||
|
||||
assert isinstance( |
||||
self.handler, GroupsLocalHandler |
||||
), "Workers cannot handle group invites." |
||||
|
||||
new_content = await self.handler.on_invite(group_id, user_id, content) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsRemoveLocalUserServlet(BaseGroupsLocalServlet): |
||||
"""A group server has removed a local user""" |
||||
|
||||
PATH = "/groups/local/(?P<group_id>[^/]*)/users/(?P<user_id>[^/]*)/remove" |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
user_id: str, |
||||
) -> Tuple[int, None]: |
||||
if get_domain_from_id(group_id) != origin: |
||||
raise SynapseError(403, "user_id doesn't match origin") |
||||
|
||||
assert isinstance( |
||||
self.handler, GroupsLocalHandler |
||||
), "Workers cannot handle group removals." |
||||
|
||||
await self.handler.user_removed_from_group(group_id, user_id, content) |
||||
|
||||
return 200, None |
||||
|
||||
|
||||
class FederationGroupsBulkPublicisedServlet(BaseGroupsLocalServlet): |
||||
"""Get roles in a group""" |
||||
|
||||
PATH = "/get_groups_publicised" |
||||
|
||||
async def on_POST( |
||||
self, origin: str, content: JsonDict, query: Dict[bytes, List[bytes]] |
||||
) -> Tuple[int, JsonDict]: |
||||
resp = await self.handler.bulk_get_publicised_groups( |
||||
content["user_ids"], proxy=False |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
GROUP_LOCAL_SERVLET_CLASSES: Tuple[Type[BaseFederationServlet], ...] = ( |
||||
FederationGroupsLocalInviteServlet, |
||||
FederationGroupsRemoveLocalUserServlet, |
||||
FederationGroupsBulkPublicisedServlet, |
||||
) |
@ -1,755 +0,0 @@ |
||||
# Copyright 2021 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. |
||||
from typing import TYPE_CHECKING, Dict, List, Tuple, Type |
||||
|
||||
from typing_extensions import Literal |
||||
|
||||
from synapse.api.constants import MAX_GROUP_CATEGORYID_LENGTH, MAX_GROUP_ROLEID_LENGTH |
||||
from synapse.api.errors import Codes, SynapseError |
||||
from synapse.federation.transport.server._base import ( |
||||
Authenticator, |
||||
BaseFederationServlet, |
||||
) |
||||
from synapse.http.servlet import parse_string_from_args |
||||
from synapse.types import JsonDict, get_domain_from_id |
||||
from synapse.util.ratelimitutils import FederationRateLimiter |
||||
|
||||
if TYPE_CHECKING: |
||||
from synapse.server import HomeServer |
||||
|
||||
|
||||
class BaseGroupsServerServlet(BaseFederationServlet): |
||||
"""Abstract base class for federation servlet classes which provides a groups server handler. |
||||
|
||||
See BaseFederationServlet for more information. |
||||
""" |
||||
|
||||
def __init__( |
||||
self, |
||||
hs: "HomeServer", |
||||
authenticator: Authenticator, |
||||
ratelimiter: FederationRateLimiter, |
||||
server_name: str, |
||||
): |
||||
super().__init__(hs, authenticator, ratelimiter, server_name) |
||||
self.handler = hs.get_groups_server_handler() |
||||
|
||||
|
||||
class FederationGroupsProfileServlet(BaseGroupsServerServlet): |
||||
"""Get/set the basic profile of a group on behalf of a user""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/profile" |
||||
|
||||
async def on_GET( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.get_group_profile(group_id, requester_user_id) |
||||
|
||||
return 200, new_content |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.update_group_profile( |
||||
group_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsSummaryServlet(BaseGroupsServerServlet): |
||||
PATH = "/groups/(?P<group_id>[^/]*)/summary" |
||||
|
||||
async def on_GET( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.get_group_summary(group_id, requester_user_id) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsRoomsServlet(BaseGroupsServerServlet): |
||||
"""Get the rooms in a group on behalf of a user""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/rooms" |
||||
|
||||
async def on_GET( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.get_rooms_in_group(group_id, requester_user_id) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsAddRoomsServlet(BaseGroupsServerServlet): |
||||
"""Add/remove room from group""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/room/(?P<room_id>[^/]*)" |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
room_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.add_room_to_group( |
||||
group_id, requester_user_id, room_id, content |
||||
) |
||||
|
||||
return 200, new_content |
||||
|
||||
async def on_DELETE( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
room_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.remove_room_from_group( |
||||
group_id, requester_user_id, room_id |
||||
) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsAddRoomsConfigServlet(BaseGroupsServerServlet): |
||||
"""Update room config in group""" |
||||
|
||||
PATH = ( |
||||
"/groups/(?P<group_id>[^/]*)/room/(?P<room_id>[^/]*)" |
||||
"/config/(?P<config_key>[^/]*)" |
||||
) |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
room_id: str, |
||||
config_key: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
result = await self.handler.update_room_in_group( |
||||
group_id, requester_user_id, room_id, config_key, content |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class FederationGroupsUsersServlet(BaseGroupsServerServlet): |
||||
"""Get the users in a group on behalf of a user""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/users" |
||||
|
||||
async def on_GET( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.get_users_in_group(group_id, requester_user_id) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsInvitedUsersServlet(BaseGroupsServerServlet): |
||||
"""Get the users that have been invited to a group""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/invited_users" |
||||
|
||||
async def on_GET( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.get_invited_users_in_group( |
||||
group_id, requester_user_id |
||||
) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsInviteServlet(BaseGroupsServerServlet): |
||||
"""Ask a group server to invite someone to the group""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/users/(?P<user_id>[^/]*)/invite" |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
user_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.invite_to_group( |
||||
group_id, user_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsAcceptInviteServlet(BaseGroupsServerServlet): |
||||
"""Accept an invitation from the group server""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/users/(?P<user_id>[^/]*)/accept_invite" |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
user_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
if get_domain_from_id(user_id) != origin: |
||||
raise SynapseError(403, "user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.accept_invite(group_id, user_id, content) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsJoinServlet(BaseGroupsServerServlet): |
||||
"""Attempt to join a group""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/users/(?P<user_id>[^/]*)/join" |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
user_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
if get_domain_from_id(user_id) != origin: |
||||
raise SynapseError(403, "user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.join_group(group_id, user_id, content) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsRemoveUserServlet(BaseGroupsServerServlet): |
||||
"""Leave or kick a user from the group""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/users/(?P<user_id>[^/]*)/remove" |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
user_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.remove_user_from_group( |
||||
group_id, user_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
class FederationGroupsSummaryRoomsServlet(BaseGroupsServerServlet): |
||||
"""Add/remove a room from the group summary, with optional category. |
||||
|
||||
Matches both: |
||||
- /groups/:group/summary/rooms/:room_id |
||||
- /groups/:group/summary/categories/:category/rooms/:room_id |
||||
""" |
||||
|
||||
PATH = ( |
||||
"/groups/(?P<group_id>[^/]*)/summary" |
||||
"(/categories/(?P<category_id>[^/]+))?" |
||||
"/rooms/(?P<room_id>[^/]*)" |
||||
) |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
category_id: str, |
||||
room_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
if category_id == "": |
||||
raise SynapseError( |
||||
400, "category_id cannot be empty string", Codes.INVALID_PARAM |
||||
) |
||||
|
||||
if len(category_id) > MAX_GROUP_CATEGORYID_LENGTH: |
||||
raise SynapseError( |
||||
400, |
||||
"category_id may not be longer than %s characters" |
||||
% (MAX_GROUP_CATEGORYID_LENGTH,), |
||||
Codes.INVALID_PARAM, |
||||
) |
||||
|
||||
resp = await self.handler.update_group_summary_room( |
||||
group_id, |
||||
requester_user_id, |
||||
room_id=room_id, |
||||
category_id=category_id, |
||||
content=content, |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
async def on_DELETE( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
category_id: str, |
||||
room_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
if category_id == "": |
||||
raise SynapseError(400, "category_id cannot be empty string") |
||||
|
||||
resp = await self.handler.delete_group_summary_room( |
||||
group_id, requester_user_id, room_id=room_id, category_id=category_id |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class FederationGroupsCategoriesServlet(BaseGroupsServerServlet): |
||||
"""Get all categories for a group""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/categories/?" |
||||
|
||||
async def on_GET( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
resp = await self.handler.get_group_categories(group_id, requester_user_id) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class FederationGroupsCategoryServlet(BaseGroupsServerServlet): |
||||
"""Add/remove/get a category in a group""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/categories/(?P<category_id>[^/]+)" |
||||
|
||||
async def on_GET( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
category_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
resp = await self.handler.get_group_category( |
||||
group_id, requester_user_id, category_id |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
category_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
if category_id == "": |
||||
raise SynapseError(400, "category_id cannot be empty string") |
||||
|
||||
if len(category_id) > MAX_GROUP_CATEGORYID_LENGTH: |
||||
raise SynapseError( |
||||
400, |
||||
"category_id may not be longer than %s characters" |
||||
% (MAX_GROUP_CATEGORYID_LENGTH,), |
||||
Codes.INVALID_PARAM, |
||||
) |
||||
|
||||
resp = await self.handler.upsert_group_category( |
||||
group_id, requester_user_id, category_id, content |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
async def on_DELETE( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
category_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
if category_id == "": |
||||
raise SynapseError(400, "category_id cannot be empty string") |
||||
|
||||
resp = await self.handler.delete_group_category( |
||||
group_id, requester_user_id, category_id |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class FederationGroupsRolesServlet(BaseGroupsServerServlet): |
||||
"""Get roles in a group""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/roles/?" |
||||
|
||||
async def on_GET( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
resp = await self.handler.get_group_roles(group_id, requester_user_id) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class FederationGroupsRoleServlet(BaseGroupsServerServlet): |
||||
"""Add/remove/get a role in a group""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/roles/(?P<role_id>[^/]+)" |
||||
|
||||
async def on_GET( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
role_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
resp = await self.handler.get_group_role(group_id, requester_user_id, role_id) |
||||
|
||||
return 200, resp |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
role_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
if role_id == "": |
||||
raise SynapseError( |
||||
400, "role_id cannot be empty string", Codes.INVALID_PARAM |
||||
) |
||||
|
||||
if len(role_id) > MAX_GROUP_ROLEID_LENGTH: |
||||
raise SynapseError( |
||||
400, |
||||
"role_id may not be longer than %s characters" |
||||
% (MAX_GROUP_ROLEID_LENGTH,), |
||||
Codes.INVALID_PARAM, |
||||
) |
||||
|
||||
resp = await self.handler.update_group_role( |
||||
group_id, requester_user_id, role_id, content |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
async def on_DELETE( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
role_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
if role_id == "": |
||||
raise SynapseError(400, "role_id cannot be empty string") |
||||
|
||||
resp = await self.handler.delete_group_role( |
||||
group_id, requester_user_id, role_id |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class FederationGroupsSummaryUsersServlet(BaseGroupsServerServlet): |
||||
"""Add/remove a user from the group summary, with optional role. |
||||
|
||||
Matches both: |
||||
- /groups/:group/summary/users/:user_id |
||||
- /groups/:group/summary/roles/:role/users/:user_id |
||||
""" |
||||
|
||||
PATH = ( |
||||
"/groups/(?P<group_id>[^/]*)/summary" |
||||
"(/roles/(?P<role_id>[^/]+))?" |
||||
"/users/(?P<user_id>[^/]*)" |
||||
) |
||||
|
||||
async def on_POST( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
role_id: str, |
||||
user_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
if role_id == "": |
||||
raise SynapseError(400, "role_id cannot be empty string") |
||||
|
||||
if len(role_id) > MAX_GROUP_ROLEID_LENGTH: |
||||
raise SynapseError( |
||||
400, |
||||
"role_id may not be longer than %s characters" |
||||
% (MAX_GROUP_ROLEID_LENGTH,), |
||||
Codes.INVALID_PARAM, |
||||
) |
||||
|
||||
resp = await self.handler.update_group_summary_user( |
||||
group_id, |
||||
requester_user_id, |
||||
user_id=user_id, |
||||
role_id=role_id, |
||||
content=content, |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
async def on_DELETE( |
||||
self, |
||||
origin: str, |
||||
content: Literal[None], |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
role_id: str, |
||||
user_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
if role_id == "": |
||||
raise SynapseError(400, "role_id cannot be empty string") |
||||
|
||||
resp = await self.handler.delete_group_summary_user( |
||||
group_id, requester_user_id, user_id=user_id, role_id=role_id |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class FederationGroupsSettingJoinPolicyServlet(BaseGroupsServerServlet): |
||||
"""Sets whether a group is joinable without an invite or knock""" |
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/settings/m.join_policy" |
||||
|
||||
async def on_PUT( |
||||
self, |
||||
origin: str, |
||||
content: JsonDict, |
||||
query: Dict[bytes, List[bytes]], |
||||
group_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester_user_id = parse_string_from_args( |
||||
query, "requester_user_id", required=True |
||||
) |
||||
if get_domain_from_id(requester_user_id) != origin: |
||||
raise SynapseError(403, "requester_user_id doesn't match origin") |
||||
|
||||
new_content = await self.handler.set_group_join_policy( |
||||
group_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, new_content |
||||
|
||||
|
||||
GROUP_SERVER_SERVLET_CLASSES: Tuple[Type[BaseFederationServlet], ...] = ( |
||||
FederationGroupsProfileServlet, |
||||
FederationGroupsSummaryServlet, |
||||
FederationGroupsRoomsServlet, |
||||
FederationGroupsUsersServlet, |
||||
FederationGroupsInvitedUsersServlet, |
||||
FederationGroupsInviteServlet, |
||||
FederationGroupsAcceptInviteServlet, |
||||
FederationGroupsJoinServlet, |
||||
FederationGroupsRemoveUserServlet, |
||||
FederationGroupsSummaryRoomsServlet, |
||||
FederationGroupsCategoriesServlet, |
||||
FederationGroupsCategoryServlet, |
||||
FederationGroupsRolesServlet, |
||||
FederationGroupsRoleServlet, |
||||
FederationGroupsSummaryUsersServlet, |
||||
FederationGroupsAddRoomsServlet, |
||||
FederationGroupsAddRoomsConfigServlet, |
||||
FederationGroupsSettingJoinPolicyServlet, |
||||
) |
@ -1,50 +0,0 @@ |
||||
# Copyright 2019 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. |
||||
import logging |
||||
from http import HTTPStatus |
||||
from typing import TYPE_CHECKING, Tuple |
||||
|
||||
from synapse.api.errors import SynapseError |
||||
from synapse.http.servlet import RestServlet |
||||
from synapse.http.site import SynapseRequest |
||||
from synapse.rest.admin._base import admin_patterns, assert_user_is_admin |
||||
from synapse.types import JsonDict |
||||
|
||||
if TYPE_CHECKING: |
||||
from synapse.server import HomeServer |
||||
|
||||
logger = logging.getLogger(__name__) |
||||
|
||||
|
||||
class DeleteGroupAdminRestServlet(RestServlet): |
||||
"""Allows deleting of local groups""" |
||||
|
||||
PATTERNS = admin_patterns("/delete_group/(?P<group_id>[^/]*)$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
self.group_server = hs.get_groups_server_handler() |
||||
self.is_mine_id = hs.is_mine_id |
||||
self.auth = hs.get_auth() |
||||
|
||||
async def on_POST( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
await assert_user_is_admin(self.auth, requester.user) |
||||
|
||||
if not self.is_mine_id(group_id): |
||||
raise SynapseError(HTTPStatus.BAD_REQUEST, "Can only delete local groups") |
||||
|
||||
await self.group_server.delete_group(group_id, requester.user.to_string()) |
||||
return HTTPStatus.OK, {} |
@ -1,962 +0,0 @@ |
||||
# Copyright 2017 Vector Creations Ltd |
||||
# Copyright 2018 New Vector Ltd |
||||
# |
||||
# 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. |
||||
|
||||
import logging |
||||
from functools import wraps |
||||
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Optional, Tuple |
||||
|
||||
from twisted.web.server import Request |
||||
|
||||
from synapse.api.constants import ( |
||||
MAX_GROUP_CATEGORYID_LENGTH, |
||||
MAX_GROUP_ROLEID_LENGTH, |
||||
MAX_GROUPID_LENGTH, |
||||
) |
||||
from synapse.api.errors import Codes, SynapseError |
||||
from synapse.handlers.groups_local import GroupsLocalHandler |
||||
from synapse.http.server import HttpServer |
||||
from synapse.http.servlet import ( |
||||
RestServlet, |
||||
assert_params_in_dict, |
||||
parse_json_object_from_request, |
||||
) |
||||
from synapse.http.site import SynapseRequest |
||||
from synapse.types import GroupID, JsonDict |
||||
|
||||
from ._base import client_patterns |
||||
|
||||
if TYPE_CHECKING: |
||||
from synapse.server import HomeServer |
||||
|
||||
logger = logging.getLogger(__name__) |
||||
|
||||
|
||||
def _validate_group_id( |
||||
f: Callable[..., Awaitable[Tuple[int, JsonDict]]] |
||||
) -> Callable[..., Awaitable[Tuple[int, JsonDict]]]: |
||||
"""Wrapper to validate the form of the group ID. |
||||
|
||||
Can be applied to any on_FOO methods that accepts a group ID as a URL parameter. |
||||
""" |
||||
|
||||
@wraps(f) |
||||
def wrapper( |
||||
self: RestServlet, request: Request, group_id: str, *args: Any, **kwargs: Any |
||||
) -> Awaitable[Tuple[int, JsonDict]]: |
||||
if not GroupID.is_valid(group_id): |
||||
raise SynapseError(400, "%s is not a legal group ID" % (group_id,)) |
||||
|
||||
return f(self, request, group_id, *args, **kwargs) |
||||
|
||||
return wrapper |
||||
|
||||
|
||||
class GroupServlet(RestServlet): |
||||
"""Get the group profile""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/profile$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_GET( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
group_description = await self.groups_handler.get_group_profile( |
||||
group_id, requester_user_id |
||||
) |
||||
|
||||
return 200, group_description |
||||
|
||||
@_validate_group_id |
||||
async def on_POST( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert_params_in_dict( |
||||
content, ("name", "avatar_url", "short_description", "long_description") |
||||
) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot create group profiles." |
||||
await self.groups_handler.update_group_profile( |
||||
group_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, {} |
||||
|
||||
|
||||
class GroupSummaryServlet(RestServlet): |
||||
"""Get the full group summary""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/summary$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_GET( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
get_group_summary = await self.groups_handler.get_group_summary( |
||||
group_id, requester_user_id |
||||
) |
||||
|
||||
return 200, get_group_summary |
||||
|
||||
|
||||
class GroupSummaryRoomsCatServlet(RestServlet): |
||||
"""Update/delete a rooms entry in the summary. |
||||
|
||||
Matches both: |
||||
- /groups/:group/summary/rooms/:room_id |
||||
- /groups/:group/summary/categories/:category/rooms/:room_id |
||||
""" |
||||
|
||||
PATTERNS = client_patterns( |
||||
"/groups/(?P<group_id>[^/]*)/summary" |
||||
"(/categories/(?P<category_id>[^/]+))?" |
||||
"/rooms/(?P<room_id>[^/]*)$" |
||||
) |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, |
||||
request: SynapseRequest, |
||||
group_id: str, |
||||
category_id: Optional[str], |
||||
room_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
if category_id == "": |
||||
raise SynapseError(400, "category_id cannot be empty", Codes.INVALID_PARAM) |
||||
|
||||
if category_id and len(category_id) > MAX_GROUP_CATEGORYID_LENGTH: |
||||
raise SynapseError( |
||||
400, |
||||
"category_id may not be longer than %s characters" |
||||
% (MAX_GROUP_CATEGORYID_LENGTH,), |
||||
Codes.INVALID_PARAM, |
||||
) |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group summaries." |
||||
resp = await self.groups_handler.update_group_summary_room( |
||||
group_id, |
||||
requester_user_id, |
||||
room_id=room_id, |
||||
category_id=category_id, |
||||
content=content, |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
@_validate_group_id |
||||
async def on_DELETE( |
||||
self, request: SynapseRequest, group_id: str, category_id: str, room_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group profiles." |
||||
resp = await self.groups_handler.delete_group_summary_room( |
||||
group_id, requester_user_id, room_id=room_id, category_id=category_id |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class GroupCategoryServlet(RestServlet): |
||||
"""Get/add/update/delete a group category""" |
||||
|
||||
PATTERNS = client_patterns( |
||||
"/groups/(?P<group_id>[^/]*)/categories/(?P<category_id>[^/]+)$" |
||||
) |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_GET( |
||||
self, request: SynapseRequest, group_id: str, category_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
category = await self.groups_handler.get_group_category( |
||||
group_id, requester_user_id, category_id=category_id |
||||
) |
||||
|
||||
return 200, category |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str, category_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
if not category_id: |
||||
raise SynapseError(400, "category_id cannot be empty", Codes.INVALID_PARAM) |
||||
|
||||
if len(category_id) > MAX_GROUP_CATEGORYID_LENGTH: |
||||
raise SynapseError( |
||||
400, |
||||
"category_id may not be longer than %s characters" |
||||
% (MAX_GROUP_CATEGORYID_LENGTH,), |
||||
Codes.INVALID_PARAM, |
||||
) |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group categories." |
||||
resp = await self.groups_handler.update_group_category( |
||||
group_id, requester_user_id, category_id=category_id, content=content |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
@_validate_group_id |
||||
async def on_DELETE( |
||||
self, request: SynapseRequest, group_id: str, category_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group categories." |
||||
resp = await self.groups_handler.delete_group_category( |
||||
group_id, requester_user_id, category_id=category_id |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class GroupCategoriesServlet(RestServlet): |
||||
"""Get all group categories""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/categories/$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_GET( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
category = await self.groups_handler.get_group_categories( |
||||
group_id, requester_user_id |
||||
) |
||||
|
||||
return 200, category |
||||
|
||||
|
||||
class GroupRoleServlet(RestServlet): |
||||
"""Get/add/update/delete a group role""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/roles/(?P<role_id>[^/]+)$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_GET( |
||||
self, request: SynapseRequest, group_id: str, role_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
category = await self.groups_handler.get_group_role( |
||||
group_id, requester_user_id, role_id=role_id |
||||
) |
||||
|
||||
return 200, category |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str, role_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
if not role_id: |
||||
raise SynapseError(400, "role_id cannot be empty", Codes.INVALID_PARAM) |
||||
|
||||
if len(role_id) > MAX_GROUP_ROLEID_LENGTH: |
||||
raise SynapseError( |
||||
400, |
||||
"role_id may not be longer than %s characters" |
||||
% (MAX_GROUP_ROLEID_LENGTH,), |
||||
Codes.INVALID_PARAM, |
||||
) |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group roles." |
||||
resp = await self.groups_handler.update_group_role( |
||||
group_id, requester_user_id, role_id=role_id, content=content |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
@_validate_group_id |
||||
async def on_DELETE( |
||||
self, request: SynapseRequest, group_id: str, role_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group roles." |
||||
resp = await self.groups_handler.delete_group_role( |
||||
group_id, requester_user_id, role_id=role_id |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class GroupRolesServlet(RestServlet): |
||||
"""Get all group roles""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/roles/$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_GET( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
category = await self.groups_handler.get_group_roles( |
||||
group_id, requester_user_id |
||||
) |
||||
|
||||
return 200, category |
||||
|
||||
|
||||
class GroupSummaryUsersRoleServlet(RestServlet): |
||||
"""Update/delete a user's entry in the summary. |
||||
|
||||
Matches both: |
||||
- /groups/:group/summary/users/:room_id |
||||
- /groups/:group/summary/roles/:role/users/:user_id |
||||
""" |
||||
|
||||
PATTERNS = client_patterns( |
||||
"/groups/(?P<group_id>[^/]*)/summary" |
||||
"(/roles/(?P<role_id>[^/]+))?" |
||||
"/users/(?P<user_id>[^/]*)$" |
||||
) |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, |
||||
request: SynapseRequest, |
||||
group_id: str, |
||||
role_id: Optional[str], |
||||
user_id: str, |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
if role_id == "": |
||||
raise SynapseError(400, "role_id cannot be empty", Codes.INVALID_PARAM) |
||||
|
||||
if role_id and len(role_id) > MAX_GROUP_ROLEID_LENGTH: |
||||
raise SynapseError( |
||||
400, |
||||
"role_id may not be longer than %s characters" |
||||
% (MAX_GROUP_ROLEID_LENGTH,), |
||||
Codes.INVALID_PARAM, |
||||
) |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group summaries." |
||||
resp = await self.groups_handler.update_group_summary_user( |
||||
group_id, |
||||
requester_user_id, |
||||
user_id=user_id, |
||||
role_id=role_id, |
||||
content=content, |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
@_validate_group_id |
||||
async def on_DELETE( |
||||
self, request: SynapseRequest, group_id: str, role_id: str, user_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group summaries." |
||||
resp = await self.groups_handler.delete_group_summary_user( |
||||
group_id, requester_user_id, user_id=user_id, role_id=role_id |
||||
) |
||||
|
||||
return 200, resp |
||||
|
||||
|
||||
class GroupRoomServlet(RestServlet): |
||||
"""Get all rooms in a group""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/rooms$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_GET( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
result = await self.groups_handler.get_rooms_in_group( |
||||
group_id, requester_user_id |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupUsersServlet(RestServlet): |
||||
"""Get all users in a group""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/users$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_GET( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
result = await self.groups_handler.get_users_in_group( |
||||
group_id, requester_user_id |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupInvitedUsersServlet(RestServlet): |
||||
"""Get users invited to a group""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/invited_users$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_GET( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
result = await self.groups_handler.get_invited_users_in_group( |
||||
group_id, requester_user_id |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupSettingJoinPolicyServlet(RestServlet): |
||||
"""Set group join policy""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/settings/m.join_policy$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
|
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group join policy." |
||||
result = await self.groups_handler.set_group_join_policy( |
||||
group_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupCreateServlet(RestServlet): |
||||
"""Create a group""" |
||||
|
||||
PATTERNS = client_patterns("/create_group$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
self.server_name = hs.hostname |
||||
|
||||
async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
# TODO: Create group on remote server |
||||
content = parse_json_object_from_request(request) |
||||
localpart = content.pop("localpart") |
||||
group_id = GroupID(localpart, self.server_name).to_string() |
||||
|
||||
if not localpart: |
||||
raise SynapseError(400, "Group ID cannot be empty", Codes.INVALID_PARAM) |
||||
|
||||
if len(group_id) > MAX_GROUPID_LENGTH: |
||||
raise SynapseError( |
||||
400, |
||||
"Group ID may not be longer than %s characters" % (MAX_GROUPID_LENGTH,), |
||||
Codes.INVALID_PARAM, |
||||
) |
||||
|
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot create groups." |
||||
result = await self.groups_handler.create_group( |
||||
group_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupAdminRoomsServlet(RestServlet): |
||||
"""Add a room to the group""" |
||||
|
||||
PATTERNS = client_patterns( |
||||
"/groups/(?P<group_id>[^/]*)/admin/rooms/(?P<room_id>[^/]*)$" |
||||
) |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str, room_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify rooms in a group." |
||||
result = await self.groups_handler.add_room_to_group( |
||||
group_id, requester_user_id, room_id, content |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
@_validate_group_id |
||||
async def on_DELETE( |
||||
self, request: SynapseRequest, group_id: str, room_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group categories." |
||||
result = await self.groups_handler.remove_room_from_group( |
||||
group_id, requester_user_id, room_id |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupAdminRoomsConfigServlet(RestServlet): |
||||
"""Update the config of a room in a group""" |
||||
|
||||
PATTERNS = client_patterns( |
||||
"/groups/(?P<group_id>[^/]*)/admin/rooms/(?P<room_id>[^/]*)" |
||||
"/config/(?P<config_key>[^/]*)$" |
||||
) |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str, room_id: str, config_key: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot modify group categories." |
||||
result = await self.groups_handler.update_room_in_group( |
||||
group_id, requester_user_id, room_id, config_key, content |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupAdminUsersInviteServlet(RestServlet): |
||||
"""Invite a user to the group""" |
||||
|
||||
PATTERNS = client_patterns( |
||||
"/groups/(?P<group_id>[^/]*)/admin/users/invite/(?P<user_id>[^/]*)$" |
||||
) |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
self.store = hs.get_datastores().main |
||||
self.is_mine_id = hs.is_mine_id |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str, user_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
config = content.get("config", {}) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot invite users to a group." |
||||
result = await self.groups_handler.invite( |
||||
group_id, user_id, requester_user_id, config |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupAdminUsersKickServlet(RestServlet): |
||||
"""Kick a user from the group""" |
||||
|
||||
PATTERNS = client_patterns( |
||||
"/groups/(?P<group_id>[^/]*)/admin/users/remove/(?P<user_id>[^/]*)$" |
||||
) |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str, user_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot kick users from a group." |
||||
result = await self.groups_handler.remove_user_from_group( |
||||
group_id, user_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupSelfLeaveServlet(RestServlet): |
||||
"""Leave a joined group""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/self/leave$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot leave a group for a users." |
||||
result = await self.groups_handler.remove_user_from_group( |
||||
group_id, requester_user_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupSelfJoinServlet(RestServlet): |
||||
"""Attempt to join a group, or knock""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/self/join$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot join a user to a group." |
||||
result = await self.groups_handler.join_group( |
||||
group_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupSelfAcceptInviteServlet(RestServlet): |
||||
"""Accept a group invite""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/self/accept_invite$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
assert isinstance( |
||||
self.groups_handler, GroupsLocalHandler |
||||
), "Workers cannot accept an invite to a group." |
||||
result = await self.groups_handler.accept_invite( |
||||
group_id, requester_user_id, content |
||||
) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupSelfUpdatePublicityServlet(RestServlet): |
||||
"""Update whether we publicise a users membership of a group""" |
||||
|
||||
PATTERNS = client_patterns("/groups/(?P<group_id>[^/]*)/self/update_publicity$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.store = hs.get_datastores().main |
||||
|
||||
@_validate_group_id |
||||
async def on_PUT( |
||||
self, request: SynapseRequest, group_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
publicise = content["publicise"] |
||||
await self.store.update_group_publicity(group_id, requester_user_id, publicise) |
||||
|
||||
return 200, {} |
||||
|
||||
|
||||
class PublicisedGroupsForUserServlet(RestServlet): |
||||
"""Get the list of groups a user is advertising""" |
||||
|
||||
PATTERNS = client_patterns("/publicised_groups/(?P<user_id>[^/]*)$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.store = hs.get_datastores().main |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
async def on_GET( |
||||
self, request: SynapseRequest, user_id: str |
||||
) -> Tuple[int, JsonDict]: |
||||
await self.auth.get_user_by_req(request, allow_guest=True) |
||||
|
||||
result = await self.groups_handler.get_publicised_groups_for_user(user_id) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class PublicisedGroupsForUsersServlet(RestServlet): |
||||
"""Get the list of groups a user is advertising""" |
||||
|
||||
PATTERNS = client_patterns("/publicised_groups$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.store = hs.get_datastores().main |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]: |
||||
await self.auth.get_user_by_req(request, allow_guest=True) |
||||
|
||||
content = parse_json_object_from_request(request) |
||||
user_ids = content["user_ids"] |
||||
|
||||
result = await self.groups_handler.bulk_get_publicised_groups(user_ids) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
class GroupsForUserServlet(RestServlet): |
||||
"""Get all groups the logged in user is joined to""" |
||||
|
||||
PATTERNS = client_patterns("/joined_groups$") |
||||
|
||||
def __init__(self, hs: "HomeServer"): |
||||
super().__init__() |
||||
self.auth = hs.get_auth() |
||||
self.clock = hs.get_clock() |
||||
self.groups_handler = hs.get_groups_local_handler() |
||||
|
||||
async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]: |
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True) |
||||
requester_user_id = requester.user.to_string() |
||||
|
||||
result = await self.groups_handler.get_joined_groups(requester_user_id) |
||||
|
||||
return 200, result |
||||
|
||||
|
||||
def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None: |
||||
GroupServlet(hs).register(http_server) |
||||
GroupSummaryServlet(hs).register(http_server) |
||||
GroupInvitedUsersServlet(hs).register(http_server) |
||||
GroupUsersServlet(hs).register(http_server) |
||||
GroupRoomServlet(hs).register(http_server) |
||||
GroupSettingJoinPolicyServlet(hs).register(http_server) |
||||
GroupCreateServlet(hs).register(http_server) |
||||
GroupAdminRoomsServlet(hs).register(http_server) |
||||
GroupAdminRoomsConfigServlet(hs).register(http_server) |
||||
GroupAdminUsersInviteServlet(hs).register(http_server) |
||||
GroupAdminUsersKickServlet(hs).register(http_server) |
||||
GroupSelfLeaveServlet(hs).register(http_server) |
||||
GroupSelfJoinServlet(hs).register(http_server) |
||||
GroupSelfAcceptInviteServlet(hs).register(http_server) |
||||
GroupsForUserServlet(hs).register(http_server) |
||||
GroupCategoryServlet(hs).register(http_server) |
||||
GroupCategoriesServlet(hs).register(http_server) |
||||
GroupSummaryRoomsCatServlet(hs).register(http_server) |
||||
GroupRoleServlet(hs).register(http_server) |
||||
GroupRolesServlet(hs).register(http_server) |
||||
GroupSelfUpdatePublicityServlet(hs).register(http_server) |
||||
GroupSummaryUsersRoleServlet(hs).register(http_server) |
||||
PublicisedGroupsForUserServlet(hs).register(http_server) |
||||
PublicisedGroupsForUsersServlet(hs).register(http_server) |
@ -1,56 +0,0 @@ |
||||
# Copyright 2021 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. |
||||
|
||||
from synapse.rest.client import groups, room |
||||
|
||||
from tests import unittest |
||||
from tests.unittest import override_config |
||||
|
||||
|
||||
class GroupsTestCase(unittest.HomeserverTestCase): |
||||
user_id = "@alice:test" |
||||
room_creator_user_id = "@bob:test" |
||||
|
||||
servlets = [room.register_servlets, groups.register_servlets] |
||||
|
||||
@override_config({"enable_group_creation": True}) |
||||
def test_rooms_limited_by_visibility(self) -> None: |
||||
group_id = "+spqr:test" |
||||
|
||||
# Alice creates a group |
||||
channel = self.make_request("POST", "/create_group", {"localpart": "spqr"}) |
||||
self.assertEqual(channel.code, 200, msg=channel.text_body) |
||||
self.assertEqual(channel.json_body, {"group_id": group_id}) |
||||
|
||||
# Bob creates a private room |
||||
room_id = self.helper.create_room_as(self.room_creator_user_id, is_public=False) |
||||
self.helper.auth_user_id = self.room_creator_user_id |
||||
self.helper.send_state( |
||||
room_id, "m.room.name", {"name": "bob's secret room"}, tok=None |
||||
) |
||||
self.helper.auth_user_id = self.user_id |
||||
|
||||
# Alice adds the room to her group. |
||||
channel = self.make_request( |
||||
"PUT", f"/groups/{group_id}/admin/rooms/{room_id}", {} |
||||
) |
||||
self.assertEqual(channel.code, 200, msg=channel.text_body) |
||||
self.assertEqual(channel.json_body, {}) |
||||
|
||||
# Alice now tries to retrieve the room list of the space. |
||||
channel = self.make_request("GET", f"/groups/{group_id}/rooms") |
||||
self.assertEqual(channel.code, 200, msg=channel.text_body) |
||||
self.assertEqual( |
||||
channel.json_body, {"chunk": [], "total_room_count_estimate": 0} |
||||
) |
Loading…
Reference in new issue