summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'server/src')
-rw-r--r--server/src/leap/soledad/server/__init__.py16
-rw-r--r--server/src/leap/soledad/server/_version.py4
-rw-r--r--server/src/leap/soledad/server/auth.py27
-rw-r--r--server/src/leap/soledad/server/sync.py14
4 files changed, 30 insertions, 31 deletions
diff --git a/server/src/leap/soledad/server/__init__.py b/server/src/leap/soledad/server/__init__.py
index adb5b561..7a03f6fb 100644
--- a/server/src/leap/soledad/server/__init__.py
+++ b/server/src/leap/soledad/server/__init__.py
@@ -92,16 +92,13 @@ import sys
from u1db.remote import http_app, utils
+from ._version import get_versions
+
# Keep OpenSSL's tsafe before importing Twisted submodules so we can put
# it back if Twisted==12.0.0 messes with it.
from OpenSSL import tsafe
-old_tsafe = tsafe
from twisted import version
-if version.base() == "12.0.0":
- # Put OpenSSL's tsafe back into place. This can probably be removed if we
- # come to use Twisted>=12.3.0.
- sys.modules['OpenSSL.tsafe'] = old_tsafe
from leap.soledad.server.auth import SoledadTokenAuthMiddleware
from leap.soledad.server.gzip_middleware import GzipMiddleware
@@ -115,11 +112,18 @@ from leap.soledad.server.sync import (
from leap.soledad.common import SHARED_DB_NAME
from leap.soledad.common.couch import CouchServerState
+old_tsafe = tsafe
+
+if version.base() == "12.0.0":
+ # Put OpenSSL's tsafe back into place. This can probably be removed if we
+ # come to use Twisted>=12.3.0.
+ sys.modules['OpenSSL.tsafe'] = old_tsafe
# ----------------------------------------------------------------------------
# Soledad WSGI application
# ----------------------------------------------------------------------------
+
class SoledadApp(http_app.HTTPApp):
"""
Soledad WSGI application
@@ -303,7 +307,5 @@ def application(environ, start_response):
return application(environ, start_response)
-
-from ._version import get_versions
__version__ = get_versions()['version']
del get_versions
diff --git a/server/src/leap/soledad/server/_version.py b/server/src/leap/soledad/server/_version.py
index 5b2e62d4..d9fb8322 100644
--- a/server/src/leap/soledad/server/_version.py
+++ b/server/src/leap/soledad/server/_version.py
@@ -1,4 +1,3 @@
-
# This file was generated by the `freeze_debianver` command in setup.py
# Using 'versioneer.py' (0.7+) from
# revision-control system data, or from the parent directory name of an
@@ -8,6 +7,3 @@
version_version = '0.6.5'
version_full = '963717dc05824bcb4c69b912d948647ece3cf3aa'
-
-def get_versions(default={}, verbose=False):
- return {'version': version_version, 'full': version_full}
diff --git a/server/src/leap/soledad/server/auth.py b/server/src/leap/soledad/server/auth.py
index 57f600a1..02b54cca 100644
--- a/server/src/leap/soledad/server/auth.py
+++ b/server/src/leap/soledad/server/auth.py
@@ -21,9 +21,9 @@ Authentication facilities for Soledad Server.
"""
+import time
import httplib
-import simplejson as json
-
+import json
from u1db import DBNAME_CONSTRAINTS, errors as u1db_errors
from abc import ABCMeta, abstractmethod
@@ -32,12 +32,8 @@ from couchdb.client import Server
from twisted.python import log
from hashlib import sha512
-
-from leap.soledad.common import (
- SHARED_DB_NAME,
- SHARED_DB_LOCK_DOC_ID_PREFIX,
- USER_DB_PREFIX,
-)
+from leap.soledad.common import SHARED_DB_NAME
+from leap.soledad.common import USER_DB_PREFIX
from leap.soledad.common.errors import InvalidAuthTokenError
@@ -268,7 +264,8 @@ class SoledadAuthMiddleware(object):
scheme, encoded = auth.split(None, 1)
uuid, auth_data = encoded.decode('base64').split(':', 1)
if not self._verify_authentication_scheme(scheme):
- return self._unauthorized_error("Wrong authentication scheme")
+ return self._unauthorized_error(
+ start_response, "Wrong authentication scheme")
# verify if user is athenticated
try:
@@ -354,7 +351,8 @@ class SoledadTokenAuthMiddleware(SoledadAuthMiddleware):
Token based authentication.
"""
- TOKENS_DB = "tokens"
+ TOKENS_DB_PREFIX = "tokens_"
+ TOKENS_DB_EXPIRE = 30 * 24 * 3600 # 30 days in seconds
TOKENS_TYPE_KEY = "type"
TOKENS_TYPE_DEF = "Token"
TOKENS_USER_ID_KEY = "user_id"
@@ -414,7 +412,14 @@ class SoledadTokenAuthMiddleware(SoledadAuthMiddleware):
invalid.
"""
server = Server(url=self._app.state.couch_url)
- dbname = self.TOKENS_DB
+ # the tokens db rotates every 30 days, and the current db name is
+ # "tokens_NNN", where NNN is the number of seconds since epoch divided
+ # by the rotate period in seconds. When rotating, old and new tokens
+ # db coexist during a certain window of time and valid tokens are
+ # replicated from the old db to the new one. See:
+ # https://leap.se/code/issues/6785
+ dbname = self.TOKENS_DB_PREFIX + \
+ str(int(time.time() / self.TOKENS_DB_EXPIRE))
db = server[dbname]
# lookup key is a hash of the token to prevent timing attacks.
token = db.get(sha512(token).hexdigest())
diff --git a/server/src/leap/soledad/server/sync.py b/server/src/leap/soledad/server/sync.py
index 6dc99b5a..18c4ee40 100644
--- a/server/src/leap/soledad/server/sync.py
+++ b/server/src/leap/soledad/server/sync.py
@@ -14,17 +14,12 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
"""
Server side synchronization infrastructure.
"""
-
import json
-
from leap.soledad.common.couch import CouchDatabase
-from itertools import izip
from u1db import sync, Document
from u1db.remote import http_app
@@ -224,7 +219,6 @@ class SyncExchange(sync.SyncExchange):
self._sync_state = ServerSyncState(
self._db, self.source_replica_uid, sync_id)
-
def find_changes_to_return(self, received):
"""
Find changes to return.
@@ -286,7 +280,8 @@ class SyncExchange(sync.SyncExchange):
doc = self._db.get_doc(changed_doc_id, include_deleted=True)
return_doc_cb(doc, gen, trans_id)
- def insert_doc_from_source(self, doc, source_gen, trans_id,
+ def insert_doc_from_source(
+ self, doc, source_gen, trans_id,
number_of_docs=None, doc_idx=None, sync_id=None):
"""Try to insert synced document from source.
@@ -371,8 +366,9 @@ class SyncResource(http_app.SyncResource):
self._sync_id = sync_id
@http_app.http_method(content_as_args=True)
- def post_put(self, id, rev, content, gen, trans_id, number_of_docs,
- doc_idx):
+ def post_put(
+ self, id, rev, content, gen,
+ trans_id, number_of_docs, doc_idx):
"""
Put one incoming document into the server replica.