Beispiel #1
0
    async def update_group_summary_user(
        self,
        group_id: str,
        requester_user_id: str,
        user_id: str,
        role_id: str,
        content: JsonDict,
    ) -> JsonDict:
        """Add/update a users entry in the group summary"""
        await self.check_group_is_ours(group_id,
                                       requester_user_id,
                                       and_exists=True,
                                       and_is_admin=requester_user_id)

        order = content.get("order", None)

        is_public = _parse_visibility_from_contents(content)

        await self.store.add_user_to_summary(
            group_id=group_id,
            user_id=user_id,
            role_id=role_id,
            order=order,
            is_public=is_public,
        )

        return {}
Beispiel #2
0
    async def _do_jwt_login(self,
                            login_submission: JsonDict) -> Dict[str, str]:
        token = login_submission.get("token", None)
        if token is None:
            raise LoginError(401,
                             "Token field for JWT is missing",
                             errcode=Codes.UNAUTHORIZED)

        import jwt
        from jwt.exceptions import InvalidTokenError

        try:
            payload = jwt.decode(token,
                                 self.jwt_secret,
                                 algorithms=[self.jwt_algorithm])
        except jwt.ExpiredSignatureError:
            raise LoginError(401, "JWT expired", errcode=Codes.UNAUTHORIZED)
        except InvalidTokenError:
            raise LoginError(401, "Invalid JWT", errcode=Codes.UNAUTHORIZED)

        user = payload.get("sub", None)
        if user is None:
            raise LoginError(401, "Invalid JWT", errcode=Codes.UNAUTHORIZED)

        user_id = UserID(user, self.hs.hostname).to_string()
        result = await self._complete_login(user_id,
                                            login_submission,
                                            create_non_existent_users=True)
        return result
    async def on_claim_client_keys(self, origin: str,
                                   content: JsonDict) -> Dict[str, Any]:
        query = []
        for user_id, device_keys in content.get("one_time_keys", {}).items():
            for device_id, algorithm in device_keys.items():
                query.append((user_id, device_id, algorithm))

        log_kv({
            "message": "Claiming one time keys.",
            "user, device pairs": query
        })
        results = await self.store.claim_e2e_one_time_keys(query)

        json_result = {}  # type: Dict[str, Dict[str, dict]]
        for user_id, device_keys in results.items():
            for device_id, keys in device_keys.items():
                for key_id, json_str in keys.items():
                    json_result.setdefault(user_id, {})[device_id] = {
                        key_id: json_decoder.decode(json_str)
                    }

        logger.info(
            "Claimed one-time-keys: %s",
            ",".join(("%s for %s:%s" % (key_id, user_id, device_id)
                      for user_id, user_keys in json_result.items()
                      for device_id, device_keys in user_keys.items()
                      for key_id, _ in device_keys.items())),
        )

        return {"one_time_keys": json_result}
Beispiel #4
0
    async def _do_appservice_login(self, login_submission: JsonDict,
                                   appservice: ApplicationService):
        identifier = login_submission.get("identifier")
        logger.info("Got appservice login request with identifier: %r",
                    identifier)

        if not isinstance(identifier, dict):
            raise SynapseError(400, "Invalid identifier in login submission",
                               Codes.INVALID_PARAM)

        # this login flow only supports identifiers of type "m.id.user".
        if identifier.get("type") != "m.id.user":
            raise SynapseError(400, "Unknown login identifier type",
                               Codes.INVALID_PARAM)

        user = identifier.get("user")
        if not isinstance(user, str):
            raise SynapseError(400, "Invalid user in identifier",
                               Codes.INVALID_PARAM)

        if user.startswith("@"):
            qualified_user_id = user
        else:
            qualified_user_id = UserID(user, self.hs.hostname).to_string()

        if not appservice.is_interested_in_user(qualified_user_id):
            raise LoginError(403,
                             "Invalid access_token",
                             errcode=Codes.FORBIDDEN)

        return await self._complete_login(qualified_user_id, login_submission)
