Passed
Push — dev ( d62152...d10d14 )
by Salim
03:23
created

Dicom_Web_Access::getRelatedVisitID()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
nc 5
nop 1
dl 0
loc 13
c 0
b 0
f 0
cc 7
rs 8.8333
1
<?php
2
/**
3
 Copyright (C) 2018 KANOUN Salim
4
 This program is free software; you can redistribute it and/or modify
5
 it under the terms of the Affero GNU General Public v.3 License as published by
6
 the Free Software Foundation;
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
 Affero GNU General Public Public for more details.
11
 You should have received a copy of the Affero GNU General Public Public along
12
 with this program; if not, write to the Free Software Foundation, Inc.,
13
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
 */
15
16
/**
17
 * Check access for each call of the DICOMWeb Protocol (for OHIF / Viewer integration)
18
 * @author salim
19
 *
20
 */
21
class Dicom_Web_Access {
22
23
    private $isStudyMetadataRequested;
24
    private $isSerieRequested;
25
    private $requestedURI;
26
    private $userObject;
27
    private $userRole;
28
    private $linkpdo;
29
    
30
    public function __construct(string $requestedURI, User $userObject, string $userRole, PDO $linkpdo){
31
        $this->requestedURI=$requestedURI;
32
        $this->userObject=$userObject;
33
        $this->userRole=$userRole;
34
        $this->linkpdo=$linkpdo;
35
        
36
        if( $this->endsWith($requestedURI, "/series") ) $this->isStudyMetadataRequested=true; 
37
        else $this->isSerieRequested=true;
38
        
39
    }
40
    
41
    /**
42
     * Output the decision for access allowance
43
     * @return boolean
44
     */
45
    public function getDecision(){
46
        //Get related visit ID of the called ressource
47
        $id_visit=$this->getRelatedVisitID($this->getUID());
48
        
49
        //Return test of acess allowance
50
        return $this->isAccessAllowedForUser($id_visit);
51
    }
52
    
53
    /**
54
     * Isolate the called Study or Series Instance UID 
55
     * @return string
56
     */
57
    private function getUID(){
58
        if($this->isSerieRequested) $level="series";
59
        else if($this->isStudyMetadataRequested) $level="studies";
60
        $studySubString=strstr($this->requestedURI, "/".$level."/");
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $level does not seem to be defined for all execution paths leading up to this point.
Loading history...
61
        $studySubString=str_replace("/".$level."/", "", $studySubString);
62
        $endStudyUIDPosition=strpos($studySubString, "/");
63
        $studyUID=substr($studySubString, 0, $endStudyUIDPosition);
64
        return $studyUID;
65
    }
66
    
67
    /**
68
     * Check if called ressource is allowed for current user
69
     * @param string $uid
70
     * @return string
71
     */
72
    private function getRelatedVisitID(string $uid){
73
       
74
        if($this->isSerieRequested) {
75
            $seriesObject=Series_Details::getSerieObjectByUID($uid, $this->linkpdo);
76
            if($this->userRole != User::SUPERVISOR && $seriesObject->deleted) throw new Exception('Deleted Series');
77
            $studyObject=$seriesObject->studyDetailsObject;
78
            
79
        } else if($this->isStudyMetadataRequested) {
80
            $studyObject=Study_Details::getStudyObjectByUID($uid, $this->linkpdo);
81
            if($this->userRole != User::SUPERVISOR && $studyObject->deleted) throw new Exception('Deleted Study');
82
        }
83
        
84
        return $studyObject->idVisit;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $studyObject does not seem to be defined for all execution paths leading up to this point.
Loading history...
85
        
86
    }
87
    
88
    /**
89
     * Check that visit is granter for the calling user (still awaiting review or still awaiting QC)
90
     * @param string $id_visit
91
     * @return boolean
92
     */
93
    private function isAccessAllowedForUser(string $id_visit){
94
        
95
        $visitObject=new Visit($id_visit, $this->linkpdo);
96
        
97
        //Check Visit Availability of the calling user
98
        if($this->userRole == User::REVIEWER || ($this->userRole == User::INVESTIGATOR && $visitObject->uploadStatus==Visit::DONE) ) {
99
            //Check that visit is in patient that is still awaiting for some reviews
100
            $visitCheck=$this->userObject->isVisitAllowed($id_visit, $this->userRole);
101
        }else if($this->userRole == User::CONTROLLER){
102
            //Check that QC status still require an action from Controller
103
            if(in_array($visitObject->stateQualityControl, array(Visit::QC_WAIT_DEFINITVE_CONCLUSION, Visit::QC_NOT_DONE)) ){
104
                $visitCheck=$this->userObject->isVisitAllowed($id_visit, $this->userRole);
105
            }
106
        }else if($this->userRole == User::SUPERVISOR){
107
            $visitCheck=$this->userObject->isVisitAllowed($id_visit, $this->userRole);
108
        }else {
109
            //Other roles can't have access to images
110
            $visitCheck=false;
111
        }
112
        
113
        return $visitCheck;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $visitCheck does not seem to be defined for all execution paths leading up to this point.
Loading history...
114
        
115
    }
116
117
    private function endsWith($haystack, $needle) {
118
        return substr_compare($haystack, $needle, -strlen($needle)) === 0;
119
    }
120
121
}