def test_validate(self): bad_ids = ["$badsigil:domain", "+:empty" ] + ["+group" + c + ":domain" for c in "A%?æ£"] for id_string in bad_ids: try: GroupID.from_string(id_string) self.fail("Parsing '%s' should raise exception" % id_string) except SynapseError as exc: self.assertEqual(400, exc.code) self.assertEqual("M_INVALID_PARAM", exc.errcode)
def test_validate(self): bad_ids = ["$badsigil:domain", "+:empty"] + [ "+group" + c + ":domain" for c in "A%?æ£" ] for id_string in bad_ids: try: GroupID.from_string(id_string) self.fail("Parsing '%s' should raise exception" % id_string) except SynapseError as exc: self.assertEqual(400, exc.code) self.assertEqual("M_UNKNOWN", exc.errcode)
def _check_namespaces(self, namespaces): # Sanity check that it is of the form: # { # users: [ {regex: "[A-z]+.*", exclusive: true}, ...], # aliases: [ {regex: "[A-z]+.*", exclusive: true}, ...], # rooms: [ {regex: "[A-z]+.*", exclusive: true}, ...], # } if not namespaces: namespaces = {} for ns in ApplicationService.NS_LIST: if ns not in namespaces: namespaces[ns] = [] continue if type(namespaces[ns]) != list: raise ValueError("Bad namespace value for '%s'" % ns) for regex_obj in namespaces[ns]: if not isinstance(regex_obj, dict): raise ValueError("Expected dict regex for ns '%s'" % ns) if not isinstance(regex_obj.get("exclusive"), bool): raise ValueError( "Expected bool for 'exclusive' in ns '%s'" % ns ) group_id = regex_obj.get("group_id") if group_id: if not isinstance(group_id, str): raise ValueError( "Expected string for 'group_id' in ns '%s'" % ns ) try: GroupID.from_string(group_id) except Exception: raise ValueError( "Expected valid group ID for 'group_id' in ns '%s'" % ns ) if get_domain_from_id(group_id) != self.server_name: raise ValueError( "Expected 'group_id' to be this host in ns '%s'" % ns ) regex = regex_obj.get("regex") if isinstance(regex, string_types): regex_obj["regex"] = re.compile(regex) # Pre-compile regex else: raise ValueError( "Expected string for 'regex' in ns '%s'" % ns ) return namespaces
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
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)
async def f(self: "GroupsLocalWorkerHandler", group_id: str, *args: Any, **kwargs: Any) -> JsonDict: if not GroupID.is_valid(group_id): raise SynapseError(400, "%s is not a legal group ID" % (group_id, )) if self.is_mine_id(group_id): return await getattr(self.groups_server_handler, func_name)(group_id, *args, **kwargs) else: destination = get_domain_from_id(group_id) try: return await getattr(self.transport_client, func_name)(destination, group_id, *args, **kwargs) except HttpResponseException as e: # Capture errors returned by the remote homeserver and # re-throw specific errors as SynapseErrors. This is so # when the remote end responds with things like 403 Not # In Group, we can communicate that to the client instead # of a 500. raise e.to_synapse_error() except RequestSendFailed: raise SynapseError(502, "Failed to contact group server")
async def on_GET(self, request, group_id): requester = await self.auth.get_user_by_req(request, allow_guest=True) requester_user_id = requester.user.to_string() if not GroupID.is_valid(group_id): raise SynapseError(400, "%s was not legal group ID" % (group_id, )) result = await self.groups_handler.get_rooms_in_group( group_id, requester_user_id) return 200, result
async def on_POST(self, request): 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() result = await self.groups_handler.create_group( group_id, requester_user_id, content) return 200, result
def _validate_group_id(group_id): """Validates the group ID is valid for creation on this home server """ localpart = GroupID.from_string(group_id).localpart if localpart.lower() != localpart: raise SynapseError(400, "Group ID must be lower case") if urllib.quote(localpart.encode('utf-8')) != localpart: raise SynapseError( 400, "Group ID can only contain characters a-z, 0-9, or '_-./'", )
def create_group(self, group_id, requester_user_id, content): group = yield self.check_group_is_ours(group_id, requester_user_id) logger.info("Attempting to create group with ID: %r", group_id) # parsing the id into a GroupID validates it. group_id_obj = GroupID.from_string(group_id) if group: raise SynapseError(400, "Group already exists") 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", ) 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, ), ) profile = content.get("profile", {}) name = profile.get("name") avatar_url = profile.get("avatar_url") short_description = profile.get("short_description") long_description = profile.get("long_description") user_profile = content.get("user_profile", {}) yield self.store.create_group( group_id, requester_user_id, name=name, avatar_url=avatar_url, short_description=short_description, long_description=long_description, ) if not self.hs.is_mine_id(requester_user_id): remote_attestation = content["attestation"] yield self.attestations.verify_attestation( remote_attestation, user_id=requester_user_id, group_id=group_id, ) local_attestation = self.attestations.create_attestation( group_id, requester_user_id, ) else: local_attestation = None remote_attestation = None yield self.store.add_user_to_group( group_id, requester_user_id, is_admin=True, is_public=True, # TODO local_attestation=local_attestation, remote_attestation=remote_attestation, ) if not self.hs.is_mine_id(requester_user_id): yield self.store.add_remote_profile_cache( requester_user_id, displayname=user_profile.get("displayname"), avatar_url=user_profile.get("avatar_url"), ) defer.returnValue({ "group_id": group_id, })
def test_parse(self): group_id = GroupID.from_string("+group/=_-.123:my.domain") self.assertEqual("group/=_-.123", group_id.localpart) self.assertEqual("my.domain", group_id.domain)
async def create_group( self, group_id: str, requester_user_id: str, content: JsonDict ) -> JsonDict: logger.info("Attempting to create group with ID: %r", group_id) # parsing the id into a GroupID validates it. group_id_obj = GroupID.from_string(group_id) group = await self.check_group_is_ours(group_id, requester_user_id) if group: raise SynapseError(400, "Group already exists") is_admin = await 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" ) 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,), ) profile = content.get("profile", {}) name = profile.get("name") avatar_url = profile.get("avatar_url") short_description = profile.get("short_description") long_description = profile.get("long_description") user_profile = content.get("user_profile", {}) await self.store.create_group( group_id, requester_user_id, name=name, avatar_url=avatar_url, short_description=short_description, long_description=long_description, ) if not self.hs.is_mine_id(requester_user_id): remote_attestation = content["attestation"] await self.attestations.verify_attestation( remote_attestation, user_id=requester_user_id, group_id=group_id ) local_attestation = self.attestations.create_attestation( group_id, requester_user_id ) # type: Optional[JsonDict] else: local_attestation = None remote_attestation = None await self.store.add_user_to_group( group_id, requester_user_id, is_admin=True, is_public=True, # TODO local_attestation=local_attestation, remote_attestation=remote_attestation, ) if not self.hs.is_mine_id(requester_user_id): await self.store.add_remote_profile_cache( requester_user_id, displayname=user_profile.get("displayname"), avatar_url=user_profile.get("avatar_url"), ) return {"group_id": group_id}
def wrapper(self, request: Request, group_id: str, *args, **kwargs): 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)
def create_group(self, group_id, user_id, content): group = yield self.check_group_is_ours(group_id) _validate_group_id(group_id) logger.info("Attempting to create group with ID: %r", group_id) if group: raise SynapseError(400, "Group already exists") is_admin = yield self.auth.is_server_admin(UserID.from_string(user_id)) if not is_admin: if not self.hs.config.enable_group_creation: raise SynapseError( 403, "Only server admin can create group on this server", ) localpart = GroupID.from_string(group_id).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, ), ) profile = content.get("profile", {}) name = profile.get("name") avatar_url = profile.get("avatar_url") short_description = profile.get("short_description") long_description = profile.get("long_description") user_profile = content.get("user_profile", {}) yield self.store.create_group( group_id, user_id, name=name, avatar_url=avatar_url, short_description=short_description, long_description=long_description, ) if not self.hs.is_mine_id(user_id): remote_attestation = content["attestation"] yield self.attestations.verify_attestation( remote_attestation, user_id=user_id, group_id=group_id, ) local_attestation = self.attestations.create_attestation( group_id, user_id) else: local_attestation = None remote_attestation = None yield self.store.add_user_to_group( group_id, user_id, is_admin=True, is_public=True, # TODO local_attestation=local_attestation, remote_attestation=remote_attestation, ) if not self.hs.is_mine_id(user_id): yield self.store.add_remote_profile_cache( user_id, displayname=user_profile.get("displayname"), avatar_url=user_profile.get("avatar_url"), ) defer.returnValue({ "group_id": group_id, })