diff --git a/diaspora_auth_provider.py b/diaspora_auth_provider.py index ab72fe7b49babae76bf920354842df67a04f7796..151b953d37e578f4b1d97febab60a0231bb4746a 100644 --- a/diaspora_auth_provider.py +++ b/diaspora_auth_provider.py @@ -1,6 +1,6 @@ """ synapse-diaspora-auth: A diaspora authenticator for matrix synapse. -Copyright (C) 2017 Shamil K Muhammed. +Copyright (C) 2017-2018 Shamil K Muhammed. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,17 +22,18 @@ import bcrypt import logging -__VERSION__ = "0.0.7" +__VERSION__ = "0.1.0" logger = logging.getLogger(__name__) class DiasporaAuthProvider: - __version__ = "0.0.7" + __version__ = "0.1.0" def __init__(self, config, account_handler): self.account_handler = account_handler self.config = config + self.auth_handler = self.account_handler._auth_handler if self.config.engine == "mysql": import pymysql self.module = pymysql @@ -60,7 +61,7 @@ class DiasporaAuthProvider: with self.connection.cursor() as cursor: yield threads.deferToThread( # Don't think this is needed, but w/e cursor.execute, - "SELECT username, encrypted_password FROM users WHERE username=%s", + "SELECT username, encrypted_password, email FROM users WHERE username=%s", (local_part,) ) user = yield threads.deferToThread( @@ -74,6 +75,7 @@ class DiasporaAuthProvider: logger.debug("User {} exists. Checking password".format(local_part)) # user exists, check if the password is correct. encrypted_password = user[1] + email = user[2] peppered_pass = u"{}{}".format(password, self.config.pepper) if not (bcrypt.hashpw(peppered_pass.encode('utf8'), encrypted_password.encode('utf8')) == encrypted_password.encode('utf8')): @@ -83,6 +85,7 @@ class DiasporaAuthProvider: # and create it if doesn't exist. if (yield self.account_handler.check_user_exists(user_id)): logger.info("User {} does exist in synapse db. Authentication complete".format(local_part)) + yield self.sync_email(user_id, email) defer.returnValue(True) # User not in synapse db. need to create it. logger.info("User {} does not exist in synapse db. creating it.".format(local_part)) @@ -93,6 +96,7 @@ class DiasporaAuthProvider: "Registration based on diaspora complete. UserID: {}.".format(user_id) ) logger.info("Confirming authentication request.") + yield self.sync_email(user_id, email) defer.returnValue(True) except self.module.Error as e: logger.warning("Error during diaspora authentication: {}".format(e)) @@ -100,6 +104,33 @@ class DiasporaAuthProvider: finally: self.connection.close() + @defer.inlineCallbacks + def sync_email(self, user_id, email): + logger.info("Syncing emails of {}".format(user_id)) + email = email.lower() + store = self.account_handler._store # Need access to datastore + threepids = yield store.user_get_threepids(user_id) + if not threepids: + logger.info("No 3pids found.") + yield self.add_email(user_id, email) + for threepid in threepids: + if not threepid['medium'] == 'email': + logger.debug("Not an email: {}".format(str(threepid))) + pass + address = threepid['address'] + if address != email: + logger.info("Existing 3pid doesn't match {} != {}. Deleting".format(address, email)) + yield self.auth_handler.delete_threepid(user_id, 'email', address) + yield self.add_email(user_id, email) + break + logger.info("Sync completed.") + + @defer.inlineCallbacks + def add_email(self, user_id, email): + logger.info("Adding 3pid: {} for {}".format(email, user_id)) + validated_at = self.account_handler.hs.get_clock().time_msec() + yield self.auth_handler.add_threepid(user_id, 'email', email, validated_at) + @staticmethod def parse_config(config): class _Conf: