Exemple #1
0
    def _connect(self, server_name: str, server_url: str) -> Optional[Tuple[str, GMatrixHttpApi]]:
        log.debug("Connecting", server=server_name)
        api = GMatrixHttpApi(server_url)
        username = self._username
        password = self._password

        if server_name != self._own_server_name:
            signer = make_signer()
            username = str(to_normalized_address(signer.address))
            password = encode_hex(signer.sign(server_name.encode()))

        try:
            response = api.login(
                "m.login.password", user=username, password=password, device_id="room_ensurer"
            )
            api.token = response["access_token"]
        except MatrixHttpLibError:
            log.warning("Could not connect to server", server_url=server_url)
            return None
        except MatrixRequestError:
            log.warning("Failed to login to server", server_url=server_url)
            return None

        log.debug("Connected", server=server_name)
        return server_name, api
Exemple #2
0
 def _connect(self, server_name: str, server_url: str) -> Tuple[str, GMatrixHttpApi]:
     log.debug("Connecting", server=server_name)
     api = GMatrixHttpApi(server_url)
     response = api.login("m.login.password", user=self._username, password=self._password)
     api.token = response["access_token"]
     log.debug("Connected", server=server_name)
     return server_name, api
Exemple #3
0
def matrix_api_shell(address, password, server):
    am = AccountManager(os.path.expanduser("~/.ethereum/keystore"))
    signer = LocalSigner(am.get_privkey(to_checksum_address(address),
                                        password))
    server_name = server.split("//")[1]
    matrix_password = encode_hex(signer.sign(server_name.encode()))

    api = GMatrixHttpApi(server)
    resp = api.login("m.login.password",
                     user=to_normalized_address(address),
                     password=matrix_password)
    api.token = resp["access_token"]
    IPython.embed(
        header=f"Use the `api` object to interact with matrix on {server}.")
Exemple #4
0
    def _connect(self, server_name: str, server_url: str) -> Tuple[str, GMatrixHttpApi]:
        log.debug("Connecting", server=server_name)
        api = GMatrixHttpApi(server_url)
        username = self._username
        password = self._password

        if server_name != self._own_server_name:
            signer = make_signer()
            username = str(to_normalized_address(signer.address))
            password = encode_hex(signer.sign(server_name.encode()))

        response = api.login("m.login.password", user=username, password=password)
        api.token = response["access_token"]
        log.debug("Connected", server=server_name)
        return server_name, api
def purge(
    server: str,
    credentials_file: TextIO,
    docker_restart_label: Optional[str],
    url_known_federation_servers: str,
) -> None:
    """ Purge inactive users from broadcast rooms

    SERVER: matrix synapse server url, e.g.: http://hostname

    All option can be passed through uppercase environment variables prefixed with 'MATRIX_'
    """

    try:
        credentials = json.loads(credentials_file.read())
        username = credentials["username"]
        password = credentials["password"]
    except (JSONDecodeError, UnicodeDecodeError, OSError, KeyError) as ex:
        click.secho(f"Invalid credentials file: {ex}", fg="red")
        sys.exit(1)

    api = GMatrixHttpApi(server)
    try:
        response = api.login("m.login.password",
                             user=username,
                             password=password,
                             device_id="purger")
        api.token = response["access_token"]
    except (MatrixError, KeyError) as ex:
        click.secho(f"Could not log in to server {server}: {ex}")
        sys.exit(1)

    try:
        global_user_activity: UserActivityInfo = {
            "last_update": int(time.time()) - USER_PURGING_THRESHOLD - 1,
            "network_to_users": {},
        }

        try:
            global_user_activity = json.loads(USER_ACTIVITY_PATH.read_text())
        except JSONDecodeError:
            click.secho(
                f"{USER_ACTIVITY_PATH} is not a valid JSON. Starting with empty list"
            )
        except FileNotFoundError:
            click.secho(
                f"{USER_ACTIVITY_PATH} not found. Starting with empty list")

        # check if there are new networks to add
        for network in Networks:
            if str(network.value) in global_user_activity["network_to_users"]:
                continue
            global_user_activity["network_to_users"][str(
                network.value)] = dict()

        new_global_user_activity = run_user_purger(api, global_user_activity)

        # write the updated user activity to file
        USER_ACTIVITY_PATH.write_text(
            json.dumps(cast(Dict[str, Any], new_global_user_activity)))
    finally:
        if docker_restart_label:
            if not url_known_federation_servers:
                # In case an empty env var is set
                url_known_federation_servers = DEFAULT_MATRIX_KNOWN_SERVERS[
                    Environment.PRODUCTION]
            # fetch remote whiltelist
            try:
                remote_whitelist = json.loads(
                    requests.get(
                        url_known_federation_servers).text)["all_servers"]
            except (requests.RequestException, JSONDecodeError,
                    KeyError) as ex:
                click.secho(
                    f"Error while fetching whitelist: {ex!r}. "
                    f"Ignoring, containers will be restarted.",
                    err=True,
                )
                # An empty whitelist will cause the container to be restarted
                remote_whitelist = []

            client = docker.from_env()  # pylint: disable=no-member
            for container in client.containers.list():
                if container.attrs["State"][
                        "Status"] != "running" or not container.attrs[
                            "Config"]["Labels"].get(docker_restart_label):
                    continue

                try:
                    # fetch local list from container's synapse config
                    local_whitelist = yaml.safe_load(
                        container.exec_run([
                            "cat", SYNAPSE_CONFIG_PATH
                        ]).output)["federation_domain_whitelist"]

                    # if list didn't change, don't proceed to restart container
                    if local_whitelist and remote_whitelist == local_whitelist:
                        continue

                    click.secho(
                        f"Whitelist changed. Restarting. new_list={remote_whitelist!r}"
                    )
                except (KeyError, IndexError) as ex:
                    click.secho(
                        f"Error fetching container status: {ex!r}. Restarting anyway.",
                        err=True,
                    )
                # restart container
                container.restart(timeout=30)