Compare commits

...

7 Commits

Author SHA1 Message Date
Ben Banfield-Zanin
1a7d96aa6f Merge remote-tracking branch 'origin/release-v1.20.0' into bbz/info-mainline-1.20.0 2020-09-15 11:44:49 +01:00
Travis Ralston
e70810934f Fix group server for older synapse 2020-08-24 11:48:50 -06:00
Travis Ralston
b8a05b5a3f Add rudimentary API for promoting/demoting other people in a group
For https://github.com/matrix-org/synapse/issues/2855 (initial)
2020-08-21 19:35:36 -06:00
Ben Banfield-Zanin
2e9f389fd2 Merge remote-tracking branch 'origin/release-v1.15.1' into bbz/info-mainline-1.15 2020-06-25 08:33:23 +01:00
Ben Banfield-Zanin
80c66c4bca Merge remote-tracking branch 'origin/babolivier/info_mainline' into bbz/info-mainline2 2020-04-30 08:24:15 +01:00
Brendan Abolivier
09cb7dec5f Improve error message 2020-04-23 17:22:47 +02:00
Brendan Abolivier
456fa172cf Implement use of internal-info 2020-04-23 13:22:02 +02:00
9 changed files with 123 additions and 8 deletions

View File

@@ -1139,6 +1139,11 @@ account_validity:
# Mandate that users are only allowed to associate certain formats of
# 3PIDs with accounts on this server.
#
# Use an Identity Server to establish which 3PIDs are allowed to register?
# Overrides allowed_local_3pids below.
#
#check_is_for_allowed_local_3pids: matrix.org
#
#allowed_local_3pids:
# - medium: email
# pattern: '.*@matrix\.org'

View File

@@ -100,6 +100,9 @@ class RegistrationConfig(Config):
self.registrations_require_3pid = config.get("registrations_require_3pid", [])
self.allowed_local_3pids = config.get("allowed_local_3pids", [])
self.check_is_for_allowed_local_3pids = config.get(
"check_is_for_allowed_local_3pids", None
)
self.enable_3pid_lookup = config.get("enable_3pid_lookup", True)
self.registration_shared_secret = config.get("registration_shared_secret")
@@ -294,6 +297,11 @@ class RegistrationConfig(Config):
# Mandate that users are only allowed to associate certain formats of
# 3PIDs with accounts on this server.
#
# Use an Identity Server to establish which 3PIDs are allowed to register?
# Overrides allowed_local_3pids below.
#
#check_is_for_allowed_local_3pids: matrix.org
#
#allowed_local_3pids:
# - medium: email
# pattern: '.*@matrix\\.org'

View File

@@ -719,6 +719,27 @@ class GroupsServerHandler(GroupsServerWorkerHandler):
raise NotImplementedError()
async def change_user_admin_in_group(
self, group_id, user_id, want_admin, requester_user_id, content
):
"""Promotes or demotes a user in a group.
"""
await self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
if requester_user_id == user_id:
raise SynapseError(400, "User cannot target themselves")
is_admin = await self.store.is_user_admin_in_group(
group_id, requester_user_id
)
if not is_admin:
raise SynapseError(403, "User is not admin in group")
await self.store.change_user_admin_in_group(group_id, user_id, want_admin)
return {}
async def remove_user_from_group(
self, group_id, user_id, requester_user_id, content
):

View File

@@ -461,6 +461,25 @@ class GroupsLocalHandler(GroupsLocalWorkerHandler):
return {"state": "invite", "user_profile": user_profile}
async def change_user_admin_in_group(
self, group_id, user_id, want_admin, requester_user_id, content
):
"""Promotes or demotes a user in a group.
"""
if not self.is_mine_id(user_id):
raise SynapseError(400, "User not on this server")
# TODO: We should probably support federation, but this is fine for now
if not self.is_mine_id(group_id):
raise SynapseError(400, "Group not on this server")
res = await self.groups_server_handler.change_user_admin_in_group(
group_id, user_id, want_admin, requester_user_id, content
)
return res
async def remove_user_from_group(
self, group_id, user_id, requester_user_id, content
):

View File

