summaryrefslogtreecommitdiff
path: root/src/leap/soledad/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/soledad/server.py')
-rw-r--r--src/leap/soledad/server.py107
1 files changed, 101 insertions, 6 deletions
diff --git a/src/leap/soledad/server.py b/src/leap/soledad/server.py
index 159f4768..53bb62f0 100644
--- a/src/leap/soledad/server.py
+++ b/src/leap/soledad/server.py
@@ -1,25 +1,41 @@
# -*- coding: utf-8 -*-
+# server.py
+# Copyright (C) 2013 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
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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 U1DB server that stores data using couchdb.
+A U1DB server that stores data using CouchDB as its persistence layer.
This should be run with:
twistd -n web --wsgi=leap.soledad.server.application
"""
import configparser
-from wsgiref.util import shift_path_info
import httplib
try:
import simplejson as json
except ImportError:
import json # noqa
-from urlparse import parse_qs
+
+from urlparse import parse_qs
+from wsgiref.util import shift_path_info
from twisted.web.wsgi import WSGIResource
from twisted.internet import reactor
-
from u1db.remote import http_app
-
from leap.soledad.backends.couch import CouchServerState
@@ -42,11 +58,41 @@ class SoledadAuthMiddleware(object):
"""
def __init__(self, app, prefix, public_dbs=None):
+ """
+ Initialize the Soledad Authentication Middleware.
+
+ @param app: The application to run on successfull authentication.
+ @type app: u1db.remote.http_app.HTTPApp
+ @param prefix: Auth app path prefix.
+ @type prefix: str
+ @param public_dbs: List of databases that should bypass
+ authentication.
+ @type public_dbs: list
+ """
self.app = app
self.prefix = prefix
self.public_dbs = public_dbs
def _error(self, start_response, status, description, message=None):
+ """
+ Send a JSON serialized error to WSGI client.
+
+ @param start_response: Callable of the form start_response(status,
+ response_headers, exc_info=None).
+ @type start_response: callable
+ @param status: Status string of the form "999 Message here"
+ @type status: str
+ @param response_headers: A list of (header_name, header_value) tuples
+ describing the HTTP response header.
+ @type response_headers: list
+ @param description: The error description.
+ @type description: str
+ @param message: The error message.
+ @type message: str
+
+ @return: List with JSON serialized error message.
+ @rtype list
+ """
start_response("%d %s" % (status, httplib.responses[status]),
[('content-type', 'application/json')])
err = {"error": description}
@@ -55,6 +101,19 @@ class SoledadAuthMiddleware(object):
return [json.dumps(err)]
def __call__(self, environ, start_response):
+ """
+ Handle a WSGI call to the authentication application.
+
+ @param environ: Dictionary containing CGI variables.
+ @type environ: dict
+ @param start_response: Callable of the form start_response(status,
+ response_headers, exc_info=None).
+ @type start_response: callable
+
+ @return: Target application results if authentication succeeds, an
+ error message otherwise.
+ @rtype: list
+ """
if self.prefix and not environ['PATH_INFO'].startswith(self.prefix):
return self._error(start_response, 400, "bad request")
shift_path_info(environ)
@@ -83,7 +142,15 @@ class SoledadAuthMiddleware(object):
def verify_token(self, environ, token):
"""
- Verify if token is valid for authenticating this action.
+ Verify if token is valid for authenticating this request.
+
+ @param environ: Dictionary containing CGI variables.
+ @type environ: dict
+ @param token: The authentication token.
+ @type token: str
+
+ @return: Whether the token is valid for authenticating the request.
+ @rtype: bool
"""
# TODO: implement token verification
return True
@@ -94,8 +161,15 @@ class SoledadAuthMiddleware(object):
Check if action can be performed on database without authentication.
For now, just allow access to /shared/*.
+
+ @param environ: Dictionary containing CGI variables.
+ @type environ: dict
+
+ @return: Whether the requests needs authentication.
+ @rtype: bool
"""
# TODO: design unauth verification.
+ # TODO: include public_dbs here or remove it from code.
return not environ.get('PATH_INFO').startswith('/shared/')
@@ -109,6 +183,18 @@ class SoledadApp(http_app.HTTPApp):
"""
def __call__(self, environ, start_response):
+ """
+ Handle a WSGI call to the Soledad application.
+
+ @param environ: Dictionary containing CGI variables.
+ @type environ: dict
+ @param start_response: Callable of the form start_response(status,
+ response_headers, exc_info=None).
+ @type start_response: callable
+
+ @return: HTTP application results.
+ @rtype: list
+ """
return super(SoledadApp, self).__call__(environ, start_response)
@@ -117,6 +203,15 @@ class SoledadApp(http_app.HTTPApp):
#-----------------------------------------------------------------------------
def load_configuration(file_path):
+ """
+ Load server configuration from file.
+
+ @param file_path: The path to the configuration file.
+ @type file_path: str
+
+ @return: A dictionary with the configuration.
+ @rtype: dict
+ """
conf = {
'couch_url': 'http://localhost:5984',
'working_dir': '/tmp',