comparison NewTests/Authorization/test_authorization.py @ 576:80ba6f1d521c

new tests for authorization plugin (native only)
author Alain Mazy <am@osimis.io>
date Wed, 06 Sep 2023 17:04:36 +0200
parents
children 0649a19df194
comparison
equal deleted inserted replaced
575:28fef24147fa 576:80ba6f1d521c
1 import unittest
2 import time
3 import pprint
4 import subprocess
5 from helpers import OrthancTestCase, Helpers
6
7 from orthanc_api_client import OrthancApiClient, generate_test_dicom_file
8 from orthanc_api_client import exceptions as orthanc_exceptions
9
10 import logging
11 import pathlib
12 here = pathlib.Path(__file__).parent.resolve()
13
14
15
16 class TestAuthorization(OrthancTestCase):
17
18 label_a_study_id = None
19 label_b_study_id = None
20 no_label_study_id = None
21 auth_service_process = None
22
23 @classmethod
24 def _terminate(cls):
25 cls.auth_service_process.terminate()
26
27 @classmethod
28 def prepare(cls):
29 test_name = "Authorization"
30 storage_name = "authorization"
31
32 print(f'-------------- preparing {test_name} tests')
33
34 cls.clear_storage(storage_name=storage_name)
35
36 config = {
37 "AuthenticationEnabled": False,
38 "Authorization": {
39 "WebServiceRootUrl": "http://localhost:8020/",
40 "StandardConfigurations": [
41 "orthanc-explorer-2",
42 "stone-webviewer"
43 ],
44 "CheckedLevel": "studies",
45 "TokenHttpHeaders": ["user-token-key"],
46 "TokenGetArguments": ["resource-token-key"]
47 }
48 }
49
50 config_path = cls.generate_configuration(
51 config_name=f"{test_name}",
52 storage_name=storage_name,
53 config=config,
54 plugins=Helpers.plugins
55 )
56
57 # Start the auth-service application as a subprocess and wait for it to start
58 cls.auth_service_process = subprocess.Popen(["uvicorn", "auth_service:app", "--host", "0.0.0.0", "--port", "8020"], cwd=here)
59 time.sleep(2)
60
61 if Helpers.break_before_preparation:
62 print(f"++++ It is now time to start your Orthanc under tests with configuration file '{config_path}' +++++")
63 input("Press Enter to continue")
64 else:
65 cls.launch_orthanc_under_tests(
66 config_name=f"{test_name}",
67 storage_name=storage_name,
68 config=config,
69 plugins=Helpers.plugins
70 )
71
72 uploader = OrthancApiClient(cls.o._root_url, headers={"user-token-key": "token-uploader"})
73
74 uploader.delete_all_content()
75
76 # upload a few studies and add labels
77 instances_ids = uploader.upload_file(here / "../../Database/Knix/Loc/IM-0001-0001.dcm")
78 cls.label_a_study_id = uploader.instances.get_parent_study_id(instances_ids[0])
79 uploader.studies.add_label(cls.label_a_study_id, "label_a")
80
81 instances_ids = uploader.upload_file(here / "../../Database/Brainix/Epi/IM-0001-0001.dcm")
82 cls.label_b_study_id = uploader.instances.get_parent_study_id(instances_ids[0])
83 uploader.studies.add_label(cls.label_b_study_id, "label_b")
84
85 instances_ids = uploader.upload_file(here / "../../Database/Comunix/Pet/IM-0001-0001.dcm")
86 cls.no_label_study_id = uploader.instances.get_parent_study_id(instances_ids[0])
87
88
89 def test_admin_user(self):
90
91 o = OrthancApiClient(self.o._root_url, headers={"user-token-key": "token-admin"})
92
93 # make sure we can access all these urls (they would throw if not)
94 system = o.get_system()
95
96 # make sure we can access all studies
97 o.studies.get_tags(self.no_label_study_id)
98 o.studies.get_tags(self.label_a_study_id)
99 o.studies.get_tags(self.label_b_study_id)
100
101 # make sure we can access series and instances of these studies
102 series_ids = o.studies.get_series_ids(self.label_a_study_id)
103 instances_ids = o.series.get_instances_ids(series_ids[0])
104 o.instances.get_tags(instances_ids[0])
105
106 # make sure labels filtering still works
107 self.assertEqual(3, len(o.studies.find(query={},
108 labels=[],
109 labels_constraint='Any')))
110
111 self.assertEqual(2, len(o.studies.find(query={},
112 labels=['label_a', 'label_b'],
113 labels_constraint='Any')))
114
115 self.assertEqual(2, len(o.studies.find(query={},
116 labels=['label_a'],
117 labels_constraint='None')))
118
119 all_labels = o.get_all_labels()
120 self.assertEqual(2, len(all_labels))
121
122 def test_user_a(self):
123
124 o = OrthancApiClient(self.o._root_url, headers={"user-token-key": "token-user-a"})
125
126 # # make sure we can access all these urls (they would throw if not)
127 # system = o.get_system()
128
129 all_labels = o.get_all_labels()
130 self.assertEqual(1, len(all_labels))
131 self.assertEqual("label_a", all_labels[0])
132
133 # make sure we can access only the label_a studies
134 with self.assertRaises(orthanc_exceptions.HttpError) as ctx:
135 o.studies.get_tags(self.label_b_study_id)
136 self.assertEqual(403, ctx.exception.http_status_code)
137
138 with self.assertRaises(orthanc_exceptions.HttpError) as ctx:
139 o.studies.get_tags(self.no_label_study_id)
140 self.assertEqual(403, ctx.exception.http_status_code)
141
142 # should not raise
143 o.studies.get_tags(self.label_a_study_id)
144
145 # make sure we can access series and instances of the label_a studies
146 series_ids = o.studies.get_series_ids(self.label_a_study_id)
147 instances_ids = o.series.get_instances_ids(series_ids[0])
148 o.instances.get_tags(instances_ids[0])
149
150 # make sure we can not access series and instances of the label_b studies
151 with self.assertRaises(orthanc_exceptions.HttpError) as ctx:
152 series_ids = o.studies.get_series_ids(self.label_b_study_id)
153 self.assertEqual(403, ctx.exception.http_status_code)
154
155 # make sure tools/find only returns the label_a studies
156 studies = o.studies.find(query={},
157 labels=[],
158 labels_constraint='Any')
159 self.assertEqual(1, len(studies))
160 self.assertEqual(self.label_a_study_id, studies[0].orthanc_id)
161
162 # if searching Any of label_a & label_b, return only label_a
163 studies = o.studies.find(query={},
164 labels=['label_a', 'label_b'],
165 labels_constraint='Any')
166 self.assertEqual(1, len(studies))
167 self.assertEqual(self.label_a_study_id, studies[0].orthanc_id)
168
169 # if searching Any of label_b, expect a Forbidden access
170 with self.assertRaises(orthanc_exceptions.HttpError) as ctx:
171 studies = o.studies.find(query={},
172 labels=['label_b'],
173 labels_constraint='Any')
174 self.assertEqual(403, ctx.exception.http_status_code)
175
176 # if searching None of label_b, expect a Forbidden access because we are not able to compute this filter
177 with self.assertRaises(orthanc_exceptions.HttpError) as ctx:
178 studies = o.studies.find(query={},
179 labels=['label_b'],
180 labels_constraint='None')
181 self.assertEqual(403, ctx.exception.http_status_code)
182
183 # if searching All of label_b, expect a Forbidden access because we are not able to compute this filter
184 with self.assertRaises(orthanc_exceptions.HttpError) as ctx:
185 studies = o.studies.find(query={},
186 labels=['label_b'],
187 labels_constraint='All')
188 self.assertEqual(403, ctx.exception.http_status_code)
189
190 studies = o.studies.find(query={"PatientName": "KNIX"}, # KNIX is label_a
191 labels=[],
192 labels_constraint='Any')
193 self.assertEqual(1, len(studies))
194
195 studies = o.studies.find(query={"PatientName": "KNIX"}, # KNIX is label_a
196 labels=['label_a'],
197 labels_constraint='Any')
198 self.assertEqual(1, len(studies))
199
200 with self.assertRaises(orthanc_exceptions.HttpError) as ctx:
201 studies = o.studies.find(query={"PatientName": "KNIX"}, # KNIX is label_a
202 labels=['label_b'],
203 labels_constraint='Any')
204 self.assertEqual(403, ctx.exception.http_status_code)