summary refs log tree commit diff
path: root/synapse/groups
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/groups')
-rw-r--r--synapse/groups/attestations.py44
-rw-r--r--synapse/groups/groups_server.py317
2 files changed, 152 insertions, 209 deletions
diff --git a/synapse/groups/attestations.py b/synapse/groups/attestations.py
index e5dda1975f..e73757570c 100644
--- a/synapse/groups/attestations.py
+++ b/synapse/groups/attestations.py
@@ -42,7 +42,7 @@ from signedjson.sign import sign_json
 
 from twisted.internet import defer
 
-from synapse.api.errors import RequestSendFailed, SynapseError
+from synapse.api.errors import HttpResponseException, RequestSendFailed, SynapseError
 from synapse.metrics.background_process_metrics import run_as_background_process
 from synapse.types import get_domain_from_id
 from synapse.util.logcontext import run_in_background
@@ -65,6 +65,7 @@ UPDATE_ATTESTATION_TIME_MS = 1 * 24 * 60 * 60 * 1000
 class GroupAttestationSigning(object):
     """Creates and verifies group attestations.
     """
+
     def __init__(self, hs):
         self.keyring = hs.get_keyring()
         self.clock = hs.get_clock()
@@ -113,11 +114,15 @@ class GroupAttestationSigning(object):
         validity_period *= random.uniform(*DEFAULT_ATTESTATION_JITTER)
         valid_until_ms = int(self.clock.time_msec() + validity_period)
 
-        return sign_json({
-            "group_id": group_id,
-            "user_id": user_id,
-            "valid_until_ms": valid_until_ms,
-        }, self.server_name, self.signing_key)
+        return sign_json(
+            {
+                "group_id": group_id,
+                "user_id": user_id,
+                "valid_until_ms": valid_until_ms,
+            },
+            self.server_name,
+            self.signing_key,
+        )
 
 
 class GroupAttestionRenewer(object):
@@ -132,9 +137,10 @@ class GroupAttestionRenewer(object):
         self.is_mine_id = hs.is_mine_id
         self.attestations = hs.get_groups_attestation_signing()
 
-        self._renew_attestations_loop = self.clock.looping_call(
-            self._start_renew_attestations, 30 * 60 * 1000,
-        )
+        if not hs.config.worker_app:
+            self._renew_attestations_loop = self.clock.looping_call(
+                self._start_renew_attestations, 30 * 60 * 1000
+            )
 
     @defer.inlineCallbacks
     def on_renew_attestation(self, group_id, user_id, content):
@@ -146,9 +152,7 @@ class GroupAttestionRenewer(object):
             raise SynapseError(400, "Neither user not group are on this server")
 
         yield self.attestations.verify_attestation(
-            attestation,
-            user_id=user_id,
-            group_id=group_id,
+            attestation, user_id=user_id, group_id=group_id
         )
 
         yield self.store.update_remote_attestion(group_id, user_id, attestation)
@@ -179,7 +183,8 @@ class GroupAttestionRenewer(object):
                 else:
                     logger.warn(
                         "Incorrectly trying to do attestations for user: %r in %r",
-                        user_id, group_id,
+                        user_id,
+                        group_id,
                     )
                     yield self.store.remove_attestation_renewal(group_id, user_id)
                     return
@@ -187,21 +192,20 @@ class GroupAttestionRenewer(object):
                 attestation = self.attestations.create_attestation(group_id, user_id)
 
                 yield self.transport_client.renew_group_attestation(
-                    destination, group_id, user_id,
-                    content={"attestation": attestation},
+                    destination, group_id, user_id, content={"attestation": attestation}
                 )
 
                 yield self.store.update_attestation_renewal(
                     group_id, user_id, attestation
                 )
-            except RequestSendFailed as e:
+            except (RequestSendFailed, HttpResponseException) as e:
                 logger.warning(
-                    "Failed to renew attestation of %r in %r: %s",
-                    user_id, group_id, e,
+                    "Failed to renew attestation of %r in %r: %s", user_id, group_id, e
                 )
             except Exception:
-                logger.exception("Error renewing attestation of %r in %r",
-                                 user_id, group_id)
+                logger.exception(
+                    "Error renewing attestation of %r in %r", user_id, group_id
+                )
 
         for row in rows:
             group_id = row["group_id"]
diff --git a/synapse/groups/groups_server.py b/synapse/groups/groups_server.py
index 817be40360..168c9e3f84 100644
--- a/synapse/groups/groups_server.py
+++ b/synapse/groups/groups_server.py
@@ -54,8 +54,9 @@ class GroupsServerHandler(object):
         hs.get_groups_attestation_renewer()
 
     @defer.inlineCallbacks
