diff options
Diffstat (limited to 'src/leap/soledad/server.py')
-rw-r--r-- | src/leap/soledad/server.py | 107 |
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', |