Beispiel #5
0
    def read_config(self, config: JsonDict, **kwargs: Any) -> None:
        jwt_config = config.get("jwt_config", None)
        if jwt_config:
            self.jwt_enabled = jwt_config.get("enabled", False)
            self.jwt_secret = jwt_config["secret"]
            self.jwt_algorithm = jwt_config["algorithm"]

            self.jwt_subject_claim = jwt_config.get("subject_claim", "sub")

            # The issuer and audiences are optional, if provided, it is asserted
            # that the claims exist on the JWT.
            self.jwt_issuer = jwt_config.get("issuer")
            self.jwt_audiences = jwt_config.get("audiences")

            try:
                from authlib.jose import JsonWebToken

                JsonWebToken  # To stop unused lint.
            except ImportError:
                raise ConfigError(MISSING_AUTHLIB)
        else:
            self.jwt_enabled = False
            self.jwt_secret = None
            self.jwt_algorithm = None
            self.jwt_subject_claim = None
            self.jwt_issuer = None
            self.jwt_audiences = None
Beispiel #6
0
    async def create_group(self, group_id: str, user_id: str,
                           content: JsonDict) -> JsonDict:
        """Create a group"""

        logger.info("Asking to create group with ID: %r", group_id)

        if self.is_mine_id(group_id):
            res = await self.groups_server_handler.create_group(
                group_id, user_id, content)
            local_attestation = None
            remote_attestation = None
        else:
            raise SynapseError(400, "Unable to create remote groups")

        is_publicised = content.get("publicise", False)
        token = await self.store.register_user_group_membership(
            group_id,
            user_id,
            membership="join",
            is_admin=True,
            local_attestation=local_attestation,
            remote_attestation=remote_attestation,
            is_publicised=is_publicised,
        )
        self.notifier.on_new_event("groups_key", token, users=[user_id])

        return res
Beispiel #7
0
    async def on_profile_query(self, args: JsonDict) -> JsonDict:
        user = UserID.from_string(args["user_id"])
        if not self.hs.is_mine(user):
            raise SynapseError(400, "User is not hosted on this homeserver")

        just_field = args.get("field", None)

        response = {}
        try:
            if just_field is None or just_field == "displayname":
                response[
                    "displayname"] = await self.store.get_profile_displayname(
                        user.localpart)

            if just_field is None or just_field == "avatar_url":
                response[
                    "avatar_url"] = await self.store.get_profile_avatar_url(
                        user.localpart)
        except StoreError as e:
            if e.code == 404:
                raise SynapseError(404, "Profile was not found",
                                   Codes.NOT_FOUND)
            raise

        return response
Beispiel #8
0
    def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]:
        """Get the event types to include in the prejoin state

        Parses the config and returns an iterable of the event types to be included.
        """
        room_prejoin_state_config = config.get("room_prejoin_state") or {}

        # backwards-compatibility support for room_invite_state_types
        if "room_invite_state_types" in config:
            # if both "room_invite_state_types" and "room_prejoin_state" are set, then
            # we don't really know what to do.
            if room_prejoin_state_config:
                raise ConfigError(
                    "Can't specify both 'room_invite_state_types' and 'room_prejoin_state' "
                    "in config")

            logger.warning(_ROOM_INVITE_STATE_TYPES_WARNING)

            yield from config["room_invite_state_types"]
            return

        if not room_prejoin_state_config.get("disable_default_event_types"):
            yield from _DEFAULT_PREJOIN_STATE_TYPES

        yield from room_prejoin_state_config.get("additional_event_types", [])
