mirror of
https://github.com/postgres/pgweb.git
synced 2025-08-10 00:42:06 +00:00
Import latest auth.py from pgeu as sample
This commit is contained in:
@ -28,8 +28,8 @@ from django.conf import settings
|
||||
import base64
|
||||
import json
|
||||
import socket
|
||||
import urlparse
|
||||
import urllib
|
||||
from urllib.parse import urlparse, urlencode, parse_qs
|
||||
import requests
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Hash import SHA
|
||||
from Crypto import Random
|
||||
@ -49,26 +49,21 @@ class AuthBackend(ModelBackend):
|
||||
|
||||
# Handle login requests by sending them off to the main site
|
||||
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:
|
||||
# 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
|
||||
# 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
|
||||
r = Random.new()
|
||||
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
|
||||
|
||||
return HttpResponseRedirect("%s?d=%s$%s" % (
|
||||
settings.PGAUTH_REDIRECT,
|
||||
base64.b64encode(iv, "-_"),
|
||||
base64.b64encode(cipher, "-_"),
|
||||
base64.b64encode(iv, b"-_").decode('utf8'),
|
||||
base64.b64encode(cipher, b"-_").decode('utf8'),
|
||||
))
|
||||
else:
|
||||
return HttpResponseRedirect(settings.PGAUTH_REDIRECT)
|
||||
@ -89,7 +84,7 @@ def auth_receive(request):
|
||||
# This was a logout request
|
||||
return HttpResponseRedirect('/')
|
||||
|
||||
if 'i' not in request:
|
||||
if 'i' not in request.GET:
|
||||
return HttpResponse("Missing IV in url!", status=400)
|
||||
if 'd' not in request.GET:
|
||||
return HttpResponse("Missing data in url!", status=400)
|
||||
@ -98,11 +93,11 @@ def auth_receive(request):
|
||||
decryptor = AES.new(base64.b64decode(settings.PGAUTH_KEY),
|
||||
AES.MODE_CBC,
|
||||
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
|
||||
try:
|
||||
data = urlparse.parse_qs(s, strict_parsing=True)
|
||||
data = parse_qs(s, strict_parsing=True)
|
||||
except ValueError:
|
||||
return HttpResponse("Invalid encrypted data received.", status=400)
|
||||
|
||||
@ -145,18 +140,6 @@ for you.
|
||||
We apologize for the inconvenience.
|
||||
""" % (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],
|
||||
first_name=data['f'][0],
|
||||
last_name=data['l'][0],
|
||||
@ -175,12 +158,12 @@ We apologize for the inconvenience.
|
||||
# redirect the user.
|
||||
if 'd' in data:
|
||||
(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,
|
||||
base64.b64decode(ivs, "-_"))
|
||||
s = decryptor.decrypt(base64.b64decode(datas, "-_")).rstrip(' ')
|
||||
base64.b64decode(ivs, b"-_"))
|
||||
s = decryptor.decrypt(base64.b64decode(datas, "-_")).rstrip(b' ').decode('utf8')
|
||||
try:
|
||||
rdata = urlparse.parse_qs(s, strict_parsing=True)
|
||||
rdata = parse_qs(s, strict_parsing=True)
|
||||
except ValueError:
|
||||
return HttpResponse("Invalid encrypted data received.", status=400)
|
||||
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
|
||||
# a direct http call.
|
||||
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.
|
||||
socket.setdefaulttimeout(10)
|
||||
if userid:
|
||||
@ -208,18 +191,20 @@ def user_search(searchterm=None, userid=None):
|
||||
else:
|
||||
q = {'s': searchterm}
|
||||
|
||||
u = urllib.urlopen('%ssearch/?%s' % (
|
||||
settings.PGAUTH_REDIRECT,
|
||||
urllib.urlencode(q),
|
||||
))
|
||||
(ivs, datas) = u.read().split('&')
|
||||
u.close()
|
||||
r = requests.get(
|
||||
'{0}search/'.format(settings.PGAUTH_REDIRECT),
|
||||
params=q,
|
||||
)
|
||||
if r.status_code != 200:
|
||||
return []
|
||||
|
||||
(ivs, datas) = r.text.encode('utf8').split(b'&')
|
||||
|
||||
# Decryption time
|
||||
decryptor = AES.new(base64.b64decode(settings.PGAUTH_KEY),
|
||||
AES.MODE_CBC,
|
||||
base64.b64decode(ivs, "-_"))
|
||||
s = decryptor.decrypt(base64.b64decode(datas, "-_")).rstrip(' ')
|
||||
s = decryptor.decrypt(base64.b64decode(datas, "-_")).rstrip(b' ').decode('utf8')
|
||||
j = json.loads(s)
|
||||
|
||||
return j
|
||||
|
Reference in New Issue
Block a user