-
Notifications
You must be signed in to change notification settings - Fork 16
/
test_api_account.py
111 lines (88 loc) · 4.89 KB
/
test_api_account.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
from flask import Response
from doajtest.helpers import DoajTestCase, with_es
from portality import models
from portality.core import load_account_for_login_manager
from portality.decorators import api_key_required, api_key_optional
class TestAPIClient(DoajTestCase):
@classmethod
def setUpClass(cls):
super(TestAPIClient, cls).setUpClass()
# Turn off debug so we're allowed to add these routes after the app has been used in other tests
cls.app_test.debug = False
@cls.app_test.route('/hello')
@api_key_required
def hello_world():
return Response("hello, world!")
@cls.app_test.route('/helloopt')
@api_key_optional
def hello_world_opt():
return Response("hello, world!")
# Reinstate debug
cls.app_test.debug = True
cls.app_test.testing = True
cls.app_test.login_manager.user_loader(load_account_for_login_manager)
@classmethod
def tearDownClass(cls) -> None:
# put debug back on
cls.app_test.debug = True
#@with_es(indices=[models.Account.__type__])
def test_01_api_role(self):
"""test the new roles added for the API"""
a1 = models.Account.make_account(email="a1@example.com", username="a1_user", name="a1_name",
roles=["user", "api"], associated_journal_ids=[])
a1.save(blocking=True)
# Check an API key was generated on account creation
a1_key = a1.api_key
assert a1_key is not None
# Check we can retrieve the account by its key
a1_retrieved = models.Account.pull_by_api_key(a1_key)
assert a1 == a1_retrieved, (a1, a1_retrieved)
# Check that removing the API role means you don't get a key
a1.remove_role('api')
assert a1.api_key is None
#@with_es(indices=[models.Account.__type__])
def test_02_api_required_decorator(self):
"""test the api_key_required decorator"""
a1 = models.Account.make_account(email="a1@example.com", username="a1_user", name="a1_name",
roles=["user", "api"], associated_journal_ids=[])
a1_key = a1.api_key
a1.save() # a1 has api access
a2 = models.Account.make_account(email="a2@example.com", username="a2_user", name="a2_name",
roles=["user", "api"], associated_journal_ids=[])
a2_key = a2.api_key # user gets the key before access is removed
a2.remove_role('api')
a2.save(blocking=True) # a2 does not have api access.
with self.app_test.test_client() as t_client:
# Check the authorised user can access our function, but the unauthorised one can't.
response_authorised = t_client.get('/hello?api_key=' + a1_key)
assert response_authorised.data == b"hello, world!", response_authorised.data
assert response_authorised.status_code == 200
response_denied = t_client.get('/hello?api_key=' + a2_key)
assert response_denied.status_code == 401
#@with_es(indices=[models.Account.__type__, models.Journal.__type__, models.Article.__type__])
def test_03_api_optional_decorator(self):
"""test the api_key_optional decorator"""
a1 = models.Account.make_account(email="a1@example.com", username="a1_user", name="a1_name",
roles=["user", "api"], associated_journal_ids=[])
a1_key = a1.api_key
a1.save() # a1 has api access
a2 = models.Account.make_account(email="a2@example.com", username="a2_user", name="a2_name",
roles=["user", "api"], associated_journal_ids=[])
a2_key = a2.api_key # user gets the key before access is removed
a2.remove_role('api')
a2.save(blocking=True) # a2 does not have api access.
# There is no a3 - the last test case is just a public call with no API key
with self.app_test.test_client() as t_client:
# Check the authorised user can access our function, but the unauthorised one can't.
response_authorised = t_client.get('/helloopt?api_key=' + a1_key)
assert response_authorised.data == b"hello, world!"
assert response_authorised.status_code == 200
response_denied = t_client.get('/helloopt?api_key=' + a2_key)
assert response_denied.status_code == 401
# also check it's ok to not have a key at all
response_authorised2 = t_client.get('/helloopt')
assert response_authorised2.data == b"hello, world!"
assert response_authorised2.status_code == 200
# but if you do specify a key it needs to exist
response_denied2 = t_client.get('/helloopt?api_key=nonexistent_key')
assert response_denied2.status_code == 401