From: Antony Chazapis Date: Mon, 20 Feb 2012 11:31:00 +0000 (+0200) Subject: Move authentication logic to lib. X-Git-Tag: pithos/v0.9.0~2^2~3 X-Git-Url: https://code.grnet.gr/git/pithos/commitdiff_plain/cf441bae216107c768509c5b573e395118f4adb1 Move authentication logic to lib. Requires changes in settings. Fixes #2070 --- diff --git a/pithos/api/functions.py b/pithos/api/functions.py index 596c4ae..d90d5c9 100644 --- a/pithos/api/functions.py +++ b/pithos/api/functions.py @@ -41,6 +41,7 @@ from django.utils.http import parse_etags from django.utils.encoding import smart_str from django.views.decorators.csrf import csrf_exempt +from pithos.lib.user import get_user from pithos.lib.filter import parse_filters from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, Forbidden, ItemNotFound, Conflict, @@ -52,6 +53,7 @@ from pithos.api.util import (json_encode_decimal, rename_meta_key, format_header copy_or_move_object, get_int_parameter, get_content_length, get_content_range, socket_read_iterator, SaveToBackendHandler, object_data_response, put_object_block, hashmap_md5, simple_list_response, api_method) from pithos.backends.base import NotAllowedError, QuotaError +from pithos.api.settings import AUTHENTICATION_URL, AUTHENTICATION_USERS import logging import hashlib @@ -62,6 +64,7 @@ logger = logging.getLogger(__name__) @csrf_exempt def top_demux(request): + get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS) if request.method == 'GET': if getattr(request, 'user', None) is not None: return account_list(request) @@ -71,6 +74,7 @@ def top_demux(request): @csrf_exempt def account_demux(request, v_account): + get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS) if request.method == 'HEAD': return account_meta(request, v_account) elif request.method == 'POST': @@ -82,6 +86,7 @@ def account_demux(request, v_account): @csrf_exempt def container_demux(request, v_account, v_container): + get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS) if request.method == 'HEAD': return container_meta(request, v_account, v_container) elif request.method == 'PUT': @@ -97,6 +102,7 @@ def container_demux(request, v_account, v_container): @csrf_exempt def object_demux(request, v_account, v_container, v_object): + get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS) if request.method == 'HEAD': return object_meta(request, v_account, v_container, v_object) elif request.method == 'GET': diff --git a/pithos/api/public.py b/pithos/api/public.py index 64c13cf..49c32fb 100644 --- a/pithos/api/public.py +++ b/pithos/api/public.py @@ -36,11 +36,14 @@ import logging from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt +from pithos.lib.user import get_user + from pithos.api.faults import (Fault, BadRequest, ItemNotFound) from pithos.api.util import (put_object_headers, update_manifest_meta, validate_modification_preconditions, validate_matching_preconditions, object_data_response, api_method) from pithos.api.short_url import decode_url +from pithos.api.settings import AUTHENTICATION_URL, AUTHENTICATION_USERS logger = logging.getLogger(__name__) @@ -48,6 +51,7 @@ logger = logging.getLogger(__name__) @csrf_exempt def public_demux(request, v_public): + get_user(request, AUTHENTICATION_URL, AUTHENTICATION_USERS) if request.method == 'HEAD': return public_meta(request, v_public) elif request.method == 'GET': diff --git a/pithos/api/settings.py b/pithos/api/settings.py index 3bd47e1..16e5575 100644 --- a/pithos/api/settings.py +++ b/pithos/api/settings.py @@ -1,8 +1,26 @@ +#coding=utf8 from django.conf import settings from os.path import abspath, dirname, join PROJECT_PATH = getattr(settings, 'PROJECT_PATH', dirname(dirname(abspath(__file__)))) +# Set local users, or a remote host. To disable local users set them to None. +sample_users = { + '0000': 'test', + '0001': 'verigak', + '0002': 'chazapis', + '0003': 'gtsouk', + '0004': 'papagian', + '0005': 'louridas', + '0006': 'chstath', + '0007': 'pkanavos', + '0008': 'mvasilak', + '0009': 'διογένης' +} + +AUTHENTICATION_URL = getattr(settings, 'PITHOS_AUTHENTICATION_URL', 'http://127.0.0.1:8000/im/authenticate') +AUTHENTICATION_USERS = getattr(settings, 'PITHOS_AUTHENTICATION_USERS', sample_users) + # SQLAlchemy (choose SQLite/MySQL/PostgreSQL). BACKEND_DB_MODULE = getattr(settings, 'PITHOS_BACKEND_DB_MODULE', 'pithos.backends.lib.sqlalchemy') BACKEND_DB_CONNECTION = getattr(settings, 'PITHOS_BACKEND_DB_CONNECTION', 'sqlite:///' + join(PROJECT_PATH, 'backend.db')) diff --git a/pithos/middleware/user.py b/pithos/lib/user.py similarity index 65% rename from pithos/middleware/user.py rename to pithos/lib/user.py index d334648..e511bce 100644 --- a/pithos/middleware/user.py +++ b/pithos/lib/user.py @@ -32,23 +32,30 @@ # or implied, of GRNET S.A. from time import time, mktime -from httplib import HTTPConnection +from urlparse import urlparse +from httplib import HTTPConnection, HTTPSConnection from urllib import quote, unquote from django.conf import settings from django.utils import simplejson as json -def authenticate(authentication_host, token): - con = HTTPConnection(authentication_host) +def authenticate(token, authentication_url='http://127.0.0.1:8000/im/authenticate'): + p = urlparse(authentication_url) + if p.scheme == 'http': + conn = HTTPConnection(p.netloc) + elif p.scheme == 'https': + conn = HTTPSConnection(p.netloc) + else: + raise Exception('Unknown URL scheme') + kwargs = {} kwargs['headers'] = {} kwargs['headers']['X-Auth-Token'] = token kwargs['headers']['Content-Length'] = 0 - path = '/im/authenticate' - con.request('GET', path, **kwargs) - response = con.getresponse() + conn.request('GET', p.path, **kwargs) + response = conn.getresponse() headers = response.getheaders() headers = dict((unquote(h), unquote(v)) for h,v in headers) @@ -61,34 +68,31 @@ def authenticate(authentication_host, token): return json.loads(data) -def get_user_from_token(token): +def user_for_token(token, authentication_url, override_users): if not token: return None - users = settings.AUTHENTICATION_USERS - if users is not None: + if override_users: try: - return {'id': 0, 'uniq': users[token].decode('utf8')} + return {'uniq': override_users[token].decode('utf8')} except: return None - host = settings.AUTHENTICATION_HOST try: - return authenticate(host, token) + return authenticate(token, authentication_url) except: return None -class UserMiddleware(object): - def process_request(self, request): - request.user = None - request.user_uniq = None - - # Try to find token in a parameter, in a request header, or in a cookie. - user = get_user_from_token(request.GET.get('X-Auth-Token')) - if not user: - user = get_user_from_token(request.META.get('HTTP_X_AUTH_TOKEN')) - if not user: - return - - request.user = user - request.user_uniq = user['uniq'] +def get_user(request, authentication_url='http://127.0.0.1:8000/im/authenticate', override_users={}): + request.user = None + request.user_uniq = None + + # Try to find token in a parameter or in a request header. + user = user_for_token(request.GET.get('X-Auth-Token'), authentication_url, override_users) + if not user: + user = user_for_token(request.META.get('HTTP_X_AUTH_TOKEN'), authentication_url, override_users) + if not user: + return + + request.user = user + request.user_uniq = user['uniq'] diff --git a/pithos/settings.py b/pithos/settings.py index 07e94e1..328eb7a 100644 --- a/pithos/settings.py +++ b/pithos/settings.py @@ -72,8 +72,7 @@ MIDDLEWARE_CLASSES = ( #'django.contrib.auth.middleware.AuthenticationMiddleware', #'django.contrib.messages.middleware.MessageMiddleware', 'pithos.middleware.LoggingConfigMiddleware', - 'pithos.middleware.SecureMiddleware', - 'pithos.middleware.UserMiddleware' + 'pithos.middleware.SecureMiddleware' ) ROOT_URLCONF = 'pithos.urls' @@ -123,24 +122,6 @@ USE_X_FORWARDED_HOST = False # Set umask (needed for gunicorn setup). #umask(0077) -# Either set local users here, or a remote host. -# To disable local users set to None. -AUTHENTICATION_USERS = { - '0000': 'test', - '0001': 'verigak', - '0002': 'chazapis', - '0003': 'gtsouk', - '0004': 'papagian', - '0005': 'louridas', - '0006': 'chstath', - '0007': 'pkanavos', - '0008': 'mvasilak', - '0009': 'διογένης' -} - -# Where astakos is hosted. -AUTHENTICATION_HOST = '127.0.0.1:10000' - conf = join(PROJECT_PATH, 'settings.local') if exists(conf): execfile(conf)