Add admin APIs to force-join users to groups and manage their flair
Fixes https://github.com/matrix-org/synapse/issues/9143 Though the groups API is disappearing soon, these functions are intended to make flair management easier in the short term.
This commit is contained in:
parent
47d48a5853
commit
95d7074322
3 changed files with 88 additions and 2 deletions
|
@ -365,6 +365,32 @@ class GroupsLocalHandler(GroupsLocalWorkerHandler):
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
async def force_join_user_to_group(self, group_id, user_id):
|
||||||
|
"""Forces a user to join a group.
|
||||||
|
"""
|
||||||
|
if not self.is_mine_id(group_id):
|
||||||
|
raise SynapseError(400, "Can only affect local groups")
|
||||||
|
|
||||||
|
if not self.is_mine_id(user_id):
|
||||||
|
raise SynapseError(400, "Can only affect local users")
|
||||||
|
|
||||||
|
# Bypass the group server to avoid business logic regarding whether or not
|
||||||
|
# the user can actually join.
|
||||||
|
await self.store.add_user_to_group(group_id, user_id)
|
||||||
|
|
||||||
|
token = await self.store.register_user_group_membership(
|
||||||
|
group_id,
|
||||||
|
user_id,
|
||||||
|
membership="join",
|
||||||
|
is_admin=False,
|
||||||
|
local_attestation=None,
|
||||||
|
remote_attestation=None,
|
||||||
|
is_publicised=False,
|
||||||
|
)
|
||||||
|
self.notifier.on_new_event("groups_key", token, users=[user_id])
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
async def accept_invite(self, group_id, user_id, content):
|
async def accept_invite(self, group_id, user_id, content):
|
||||||
"""Accept an invite to a group
|
"""Accept an invite to a group
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -31,7 +31,11 @@ from synapse.rest.admin.event_reports import (
|
||||||
EventReportDetailRestServlet,
|
EventReportDetailRestServlet,
|
||||||
EventReportsRestServlet,
|
EventReportsRestServlet,
|
||||||
)
|
)
|
||||||
from synapse.rest.admin.groups import DeleteGroupAdminRestServlet
|
from synapse.rest.admin.groups import (
|
||||||
|
DeleteGroupAdminRestServlet,
|
||||||
|
ForceJoinGroupAdminRestServlet,
|
||||||
|
UpdatePublicityGroupAdminRestServlet,
|
||||||
|
)
|
||||||
from synapse.rest.admin.media import ListMediaInRoom, register_servlets_for_media_repo
|
from synapse.rest.admin.media import ListMediaInRoom, register_servlets_for_media_repo
|
||||||
from synapse.rest.admin.purge_room_servlet import PurgeRoomServlet
|
from synapse.rest.admin.purge_room_servlet import PurgeRoomServlet
|
||||||
from synapse.rest.admin.rooms import (
|
from synapse.rest.admin.rooms import (
|
||||||
|
@ -244,6 +248,8 @@ def register_servlets_for_client_rest_resource(hs, http_server):
|
||||||
ShutdownRoomRestServlet(hs).register(http_server)
|
ShutdownRoomRestServlet(hs).register(http_server)
|
||||||
UserRegisterServlet(hs).register(http_server)
|
UserRegisterServlet(hs).register(http_server)
|
||||||
DeleteGroupAdminRestServlet(hs).register(http_server)
|
DeleteGroupAdminRestServlet(hs).register(http_server)
|
||||||
|
ForceJoinGroupAdminRestServlet(hs).register(http_server)
|
||||||
|
UpdatePublicityGroupAdminRestServlet(hs).register(http_server)
|
||||||
AccountValidityRenewServlet(hs).register(http_server)
|
AccountValidityRenewServlet(hs).register(http_server)
|
||||||
|
|
||||||
# Load the media repo ones if we're using them. Otherwise load the servlets which
|
# Load the media repo ones if we're using them. Otherwise load the servlets which
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from synapse.api.errors import SynapseError
|
from synapse.api.errors import SynapseError
|
||||||
from synapse.http.servlet import RestServlet
|
from synapse.http.servlet import assert_params_in_dict, parse_json_object_from_request, RestServlet
|
||||||
from synapse.rest.admin._base import admin_patterns, assert_user_is_admin
|
from synapse.rest.admin._base import admin_patterns, assert_user_is_admin
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -41,3 +41,57 @@ class DeleteGroupAdminRestServlet(RestServlet):
|
||||||
|
|
||||||
await self.group_server.delete_group(group_id, requester.user.to_string())
|
await self.group_server.delete_group(group_id, requester.user.to_string())
|
||||||
return 200, {}
|
return 200, {}
|
||||||
|
|
||||||
|
|
||||||
|
class ForceJoinGroupAdminRestServlet(RestServlet):
|
||||||
|
"""Allows a server admin to force-join a local user to a local group.
|
||||||
|
"""
|
||||||
|
|
||||||
|
PATTERNS = admin_patterns("/group/(?P<group_id>[^/]*)/force_join$")
|
||||||
|
|
||||||
|
def __init__(self, hs):
|
||||||
|
self.groups_handler = hs.get_groups_local_handler()
|
||||||
|
self.is_mine_id = hs.is_mine_id
|
||||||
|
self.auth = hs.get_auth()
|
||||||
|
|
||||||
|
async def on_POST(self, request, group_id):
|
||||||
|
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(400, "Can only affect local groups")
|
||||||
|
|
||||||
|
body = parse_json_object_from_request(request, allow_empty_body=False)
|
||||||
|
assert_params_in_dict(body, ["user_id"])
|
||||||
|
target_user_id = body["user_id"]
|
||||||
|
await self.groups_handler.force_join_user_to_group(group_id, target_user_id)
|
||||||
|
|
||||||
|
return 200, {}
|
||||||
|
|
||||||
|
|
||||||
|
class UpdatePublicityGroupAdminRestServlet(RestServlet):
|
||||||
|
"""Allows a server admin to update a user's publicity (flair) for a given group.
|
||||||
|
"""
|
||||||
|
|
||||||
|
PATTERNS = admin_patterns("/group/(?P<group_id>[^/]*)/update_publicity$")
|
||||||
|
|
||||||
|
def __init__(self, hs):
|
||||||
|
self.store = hs.get_datastore()
|
||||||
|
self.is_mine_id = hs.is_mine_id
|
||||||
|
self.auth = hs.get_auth()
|
||||||
|
|
||||||
|
async def on_POST(self, request, group_id):
|
||||||
|
requester = await self.auth.get_user_by_req(request)
|
||||||
|
await assert_user_is_admin(self.auth, requester.user)
|
||||||
|
|
||||||
|
body = parse_json_object_from_request(request, allow_empty_body=False)
|
||||||
|
assert_params_in_dict(body, ["user_id"])
|
||||||
|
target_user_id = body["user_id"]
|
||||||
|
if not self.is_mine_id(target_user_id):
|
||||||
|
raise SynapseError(400, "Can only affect local users")
|
||||||
|
|
||||||
|
# Logic copied from `/self/update_publicity` endpoint.
|
||||||
|
publicise = body["publicise"]
|
||||||
|
await self.store.update_group_publicity(group_id, target_user_id, publicise)
|
||||||
|
|
||||||
|
return 200, {}
|
||||||
|
|
Loading…
Reference in a new issue