summaryrefslogtreecommitdiff
path: root/src/leap/mx/couchdbhelper.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/mx/couchdbhelper.py')
-rw-r--r--src/leap/mx/couchdbhelper.py148
1 files changed, 38 insertions, 110 deletions
diff --git a/src/leap/mx/couchdbhelper.py b/src/leap/mx/couchdbhelper.py
index f20f1dd..1752b4e 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``.
@@ -96,110 +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 alias: A string representing the email or alias to check.
- :type alias: str
- :return: a deferred for this query
+ :param address: A string representing the email or alias to check.
+ :type address: str
+ :return: A deferred that will fire with the user's uuid and pgp public
+ key.
: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)
- d.addCallbacks(partial(self._get_uuid, address), log.err)
-
+ 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 _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, uuid):
"""
- Returns a deferred that will return the pubkey for the uuid provided
+ Query couch and return a deferred that will fire with the pgp public
+ key for user with given uuid.
- :param uuid: uuid for the user to query
+ :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/",
- user_id=uuid,
+ viewId="by_user_id/",
+ key=uuid,
reduce=False,
include_docs=True)
- d.addCallbacks(partial(self._get_pgp_key, uuid), log.err)
+ 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
-
- def _get_pgp_key(self, uuid, result):
- """
- Callback used to filter the correct pubkey from the result of
- the query to the couchdb
-
- :param uuid: uuid for the user that was queried
- :type uuid: str
- :param result: result dictionary for the db query
- :type result: dict
-
- :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()