_baseFileAccessPolicy = $this->buildFileAccessPolicy($request, $args, $roleAssignments, $mode, $submissionFileId, $submissionParameterName); } /** * * @param PKPRequest $request * @param array $args * @param array $roleAssignments * @param int $mode bitfield * @param int $submissionFileId * @param string $submissionParameterName */ public function buildFileAccessPolicy($request, $args, $roleAssignments, $mode, $submissionFileId, $submissionParameterName) { // We need a submission matching the file in the request. $this->addPolicy(new SubmissionRequiredPolicy($request, $args, $submissionParameterName)); $this->addPolicy(new SubmissionFileMatchesSubmissionPolicy($request, $submissionFileId)); // Authors, managers and series editors potentially have // access to submission files. We'll have to define // differentiated policies for those roles in a policy set. $fileAccessPolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES); // // Site administrator role if (isset($roleAssignments[Role::ROLE_ID_SITE_ADMIN])) { $adminPolicy = new PolicySet(PolicySet::COMBINING_DENY_OVERRIDES); $adminPolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, Role::ROLE_ID_SITE_ADMIN, $roleAssignments[Role::ROLE_ID_SITE_ADMIN])); // A valid workflow stage needs to be in the authorized objects for most file operations $stageId = (int) $request->getUserVar('stageId'); $adminPolicy->addPolicy(new WorkflowStageRequiredPolicy($stageId)); $fileAccessPolicy->addPolicy($adminPolicy); } // // Managerial role // if (isset($roleAssignments[Role::ROLE_ID_MANAGER])) { // Managers can access all submission files as long as the manager has not // been assigned to a lesser role in the stage. $managerFileAccessPolicy = new PolicySet(PolicySet::COMBINING_DENY_OVERRIDES); $managerFileAccessPolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, Role::ROLE_ID_MANAGER, $roleAssignments[Role::ROLE_ID_MANAGER])); $stageId = $request->getUserVar('stageId'); // WORKFLOW_STAGE_ID_... $managerFileAccessPolicy->addPolicy(new SubmissionFileMatchesWorkflowStageIdPolicy($request, $submissionFileId, $stageId)); $managerFileAccessPolicy->addPolicy(new WorkflowStageAccessPolicy($request, $args, $roleAssignments, 'submissionId', $stageId)); $managerFileAccessPolicy->addPolicy(new AssignedStageRoleHandlerOperationPolicy($request, Role::ROLE_ID_MANAGER, $roleAssignments[Role::ROLE_ID_MANAGER], $stageId)); $fileAccessPolicy->addPolicy($managerFileAccessPolicy); } // // Author role // if (isset($roleAssignments[Role::ROLE_ID_AUTHOR])) { // 1) Author role user groups can access whitelisted operations ... $authorFileAccessPolicy = new PolicySet(PolicySet::COMBINING_DENY_OVERRIDES); $authorFileAccessPolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, Role::ROLE_ID_AUTHOR, $roleAssignments[Role::ROLE_ID_AUTHOR])); // 2) ...if they are assigned to the workflow stage as an author. Note: This loads the application-specific policy class. $stageId = $request->getUserVar('stageId'); $authorFileAccessPolicy->addPolicy(new WorkflowStageAccessPolicy($request, $args, $roleAssignments, 'submissionId', $stageId)); $authorFileAccessPolicy->addPolicy(new SubmissionFileMatchesWorkflowStageIdPolicy($request, $submissionFileId, $stageId)); $authorFileAccessPolicy->addPolicy(new AssignedStageRoleHandlerOperationPolicy($request, Role::ROLE_ID_AUTHOR, $roleAssignments[Role::ROLE_ID_AUTHOR], $stageId)); // 3) ...and if they meet one of the following requirements: $authorFileAccessOptionsPolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES); // 3a) If the file was uploaded by the current user, allow... $authorFileAccessOptionsPolicy->addPolicy(new SubmissionFileUploaderAccessPolicy($request, $submissionFileId)); // 3b) ...or if the file is a file in a review round with requested revision decision, allow... // Note: This loads the application-specific policy class $authorFileAccessOptionsPolicy->addPolicy(new SubmissionFileRequestedRevisionRequiredPolicy($request, $submissionFileId)); // ...or if we don't want to modify the file... if (!($mode & self::SUBMISSION_FILE_ACCESS_MODIFY)) { // 3c) ...the file is at submission stage... $authorFileAccessOptionsPolicy->addPolicy(new SubmissionFileStageRequiredPolicy($request, $submissionFileId, SubmissionFile::SUBMISSION_FILE_SUBMISSION)); // 3d) ...or the file is a viewable reviewer response... $authorFileAccessOptionsPolicy->addPolicy(new SubmissionFileStageRequiredPolicy($request, $submissionFileId, SubmissionFile::SUBMISSION_FILE_REVIEW_ATTACHMENT, true)); // 3e) ...or if the file is part of a query assigned to the user... $authorFileAccessOptionsPolicy->addPolicy(new SubmissionFileAssignedQueryAccessPolicy($request, $submissionFileId)); // 3f) ...or the file is at revision stage... $authorFileAccessOptionsPolicy->addPolicy(new SubmissionFileStageRequiredPolicy($request, $submissionFileId, SubmissionFile::SUBMISSION_FILE_REVIEW_REVISION)); // 3f) ...or the file is at revision stage... $authorFileAccessOptionsPolicy->addPolicy(new SubmissionFileStageRequiredPolicy($request, $submissionFileId, SubmissionFile::SUBMISSION_FILE_INTERNAL_REVIEW_REVISION)); // 3g) ...or the file is a copyedited file... $authorFileAccessOptionsPolicy->addPolicy(new SubmissionFileStageRequiredPolicy($request, $submissionFileId, SubmissionFile::SUBMISSION_FILE_COPYEDIT)); // 3h) ...or the file is a representation (galley/publication format)... $authorFileAccessOptionsPolicy->addPolicy(new SubmissionFileStageRequiredPolicy($request, $submissionFileId, SubmissionFile::SUBMISSION_FILE_PROOF)); } // Add the rules from 3) $authorFileAccessPolicy->addPolicy($authorFileAccessOptionsPolicy); $fileAccessPolicy->addPolicy($authorFileAccessPolicy); } // // Reviewer role // if (isset($roleAssignments[Role::ROLE_ID_REVIEWER])) { // 1) Reviewers can access whitelisted operations ... $reviewerFileAccessPolicy = new PolicySet(PolicySet::COMBINING_DENY_OVERRIDES); $reviewerFileAccessPolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, Role::ROLE_ID_REVIEWER, $roleAssignments[Role::ROLE_ID_REVIEWER])); // 2) ...if they meet one of the following requirements: $reviewerFileAccessOptionsPolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES); // 2a) If the file was uploaded by the current user, allow. $reviewerFileAccessOptionsPolicy->addPolicy(new SubmissionFileUploaderAccessPolicy($request, $submissionFileId)); // 2b) If the file is part of an assigned review, and we're not // trying to modify it, allow. if (!($mode & self::SUBMISSION_FILE_ACCESS_MODIFY)) { $reviewerFileAccessOptionsPolicy->addPolicy(new SubmissionFileAssignedReviewerAccessPolicy($request, $submissionFileId)); } // 2c) If the file is part of a query assigned to the user, allow. $reviewerFileAccessOptionsPolicy->addPolicy(new SubmissionFileAssignedQueryAccessPolicy($request, $submissionFileId)); // Add the rules from 2) $reviewerFileAccessPolicy->addPolicy($reviewerFileAccessOptionsPolicy); // Add this policy set $fileAccessPolicy->addPolicy($reviewerFileAccessPolicy); } // // Assistant role. // if (isset($roleAssignments[Role::ROLE_ID_ASSISTANT])) { // 1) Assistants can access whitelisted operations... $contextAssistantFileAccessPolicy = new PolicySet(PolicySet::COMBINING_DENY_OVERRIDES); $contextAssistantFileAccessPolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, Role::ROLE_ID_ASSISTANT, $roleAssignments[Role::ROLE_ID_ASSISTANT])); // 2) ... but only if they have been assigned to the submission workflow as an assistant. // Note: This loads the application-specific policy class $stageId = $request->getUserVar('stageId'); $contextAssistantFileAccessPolicy->addPolicy(new WorkflowStageAccessPolicy($request, $args, $roleAssignments, 'submissionId', $stageId)); $contextAssistantFileAccessPolicy->addPolicy(new SubmissionFileMatchesWorkflowStageIdPolicy($request, $submissionFileId, $stageId)); $contextAssistantFileAccessPolicy->addPolicy(new AssignedStageRoleHandlerOperationPolicy($request, Role::ROLE_ID_ASSISTANT, $roleAssignments[Role::ROLE_ID_ASSISTANT], $stageId)); // 3) ...and if they meet one of the following requirements: $contextAssistantFileAccessOptionsPolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES); // 3a) ...the file not part of a query... $contextAssistantFileAccessOptionsPolicy->addPolicy(new SubmissionFileNotQueryAccessPolicy($request, $submissionFileId)); // 3b) ...or the file is part of a query they are assigned to... $contextAssistantFileAccessOptionsPolicy->addPolicy(new SubmissionFileAssignedQueryAccessPolicy($request, $submissionFileId)); // Add the rules from 3 $contextAssistantFileAccessPolicy->addPolicy($contextAssistantFileAccessOptionsPolicy); $fileAccessPolicy->addPolicy($contextAssistantFileAccessPolicy); } // // Sub editor role // if (isset($roleAssignments[Role::ROLE_ID_SUB_EDITOR])) { // 1) Sub editors can access all operations on submissions ... $subEditorFileAccessPolicy = new PolicySet(PolicySet::COMBINING_DENY_OVERRIDES); $subEditorFileAccessPolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, Role::ROLE_ID_SUB_EDITOR, $roleAssignments[Role::ROLE_ID_SUB_EDITOR])); // 2) ... but only if they have been assigned as a subeditor to the requested submission ... $stageId = $request->getUserVar('stageId'); $subEditorFileAccessPolicy->addPolicy(new WorkflowStageAccessPolicy($request, $args, $roleAssignments, 'submissionId', $stageId)); $subEditorFileAccessPolicy->addPolicy(new UserAccessibleWorkflowStageRequiredPolicy($request)); $subEditorFileAccessPolicy->addPolicy(new AssignedStageRoleHandlerOperationPolicy($request, Role::ROLE_ID_SUB_EDITOR, $roleAssignments[Role::ROLE_ID_SUB_EDITOR], $stageId)); $subEditorFileAccessPolicy->addPolicy(new SubmissionFileMatchesWorkflowStageIdPolicy($request, $submissionFileId, $stageId)); // 3) ...and if they meet one of the following requirements: $subEditorQueryFileAccessPolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES); // 3a) ...the file not part of a query... $subEditorQueryFileAccessPolicy->addPolicy(new SubmissionFileNotQueryAccessPolicy($request, $submissionFileId)); // 3b) ...or the file is part of a query they are assigned to... $subEditorQueryFileAccessPolicy->addPolicy(new SubmissionFileAssignedQueryAccessPolicy($request, $submissionFileId)); // Add the rules from 3 $subEditorFileAccessPolicy->addPolicy($subEditorQueryFileAccessPolicy); // 4) ... and only if they are not also assigned as an author and this is not part of a anonymous review $subEditorFileAccessPolicy->addPolicy(new SubmissionFileAuthorEditorPolicy($request, $submissionFileId)); $fileAccessPolicy->addPolicy($subEditorFileAccessPolicy); } $this->addPolicy($fileAccessPolicy); return $fileAccessPolicy; } } if (!PKP_STRICT_MODE) { class_alias('\PKP\security\authorization\SubmissionFileAccessPolicy', '\SubmissionFileAccessPolicy'); define('SUBMISSION_FILE_ACCESS_READ', SubmissionFileAccessPolicy::SUBMISSION_FILE_ACCESS_READ); define('SUBMISSION_FILE_ACCESS_MODIFY', SubmissionFileAccessPolicy::SUBMISSION_FILE_ACCESS_MODIFY); }