Commit cb427290 authored by sim's avatar sim

Implement PostgREST-like authentication at database level

parent b22a0ce6
import logging
from django.contrib.auth.models import AnonymousUser
from rest_framework.authentication import BaseAuthentication as BA
from rest_framework.authentication import SessionAuthentication as SA
from rest_framework_jwt.authentication import JSONWebTokenAuthentication as JA
logger = logging.getLogger(__name__)
class UserAuthMixin(object):
def authenticate(self, request):
result = super().authenticate(request)
if result is None:
return
user, token = result
logger.debug("%s: authenticate as %s",
self.__class__.__name__, user.username or '<anon>')
# Authenticate user in database session
request.db.login(user)
return (user, token)
class AnonymousAuthenticationBase(BA):
def authenticate(self, request):
return AnonymousUser(), None
class JWTAuthentication(UserAuthMixin, JA): pass
class SessionAuthentication(UserAuthMixin, SA): pass
class AnonymousAuthentication(UserAuthMixin, AnonymousAuthenticationBase): pass
...@@ -31,3 +31,10 @@ def jwt_payload_handler(user): ...@@ -31,3 +31,10 @@ def jwt_payload_handler(user):
return payload return payload
def jwt_get_user_id_from_payload_handler(payload):
return payload.get('user_id')
def jwt_get_username_from_payload_handler(payload):
return payload.get('sub')
import logging
from gargantext.core.db import Session
logger = logging.getLogger('gargantext')
class DatabaseSessionMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
logger.debug('---8<----- DatabaseSession: start ----------')
# Create database session and attach it to the current request instance
session = request.db = Session()
# Render view: if any exception occurs while doing this, it will be
# handled by django rest framework, so we don't need to care about
# exceptions here.
response = self.get_response(request)
# Commit to database if no error happened
if not session.is_rollbacked:
session.commit()
# Finally, close the session
session.close()
logger.debug('---------- DatabaseSession: end ------->8---')
return response
...@@ -53,6 +53,7 @@ MIDDLEWARE = [ ...@@ -53,6 +53,7 @@ MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'gargantext.backend.middleware.DatabaseSessionMiddleware',
] ]
ROOT_URLCONF = 'gargantext.backend.urls' ROOT_URLCONF = 'gargantext.backend.urls'
...@@ -220,22 +221,27 @@ CELERY_IMPORTS = () ...@@ -220,22 +221,27 @@ CELERY_IMPORTS = ()
# See http://getblimp.github.io/django-rest-framework-jwt/#additional-settings # See http://getblimp.github.io/django-rest-framework-jwt/#additional-settings
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ( 'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated', 'rest_framework.permissions.AllowAny',
), ),
'DEFAULT_AUTHENTICATION_CLASSES': ( 'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'gargantext.backend.authentication.SessionAuthentication',
'rest_framework.authentication.SessionAuthentication', 'gargantext.backend.authentication.JWTAuthentication',
'rest_framework.authentication.BasicAuthentication', 'gargantext.backend.authentication.AnonymousAuthentication',
), ),
} }
# See http://getblimp.github.io/django-rest-framework-jwt/ # See http://getblimp.github.io/django-rest-framework-jwt/
JWT_AUTH = { JWT_AUTH = {
'JWT_PAYLOAD_HANDLER': 'gargantext.backend.jwt.jwt_payload_handler', 'JWT_PAYLOAD_HANDLER': 'gargantext.backend.jwt.jwt_payload_handler',
'JWT_PAYLOAD_GET_USER_ID_HANDLER':
'gargantext.backend.jwt.jwt_get_user_id_from_payload_handler',
'JWT_PAYLOAD_GET_USERNAME_HANDLER':
'gargantext.backend.jwt.jwt_get_username_from_payload_handler',
'JWT_VERIFY_EXPIRATION': True, 'JWT_VERIFY_EXPIRATION': True,
'JWT_SECRET_KEY': config('SECRET_KEY'), 'JWT_SECRET_KEY': config('SECRET_KEY'),
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=36000), 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=36000),
'JWT_AUTH_HEADER_PREFIX': 'Bearer', 'JWT_AUTH_HEADER_PREFIX': 'Bearer',
'JWT_AUTH_COOKIE': 'JWT' if DEBUG else None,
} }
ROLE_SUPERUSER = 'gargantua' ROLE_SUPERUSER = 'gargantua'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment