Internal - Add voters when using api platform, fix documents visibility.

pull/3464/head
Julio Montoya 5 years ago
parent 80355de806
commit 0b0dc1b950
  1. 4
      config/packages/security.yaml
  2. 27
      src/CoreBundle/Entity/Course.php
  3. 2
      src/CoreBundle/Entity/ResourceComment.php
  4. 1
      src/CoreBundle/Entity/User.php
  5. 1
      src/CoreBundle/Entity/Usergroup.php
  6. 57
      src/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php
  7. 31
      src/CourseBundle/Entity/CDocument.php

@ -28,6 +28,7 @@ security:
- ROLE_DIRECTOR - ROLE_DIRECTOR
- ROLE_JURY_PRESIDENT - ROLE_JURY_PRESIDENT
- ROLE_CURRENT_COURSE_TEACHER - ROLE_CURRENT_COURSE_TEACHER
- ROLE_CURRENT_SESSION_COURSE_TEACHER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
ROLE_GLOBAL_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] ROLE_GLOBAL_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
ROLE_RRHH: [ROLE_TEACHER, ROLE_ALLOWED_TO_SWITCH] ROLE_RRHH: [ROLE_TEACHER, ROLE_ALLOWED_TO_SWITCH]
@ -35,8 +36,7 @@ security:
ROLE_QUESTION_MANAGER: [ROLE_STUDENT, ROLE_QUESTION_MANAGER] ROLE_QUESTION_MANAGER: [ROLE_STUDENT, ROLE_QUESTION_MANAGER]
ROLE_SESSION_MANAGER: [ROLE_STUDENT, ROLE_SESSION_MANAGER, ROLE_ALLOWED_TO_SWITCH] ROLE_SESSION_MANAGER: [ROLE_STUDENT, ROLE_SESSION_MANAGER, ROLE_ALLOWED_TO_SWITCH]
ROLE_STUDENT: [ROLE_STUDENT] ROLE_STUDENT: [ROLE_STUDENT]
ROLE_CURRENT_TEACHER: [] ROLE_CURRENT_COURSE_STUDENT: [ROLE_CURRENT_COURSE_STUDENT] # Set in the CourseListener
ROLE_CURRENT_COURSE_STUDENT: [ROLE_CURRENT_COURSE_STUDENT] # Set in the course listener
ROLE_CURRENT_COURSE_TEACHER: [ROLE_CURRENT_COURSE_TEACHER, ROLE_CURRENT_COURSE_STUDENT] # Set in the course listener ROLE_CURRENT_COURSE_TEACHER: [ROLE_CURRENT_COURSE_TEACHER, ROLE_CURRENT_COURSE_STUDENT] # Set in the course listener
ROLE_CURRENT_SESSION_COURSE_STUDENT: [ROLE_CURRENT_SESSION_COURSE_STUDENT] ROLE_CURRENT_SESSION_COURSE_STUDENT: [ROLE_CURRENT_SESSION_COURSE_STUDENT]
ROLE_CURRENT_SESSION_COURSE_TEACHER: [ROLE_CURRENT_SESSION_COURSE_STUDENT, ROLE_CURRENT_SESSION_COURSE_TEACHER] ROLE_CURRENT_SESSION_COURSE_TEACHER: [ROLE_CURRENT_SESSION_COURSE_STUDENT, ROLE_CURRENT_SESSION_COURSE_TEACHER]

