Make get_user_from_api_query_string() report detailed errors when signature checking fails (refs #5536)
This commit is contained in:
parent
a873d2678a
commit
3074204f09
39
wcs/api.py
39
wcs/api.py
|
@ -20,55 +20,64 @@ import hashlib
|
|||
import datetime
|
||||
|
||||
from quixote import get_request, get_publisher
|
||||
from qommon.errors import AccessForbiddenError
|
||||
|
||||
def get_user_from_api_query_string():
|
||||
query_string = get_request().get_query()
|
||||
if not query_string:
|
||||
return None
|
||||
# verify signature
|
||||
orig = get_request().form.get('orig')
|
||||
if not isinstance(orig, basestring):
|
||||
return None
|
||||
key = get_publisher().get_site_option(orig, 'api-secrets')
|
||||
if not key:
|
||||
return None
|
||||
signature = get_request().form.get('signature')
|
||||
if not isinstance(signature, basestring):
|
||||
return None
|
||||
# verify signature
|
||||
orig = get_request().form.get('orig')
|
||||
if not isinstance(orig, basestring):
|
||||
raise AccessForbiddenError('missing/multiple orig field')
|
||||
key = get_publisher().get_site_option(orig, 'api-secrets')
|
||||
if not key:
|
||||
raise AccessForbiddenError('invalid orig')
|
||||
algo = get_request().form.get('algo')
|
||||
if not isinstance(algo, basestring):
|
||||
return None
|
||||
raise AccessForbiddenError('missing/multiple algo field')
|
||||
try:
|
||||
algo = getattr(hashlib, algo)
|
||||
except AttributeError:
|
||||
algo = hashlib.sha256
|
||||
raise AccessForbiddenError('invalid algo')
|
||||
if signature != base64.standard_b64encode(hmac.new(key,
|
||||
query_string[:query_string.find('&signature=')],
|
||||
algo).digest()):
|
||||
return None
|
||||
raise AccessForbiddenError('invalid signature')
|
||||
timestamp = get_request().form.get('timestamp')
|
||||
if not isinstance(timestamp, basestring):
|
||||
return None
|
||||
raise AccessForbiddenError('missing/multiple timestamp field')
|
||||
delta = (datetime.datetime.utcnow().replace(tzinfo=None) -
|
||||
datetime.datetime.strptime(timestamp,
|
||||
'%Y-%m-%dT%H:%M:%SZ'))
|
||||
if abs(delta) > datetime.timedelta(seconds=30):
|
||||
return None
|
||||
MAX_DELTA = 30
|
||||
if abs(delta) > datetime.timedelta(seconds=MAX_DELTA):
|
||||
raise AccessForbiddenError('timestamp delta is more '
|
||||
'than %s seconds: %s seconds' % (MAX_DELTA, delta))
|
||||
|
||||
user = None
|
||||
if get_request().form.get('email'):
|
||||
email = get_request().form.get('email')
|
||||
if not isinstance(email, basestring):
|
||||
return None
|
||||
raise AccessForbiddenError('multiple email field')
|
||||
users = list(get_publisher().user_class.get_users_with_email(email))
|
||||
if users:
|
||||
user = users[0]
|
||||
else:
|
||||
raise AccessForbiddenError('unknown email')
|
||||
elif get_request().form.get('NameID'):
|
||||
ni = get_request().form.get('NameID')
|
||||
if not isinstance(ni, basestring):
|
||||
return None
|
||||
raise AccessForbiddenError('multiple NameID field')
|
||||
users = list(get_publisher().user_class.get_users_with_name_identifier(ni))
|
||||
if users:
|
||||
user = users[0]
|
||||
else:
|
||||
raise AccessForbiddenError('unknown NameID')
|
||||
else:
|
||||
raise AccessForbiddenError('missing email or NameID fields')
|
||||
|
||||
return user
|
||||
|
|
Loading…
Reference in New Issue