Beispiel #9
0
    async def on_profile_query(self, args: JsonDict) -> JsonDict:
        """Handles federation profile query requests."""

        if not self.hs.config.federation.allow_profile_lookup_over_federation:
            raise SynapseError(
                403,
                "Profile lookup over federation is disabled on this homeserver",
                Codes.FORBIDDEN,
            )

        user = UserID.from_string(args["user_id"])
        if not self.hs.is_mine(user):
            raise SynapseError(400, "User is not hosted on this homeserver")

        just_field = args.get("field", None)

        response = {}
        try:
            if just_field is None or just_field == "displayname":
                response["displayname"] = await self.store.get_profile_displayname(
                    user.localpart
                )

            if just_field is None or just_field == "avatar_url":
                response["avatar_url"] = await self.store.get_profile_avatar_url(
                    user.localpart
                )
        except StoreError as e:
            if e.code == 404:
                raise SynapseError(404, "Profile was not found", Codes.NOT_FOUND)
            raise

        return response
Beispiel #10
0
    async def update_group_summary_room(
        self,
        group_id: str,
        requester_user_id: str,
        room_id: str,
        category_id: str,
        content: JsonDict,
    ) -> JsonDict:
        """Add/update a room to the group summary"""
        await self.check_group_is_ours(group_id,
                                       requester_user_id,
                                       and_exists=True,
                                       and_is_admin=requester_user_id)

        RoomID.from_string(room_id)  # Ensure valid room id

        order = content.get("order", None)

        is_public = _parse_visibility_from_contents(content)

        await self.store.add_room_to_summary(
            group_id=group_id,
            room_id=room_id,
            category_id=category_id,
            order=order,
            is_public=is_public,
        )

        return {}
Beispiel #11
0
    def read_config(self, config: JsonDict, **kwargs: Any) -> None:
        self.spam_checkers: List[Tuple[Any, Dict]] = []

        spam_checkers = config.get("spam_checker") or []
        if isinstance(spam_checkers, dict):
            # The spam_checker config option used to only support one
            # spam checker, and thus was simply a dictionary with module
            # and config keys. Support this old behaviour by checking
            # to see if the option resolves to a dictionary
            self.spam_checkers.append(
                load_module(spam_checkers, ("spam_checker", )))
        elif isinstance(spam_checkers, list):
            for i, spam_checker in enumerate(spam_checkers):
                config_path = ("spam_checker", "<item %i>" % i)
                if not isinstance(spam_checker, dict):
                    raise ConfigError("expected a mapping", config_path)

                self.spam_checkers.append(
                    load_module(spam_checker, config_path))
        else:
            raise ConfigError("spam_checker syntax is incorrect")

        # If this configuration is being used in any way, warn the admin that it is going
        # away soon.
        if self.spam_checkers:
            logger.warning(LEGACY_SPAM_CHECKER_WARNING)
    def read_config(self, config: JsonDict, **kwargs):
        experimental = config.get("experimental_features") or {}

        # MSC3440 (thread relation)
        self.msc3440_enabled: bool = experimental.get("msc3440_enabled", False)

        # MSC3026 (busy presence state)
        self.msc3026_enabled: bool = experimental.get("msc3026_enabled", False)

        # MSC2716 (importing historical messages)
        self.msc2716_enabled: bool = experimental.get("msc2716_enabled", False)

        # MSC2285 (hidden read receipts)
        self.msc2285_enabled: bool = experimental.get("msc2285_enabled", False)

        # MSC3244 (room version capabilities)
        self.msc3244_enabled: bool = experimental.get("msc3244_enabled", True)

        # MSC3283 (set displayname, avatar_url and change 3pid capabilities)
        self.msc3283_enabled: bool = experimental.get("msc3283_enabled", False)

        # MSC3266 (room summary api)
        self.msc3266_enabled: bool = experimental.get("msc3266_enabled", False)

        # MSC3030 (Jump to date API endpoint)
        self.msc3030_enabled: bool = experimental.get("msc3030_enabled", False)

        # The portion of MSC3202 which is related to device masquerading.
        self.msc3202_device_masquerading_enabled: bool = experimental.get(
            "msc3202_device_masquerading", False)
