Adds roles to handle CRUD permissions.

ROLE_CURRENT_COURSE_STUDENT  and ROLE_CURRENT_COURSE_TEACHER
1.10.x
Julio Montoya 11 years ago
parent c024248afe
commit bfda337488
  1. 2
      app/AppKernel.php
  2. 6
      app/config/config.yml
  3. 10
      app/config/security.yml
  4. 4
      main/inc/lib/api.lib.php
  5. 73
      src/Chamilo/CoreBundle/Entity/Course.php
  6. 20
      src/Chamilo/CoreBundle/Entity/Manager/CourseManager.php
  7. 31
      src/Chamilo/CoreBundle/Entity/Session.php
  8. 45
      src/Chamilo/CoreBundle/Entity/ToolResourceRights.php
  9. 15
      src/Chamilo/CoreBundle/Resources/config/services.yml
  10. 75
      src/Chamilo/CoreBundle/Security/Authorization/Voter/CourseVoter.php
  11. 133
      src/Chamilo/CoreBundle/Security/Authorization/Voter/ResourceLinkVoter.php
  12. 268
      src/Chamilo/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php
  13. 125
      src/Chamilo/CoreBundle/Security/Authorization/Voter/SessionVoter.php
  14. 15
      src/Chamilo/CourseBundle/EventListener/CourseAccessListener.php
  15. 32
      src/Chamilo/CourseBundle/EventListener/CourseListener.php
  16. 160
      src/Chamilo/NotebookBundle/Controller/NotebookController.php
  17. 2
      src/Chamilo/NotebookBundle/Resources/views/Notebook/index.html.twig

@ -34,7 +34,7 @@ class AppKernel extends Kernel
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new JMS\AopBundle\JMSAopBundle(),
new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(),
//new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(),
new Symfony\Bundle\AsseticBundle\AsseticBundle(),
// Doctrine

@ -177,8 +177,8 @@ swiftmailer:
username: %mailer_user%
password: %mailer_password%
jms_security_extra:
secure_all_services: false
#jms_security_extra:
# secure_all_services: false
jms_serializer:
metadata:
@ -297,4 +297,4 @@ liip_theme:
# inject_on_load: false
# delete_on_update: true
# delete_on_remove: true
# directory_namer: chamilo_core.directory_namer.user_image
# directory_namer: chamilo_core.naming.user_image

