summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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