-    def check_group_is_ours(self, group_id, requester_user_id,
-                            and_exists=False, and_is_admin=None):
+    def check_group_is_ours(
+        self, group_id, requester_user_id, and_exists=False, and_is_admin=None
+    ):
         """Check that the group is ours, and optionally if it exists.
 
         If group does exist then return group.
@@ -73,7 +74,9 @@ class GroupsServerHandler(object):
         if and_exists and not group:
             raise SynapseError(404, "Unknown group")
 
-        is_user_in_group = yield self.store.is_user_in_group(requester_user_id, group_id)
+        is_user_in_group = yield self.store.is_user_in_group(
+            requester_user_id, group_id
+        )
         if group and not is_user_in_group and not group["is_public"]:
             raise SynapseError(404, "Unknown group")
 
@@ -96,25 +99,27 @@ class GroupsServerHandler(object):
         """
         yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
-        is_user_in_group = yield self.store.is_user_in_group(requester_user_id, group_id)
+        is_user_in_group = yield self.store.is_user_in_group(
+            requester_user_id, group_id
+        )
 
         profile = yield self.get_group_profile(group_id, requester_user_id)
 
         users, roles = yield self.store.get_users_for_summary_by_role(
-            group_id, include_private=is_user_in_group,
+            group_id, include_private=is_user_in_group
         )
 
         # TODO: Add profiles to users
 
         rooms, categories = yield self.store.get_rooms_for_summary_by_category(
-            group_id, include_private=is_user_in_group,
+            group_id, include_private=is_user_in_group
         )
 
         for room_entry in rooms:
             room_id = room_entry["room_id"]
             joined_users = yield self.store.get_users_in_room(room_id)
             entry = yield self.room_list_handler.generate_room_entry(
-                room_id, len(joined_users), with_alias=False, allow_private=True,
+                room_id, len(joined_users), with_alias=False, allow_private=True
             )
             entry = dict(entry)  # so we don't change whats cached
             entry.pop("room_id", None)
@@ -134,7 +139,7 @@ class GroupsServerHandler(object):
                 entry["attestation"] = attestation
             else:
                 entry["attestation"] = self.attestations.create_attestation(
-                    group_id, user_id,
+                    group_id, user_id
                 )
 
             user_profile = yield self.profile_handler.get_profile_from_cache(user_id)
@@ -143,34 +148,34 @@ class GroupsServerHandler(object):
         users.sort(key=lambda e: e.get("order", 0))
 
         membership_info = yield self.store.get_users_membership_info_in_group(
-            group_id, requester_user_id,
+            group_id, requester_user_id
         )
 
-        defer.returnValue({
-            "profile": profile,
-            "users_section": {
-                "users": users,
-                "roles": roles,
-                "total_user_count_estimate": 0,  # TODO
-            },
-            "rooms_section": {
-                "rooms": rooms,
-                "categories": categories,
-                "total_room_count_estimate": 0,  # TODO
-            },
-            "user": membership_info,
-        })
+        defer.returnValue(
+            {
+                "profile": profile,
+                "users_section": {
+                    "users": users,
+                    "roles": roles,
+                    "total_user_count_estimate": 0,  # TODO
+                },
+                "rooms_section": {
+                    "rooms": rooms,
+                    "categories": categories,
+                    "total_room_count_estimate": 0,  # TODO
+                },
+                "user": membership_info,
+            }
+        )
 
     @defer.inlineCallbacks
-    def update_group_summary_room(self, group_id, requester_user_id,
-                                  room_id, category_id, content):
+    def update_group_summary_room(
+        self, group_id, requester_user_id, room_id, category_id, content
+    ):
         """Add/update a room to the group summary
         """
         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
         )
 
         RoomID.from_string(room_id)  # Ensure valid room id
@@ -190,21 +195,17 @@ class GroupsServerHandler(object):
         defer.returnValue({})
 
     @defer.inlineCallbacks
-    def delete_group_summary_room(self, group_id, requester_user_id,
-                                  room_id, category_id):
+    def delete_group_summary_room(
+        self, group_id, requester_user_id, room_id, category_id
+    ):
         """Remove a room from the summary
         """
         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
         )
 
         yield self.store.remove_room_from_summary(
-            group_id=group_id,
-            room_id=room_id,
-            category_id=category_id,
+            group_id=group_id, room_id=room_id, category_id=category_id
         )
 
         defer.returnValue({})
