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_JURY_PRESIDENT
- ROLE_CURRENT_COURSE_TEACHER
- ROLE_CURRENT_SESSION_COURSE_TEACHER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
ROLE_GLOBAL_ADMIN: [ROLE_ADMIN, 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_SESSION_MANAGER: [ROLE_STUDENT, ROLE_SESSION_MANAGER, ROLE_ALLOWED_TO_SWITCH]
ROLE_STUDENT: [ROLE_STUDENT]
ROLE_CURRENT_TEACHER: []
ROLE_CURRENT_COURSE_STUDENT: [ROLE_CURRENT_COURSE_STUDENT] # Set in the course listener
ROLE_CURRENT_COURSE_STUDENT: [ROLE_CURRENT_COURSE_STUDENT] # Set in the CourseListener
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_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;
}
/**
* @param Room $room
*
* @return Course
*/
public function setRoom($room)
public function setRoom(Room $room): self
{
$this->room = $room;
return $this;
}
/**
* @return bool
*/
public function isActive()
public function isActive(): bool
{
$activeVisibilityList = [
self::REGISTERED,
@ -1264,10 +1256,7 @@ class Course extends AbstractResource implements ResourceInterface, ResourceWith
return self::HIDDEN === $this->visibility;
}
/**
* @return array
*/
public static function getStatusList()
public static function getStatusList(): array
{
return [
self::CLOSED => 'Closed',
@ -1286,10 +1275,7 @@ class Course extends AbstractResource implements ResourceInterface, ResourceWith
return $this->currentSession;
}
/**
* @return $this
*/
public function setCurrentSession(Session $session)
public function setCurrentSession(Session $session): self
{
// If the session is registered in the course session list.
/*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)
public function setCurrentUrl(AccessUrl $url): self
{
$urlList = $this->getUrls();
/** @var AccessUrlRelCourse $item */

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

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

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

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

@ -20,27 +20,30 @@ use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
//* attributes={"security"="is_granted('ROLE_ADMIN')"},
/**
* @ApiResource(
* shortName="Documents",
* normalizationContext={"groups"={"document:read", "resource_node:read"}},
* denormalizationContext={"groups"={"document:write"}},
* itemOperations={
* "put" ={
* "controller"=UpdateResourceNodeFileAction::class,
* "deserialize"=false,
* "security"="is_granted('ROLE_USER')",
* "validation_groups"={"Default", "media_object_create", "document:write"},
* },
* "get",
* "delete"
* itemOperations={
* "put" ={
* "controller"=UpdateResourceNodeFileAction::class,
* "deserialize"=false,
* "security" = "is_granted('EDIT', object.resourceNode)",
* "validation_groups"={"Default", "media_object_create", "document:write"},
* },
* "get" = {
* "security" = "is_granted('VIEW', object.resourceNode)",
* },
* "delete" = {
* "security" = "is_granted('DELETE', object.resourceNode)",
* },
* },
* collectionOperations={
* collectionOperations={
* "post"={
* "controller"=CreateResourceNodeFileAction::class,
* "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"},
* "openapi_context"={
* "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"})

Loading…
Cancel
Save