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.

Files changed (41) hide show
  1. matlab_proxy/app.py +13 -7
  2. matlab_proxy/app_state.py +9 -6
  3. matlab_proxy/constants.py +1 -0
  4. matlab_proxy/gui/asset-manifest.json +3 -3
  5. matlab_proxy/gui/index.html +1 -1
  6. matlab_proxy/gui/static/js/{main.14aa7840.js → main.522d83ba.js} +3 -3
  7. matlab_proxy/gui/static/js/main.522d83ba.js.map +1 -0
  8. matlab_proxy/settings.py +7 -4
  9. matlab_proxy/util/__init__.py +8 -1
  10. matlab_proxy/util/mwi/token_auth.py +19 -5
  11. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/METADATA +1 -1
  12. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/RECORD +40 -20
  13. tests/integration/integration_tests_with_license/test_http_end_points.py +4 -4
  14. tests/integration/integration_tests_without_license/conftest.py +4 -3
  15. tests/integration/integration_tests_without_license/test_matlab_is_down_if_unlicensed.py +3 -0
  16. tests/unit/__init__.py +1 -0
  17. tests/unit/conftest.py +67 -0
  18. tests/unit/test_app.py +1113 -0
  19. tests/unit/test_app_state.py +586 -0
  20. tests/unit/test_constants.py +6 -0
  21. tests/unit/test_ddux.py +22 -0
  22. tests/unit/test_devel.py +246 -0
  23. tests/unit/test_non_dev_mode.py +169 -0
  24. tests/unit/test_settings.py +460 -0
  25. tests/unit/util/__init__.py +3 -0
  26. tests/unit/util/mwi/__init__.py +1 -0
  27. tests/unit/util/mwi/embedded_connector/__init__.py +1 -0
  28. tests/unit/util/mwi/embedded_connector/test_helpers.py +29 -0
  29. tests/unit/util/mwi/embedded_connector/test_request.py +64 -0
  30. tests/unit/util/mwi/test_custom_http_headers.py +281 -0
  31. tests/unit/util/mwi/test_logger.py +49 -0
  32. tests/unit/util/mwi/test_token_auth.py +303 -0
  33. tests/unit/util/mwi/test_validators.py +331 -0
  34. tests/unit/util/test_mw.py +550 -0
  35. tests/unit/util/test_util.py +135 -0
  36. matlab_proxy/gui/static/js/main.14aa7840.js.map +0 -1
  37. /matlab_proxy/gui/static/js/{main.14aa7840.js.LICENSE.txt → main.522d83ba.js.LICENSE.txt} +0 -0
  38. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/LICENSE.md +0 -0
  39. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/WHEEL +0 -0
  40. {matlab_proxy-0.15.0.dist-info → matlab_proxy-0.16.0.dist-info}/entry_points.txt +0 -0
  41. {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"