matlab-proxy 0.15.0__py3-none-any.whl → 0.16.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of matlab-proxy might be problematic. Click here for more details.
- matlab_proxy/app.py +13 -7
- matlab_proxy/app_state.py +9 -6
- matlab_proxy/constants.py +1 -0
- matlab_proxy/gui/asset-manifest.json +3 -3
- matlab_proxy/gui/index.html +1 -1
- matlab_proxy/gui/static/js/{main.14aa7840.js → main.522d83ba.js} +3 -3
- matlab_proxy/gui/static/js/main.522d83ba.js.map +1 -0
- matlab_proxy/settings.py +7 -4
- matlab_proxy/util/__init__.py +8 -1
- matlab_proxy/util/mwi/token_auth.py +19 -5
- {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/METADATA +1 -1
- {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/RECORD +40 -20
- tests/integration/integration_tests_with_license/test_http_end_points.py +4 -4
- tests/integration/integration_tests_without_license/conftest.py +4 -3
- tests/integration/integration_tests_without_license/test_matlab_is_down_if_unlicensed.py +3 -0
- tests/unit/__init__.py +1 -0
- tests/unit/conftest.py +67 -0
- tests/unit/test_app.py +1113 -0
- tests/unit/test_app_state.py +586 -0
- tests/unit/test_constants.py +6 -0
- tests/unit/test_ddux.py +22 -0
- tests/unit/test_devel.py +246 -0
- tests/unit/test_non_dev_mode.py +169 -0
- tests/unit/test_settings.py +460 -0
- tests/unit/util/__init__.py +3 -0
- tests/unit/util/mwi/__init__.py +1 -0
- tests/unit/util/mwi/embedded_connector/__init__.py +1 -0
- tests/unit/util/mwi/embedded_connector/test_helpers.py +29 -0
- tests/unit/util/mwi/embedded_connector/test_request.py +64 -0
- tests/unit/util/mwi/test_custom_http_headers.py +281 -0
- tests/unit/util/mwi/test_logger.py +49 -0
- tests/unit/util/mwi/test_token_auth.py +303 -0
- tests/unit/util/mwi/test_validators.py +331 -0
- tests/unit/util/test_mw.py +550 -0
- tests/unit/util/test_util.py +135 -0
- matlab_proxy/gui/static/js/main.14aa7840.js.map +0 -1
- /matlab_proxy/gui/static/js/{main.14aa7840.js.LICENSE.txt → main.522d83ba.js.LICENSE.txt} +0 -0
- {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/LICENSE.md +0 -0
- {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/WHEEL +0 -0
- {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/entry_points.txt +0 -0
- {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Copyright 2020-2022 The MathWorks, Inc.
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import stat
|
|
6
|
+
import time
|
|
7
|
+
from json.decoder import JSONDecodeError
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
from matlab_proxy.util import system
|
|
11
|
+
from matlab_proxy.util.mwi import custom_http_headers
|
|
12
|
+
from matlab_proxy.util.mwi import environment_variables as mwi_env
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_get_custom_header_env_var():
|
|
16
|
+
"""Test to check if the __get_custom_header_env_var() method returns the expected environment variable name"""
|
|
17
|
+
assert (
|
|
18
|
+
mwi_env.get_env_name_custom_http_headers()
|
|
19
|
+
== custom_http_headers.__get_custom_header_env_var()
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_get_exception_statement():
|
|
24
|
+
"""Test to check if __get_exception_statement() contains 'JSON data' in the generic exception statement returned by __get_exception_statement()"""
|
|
25
|
+
assert "JSON data" in custom_http_headers.__get_exception_statement()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.fixture(name="non_existent_temp_json_file")
|
|
29
|
+
def non_existent_random_json_file_fixture(tmp_path):
|
|
30
|
+
"""Pytest fixture which returns a non-existent random json file within a temporary directory
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
tmp_path : Built in Pytest fixture.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
PosixPath: of the non-existent random json file.
|
|
37
|
+
"""
|
|
38
|
+
random_file = tmp_path / f'{str(time.time()).replace(".", "")}.json'
|
|
39
|
+
return random_file
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.fixture(name="monkeypatch_env_var_with_json_file")
|
|
43
|
+
def monkeypatch_env_var_with_json_file_fixture(
|
|
44
|
+
monkeypatch, non_existent_temp_json_file
|
|
45
|
+
):
|
|
46
|
+
"""Pytest fixture which monkeypatches the env variable returned by the __get_custom_header_env_var()
|
|
47
|
+
method with the value returned by the pytest fixture non_existent_tmp_json_file
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
monkeypatch : Built in pytest fixture
|
|
51
|
+
non_existent_temp_json_file: Pytest fixture which returns a string containing path
|
|
52
|
+
to non-existent file in a temporary directory.
|
|
53
|
+
"""
|
|
54
|
+
monkeypatch.setenv(
|
|
55
|
+
mwi_env.get_env_name_custom_http_headers(),
|
|
56
|
+
str(non_existent_temp_json_file),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@pytest.fixture(name="valid_json_content")
|
|
61
|
+
def valid_json_content_fixture():
|
|
62
|
+
"""Pytest fixture which returns valid JSON data as a string
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
[String]: containing valid JSON data.
|
|
66
|
+
"""
|
|
67
|
+
return '{"abcd": "hello"}'
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@pytest.fixture(name="json_file_with_valid_json")
|
|
71
|
+
def json_file_with_valid_json_fixture(non_existent_temp_json_file, valid_json_content):
|
|
72
|
+
"""Pytest fixture which returns a random json file containing valid json data
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
non_existent_temp_json_file : Pytest fixture which returns a non-existent random json file.
|
|
76
|
+
valid_json_content : Pytest fixture which returns valid JSON data as a string.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
[PosixPath]: Of a random json file containing valid json data.
|
|
80
|
+
"""
|
|
81
|
+
json_file_with_valid_content = non_existent_temp_json_file
|
|
82
|
+
with open(json_file_with_valid_content, "w") as f:
|
|
83
|
+
f.write(valid_json_content)
|
|
84
|
+
|
|
85
|
+
return json_file_with_valid_content
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_get_file_contents_with_valid_json(json_file_with_valid_json):
|
|
89
|
+
"""Test to check if __get_file_contents() returns valid json data as a dict from a file
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
json_file_with_valid_json : Pytest fixture which returns a non-existent random json file.
|
|
93
|
+
"""
|
|
94
|
+
file_content = None
|
|
95
|
+
with open(json_file_with_valid_json, "r") as f:
|
|
96
|
+
file_content = json.load(f)
|
|
97
|
+
|
|
98
|
+
assert file_content == custom_http_headers.__get_file_contents(
|
|
99
|
+
json_file_with_valid_json
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@pytest.fixture(name="invalid_json_content")
|
|
104
|
+
def invalid_json_content_fixture():
|
|
105
|
+
"""Pytest fixture which returns invalid json data as a string
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
[String]: containing invalid json data.
|
|
109
|
+
"""
|
|
110
|
+
return '{"abcd"= "hello"}'
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@pytest.fixture(name="json_file_with_invalid_json")
|
|
114
|
+
def json_file_with_invalid_json_fixture(
|
|
115
|
+
non_existent_temp_json_file, invalid_json_content
|
|
116
|
+
):
|
|
117
|
+
"""Pytest fixture which returns a path to a random json file containing invalid json data.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
non_existent_temp_json_file : Pytest fixture which returns a non-existent random json file.
|
|
121
|
+
invalid_json_content : Pytest fixture which returns invalid json data as a string.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
PosixPath: to a random file containing invalid json data.
|
|
125
|
+
"""
|
|
126
|
+
json_file_with_invalid_content = non_existent_temp_json_file
|
|
127
|
+
with open(json_file_with_invalid_content, "w") as f:
|
|
128
|
+
f.write(invalid_json_content)
|
|
129
|
+
|
|
130
|
+
return json_file_with_invalid_content
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_get_file_contents_with_invalid_json(json_file_with_invalid_json, capsys):
|
|
134
|
+
"""Test to check __get_file_contents() raises JSONDecodeError when invalid json data is present in a file.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
json_file_with_invalid_json : Pytest fixture which returns a non-existent random json file.
|
|
138
|
+
"""
|
|
139
|
+
with pytest.raises(SystemExit):
|
|
140
|
+
custom_http_headers.__get_file_contents(json_file_with_invalid_json)
|
|
141
|
+
out, err = capsys.readouterr()
|
|
142
|
+
assert JSONDecodeError.__name__ in out
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def test_check_file_validity_no_read_access(non_existent_temp_json_file, capsys):
|
|
146
|
+
"""Test to check if OSError is raised when trying to read file with no read access.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
non_existent_temp_json_file : Pytest fixture which returns a non-existent random json file.
|
|
150
|
+
"""
|
|
151
|
+
temp_json_file_no_read_access = non_existent_temp_json_file
|
|
152
|
+
|
|
153
|
+
# Not possible to create a file in windows without read permission
|
|
154
|
+
# So not creating the file itself to check for SystemExit exception.
|
|
155
|
+
if not system.is_windows():
|
|
156
|
+
temp_json_file_no_read_access.touch(mode=stat.S_IWUSR)
|
|
157
|
+
|
|
158
|
+
with pytest.raises(SystemExit):
|
|
159
|
+
custom_http_headers.__check_file_validity(temp_json_file_no_read_access)
|
|
160
|
+
out, err = capsys.readouterr()
|
|
161
|
+
assert OSError.__name__ in out
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def test_check_file_validity_no_error(non_existent_temp_json_file, valid_json_content):
|
|
165
|
+
"""Test to check __check_file_validity() does not raise any exception when the custom headers file
|
|
166
|
+
exists, has valid JSON data and the current python process has read access to the file.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
non_existent_temp_json_file : Pytest fixture which returns a non-existent random json file.
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
random_json_file_with_valid_content = non_existent_temp_json_file
|
|
173
|
+
with open(random_json_file_with_valid_content, "w") as f:
|
|
174
|
+
f.write(valid_json_content)
|
|
175
|
+
|
|
176
|
+
assert (
|
|
177
|
+
custom_http_headers.__check_file_validity(random_json_file_with_valid_content)
|
|
178
|
+
is True
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def test_get_no_env_var():
|
|
183
|
+
"""Test to check if get() returns an empty dict, when mwi_custom_http_headers env variable is not present."""
|
|
184
|
+
assert custom_http_headers.get() == dict()
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def test_get_with_json_file_no_error(
|
|
188
|
+
monkeypatch_env_var_with_json_file, valid_json_content
|
|
189
|
+
):
|
|
190
|
+
"""Test to check if expected json content is returned by get() as a dict when the
|
|
191
|
+
environment variable returned by __get_custom_header_env_var() contains a path to a JSON file
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
monkeypatch_env_var_with_json_file : Pytest fixture which monkeypatches the env variable returned by __get_custom_header_env_var() to
|
|
195
|
+
have a non-existent temporary json file.
|
|
196
|
+
valid_json_content : Pytest fixture which returns valid json data as a string.
|
|
197
|
+
"""
|
|
198
|
+
tmp_file_path = os.getenv(mwi_env.get_env_name_custom_http_headers())
|
|
199
|
+
|
|
200
|
+
with open(tmp_file_path, "w") as f:
|
|
201
|
+
f.write(valid_json_content)
|
|
202
|
+
|
|
203
|
+
assert custom_http_headers.get() == json.loads(valid_json_content)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def test_get_with_json_file_raise_exception(
|
|
207
|
+
monkeypatch_env_var_with_json_file, invalid_json_content, capsys
|
|
208
|
+
):
|
|
209
|
+
"""Test to check if the get() method raises SystemExit exception when the environment variable returned by __get_custom_env_var()
|
|
210
|
+
contains path to a file with invalid JSON data. Also asserts for JSONDecodeError in stdout.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
monkeypatch_env_var_with_json_file : Pytest fixture which monkeypatches the env variable returned by __get_custom_header_env_var() to
|
|
214
|
+
have a non-existent temporary json file.
|
|
215
|
+
invalid_json_content : Pytest fixture which returns invalid json data as a string.
|
|
216
|
+
"""
|
|
217
|
+
tmp_file_path = os.getenv(mwi_env.get_env_name_custom_http_headers())
|
|
218
|
+
|
|
219
|
+
with open(tmp_file_path, "w") as f:
|
|
220
|
+
f.write(invalid_json_content)
|
|
221
|
+
|
|
222
|
+
with pytest.raises(SystemExit):
|
|
223
|
+
custom_http_headers.get()
|
|
224
|
+
out, err = capsys.readouterr()
|
|
225
|
+
assert JSONDecodeError.__name__ in out
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@pytest.fixture(name="monkeypatch_env_var_with_invalid_json_string")
|
|
229
|
+
def monkeypatch_env_var_with_invalid_json_string_fixture(
|
|
230
|
+
monkeypatch, invalid_json_content
|
|
231
|
+
):
|
|
232
|
+
"""Pytest fixture which monkeypatches the env variable returned by the __get_custom_header_env_var()
|
|
233
|
+
method with the value returned by the pytest fixture non_existent_temp_json_file
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
monkeypatch : Built in pytest fixture
|
|
237
|
+
non_existent_temp_json_file: Pytest fixture which returns a string containing path
|
|
238
|
+
to non-existent file in a temporary directory.
|
|
239
|
+
"""
|
|
240
|
+
monkeypatch.setenv(mwi_env.get_env_name_custom_http_headers(), invalid_json_content)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def test_get_with_invalid_json_string(
|
|
244
|
+
monkeypatch_env_var_with_invalid_json_string, capsys
|
|
245
|
+
):
|
|
246
|
+
"""Test to check if the get() method raises SystemExit exception when the environment variable returned by __get_custom_env_var()
|
|
247
|
+
contains invalid JSON data as a string. Also asserts for JSONDecodeError in stdout.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
monkeypatch_env_var_with_invalid_json_string : Pytest fixture which monkeypatches the env variable returned by __get_custom_header_env_var() to
|
|
251
|
+
contain invalid JSON data as a string.
|
|
252
|
+
"""
|
|
253
|
+
with pytest.raises(SystemExit):
|
|
254
|
+
headers = custom_http_headers.get()
|
|
255
|
+
out, err = capsys.readouterr()
|
|
256
|
+
assert JSONDecodeError.__name__ in out
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@pytest.fixture(name="monkeypatch_env_var_with_valid_json_string")
|
|
260
|
+
def monkeypatch_env_var_with_valid_json_string_fixture(monkeypatch, valid_json_content):
|
|
261
|
+
"""Pytest fixture which monkeypatches the env variable returned by the __get_custom_header_env_var()
|
|
262
|
+
method with the value returned by the pytest fixture non_existent_tmp_json_file
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
monkeypatch : Built in pytest fixture
|
|
266
|
+
non_existent_temp_json_file: Pytest fixture which returns a string containing path
|
|
267
|
+
to non-existent file in a temporary directory.
|
|
268
|
+
"""
|
|
269
|
+
monkeypatch.setenv(mwi_env.get_env_name_custom_http_headers(), valid_json_content)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def test_get_with_valid_json_string(monkeypatch_env_var_with_valid_json_string):
|
|
273
|
+
"""Test to check if expected json content is returned by get() as a dict when the
|
|
274
|
+
environment variable contains valid JSON data as a string
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
monkeypatch_env_var_with_valid_json_string : Pytest fixture which monkeypatches the env variable returned by __get_custom_header_env_var() to
|
|
278
|
+
contain valid JSON data as a string.
|
|
279
|
+
"""
|
|
280
|
+
headers = json.loads(os.getenv(mwi_env.get_env_name_custom_http_headers()))
|
|
281
|
+
assert headers == custom_http_headers.get()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Copyright 2020-2022 The MathWorks, Inc.
|
|
2
|
+
"""This file tests methods present in matlab_proxy/util/mwi_logger.py
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
from matlab_proxy.util.mwi import logger as mwi_logger
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_get():
|
|
12
|
+
"""This test checks if the get method returns a logger with expected name"""
|
|
13
|
+
logger = mwi_logger.get()
|
|
14
|
+
# Okay to use hidden API for testing only.
|
|
15
|
+
assert logger.name == mwi_logger.__get_mw_logger_name()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_get_mw_logger_name():
|
|
19
|
+
"""Test to lock down the name of the logger used."""
|
|
20
|
+
# Okay to use hidden API for testing only.
|
|
21
|
+
assert "MATLABProxyApp" == mwi_logger.__get_mw_logger_name()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_get_with_no_environment_variables(monkeypatch):
|
|
25
|
+
"""This test checks if the get method returns a logger with default settings"""
|
|
26
|
+
# Delete the environment variables if they do exist
|
|
27
|
+
env_names_list = mwi_logger.get_environment_variable_names()
|
|
28
|
+
monkeypatch.delenv(env_names_list[0], raising=False)
|
|
29
|
+
monkeypatch.delenv(env_names_list[1], raising=False)
|
|
30
|
+
|
|
31
|
+
logger = mwi_logger.get(init=True)
|
|
32
|
+
assert logger.isEnabledFor(logging.INFO) == True
|
|
33
|
+
assert len(logger.handlers) == 0
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_get_with_environment_variables(monkeypatch, tmp_path):
|
|
37
|
+
"""This test checks if the get method returns a logger with default settings"""
|
|
38
|
+
env_names_list = mwi_logger.get_environment_variable_names()
|
|
39
|
+
monkeypatch.setenv(env_names_list[0], "CRITICAL")
|
|
40
|
+
monkeypatch.setenv(env_names_list[1], str(tmp_path / "testing123.log"))
|
|
41
|
+
|
|
42
|
+
logger = mwi_logger.get(init=True)
|
|
43
|
+
|
|
44
|
+
# Verify that environment variable controlling level is respected
|
|
45
|
+
assert logger.isEnabledFor(logging.CRITICAL) == True
|
|
46
|
+
|
|
47
|
+
# Verify that environment variable setting the file is respected
|
|
48
|
+
assert len(logger.handlers) == 1
|
|
49
|
+
assert os.path.basename(logger.handlers[0].baseFilename) == "testing123.log"
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Copyright 2023-2024 The MathWorks, Inc.
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from aiohttp import web
|
|
5
|
+
from aiohttp_session import setup as aiohttp_session_setup
|
|
6
|
+
from aiohttp_session.cookie_storage import EncryptedCookieStorage
|
|
7
|
+
from cryptography import fernet
|
|
8
|
+
|
|
9
|
+
from matlab_proxy.constants import MWI_AUTH_TOKEN_NAME_FOR_HTTP
|
|
10
|
+
from matlab_proxy.util.mwi import environment_variables as mwi_env
|
|
11
|
+
from matlab_proxy.util.mwi import token_auth
|
|
12
|
+
|
|
13
|
+
## APIs to test:
|
|
14
|
+
# 1. generate_mwi_auth_token (auth enabled, auth enabled+custom token, custom token, auth disabled)
|
|
15
|
+
# 2. authenticate_access_decorator (headers & url_string, and session storage)
|
|
16
|
+
|
|
17
|
+
## Testing generate_mwi_auth_token :
|
|
18
|
+
|
|
19
|
+
test_data = [
|
|
20
|
+
pytest.param(
|
|
21
|
+
"False",
|
|
22
|
+
"CustomTokenStr123_-Test1",
|
|
23
|
+
None,
|
|
24
|
+
id="token isn't generated when MWI_ENABLE_AUTH_TOKEN is explicitly disabled & has custom token set",
|
|
25
|
+
),
|
|
26
|
+
pytest.param(
|
|
27
|
+
"",
|
|
28
|
+
"CustomTokenStr123_-Test2",
|
|
29
|
+
"CustomTokenStr123_-Test2",
|
|
30
|
+
id="token is generated when MWI_ENABLE_AUTH_TOKEN is not set & has custom token set",
|
|
31
|
+
),
|
|
32
|
+
pytest.param(
|
|
33
|
+
"True",
|
|
34
|
+
"CustomTokenStr123_-Test3",
|
|
35
|
+
"CustomTokenStr123_-Test3",
|
|
36
|
+
id="token is generated when MWI_ENABLE_AUTH_TOKEN is set & has custom token set",
|
|
37
|
+
),
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@pytest.mark.parametrize(
|
|
42
|
+
"expected_auth_enablement, auth_token, expected_auth_token",
|
|
43
|
+
test_data,
|
|
44
|
+
)
|
|
45
|
+
def test_generate_mwi_auth_token(
|
|
46
|
+
monkeypatch, expected_auth_enablement, auth_token, expected_auth_token
|
|
47
|
+
):
|
|
48
|
+
monkeypatch.setenv(
|
|
49
|
+
mwi_env.get_env_name_enable_mwi_auth_token(), str(expected_auth_enablement)
|
|
50
|
+
)
|
|
51
|
+
monkeypatch.setenv(mwi_env.get_env_name_mwi_auth_token(), str(auth_token))
|
|
52
|
+
|
|
53
|
+
generated_token = token_auth.generate_mwi_auth_token_and_hash()["token"]
|
|
54
|
+
assert generated_token == expected_auth_token
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_auto_token_generation_with_enable_flag_set(monkeypatch):
|
|
58
|
+
# Test if token is auto-generated when MWI_ENABLE_AUTH_TOKEN is True
|
|
59
|
+
expected_auth_enablement = "True"
|
|
60
|
+
monkeypatch.setenv(
|
|
61
|
+
mwi_env.get_env_name_enable_mwi_auth_token(), str(expected_auth_enablement)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
generated_token = token_auth.generate_mwi_auth_token_and_hash()["token"]
|
|
65
|
+
assert generated_token is not None
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_auto_token_generation_with_enable_flag_unset():
|
|
69
|
+
# Test if token is generated by default when MWI_ENABLE_AUTH_TOKEN and MWI_AUTH_TOKEN are not set
|
|
70
|
+
generated_token = token_auth.generate_mwi_auth_token_and_hash()["token"]
|
|
71
|
+
assert generated_token is not None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
## Testing authenticate_access_decorator :
|
|
75
|
+
# This in turn, also tests authenticate_request
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@pytest.fixture
|
|
79
|
+
def get_custom_auth_token_str():
|
|
80
|
+
return "CustomTokenStr123_-TestOtherAPIS"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@token_auth.authenticate_access_decorator
|
|
84
|
+
async def fake_endpoint(request):
|
|
85
|
+
if request.method == "POST":
|
|
86
|
+
request.app["value"] = (await request.post())["value"]
|
|
87
|
+
return web.Response(body=b"thanks for the data")
|
|
88
|
+
return web.Response(body="value: {}".format(request.app["value"]).encode("utf-8"))
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@pytest.fixture
|
|
92
|
+
def fake_server_with_auth_enabled(
|
|
93
|
+
loop, aiohttp_client, monkeypatch, get_custom_auth_token_str
|
|
94
|
+
):
|
|
95
|
+
auth_token = get_custom_auth_token_str
|
|
96
|
+
auth_enablement = "True"
|
|
97
|
+
monkeypatch.setenv(
|
|
98
|
+
mwi_env.get_env_name_enable_mwi_auth_token(), str(auth_enablement)
|
|
99
|
+
)
|
|
100
|
+
monkeypatch.setenv(mwi_env.get_env_name_mwi_auth_token(), str(auth_token))
|
|
101
|
+
|
|
102
|
+
(
|
|
103
|
+
mwi_auth_token,
|
|
104
|
+
mwi_auth_token_hash,
|
|
105
|
+
) = token_auth.generate_mwi_auth_token_and_hash().values()
|
|
106
|
+
|
|
107
|
+
app = web.Application()
|
|
108
|
+
app["settings"] = {
|
|
109
|
+
"mwi_is_token_auth_enabled": mwi_auth_token is not None,
|
|
110
|
+
"mwi_auth_token": mwi_auth_token,
|
|
111
|
+
"mwi_auth_token_hash": mwi_auth_token_hash,
|
|
112
|
+
"mwi_auth_token_name_for_http": MWI_AUTH_TOKEN_NAME_FOR_HTTP,
|
|
113
|
+
"mwi_auth_token_name_for_env": mwi_env.get_env_name_mwi_auth_token().lower(),
|
|
114
|
+
}
|
|
115
|
+
app.router.add_get("/", fake_endpoint)
|
|
116
|
+
app.router.add_post("/", fake_endpoint)
|
|
117
|
+
# Setup the session storage
|
|
118
|
+
fernet_key = fernet.Fernet.generate_key()
|
|
119
|
+
f = fernet.Fernet(fernet_key)
|
|
120
|
+
aiohttp_session_setup(
|
|
121
|
+
app, EncryptedCookieStorage(f, cookie_name="matlab-proxy-session")
|
|
122
|
+
)
|
|
123
|
+
return loop.run_until_complete(aiohttp_client(app))
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
async def test_set_value_with_token(
|
|
127
|
+
fake_server_with_auth_enabled, get_custom_auth_token_str
|
|
128
|
+
):
|
|
129
|
+
resp = await fake_server_with_auth_enabled.post(
|
|
130
|
+
"/",
|
|
131
|
+
data={"value": "foo"},
|
|
132
|
+
headers={MWI_AUTH_TOKEN_NAME_FOR_HTTP: get_custom_auth_token_str},
|
|
133
|
+
)
|
|
134
|
+
assert resp.status == web.HTTPOk.status_code
|
|
135
|
+
assert await resp.text() == "thanks for the data"
|
|
136
|
+
assert fake_server_with_auth_enabled.server.app["value"] == "foo"
|
|
137
|
+
|
|
138
|
+
# Test subsequent requests do not need token authentication
|
|
139
|
+
resp2 = await fake_server_with_auth_enabled.post(
|
|
140
|
+
"/",
|
|
141
|
+
data={"value": "foobar"},
|
|
142
|
+
)
|
|
143
|
+
assert resp2.status == web.HTTPOk.status_code
|
|
144
|
+
assert fake_server_with_auth_enabled.server.app["value"] == "foobar"
|
|
145
|
+
|
|
146
|
+
# Test request which accepts cookies from previous request
|
|
147
|
+
resp3 = await fake_server_with_auth_enabled.post(
|
|
148
|
+
"/",
|
|
149
|
+
data={"value": "foobar1"},
|
|
150
|
+
cookies=resp.cookies,
|
|
151
|
+
)
|
|
152
|
+
assert resp3.status == web.HTTPOk.status_code
|
|
153
|
+
assert fake_server_with_auth_enabled.server.app["value"] == "foobar1"
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
async def test_set_value_with_token_hash(
|
|
157
|
+
fake_server_with_auth_enabled, get_custom_auth_token_str
|
|
158
|
+
):
|
|
159
|
+
resp = await fake_server_with_auth_enabled.post(
|
|
160
|
+
"/",
|
|
161
|
+
data={"value": "foo"},
|
|
162
|
+
headers={
|
|
163
|
+
MWI_AUTH_TOKEN_NAME_FOR_HTTP: token_auth._generate_hash(
|
|
164
|
+
get_custom_auth_token_str
|
|
165
|
+
)
|
|
166
|
+
},
|
|
167
|
+
)
|
|
168
|
+
assert resp.status == web.HTTPOk.status_code
|
|
169
|
+
assert await resp.text() == "thanks for the data"
|
|
170
|
+
assert fake_server_with_auth_enabled.server.app["value"] == "foo"
|
|
171
|
+
|
|
172
|
+
# Test subsequent requests do not need token authentication
|
|
173
|
+
resp2 = await fake_server_with_auth_enabled.post(
|
|
174
|
+
"/",
|
|
175
|
+
data={"value": "foobar"},
|
|
176
|
+
)
|
|
177
|
+
assert resp2.status == web.HTTPOk.status_code
|
|
178
|
+
assert fake_server_with_auth_enabled.server.app["value"] == "foobar"
|
|
179
|
+
|
|
180
|
+
# Test request which accepts cookies from previous request
|
|
181
|
+
resp3 = await fake_server_with_auth_enabled.post(
|
|
182
|
+
"/",
|
|
183
|
+
data={"value": "foobar1"},
|
|
184
|
+
cookies=resp.cookies,
|
|
185
|
+
)
|
|
186
|
+
assert resp3.status == web.HTTPOk.status_code
|
|
187
|
+
assert fake_server_with_auth_enabled.server.app["value"] == "foobar1"
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
async def test_set_value_without_token(fake_server_with_auth_enabled):
|
|
191
|
+
resp2 = await fake_server_with_auth_enabled.post(
|
|
192
|
+
"/",
|
|
193
|
+
data={"value": "foobar"},
|
|
194
|
+
)
|
|
195
|
+
assert resp2.status == web.HTTPForbidden.status_code
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
async def test_set_value_with_invalid_token(fake_server_with_auth_enabled):
|
|
199
|
+
resp2 = await fake_server_with_auth_enabled.post(
|
|
200
|
+
"/",
|
|
201
|
+
data={"value": "foobar"},
|
|
202
|
+
headers={MWI_AUTH_TOKEN_NAME_FOR_HTTP: "invalid-token"},
|
|
203
|
+
)
|
|
204
|
+
assert resp2.status == web.HTTPForbidden.status_code
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
async def test_set_value_with_token_in_params(
|
|
208
|
+
fake_server_with_auth_enabled, get_custom_auth_token_str
|
|
209
|
+
):
|
|
210
|
+
fake_server_with_auth_enabled.server.app["value"] = "foo"
|
|
211
|
+
resp = await fake_server_with_auth_enabled.post(
|
|
212
|
+
"/",
|
|
213
|
+
data={"value": "foofoo"},
|
|
214
|
+
params={
|
|
215
|
+
MWI_AUTH_TOKEN_NAME_FOR_HTTP: token_auth._generate_hash(
|
|
216
|
+
get_custom_auth_token_str
|
|
217
|
+
)
|
|
218
|
+
},
|
|
219
|
+
)
|
|
220
|
+
assert resp.status == web.HTTPOk.status_code
|
|
221
|
+
assert await resp.text() == "thanks for the data"
|
|
222
|
+
assert fake_server_with_auth_enabled.server.app["value"] == "foofoo"
|
|
223
|
+
|
|
224
|
+
# Test subsequent requests do not need token authentication
|
|
225
|
+
resp2 = await fake_server_with_auth_enabled.post(
|
|
226
|
+
"/",
|
|
227
|
+
data={"value": "foobar"},
|
|
228
|
+
)
|
|
229
|
+
assert resp2.status == web.HTTPForbidden.status_code
|
|
230
|
+
# assert server_with_auth_enabled.server.app["value"] == "foobar"
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
async def test_get_value_without_token(fake_server_with_auth_enabled):
|
|
234
|
+
fake_server_with_auth_enabled.server.app["value"] = "bar"
|
|
235
|
+
resp = await fake_server_with_auth_enabled.get("/")
|
|
236
|
+
assert resp.status == web.HTTPForbidden.status_code
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
async def test_get_value_with_token_in_query_params(
|
|
240
|
+
fake_server_with_auth_enabled, get_custom_auth_token_str
|
|
241
|
+
):
|
|
242
|
+
fake_server_with_auth_enabled.server.app["value"] = "bar"
|
|
243
|
+
resp = await fake_server_with_auth_enabled.get(
|
|
244
|
+
"/",
|
|
245
|
+
params={
|
|
246
|
+
MWI_AUTH_TOKEN_NAME_FOR_HTTP: token_auth._generate_hash(
|
|
247
|
+
get_custom_auth_token_str
|
|
248
|
+
)
|
|
249
|
+
},
|
|
250
|
+
)
|
|
251
|
+
assert resp.status == web.HTTPOk.status_code
|
|
252
|
+
assert await resp.text() == "value: bar"
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
## Create a fake_server without authentication enabled, and test that you can access data.
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@pytest.fixture
|
|
259
|
+
def fake_server_without_auth_enabled(loop, aiohttp_client, monkeypatch):
|
|
260
|
+
auth_enablement = "False"
|
|
261
|
+
monkeypatch.setenv(
|
|
262
|
+
mwi_env.get_env_name_enable_mwi_auth_token(), str(auth_enablement)
|
|
263
|
+
)
|
|
264
|
+
(
|
|
265
|
+
mwi_auth_token,
|
|
266
|
+
mwi_auth_token_hash,
|
|
267
|
+
) = token_auth.generate_mwi_auth_token_and_hash().values()
|
|
268
|
+
|
|
269
|
+
app = web.Application()
|
|
270
|
+
app["settings"] = {
|
|
271
|
+
"mwi_is_token_auth_enabled": mwi_auth_token != None,
|
|
272
|
+
"mwi_auth_token": mwi_auth_token,
|
|
273
|
+
"mwi_auth_token_hash": mwi_auth_token_hash,
|
|
274
|
+
"mwi_auth_token_name_for_env": mwi_env.get_env_name_mwi_auth_token().lower(),
|
|
275
|
+
}
|
|
276
|
+
app.router.add_get("/", fake_endpoint)
|
|
277
|
+
app.router.add_post("/", fake_endpoint)
|
|
278
|
+
# Setup the session storage
|
|
279
|
+
fernet_key = fernet.Fernet.generate_key()
|
|
280
|
+
f = fernet.Fernet(fernet_key)
|
|
281
|
+
aiohttp_session_setup(
|
|
282
|
+
app, EncryptedCookieStorage(f, cookie_name="matlab-proxy-session")
|
|
283
|
+
)
|
|
284
|
+
return loop.run_until_complete(aiohttp_client(app))
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
async def test_get_value(fake_server_without_auth_enabled):
|
|
288
|
+
fake_server_without_auth_enabled.server.app["value"] = "bar1"
|
|
289
|
+
resp = await fake_server_without_auth_enabled.get("/")
|
|
290
|
+
assert resp.status == web.HTTPOk.status_code
|
|
291
|
+
assert await resp.text() == "value: bar1"
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
async def test_get_value_in_query_params(
|
|
295
|
+
fake_server_without_auth_enabled, get_custom_auth_token_str
|
|
296
|
+
):
|
|
297
|
+
# Server should respond even if token is provided when not needed.
|
|
298
|
+
fake_server_without_auth_enabled.server.app["value"] = "bar2"
|
|
299
|
+
resp = await fake_server_without_auth_enabled.get(
|
|
300
|
+
"/", params={"mwi-auth-token": get_custom_auth_token_str}
|
|
301
|
+
)
|
|
302
|
+
assert resp.status == web.HTTPOk.status_code
|
|
303
|
+
assert await resp.text() == "value: bar2"
|