summaryrefslogtreecommitdiff
path: root/shared_db.py
blob: c27bba7115b8672c736e059fe8d152d35ffe3d8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# -*- coding: utf-8 -*-
"""
Created on Tue Mar  5 18:46:38 2013

@author: drebs
"""

try:
    import simplejson as json
except ImportError:
    import json  # noqa

from u1db import errors
from u1db.remote import http_database


#-----------------------------------------------------------------------------
# Soledad shared database
#-----------------------------------------------------------------------------

class NoTokenForAuth(Exception):
    """
    No token was found for token-based authentication.
    """


class Unauthorized(Exception):
    """
    User does not have authorization to perform task.
    """


class SoledadSharedDatabase(http_database.HTTPDatabase):
    """
    This is a shared HTTP database that holds users' encrypted keys.

    An authorization token is attached to every request other than
    get_doc_unauth, which has the purpose of retrieving encrypted content from
    the shared database without the need to associate user information with
    the request.
    """
    # TODO: prevent client from messing with the shared DB.
    # TODO: define and document API.

    @staticmethod
    def open_database(url, create, token=None):
        """
        Open a Soledad shared database.
        """
        db = SoledadSharedDatabase(url, token=token)
        db.open(create)
        return db

    @staticmethod
    def delete_database(url):
        """
        Dummy method that prevents from deleting shared database.
        """
        raise Unauthorized("Can't delete shared database.")

    def __init__(self, url, document_factory=None, creds=None, token=None):
        """
        Initialize database with auth token and encryption powers.
        """
        self._token = token
        super(SoledadSharedDatabase, self).__init__(url, document_factory,
                                                    creds)

    def _request(self, method, url_parts, params=None, body=None,
                 content_type=None, auth=True):
        """
        Perform token-based http request.
        """
        # add the auth-token as a request parameter
        if auth:
            if not self._token:
                raise NoTokenForAuth()
            if not params:
                params = {}
            params['auth_token'] = self._token
        return super(SoledadSharedDatabase, self)._request(
            method, url_parts,
            params,
            body,
            content_type)

    def _request_json(self, method, url_parts, params=None, body=None,
                      content_type=None, auth=True):
        """
        Perform token-based http request.
        """
        # allow for token-authenticated requests.
        res, headers = self._request(method, url_parts,
                                     params=params, body=body,
                                     content_type=content_type, auth=auth)
        return json.loads(res), headers

    def get_doc_unauth(self, doc_id):
        """
        Modified method to allow for unauth request.
        """
        db = http_database.HTTPDatabase(self._url, factory=self._factory,
                                        creds=self._creds)
        return db.get_doc(doc_id)