Use join_policy API instead of joinable

The API is now under
 /groups/$group_id/setting/m.join_policy

and expects a JSON blob of the shape

```json
{
  "m.join_policy": {
    "type": "invite"
  }
}
```

where "invite" could alternatively be "open".
pull/3045/head
Luke Barnard 2018-04-03 15:40:43 +01:00
parent c5de6987c2
commit eb8d8d6f57
7 changed files with 58 additions and 23 deletions

View File

@ -860,9 +860,9 @@ class TransportLayerClient(object):
@log_function @log_function
def set_group_joinable(self, destination, group_id, requester_user_id, def set_group_joinable(self, destination, group_id, requester_user_id,
content): content):
"""Sets whether a group is joinable without an invite or knock """Sets the join policy for a group
""" """
path = PREFIX + "/groups/%s/joinable" % (group_id,) path = PREFIX + "/groups/%s/setting/m.join_policy" % (group_id,)
return self.client.post_json( return self.client.post_json(
destination=destination, destination=destination,

View File

@ -1125,10 +1125,10 @@ class FederationGroupsBulkPublicisedServlet(BaseFederationServlet):
defer.returnValue((200, resp)) defer.returnValue((200, resp))
class FederationGroupsJoinableServlet(BaseFederationServlet): class FederationGroupsSettingJoinPolicyServlet(BaseFederationServlet):
"""Sets whether a group is joinable without an invite or knock """Sets whether a group is joinable without an invite or knock
""" """
PATH = "/groups/(?P<group_id>[^/]*)/joinable$" PATH = "/groups/(?P<group_id>[^/]*)/setting/m.join_policy$"
@defer.inlineCallbacks @defer.inlineCallbacks
def on_POST(self, origin, content, query, group_id): def on_POST(self, origin, content, query, group_id):
@ -1136,7 +1136,7 @@ class FederationGroupsJoinableServlet(BaseFederationServlet):
if get_domain_from_id(requester_user_id) != origin: if get_domain_from_id(requester_user_id) != origin:
raise SynapseError(403, "requester_user_id doesn't match origin") raise SynapseError(403, "requester_user_id doesn't match origin")
new_content = yield self.handler.set_group_joinable( new_content = yield self.handler.set_group_join_policy(
group_id, requester_user_id, content group_id, requester_user_id, content
) )
@ -1191,7 +1191,7 @@ GROUP_SERVER_SERVLET_CLASSES = (
FederationGroupsSummaryUsersServlet, FederationGroupsSummaryUsersServlet,
FederationGroupsAddRoomsServlet, FederationGroupsAddRoomsServlet,
FederationGroupsAddRoomsConfigServlet, FederationGroupsAddRoomsConfigServlet,
FederationGroupsJoinableServlet, FederationGroupsSettingJoinPolicyServlet,
) )

View File

@ -207,20 +207,24 @@ class GroupsServerHandler(object):
defer.returnValue({}) defer.returnValue({})
@defer.inlineCallbacks @defer.inlineCallbacks
def set_group_joinable(self, group_id, requester_user_id, content): def set_group_join_policy(self, group_id, requester_user_id, content):
"""Sets whether a group is joinable without an invite or knock """Sets the group join policy.
Currently supported policies are:
- "invite": an invite must be received and accepted in order to join.
- "open": anyone can join.
""" """
yield self.check_group_is_ours( yield self.check_group_is_ours(
group_id, requester_user_id, and_exists=True, and_is_admin=requester_user_id group_id, requester_user_id, and_exists=True, and_is_admin=requester_user_id
) )
is_joinable = content.get('joinable') join_policy = _parse_join_policy_from_contents(content)
if is_joinable is None: if join_policy is None:
raise SynapseError( raise SynapseError(
400, "No value specified for 'joinable'" 400, "No value specified for 'm.join_policy'"
) )
yield self.store.set_group_joinable(group_id, is_joinable=is_joinable) yield self.store.set_group_join_policy(group_id, join_policy=join_policy)
defer.returnValue({}) defer.returnValue({})
@ -854,6 +858,31 @@ class GroupsServerHandler(object):
}) })
def _parse_join_policy_from_contents(content):
"""Given a content for a request, return the specified join policy or None
"""
join_policy_dict = content.get("m.join_policy")
if join_policy_dict:
return _parse_join_policy_dict(join_policy_dict)
else:
return None
def _parse_join_policy_dict(join_policy_dict):
"""Given a dict for the "m.join_policy" config return the join policy specified
"""
join_policy_type = join_policy_dict.get("type")
if not join_policy_type:
return True
if join_policy_type not in ("invite", "open"):
raise SynapseError(
400, "Synapse only supports 'invite'/'open' join rule"
)
return join_policy_type
def _parse_visibility_from_contents(content): def _parse_visibility_from_contents(content):
"""Given a content for a request parse out whether the entity should be """Given a content for a request parse out whether the entity should be
public or not public or not

