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.py172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/leap/mx/couchdbhelper.py b/src/leap/mx/couchdbhelper.py
new file mode 100644
index 0000000..cbb087d
--- /dev/null
+++ b/src/leap/mx/couchdbhelper.py
@@ -0,0 +1,172 @@
+# -*- encoding: utf-8 -*-
+# couchdb.py
+# Copyright (C) 2013 LEAP
+#
+# 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
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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.
+"""
+
+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.internet import defer
+except ImportError:
+ print "This software requires Twisted. Please see the README file"
+ print "for instructions on getting required dependencies."
+
+from functools import partial
+
+from leap.mx.util import log
+
+
+class ConnectedCouchDB(client.CouchDB):
+ """
+ Connect to a CouchDB instance.
+
+ CouchDB document for testing is '_design', and the view is simply
+ a preconfigured set of mapped responses.
+ """
+
+ def __init__(self, host, port=5984, dbName=None, username=None,
+ password=None, *args, **kwargs):
+ """
+ Connect to a CouchDB instance.
+
+ @param host: A hostname string for the CouchDB server.
+ @type host: str
+ @param port: The port of the CouchDB server.
+ @type port: int
+ @param dbName: (optional) The default database to bind queries to.
+ @type dbName: str
+ @param username: (optional) The username for authorization.
+ @type username: str
+ @param str password: (optional) The password for authorization.
+ @type password: str
+ """
+ client.CouchDB.__init__(self,
+ host,
+ port=port,
+ dbName=dbName,
+ 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``.
+ """
+ pass
+
+ def deleteDB(self, dbName):
+ """
+ Overrides ``paisley.client.CouchDB.deleteDB``.
+ """
+ pass
+
+ def queryByLoginOrAlias(self, alias):
+ """
+ Check to see if a particular email or alias exists.
+
+ @param alias: A string representing the email or alias to check.
+ @type alias: str
+ @return: a deferred for this query
+ @rtype twisted.defer.Deferred
+ """
+ assert isinstance(alias, str), "Email or alias queries must be string"
+
+ # TODO: Cache results
+
+ d = self.openView(docId="User",
+ viewId="by_login_or_alias/",
+ key=alias,
+ reduce=False)
+
+ d.addCallbacks(partial(self._get_uuid, alias), log.err)
+
+ return d
+
+ def _get_uuid(self, alias, result):
+ """
+ Parses the result of the by_login_or_alias query and gets the
+ uuid
+
+ @param alias: alias looked up
+ @type alias: 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"] == alias:
+ uuid = row["id"]
+ self._cache[uuid] = row["value"]
+ return uuid
+ return None
+
+
+ def getPubKey(self, uuid):
+ pubkey = None
+ try:
+ pubkey = self._cache[uuid]
+ except:
+ pass
+ return pubkey
+
+
+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 cdb.getPubKey(result)
+
+ d2 = cdb.queryByLoginOrAlias("asdjaoisdjoiqwjeoi")
+ @d2.addCallback
+ def wrong(result):
+ print "Should be None:", result
+
+ reactor.callLater(5, reactor.stop)
+ reactor.run()