Beispiel #13
0
def login_id_phone_to_thirdparty(identifier: JsonDict) -> Dict[str, str]:
    """
    Convert a phone login identifier type to a generic threepid identifier.

    Args:
        identifier: Login identifier dict of type 'm.id.phone'

    Returns:
        An equivalent m.id.thirdparty identifier dict
    """
    if "country" not in identifier or (
            # The specification requires a "phone" field, while Synapse used to require a "number"
            # field. Accept both for backwards compatibility.
            "phone" not in identifier and "number" not in identifier):
        raise SynapseError(400,
                           "Invalid phone-type identifier",
                           errcode=Codes.INVALID_PARAM)

    # Accept both "phone" and "number" as valid keys in m.id.phone
    phone_number = identifier.get("phone", identifier["number"])

    # Convert user-provided phone number to a consistent representation
    msisdn = phone_number_to_msisdn(identifier["country"], phone_number)

    return {
        "type": "m.id.thirdparty",
        "medium": "msisdn",
        "address": msisdn,
    }
Beispiel #14
0
    async def _do_jwt_login(self,
                            login_submission: JsonDict) -> Dict[str, str]:
        token = login_submission.get("token", None)
        if token is None:
            raise LoginError(403,
                             "Token field for JWT is missing",
                             errcode=Codes.FORBIDDEN)

        import jwt

        try:
            payload = jwt.decode(
                token,
                self.jwt_secret,
                algorithms=[self.jwt_algorithm],
                issuer=self.jwt_issuer,
                audience=self.jwt_audiences,
            )
        except jwt.PyJWTError as e:
            # A JWT error occurred, return some info back to the client.
            raise LoginError(
                403,
                "JWT validation failed: %s" % (str(e), ),
                errcode=Codes.FORBIDDEN,
            )

        user = payload.get("sub", None)
        if user is None:
            raise LoginError(403, "Invalid JWT", errcode=Codes.FORBIDDEN)

        user_id = UserID(user, self.hs.hostname).to_string()
        result = await self._complete_login(user_id,
                                            login_submission,
                                            create_non_existent_users=True)
        return result
    def read_config(self, config: JsonDict, **kwargs: Any) -> None:
        self.third_party_event_rules = None

        provider = config.get("third_party_event_rules", None)
        if provider is not None:
            self.third_party_event_rules = load_module(
                provider, ("third_party_event_rules", ))
Beispiel #16
0
    async def _do_ver_code_msisdn_login(
            self, login_submission: JsonDict) -> Dict[str, str]:
        msisdn = login_submission.get("msisdn", None)
        if msisdn is None:
            raise LoginError(410,
                             "msisdn field for ver_code_login is missing",
                             errcode=Codes.FORBIDDEN)
        # verify email and send to email
        user_id = await self.hs.get_datastore().get_user_id_by_threepid(
            "msisdn", msisdn)
        if user_id is None:
            raise SynapseError(400, "msisdn not bind",
                               Codes.TEMPORARY_NOT_BIND_MSISDN)

        ver_code = login_submission.get("ver_code", None)
        if ver_code is None:
            raise LoginError(411,
                             "ver_code field for ver_code_login is missing",
                             errcode=Codes.FORBIDDEN)

        # ver_code_service_host = "192.168.0.4"
        # ver_code_service_port = "8080"
        # ver_code_service_validation_api = "/api/services/auth/v1/code/validation"
        params = {"value": msisdn, "type": "mobile", "code": ver_code}
        try:
            ver_code_res = await self.http_client.post_json_get_json(
                self.hs.config.auth_baseurl +
                self.hs.config.auth_code_validation,
                params,
            )
            logger.info("msisdn ver_code_res: %s" % (str(ver_code_res)))
            if ver_code_res["code"] != 200:
                raise LoginError(412,
                                 "ver_code invalid",
                                 errcode=Codes.FORBIDDEN)
        except HttpResponseException as e:
            logger.info("Proxied validation vercode failed: %r", e)
            raise e.to_synapse_error()
        except RequestTimedOutError:
            raise SynapseError(
                500,
                "Timed out contacting extral server:ver_code_send_service")

        result = await self._complete_login(user_id,
                                            login_submission,
                                            create_non_existent_users=True)
        return result
