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):
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 = [
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'gargantext.backend.middleware.DatabaseSessionMiddleware',
]
ROOT_URLCONF = 'gargantext.backend.urls'
......@@ -220,22 +221,27 @@ CELERY_IMPORTS = ()
# See http://getblimp.github.io/django-rest-framework-jwt/#additional-settings
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.AllowAny',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
'gargantext.backend.authentication.SessionAuthentication',
'gargantext.backend.authentication.JWTAuthentication',
'gargantext.backend.authentication.AnonymousAuthentication',
),
}
# See http://getblimp.github.io/django-rest-framework-jwt/
JWT_AUTH = {
'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_SECRET_KEY': config('SECRET_KEY'),
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=36000),
'JWT_AUTH_HEADER_PREFIX': 'Bearer',
'JWT_AUTH_COOKIE': 'JWT' if DEBUG else None,
}
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