mirror of
https://github.com/postgres/pgweb.git
synced 2025-08-12 23:05:12 +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 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
|
||||||
|
Reference in New Issue
Block a user