summaryrefslogtreecommitdiff
path: root/src/leap/soledad
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/soledad')
-rw-r--r--src/leap/soledad/common/couch/state.py86
-rw-r--r--src/leap/soledad/server/_wsgi.py3
-rw-r--r--src/leap/soledad/server/entrypoints.py2
3 files changed, 36 insertions, 55 deletions
diff --git a/src/leap/soledad/common/couch/state.py b/src/leap/soledad/common/couch/state.py
index d9ff61a2..8cbe0934 100644
--- a/src/leap/soledad/common/couch/state.py
+++ b/src/leap/soledad/common/couch/state.py
@@ -17,12 +17,10 @@
"""
Server state using CouchDatabase as backend.
"""
+import couchdb
import re
-import treq
from six.moves.urllib.parse import urljoin
-from twisted.internet import defer
-from urlparse import urlsplit
from leap.soledad.common.log import getLogger
from leap.soledad.common.couch import CouchDatabase
@@ -53,61 +51,14 @@ def is_db_name_valid(name):
return re.match(db_name_regex, name) is not None
-@defer.inlineCallbacks
-def _check_db(url, db, auth, agent=None):
- # if there are documents, ensure that a config doc exists
- db_url = urljoin(url, '%s/' % db)
- config_doc_url = urljoin(db_url, CONFIG_DOC_ID)
- res = yield treq.get(config_doc_url, auth=auth, agent=agent)
- raise Exception
-
- if res.code != 200 and res.code != 404:
- raise Exception
-
- if res.code == 404:
- res = yield treq.get(urljoin(db_url, '_all_docs'), auth=auth,
- params={'limit': 1}, agent=agent)
- docs = yield res.json()
- if docs['total_rows'] != 0:
- logger.error(
- "Missing couch config document in database %s" % db)
- raise MissingCouchConfigDocumentError(db)
-
- if res.code == 200:
- config_doc = yield res.json()
- if config_doc[SCHEMA_VERSION_KEY] != SCHEMA_VERSION:
- logger.error(
- "Unsupported database schema in database %s" % db)
- raise WrongCouchSchemaVersionError(db)
-
-
-@defer.inlineCallbacks
-def check_schema_versions(couch_url, agent=None):
- """
- Check that all user databases use the correct couch schema.
- """
- url = urlsplit(couch_url)
- auth = (url.username, url.password) if url.username else None
- url = "%s://%s:%d" % (url.scheme, url.hostname, url.port)
- res = yield treq.get(urljoin(url, '_all_dbs'), auth=auth, agent=agent)
- dbs = yield res.json()
- deferreds = []
- semaphore = defer.DeferredSemaphore(20)
- for db in dbs:
- if not db.startswith('user-'):
- continue
- d = semaphore.run(_check_db, url, db, auth, agent=agent)
- deferreds.append(d)
- yield defer.gatherResults(deferreds)
-
-
class CouchServerState(ServerState):
"""
Inteface of the WSGI server with the CouchDB backend.
"""
- def __init__(self, couch_url, create_cmd=None):
+ def __init__(self, couch_url, create_cmd=None,
+ check_schema_versions=False):
"""
Initialize the couch server state.
@@ -118,9 +69,40 @@ class CouchServerState(ServerState):
name and should access CouchDB with necessary
privileges, which server lacks for security reasons.
:type create_cmd: str
+ :param check_schema_versions: Whether to check couch schema version of
+ user dbs. Set to False as this is only
+ intended to run once during start-up.
+ :type check_schema_versions: bool
"""
self.couch_url = couch_url
self.create_cmd = create_cmd
+ if check_schema_versions:
+ self._check_schema_versions()
+
+ def _check_schema_versions(self):
+ """
+ Check that all user databases use the correct couch schema.
+ """
+ server = couchdb.client.Server(self.couch_url)
+ for dbname in server:
+ if not dbname.startswith('user-'):
+ continue
+ db = server[dbname]
+
+ # if there are documents, ensure that a config doc exists
+ config_doc = db.get(CONFIG_DOC_ID)
+ if config_doc:
+ if config_doc[SCHEMA_VERSION_KEY] != SCHEMA_VERSION:
+ logger.error(
+ "Unsupported database schema in database %s" % dbname)
+ raise WrongCouchSchemaVersionError(dbname)
+ else:
+ result = db.view('_all_docs', limit=1)
+ if result.total_rows != 0:
+ logger.error(
+ "Missing couch config document in database %s"
+ % dbname)
+ raise MissingCouchConfigDocumentError(dbname)
def open_database(self, dbname):
"""
diff --git a/src/leap/soledad/server/_wsgi.py b/src/leap/soledad/server/_wsgi.py
index 510cb7b9..f1b0018d 100644
--- a/src/leap/soledad/server/_wsgi.py
+++ b/src/leap/soledad/server/_wsgi.py
@@ -33,7 +33,8 @@ __all__ = ['init_couch_state', 'get_sync_resource']
def _get_couch_state(conf):
- state = CouchServerState(conf['couch_url'], create_cmd=conf['create_cmd'])
+ state = CouchServerState(conf['couch_url'], create_cmd=conf['create_cmd'],
+ check_schema_versions=True)
SoledadBackend.BATCH_SUPPORT = conf.get('batching', False)
return state
diff --git a/src/leap/soledad/server/entrypoints.py b/src/leap/soledad/server/entrypoints.py
index 9bccbcf4..7d18ca58 100644
--- a/src/leap/soledad/server/entrypoints.py
+++ b/src/leap/soledad/server/entrypoints.py
@@ -26,7 +26,6 @@ from twisted.internet import reactor
from twisted.python import threadpool
from twisted.logger import Logger
-from ..common.couch.state import check_schema_versions
from .auth import localPortal, publicPortal
from .session import SoledadSession
from ._config import get_config
@@ -74,5 +73,4 @@ def check_conf():
reactor.callWhenRunning(check_conf)
-reactor.callWhenRunning(check_schema_versions, conf['couch_url'])
reactor.callWhenRunning(init_couch_state, conf)