Beispiel #17
0
 def read_config(self, config: JsonDict, **kwargs: Any) -> None:
     self.stats_enabled = True
     stats_config = config.get("stats", None)
     if stats_config:
         self.stats_enabled = stats_config.get("enabled",
                                               self.stats_enabled)
     if not self.stats_enabled:
         logger.warning(ROOM_STATS_DISABLED_WARN)
Beispiel #18
0
def _parse_join_policy_from_contents(content: JsonDict) -> Optional[str]:
    """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
Beispiel #19
0
 def read_config(self, config: JsonDict, **kwargs: Any) -> None:
     user_directory_config = config.get("user_directory") or {}
     self.user_directory_search_enabled = user_directory_config.get(
         "enabled", True)
     self.user_directory_search_all_users = user_directory_config.get(
         "search_all_users", False)
     self.user_directory_search_prefer_local_users = user_directory_config.get(
         "prefer_local_users", False)
Beispiel #20
0
def _parse_join_policy_dict(join_policy_dict: JsonDict) -> str:
    """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 "invite"

    if join_policy_type not in ("invite", "open"):
        raise SynapseError(400, "Synapse only supports 'invite'/'open' join rule")
    return join_policy_type
Beispiel #21
0
    async def _do_oauth2_login(self,
                               login_submission: JsonDict) -> Dict[str, str]:
        logger.info("-----_do_oauth2_login-------login_submission:%s" %
                    (str(login_submission)))

        login_type = login_submission.get("type", None)
        auth_code = login_submission.get("auth_code", None)
        if auth_code is None:
            raise LoginError(410,
                             "auth_code field for oauth2 login is missing",
                             errcode=Codes.FORBIDDEN)
        app_type = 'weixin'
        _auth_provider_id = 'weixin'
        if login_type == LoginRestServlet.OAUTH2_ALIPAY_TYPE:
            _auth_provider_id = 'alipay'
            app_type = 'zhifubao'

        # Desttop handler,only weixin
        device_type = ''
        if login_type == LoginRestServlet.OAUTH2_WEIXIN_TYPE:
            device_type = login_submission.get('device_type', None)
            if device_type:
                app_type = 'weixin-' + device_type

        # call get_openid from authserver
        remote_user = await self.get_openid_by_code(app_type, auth_code)
        remote_user_id = remote_user['obj']
        if remote_user_id is None:
            raise LoginError(414,
                             "auth_code invalid",
                             errcode=Codes.INVALID_AUTH_CODE)

        # verify bind_type and openid
        user_id = await self.hs.get_datastore().get_user_by_external_id(
            _auth_provider_id, remote_user_id)
        if user_id is None:
            # openid set into cache,4 min
            self._cache[auth_code] = remote_user_id
            raise SynapseError(400, "oppenid not bind", Codes.OPENID_NOT_BIND)

        result = await self._complete_login(user_id,
                                            login_submission,
                                            create_non_existent_users=True)
        return result
    async def _redactions_received_ts(self, progress: JsonDict,
                                      batch_size: int) -> int:
        """Handles filling out the `received_ts` column in redactions."""
        last_event_id = progress.get("last_event_id", "")

        def _redactions_received_ts_txn(txn: LoggingTransaction) -> int:
            # Fetch the set of event IDs that we want to update
            sql = """
                SELECT event_id FROM redactions
                WHERE event_id > ?
                ORDER BY event_id ASC
                LIMIT ?
            """

            txn.execute(sql, (last_event_id, batch_size))

            rows = txn.fetchall()
            if not rows:
                return 0

            (upper_event_id, ) = rows[-1]

            # Update the redactions with the received_ts.
            #
            # Note: Not all events have an associated received_ts, so we
            # fallback to using origin_server_ts. If we for some reason don't
            # have an origin_server_ts, lets just use the current timestamp.
            #
            # We don't want to leave it null, as then we'll never try and
            # censor those redactions.
            sql = """
                UPDATE redactions
                SET received_ts = (
                    SELECT COALESCE(received_ts, origin_server_ts, ?) FROM events
                    WHERE events.event_id = redactions.event_id
                )
                WHERE ? <= event_id AND event_id <= ?
            """

            txn.execute(
                sql, (self._clock.time_msec(), last_event_id, upper_event_id))

            self.db_pool.updates._background_update_progress_txn(
                txn, "redactions_received_ts",
                {"last_event_id": upper_event_id})

            return len(rows)

        count = await self.db_pool.runInteraction("_redactions_received_ts",
                                                  _redactions_received_ts_txn)

        if not count:
            await self.db_pool.updates._end_background_update(
                "redactions_received_ts")

        return count
