Browse Source
Merge pull request #301 from CatalystCode/enhancement/auth-middleware
Added middleware that enables automatic login based on HTTP headers
pull/837/head
Hiroki Nakayama
4 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with
78 additions and
0 deletions
-
app/app/settings.py
-
app/server/middleware.py
-
app/server/tests/test_middleware.py
|
|
@ -147,6 +147,15 @@ AUTHENTICATION_BACKENDS = [ |
|
|
|
'django.contrib.auth.backends.ModelBackend', |
|
|
|
] |
|
|
|
|
|
|
|
HEADER_AUTH_USER_NAME = env('HEADER_AUTH_USER_NAME', '') |
|
|
|
HEADER_AUTH_USER_GROUPS = env('HEADER_AUTH_USER_GROUPS', '') |
|
|
|
HEADER_AUTH_ADMIN_GROUP_NAME = env('HEADER_AUTH_ADMIN_GROUP_NAME', '') |
|
|
|
HEADER_AUTH_GROUPS_SEPERATOR = env('HEADER_AUTH_GROUPS_SEPERATOR', default=',') |
|
|
|
|
|
|
|
if HEADER_AUTH_USER_NAME and HEADER_AUTH_USER_GROUPS and HEADER_AUTH_ADMIN_GROUP_NAME: |
|
|
|
MIDDLEWARE.append('server.middleware.HeaderAuthMiddleware') |
|
|
|
AUTHENTICATION_BACKENDS.append('django.contrib.auth.backends.RemoteUserBackend') |
|
|
|
|
|
|
|
SOCIAL_AUTH_GITHUB_KEY = env('OAUTH_GITHUB_KEY', None) |
|
|
|
SOCIAL_AUTH_GITHUB_SECRET = env('OAUTH_GITHUB_SECRET', None) |
|
|
|
GITHUB_ADMIN_ORG_NAME = env('GITHUB_ADMIN_ORG_NAME', None) |
|
|
|
|
|
@ -0,0 +1,42 @@ |
|
|
|
from django.conf import settings |
|
|
|
from django.contrib.auth.middleware import RemoteUserMiddleware |
|
|
|
|
|
|
|
|
|
|
|
def to_django_header(header): |
|
|
|
return f"HTTP_{header.replace('-', '_').upper()}" |
|
|
|
|
|
|
|
|
|
|
|
class HeaderAuthMiddleware(RemoteUserMiddleware): |
|
|
|
header = to_django_header(settings.HEADER_AUTH_USER_NAME) |
|
|
|
|
|
|
|
def process_request(self, request): |
|
|
|
if request.user.is_authenticated: |
|
|
|
return |
|
|
|
|
|
|
|
username = request.META.get(self.header) |
|
|
|
if not username: |
|
|
|
return |
|
|
|
|
|
|
|
super().process_request(request) |
|
|
|
self.process_user_groups(request.user, request.META) |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def process_user_groups(cls, user, headers): |
|
|
|
if not user.is_authenticated: |
|
|
|
return |
|
|
|
|
|
|
|
groups = cls.parse_user_groups_from_header(headers) |
|
|
|
|
|
|
|
is_superuser = settings.HEADER_AUTH_ADMIN_GROUP_NAME in groups |
|
|
|
if user.is_superuser != is_superuser: |
|
|
|
user.is_superuser = is_superuser |
|
|
|
user.save() |
|
|
|
|
|
|
|
@classmethod |
|
|
|
def parse_user_groups_from_header(cls, headers): |
|
|
|
try: |
|
|
|
groups_header = headers[to_django_header(settings.HEADER_AUTH_USER_GROUPS)] |
|
|
|
except KeyError: |
|
|
|
return [] |
|
|
|
else: |
|
|
|
return groups_header.split(settings.HEADER_AUTH_GROUPS_SEPERATOR) |
|
|
@ -0,0 +1,27 @@ |
|
|
|
from django.test import TestCase, override_settings |
|
|
|
from django.contrib.auth.models import User |
|
|
|
|
|
|
|
from ..middleware import HeaderAuthMiddleware |
|
|
|
|
|
|
|
|
|
|
|
@override_settings(HEADER_AUTH_USER_GROUPS='X-AuthProxy-Groups') |
|
|
|
@override_settings(HEADER_AUTH_ADMIN_GROUP_NAME='Admin') |
|
|
|
@override_settings(HEADER_AUTH_GROUPS_SEPERATOR=';') |
|
|
|
class HeaderAuthMiddlewareTest(TestCase): |
|
|
|
def test_process_user_groups_is_super(self): |
|
|
|
user = User.objects.create_user(username='TestUser') |
|
|
|
user.is_superuser = False |
|
|
|
|
|
|
|
middleware = HeaderAuthMiddleware() |
|
|
|
middleware.process_user_groups(user, {'HTTP_X_AUTHPROXY_GROUPS': 'Admin;Reader'}) |
|
|
|
|
|
|
|
self.assertTrue(user.is_superuser) |
|
|
|
|
|
|
|
def test_process_user_groups_is_not_super(self): |
|
|
|
user = User.objects.create_user(username='TestUser') |
|
|
|
user.is_superuser = True |
|
|
|
|
|
|
|
middleware = HeaderAuthMiddleware() |
|
|
|
middleware.process_user_groups(user, {'HTTP_X_AUTHPROXY_GROUPS': 'Guest;Reader'}) |
|
|
|
|
|
|
|
self.assertFalse(user.is_superuser) |