Skip to content

Commit

Permalink
Auth staff only (#60)
Browse files Browse the repository at this point in the history
* Only allow staff to log in

* Management command to kill all login sessions

* Remove useless import
  • Loading branch information
mgax authored and gabriel-v committed Jul 24, 2019
1 parent 49f391c commit 1964390
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 15 deletions.
49 changes: 49 additions & 0 deletions liquidcore/home/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import json
import base64
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.contrib.sessions.models import Session
from oauth2_provider.models import RefreshToken, AccessToken

staff_only = settings.AUTH_STAFF_ONLY


class AuthBackend(ModelBackend):

def user_can_authenticate(self, user):
if staff_only and not user.is_staff:
return False

return super().user_can_authenticate(user)


def kill_sessions(user=None):
"""
Delete oauth2 access and refresh tokens, for `user` if specified, or for
everybody if `user == None`.
"""

if user:
# for the user
access_tokens = user.oauth2_provider_accesstoken.all()
refresh_tokens = user.oauth2_provider_refreshtoken.all()
else:
# for everybody
access_tokens = AccessToken.objects.all()
refresh_tokens = RefreshToken.objects.all()

access_tokens.delete()
refresh_tokens.delete()

# delete all Django sessions
if user:
# for the user
for session in Session.objects.all().iterator():
session_data = base64.b64decode(session.session_data)
session_json = session_data.split(b':', 1)[1]
user_id = json.loads(session_json).get('_auth_user_id')
if user_id and int(user_id) == user.id:
session.delete()
else:
# for everybody
Session.objects.all().delete()
10 changes: 10 additions & 0 deletions liquidcore/home/management/commands/killsessions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.core.management.base import BaseCommand
from ...auth import kill_sessions


class Command(BaseCommand):

help = "Log out all users"

def handle(self, **options):
kill_sessions()
17 changes: 3 additions & 14 deletions liquidcore/home/signals.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
import json
import base64
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_out
from django.contrib.sessions.models import Session
from .auth import kill_sessions


@receiver(user_logged_out)
def kill_sessions(user, **kwargs):
# delete oauth2 access and refresh tokens for the user
user.oauth2_provider_accesstoken.all().delete()
user.oauth2_provider_refreshtoken.all().delete()

# delete all Django sessions for the user
for session in Session.objects.all().iterator():
session_json = base64.b64decode(session.session_data).split(b':', 1)[1]
user_id = json.loads(session_json).get('_auth_user_id')
if user_id and int(user_id) == user.id:
session.delete()
def kill_user_sessions(user, **kwargs):
kill_sessions(user=user)
4 changes: 3 additions & 1 deletion liquidcore/site/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ def bool_env(value):
'whitenoise.middleware.WhiteNoiseMiddleware',
]

AUTH_STAFF_ONLY = bool_env(os.environ.get('AUTH_STAFF_ONLY'))

if LIQUID_2FA:
INSTALLED_APPS += [
'liquidcore.twofactor',
Expand All @@ -67,7 +69,7 @@ def bool_env(value):

AUTHENTICATION_BACKENDS = [
'oauth2_provider.backends.OAuth2Backend',
'django.contrib.auth.backends.ModelBackend'
'liquidcore.home.auth.AuthBackend',
]

ROOT_URLCONF = 'liquidcore.site.urls'
Expand Down

0 comments on commit 1964390

Please sign in to comment.