View File

@ -91,7 +91,7 @@ class GroupsLocalHandler(object):
get_group_role = _create_rerouter("get_group_role") get_group_role = _create_rerouter("get_group_role")
get_group_roles = _create_rerouter("get_group_roles") get_group_roles = _create_rerouter("get_group_roles")
set_group_joinable = _create_rerouter("set_group_joinable") set_group_join_policy = _create_rerouter("set_group_join_policy")
@defer.inlineCallbacks @defer.inlineCallbacks
def get_group_summary(self, group_id, requester_user_id): def get_group_summary(self, group_id, requester_user_id):

View File

@ -402,13 +402,13 @@ class GroupInvitedUsersServlet(RestServlet):
defer.returnValue((200, result)) defer.returnValue((200, result))
class GroupJoinableServlet(RestServlet): class GroupSettingJoinPolicyServlet(RestServlet):
"""Set whether a group is joinable without an invite """Set group join policy
""" """
PATTERNS = client_v2_patterns("/groups/(?P<group_id>[^/]*)/joinable$") PATTERNS = client_v2_patterns("/groups/(?P<group_id>[^/]*)/setting/m.join_policy$")
def __init__(self, hs): def __init__(self, hs):
super(GroupJoinableServlet, self).__init__() super(GroupSettingJoinPolicyServlet, self).__init__()
self.auth = hs.get_auth() self.auth = hs.get_auth()
self.groups_handler = hs.get_groups_local_handler() self.groups_handler = hs.get_groups_local_handler()
@ -419,7 +419,7 @@ class GroupJoinableServlet(RestServlet):
content = parse_json_object_from_request(request) content = parse_json_object_from_request(request)
result = yield self.groups_handler.set_group_joinable( result = yield self.groups_handler.set_group_join_policy(
group_id, group_id,
requester_user_id, requester_user_id,
content, content,
@ -765,7 +765,7 @@ def register_servlets(hs, http_server):
GroupInvitedUsersServlet(hs).register(http_server) GroupInvitedUsersServlet(hs).register(http_server)
GroupUsersServlet(hs).register(http_server) GroupUsersServlet(hs).register(http_server)
GroupRoomServlet(hs).register(http_server) GroupRoomServlet(hs).register(http_server)
GroupJoinableServlet(hs).register(http_server) GroupSettingJoinPolicyServlet(hs).register(http_server)
GroupCreateServlet(hs).register(http_server) GroupCreateServlet(hs).register(http_server)
GroupAdminRoomsServlet(hs).register(http_server) GroupAdminRoomsServlet(hs).register(http_server)
GroupAdminRoomsConfigServlet(hs).register(http_server) GroupAdminRoomsConfigServlet(hs).register(http_server)

View File

@ -30,16 +30,16 @@ _DEFAULT_ROLE_ID = ""
class GroupServerStore(SQLBaseStore): class GroupServerStore(SQLBaseStore):
def set_group_joinable(self, group_id, is_joinable): def set_group_join_policy(self, group_id, join_policy):
return self._simple_update_one( return self._simple_update_one(
table="groups", table="groups",
keyvalues={ keyvalues={
"group_id": group_id, "group_id": group_id,
}, },
updatevalues={ updatevalues={
"is_joinable": is_joinable, "join_policy": join_policy,
}, },
desc="set_group_joinable", desc="set_group_join_policy",
) )
def get_group(self, group_id): def get_group(self, group_id):

View File

@ -13,4 +13,10 @@
* limitations under the License. * limitations under the License.
*/ */
ALTER TABLE groups ADD COLUMN is_joinable SMALLINT DEFAULT 0 NOT NULL; /*
* This isn't a real ENUM because sqlite doesn't support it
* and we use a default of NULL for inserted rows and interpret
* NULL at the python store level as necessary so that existing
* rows are given the correct default policy.
*/
ALTER TABLE groups ADD COLUMN join_policy TEXT DEFAULT NULL;