Import latest auth.py from pgeu as sample

This commit is contained in:
Magnus Hagander
2019-01-19 20:00:35 +01:00
parent a156829375
commit 9b42500478

View File

@ -28,8 +28,8 @@ from django.conf import settings
import base64 import base64
import json import json
import socket import socket
import urlparse from urllib.parse import urlparse, urlencode, parse_qs
import urllib import requests
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Hash import SHA from Crypto.Hash import SHA
from Crypto import Random from Crypto import Random
@ -49,26 +49,21 @@ class AuthBackend(ModelBackend):
# Handle login requests by sending them off to the main site # Handle login requests by sending them off to the main site
def login(request): def login(request):
if not hasattr(settings, 'PGAUTH_REDIRECT'):
# No pgauth installed, so allow local installs.
from django.contrib.auth.views import login
return login(request, template_name='admin.html')
if 'next' in request.GET: if 'next' in request.GET:
# Put together an url-encoded dict of parameters we're getting back, # Put together an url-encoded dict of parameters we're getting back,
# including a small nonce at the beginning to make sure it doesn't # including a small nonce at the beginning to make sure it doesn't
# encrypt the same way every time. # encrypt the same way every time.
s = "t=%s&%s" % (int(time.time()), urllib.urlencode({'r': request.GET['next']})) s = "t=%s&%s" % (int(time.time()), urlencode({'r': request.GET['next']}))
# Now encrypt it # Now encrypt it
r = Random.new() r = Random.new()
iv = r.read(16) iv = r.read(16)
encryptor = AES.new(SHA.new(settings.SECRET_KEY).digest()[:16], AES.MODE_CBC, iv) encryptor = AES.new(SHA.new(settings.SECRET_KEY.encode('ascii')).digest()[:16], AES.MODE_CBC, iv)
cipher = encryptor.encrypt(s + ' ' * (16 - (len(s) % 16))) # pad to 16 bytes cipher = encryptor.encrypt(s + ' ' * (16 - (len(s) % 16))) # pad to 16 bytes
return HttpResponseRedirect("%s?d=%s$%s" % ( return HttpResponseRedirect("%s?d=%s$%s" % (
settings.PGAUTH_REDIRECT, settings.PGAUTH_REDIRECT,
base64.b64encode(iv, "-_"), base64.b64encode(iv, b"-_").decode('utf8'),
base64.b64encode(cipher, "-_"), base64.b64encode(cipher, b"-_").decode('utf8'),
)) ))
else: else:
return HttpResponseRedirect(settings.PGAUTH_REDIRECT) return HttpResponseRedirect(settings.PGAUTH_REDIRECT)
@ -89,7 +84,7 @@ def auth_receive(request):
# This was a logout request # This was a logout request
return HttpResponseRedirect('/') return HttpResponseRedirect('/')
if 'i' not in request: if 'i' not in request.GET:
return HttpResponse("Missing IV in url!", status=400) return HttpResponse("Missing IV in url!", status=400)
if 'd' not in request.GET: if 'd' not in request.GET:
return HttpResponse("Missing data in url!", status=400) return HttpResponse("Missing data in url!", status=400)
@ -98,11 +93,11 @@ def auth_receive(request):
decryptor = AES.new(base64.b64decode(settings.PGAUTH_KEY), decryptor = AES.new(base64.b64decode(settings.PGAUTH_KEY),
AES.MODE_CBC, AES.MODE_CBC,
base64.b64decode(str(request.GET['i']), "-_")) base64.b64decode(str(request.GET['i']), "-_"))
s = decryptor.decrypt(base64.b64decode(str(request.GET['d']), "-_")).rstrip(' ') s = decryptor.decrypt(base64.b64decode(str(request.GET['d']), "-_")).rstrip(b' ').decode('utf8')
# Now un-urlencode it # Now un-urlencode it
try: try:
data = urlparse.parse_qs(s, strict_parsing=True) data = parse_qs(s, strict_parsing=True)
except ValueError: except ValueError:
return HttpResponse("Invalid encrypted data received.", status=400) return HttpResponse("Invalid encrypted data received.", status=400)
@ -145,18 +140,6 @@ for you.
We apologize for the inconvenience. We apologize for the inconvenience.
""" % (data['e'][0], data['u'][0]), content_type='text/plain') """ % (data['e'][0], data['u'][0]), content_type='text/plain')
if hasattr(settings, 'PGAUTH_CREATEUSER_CALLBACK'):
res = getattr(settings, 'PGAUTH_CREATEUSER_CALLBACK')(
data['u'][0],
data['e'][0],
['f'][0],
data['l'][0],
)
# If anything is returned, we'll return that as our result.
# If None is returned, it means go ahead and create the user.
if res:
return res
user = User(username=data['u'][0], user = User(username=data['u'][0],
first_name=data['f'][0], first_name=data['f'][0],
last_name=data['l'][0], last_name=data['l'][0],
@ -175,12 +158,12 @@ We apologize for the inconvenience.
# redirect the user. # redirect the user.
if 'd' in data: if 'd' in data:
(ivs, datas) = data['d'][0].split('$') (ivs, datas) = data['d'][0].split('$')
decryptor = AES.new(SHA.new(settings.SECRET_KEY).digest()[:16], decryptor = AES.new(SHA.new(settings.SECRET_KEY.encode('ascii')).digest()[:16],
AES.MODE_CBC, AES.MODE_CBC,
base64.b64decode(ivs, "-_")) base64.b64decode(ivs, b"-_"))
s = decryptor.decrypt(base64.b64decode(datas, "-_")).rstrip(' ') s = decryptor.decrypt(base64.b64decode(datas, "-_")).rstrip(b' ').decode('utf8')
try: try:
rdata = urlparse.parse_qs(s, strict_parsing=True) rdata = parse_qs(s, strict_parsing=True)
except ValueError: except ValueError:
return HttpResponse("Invalid encrypted data received.", status=400) return HttpResponse("Invalid encrypted data received.", status=400)
if 'r' in rdata: if 'r' in rdata:
@ -200,7 +183,7 @@ We apologize for the inconvenience.
# Unlike the authentication, searching does not involve the browser - we just make # Unlike the authentication, searching does not involve the browser - we just make
# a direct http call. # a direct http call.
def user_search(searchterm=None, userid=None): def user_search(searchterm=None, userid=None):
# If upstream isn't responding quickly, it's not going to respond at all, and # If upsteam isn't responding quickly, it's not going to respond at all, and
# 10 seconds is already quite long. # 10 seconds is already quite long.
socket.setdefaulttimeout(10) socket.setdefaulttimeout(10)
if userid: if userid:
@ -208,18 +191,20 @@ def user_search(searchterm=None, userid=None):
else: else:
q = {'s': searchterm} q = {'s': searchterm}
u = urllib.urlopen('%ssearch/?%s' % ( r = requests.get(
settings.PGAUTH_REDIRECT, '{0}search/'.format(settings.PGAUTH_REDIRECT),
urllib.urlencode(q), params=q,
)) )
(ivs, datas) = u.read().split('&') if r.status_code != 200:
u.close() return []
(ivs, datas) = r.text.encode('utf8').split(b'&')
# Decryption time # Decryption time
decryptor = AES.new(base64.b64decode(settings.PGAUTH_KEY), decryptor = AES.new(base64.b64decode(settings.PGAUTH_KEY),
AES.MODE_CBC, AES.MODE_CBC,
base64.b64decode(ivs, "-_")) base64.b64decode(ivs, "-_"))
s = decryptor.decrypt(base64.b64decode(datas, "-_")).rstrip(' ') s = decryptor.decrypt(base64.b64decode(datas, "-_")).rstrip(b' ').decode('utf8')
j = json.loads(s) j = json.loads(s)
return j return j