Move authentication logic to lib.
authorAntony Chazapis <chazapis@gmail.com>
Mon, 20 Feb 2012 11:31:00 +0000 (13:31 +0200)
committerAntony Chazapis <chazapis@gmail.com>
Mon, 20 Feb 2012 11:31:00 +0000 (13:31 +0200)
Requires changes in settings.

Fixes #2070

pithos/api/functions.py
pithos/api/public.py
pithos/api/settings.py
pithos/lib/user.py [moved from pithos/middleware/user.py with 65% similarity]
pithos/settings.py

index 596c4ae..d90d5c9 100644 (file)
@@ -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':
index 64c13cf..49c32fb 100644 (file)
@@ -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':
index 3bd47e1..16e5575 100644 (file)
@@ -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'))
similarity index 65%
rename from pithos/middleware/user.py
rename to pithos/lib/user.py
index d334648..e511bce 100644 (file)
 # 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']
index 07e94e1..328eb7a 100644 (file)
@@ -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)