-
Notifications
You must be signed in to change notification settings - Fork 444
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6266 from NateWr/i6257_stable320
#6257 Apply additional policies to submission file uploads
- Loading branch information
Showing
20 changed files
with
732 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?php | ||
/** | ||
* @file classes/security/authorization/NoteAccessPolicy.inc.php | ||
* | ||
* Copyright (c) 2014-2020 Simon Fraser University | ||
* Copyright (c) 2000-2020 John Willinsky | ||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. | ||
* | ||
* @class NoteAccessPolicy | ||
* @ingroup security_authorization | ||
* | ||
* @brief Class to control access to a note | ||
* | ||
* NB: This policy expects previously authorized submission, query and | ||
* accessibile workflow stages in the authorization context. | ||
*/ | ||
|
||
import('lib.pkp.classes.security.authorization.AuthorizationPolicy'); | ||
|
||
define('NOTE_ACCESS_READ', 1); | ||
define('NOTE_ACCESS_WRITE', 2); | ||
|
||
class NoteAccessPolicy extends AuthorizationPolicy { | ||
|
||
/** @var Request */ | ||
private $_request; | ||
|
||
/** @var int */ | ||
private $_noteId; | ||
|
||
/** @var int */ | ||
private $_accessMode; | ||
|
||
/** | ||
* Constructor | ||
* @param $request PKPRequest | ||
* @param $noteId int | ||
* @param $accessMode int NOTE_ACCESS_... | ||
*/ | ||
function __construct($request, $noteId, $accessMode) { | ||
parent::__construct('user.authorization.accessDenied'); | ||
$this->_request = $request; | ||
$this->_noteId = $noteId; | ||
$this->_accessMode = $accessMode; | ||
} | ||
|
||
// | ||
// Implement template methods from AuthorizationPolicy | ||
// | ||
/** | ||
* @see AuthorizationPolicy::effect() | ||
*/ | ||
function effect() { | ||
|
||
if (!$this->_noteId) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
$query = $this->getAuthorizedContextObject(ASSOC_TYPE_QUERY); | ||
$submission = $this->getAuthorizedContextObject(ASSOC_TYPE_SUBMISSION); | ||
$assignedStages = $this->getAuthorizedContextObject(ASSOC_TYPE_ACCESSIBLE_WORKFLOW_STAGES); | ||
|
||
if (!$query || !$submission || empty($assignedStages)) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
$noteDao = DAORegistry::getDAO('NoteDAO'); /* @var $noteDao NoteDAO */ | ||
$note = $noteDao->getById($this->_noteId); | ||
|
||
if (!is_a($note, 'Note')) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
// Note, query, submission and assigned stages must match | ||
if ($note->getAssocId() != $query->getId() | ||
|| $note->getAssocType() != ASSOC_TYPE_QUERY | ||
|| $query->getAssocId() != $submission->getId() | ||
|| $query->getAssocType() != ASSOC_TYPE_SUBMISSION | ||
|| !array_key_exists($query->getStageId(), $assignedStages) | ||
|| empty($assignedStages[$query->getStageId()])) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
// Notes can only be edited by their original creators | ||
if ($this->_accessMode === NOTE_ACCESS_WRITE | ||
&& $note->getUserId() != $this->_request->getUser()->getId()) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
$this->addAuthorizedContextObject(ASSOC_TYPE_NOTE, $note); | ||
|
||
return AUTHORIZATION_PERMIT; | ||
} | ||
} | ||
|
||
|
100 changes: 100 additions & 0 deletions
100
classes/security/authorization/ReviewAssignmentFileWritePolicy.inc.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
<?php | ||
/** | ||
* @file classes/security/authorization/ReviewAssignmentFileWritePolicy.inc.php | ||
* | ||
* Copyright (c) 2014-2020 Simon Fraser University | ||
* Copyright (c) 2000-2020 John Willinsky | ||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. | ||
* | ||
* @class ReviewAssignmentFileWritePolicy | ||
* @ingroup security_authorization_internal | ||
* | ||
* @brief Authorize access to add, edit and delete reviewer attachments. This policy | ||
* expects review round, submission, assigned workflow stages and user roles to be | ||
* in the authorized context. | ||
*/ | ||
|
||
import('lib.pkp.classes.security.authorization.AuthorizationPolicy'); | ||
|
||
class ReviewAssignmentFileWritePolicy extends AuthorizationPolicy { | ||
|
||
/** @var Request */ | ||
private $_request; | ||
|
||
/** @var int */ | ||
private $_reviewAssignmentId; | ||
|
||
/** | ||
* Constructor | ||
* @param $request PKPRequest | ||
* @param $reviewAssignmentId int | ||
*/ | ||
function __construct($request, $reviewAssignmentId) { | ||
parent::__construct('user.authorization.accessDenied'); | ||
$this->_request = $request; | ||
$this->_reviewAssignmentId = $reviewAssignmentId; | ||
} | ||
|
||
// | ||
// Implement template methods from AuthorizationPolicy | ||
// | ||
/** | ||
* @see AuthorizationPolicy::effect() | ||
*/ | ||
function effect() { | ||
|
||
if (!$this->_reviewAssignmentId) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
$reviewRound = $this->getAuthorizedContextObject(ASSOC_TYPE_REVIEW_ROUND); | ||
$submission = $this->getAuthorizedContextObject(ASSOC_TYPE_SUBMISSION); | ||
$assignedStages = $this->getAuthorizedContextObject(ASSOC_TYPE_ACCESSIBLE_WORKFLOW_STAGES); | ||
$userRoles = $this->getAuthorizedContextObject(ASSOC_TYPE_USER_ROLES); | ||
|
||
if (!$reviewRound || !$submission) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /* @var $noteDao ReviewAssignmentDAO */ | ||
$reviewAssignment = $reviewAssignmentDao->getById($this->_reviewAssignmentId); | ||
|
||
if (!is_a($reviewAssignment, 'ReviewAssignment')) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
// Review assignment, review round and submission must match | ||
if ($reviewAssignment->getReviewRoundId() != $reviewRound->getId() | ||
|| $reviewRound->getSubmissionId() != $submission->getId()) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
// Managers can write review attachments when they are not assigned to a submission | ||
if (empty($stageAssignments) && in_array(ROLE_ID_MANAGER, $userRoles)) { | ||
$this->addAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT, $reviewAssignment); | ||
return AUTHORIZATION_PERMIT; | ||
} | ||
|
||
// Managers, editors and assistants can write review attachments when they are assigned | ||
// to the correct stage. | ||
if (!empty($assignedStages[$reviewRound->getStageId()])) { | ||
$allowedRoles = [ROLE_ID_MANAGER, ROLE_ID_SUB_EDITOR, ROLE_ID_ASSISTANT]; | ||
if (!empty(array_intersect($allowedRoles, $assignedStages[$reviewRound->getStageId()]))) { | ||
$this->addAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT, $reviewAssignment); | ||
return AUTHORIZATION_PERMIT; | ||
} | ||
} | ||
|
||
// Reviewers can write review attachments to their own review assigments, | ||
// if the assignment is not yet complete, cancelled or declined. | ||
if ($reviewAssignment->getReviewerId() == $this->_request->getUser()->getId()) { | ||
$notAllowedStatuses = [REVIEW_ASSIGNMENT_STATUS_DECLINED, REVIEW_ASSIGNMENT_STATUS_COMPLETE, REVIEW_ASSIGNMENT_STATUS_THANKED, REVIEW_ASSIGNMENT_STATUS_CANCELLED]; | ||
if (!in_array($reviewAssignment->getStatus(), $notAllowedStatuses)) { | ||
$this->addAuthorizedContextObject(ASSOC_TYPE_REVIEW_ASSIGNMENT, $reviewAssignment); | ||
return AUTHORIZATION_PERMIT; | ||
} | ||
} | ||
|
||
return AUTHORIZATION_DENY; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
classes/security/authorization/internal/RepresentationUploadAccessPolicy.inc.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
<?php | ||
/** | ||
* @file classes/security/authorization/internal/RepresentationUploadAccessPolicy.inc.php | ||
* | ||
* Copyright (c) 2014-2020 Simon Fraser University | ||
* Copyright (c) 2000-2020 John Willinsky | ||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. | ||
* | ||
* @class RepresentationUploadAccessPolicy | ||
* @ingroup security_authorization_internal | ||
* | ||
* @brief Policy that checks whether a file can be uploaded to a representation. | ||
* It checks whether the user is allowed to access the representation file stage, | ||
* whether the representation exists, whether it matches the authorized submission, | ||
* and whether it is not part of a published publication. This policy expects an | ||
* authorized submission in the authorization context. | ||
*/ | ||
|
||
import('lib.pkp.classes.security.authorization.DataObjectRequiredPolicy'); | ||
|
||
class RepresentationUploadAccessPolicy extends DataObjectRequiredPolicy { | ||
|
||
/** @var int */ | ||
public $_representationId; | ||
|
||
/** | ||
* Constructor | ||
* @param $request PKPRequest | ||
* @param $args array request parameters | ||
* @param $representationId int | ||
*/ | ||
function __construct($request, &$args, $representationId) { | ||
parent::__construct($request, $args, 'user.authorization.accessDenied'); | ||
$this->_representationId = $representationId; | ||
} | ||
|
||
// | ||
// Implement template methods from AuthorizationPolicy | ||
// | ||
/** | ||
* @see DataObjectRequiredPolicy::dataObjectEffect() | ||
*/ | ||
function dataObjectEffect() { | ||
AppLocale::requireComponents([LOCALE_COMPONENT_PKP_SUBMISSION, LOCALE_COMPONENT_APP_SUBMISSION]); | ||
|
||
$assignedFileStageIds = $this->getAuthorizedContextObject(ASSOC_TYPE_ACCESSIBLE_FILE_STAGES); | ||
if (empty($assignedFileStageIds) || !in_array(SUBMISSION_FILE_PROOF, $assignedFileStageIds)) { | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
if (empty($this->_representationId)) { | ||
$this->setAdvice(AUTHORIZATION_ADVICE_DENY_MESSAGE, 'user.authorization.representationNotFound'); | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
$representationDao = Application::get()->getRepresentationDAO(); | ||
$representation = $representationDao->getById($this->_representationId); | ||
|
||
if (!$representation) { | ||
$this->setAdvice(AUTHORIZATION_ADVICE_DENY_MESSAGE, 'user.authorization.representationNotFound'); | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
$submission = $this->getAuthorizedContextObject(ASSOC_TYPE_SUBMISSION); | ||
if (!$submission) { | ||
$this->setAdvice(AUTHORIZATION_ADVICE_DENY_MESSAGE, 'user.authorization.invalidSubmission'); | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
$publication = Services::get('publication')->get($representation->getData('publicationId')); | ||
if (!$publication) { | ||
$this->setAdvice(AUTHORIZATION_ADVICE_DENY_MESSAGE, 'galley.publicationNotFound'); | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
// Publication and submission must match | ||
if ($publication->getData('submissionId') !== $submission->getId()) { | ||
$this->setAdvice(AUTHORIZATION_ADVICE_DENY_MESSAGE, 'user.authorization.invalidPublication'); | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
// Representations can not be modified on published publications | ||
if ($publication->getData('status') === STATUS_PUBLISHED) { | ||
$this->setAdvice(AUTHORIZATION_ADVICE_DENY_MESSAGE, 'galley.editPublishedDisabled'); | ||
return AUTHORIZATION_DENY; | ||
} | ||
|
||
$this->addAuthorizedContextObject(ASSOC_TYPE_REPRESENTATION, $representation); | ||
|
||
return AUTHORIZATION_PERMIT; | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.