20 |
20 |
import datetime
|
21 |
21 |
|
22 |
22 |
from quixote import get_request, get_publisher
|
|
23 |
from qommon.errors import AccessForbiddenError
|
23 |
24 |
|
24 |
25 |
def get_user_from_api_query_string():
|
25 |
26 |
query_string = get_request().get_query()
|
26 |
27 |
if not query_string:
|
27 |
28 |
return None
|
|
29 |
signature = get_request().form.get('signature')
|
|
30 |
if not isinstance(signature, basestring):
|
|
31 |
return None
|
28 |
32 |
# verify signature
|
29 |
33 |
orig = get_request().form.get('orig')
|
30 |
34 |
if not isinstance(orig, basestring):
|
31 |
|
return None
|
|
35 |
raise AccessForbiddenError('missing/multiple orig field')
|
32 |
36 |
key = get_publisher().get_site_option(orig, 'api-secrets')
|
33 |
37 |
if not key:
|
34 |
|
return None
|
35 |
|
signature = get_request().form.get('signature')
|
36 |
|
if not isinstance(signature, basestring):
|
37 |
|
return None
|
|
38 |
raise AccessForbiddenError('invalid orig')
|
38 |
39 |
algo = get_request().form.get('algo')
|
39 |
40 |
if not isinstance(algo, basestring):
|
40 |
|
return None
|
|
41 |
raise AccessForbiddenError('missing/multiple algo field')
|
41 |
42 |
try:
|
42 |
43 |
algo = getattr(hashlib, algo)
|
43 |
44 |
except AttributeError:
|
44 |
|
algo = hashlib.sha256
|
|
45 |
raise AccessForbiddenError('invalid algo')
|
45 |
46 |
if signature != base64.standard_b64encode(hmac.new(key,
|
46 |
47 |
query_string[:query_string.find('&signature=')],
|
47 |
48 |
algo).digest()):
|
48 |
|
return None
|
|
49 |
raise AccessForbiddenError('invalid signature')
|
49 |
50 |
timestamp = get_request().form.get('timestamp')
|
50 |
51 |
if not isinstance(timestamp, basestring):
|
51 |
|
return None
|
|
52 |
raise AccessForbiddenError('missing/multiple timestamp field')
|
52 |
53 |
delta = (datetime.datetime.utcnow().replace(tzinfo=None) -
|
53 |
54 |
datetime.datetime.strptime(timestamp,
|
54 |
55 |
'%Y-%m-%dT%H:%M:%SZ'))
|
55 |
|
if abs(delta) > datetime.timedelta(seconds=30):
|
56 |
|
return None
|
|
56 |
MAX_DELTA = 30
|
|
57 |
if abs(delta) > datetime.timedelta(seconds=MAX_DELTAT):
|
|
58 |
raise AccessForbiddenError('timestamp delta is more '
|
|
59 |
'than %s seconds: %s seconds' % (MAX_DELTA, delta))
|
57 |
60 |
|
58 |
61 |
user = None
|
59 |
62 |
if get_request().form.get('email'):
|
60 |
63 |
email = get_request().form.get('email')
|
61 |
64 |
if not isinstance(email, basestring):
|
62 |
|
return None
|
|
65 |
raise AccessForbiddenError('multiple email field')
|
63 |
66 |
users = list(get_publisher().user_class.get_users_with_email(email))
|
64 |
67 |
if users:
|
65 |
68 |
user = users[0]
|
|
69 |
else:
|
|
70 |
raise AccessForbiddenError('unknown email')
|
66 |
71 |
elif get_request().form.get('NameID'):
|
67 |
72 |
ni = get_request().form.get('NameID')
|
68 |
73 |
if not isinstance(ni, basestring):
|
69 |
|
return None
|
|
74 |
raise AccessForbiddenError('multiple NameID field')
|
70 |
75 |
users = list(get_publisher().user_class.get_users_with_name_identifier(ni))
|
71 |
76 |
if users:
|
72 |
77 |
user = users[0]
|
|
78 |
else:
|
|
79 |
raise AccessForbiddenError('unknown NameID')
|
|
80 |
else:
|
|
81 |
raise AccessForbiddenError('missing email or NameID fields')
|
73 |
82 |
|
74 |
83 |
return user
|
75 |
|
-
|