summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrebs <drebs@leap.se>2015-04-15 12:48:34 -0300
committerdrebs <drebs@leap.se>2015-04-16 11:53:13 -0300
commit527d7d4a67f859a3315812b100b2c58fd0eeded6 (patch)
treeb51959b18ec0053f9ed448cec9bd8c1bc98eb607
parent14ef3dcce18240b756415fefa2a56936f96a12e9 (diff)
[bug] return uuid as result of alias resolver
This fixes a bug introduced on b0ef529cc882a96903597fb5279919969fa286c3, when the alias resolver was modified to return the user's address instead of the uuid. In order to fix this, I had to revert one of the changes made by the commit above, which is to don't make use of reduced view for the uuid query. The pgp public key query remains reduced, as implemented in the commit above. We also refactor the code a bit to allow for log messages specific to each of tcp map's sublasses. Related: #6858.
-rw-r--r--src/leap/mx/alias_resolver.py18
-rw-r--r--src/leap/mx/check_recipient_access.py35
-rw-r--r--src/leap/mx/couchdbhelper.py73
-rw-r--r--src/leap/mx/mail_receiver.py2
-rw-r--r--src/leap/mx/tcp_map.py30
5 files changed, 81 insertions, 77 deletions
diff --git a/src/leap/mx/alias_resolver.py b/src/leap/mx/alias_resolver.py
index dd631c8..752eac4 100644
--- a/src/leap/mx/alias_resolver.py
+++ b/src/leap/mx/alias_resolver.py
@@ -40,22 +40,26 @@ class LEAPPostfixTCPMapAliasServer(postfix.PostfixTCPMapServer):
A postfix tcp map alias resolver server.
"""
- def _cbGot(self, address):
+ def _cbGot(self, user_data):
"""
Return a code and message depending on the result of the factory's
get().
- :param address: The address returned by the factory.
- :type address: str
+ :param user_data: The user's uuid and pgp public key.
+ :type user_data: list
"""
- if address is None:
+ uuid, _ = user_data
+ if uuid is None:
self.sendCode(
TCP_MAP_CODE_PERMANENT_FAILURE,
postfix.quote("NOT FOUND SRY"))
else:
+ # properly encode uuid, otherwise twisted complains when replying
+ if isinstance(uuid, unicode):
+ uuid = uuid.encode("utf8")
self.sendCode(
TCP_MAP_CODE_SUCCESS,
- postfix.quote(address))
+ postfix.quote(uuid))
class AliasResolverFactory(LEAPPostfixTCPMapServerFactory):
@@ -64,3 +68,7 @@ class AliasResolverFactory(LEAPPostfixTCPMapServerFactory):
"""
protocol = LEAPPostfixTCPMapAliasServer
+
+ @property
+ def _query_message(self):
+ return "Resolving alias for"
diff --git a/src/leap/mx/check_recipient_access.py b/src/leap/mx/check_recipient_access.py
index 3b61fe8..9f79dfe 100644
--- a/src/leap/mx/check_recipient_access.py
+++ b/src/leap/mx/check_recipient_access.py
@@ -23,7 +23,6 @@ Test this with postmap -v -q "foo" tcp:localhost:2244
"""
from twisted.protocols import postfix
-from twisted.internet import defer
from leap.mx.tcp_map import LEAPPostfixTCPMapServerFactory
from leap.mx.tcp_map import TCP_MAP_CODE_SUCCESS
@@ -50,8 +49,8 @@ class LEAPPostFixTCPMapAccessServer(postfix.PostfixTCPMapServer):
:param value: The uuid and public key.
:type value: list
"""
- address, pubkey = value
- if address is None:
+ uuid, pubkey = value
+ if uuid is None:
self.sendCode(
TCP_MAP_CODE_PERMANENT_FAILURE,
postfix.quote("REJECT"))
@@ -75,31 +74,7 @@ class CheckRecipientAccessFactory(LEAPPostfixTCPMapServerFactory):
protocol = LEAPPostFixTCPMapAccessServer
- def _getPubKey(self, address):
- """
- Look up PGP public key based on email address.
-
- :param address: The email address.
- :type address: str
-
- :return: A deferred that is fired with the address and the public key, if
- each of them exists.
- :rtype: DeferredList
- """
- if not address:
- return defer.succeed([None, None])
- return defer.gatherResults([
- defer.succeed(address),
- self._cdb.getPubKey(address),
- ])
-
- def get(self, key):
- """
- Look up uuid and PGP public key based on key.
+ @property
+ def _query_message(self):
+ return "Checking recipient access for"
- :param key: The lookup key.
- :type key: str
- """
- d = LEAPPostfixTCPMapServerFactory.get(self, key)
- d.addCallback(self._getPubKey)
- return d
diff --git a/src/leap/mx/couchdbhelper.py b/src/leap/mx/couchdbhelper.py
index 7bcb5aa..1752b4e 100644
--- a/src/leap/mx/couchdbhelper.py
+++ b/src/leap/mx/couchdbhelper.py
@@ -71,56 +71,63 @@ class ConnectedCouchDB(client.CouchDB):
"""
pass
- def queryByAddress(self, address):
+ def getUuidAndPubkey(self, address):
"""
- Check to see if a particular email or alias exists.
+ Query couch and return a deferred that will fire with the uuid and pgp
+ public key for address.
:param address: A string representing the email or alias to check.
:type address: str
- :return: a deferred for this query
+ :return: A deferred that will fire with the user's uuid and pgp public
+ key.
:rtype twisted.defer.Deferred
"""
# TODO: Cache results
d = self.openView(docId="Identity",
viewId="by_address/",
key=address,
- reduce=True,
- include_docs=False)
-
- def _callback(result):
- if len(result["rows"]):
- return address
- return None
-
- d.addCallbacks(_callback, log.err)
-
+ reduce=False,
+ include_docs=True)
+
+ def _get_uuid_and_pubkey_cbk(result):
+ uuid = None
+ pubkey = None
+ if result["rows"]:
+ doc = result["rows"][0]["doc"]
+ uuid = doc["user_id"]
+ if "keys" in doc:
+ pubkey = doc["keys"]["pgp"]
+ return uuid, pubkey
+
+ d.addCallback(_get_uuid_and_pubkey_cbk)
return d
- def getPubKey(self, address):
+ def getPubkey(self, uuid):
"""
- Returns a deferred that will fire with the pubkey for the address.
+ Query couch and return a deferred that will fire with the pgp public
+ key for user with given uuid.
- :param address: email address to query
- :type address: str
+ :param uuid: The uuid of a user
+ :type uuid: str
+ :return: A deferred that will fire with the pgp public key for
+ the user.
:rtype: Deferred
"""
d = self.openView(docId="Identity",
- viewId="pgp_key_by_email/",
- key=address,
+ viewId="by_user_id/",
+ key=uuid,
reduce=False,
- include_docs=False)
-
- 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"]
-
- d.addCallbacks(_callback, log.err)
-
+ include_docs=True)
+
+ def _get_pubkey_cbk(result):
+ pubkey = None
+ try:
+ doc = result["rows"][0]["doc"]
+ pubkey = doc["keys"]["pgp"]
+ except (KeyError, IndexError):
+ pass
+ return pubkey
+
+ d.addCallbacks(_get_pubkey_cbk, log.err)
return d
diff --git a/src/leap/mx/mail_receiver.py b/src/leap/mx/mail_receiver.py
index 77909b0..f0b9c03 100644
--- a/src/leap/mx/mail_receiver.py
+++ b/src/leap/mx/mail_receiver.py
@@ -491,7 +491,7 @@ class MailReceiver(Service):
log.msg("BUG: There was no uuid!")
defer.returnValue(None)
- pubkey = yield self._users_cdb.getPubKey(uuid)
+ pubkey = yield self._users_cdb.getPubkey(uuid)
if pubkey is None or len(pubkey) == 0:
log.msg("No public key, stopping the processing chain")
bounce_reason = "Missing PubKey: There was a problem " \
diff --git a/src/leap/mx/tcp_map.py b/src/leap/mx/tcp_map.py
index d8cd835..108c2aa 100644
--- a/src/leap/mx/tcp_map.py
+++ b/src/leap/mx/tcp_map.py
@@ -17,8 +17,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from twisted.python import log
+from abc import ABCMeta
+from abc import abstractproperty
+
from twisted.internet.protocol import ServerFactory
+from twisted.python import log
# For info on codes, see: http://www.postfix.org/tcp_table.5.html
@@ -27,11 +30,14 @@ TCP_MAP_CODE_TEMPORARY_FAILURE = 400
TCP_MAP_CODE_PERMANENT_FAILURE = 500
-class LEAPPostfixTCPMapServerFactory(ServerFactory):
+class LEAPPostfixTCPMapServerFactory(ServerFactory, object):
"""
A factory for postfix tcp map servers.
"""
+ __metaclass__ = ABCMeta
+
+
def __init__(self, couchdb):
"""
Initialize the factory.
@@ -41,14 +47,22 @@ class LEAPPostfixTCPMapServerFactory(ServerFactory):
"""
self._cdb = couchdb
- def get(self, key):
+ @abstractproperty
+ def _query_message(self):
+ pass
+
+ def get(self, lookup_key):
"""
- Look up if address exists.
+ Look up user based on lookup_key.
+
+ :param lookup_key: The lookup key.
+ :type lookup_key: str
- :param key: The lookup key.
- :type key: str
+ :return: A deferred that will be fired with the user's address, uuid
+ and pgp key.
+ :rtype: Deferred
"""
- log.msg("Query key: %s" % (key,))
- d = self._cdb.queryByAddress(key)
+ log.msg("%s %s" % (self._query_message, lookup_key,))
+ d = self._cdb.getUuidAndPubkey(lookup_key)
d.addErrback(log.err)
return d