106 lines
4.0 KiB
Python
106 lines
4.0 KiB
Python
from django.shortcuts import render
|
|
from django.views import View
|
|
from django.views.generic.base import TemplateView
|
|
from django.conf import settings
|
|
from django.http import HttpResponse
|
|
from django.http import HttpResponseRedirect
|
|
from django.db.models import Max
|
|
import requests
|
|
import hashlib
|
|
import json
|
|
from .models import User
|
|
from .models import Show
|
|
from .models import Submission
|
|
from .models import DiscussionBoard
|
|
|
|
# Create your views here.
|
|
# Redirect url should point to this view
|
|
class LoginRedirect(View):
|
|
def get(self, req):
|
|
|
|
# Check request has correct arguments
|
|
request_valid = 'state' in req.GET and 'code' in req.GET
|
|
if not request_valid:
|
|
r = HttpResponse('<h1>Error</h1><p>There was an error in your request. Please <a href=/login>try again</a></p>')
|
|
r.status = 400
|
|
return r
|
|
|
|
# Check state
|
|
userstate = generateState(req)
|
|
if userstate == req.GET['state']:
|
|
code = req.GET['code']
|
|
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:
|
|
r = HttpResponse('<h1>OAuth Error</h1><pre>%s</pre>'%json.dumps(resp_json))
|
|
r.status = 500
|
|
return r
|
|
else:
|
|
user_info = requests.get(
|
|
settings.AUTH_TOKEN_ENDPOINT+"user",
|
|
headers = {
|
|
'Authorization': 'Bearer ' + resp_json['access_token']
|
|
}
|
|
).json()
|
|
req.session['user_id'] = user_info['uuid']
|
|
matches = User.objects.filter(user_id=user_info['uuid'])
|
|
match = None
|
|
if not len(matches):
|
|
user = User(
|
|
user_id = user_info['uuid'],
|
|
email = user_info['email'],
|
|
display_name = user_info['display_name']
|
|
)
|
|
user.save()
|
|
match = user
|
|
else:
|
|
match = matches[0]
|
|
req.session['token'] = resp_json['access_token']
|
|
req.session['disp_name'] = match.display_name
|
|
return HttpResponseRedirect('/')
|
|
else:
|
|
return HttpResponse('<h1>Unmatching state tokens</h1><br><p>It looks like the request to login wasn\'t started by you. Try going back to the home page and logging in again.</p>', status=400)
|
|
|
|
class Login(View):
|
|
def get(self, req):
|
|
url = '%sauthorize?response_type=code&client_id=%s&redirect_uri=%s&scope=email&state=%s'%(settings.AUTH_TOKEN_ENDPOINT,settings.AUTH_CLIENT_ID,settings.AUTH_REDIRECT_URL, generateState(req))
|
|
response = HttpResponse("Redirecting you to the IcyNet auth page...")
|
|
response.status_code = 302
|
|
response['Location'] = url
|
|
return response
|
|
|
|
def generateState(request):
|
|
request.session.save()
|
|
|
|
m = hashlib.sha256()
|
|
m.update(bytearray(request.session.session_key, 'utf-8'))
|
|
m.update(bytearray(settings.SECRET_KEY, 'utf-8'))
|
|
return m.hexdigest()
|
|
|
|
class LandingPage(TemplateView):
|
|
|
|
template_name = "landing_page.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data()
|
|
ctx['recent'] = Show.objects.annotate(recency=Max('episodes__airdate')).order_by('-recency')[:8]
|
|
ctx['stats'] = {
|
|
'shows': Show.objects.count(),
|
|
'episodes': Submission.objects.count(),
|
|
'boards': DiscussionBoard.objects.count()
|
|
}
|
|
return ctx
|
|
|
|
|