@ -12,6 +12,7 @@ security:
- ROLE_TEACHER
- ROLE_DIRECTOR
- ROLE_JURY_PRESIDENT
- ROLE_CURRENT_COURSE_TEACHER
ROLE_SUPER_ADMIN: [ROLE_SONATA_ADMIN, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
ROLE_GLOBAL_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
ROLE_RRHH: [ROLE_TEACHER]
@ -19,9 +20,14 @@ 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]
ROLE_CURRENT_COURSE_TEACHER: [ROLE_CURRENT_COURSE_TEACHER, ROLE_CURRENT_COURSE_STUDENT]
ROLE_ANONYMOUS: [ROLE_ANONYMOUS]
access_decision_manager:
# strategy can be: affirmative, unanimous or consensus
strategy: unanimous
providers:
@ -87,5 +93,5 @@ security:
- { path: ^/profile/, role: IS_AUTHENTICATED_FULLY }
- { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
acl:
connection: default
# acl:
# connection: default

@ -2484,7 +2484,7 @@ function api_display_tool_title($title_element) {
* @todo rewrite code so it is easier to understand
*/
function api_display_tool_view_option() {
if (api_get_setting('student_view_enabled') != 'true') {
if (api_get_setting('course.student_view_enabled') != 'true') {
return '';
}
@ -2626,7 +2626,7 @@ function api_is_allowed_to_edit($tutor = false, $coach = false, $session_coach =
}
// Check if the student_view is enabled, and if so, if it is activated.
if (api_get_setting('student_view_enabled') == 'true') {
if (api_get_setting('course.student_view_enabled') == 'true') {
$studentViewSession = Session::read('studentview');
if (!empty($my_session_id)) {
// Check if session visibility is read only for coachs

@ -374,6 +374,28 @@ class Course
return $this->users;
}
/**
* @return ArrayCollection
*/
public function getTeachers()
{
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('status', User::COURSE_MANAGER));
return $this->users->matching($criteria);
}
/**
* @return ArrayCollection
*/
public function getStudents()
{
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('status', User::STUDENT));
return $this->users->matching($criteria);
}
/**
* @param ArrayCollection $users
*/
@ -387,14 +409,14 @@ class Course
}
/**
* @param CourseRelUser $user
* @param CourseRelUser $courseRelUser
*/
public function addUsers(CourseRelUser $user)
public function addUsers(CourseRelUser $courseRelUser)
{
$user->setCourse($this);
$courseRelUser->setCourse($this);
if (!$this->hasUser($user)) {
$this->users[] = $user;
if (!$this->hasSubscription($courseRelUser)) {
$this->users[] = $courseRelUser;
}
}
@ -402,7 +424,7 @@ class Course
* @param CourseRelUser $subscription
* @return bool
*/
public function hasUser(CourseRelUser $subscription)
private function hasSubscription(CourseRelUser $subscription)
{
if ($this->getUsers()->count()) {
$criteria = Criteria::create()->where(
@ -421,6 +443,45 @@ class Course
return false;
}
/**
* @param User $user
* @return bool
*/
public function hasUser(User $user)
{
$criteria = Criteria::create()->where(
Criteria::expr()->eq("user", $user)
);
return $this->getUsers()->matching($criteria)->count() > 0;
}
/**
* @param User $user
* @return bool
*/
public function hasStudent(User $user)
{
$criteria = Criteria::create()->where(
Criteria::expr()->eq("user", $user)
);
return $this->getStudents()->matching($criteria)->count() > 0;
}
/**
* @param User $user
* @return bool
*/
public function hasTeacher(User $user)
{
$criteria = Criteria::create()->where(
Criteria::expr()->eq("user", $user)
);
return $this->getTeachers()->matching($criteria)->count() > 0;
}
/**
* Remove $user
*

@ -42,24 +42,4 @@ class CourseManager extends BaseEntityManager
{
return $this->getRepository()->findOneByTitle($name);
}
/**
* @param User $user
* @param Course $course
* @return bool
*/
public function isUserSubscribedInCourse(User $user, Course $course)
{
$userCollection = $course->getUsers();
$criteria = Criteria::create()
->where(Criteria::expr()->eq("user", $user));
$userCollection = $userCollection->matching($criteria);
if ($userCollection->count()) {
return true;
}
return false;
}
}

@ -169,6 +169,11 @@ class Session
**/
protected $userCourseSubscriptions;
/**
* @var Course
**/
protected $currentCourse;
/**
* Constructor
*/
@ -354,7 +359,8 @@ class Session
/**
* @param User $user
* @param Course $course
* @param int $status
* @param int $status if not set it will check if the user is registered
* with any status
*
* @return bool
*/
@ -371,7 +377,7 @@ class Session
*
* @return bool
*/
public function hasStudentInCourseWithStatus(User $user, Course $course)
public function hasStudentInCourse(User $user, Course $course)
{
return $this->hasUserInCourse($user, $course, self::STUDENT);
}
@ -853,4 +859,25 @@ class Session
return false;
}
/**
* @return Course
*/
public function getCurrentCourse()
{
return $this->currentCourse;
}
/**
* @param Course $course
* @return $this
*/
public function setCurrentCourse(Course $course)
{
// If the session is registered in the course session list.
if ($this->getCourses()->contains($course->getId())) {
$this->currentCourse = $course;
}
return $this;
}
}

@ -3,10 +3,8 @@
namespace Chamilo\CoreBundle\Entity;
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
use Doctrine\ORM\Mapping as ORM;
use Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap;
use Symfony\Component\Security\Acl\Permission\BasicPermissionMap;
use Symfony\Component\Security\Acl\Permission\MaskBuilder;
/**
* Tool
@ -139,49 +137,12 @@ class ToolResourceRights
*/
public static function getMaskList()
{
$builder = new MaskBuilder();
$builder
->add('VIEW')
;
$readerMask = $builder->get();
$builder = new MaskBuilder();
$builder
->add('EDIT')
;
$editorMask = $builder->get();
$readerMask = ResourceNodeVoter::getReaderMask();
$editorMask = ResourceNodeVoter::getEditorMask();
return array(
$readerMask => 'Can read',
$editorMask => 'Can edit'
);
}
/**
* @return int
*/
public static function getReaderMask()
{
$builder = new MaskBuilder();
$builder
->add('VIEW')
;
return $builder->get();
}
/**
* @return int
*/
public static function getEditorMask()
{
$builder = new MaskBuilder();
$builder
->add('EDIT')
;
return $builder->get();
}
}

@ -26,21 +26,28 @@ services:
tags:
- { name: twig.extension }
chamilo_core.security.authorization.voter.course:
chamilo_core.security.authorization.voter.course_voter:
class: Chamilo\CoreBundle\Security\Authorization\Voter\CourseVoter
arguments: [ @doctrine.orm.entity_manager, @chamilo_core.manager.course ]
arguments: [ @doctrine.orm.entity_manager, @chamilo_core.manager.course, @service_container]
public: false
tags:
- { name: security.voter }
chamilo_core.security.authorization.voter.resource_link:
chamilo_core.security.authorization.voter.session_voter:
class: Chamilo\CoreBundle\Security\Authorization\Voter\SessionVoter
arguments: [ @doctrine.orm.entity_manager, @chamilo_core.manager.course, @service_container]
public: false
tags:
- { name: security.voter }
chamilo_core.security.authorization.voter.resource_node_voter:
class: Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter
public: false
arguments: [ @service_container ]
tags:
- { name: security.voter }
chamilo_core.directory_namer.user_image:
chamilo_core.naming.user_image:
class: Chamilo\CoreBundle\Naming\UserImage
chamilo_core.form.type.yes_no:

@ -7,6 +7,7 @@ use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Manager\CourseManager;
use Chamilo\UserBundle\Entity\User;
use Doctrine\ORM\EntityManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
use Symfony\Component\Security\Core\User\UserInterface;
@ -16,8 +17,9 @@ use Symfony\Component\Security\Core\User\UserInterface;
*/
class CourseVoter extends AbstractVoter
{
const VIEW = 'view';
const EDIT = 'edit';
const VIEW = 'VIEW';
const EDIT = 'EDIT';
const DELETE = 'DELETE';
private $entityManager;
private $courseManager;
@ -25,14 +27,17 @@ class CourseVoter extends AbstractVoter
/**
* @param EntityManager $entityManager
* @param CourseManager $courseManager
* @param ContainerInterface $container
*/
public function __construct(
EntityManager $entityManager,
CourseManager $courseManager
CourseManager $courseManager,
ContainerInterface $container
)
{
$this->entityManager = $entityManager;
$this->courseManager = $courseManager;
$this->container = $container;
}
/**
@ -56,7 +61,7 @@ class CourseVoter extends AbstractVoter
*/
protected function getSupportedAttributes()
{
return array(self::VIEW, self::EDIT);
return array(self::VIEW, self::EDIT, self::DELETE);
}
/**
@ -80,49 +85,45 @@ class CourseVoter extends AbstractVoter
return false;
}
$courseManager = $this->getCourseManager();
$authChecker = $this->container->get('security.authorization_checker');
switch ($attribute) {
case self::VIEW:
$session = $course->getCurrentSession();
if (empty($session)) {
// "Open to the world"
if ($course->isPublic()) {
//return true;
}
// Admins have access to everything
if ($authChecker->isGranted('ROLE_ADMIN')) {
dump('Im admin');
// return true;
}
// User is subscribed in the user list.
$userIsSubscribed = $courseManager->isUserSubscribedInCourse(
$user,
$course
);
// Is an active course
if (!$course->isActive()) {
dump('Course is not active');
return false;
}
if ($userIsSubscribed) {
dump('user_is_subscribed');
return true;
}
switch ($attribute) {
case self::VIEW:
// "Open to the world" no need to check if user is registered
if ($course->isPublic()) {
dump('Course is public');
return true;
}
// Is an active course
if ($course->isActive()) {
//return true;
}
} else {
// Course in a session.
if ($session->isActive() && $course->isActive()) {
return true;
}
// User is subscribed in the course no matter if is teacher/student
if ($course->hasUser($user)) {
dump('User is subscribed in course');
$user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT);
return true;
}
break;
case self::EDIT:
// Teacher
// @todo
if ($user->getId() === $course->getOwner()->getId()) {
case self::DELETE:
// Only teacher can edit stuff
if ($course->hasTeacher($user)) {
$user->addRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER);
return true;
}
break;
}
dump('Course voter false!');
return true;
dump("You dont have access to this course!!");
return false;
}
}

@ -1,133 +0,0 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Security\Authorization\Voter;
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
use Chamilo\CoreBundle\Entity\Resource\ResourceRights;
use Chamilo\CoreBundle\Entity\ToolResourceRights;
use Doctrine\Common\Collections\ArrayCollection;
use Sonata\AdminBundle\Security\Acl\Permission\MaskBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Class ResourceVoter
* @package Chamilo\CoreBundle\Security\Authorization\Voter
*/
class ResourceLinkVoter extends AbstractVoter
{
private $container;
const VIEW = 'view';
const EDIT = 'edit';
const DELETE = 'delete';
/**
* Constructor
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
/**
* {@inheritdoc}
*/
protected function getSupportedAttributes()
{
return array(
self::VIEW,
self::EDIT,
self::DELETE
);
}
/**
* {@inheritdoc}
*/
protected function getSupportedClasses()
{
return array('Chamilo\CoreBundle\Entity\Resource\ResourceLink');
}
/**
* @param string $attribute
* @param ResourceLink $resourceLink
* @param null $user
*
* @return bool
*/
protected function isGranted($attribute, $resourceLink, $user = null)
{
// make sure there is a user object (i.e. that the user is logged in)
if (!$user instanceof UserInterface) {
return false;
}
// Checking admin roles
$authChecker = $this->container->get('security.authorization_checker');
$adminRoles = array(
'ROLE_SUPER_ADMIN',
'ROLE_ADMIN'
);
foreach ($adminRoles as $adminRole) {
if ($authChecker->isGranted($adminRole)) {
//return true;
}
}
$userSent = $resourceLink->getUser();
// Owner.
if ($userSent instanceof UserInterface &&
$user->getUsername() == $userSent->getUsername()) {
return true;
}
// Getting user rights
$rightFromResourceLink = $resourceLink->getRights();
if ($rightFromResourceLink->count()) {
// Taken rights of the link
$rights = $rightFromResourceLink;
} else {
// Taken the rights from the default tool
$rights = $resourceLink->getResourceNode()->getTool()->getToolResourceRights();
}
$roles = array();
foreach ($rights as $right) {
$roles[$right->getRole()] = $right->getMask();
}
$mask = new MaskBuilder();
$mask->add($attribute);
$code = $mask->get();
switch ($attribute) {
case self::VIEW:
foreach ($user->getRoles() as $role) {
if (isset($roles[$role]) && $roles[$role] == $code) {
dump('return true');
return true;
}
}
dump('return false');
return false;
case self::EDIT:
break;
}
// Course is visible?
if ($attribute == self::VIEW) {
return true;
}
return false;
}
}

@ -0,0 +1,268 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Security\Authorization\Voter;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
use Chamilo\CoreBundle\Entity\Resource\ResourceRights;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CoreBundle\Entity\ToolResourceRights;
use Doctrine\Common\Collections\ArrayCollection;
use Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
use Symfony\Component\Security\Core\User\UserInterface;
use Zend\Permissions\Acl\Acl;
use Zend\Permissions\Acl\Role\GenericRole as Role;
use Zend\Permissions\Acl\Resource\GenericResource as Resource;
use Symfony\Component\Security\Acl\Permission\MaskBuilder;
//use Sonata\AdminBundle\Security\Acl\Permission\MaskBuilder;
/**
* Class ResourceNodeVoter
* @package Chamilo\CoreBundle\Security\Authorization\Voter
*/
class ResourceNodeVoter extends AbstractVoter
{
private $container;
const VIEW = 'VIEW';
const CREATE = 'CREATE';
const EDIT = 'EDIT';
const DELETE = 'DELETE';
const EXPORT = 'EXPORT';
const ROLE_CURRENT_COURSE_TEACHER = 'ROLE_CURRENT_COURSE_TEACHER';
const ROLE_CURRENT_COURSE_STUDENT = 'ROLE_CURRENT_COURSE_STUDENT';
/**
* Constructor
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
/**
* {@inheritdoc}
*/
protected function getSupportedAttributes()
{
return array(
self::VIEW,
self::CREATE,
self::EDIT,
self::DELETE,
self::EXPORT
);
}
/**
* {@inheritdoc}
*/
protected function getSupportedClasses()
{
return array('Chamilo\CoreBundle\Entity\Resource\ResourceNode');
}
/**
* @param string $attribute
* @param ResourceNode $resourceNode
* @param null $user
*
* @return bool
*/
protected function isGranted($attribute, $resourceNode, $user = null)
{
// Make sure there is a user object (i.e. that the user is logged in)
if (!$user instanceof UserInterface) {
return false;
}
// Checking admin roles
$authChecker = $this->container->get('security.authorization_checker');
// Admins have access to everything
if ($authChecker->isGranted('ROLE_ADMIN')) {
// return true;
}
// Check if I'm the owner
$creator = $resourceNode->getCreator();
if ($creator instanceof UserInterface &&
$user->getUsername() == $creator->getUsername()) {
//return true;
}
// Checking possible links connected to this resource
$request = $this->container->get('request_stack')->getCurrentRequest();
$courseCode = $request->get('course');
$sessionId = $request->get('session');
$links = $resourceNode->getLinks();
$linkFound = false;
/** @var ResourceLink $link */
foreach ($links as $link) {
$linkUser = $link->getUser();
$linkCourse = $link->getCourse();
$linkSession = $link->getSession();
$linkUserGroup = $link->getUserGroup();
// Check if resource was sent to the current user
if ($linkUser instanceof UserInterface &&
$linkUser->getUsername() == $creator->getUsername()
) {
$linkFound = true;
break;
}
// @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
if ($linkSession instanceof Session && !empty($sessionId) &&
$linkCourse instanceof Course && !empty($courseCode)
) {
$session = $this->container->get('chamilo_core.manager.session')->find($sessionId);
$course = $this->container->get('chamilo_core.manager.course')->findOneByCode($courseCode);
if ($session instanceof Session &&
$course instanceof Course &&
$linkCourse->getCode() == $course->getCode() &&
$linkSession->getId() == $session->getId()
) {
$linkFound = true;
break;
}
}
// Check if resource was sent to a course
if ($linkCourse instanceof Course && !empty($courseCode)) {
$course = $this->container->get('chamilo_core.manager.course')->findOneByCode($courseCode);
if ($course instanceof Course &&
$linkCourse->getCode() == $course->getCode()
) {
$linkFound = true;
break;
}
}
}
// No link was found!
if ($linkFound === false) {
return false;
}
// Getting rights from the link
$rightFromResourceLink = $link->getRights();
if ($rightFromResourceLink->count()) {
// Taken rights from the link
$rights = $rightFromResourceLink;
} else {
// Taken the rights from the default tool
$rights = $link->getResourceNode()->getTool()->getToolResourceRights();
}
// Asked mask
$mask = new MaskBuilder();
$mask->add($attribute);
$askedMask = $mask->get();
// Check all the right this link has.
$roles = array();
foreach ($rights as $right) {
$roles[$right->getMask()] = $right->getRole();
}
// Setting zend simple ACL
$acl = new Acl();
// Creating roles
// @todo move this in a service
$userRole = new Role('ROLE_USER');
$teacher = new Role(self::ROLE_CURRENT_COURSE_TEACHER);
$student = new Role(self::ROLE_CURRENT_COURSE_STUDENT);
$superAdmin = new Role('ROLE_SUPER_ADMIN');
$admin = new Role('ROLE_ADMIN');
// Adding roles to the ACL
// User role
$acl->addRole($userRole);
// Adds role student
$acl->addRole($student);
// Adds teacher role, inherit student role
$acl->addRole($teacher, $student);
$acl->addRole($superAdmin);
$acl->addRole($admin);
// Adds a resource
$resource = new Resource($link);
$acl->addResource($resource);
// Role and permissions settings
// Students can view
// Student can just view (read)
$acl->allow($student, null, self::getReaderMask());
// Teacher can view/edit
$acl->allow(
$teacher,
null,
array(
self::getReaderMask(),
self::getEditorMask()
)
);
// Admin can do everything
$acl->allow($admin);
$acl->allow($superAdmin);
foreach ($user->getRoles() as $role) {
if ($acl->isAllowed($role, $resource, $askedMask)) {
dump('passed');
return true;
}
}
dump('not allowed to '.$attribute);
return false;
}
/**
* @return int
*/
public static function getReaderMask()
{
$builder = new MaskBuilder();
$builder
->add(self::VIEW)
;
return $builder->get();
}
/**
* @return int
*/
public static function getEditorMask()
{
$builder = new MaskBuilder();
$builder
->add(self::EDIT)
;
return $builder->get();
}
}

@ -0,0 +1,125 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Security\Authorization\Voter;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Manager\CourseManager;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\UserBundle\Entity\User;
use Doctrine\ORM\EntityManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Class CourseVoter
* @package Chamilo\CoreBundle\Security\Authorization\Voter
*/
class SessionVoter extends AbstractVoter
{
const VIEW = 'VIEW';
const EDIT = 'EDIT';
const DELETE = 'DELETE';
private $entityManager;
private $courseManager;
/**
* @param EntityManager $entityManager
* @param CourseManager $courseManager
* @param ContainerInterface $container
*/
public function __construct(
EntityManager $entityManager,
CourseManager $courseManager,
ContainerInterface $container
)
{
$this->entityManager = $entityManager;
$this->courseManager = $courseManager;
$this->container = $container;
}
/**
* @return EntityManager
*/
public function getEntityManager()
{
return $this->entityManager;
}
/**
* @return CourseManager
*/
public function getCourseManager()
{
return $this->courseManager;
}
/**
* {@inheritdoc}
*/
protected function getSupportedAttributes()
{
return array(self::VIEW, self::EDIT, self::DELETE);
}
/**
* {@inheritdoc}
*/
protected function getSupportedClasses()
{
return array('Chamilo\CoreBundle\Entity\Session');
}
/**
* @param string $attribute
* @param Session $session
* @param User $user
* @return bool
*/
protected function isGranted($attribute, $session, $user = null)
{
// make sure there is a user object (i.e. that the user is logged in)
if (!$user instanceof UserInterface) {
return false;
}
// Checks if the current user was set up
$course = $session->getCurrentCourse();
if ($course == false) {
return false;
}
$authChecker = $this->container->get('security.authorization_checker');
// Admins have access to everything
if ($authChecker->isGranted('ROLE_ADMIN')) {
// return true;
}
if (!$session->isActive()) {
return false;
}
switch ($attribute) {
case self::VIEW:
if (!$session->hasUserInCourse($user, $course)) {
$user->addRole('ROLE_CURRENT_SESSION_COURSE_STUDENT');
return true;
}
break;
case self::EDIT:
case self::DELETE:
if (!$session->hasCoachInCourseWithStatus($user, $course)) {
$user->addRole('ROLE_CURRENT_SESSION_COURSE_TEACHER');
return true;
}
break;
}
dump("You dont have access to this session!!");
return false;
}
}

@ -30,13 +30,14 @@ class CourseAccessListener
{
$user = $event->getUser();
$course = $event->getCourse();
if ($user && $course) {
$trackAccess = new TrackEAccess();
$trackAccess->setCId($course->getId());
$trackAccess->setAccessUserId($user->getId());
$trackAccess->setAccessSessionId(0);
$trackAccess = new TrackEAccess();
$trackAccess->setCId($course->getId());
$trackAccess->setAccessUserId($user->getId());
$trackAccess->setAccessSessionId(0);
$this->em->persist($trackAccess);
$this->em->flush();
$this->em->persist($trackAccess);
$this->em->flush();
}
}
}

@ -3,7 +3,10 @@
namespace Chamilo\CourseBundle\EventListener;
use Chamilo\CoreBundle\Security\Authorization\Voter\CourseVoter;
use Chamilo\CoreBundle\Security\Authorization\Voter\SessionVoter;
use Doctrine\ORM\EntityManager;
use Chamilo\UserBundle\Entity\User;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -11,6 +14,7 @@ use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Chamilo\CourseBundle\Controller\ToolInterface;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
@ -80,6 +84,8 @@ class CourseListener
$em = $container->get('doctrine')->getManager();
$securityChecker = $container->get('security.authorization_checker');
/** @var User $user */
$user = $container->get('security.token_storage')->getToken()->getUser();
if (!empty($courseCode)) {
/** @var Course $course */
@ -88,20 +94,28 @@ class CourseListener
// Session
$sessionId = $request->get('id_session');
if (!empty($sessionId)) {
if (empty($sessionId)) {
// Check if user is allowed to this course
// See CourseVoter.php
if (false === $securityChecker->isGranted(CourseVoter::VIEW, $course)) {
throw new AccessDeniedException('Unauthorised access to course!');
}
} else {
$session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId);
if ($session) {
$course->setCurrentSession($session);
//$course->setCurrentSession($session);
$controller[0]->setSession($session);
$session->setCurrentCourse($course);
// Check if user is allowed to this course-session
// See SessionVoter.php
if (false === $securityChecker->isGranted(SessionVoter::VIEW, $session)) {
throw new AccessDeniedException('Unauthorised access to session!');
}
} else {
throw new NotFoundHttpException('Session not found');
}
}
// Check if user is allowed to this course / course-session
// See CourseVoter.php
if (false === $securityChecker->isGranted('view', $course)) {
throw new AccessDeniedException('Unauthorised access!');
}
// Legacy code
$courseInfo = api_get_course_info($course->getCode());
@ -114,6 +128,8 @@ class CourseListener
Sets the controller course in order to use $this->getCourse()
*/
$controller[0]->setCourse($course);
} else {
throw new NotFoundHttpException('Course not found');
}
}
}

