diff --git a/lib/CandidateAuthorization.php b/lib/CandidateAuthorization.php new file mode 100644 index 000000000..454d51843 --- /dev/null +++ b/lib/CandidateAuthorization.php @@ -0,0 +1,58 @@ +get($candidateID); + } + + public static function canAccessCandidate($candidateID, &$candidate = null) + { + $candidate = self::getCandidate($candidateID); + if (empty($candidate)) + { + return false; + } + + if ($candidate['isAdminHidden'] == 1 && + $_SESSION['CATS']->getAccessLevel('candidates.hidden') < ACCESS_LEVEL_SA) + { + return false; + } + + return true; + } + + public static function getAttachment($attachmentID) + { + $attachments = new Attachments(); + return $attachments->get($attachmentID); + } + + public static function canAccessCandidateAttachment($attachmentID, &$attachment = null) + { + $attachment = self::getAttachment($attachmentID); + if (!isset($attachment['attachmentID'])) + { + return false; + } + + if ($attachment['dataItemType'] == DATA_ITEM_CANDIDATE) + { + $candidate = null; + return self::canAccessCandidate($attachment['dataItemID'], $candidate); + } + + return true; + } +} + +?> diff --git a/modules/attachments/AttachmentsUI.php b/modules/attachments/AttachmentsUI.php index 7d18c25fe..6b2aa0256 100755 --- a/modules/attachments/AttachmentsUI.php +++ b/modules/attachments/AttachmentsUI.php @@ -29,6 +29,7 @@ include_once(LEGACY_ROOT . '/lib/CommonErrors.php'); include_once(LEGACY_ROOT . '/lib/Attachments.php'); +include_once(LEGACY_ROOT . '/lib/CandidateAuthorization.php'); class AttachmentsUI extends UserInterface { @@ -83,7 +84,7 @@ private function getAttachment() $attachments = new Attachments(); $rs = $attachments->get($attachmentID, false); - if (empty($rs) || md5($rs['directoryName']) != $_GET['directoryNameHash']) + if (!isset($rs['attachmentID']) || md5($rs['directoryName']) != $_GET['directoryNameHash']) { CommonErrors::fatal( COMMONERROR_BADFIELDS, @@ -91,6 +92,15 @@ private function getAttachment() 'Invalid id / directory / filename, or you do not have permission to access this attachment.' ); } + + if (!CandidateAuthorization::canAccessCandidateAttachment($attachmentID, $rs)) + { + CommonErrors::fatal( + COMMONERROR_PERMISSION, + $this, + 'Invalid user level for action.' + ); + } $directoryName = $rs['directoryName']; $fileName = $rs['storedFilename']; diff --git a/modules/candidates/CandidatesUI.php b/modules/candidates/CandidatesUI.php index a68a46fe7..a72249807 100755 --- a/modules/candidates/CandidatesUI.php +++ b/modules/candidates/CandidatesUI.php @@ -32,6 +32,7 @@ include_once(LEGACY_ROOT . '/lib/ResultSetUtility.php'); include_once(LEGACY_ROOT . '/lib/DateUtility.php'); /* Depends on StringUtility. */ include_once(LEGACY_ROOT . '/lib/Candidates.php'); +include_once(LEGACY_ROOT . '/lib/CandidateAuthorization.php'); include_once(LEGACY_ROOT . '/lib/Pipelines.php'); include_once(LEGACY_ROOT . '/lib/Attachments.php'); include_once(LEGACY_ROOT . '/lib/ActivityEntries.php'); @@ -890,8 +891,7 @@ private function add($contents = '', $fields = array()) { $associatedAttachment = $_GET['attachmentID']; - $attachments = new Attachments(); - $associatedAttachmentRS = $attachments->get($associatedAttachment); + $associatedAttachmentRS = $this->enforceAttachmentCandidateHiddenAccess($associatedAttachment); /* Show an attachment icon based on the document's file type. */ $attachmentIcon = strtolower( @@ -1277,6 +1277,9 @@ private function onEdit() return; } + $candidateID = $_POST['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); + /* Bail out if we don't have a valid owner user ID. */ if (!$this->isOptionalIDValid('owner', $_POST)) { @@ -1339,7 +1342,6 @@ private function onEdit() $phoneWork = $this->getTrimmedInput('phoneWork', $_POST); } - $candidateID = $_POST['candidateID']; $owner = $_POST['owner']; /* Can Relocate */ @@ -1520,6 +1522,7 @@ private function onDelete() } $candidateID = $_POST['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); if (!eval(Hooks::get('CANDIDATE_DELETE'))) return; @@ -1574,6 +1577,8 @@ private function considerForJobSearch($candidateIDArray = array()) CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); return; } + + $this->enforceCandidateHiddenAccess($candidateID); } /* Bail out to prevent an error if the POST string doesn't even contain @@ -1713,6 +1718,11 @@ private function onAddToPipeline() } + foreach ($candidateIDArray as $candidateID) + { + $this->enforceCandidateHiddenAccess($candidateID); + } + $jobOrderID = $_POST['jobOrderID']; if (!eval(Hooks::get('CANDIDATE_ADD_TO_PIPELINE_PRE'))) return; @@ -1785,16 +1795,7 @@ private function addActivity() $selectedJobOrderID = -1; } $candidateID = $_GET['candidateID']; - - $candidates = new Candidates(); - $candidateData = $candidates->get($candidateID); - - /* Bail out if we got an empty result set. */ - if (empty($candidateData)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this); - return; - } + $candidateData = $this->enforceCandidateHiddenAccess($candidateID); $pipelines = new Pipelines(); $pipelineRS = $pipelines->getNonClosedCandidatePipeline($candidateID); @@ -1875,16 +1876,7 @@ private function changeStatus() $selectedJobOrderID = -1; } $candidateID = $_GET['candidateID']; - - $candidates = new Candidates(); - $candidateData = $candidates->get($candidateID); - - /* Bail out if we got an empty result set. */ - if (empty($candidateData)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this); - return; - } + $candidateData = $this->enforceCandidateHiddenAccess($candidateID); $pipelines = new Pipelines(); $pipelineRS = $pipelines->getCandidatePipeline($candidateID); @@ -2002,6 +1994,7 @@ private function onAddCandidateTags() } $candidateID = $_POST['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); $tagIDs = $_POST['candidate_tags']; $tags = new Tags(); @@ -2025,19 +2018,7 @@ private function addCandidateTags() } $candidateID = $_GET['candidateID']; - - $candidates = new Candidates(); - $candidateData = $candidates->get($candidateID); - - /* Bail out if we got an empty result set. */ - if (empty($candidateData)) - { - CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this); - return; - /*$this->fatalModal( - 'The specified candidate ID could not be found.' - );*/ - } + $this->enforceCandidateHiddenAccess($candidateID); $tags = new Tags(); $tagsRS = $tags->getAll(); @@ -2099,6 +2080,7 @@ private function onRemoveFromPipeline() } $candidateID = $_POST['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); $jobOrderID = $_POST['jobOrderID']; if (!eval(Hooks::get('CANDIDATE_REMOVE_FROM_PIPELINE_PRE'))) return; @@ -2460,6 +2442,8 @@ private function viewResume() if (!empty($data)) { + $this->enforceCandidateHiddenAccess($data['candidateID']); + /* Keyword highlighting. */ $data['text'] = SearchUtility::makePreview($query, $data['text']); } @@ -2471,6 +2455,28 @@ private function viewResume() $this->_template->display('./modules/candidates/ResumeView.tpl'); } + private function enforceCandidateHiddenAccess($candidateID) + { + $candidate = null; + if (!CandidateAuthorization::canAccessCandidate($candidateID, $candidate)) + { + CommonErrors::fatalModal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + + return $candidate; + } + + private function enforceAttachmentCandidateHiddenAccess($attachmentID) + { + $attachment = null; + if (!CandidateAuthorization::canAccessCandidateAttachment($attachmentID, $attachment)) + { + CommonErrors::fatalModal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); + } + + return $attachment; + } + private function addEditImage() { /* Bail out if we don't have a valid candidate ID. */ @@ -2480,6 +2486,7 @@ private function addEditImage() } $candidateID = $_GET['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); $attachments = new Attachments(); $attachmentsRS = $attachments->getAll( @@ -2508,6 +2515,7 @@ private function onAddEditImage() } $candidateID = $_POST['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); if (!eval(Hooks::get('CANDIDATE_ON_ADD_EDIT_IMAGE_PRE'))) return; @@ -2545,6 +2553,7 @@ private function createAttachment() } $candidateID = $_GET['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); if (!eval(Hooks::get('CANDIDATE_CREATE_ATTACHMENT'))) return; @@ -2574,6 +2583,7 @@ private function onCreateAttachment() } $candidateID = $_POST['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); if ($_POST['resume'] == '1') { @@ -2639,6 +2649,15 @@ private function onDeleteAttachment() $candidateID = $_POST['candidateID']; $attachmentID = $_POST['attachmentID']; + $attachment = $this->enforceAttachmentCandidateHiddenAccess($attachmentID); + if ($attachment['dataItemType'] != DATA_ITEM_CANDIDATE || + $attachment['dataItemID'] != $candidateID) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid attachment ID.'); + } + + $this->enforceCandidateHiddenAccess($attachment['dataItemID']); + if (!eval(Hooks::get('CANDIDATE_ON_DELETE_ATTACHMENT_PRE'))) return; $attachments = new Attachments(); @@ -2958,6 +2977,7 @@ private function _addCandidate($isModal, $directoryOverride = '') if (isset($_POST['associatedAttachment'])) { $attachmentID = $_POST['associatedAttachment']; + $this->enforceAttachmentCandidateHiddenAccess($attachmentID); $attachments = new Attachments(); $attachments->setDataItemID($attachmentID, $candidateID, DATA_ITEM_CANDIDATE); @@ -3160,6 +3180,7 @@ private function _addActivity($isJobOrdersMode, $regardingID, } $candidateID = $_POST['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); if (!eval(Hooks::get('CANDIDATE_ON_ADD_ACTIVITY_CHANGE_STATUS_PRE'))) return; @@ -3531,6 +3552,7 @@ private function _changeStatus($isJobOrdersMode, $regardingID, } $candidateID = $_POST['candidateID']; + $this->enforceCandidateHiddenAccess($candidateID); if (!eval(Hooks::get('CANDIDATE_ON_ADD_ACTIVITY_CHANGE_STATUS_PRE'))) return; @@ -3786,8 +3808,8 @@ private function onShowQuestionnaire() CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Bad Server Information.'); } + $cData = $this->enforceCandidateHiddenAccess($candidateID); $candidates = new Candidates(); - $cData = $candidates->get($candidateID); $questionnaire = new Questionnaire(); $qData = $questionnaire->getCandidateQuestionnaire($candidateID, $title); diff --git a/modules/companies/CompaniesUI.php b/modules/companies/CompaniesUI.php index d0e1f0eeb..cca4e690e 100755 --- a/modules/companies/CompaniesUI.php +++ b/modules/companies/CompaniesUI.php @@ -1145,6 +1145,32 @@ private function onSearch() $this->_template->display('./modules/companies/Search.tpl'); } + private function getCompanyForAction($companyID) + { + $companies = new Companies(); + $company = $companies->get($companyID); + if (empty($company)) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'The specified company ID could not be found.'); + } + + return $company; + } + + private function getCompanyAttachmentForAction($attachmentID, $companyID) + { + $attachments = new Attachments(); + $attachment = $attachments->get($attachmentID); + if (!isset($attachment['attachmentID']) || + $attachment['dataItemType'] != DATA_ITEM_COMPANY || + $attachment['dataItemID'] != $companyID) + { + CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid attachment ID.'); + } + + return $attachment; + } + /* * Called by handleRequest() to process loading the create attachment * modal dialog. @@ -1158,6 +1184,7 @@ private function createAttachment() } $companyID = $_GET['companyID']; + $this->getCompanyForAction($companyID); if (!eval(Hooks::get('CLIENTS_CREATE_ATTACHMENT'))) return; @@ -1180,6 +1207,7 @@ private function onCreateAttachment() } $companyID = $_POST['companyID']; + $this->getCompanyForAction($companyID); if (!eval(Hooks::get('CLIENTS_ON_CREATE_ATTACHMENT_PRE'))) return; @@ -1221,6 +1249,8 @@ private function onDeleteAttachment() $companyID = $_POST['companyID']; $attachmentID = $_POST['attachmentID']; + $this->getCompanyForAction($companyID); + $this->getCompanyAttachmentForAction($attachmentID, $companyID); if (!eval(Hooks::get('CLIENTS_ON_DELETE_ATTACHMENT_PRE'))) return; diff --git a/modules/lists/ajax/addToLists.php b/modules/lists/ajax/addToLists.php index 6e43adaef..523cf8fc0 100755 --- a/modules/lists/ajax/addToLists.php +++ b/modules/lists/ajax/addToLists.php @@ -32,6 +32,7 @@ include_once(LEGACY_ROOT . '/lib/StringUtility.php'); include_once(LEGACY_ROOT . '/lib/ActivityEntries.php'); include_once(LEGACY_ROOT . '/lib/SavedLists.php'); +include_once(LEGACY_ROOT . '/lib/CandidateAuthorization.php'); function isRequiredValueValid($value) { @@ -130,6 +131,19 @@ function isRequiredValueValid($value) } } +if ((int) $dataItemType === DATA_ITEM_CANDIDATE) +{ + foreach ($itemsToAdd as $item) + { + $candidate = null; + if (!CandidateAuthorization::canAccessCandidate($item, $candidate)) + { + $interface->outputXMLErrorPage(-1, ERROR_NO_PERMISSION); + die(); + } + } +} + $savedLists = new SavedLists(); /* Write changes. */