summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Shyba <victor.shyba@gmail.com>2015-10-28 17:58:27 -0300
committerVictor Shyba <victor.shyba@gmail.com>2015-11-03 12:41:37 -0300
commiteaf19626a57d5f5325653fee3aea9db27c9531fe (patch)
treefce19a8c6841a78698395e31306b5c31c9810e2b
parent421691ef71019d0bcd4447a773efa5e9b15b0c71 (diff)
[refactor] resource logic encapsulation
Creating a resource from a path to use get_json causes a lot of dirty code and unexplained things like response[2]. This commit extracts that logic into a helper to let it more clear about what is happening.
-rw-r--r--common/src/leap/soledad/common/couch/__init__.py169
-rw-r--r--common/src/leap/soledad/common/document.py1
-rw-r--r--server/src/leap/soledad/server/auth.py5
3 files changed, 71 insertions, 104 deletions
diff --git a/common/src/leap/soledad/common/couch/__init__.py b/common/src/leap/soledad/common/couch/__init__.py
index 6fd4d0ce..274f59e2 100644
--- a/common/src/leap/soledad/common/couch/__init__.py
+++ b/common/src/leap/soledad/common/couch/__init__.py
@@ -166,8 +166,8 @@ class CouchDatabase(object):
"""
for ddoc_name in ['docs', 'syncs', 'transactions']:
try:
- self._database.resource('_design',
- ddoc_name, '_info').get_json()
+ self.json_from_resource(['_design', ddoc_name, '_info'],
+ check_missing_ddoc=False)
except ResourceNotFound:
ddoc = json.loads(
binascii.a2b_base64(
@@ -320,12 +320,9 @@ class CouchDatabase(object):
"""
# get document with all attachments (u1db content and eventual
# conflicts)
- try:
- result = \
- self._database.resource(doc_id).get_json(
- attachments=True)[2]
- except ResourceNotFound:
+ if doc_id not in self._database:
return None
+ result = self.json_from_resource([doc_id], attachments=True)
return self.__parse_doc_from_couch(result, doc_id, check_for_conflicts)
def __parse_doc_from_couch(self, result, doc_id,
@@ -387,19 +384,6 @@ class CouchDatabase(object):
:rtype: str
:raise InvalidGeneration: Raised when the generation does not exist.
- :raise MissingDesignDocError: Raised when tried to access a missing
- design document.
- :raise MissingDesignDocListFunctionError: Raised when trying to access
- a missing list function on a
- design document.
- :raise MissingDesignDocNamedViewError: Raised when trying to access a
- missing named view on a design
- document.
- :raise MissingDesignDocDeletedError: Raised when trying to access a
- deleted design document.
- :raise MissingDesignDocUnknownError: Raised when failed to access a
- design document for an yet
- unknown reason.
"""
if generation == 0:
return ''
@@ -407,16 +391,10 @@ class CouchDatabase(object):
ddoc_path = [
'_design', 'transactions', '_list', 'trans_id_for_gen', 'log'
]
- res = self._database.resource(*ddoc_path)
- try:
- response = res.get_json(gen=generation)
- if response[2] == {}:
- raise InvalidGeneration
- return response[2]['transaction_id']
- except ResourceNotFound as e:
- raise_missing_design_doc_error(e, ddoc_path)
- except ServerError as e:
- raise_server_error(e, ddoc_path)
+ response = self.json_from_resource(ddoc_path, gen=generation)
+ if response == {}:
+ raise InvalidGeneration
+ return response['transaction_id']
def get_replica_gen_and_trans_id(self, other_replica_uid):
"""
@@ -472,11 +450,13 @@ class CouchDatabase(object):
# TODO: move into resource logic!
first_entry = self.get_doc(doc_id, check_for_conflicts=True)
conflicts.append(first_entry)
- resource = self._database.resource(doc_id, 'u1db_conflicts')
+
try:
- response = resource.get_json(**params)
+ response = self.json_from_resource([doc_id, 'u1db_conflicts'],
+ check_missing_ddoc=False,
+ **params)
return conflicts + self._build_conflicts(
- doc_id, json.loads(response[2].read()))
+ doc_id, json.loads(response.read()))
except ResourceNotFound:
return []
@@ -513,31 +493,13 @@ class CouchDatabase(object):
:return: The complete transaction log.
:rtype: [(str, str)]
-
- :raise MissingDesignDocError: Raised when tried to access a missing
- design document.
- :raise MissingDesignDocListFunctionError: Raised when trying to access
- a missing list function on a
- design document.
- :raise MissingDesignDocNamedViewError: Raised when trying to access a
- missing named view on a design
- document.
- :raise MissingDesignDocDeletedError: Raised when trying to access a
- deleted design document.
- :raise MissingDesignDocUnknownError: Raised when failed to access a
- design document for an yet
- unknown reason.
"""
# query a couch view
ddoc_path = ['_design', 'transactions', '_view', 'log']
- res = self._database.resource(*ddoc_path)
- try:
- response = res.get_json()
- return map(
- lambda row: (row['id'], row['value']),
- response[2]['rows'])
- except ResourceNotFound as e:
- raise_missing_design_doc_error(e, ddoc_path)
+ response = self.json_from_resource(ddoc_path)
+ return map(
+ lambda row: (row['id'], row['value']),
+ response['rows'])
def whats_changed(self, old_generation=0):
"""
@@ -555,53 +517,33 @@ class CouchDatabase(object):
to the last intervening change and sorted by generation (old
changes first)
:rtype: (int, str, [(str, int, str)])
-
- :raise MissingDesignDocError: Raised when tried to access a missing
- design document.
- :raise MissingDesignDocListFunctionError: Raised when trying to access
- a missing list function on a
- design document.
- :raise MissingDesignDocNamedViewError: Raised when trying to access a
- missing named view on a design
- document.
- :raise MissingDesignDocDeletedError: Raised when trying to access a
- deleted design document.
- :raise MissingDesignDocUnknownError: Raised when failed to access a
- design document for an yet
- unknown reason.
"""
# query a couch list function
ddoc_path = [
'_design', 'transactions', '_list', 'whats_changed', 'log'
]
- res = self._database.resource(*ddoc_path)
- try:
- response = res.get_json(old_gen=old_generation)
- results = map(
- lambda row:
- (row['generation'], row['doc_id'], row['transaction_id']),
- response[2]['transactions'])
- results.reverse()
- cur_gen = old_generation
- seen = set()
- changes = []
- newest_trans_id = ''
- for generation, doc_id, trans_id in results:
- if doc_id not in seen:
- changes.append((doc_id, generation, trans_id))
- seen.add(doc_id)
- if changes:
- cur_gen = changes[0][1] # max generation
- newest_trans_id = changes[0][2]
- changes.reverse()
- else:
- cur_gen, newest_trans_id = self.get_generation_info()
+ response = self.json_from_resource(ddoc_path, old_gen=old_generation)
+ results = map(
+ lambda row:
+ (row['generation'], row['doc_id'], row['transaction_id']),
+ response['transactions'])
+ results.reverse()
+ cur_gen = old_generation
+ seen = set()
+ changes = []
+ newest_trans_id = ''
+ for generation, doc_id, trans_id in results:
+ if doc_id not in seen:
+ changes.append((doc_id, generation, trans_id))
+ seen.add(doc_id)
+ if changes:
+ cur_gen = changes[0][1] # max generation
+ newest_trans_id = changes[0][2]
+ changes.reverse()
+ else:
+ cur_gen, newest_trans_id = self.get_generation_info()
- return cur_gen, newest_trans_id, changes
- except ResourceNotFound as e:
- raise_missing_design_doc_error(e, ddoc_path)
- except ServerError as e:
- raise_server_error(e, ddoc_path)
+ return cur_gen, newest_trans_id, changes
def get_generation_info(self):
"""
@@ -609,6 +551,25 @@ class CouchDatabase(object):
:return: A tuple containing the current generation and transaction id.
:rtype: (int, str)
+ """
+ # query a couch list function
+ ddoc_path = ['_design', 'transactions', '_list', 'generation', 'log']
+ info = self.json_from_resource(ddoc_path)
+ return (info['generation'], info['transaction_id'])
+
+ def json_from_resource(self, ddoc_path, check_missing_ddoc=True,
+ **kwargs):
+ """
+ Get a resource from it's path and gets a doc's JSON using provided
+ parameters, also checking for missing design docs by default.
+
+ :param ddoc_path: The path to resource.
+ :type ddoc_path: [str]
+ :param check_missing_ddoc: Raises info on what design doc is missing.
+ :type check_missin_ddoc: bool
+
+ :return: The request's data parsed from JSON to a dict.
+ :rtype: dict
:raise MissingDesignDocError: Raised when tried to access a missing
design document.
@@ -624,14 +585,18 @@ class CouchDatabase(object):
design document for an yet
unknown reason.
"""
- # query a couch list function
- ddoc_path = ['_design', 'transactions', '_list', 'generation', 'log']
- res = self._database.resource(*ddoc_path)
+ if ddoc_path is not None:
+ resource = self._database.resource(*ddoc_path)
+ else:
+ resource = self._database.resource()
try:
- response = res.get_json()
- return (response[2]['generation'], response[2]['transaction_id'])
+ _, _, data = resource.get_json(**kwargs)
+ return data
except ResourceNotFound as e:
- raise_missing_design_doc_error(e, ddoc_path)
+ if check_missing_ddoc:
+ raise_missing_design_doc_error(e, ddoc_path)
+ else:
+ raise e
except ServerError as e:
raise_server_error(e, ddoc_path)
diff --git a/common/src/leap/soledad/common/document.py b/common/src/leap/soledad/common/document.py
index 20510544..9e0c0976 100644
--- a/common/src/leap/soledad/common/document.py
+++ b/common/src/leap/soledad/common/document.py
@@ -132,7 +132,6 @@ class ServerDocument(SoledadDocument):
:type has_conflicts: bool
"""
SoledadDocument.__init__(self, doc_id, rev, json, has_conflicts)
- self.transactions = None
self._conflicts = None
def get_conflicts(self):
diff --git a/server/src/leap/soledad/server/auth.py b/server/src/leap/soledad/server/auth.py
index 01baf1ce..ccbd6fbd 100644
--- a/server/src/leap/soledad/server/auth.py
+++ b/server/src/leap/soledad/server/auth.py
@@ -189,7 +189,6 @@ class SoledadAuthMiddleware(object):
@type prefix: str
"""
self._app = app
- self._state = app.state
def _error(self, start_response, status, description, message=None):
"""
@@ -350,6 +349,10 @@ 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 _verify_authentication_scheme(self, scheme):
"""
Verify if authentication scheme is valid.