@ -14,7 +14,7 @@ use Chamilo\NotebookBundle\Tool\Notebook;
use Doctrine\ORM\QueryBuilder;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use APY\DataGridBundle\Grid\Source\Entity;
@ -45,7 +45,7 @@ class NotebookController extends ToolBaseCrudController
public function indexAction(Request $request)
{
/*if (false === $this->get('security.authorization_checker')->isGranted('view', $course)) {
throw new AccessDeniedException('Unauthorised access!');
throw new AccessDeniedHttpException('Unauthorised access!');
}*/
$source = new Entity('ChamiloNotebookBundle:CNotebook');
@ -85,17 +85,18 @@ class NotebookController extends ToolBaseCrudController
}
);*/
//$deleteMassAction = new MassAction('Delete', 'ChamiloNotebookBundle:CNotebook:deleteMass');
$deleteMassAction = new MassAction(
'Delete',
'chamilo.controller.notebook:deleteMassAction',
true,
array('course' => $request->get('course'))
);
$grid->addMassAction($deleteMassAction);
if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
$deleteMassAction = new MassAction(
'Delete',
'chamilo.controller.notebook:deleteMassAction',
true,
array('course' => $request->get('course'))
);
$grid->addMassAction($deleteMassAction);
}
$myRowAction = new RowAction(
'View',
$this->trans('View'),
'chamilo_notebook_show',
false,
'_self',
@ -104,35 +105,38 @@ class NotebookController extends ToolBaseCrudController
$myRowAction->setRouteParameters(array('course' => $course, 'id'));
$grid->addRowAction($myRowAction);
$myRowAction = new RowAction(
'Edit',
'chamilo_notebook_edit',
false,
'_self',
array('class' => 'btn btn-info')
);
$myRowAction->setRouteParameters(array('course' => $course, 'id'));
$grid->addRowAction($myRowAction);
if ($this->isGranted(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)) {
$myRowAction = new RowAction(
'Delete',
'chamilo_notebook_delete',
false,
'_self',
array('class' => 'btn btn-danger', 'form_delete' => true)
);
$myRowAction->setRouteParameters(array('course' => $course, 'id'));
$grid->addRowAction($myRowAction);
$myRowAction = new RowAction(
$this->trans('Edit'),
'chamilo_notebook_edit',
false,
'_self',
array('class' => 'btn btn-info')
);
$myRowAction->setRouteParameters(array('course' => $course, 'id'));
$grid->addRowAction($myRowAction);
$myRowAction = new RowAction(
$this->trans('Delete'),
'chamilo_notebook_delete',
false,
'_self',
array('class' => 'btn btn-danger', 'form_delete' => true)
);
$myRowAction->setRouteParameters(array('course' => $course, 'id'));
$grid->addRowAction($myRowAction);
}
$grid->addExport(
new CSVExport(
'CSV Export', 'export', array('course' => $course)
$this->trans('CSV Export'), 'export', array('course' => $course)
)
);
$grid->addExport(
new ExcelExport(
'Excel Export',
$this->trans('Excel Export'),
'export',
array('course' => $course)
)
@ -155,9 +159,11 @@ class NotebookController extends ToolBaseCrudController
$resource = $this->findOr404($request);
$resourceNode = $resource->getResourceNode();
if (false === $this->isGranted(ResourceNodeVoter::VIEW, $resourceNode)) {
throw new AccessDeniedException('Unauthorised access!');
}
$this->denyAccessUnlessGranted(
ResourceNodeVoter::VIEW,
$resourceNode,
'Unauthorised access to resource'
);
$view = $this
->view()
@ -169,62 +175,6 @@ class NotebookController extends ToolBaseCrudController
return $this->handleView($view);
}
/**
* @param ResourceNode $resourceNode
* @return ResourceLink|null
*/
public function detectLink(ResourceNode $resourceNode)
{
$user = $this->getUser();
$session = $this->getSession();
$course = $this->getCourse();
/*if ($user->getId() == $resourceNode->getCreator()->getId()) {
}*/
$links = $resourceNode->getLinks();
$linkFound = null;
if (!empty($links)) {
/** @var ResourceLink $link */
foreach ($links as $link) {
$linkCourse = $link->getCourse();
$linkSession = $link->getSession();
$linkUser = $link->getUser();
if (isset($course) && isset($session)) {
if ($linkCourse->getId() == $course->getId() &&
$linkSession->getId() == $session->getId()
) {
$linkFound = $link;
break;
}
}
if (isset($course) && isset($linkCourse)) {
if ($linkCourse->getId() == $course->getId()) {
$linkFound = $link;
break;
}
}
if (isset($linkUser)) {
if ($linkUser->getId() == $user->getId()) {
$linkFound = $link;
break;
}
}
}
}
if (empty($linkFound)) {
throw new NotFoundResourceException('Link not found');
}
return $linkFound;
}
/**
* @param Request $request
*
@ -236,6 +186,10 @@ class NotebookController extends ToolBaseCrudController
$resource = $this->createNew();
$form = $this->getForm($resource);
$this->denyAccessUnlessGranted(
ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER
);
if ($form->handleRequest($request)->isValid()) {
$sharedType = $form->get('shared')->getData();
$shareList = array();
@ -247,14 +201,14 @@ class NotebookController extends ToolBaseCrudController
$shareList = array(
array(
'sharing' => 'course',
'mask' => ToolResourceRights::getReaderMask(),
'role' => 'ROLE_STUDENT',
'mask' => ResourceNodeVoter::getReaderMask(),
'role' => ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT,
'search' => $this->getCourse()->getId()
),
array(
'sharing' => 'course',
'mask' => ToolResourceRights::getEditorMask(),
'role' => 'ROLE_TEACHER',
'mask' => ResourceNodeVoter::getEditorMask(),
'role' => ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER,
'search' => $this->getCourse()->getId()
)
);
@ -370,6 +324,15 @@ class NotebookController extends ToolBaseCrudController
*/
public function updateAction(Request $request)
{
$resource = $this->findOr404($request);
$resourceNode = $resource->getResourceNode();
$this->denyAccessUnlessGranted(
ResourceNodeVoter::EDIT,
$resourceNode,
'Unauthorised access to resource'
);
return parent::updateAction($request);
}
@ -398,6 +361,14 @@ class NotebookController extends ToolBaseCrudController
{
/** @var AbstractResource $resource */
$resource = $this->getRepository()->find($id);
$resourceNode = $resource->getResourceNode();
$this->denyAccessUnlessGranted(
ResourceNodeVoter::DELETE,
$resourceNode,
'Unauthorised access to resource'
);
$this->domainManager->delete($resource);
}
@ -408,5 +379,4 @@ class NotebookController extends ToolBaseCrudController
{
return $this->get('chamilo_notebook.entity.notebook_manager');
}
}

@ -1,8 +1,10 @@
{% if is_granted('ROLE_CURRENT_COURSE_TEACHER') %}
<div class="actions">
<a class="btn btn-default" href="{{ url('chamilo_notebook_new', { 'course': course }) }}">
{{ 'Add' | trans }}
</a>
</div>
{% endif %}
<div class="row">
{{ grid_search(grid) }}

Loading…
Cancel
Save