summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrebs <drebs@leap.se>2016-11-22 21:50:22 -0200
committerdrebs <drebs@leap.se>2016-11-23 07:10:29 -0200
commitab929ff384666922fdb54f33092d5d8a361f3bba (patch)
tree14741e97ffa08d5127596edd718deaafb22cb9b2
parent3ad3241cb21390923e551959829f0af98dd7ad34 (diff)
[bug] delay couch state initialization
The couch state checks if all user databases have the correct schema version on initialization, and may log errors and raise exceptions if that is not the case. Because we are currently using `twistd web --wsgi`, if those errors are logged too early the reactor may have not been started and the twistd logging facilities may not have been initialized. This commit delays the state initialization until the reactor has been started, to make sure any errors raised and logged in that stage will actually reach the logfile.
-rw-r--r--server/src/leap/soledad/server/application.py42
-rw-r--r--server/src/leap/soledad/server/auth.py12
2 files changed, 42 insertions, 12 deletions
diff --git a/server/src/leap/soledad/server/application.py b/server/src/leap/soledad/server/application.py
index a9ebcaf6..17296425 100644
--- a/server/src/leap/soledad/server/application.py
+++ b/server/src/leap/soledad/server/application.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# application.py
-# Copyright (C) 2013 LEAP
+# Copyright (C) 2016 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
@@ -14,6 +14,14 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+A WSGI application to serve as the root resource of the webserver.
+
+Use it like this:
+
+ twistd web --wsgi=leap.soledad.server.application.wsgi_application
+"""
+from twisted.internet import reactor
from leap.soledad.server import SoledadApp
from leap.soledad.server.auth import SoledadTokenAuthMiddleware
@@ -21,11 +29,11 @@ from leap.soledad.server.gzip_middleware import GzipMiddleware
from leap.soledad.server.config import load_configuration
from leap.soledad.common.backend import SoledadBackend
from leap.soledad.common.couch.state import CouchServerState
+from leap.soledad.common.log import getLogger
-# ----------------------------------------------------------------------------
-# Run as Twisted WSGI Resource
-# ----------------------------------------------------------------------------
+__all__ = ['wsgi_application']
+
def _load_config():
conf = load_configuration('/etc/soledad/soledad-server.conf')
@@ -40,8 +48,26 @@ def _get_couch_state():
return state
-_couch_state = _get_couch_state()
+_app = SoledadTokenAuthMiddleware(SoledadApp(None)) # delay state init
+wsgi_application = GzipMiddleware(_app)
+
+
+# During its initialization, the couch state verifies if all user databases
+# contain a config document with the correct couch schema version stored, and
+# will log an error and raise an exception if that is not the case.
+#
+# If this verification made too early (i.e. before the reactor has started and
+# the twistd web logging facilities have been setup), the logging will not
+# work. Because of that, we delay couch state initialization until the reactor
+# is running.
+
+def _init_couch_state(_app):
+ try:
+ _app.state = _get_couch_state()
+ except Exception as e:
+ logger = getLogger()
+ logger.error(str(e))
+ reactor.stop()
+
-# a WSGI application that may be used by `twistd -web`
-wsgi_application = GzipMiddleware(
- SoledadTokenAuthMiddleware(SoledadApp(_couch_state)))
+reactor.callWhenRunning(_init_couch_state, _app)
diff --git a/server/src/leap/soledad/server/auth.py b/server/src/leap/soledad/server/auth.py
index b7186b3b..b0764569 100644
--- a/server/src/leap/soledad/server/auth.py
+++ b/server/src/leap/soledad/server/auth.py
@@ -343,9 +343,13 @@ class SoledadTokenAuthMiddleware(SoledadAuthMiddleware):
TOKEN_AUTH_ERROR_STRING = "Incorrect address or token."
- def __init__(self, app):
- self._state = app.state
- super(SoledadTokenAuthMiddleware, self).__init__(app)
+ def _get_state(self):
+ return self._app.state
+
+ def _set_state(self, state):
+ self._app.state = state
+
+ state = property(_get_state, _set_state)
def _verify_authentication_scheme(self, scheme):
"""
@@ -379,7 +383,7 @@ class SoledadTokenAuthMiddleware(SoledadAuthMiddleware):
"""
token = auth_data # we expect a cleartext token at this point
try:
- return self._state.verify_token(uuid, token)
+ return self.state.verify_token(uuid, token)
except Exception as e:
logger.error(e)
return False