@@ -223,9 +224,7 @@ class GroupsServerHandler(object):
 
         join_policy = _parse_join_policy_from_contents(content)
         if join_policy is None:
-            raise SynapseError(
-                400, "No value specified for 'm.join_policy'"
-            )
+            raise SynapseError(400, "No value specified for 'm.join_policy'")
 
         yield self.store.set_group_join_policy(group_id, join_policy=join_policy)
 
@@ -237,9 +236,7 @@ class GroupsServerHandler(object):
         """
         yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
-        categories = yield self.store.get_group_categories(
-            group_id=group_id,
-        )
+        categories = yield self.store.get_group_categories(group_id=group_id)
         defer.returnValue({"categories": categories})
 
     @defer.inlineCallbacks
@@ -249,8 +246,7 @@ class GroupsServerHandler(object):
         yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
         res = yield self.store.get_group_category(
-            group_id=group_id,
-            category_id=category_id,
+            group_id=group_id, category_id=category_id
         )
 
         defer.returnValue(res)
@@ -260,10 +256,7 @@ class GroupsServerHandler(object):
         """Add/Update a group category
         """
         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_public = _parse_visibility_from_contents(content)
@@ -283,15 +276,11 @@ class GroupsServerHandler(object):
         """Delete a group category
         """
         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
         )
 
         yield self.store.remove_group_category(
-            group_id=group_id,
-            category_id=category_id,
+            group_id=group_id, category_id=category_id
         )
 
         defer.returnValue({})
@@ -302,9 +291,7 @@ class GroupsServerHandler(object):
         """
         yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
-        roles = yield self.store.get_group_roles(
-            group_id=group_id,
-        )
+        roles = yield self.store.get_group_roles(group_id=group_id)
         defer.returnValue({"roles": roles})
 
     @defer.inlineCallbacks