@@ -91,7 +91,7 @@ class EmailPasswordRequestTokenRestServlet(RestServlet):
send_attempt = body["send_attempt"]
next_link = body.get("next_link") # Optional param
if not check_3pid_allowed(self.hs, "email", email):
if not await check_3pid_allowed(self.hs, "email", email):
raise SynapseError(
403,
"Your email domain is not authorized on this server",
@@ -439,7 +439,7 @@ class EmailThreepidRequestTokenRestServlet(RestServlet):
send_attempt = body["send_attempt"]
next_link = body.get("next_link") # Optional param
if not check_3pid_allowed(self.hs, "email", email):
if not await check_3pid_allowed(self.hs, "email", email):
raise SynapseError(
403,
"Your email domain is not authorized on this server",
@@ -510,7 +510,7 @@ class MsisdnThreepidRequestTokenRestServlet(RestServlet):
msisdn = phone_number_to_msisdn(country, phone_number)
if not check_3pid_allowed(self.hs, "msisdn", msisdn):
if not await check_3pid_allowed(self.hs, "msisdn", msisdn):
raise SynapseError(
403,
"Account phone numbers are not authorized on this server",

View File

@@ -552,6 +552,31 @@ class GroupAdminUsersKickServlet(RestServlet):
return 200, result
class GroupAdminChangeAdminServlet(RestServlet):
"""Promote or demote a user in the group
"""
PATTERNS = client_patterns(
"/groups/(?P<group_id>[^/]*)/admin/users/admins/(?P<user_id>[^/]*)$"
)
def __init__(self, hs):
super(GroupAdminChangeAdminServlet, self).__init__()
self.auth = hs.get_auth()
self.clock = hs.get_clock()
self.groups_handler = hs.get_groups_local_handler()
async def on_POST(self, request, group_id, user_id):
requester = await self.auth.get_user_by_req(request)
requester_user_id = requester.user.to_string()
content = parse_json_object_from_request(request)
want_admin = content["is_admin"]
result = await self.groups_handler.change_user_admin_in_group(
group_id, user_id, want_admin, requester_user_id, content
)
return 200, result
class GroupSelfLeaveServlet(RestServlet):
"""Leave a joined group
@@ -726,6 +751,7 @@ def register_servlets(hs, http_server):
GroupAdminRoomsConfigServlet(hs).register(http_server)
GroupAdminUsersInviteServlet(hs).register(http_server)
GroupAdminUsersKickServlet(hs).register(http_server)
GroupAdminChangeAdminServlet(hs).register(http_server)
GroupSelfLeaveServlet(hs).register(http_server)
GroupSelfJoinServlet(hs).register(http_server)
GroupSelfAcceptInviteServlet(hs).register(http_server)

View File

@@ -117,10 +117,10 @@ class EmailRegisterRequestTokenRestServlet(RestServlet):
send_attempt = body["send_attempt"]
next_link = body.get("next_link") # Optional param
if not check_3pid_allowed(self.hs, "email", email):
if not await check_3pid_allowed(self.hs, "email", email):
raise SynapseError(
403,
"Your email domain is not authorized to register on this server",
"You currently can't create an account with this email address",
Codes.THREEPID_DENIED,
)
@@ -192,7 +192,7 @@ class MsisdnRegisterRequestTokenRestServlet(RestServlet):
msisdn = phone_number_to_msisdn(country, phone_number)
if not check_3pid_allowed(self.hs, "msisdn", msisdn):
if not await check_3pid_allowed(self.hs, "msisdn", msisdn):
raise SynapseError(
403,
"Phone numbers are not authorized to register on this server",
@@ -535,7 +535,7 @@ class RegisterRestServlet(RestServlet):
medium = auth_result[login_type]["medium"]
address = auth_result[login_type]["address"]
if not check_3pid_allowed(self.hs, medium, address):
if not await check_3pid_allowed(self.hs, medium, address):
raise SynapseError(
403,
"Third party identifiers (email/phone numbers)"

View File

@@ -1116,6 +1116,16 @@ class GroupServerStore(GroupServerWorkerStore):
"remove_user_from_group", _remove_user_from_group_txn
)
async def change_user_admin_in_group(
self, group_id: str, user_id: str, is_admin: bool
) -> int:
return await self.db_pool.simple_update(
table="group_users",
keyvalues={"group_id": group_id, "user_id": user_id},
updatevalues={"is_admin": is_admin},
desc="change_user_admin_in_group"
)
async def add_room_to_group(
self, group_id: str, room_id: str, is_public: bool
) -> None:

View File

@@ -19,7 +19,7 @@ import re
logger = logging.getLogger(__name__)
def check_3pid_allowed(hs, medium, address):
async def check_3pid_allowed(hs, medium, address):
"""Checks whether a given format of 3PID is allowed to be used on this HS
Args:
@@ -31,6 +31,32 @@ def check_3pid_allowed(hs, medium, address):
bool: whether the 3PID medium/address is allowed to be added to this HS
"""
if hs.config.check_is_for_allowed_local_3pids:
data = await hs.get_simple_http_client().get_json(
"https://%s%s" % (
hs.config.check_is_for_allowed_local_3pids,
"/_matrix/identity/api/v1/internal-info"
),
{'medium': medium, 'address': address}
)
# Check for invalid response
if 'hs' not in data and 'shadow_hs' not in data:
return False
# Check if this user is intended to register for this homeserver
if (
data.get('hs') != hs.config.server_name
and data.get('shadow_hs') != hs.config.server_name
):
return False
if data.get('requires_invite', False) and not data.get('invited', False):
# Requires an invite but hasn't been invited
return False
return True
if hs.config.allowed_local_3pids:
for constraint in hs.config.allowed_local_3pids:
logger.debug(