diff --git a/src/CoreBundle/Component/Utils/ResourceSettings.php b/src/CoreBundle/Component/Utils/ResourceSettings.php index 4b6843ff01..8c76b6678b 100644 --- a/src/CoreBundle/Component/Utils/ResourceSettings.php +++ b/src/CoreBundle/Component/Utils/ResourceSettings.php @@ -11,12 +11,15 @@ class ResourceSettings public $allowResourceContentCreation; /** @var bool */ public $allowResourceUploadCreation; + /** @var bool */ + public $allowEditResource; public function __construct() { $this->allowNodeFolderCreation = true; $this->allowResourceContentCreation = true; $this->allowResourceUploadCreation = true; + $this->allowEditResource = true; } /** @@ -79,4 +82,23 @@ class ResourceSettings return $this; } + /** + * @return bool + */ + public function isAllowEditResource(): bool + { + return $this->allowEditResource; + } + + /** + * @param bool $allowEditResource + * + * @return ResourceSettings + */ + public function setAllowEditResource(bool $allowEditResource): ResourceSettings + { + $this->allowEditResource = $allowEditResource; + + return $this; + } } diff --git a/src/CoreBundle/Controller/ResourceController.php b/src/CoreBundle/Controller/ResourceController.php index 8312fe3c7a..f38cd73079 100644 --- a/src/CoreBundle/Controller/ResourceController.php +++ b/src/CoreBundle/Controller/ResourceController.php @@ -133,6 +133,8 @@ class ResourceController extends AbstractResourceController implements CourseCon $source = new Entity($class, 'resource'); $parentNode = $repository->getResourceNodeRepository()->find($resourceNodeId); + $settings = $repository->getResourceSettings(); + $this->denyAccessUnlessGranted( ResourceNodeVoter::VIEW, $parentNode, @@ -258,7 +260,7 @@ class ResourceController extends AbstractResourceController implements CourseCon } // Delete mass action. - if ($this->isGranted(ResourceNodeVoter::DELETE, $this->getCourse())) { + if ($this->isGranted(ResourceNodeVoter::DELETE, $parentNode)) { $deleteMassAction = new MassAction( 'Delete', 'ChamiloCoreBundle:Resource:deleteMass', @@ -327,7 +329,7 @@ class ResourceController extends AbstractResourceController implements CourseCon $myRowAction->addManipulateRender($setNodeParameters); $grid->addRowAction($myRowAction); - if ($this->isGranted(ResourceNodeVoter::EDIT, $this->getCourse())) { + if ($this->isGranted(ResourceNodeVoter::EDIT, $parentNode)) { // Enable/Disable $myRowAction = new RowAction( '', @@ -342,7 +344,11 @@ class ResourceController extends AbstractResourceController implements CourseCon $id = $resource->getResourceNode()->getId(); $icon = 'fa-eye-slash'; - $link = $resource->getCourseSessionResourceLink($this->getCourse(), $this->getSession()); + if ($this->hasCourse()) { + $link = $resource->getCourseSessionResourceLink($this->getCourse(), $this->getSession()); + } else { + $link = $resource->getFirstResourceLink(); + } if ($link === null) { return null; @@ -365,16 +371,19 @@ class ResourceController extends AbstractResourceController implements CourseCon $myRowAction->addManipulateRender($setVisibleParameters); $grid->addRowAction($myRowAction); - // Edit action. - $myRowAction = new RowAction( - $this->trans('Edit'), - 'chamilo_core_resource_edit', - false, - '_self', - ['class' => 'btn btn-secondary', 'icon' => 'fa fa-pen'] - ); - $myRowAction->addManipulateRender($setNodeParameters); - $grid->addRowAction($myRowAction); + if($settings->isAllowEditResource()) { + + // Edit action. + $myRowAction = new RowAction( + $this->trans('Edit'), + 'chamilo_core_resource_edit', + false, + '_self', + ['class' => 'btn btn-secondary', 'icon' => 'fa fa-pen'] + ); + $myRowAction->addManipulateRender($setNodeParameters); + $grid->addRowAction($myRowAction); + } // More action. $myRowAction = new RowAction( @@ -618,7 +627,11 @@ class ResourceController extends AbstractResourceController implements CourseCon ); /** @var ResourceLink $link */ - $link = $resource->getCourseSessionResourceLink($this->getCourse(), $this->getSession()); + if ($this->hasCourse()) { + $link = $resource->getCourseSessionResourceLink($this->getCourse(), $this->getSession()); + } else { + $link = $resource->getFirstResourceLink(); + } $icon = 'fa-eye'; // Use repository to change settings easily. diff --git a/src/CoreBundle/Entity/Resource/AbstractResource.php b/src/CoreBundle/Entity/Resource/AbstractResource.php index d804b9e67f..eb9e359f20 100644 --- a/src/CoreBundle/Entity/Resource/AbstractResource.php +++ b/src/CoreBundle/Entity/Resource/AbstractResource.php @@ -42,14 +42,25 @@ abstract class AbstractResource return $this->resourceNode; } - /** - * @return ResourceLink - */ - public function getCourseSessionResourceLink(Course $course, Session $session = null) + public function getCourseSessionResourceLink(Course $course, Session $session = null): ?ResourceLink { return $this->getFirstResourceLinkFromCourseSession($course, $session); } + public function getFirstResourceLink(): ?ResourceLink + { + $resourceNode = $this->getResourceNode(); + + if ($resourceNode && $resourceNode->getResourceLinks()) { + $result = $resourceNode->getResourceLinks()->first(); + if ($result) { + return $result; + } + } + + return null; + } + /** * See ResourceLink to see the visibility constants. Example: ResourceLink::VISIBILITY_DELETED. * diff --git a/src/CoreBundle/Repository/PersonalFileRepository.php b/src/CoreBundle/Repository/PersonalFileRepository.php index d7fee3f59a..c7ac87853a 100644 --- a/src/CoreBundle/Repository/PersonalFileRepository.php +++ b/src/CoreBundle/Repository/PersonalFileRepository.php @@ -20,6 +20,7 @@ final class PersonalFileRepository extends ResourceRepository implements Resourc ->setAllowNodeFolderCreation(true) //->setAllowResourceContentCreation(true) ->setAllowResourceUploadCreation(true) + ->setAllowEditResource(false) ; return $settings; diff --git a/src/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php b/src/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php index 0742d0322a..bda6ad109b 100644 --- a/src/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php +++ b/src/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php @@ -113,6 +113,12 @@ class ResourceNodeVoter extends Voter // Check if I'm the owner. $creator = $resourceNode->getCreator(); + // @todo improve permission handling for always public resource file type. + // Illustration are always visible. + if ($resourceNode->getResourceType()->getName() === 'illustrations') { + return true; + } + if ($creator instanceof UserInterface && $user->getUsername() === $creator->getUsername()) { return true; @@ -136,6 +142,7 @@ class ResourceNodeVoter extends Voter $linkFound = false; break; } + $linkUser = $link->getUser(); // Check if resource was sent to the current user. if ($linkUser instanceof UserInterface && @@ -147,7 +154,7 @@ class ResourceNodeVoter extends Voter $linkCourse = $link->getCourse(); $linkSession = $link->getSession(); - $linkUserGroup = $link->getUserGroup(); + //$linkUserGroup = $link->getUserGroup(); // @todo Check if resource was sent to a usergroup // @todo Check if resource was sent to a group inside a course @@ -178,6 +185,11 @@ class ResourceNodeVoter extends Voter break; } } + + if ($link->getVisibility() === ResourceLink::VISIBILITY_PUBLISHED) { + $linkFound = true; + break; + } } // No link was found or not available @@ -187,6 +199,8 @@ class ResourceNodeVoter extends Voter // Getting rights from the link $rightFromResourceLink = $link->getResourceRight(); + + $rights = []; if ($rightFromResourceLink->count() > 0) { // Taken rights from the link $rights = $rightFromResourceLink; @@ -200,19 +214,19 @@ class ResourceNodeVoter extends Voter $readerMask = self::getReaderMask(); $editorMask = self::getEditorMask(); - $resourceRight = new ResourceRight(); - $resourceRight - ->setMask($editorMask) - ->setRole(self::ROLE_CURRENT_COURSE_TEACHER) - ; - $rights[] = $resourceRight; + if (!empty($courseId)) { + $resourceRight = new ResourceRight(); + $resourceRight + ->setMask($editorMask) + ->setRole(self::ROLE_CURRENT_COURSE_TEACHER); + $rights[] = $resourceRight; - $resourceRight = new ResourceRight(); - $resourceRight - ->setMask($readerMask) - ->setRole(self::ROLE_CURRENT_COURSE_STUDENT) - ; - $rights[] = $resourceRight; + $resourceRight = new ResourceRight(); + $resourceRight + ->setMask($readerMask) + ->setRole(self::ROLE_CURRENT_COURSE_STUDENT); + $rights[] = $resourceRight; + } if (!empty($sessionId)) { $resourceRight = new ResourceRight(); @@ -229,6 +243,15 @@ class ResourceNodeVoter extends Voter ; $rights[] = $resourceRight; } + if (empty($rights) && $link->getVisibility() === ResourceLink::VISIBILITY_PUBLISHED) { + // Give just read access + $resourceRight = new ResourceRight(); + $resourceRight + ->setMask($readerMask) + ->setRole('ROLE_USER') + ; + $rights[] = $resourceRight; + } } // Asked mask