@@ -313,10 +300,7 @@ class GroupsServerHandler(object):
         """
         yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
-        res = yield self.store.get_group_role(
-            group_id=group_id,
-            role_id=role_id,
-        )
+        res = yield self.store.get_group_role(group_id=group_id, role_id=role_id)
         defer.returnValue(res)
 
     @defer.inlineCallbacks
@@ -324,10 +308,7 @@ class GroupsServerHandler(object):
         """Add/update a role in a group
         """
         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_public = _parse_visibility_from_contents(content)
@@ -335,10 +316,7 @@ class GroupsServerHandler(object):
         profile = content.get("profile")
 
         yield self.store.upsert_group_role(
-            group_id=group_id,
-            role_id=role_id,
-            is_public=is_public,
-            profile=profile,
+            group_id=group_id, role_id=role_id, is_public=is_public, profile=profile
         )
 
         defer.returnValue({})
@@ -348,26 +326,21 @@ class GroupsServerHandler(object):
         """Remove role from group
         """
         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
         )
 
-        yield self.store.remove_group_role(
-            group_id=group_id,
-            role_id=role_id,
-        )
+        yield self.store.remove_group_role(group_id=group_id, role_id=role_id)
 
         defer.returnValue({})
 
     @defer.inlineCallbacks
-    def update_group_summary_user(self, group_id, requester_user_id, user_id, role_id,
-                                  content):
+    def update_group_summary_user(
+        self, group_id, requester_user_id, user_id, role_id, content
+    ):
         """Add/update a users entry in the group summary
         """
         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
         )
 
         order = content.get("order", None)
@@ -389,13 +362,11 @@ class GroupsServerHandler(object):
         """Remove a user from the group summary
         """
         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
         )
 
         yield self.store.remove_user_from_summary(
-            group_id=group_id,
-            user_id=user_id,
-            role_id=role_id,
+            group_id=group_id, user_id=user_id, role_id=role_id
         )
 
         defer.returnValue({})
@@ -411,8 +382,11 @@ class GroupsServerHandler(object):
 
         if group:
             cols = [
-                "name", "short_description", "long_description",
-                "avatar_url", "is_public",
+                "name",
+                "short_description",
+                "long_description",
+                "avatar_url",
+                "is_public",
             ]
             group_description = {key: group[key] for key in cols}
             group_description["is_openly_joinable"] = group["join_policy"] == "open"
@@ -426,12 +400,11 @@ class GroupsServerHandler(object):
         """Update the group profile
         """
         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
         )
 
         profile = {}
-        for keyname in ("name", "avatar_url", "short_description",
-                        "long_description"):
+        for keyname in ("name", "avatar_url", "short_description", "long_description"):
             if keyname in content:
                 value = content[keyname]
                 if not isinstance(value, string_types):
@@ -449,10 +422,12 @@ class GroupsServerHandler(object):
 
         yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
-        is_user_in_group = yield self.store.is_user_in_group(requester_user_id, group_id)
+        is_user_in_group = yield self.store.is_user_in_group(
+            requester_user_id, group_id
+        )
 
         user_results = yield self.store.get_users_in_group(
-            group_id, include_private=is_user_in_group,
+            group_id, include_private=is_user_in_group
         )
 
         chunk = []
@@ -470,24 +445,25 @@ class GroupsServerHandler(object):
             entry["is_privileged"] = bool(is_privileged)
 
             if not self.is_mine_id(g_user_id):
-                attestation = yield self.store.get_remote_attestation(group_id, g_user_id)
+                attestation = yield self.store.get_remote_attestation(
+                    group_id, g_user_id
+                )
                 if not attestation:
                     continue
 
                 entry["attestation"] = attestation
             else:
                 entry["attestation"] = self.attestations.create_attestation(
-                    group_id, g_user_id,
+                    group_id, g_user_id
                 )
 
             chunk.append(entry)
 
         # TODO: If admin add lists of users whose attestations have timed out
 
-        defer.returnValue({
-            "chunk": chunk,
-            "total_user_count_estimate": len(user_results),
-        })
+        defer.returnValue(
+            {"chunk": chunk, "total_user_count_estimate": len(user_results)}
+        )
 
     @defer.inlineCallbacks
     def get_invited_users_in_group(self, group_id, requester_user_id):
@@ -498,7 +474,9 @@ class GroupsServerHandler(object):
 
         yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
-        is_user_in_group = yield self.store.is_user_in_group(requester_user_id, group_id)
+        is_user_in_group = yield self.store.is_user_in_group(
+            requester_user_id, group_id
+        )
 
         if not is_user_in_group:
             raise SynapseError(403, "User not in group")
@@ -508,9 +486,7 @@ class GroupsServerHandler(object):
         user_profiles = []
 
         for user_id in invited_users:
-            user_profile = {
-                "user_id": user_id
-            }
+            user_profile = {"user_id": user_id}
             try:
                 profile = yield self.profile_handler.get_profile_from_cache(user_id)
                 user_profile.update(profile)
@@ -518,10 +494,9 @@ class GroupsServerHandler(object):
                 logger.warn("Error getting profile for %s: %s", user_id, e)
             user_profiles.append(user_profile)
 
-        defer.returnValue({
-            "chunk": user_profiles,
-            "total_user_count_estimate": len(invited_users),
-        })
+        defer.returnValue(
+            {"chunk": user_profiles, "total_user_count_estimate": len(invited_users)}
+        )
 
     @defer.inlineCallbacks
     def get_rooms_in_group(self, group_id, requester_user_id):
@@ -532,10 +507,12 @@ class GroupsServerHandler(object):
 
         yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
-        is_user_in_group = yield self.store.is_user_in_group(requester_user_id, group_id)
+        is_user_in_group = yield self.store.is_user_in_group(
+            requester_user_id, group_id
+        )
 
         room_results = yield self.store.get_rooms_in_group(
-            group_id, include_private=is_user_in_group,
+            group_id, include_private=is_user_in_group
         )
 
         chunk = []
@@ -544,7 +521,7 @@ class GroupsServerHandler(object):
 
             joined_users = yield self.store.get_users_in_room(room_id)
             entry = yield self.room_list_handler.generate_room_entry(
-                room_id, len(joined_users), with_alias=False, allow_private=True,
+                room_id, len(joined_users), with_alias=False, allow_private=True
             )
 
             if not entry:
@@ -556,10 +533,9 @@ class GroupsServerHandler(object):
 
         chunk.sort(key=lambda e: -e["num_joined_members"])
 
-        defer.returnValue({
-            "chunk": chunk,
-            "total_room_count_estimate": len(room_results),
-        })
+        defer.returnValue(
+            {"chunk": chunk, "total_room_count_estimate": len(room_results)}
+        )
 
     @defer.inlineCallbacks
     def add_room_to_group(self, group_id, requester_user_id, room_id, content):
@@ -578,8 +554,9 @@ class GroupsServerHandler(object):
         defer.returnValue({})
 
     @defer.inlineCallbacks
-    def update_room_in_group(self, group_id, requester_user_id, room_id, config_key,
-                             content):
+    def update_room_in_group(
+        self, group_id, requester_user_id, room_id, config_key, content
+    ):
         """Update room in group
         """
         RoomID.from_string(room_id)  # Ensure valid room id
@@ -592,8 +569,7 @@ class GroupsServerHandler(object):
             is_public = _parse_visibility_dict(content)
 
             yield self.store.update_room_in_group_visibility(
-                group_id, room_id,
-                is_public=is_public,
+                group_id, room_id, is_public=is_public
             )
         else:
             raise SynapseError(400, "Uknown config option")
@@ -625,10 +601,7 @@ class GroupsServerHandler(object):
         # TODO: Check if user is already invited
 
         content = {
-            "profile": {
-                "name": group["name"],
-                "avatar_url": group["avatar_url"],
-            },
+            "profile": {"name": group["name"], "avatar_url": group["avatar_url"]},
             "inviter": requester_user_id,
         }
 
@@ -638,9 +611,7 @@ class GroupsServerHandler(object):
             local_attestation = None
         else:
             local_attestation = self.attestations.create_attestation(group_id, user_id)
-            content.update({
-                "attestation": local_attestation,
-            })
+            content.update({"attestation": local_attestation})
 
             res = yield self.transport_client.invite_to_group_notification(
                 get_domain_from_id(user_id), group_id, user_id, content
@@ -658,31 +629,24 @@ class GroupsServerHandler(object):
                 remote_attestation = res["attestation"]
 
                 yield self.attestations.verify_attestation(
-                    remote_attestation,
-                    user_id=user_id,
-                    group_id=group_id,
+                    remote_attestation, user_id=user_id, group_id=group_id
                 )
             else:
                 remote_attestation = None
 
             yield self.store.add_user_to_group(
-                group_id, user_id,
+                group_id,
+                user_id,
                 is_admin=False,
                 is_public=False,  # TODO
                 local_attestation=local_attestation,
                 remote_attestation=remote_attestation,
             )
         elif res["state"] == "invite":
-            yield self.store.add_group_invite(
-                group_id, user_id,
-            )
-            defer.returnValue({
-                "state": "invite"
-            })
+            yield self.store.add_group_invite(group_id, user_id)
+            defer.returnValue({"state": "invite"})
         elif res["state"] == "reject":
-            defer.returnValue({
-                "state": "reject"
-            })
+            defer.returnValue({"state": "reject"})
         else:
             raise SynapseError(502, "Unknown state returned by HS")
 
@@ -693,16 +657,12 @@ class GroupsServerHandler(object):
         See accept_invite, join_group.
         """
         if not self.hs.is_mine_id(user_id):
