changeset 370:7eb5b86508b1

added Tests/CheckHttpServerSecurity.py and Tests/CheckIngestTranscoding.py
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 21 Jan 2021 11:38:47 +0100
parents 24d93b42873a
children 6941a4f449cc
files Tests/CheckHttpServerSecurity.py Tests/CheckIngestTranscoding.py
diffstat 2 files changed, 338 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Tests/CheckHttpServerSecurity.py	Thu Jan 21 11:38:47 2021 +0100
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2021 Osimis S.A., Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import json
+import os
+import subprocess
+import sys
+import time
+import Toolbox
+
+if len(sys.argv) != 2:
+    print('Must provide a path to Orthanc binaries')
+    exit(-1)
+
+
+TMP = '/tmp/OrthancTest'
+CONFIG = os.path.join(TMP, 'Configuration.json')
+
+if os.path.exists(TMP):
+    print('Temporary path already exists: %s' % TMP)
+    exit(-1)
+
+os.mkdir(TMP)
+
+
+ORTHANC = Toolbox.DefineOrthanc(username = 'orthanc',
+                                password = 'orthanc')
+
+
+def IsHttpServerSecure(config):
+    with open(CONFIG, 'w') as f:
+        f.write(json.dumps(config))
+    
+    process = subprocess.Popen(
+        [ sys.argv[1], CONFIG ],
+        cwd = TMP,
+        #stdout=subprocess.PIPE, 
+        stderr=subprocess.PIPE, 
+        #shell=True
+        )
+
+    time.sleep(1)
+
+    while True:
+        try:
+            system = Toolbox.DoGet(ORTHANC, '/system')
+            break
+        except:
+            time.sleep(0.1)
+
+    process.terminate()
+    process.wait()
+
+    return system['IsHttpServerSecure']
+
+
+def Assert(b):
+    if not b:
+        raise Exception('Bad result')
+
+
+print('==== TEST 1 ====')
+Assert(IsHttpServerSecure({
+            'RemoteAccessAllowed': False,
+            'RegisteredUsers' : { }
+            }))
+
+print('==== TEST 2 ====')
+Assert(IsHttpServerSecure({
+            'RemoteAccessAllowed': False,
+            'AuthenticationEnabled': False,
+            'RegisteredUsers' : { }
+            }))
+
+print('==== TEST 3 ====')
+Assert(IsHttpServerSecure({
+            'RemoteAccessAllowed': False,
+            'AuthenticationEnabled': True,
+            'RegisteredUsers' : { 'orthanc' : 'orthanc' }
+            }))
+
+print('==== TEST 4 ====')
+Assert(not IsHttpServerSecure({
+            'RemoteAccessAllowed': True
+            }))
+
+print('==== TEST 5 (server application scenario) ====')
+Assert(not IsHttpServerSecure({
+            'RemoteAccessAllowed': True,
+            'AuthenticationEnabled': False,
+            }))
+
+print('==== TEST 6 ====')
+Assert(IsHttpServerSecure({
+            'RemoteAccessAllowed': True,
+            'AuthenticationEnabled': True,
+            'RegisteredUsers' : { 'orthanc' : 'orthanc' }
+            }))
+
+print('==== TEST 7 (Docker scenario) ====')
+Assert(not IsHttpServerSecure({
+            'RemoteAccessAllowed': True,
+            'AuthenticationEnabled': True
+            }))
+
+print('Success!')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Tests/CheckIngestTranscoding.py	Thu Jan 21 11:38:47 2021 +0100
@@ -0,0 +1,214 @@
+#!/usr/bin/env python
+
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2021 Osimis S.A., Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import json
+import os
+import subprocess
+import sys
+import time
+import Toolbox
+
+
+if len(sys.argv) < 2:
+    print('Must provide a path to Orthanc binaries')
+    exit(-1)
+
+
+TMP = '/tmp/OrthancTest'
+CONFIG = os.path.join(TMP, 'Configuration.json')
+ORTHANC = Toolbox.DefineOrthanc()
+
+if os.path.exists(TMP):
+    print('Temporary path already exists: %s' % TMP)
+    exit(-1)
+
+os.mkdir(TMP)
+
+
+def DropOrthanc():
+    while True:
+        try:
+            instances = Toolbox.DoGet(ORTHANC, '/instances')
+            if len(instances) == 0:
+                break
+            else:
+                for i in instances:
+                    Toolbox.DoDelete(ORTHANC, '/instances/%s' % i)
+        except:
+            time.sleep(0.05)
+    
+
+
+def TestTranscoding(config, tests):
+    with open(CONFIG, 'w') as f:
+        f.write(json.dumps(config))
+    
+    process = subprocess.Popen(
+        sys.argv[1:] + [ CONFIG ],
+        cwd = TMP,
+        #stdout=subprocess.PIPE, 
+        stderr=subprocess.PIPE, 
+        #shell=True
+        )
+
+    success = True
+
+    try:
+        for test in tests:
+            DropOrthanc()
+            with open(Toolbox.GetDatabasePath(test[0]), 'rb') as f:
+                Toolbox.DoPost(ORTHANC, '/instances', f.read(), 'application/dicom')
+
+            instances = Toolbox.DoGet(ORTHANC, '/instances')
+            if len(instances) != 1:
+                print('BAD NUMBER OF INSTANCES')
+                success = False
+                break
+
+            metadata = Toolbox.DoGet(ORTHANC, '/instances/%s/metadata?expand' % instances[0])
+            if not 'TransferSyntax' in metadata:
+                print('NO METADATA')
+                success = False
+                break
+
+            if metadata['TransferSyntax'] != test[1]:
+                print('TRANSFER SYNTAX MISMATCH: %s vs %s' % (metadata['TransferSyntax'], test[1]))
+                success = False
+    except:
+        success = False
+            
+    process.terminate()
+    process.wait()
+
+    return success
+
+
+def Assert(b):
+    if not b:
+        raise Exception('Bad result')
+
+
+print('==== TEST 1 ====')  # No transcoding by default
+Assert(TestTranscoding({ }, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.2.dcm', '1.2.840.10008.1.2.2'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.4.51'),
+]))
+
+print('==== TEST 2 ====')
+Assert(TestTranscoding({
+    'IngestTranscoding' : '1.2.840.10008.1.2.1',
+}, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.2.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.1'),
+]))
+
+print('==== TEST 3 ====')
+Assert(TestTranscoding({
+    'IngestTranscoding' : '1.2.840.10008.1.2.1',
+    'IngestTranscodingOfUncompressed' : True,
+    'IngestTranscodingOfCompressed' : True,
+}, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.2.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.1'),
+]))
+
+print('==== TEST 4 ====')
+Assert(TestTranscoding({
+    'IngestTranscoding' : '1.2.840.10008.1.2.1',
+    'IngestTranscodingOfUncompressed' : True,
+    'IngestTranscodingOfCompressed' : False,
+}, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.2.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.4.51'),
+]))
+
+print('==== TEST 5 ====')
+Assert(TestTranscoding({
+    'IngestTranscoding' : '1.2.840.10008.1.2.1',
+    'IngestTranscodingOfUncompressed' : False,
+    'IngestTranscodingOfCompressed' : True,
+}, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.2.dcm', '1.2.840.10008.1.2.2'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.1'),
+]))
+
+print('==== TEST 6 ====')
+Assert(TestTranscoding({
+    'IngestTranscoding' : '1.2.840.10008.1.2.1',
+    'IngestTranscodingOfUncompressed' : False,
+    'IngestTranscodingOfCompressed' : False,
+}, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.2.dcm', '1.2.840.10008.1.2.2'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.4.51'),
+]))
+
+print('==== TEST 7 ====')
+Assert(TestTranscoding({
+    'IngestTranscoding' : '1.2.840.10008.1.2.4.51',
+    'IngestTranscodingOfUncompressed' : True,
+    'IngestTranscodingOfCompressed' : True,
+}, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.4.51'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.4.51'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.57.dcm', '1.2.840.10008.1.2.4.51'),
+]))
+
+print('==== TEST 8 ====')
+Assert(TestTranscoding({
+    'IngestTranscoding' : '1.2.840.10008.1.2.4.51',
+    'IngestTranscodingOfUncompressed' : True,
+    'IngestTranscodingOfCompressed' : False,
+}, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.4.51'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.4.51'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.57.dcm', '1.2.840.10008.1.2.4.57'),
+]))
+
+print('==== TEST 9 ====')
+Assert(TestTranscoding({
+    'IngestTranscoding' : '1.2.840.10008.1.2.4.51',
+    'IngestTranscodingOfUncompressed' : False,
+    'IngestTranscodingOfCompressed' : True,
+}, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.4.51'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.57.dcm', '1.2.840.10008.1.2.4.51'),
+]))
+
+print('==== TEST 10 ====')
+Assert(TestTranscoding({
+    'IngestTranscoding' : '1.2.840.10008.1.2.4.51',
+    'IngestTranscodingOfUncompressed' : False,
+    'IngestTranscodingOfCompressed' : False,
+}, [
+    ('TransferSyntaxes/1.2.840.10008.1.2.1.dcm', '1.2.840.10008.1.2.1'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.51.dcm', '1.2.840.10008.1.2.4.51'),
+    ('TransferSyntaxes/1.2.840.10008.1.2.4.57.dcm', '1.2.840.10008.1.2.4.57'),
+]))
+
+
+print('Success!')