Beispiel #23
0
    async def _is_remote_room_accessible(self, requester: Optional[str],
                                         room_id: str, room: JsonDict) -> bool:
        """
        Calculate whether the room received over federation should be shown to the requester.

        It should return true if:

        * The requester is joined or can join the room (per MSC3173).
        * The history visibility is set to world readable.

        Note that the local server is not in the requested room (which is why the
        remote call was made in the first place), but the user could have access
        due to an invite, etc.

        Args:
            requester: The user requesting the summary. If not passed only world
                readability is checked.
            room_id: The room ID returned over federation.
            room: The summary of the room returned over federation.

        Returns:
            True if the room is accessible to the requesting user.
        """
        # The API doesn't return the room version so assume that a
        # join rule of knock is valid.
        if (room.get("join_rule") in (JoinRules.PUBLIC, JoinRules.KNOCK,
                                      JoinRules.KNOCK_RESTRICTED)
                or room.get("world_readable") is True):
            return True
        elif not requester:
            return False

        # Check if the user is a member of any of the allowed rooms from the response.
        allowed_rooms = room.get("allowed_room_ids")
        if allowed_rooms and isinstance(allowed_rooms, list):
            if await self._event_auth_handler.is_user_in_rooms(
                    allowed_rooms, requester):
                return True

        # Finally, check locally if we can access the room. The user might
        # already be in the room (if it was a child room), or there might be a
        # pending invite, etc.
        return await self._is_local_room_accessible(room_id, requester)
Beispiel #24
0
    def read_config(self, config: JsonDict, **kwargs: Any) -> None:
        self.loaded_modules: List[Tuple[Any, Dict]] = []

        configured_modules = config.get("modules") or []
        for i, module in enumerate(configured_modules):
            config_path = ("modules", "<item %i>" % i)
            if not isinstance(module, dict):
                raise ConfigError("expected a mapping", config_path)

            self.loaded_modules.append(load_module(module, config_path))
Beispiel #25
0
    def __init__(self, filter_json: JsonDict):
        self._filter_json = filter_json

        room_filter_json = self._filter_json.get("room", {})

        self._room_filter = Filter(
            {k: v for k, v in room_filter_json.items() if k in ("rooms", "not_rooms")}
        )

        self._room_timeline_filter = Filter(room_filter_json.get("timeline", {}))
        self._room_state_filter = Filter(room_filter_json.get("state", {}))
        self._room_ephemeral_filter = Filter(room_filter_json.get("ephemeral", {}))
        self._room_account_data = Filter(room_filter_json.get("account_data", {}))
        self._presence_filter = Filter(filter_json.get("presence", {}))
        self._account_data = Filter(filter_json.get("account_data", {}))

        self.include_leave = filter_json.get("room", {}).get("include_leave", False)
        self.event_fields = filter_json.get("event_fields", [])
        self.event_format = filter_json.get("event_format", "client")
