diff --git a/EpisodesCommunity/settings.py b/EpisodesCommunity/settings.py index 8b9743e..6dd7465 100644 --- a/EpisodesCommunity/settings.py +++ b/EpisodesCommunity/settings.py @@ -42,6 +42,11 @@ ALLOWED_HOSTS = [] # Application definition +AUTHENTICATION_BACKENDS = ( + 'LandingPage.backends.OAuthBackend', + 'django.contrib.auth.backends.ModelBackend', +) + INSTALLED_APPS = [ 'LandingPage.apps.LandingpageConfig', 'Show.apps.ShowConfig', diff --git a/LandingPage/admin.py b/LandingPage/admin.py index 77fe1f1..5515ecf 100644 --- a/LandingPage/admin.py +++ b/LandingPage/admin.py @@ -3,7 +3,7 @@ from .models import * # Register your models here. admin.site.register(Show) -admin.site.register(User) +admin.site.register(ExternalUser) admin.site.register(Admin) admin.site.register(Ban) admin.site.register(ShowModerator) diff --git a/LandingPage/backends.py b/LandingPage/backends.py new file mode 100644 index 0000000..be13a4c --- /dev/null +++ b/LandingPage/backends.py @@ -0,0 +1,64 @@ +import requests +import hashlib +import json +import logging +from django.conf import settings +from django.contrib.auth import get_user_model +from django.contrib.auth.backends import ModelBackend +from .models import ExternalUser + +class OAuthBackend(ModelBackend): + def authenticate(self, code=None): + resp = requests.post( + settings.AUTH_TOKEN_ENDPOINT+"token", + data={ + 'grant_type':'authorization_code', + 'code':code, + 'redirect_uri':settings.AUTH_REDIRECT_URL, + 'client_id':settings.AUTH_CLIENT_ID + }, + headers = { + 'Authorization':'Basic %s'%settings.AUTH_B64 + } + ) + resp_json = resp.json() + if 'error' in resp_json: + logging.warn('OAuth server returned an error: %s'%json.dumps(resp_json)) + else: + user_info = requests.get( + settings.AUTH_TOKEN_ENDPOINT+"user", + headers = { + 'Authorization': 'Bearer ' + resp_json['access_token'] + } + ).json() + + usermodel = get_user_model() + matches = usermodel.objects.filter(externaluser__icy_id=user_info['uuid']) + match = None + + if not len(matches): + user = usermodel.objects.create_user( + username = user_info['username'], + email = user_info['email'], + ) + + if 'privilege' in user_info: + priv = user_info['privilege'] + user.is_superuser = (priv == 5) + user.is_staff = (priv > 0) + + user.save() + user.externaluser = ExternalUser( + user = user, + icy_id = user_info['uuid'], + display_name = user_info['display_name'] + ) + user.externaluser.save() + match = user + else: + match = matches[0] + + match.access_token = resp_json['access_token'] + + return match + return None diff --git a/LandingPage/models.py b/LandingPage/models.py index e03a920..309acf8 100644 --- a/LandingPage/models.py +++ b/LandingPage/models.py @@ -1,4 +1,5 @@ from django.db import models +from django.contrib.auth.models import User from django.core.files.storage import FileSystemStorage from django.conf import settings import os @@ -71,14 +72,17 @@ class Show(TimestampedModel): def __str__(self): return '%s [%s]'%(self.name,self.abbr) -class User(TimestampedModel): - user_id = models.CharField( +class ExternalUser(TimestampedModel): + user = models.OneToOneField( + User, + on_delete=models.CASCADE, + help_text='The internal Django user', + verbose_name="User" + ) + icy_id = models.CharField( max_length=36, help_text='The UUID assigned to this user by IcyNet\'s auth servers' ) - email = models.EmailField( - help_text='This user\'s email address' - ) display_name=models.CharField( max_length=20, help_text="The name shown to other users", @@ -95,7 +99,7 @@ class User(TimestampedModel): through='Watch' ) def __str__(self): - return self.email + return 'External for %s (%s)'%(self.user.email, self.display_name) class Admin(User): pass @@ -285,7 +289,7 @@ class Submission(TimestampedModel): verbose_name='Submitted For' ) user = models.ForeignKey( - 'User', + User, on_delete=models.SET_NULL, null=True, related_name='submissions', @@ -309,7 +313,7 @@ class SubmissionVote(TimestampedModel): help_text='What this submission was cast on' ) user = models.ForeignKey( - 'User', + User, on_delete=models.CASCADE, related_name='votes', help_text='The user who cast this vote' @@ -322,7 +326,7 @@ class SubmissionVote(TimestampedModel): class Favorite(TimestampedModel): user = models.ForeignKey( - User, + ExternalUser, on_delete=models.CASCADE ) episode = models.ForeignKey( @@ -334,7 +338,7 @@ class Favorite(TimestampedModel): class Watch(TimestampedModel): user = models.ForeignKey( - User, + ExternalUser, on_delete=models.CASCADE ) episode = models.ForeignKey( diff --git a/LandingPage/templates/base.html b/LandingPage/templates/base.html index 9d3499a..d729237 100644 --- a/LandingPage/templates/base.html +++ b/LandingPage/templates/base.html @@ -20,8 +20,8 @@