@ -1225,22 +1225,14 @@ class Course extends AbstractResource implements ResourceInterface, ResourceWith
return $this->room; return $this->room;
} }
/** public function setRoom(Room $room): self
* @param Room $room
*
* @return Course
*/
public function setRoom($room)
{ {
$this->room = $room; $this->room = $room;
return $this; return $this;
} }
/** public function isActive(): bool
* @return bool
*/
public function isActive()
{ {
$activeVisibilityList = [ $activeVisibilityList = [
self::REGISTERED, self::REGISTERED,
@ -1264,10 +1256,7 @@ class Course extends AbstractResource implements ResourceInterface, ResourceWith
return self::HIDDEN === $this->visibility; return self::HIDDEN === $this->visibility;
} }
/** public static function getStatusList(): array
* @return array
*/
public static function getStatusList()
{ {
return [ return [
self::CLOSED => 'Closed', self::CLOSED => 'Closed',
@ -1286,10 +1275,7 @@ class Course extends AbstractResource implements ResourceInterface, ResourceWith
return $this->currentSession; return $this->currentSession;
} }
/** public function setCurrentSession(Session $session): self
* @return $this
*/
public function setCurrentSession(Session $session)
{ {
// If the session is registered in the course session list. // If the session is registered in the course session list.
/*if ($this->getSessions()->contains($session->getId())) { /*if ($this->getSessions()->contains($session->getId())) {
@ -1309,10 +1295,7 @@ class Course extends AbstractResource implements ResourceInterface, ResourceWith
return $this; return $this;
} }
/** public function setCurrentUrl(AccessUrl $url): self
* @return $this
*/
public function setCurrentUrl(AccessUrl $url)
{ {
$urlList = $this->getUrls(); $urlList = $this->getUrls();
/** @var AccessUrlRelCourse $item */ /** @var AccessUrlRelCourse $item */

@ -16,7 +16,7 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* @ApiResource( * @ApiResource(
* attributes={"security"="is_granted('ROLE_USER')"}, * attributes={"security"="is_granted('ROLE_ADMIN')"},
* normalizationContext={"groups"={"comment:read"}} * normalizationContext={"groups"={"comment:read"}}
* ) * )
* *

@ -29,7 +29,6 @@ use Symfony\Component\Validator\Mapping\ClassMetadata;
* @ApiResource( * @ApiResource(
* attributes={"security"="is_granted('ROLE_ADMIN')"}, * attributes={"security"="is_granted('ROLE_ADMIN')"},
* iri="http://schema.org/Person", * iri="http://schema.org/Person",
* attributes={"security"="is_granted('ROLE_ADMIN')"},
* normalizationContext={"groups"={"user:read"}}, * normalizationContext={"groups"={"user:read"}},
* denormalizationContext={"groups"={"user:write"}}, * denormalizationContext={"groups"={"user:write"}},
* collectionOperations={"get"}, * collectionOperations={"get"},

@ -11,6 +11,7 @@ use Gedmo\Timestampable\Traits\TimestampableEntity;
/** /**
* @ApiResource( * @ApiResource(
* attributes={"security"="is_granted('ROLE_ADMIN')"},
* normalizationContext={"groups"={"usergroup:read"}} * normalizationContext={"groups"={"usergroup:read"}}
* ) * )
* *

@ -143,14 +143,17 @@ class ResourceNodeVoter extends Voter
$request = $this->requestStack->getCurrentRequest(); $request = $this->requestStack->getCurrentRequest();
// @todo fix parameters. // @todo fix parameters.
$courseId = $request->get('cid'); $courseId = (int) $request->get('cid');
$sessionId = $request->get('sid'); $sessionId = (int) $request->get('sid');
$links = $resourceNode->getResourceLinks(); $links = $resourceNode->getResourceLinks();
$linkFound = false; $linkFound = false;
$courseManager = $this->entityManager->getRepository(Course::class); $courseManager = $this->entityManager->getRepository(Course::class);
$sessionManager = $this->entityManager->getRepository(Session::class); $sessionManager = $this->entityManager->getRepository(Session::class);
$course = null;
$link = null;
// @todo implement view, edit, delete. // @todo implement view, edit, delete.
foreach ($links as $link) { foreach ($links as $link) {
// Block access if visibility is deleted. Creator and admin already can access before. // Block access if visibility is deleted. Creator and admin already can access before.
@ -178,8 +181,9 @@ class ResourceNodeVoter extends Voter
} }
// @todo Check if resource was sent to a usergroup // @todo Check if resource was sent to a usergroup
// @todo Check if resource was sent to a group inside a course // @todo Check if resource was sent to a group inside a course.
// Check if resource was sent to a course inside a session
// Check if resource was sent to a course inside a session.
if ($linkSession instanceof Session && !empty($sessionId) && if ($linkSession instanceof Session && !empty($sessionId) &&
$linkCourse instanceof Course && !empty($courseId) $linkCourse instanceof Course && !empty($courseId)
) { ) {
@ -196,24 +200,21 @@ class ResourceNodeVoter extends Voter
} }
} }
// Check if resource was sent to a course // Check if resource was sent to a course.
if ($linkCourse instanceof Course && !empty($courseId)) { if ($linkCourse instanceof Course && !empty($courseId)) {
$course = $courseManager->find($courseId); //$course = $courseManager->find($courseId);
if ($linkCourse->getId() === $courseId) {
if ($course instanceof Course &&
$linkCourse->getCode() === $course->getCode()
) {
$linkFound = true; $linkFound = true;
break; break;
} }
} }
if (ResourceLink::VISIBILITY_PUBLISHED === $link->getVisibility()) { /*if (ResourceLink::VISIBILITY_PUBLISHED === $link->getVisibility()) {
$linkFound = true; $linkFound = true;
break; break;
} }*/
} }
// No link was found or not available. // No link was found or not available.
@ -223,7 +224,7 @@ class ResourceNodeVoter extends Voter
// Getting rights from the link // Getting rights from the link
$rightFromResourceLink = $link->getResourceRight(); $rightFromResourceLink = $link->getResourceRight();
$allowAnonsToSee = false;
$rights = []; $rights = [];
if ($rightFromResourceLink->count() > 0) { if ($rightFromResourceLink->count() > 0) {
// Taken rights from the link // Taken rights from the link
@ -239,8 +240,8 @@ class ResourceNodeVoter extends Voter
// Anons: Only read. // Anons: Only read.
$readerMask = self::getReaderMask(); $readerMask = self::getReaderMask();
$editorMask = self::getEditorMask(); $editorMask = self::getEditorMask();
error_log($courseId);
if (!empty($courseId)) { if ($courseId) {
$resourceRight = new ResourceRight(); $resourceRight = new ResourceRight();
$resourceRight $resourceRight
->setMask($editorMask) ->setMask($editorMask)
@ -253,7 +254,8 @@ class ResourceNodeVoter extends Voter
->setRole(self::ROLE_CURRENT_COURSE_STUDENT); ->setRole(self::ROLE_CURRENT_COURSE_STUDENT);
$rights[] = $resourceRight; $rights[] = $resourceRight;
if ($course->isPublic() && ResourceLink::VISIBILITY_PUBLISHED === $link->getVisibility()) { if (ResourceLink::VISIBILITY_PUBLISHED === $link->getVisibility() && $link->getCourse()->isPublic()) {
$allowAnonsToSee = true;
$resourceRight = new ResourceRight(); $resourceRight = new ResourceRight();
$resourceRight $resourceRight
->setMask($readerMask) ->setMask($readerMask)
@ -289,6 +291,8 @@ class ResourceNodeVoter extends Voter
} }
} }
error_log(print_r($rights, 1));
// Asked mask // Asked mask
$mask = new MaskBuilder(); $mask = new MaskBuilder();
$mask->add($attribute); $mask->add($attribute);
@ -301,13 +305,14 @@ class ResourceNodeVoter extends Voter
// @todo move this in a service // @todo move this in a service
$anon = new Role('IS_AUTHENTICATED_ANONYMOUSLY'); $anon = new Role('IS_AUTHENTICATED_ANONYMOUSLY');
$userRole = new Role('ROLE_USER'); $userRole = new Role('ROLE_USER');
$teacher = new Role('ROLE_TEACHER');
$student = new Role('ROLE_STUDENT'); $student = new Role('ROLE_STUDENT');
$currentTeacher = new Role(self::ROLE_CURRENT_COURSE_TEACHER); $teacher = new Role('ROLE_TEACHER');
$currentStudent = new Role(self::ROLE_CURRENT_COURSE_STUDENT); $currentStudent = new Role(self::ROLE_CURRENT_COURSE_STUDENT);
$currentTeacher = new Role(self::ROLE_CURRENT_COURSE_TEACHER);
$currentTeacherSession = new Role(self::ROLE_CURRENT_SESSION_COURSE_TEACHER);
$currentStudentSession = new Role(self::ROLE_CURRENT_SESSION_COURSE_STUDENT); $currentStudentSession = new Role(self::ROLE_CURRENT_SESSION_COURSE_STUDENT);
$currentTeacherSession = new Role(self::ROLE_CURRENT_SESSION_COURSE_TEACHER);
$superAdmin = new Role('ROLE_SUPER_ADMIN'); $superAdmin = new Role('ROLE_SUPER_ADMIN');
$admin = new Role('ROLE_ADMIN'); $admin = new Role('ROLE_ADMIN');
@ -326,9 +331,9 @@ class ResourceNodeVoter extends Voter
->addRole($admin) ->addRole($admin)
; ;
// Add a resource. // Add a security resource.
$resource = new SecurityResource($link); $securityResource = new SecurityResource($link);
$acl->addResource($resource); $acl->addResource($securityResource);
// Check all the right this link has. // Check all the right this link has.
// Set rights from the ResourceRight. // Set rights from the ResourceRight.
@ -342,7 +347,9 @@ class ResourceNodeVoter extends Voter
$acl->allow($student, null, self::getReaderMask()); $acl->allow($student, null, self::getReaderMask());
// Anons can see. // Anons can see.
$acl->allow($anon, null, self::getReaderMask()); if ($allowAnonsToSee) {
$acl->allow($anon, null, self::getReaderMask());
}
// Teacher can view/edit // Teacher can view/edit
$acl->allow( $acl->allow(
@ -359,7 +366,7 @@ class ResourceNodeVoter extends Voter
$acl->allow($superAdmin); $acl->allow($superAdmin);
if ($token instanceof AnonymousToken) { if ($token instanceof AnonymousToken) {
if ($acl->isAllowed('IS_AUTHENTICATED_ANONYMOUSLY', $resource, $askedMask)) { if ($acl->isAllowed('IS_AUTHENTICATED_ANONYMOUSLY', $securityResource, $askedMask)) {
return true; return true;
} }
@ -367,7 +374,7 @@ class ResourceNodeVoter extends Voter
} }
foreach ($user->getRoles() as $role) { foreach ($user->getRoles() as $role) {
if ($acl->isAllowed($role, $resource, $askedMask)) { if ($acl->isAllowed($role, $securityResource, $askedMask)) {
return true; return true;
} }
} }

@ -20,27 +20,30 @@ use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
//* attributes={"security"="is_granted('ROLE_ADMIN')"},
/** /**
* @ApiResource( * @ApiResource(
* shortName="Documents", * shortName="Documents",
* normalizationContext={"groups"={"document:read", "resource_node:read"}}, * normalizationContext={"groups"={"document:read", "resource_node:read"}},
* denormalizationContext={"groups"={"document:write"}}, * denormalizationContext={"groups"={"document:write"}},
* itemOperations={ * itemOperations={
* "put" ={ * "put" ={
* "controller"=UpdateResourceNodeFileAction::class, * "controller"=UpdateResourceNodeFileAction::class,
* "deserialize"=false, * "deserialize"=false,
* "security"="is_granted('ROLE_USER')", * "security" = "is_granted('EDIT', object.resourceNode)",
* "validation_groups"={"Default", "media_object_create", "document:write"}, * "validation_groups"={"Default", "media_object_create", "document:write"},
* }, * },
* "get", * "get" = {
* "delete" * "security" = "is_granted('VIEW', object.resourceNode)",
* },
* "delete" = {
* "security" = "is_granted('DELETE', object.resourceNode)",
* },
* }, * },
* collectionOperations={ * collectionOperations={
* "post"={ * "post"={
* "controller"=CreateResourceNodeFileAction::class, * "controller"=CreateResourceNodeFileAction::class,
* "deserialize"=false, * "deserialize"=false,
* "security"="is_granted('ROLE_USER')", * "security"="is_granted('ROLE_CURRENT_COURSE_TEACHER') or is_granted('ROLE_CURRENT_SESSION_COURSE_TEACHER')",
* "validation_groups"={"Default", "media_object_create", "document:write"}, * "validation_groups"={"Default", "media_object_create", "document:write"},
* "openapi_context"={ * "openapi_context"={
* "requestBody"={ * "requestBody"={
@ -93,7 +96,9 @@ use Symfony\Component\Validator\Constraints as Assert;
* } * }
* } * }
* }, * },
* "get", * "get" = {
* "security"="is_granted('ROLE_USER')",
* },
* }, * },
* ) * )
* @ApiFilter(SearchFilter::class, properties={"title": "partial", "resourceNode.parent": "exact"}) * @ApiFilter(SearchFilter::class, properties={"title": "partial", "resourceNode.parent": "exact"})

Loading…
Cancel
Save