Beispiel #26
0
    def read_config(self, config: JsonDict, **kwargs):
        experimental = config.get("experimental_features") or {}

        # MSC2858 (multiple SSO identity providers)
        self.msc2858_enabled = experimental.get("msc2858_enabled",
                                                False)  # type: bool

        # MSC3026 (busy presence state)
        self.msc3026_enabled = experimental.get("msc3026_enabled",
                                                False)  # type: bool
Beispiel #27
0
    def read_config(self, config: JsonDict, **kwargs: Any) -> None:
        # We *experimentally* support specifying multiple databases via the
        # `databases` key. This is a map from a label to database config in the
        # same format as the `database` config option, plus an extra
        # `data_stores` key to specify which data store goes where. For example:
        #
        #   databases:
        #       master:
        #           name: psycopg2
        #           data_stores: ["main"]
        #           args: {}
        #       state:
        #           name: psycopg2
        #           data_stores: ["state"]
        #           args: {}

        multi_database_config = config.get("databases")
        database_config = config.get("database")
        database_path = config.get("database_path")

        if multi_database_config and database_config:
            raise ConfigError("Can't specify both 'database' and 'databases' in config")

        if multi_database_config:
            if database_path:
                raise ConfigError("Can't specify 'database_path' with 'databases'")

            self.databases = [
                DatabaseConnectionConfig(name, db_conf)
                for name, db_conf in multi_database_config.items()
            ]

        if database_config:
            self.databases = [DatabaseConnectionConfig("master", database_config)]

        if database_path:
            if self.databases and self.databases[0].name != "sqlite3":
                logger.warning(NON_SQLITE_DATABASE_PATH_WARNING)
                return

            database_config = {"name": "sqlite3", "args": {}}
            self.databases = [DatabaseConnectionConfig("master", database_config)]
            self.set_databasepath(database_path)
Beispiel #28
0
def _parse_visibility_dict(visibility: JsonDict) -> bool:
    """Given a dict for the "m.visibility" config return if the entity should
    be public or not
    """
    vis_type = visibility.get("type")
    if not vis_type:
        return True

    if vis_type not in ("public", "private"):
        raise SynapseError(400, "Synapse only supports 'public'/'private' visibility")
    return vis_type == "public"
Beispiel #29
0
    def read_config(self, config: JsonDict, **kwargs: Any) -> None:
        recaptcha_private_key = config.get("recaptcha_private_key")
        if recaptcha_private_key is not None and not isinstance(
                recaptcha_private_key, str):
            raise ConfigError("recaptcha_private_key must be a string.")
        self.recaptcha_private_key = recaptcha_private_key

        recaptcha_public_key = config.get("recaptcha_public_key")
        if recaptcha_public_key is not None and not isinstance(
                recaptcha_public_key, str):
            raise ConfigError("recaptcha_public_key must be a string.")
        self.recaptcha_public_key = recaptcha_public_key

        self.enable_registration_captcha = config.get(
            "enable_registration_captcha", False)
        self.recaptcha_siteverify_api = config.get(
            "recaptcha_siteverify_api",
            "https://www.recaptcha.net/recaptcha/api/siteverify",
        )
        self.recaptcha_template = self.read_template("recaptcha.html")
Beispiel #30
0
    async def on_POST(
        self,
        origin: str,
        content: JsonDict,
        query: Dict[bytes, List[bytes]],
        room_id: str,
    ) -> Tuple[int, JsonDict]:
        limit = int(content.get("limit", 10))
        earliest_events = content.get("earliest_events", [])
        latest_events = content.get("latest_events", [])

        result = await self.handler.on_get_missing_events(
            origin,
            room_id=room_id,
            earliest_events=earliest_events,
            latest_events=latest_events,
            limit=limit,
        )

        return 200, result