diff options
-rw-r--r-- | src/leap/mx/alias_resolver.py | 10 | ||||
-rw-r--r-- | src/leap/mx/check_recipient_access.py | 25 | ||||
-rw-r--r-- | src/leap/mx/couchdbhelper.py | 139 | ||||
-rw-r--r-- | src/leap/mx/tcp_map.py | 4 |
4 files changed, 47 insertions, 131 deletions
diff --git a/src/leap/mx/alias_resolver.py b/src/leap/mx/alias_resolver.py index a139dd0..dd631c8 100644 --- a/src/leap/mx/alias_resolver.py +++ b/src/leap/mx/alias_resolver.py @@ -40,22 +40,22 @@ class LEAPPostfixTCPMapAliasServer(postfix.PostfixTCPMapServer): A postfix tcp map alias resolver server. """ - def _cbGot(self, uuid): + def _cbGot(self, address): """ Return a code and message depending on the result of the factory's get(). - :param value: The uuid. - :type value: list + :param address: The address returned by the factory. + :type address: str """ - if uuid is None: + if address is None: self.sendCode( TCP_MAP_CODE_PERMANENT_FAILURE, postfix.quote("NOT FOUND SRY")) else: self.sendCode( TCP_MAP_CODE_SUCCESS, - postfix.quote(uuid)) + postfix.quote(address)) class AliasResolverFactory(LEAPPostfixTCPMapServerFactory): diff --git a/src/leap/mx/check_recipient_access.py b/src/leap/mx/check_recipient_access.py index 0977564..3b61fe8 100644 --- a/src/leap/mx/check_recipient_access.py +++ b/src/leap/mx/check_recipient_access.py @@ -50,8 +50,8 @@ class LEAPPostFixTCPMapAccessServer(postfix.PostfixTCPMapServer): :param value: The uuid and public key. :type value: list """ - uuid, pubkey = value - if uuid is None: + address, pubkey = value + if address is None: self.sendCode( TCP_MAP_CODE_PERMANENT_FAILURE, postfix.quote("REJECT")) @@ -75,25 +75,22 @@ class CheckRecipientAccessFactory(LEAPPostfixTCPMapServerFactory): protocol = LEAPPostFixTCPMapAccessServer - def _getPubKey(self, uuid): + def _getPubKey(self, address): """ - Look up PGP public key based on user uid. + Look up PGP public key based on email address. - :param uuid: The user uid. - :type uuid: str + :param address: The email address. + :type address: str - :return: A deferred that is fired with the uuid and the public key, if - available. + :return: A deferred that is fired with the address and the public key, if + each of them exists. :rtype: DeferredList """ - if uuid is None: + if not address: return defer.succeed([None, None]) - # properly encode uuid, otherwise twisted complains when replying - if isinstance(uuid, unicode): - uuid = uuid.encode("utf8") return defer.gatherResults([ - defer.succeed(uuid), - self._cdb.getPubKey(uuid), + defer.succeed(address), + self._cdb.getPubKey(address), ]) def get(self, key): diff --git a/src/leap/mx/couchdbhelper.py b/src/leap/mx/couchdbhelper.py index f20f1dd..7bcb5aa 100644 --- a/src/leap/mx/couchdbhelper.py +++ b/src/leap/mx/couchdbhelper.py @@ -15,24 +15,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. + """ Classes for working with CouchDB or BigCouch instances which store email alias maps, user UUIDs, and GPG keyIDs. """ -from functools import partial - -try: - from paisley import client -except ImportError: - print "This software requires paisley. Please see the README file" - print "for instructions on getting required dependencies." -try: - from twisted.python import log -except ImportError: - print "This software requires Twisted. Please see the README file" - print "for instructions on getting required dependencies." +from paisley import client +from twisted.python import log class ConnectedCouchDB(client.CouchDB): @@ -66,24 +57,8 @@ class ConnectedCouchDB(client.CouchDB): username=username, password=password, *args, **kwargs) - self._cache = {} - if dbName is None: - databases = self.listDB() - databases.addCallback(self._print_databases) - - def _print_databases(self, data): - """ - Callback for listDB that prints the available databases - - :param data: response from the listDB command - :type data: array - """ - log.msg("Available databases:") - for database in data: - log.msg(" * %s" % (database,)) - def createDB(self, dbName): """ Overrides ``paisley.client.CouchDB.createDB``. @@ -100,106 +75,52 @@ class ConnectedCouchDB(client.CouchDB): """ Check to see if a particular email or alias exists. - :param alias: A string representing the email or alias to check. - :type alias: str + :param address: A string representing the email or alias to check. + :type address: str :return: a deferred for this query :rtype twisted.defer.Deferred """ - assert isinstance(address, (str, unicode)), "Email or alias queries must be string" - # TODO: Cache results - d = self.openView(docId="Identity", viewId="by_address/", key=address, - reduce=False, - include_docs=True) + reduce=True, + include_docs=False) - d.addCallbacks(partial(self._get_uuid, address), log.err) + def _callback(result): + if len(result["rows"]): + return address + return None + + d.addCallbacks(_callback, log.err) return d - def _get_uuid(self, address, result): - """ - Parses the result of the by_address query and gets the uuid - - :param address: alias looked up - :type address: string - :param result: result dictionary - :type result: dict - :return: The uuid for alias if available - :rtype: str - """ - for row in result["rows"]: - if row["key"] == address: - uuid = row["doc"].get("user_id", None) - if uuid is None: - log.msg("ERROR: Found doc for %s but there's not user_id!" - % (address,)) - return uuid - return None - - def getPubKey(self, uuid): + def getPubKey(self, address): """ - Returns a deferred that will return the pubkey for the uuid provided + Returns a deferred that will fire with the pubkey for the address. - :param uuid: uuid for the user to query - :type uuid: str + :param address: email address to query + :type address: str :rtype: Deferred """ d = self.openView(docId="Identity", viewId="pgp_key_by_email/", - user_id=uuid, + key=address, reduce=False, - include_docs=True) - - d.addCallbacks(partial(self._get_pgp_key, uuid), log.err) + include_docs=False) - return d - - def _get_pgp_key(self, uuid, result): - """ - Callback used to filter the correct pubkey from the result of - the query to the couchdb + def _callback(result): + if not result["rows"]: + log.msg("No PGP public key found for %s." % address) + return None + if len(result["rows"]) > 1: + log.msg("More than one PGP public key found for %s, " + "will pick the first one found." % address) + row = result["rows"].pop(0) + return row["value"] - :param uuid: uuid for the user that was queried - :type uuid: str - :param result: result dictionary for the db query - :type result: dict + d.addCallbacks(_callback, log.err) - :rtype: str or None - """ - for row in result["rows"]: - user_id = row["doc"].get("user_id") - if not user_id: - print("User %s is in an inconsistent state") - continue - if user_id == uuid: - return row["value"] - return None - -if __name__ == "__main__": - from twisted.internet import reactor - cdb = ConnectedCouchDB("localhost", - port=6666, - dbName="users", - username="", - password="") - - d = cdb.queryByLoginOrAlias("test1") - - @d.addCallback - def right(result): - print "Should be an actual uuid:", result - print "Public Key:" - print cdb.getPubKey(result) - - d2 = cdb.queryByLoginOrAlias("asdjaoisdjoiqwjeoi") - - @d2.addCallback - def wrong(result): - print "Should be None:", result - - reactor.callLater(5, reactor.stop) - reactor.run() + return d diff --git a/src/leap/mx/tcp_map.py b/src/leap/mx/tcp_map.py index b62441f..d8cd835 100644 --- a/src/leap/mx/tcp_map.py +++ b/src/leap/mx/tcp_map.py @@ -43,9 +43,7 @@ class LEAPPostfixTCPMapServerFactory(ServerFactory): def get(self, key): """ - Look up uuid based on key, only up to the username id of the key. - - At some point we will have to consider the domain part too. + Look up if address exists. :param key: The lookup key. :type key: str |