-            local_attestation = self.attestations.create_attestation(
-                group_id, user_id,
-            )
+            local_attestation = self.attestations.create_attestation(group_id, user_id)
 
             remote_attestation = content["attestation"]
 
             yield self.attestations.verify_attestation(
-                remote_attestation,
-                user_id=user_id,
-                group_id=group_id,
+                remote_attestation, user_id=user_id, group_id=group_id
             )
         else:
             local_attestation = None
@@ -711,7 +671,8 @@ class GroupsServerHandler(object):
         is_public = _parse_visibility_from_contents(content)
 
         yield self.store.add_user_to_group(
-            group_id, user_id,
+            group_id,
+            user_id,
             is_admin=False,
             is_public=is_public,
             local_attestation=local_attestation,
@@ -731,17 +692,14 @@ class GroupsServerHandler(object):
         yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
         is_invited = yield self.store.is_user_invited_to_local_group(
-            group_id, requester_user_id,
+            group_id, requester_user_id
         )
         if not is_invited:
             raise SynapseError(403, "User not invited to group")
 
         local_attestation = yield self._add_user(group_id, requester_user_id, content)
 
-        defer.returnValue({
-            "state": "join",
-            "attestation": local_attestation,
-        })
+        defer.returnValue({"state": "join", "attestation": local_attestation})
 
     @defer.inlineCallbacks
     def join_group(self, group_id, requester_user_id, content):
@@ -753,15 +711,12 @@ class GroupsServerHandler(object):
         group_info = yield self.check_group_is_ours(
             group_id, requester_user_id, and_exists=True
         )
-        if group_info['join_policy'] != "open":
+        if group_info["join_policy"] != "open":
             raise SynapseError(403, "Group is not publicly joinable")
 
         local_attestation = yield self._add_user(group_id, requester_user_id, content)
 
-        defer.returnValue({
-            "state": "join",
-            "attestation": local_attestation,
-        })
+        defer.returnValue({"state": "join", "attestation": local_attestation})
 
     @defer.inlineCallbacks
     def knock(self, group_id, requester_user_id, content):
@@ -800,9 +755,7 @@ class GroupsServerHandler(object):
 
             is_kick = True
 
-        yield self.store.remove_user_from_group(
-            group_id, user_id,
-        )
+        yield self.store.remove_user_from_group(group_id, user_id)
 
         if is_kick:
             if self.hs.is_mine_id(user_id):
@@ -830,19 +783,20 @@ class GroupsServerHandler(object):
         if group:
             raise SynapseError(400, "Group already exists")
 
-        is_admin = yield self.auth.is_server_admin(UserID.from_string(requester_user_id))
+        is_admin = yield self.auth.is_server_admin(
+            UserID.from_string(requester_user_id)
+        )
         if not is_admin:
             if not self.hs.config.enable_group_creation:
                 raise SynapseError(
-                    403, "Only a server admin can create groups on this server",
+                    403, "Only a server admin can create groups on this server"
                 )
             localpart = group_id_obj.localpart
             if not localpart.startswith(self.hs.config.group_creation_prefix):
                 raise SynapseError(
                     400,
-                    "Can only create groups with prefix %r on this server" % (
-                        self.hs.config.group_creation_prefix,
-                    ),
+                    "Can only create groups with prefix %r on this server"
+                    % (self.hs.config.group_creation_prefix,),
                 )
 
         profile = content.get("profile", {})
@@ -865,21 +819,19 @@ class GroupsServerHandler(object):
             remote_attestation = content["attestation"]
 
             yield self.attestations.verify_attestation(
-                remote_attestation,
-                user_id=requester_user_id,
-                group_id=group_id,
+                remote_attestation, user_id=requester_user_id, group_id=group_id
             )
 
             local_attestation = self.attestations.create_attestation(
-                group_id,
-                requester_user_id,
+                group_id, requester_user_id
             )
         else:
             local_attestation = None
             remote_attestation = None
 
         yield self.store.add_user_to_group(
-            group_id, requester_user_id,
+            group_id,
+            requester_user_id,
             is_admin=True,
             is_public=True,  # TODO
             local_attestation=local_attestation,
@@ -893,9 +845,7 @@ class GroupsServerHandler(object):
                 avatar_url=user_profile.get("avatar_url"),
             )
 
-        defer.returnValue({
-            "group_id": group_id,
-        })
+        defer.returnValue({"group_id": group_id})
 
     @defer.inlineCallbacks
     def delete_group(self, group_id, requester_user_id):
@@ -911,29 +861,22 @@ class GroupsServerHandler(object):
             Deferred
         """
 
-        yield self.check_group_is_ours(
-            group_id, requester_user_id,
-            and_exists=True,
-        )
+        yield self.check_group_is_ours(group_id, requester_user_id, and_exists=True)
 
         # Only server admins or group admins can delete groups.
 
-        is_admin = yield self.store.is_user_admin_in_group(
-            group_id, requester_user_id
-        )
+        is_admin = yield self.store.is_user_admin_in_group(group_id, requester_user_id)
 
         if not is_admin:
             is_admin = yield self.auth.is_server_admin(
-                UserID.from_string(requester_user_id),
+                UserID.from_string(requester_user_id)
             )
 
         if not is_admin:
             raise SynapseError(403, "User is not an admin")
 
         # Before deleting the group lets kick everyone out of it
-        users = yield self.store.get_users_in_group(
-            group_id, include_private=True,
-        )
+        users = yield self.store.get_users_in_group(group_id, include_private=True)
 
         @defer.inlineCallbacks
         def _kick_user_from_group(user_id):
@@ -989,9 +932,7 @@ def _parse_join_policy_dict(join_policy_dict):
         return "invite"
 
     if join_policy_type not in ("invite", "open"):
-        raise SynapseError(
-            400, "Synapse only supports 'invite'/'open' join rule"
-        )
+        raise SynapseError(400, "Synapse only supports 'invite'/'open' join rule")
     return join_policy_type
 
 
@@ -1018,7 +959,5 @@ def _parse_visibility_dict(visibility):
         return True
 
     if vis_type not in ("public", "private"):
-        raise SynapseError(
-            400, "Synapse only supports 'public'/'private' visibility"
-        )
+        raise SynapseError(400, "Synapse only supports 'public'/'private' visibility")
     return vis_type == "public"