From b808119a73861e171a067c203bdb39cd7cbb7e52 Mon Sep 17 00:00:00 2001 From: Jason Robinson <mail@jasonrobinson.me> Date: Tue, 15 Dec 2020 00:38:47 +0200 Subject: [PATCH] Enable logging in using an access token (#21) We do a `client.load_store()` to restore a previous session. If both token and password are defined, token is preferred, since it wont create a new device for the bot. One or the other needs to be defined. Requires https://github.com/anoadragon453/nio-template/pull/20 for the configuration change since password and access token must both be optional (but one must be given). --- my_project_name/config.py | 6 ++++- my_project_name/main.py | 50 ++++++++++++++++++++++++--------------- sample.config.yaml | 4 +++- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/my_project_name/config.py b/my_project_name/config.py index c7d44a0..ff8104c 100644 --- a/my_project_name/config.py +++ b/my_project_name/config.py @@ -85,7 +85,11 @@ class Config(object): if not re.match("@.*:.*", self.user_id): raise ConfigError("matrix.user_id must be in the form @name:domain") - self.user_password = self._get_cfg(["matrix", "user_password"], required=True) + self.user_password = self._get_cfg(["matrix", "user_password"], required=False) + self.user_token = self._get_cfg(["matrix", "user_token"], required=False) + if not self.user_token and not self.user_password: + raise ConfigError("Must supply either user token or password") + self.device_id = self._get_cfg(["matrix", "device_id"], required=True) self.device_name = self._get_cfg( ["matrix", "device_name"], default="nio-template" diff --git a/my_project_name/main.py b/my_project_name/main.py index bcb9ddd..f3173ef 100644 --- a/my_project_name/main.py +++ b/my_project_name/main.py @@ -51,6 +51,10 @@ async def main(): config=client_config, ) + if config.user_token: + client.access_token = config.user_token + client.user_id = config.user_id + # Set up event callbacks callbacks = Callbacks(client, store, config) client.add_event_callback(callbacks.message, (RoomMessageText,)) @@ -59,28 +63,36 @@ async def main(): # Keep trying to reconnect on failure (with some time in-between) while True: try: - # Try to login with the configured username/password - try: - login_response = await client.login( - password=config.user_password, device_name=config.device_name, - ) + if config.user_token: + # Use token to log in + client.load_store() - # Check if login failed - if type(login_response) == LoginError: - logger.error("Failed to login: %s", login_response.message) + # Sync encryption keys with the server + if client.should_upload_keys: + await client.keys_upload() + else: + # Try to login with the configured username/password + try: + login_response = await client.login( + password=config.user_password, device_name=config.device_name, + ) + + # Check if login failed + if type(login_response) == LoginError: + logger.error("Failed to login: %s", login_response.message) + return False + except LocalProtocolError as e: + # There's an edge case here where the user hasn't installed the correct C + # dependencies. In that case, a LocalProtocolError is raised on login. + logger.fatal( + "Failed to login. Have you installed the correct dependencies? " + "https://github.com/poljar/matrix-nio#installation " + "Error: %s", + e, + ) return False - except LocalProtocolError as e: - # There's an edge case here where the user hasn't installed the correct C - # dependencies. In that case, a LocalProtocolError is raised on login. - logger.fatal( - "Failed to login. Have you installed the correct dependencies? " - "https://github.com/poljar/matrix-nio#installation " - "Error: %s", - e, - ) - return False - # Login succeeded! + # Login succeeded! logger.info(f"Logged in as {config.user_id}") await client.sync_forever(timeout=30000, full_state=True) diff --git a/sample.config.yaml b/sample.config.yaml index 969b3a5..d33538e 100644 --- a/sample.config.yaml +++ b/sample.config.yaml @@ -9,8 +9,10 @@ command_prefix: "!c" matrix: # The Matrix User ID of the bot account user_id: "@bot:example.com" - # Matrix account password + # Matrix account password (optional if access token used) user_password: "" + # Matrix account access token (optional if password used) + #user_token: "" # The URL of the homeserver to connect to homeserver_url: https://example.com # The device ID that is **non pre-existing** device