Admin: Add permissions management and role assignment - refs #5644
Author: @christianbeeznestpull/5654/head
parent
18e8c0a65b
commit
4526fcf836
@ -0,0 +1,103 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Controller; |
||||
|
||||
use Chamilo\CoreBundle\Entity\PermissionRelRole; |
||||
use Chamilo\CoreBundle\Form\PermissionType; |
||||
use Chamilo\CoreBundle\Repository\PermissionRelRoleRepository; |
||||
use Chamilo\CoreBundle\Repository\PermissionRepository; |
||||
use Doctrine\ORM\EntityManagerInterface; |
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
||||
use Symfony\Component\HttpFoundation\Request; |
||||
use Symfony\Component\HttpFoundation\Response; |
||||
use Symfony\Component\Routing\Annotation\Route; |
||||
use Symfony\Component\Security\Http\Attribute\IsGranted; |
||||
|
||||
/** |
||||
* The Permission controller manages the /permissions page to control what roles has what permission |
||||
*/ |
||||
class PermissionController extends AbstractController |
||||
{ |
||||
|
||||
#[IsGranted('ROLE_ADMIN')] |
||||
#[Route('/permissions/test', name: 'permissions_test')] |
||||
public function testPermissions(): Response |
||||
{ |
||||
// Test roles and permission slug |
||||
$roles = ['ROLE_STUDENT', 'ROLE_TEACHER']; |
||||
$permissionSlug = 'analytics:view'; |
||||
|
||||
// Call the api_get_permission function and log the result |
||||
$hasPermission = api_get_permission($permissionSlug, $roles); |
||||
error_log('Permission check for ' . $permissionSlug . ' with roles ' . implode(', ', $roles) . ': ' . ($hasPermission ? 'true' : 'false')); |
||||
|
||||
// Return a simple response for testing purposes |
||||
return new Response('<html><body>Permission check result: ' . ($hasPermission ? 'true' : 'false') . '</body></html>'); |
||||
} |
||||
|
||||
#[IsGranted('ROLE_ADMIN')] |
||||
#[Route('/permissions', name: 'permissions')] |
||||
public function index( |
||||
PermissionRepository $permissionRepo, |
||||
PermissionRelRoleRepository $permissionRelRoleRepo, |
||||
Request $request, |
||||
EntityManagerInterface $em |
||||
): Response { |
||||
$permissions = $permissionRepo->findAll(); |
||||
$roles = ['ROLE_INVITEE', 'ROLE_STUDENT', 'ROLE_TEACHER', 'ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_GLOBAL_ADMIN', 'ROLE_RRHH', 'ROLE_QUESTION_MANAGER', 'ROLE_SESSION_MANAGER', 'ROLE_STUDENT_BOSS']; |
||||
|
||||
if ($request->isMethod('POST')) { |
||||
$data = $request->request->all('permissions'); |
||||
foreach ($permissions as $permission) { |
||||
foreach ($roles as $role) { |
||||
$checkboxValue = isset($data[$permission->getSlug()][$role]); |
||||
error_log('Processing role: ' . $role . ' with value: ' . ($checkboxValue ? 'true' : 'false')); |
||||
$permRelRole = $permissionRelRoleRepo->findOneBy(['permission' => $permission, 'roleCode' => $role]); |
||||
|
||||
if ($checkboxValue) { |
||||
if (!$permRelRole) { |
||||
$permRelRole = new PermissionRelRole(); |
||||
$permRelRole->setPermission($permission); |
||||
$permRelRole->setRoleCode($role); |
||||
} |
||||
$permRelRole->setChangeable(true); |
||||
$permRelRole->setUpdatedAt(new \DateTime()); |
||||
$em->persist($permRelRole); |
||||
error_log('Persisting PermissionRelRole for permission: ' . $permission->getSlug() . ' and role: ' . $role); |
||||
} else { |
||||
if ($permRelRole) { |
||||
$em->remove($permRelRole); |
||||
error_log('Removing PermissionRelRole for permission: ' . $permission->getSlug() . ' and role: ' . $role); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
$em->flush(); |
||||
error_log('Flush complete'); |
||||
|
||||
return $this->redirectToRoute('permissions'); |
||||
} |
||||
|
||||
$forms = []; |
||||
foreach ($permissions as $permission) { |
||||
$defaultData = []; |
||||
foreach ($roles as $role) { |
||||
$permRelRole = $permissionRelRoleRepo->findOneBy(['permission' => $permission, 'roleCode' => $role]); |
||||
$defaultData[$role] = $permRelRole ? $permRelRole->isChangeable() : false; |
||||
} |
||||
|
||||
$form = $this->createForm(PermissionType::class, $defaultData, ['roles' => $roles]); |
||||
$forms[$permission->getSlug()] = $form->createView(); |
||||
} |
||||
|
||||
return $this->render('@ChamiloCore/Permission/index.html.twig', [ |
||||
'permissions' => $permissions, |
||||
'forms' => $forms, |
||||
'roles' => $roles |
||||
]); |
||||
} |
||||
} |
@ -0,0 +1,262 @@ |
||||
<?php |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Chamilo\CoreBundle\DataFixtures; |
||||
|
||||
use Chamilo\CoreBundle\Entity\Permission; |
||||
use Chamilo\CoreBundle\Entity\PermissionRelRole; |
||||
use Doctrine\Bundle\FixturesBundle\Fixture; |
||||
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface; |
||||
use Doctrine\Persistence\ObjectManager; |
||||
|
||||
class PermissionFixtures extends Fixture implements FixtureGroupInterface |
||||
{ |
||||
public static function getGroups(): array |
||||
{ |
||||
return ['permissions']; |
||||
} |
||||
|
||||
public function load(ObjectManager $manager): void |
||||
{ |
||||
$permissions = self::getPermissions(); |
||||
$roles = self::getRoles(); |
||||
$permissionsMapping = self::getPermissionsMapping(); |
||||
|
||||
foreach ($permissions as $permData) { |
||||
$existingPermission = $manager->getRepository(Permission::class)->findOneBy(['slug' => $permData['slug']]); |
||||
if ($existingPermission) { |
||||
continue; |
||||
} |
||||
|
||||
$permission = new Permission(); |
||||
$permission->setTitle($permData['title']); |
||||
$permission->setSlug($permData['slug']); |
||||
$permission->setDescription($permData['description']); |
||||
$manager->persist($permission); |
||||
|
||||
$manager->flush(); |
||||
|
||||
foreach ($roles as $roleName => $roleCode) { |
||||
if (in_array($roleCode, $permissionsMapping[$permData['slug']])) { |
||||
$permRelRole = new PermissionRelRole(); |
||||
$permRelRole->setPermission($permission); |
||||
$permRelRole->setRoleCode($roleName); |
||||
$permRelRole->setChangeable(true); |
||||
$permRelRole->setUpdatedAt(new \DateTime()); |
||||
$manager->persist($permRelRole); |
||||
} |
||||
} |
||||
} |
||||
|
||||
$manager->flush(); |
||||
} |
||||
|
||||
public static function getPermissions(): array |
||||
{ |
||||
return [ |
||||
['title' => 'View Analytics', 'slug' => 'analytics:view', 'description' => 'View analytics data'], |
||||
['title' => 'View Assigned Analytics', 'slug' => 'analytics:viewassigned', 'description' => 'View results of users assigned to me'], |
||||
['title' => 'View All Analytics', 'slug' => 'analytics:viewall', 'description' => 'View results of all users'], |
||||
['title' => 'Create Assignment', 'slug' => 'assignment:create', 'description' => 'Create assignments'], |
||||
['title' => 'Delete Assignment', 'slug' => 'assignment:delete', 'description' => 'Delete assignments'], |
||||
['title' => 'Edit Assignment', 'slug' => 'assignment:edit', 'description' => 'Edit assignments'], |
||||
['title' => 'Grade Assignment', 'slug' => 'assignment:grade', 'description' => 'Grade assignments'], |
||||
['title' => 'Submit Assignment', 'slug' => 'assignment:submit', 'description' => 'Submit assignments'], |
||||
['title' => 'View Assignment', 'slug' => 'assignment:view', 'description' => 'View assignments'], |
||||
['title' => 'Backup', 'slug' => 'backup:backup', 'description' => 'Backup'], |
||||
['title' => 'Copy Backup', 'slug' => 'backup:copy', 'description' => 'Copy backup'], |
||||
['title' => 'Restore Backup', 'slug' => 'backup:restore', 'description' => 'Restore backup'], |
||||
['title' => 'Configure Badge Criteria', 'slug' => 'badge:configurecriteria', 'description' => 'Configure badge criteria'], |
||||
['title' => 'Create Badge', 'slug' => 'badge:create', 'description' => 'Create badges'], |
||||
['title' => 'Edit Badge', 'slug' => 'badge:edit', 'description' => 'Edit badges'], |
||||
['title' => 'Delete Badge', 'slug' => 'badge:delete', 'description' => 'Delete badges'], |
||||
['title' => 'View Badge', 'slug' => 'badge:view', 'description' => 'View badges'], |
||||
['title' => 'Create Calendar Event', 'slug' => 'calendar:create', 'description' => 'Create calendar events'], |
||||
['title' => 'Edit Calendar Event', 'slug' => 'calendar:edit', 'description' => 'Edit calendar events'], |
||||
['title' => 'Delete Calendar Event', 'slug' => 'calendar:delete', 'description' => 'Delete calendar events'], |
||||
['title' => 'View Courses Catalogue', 'slug' => 'catalogue:view', 'description' => 'View courses catalogue'], |
||||
['title' => 'Create Certificate Template', 'slug' => 'certificate:create', 'description' => 'Create certificate templates'], |
||||
['title' => 'Delete Certificate Template', 'slug' => 'certificate:delete', 'description' => 'Delete certificate templates'], |
||||
['title' => 'Edit Certificate Template', 'slug' => 'certificate:edit', 'description' => 'Edit certificate templates'], |
||||
['title' => 'Generate Certificate', 'slug' => 'certificate:generate', 'description' => 'Generate certificates'], |
||||
['title' => 'Generate All Certificates', 'slug' => 'certificate:generateall', 'description' => 'Generate all certificates in a gradebook'], |
||||
['title' => 'View All Certificates', 'slug' => 'certificate:viewall', 'description' => 'View all instances of one certificate issued to all users'], |
||||
['title' => 'Assign Course to Class', 'slug' => 'class:assigncourse', 'description' => 'Assign a course to a class'], |
||||
['title' => 'Assign Session to Class', 'slug' => 'class:assignsession', 'description' => 'Assign a session to a class'], |
||||
['title' => 'Assign User to Class', 'slug' => 'class:assignuser', 'description' => 'Assign a user to a class'], |
||||
['title' => 'Create Class', 'slug' => 'class:create', 'description' => 'Manage global classes of users'], |
||||
['title' => 'Delete Class', 'slug' => 'class:delete', 'description' => 'Delete classes'], |
||||
['title' => 'Edit Class', 'slug' => 'class:edit', 'description' => 'Edit classes'], |
||||
['title' => 'View Class', 'slug' => 'class:view', 'description' => 'View classes'], |
||||
['title' => 'Create CMS Page', 'slug' => 'cms:create', 'description' => 'Create CMS pages'], |
||||
['title' => 'Delete CMS Page', 'slug' => 'cms:delete', 'description' => 'Delete CMS pages'], |
||||
['title' => 'Edit CMS Page', 'slug' => 'cms:edit', 'description' => 'Edit CMS pages'], |
||||
['title' => 'Create Course Space', 'slug' => 'course:create', 'description' => 'Create course spaces'], |
||||
['title' => 'Delete Course Space', 'slug' => 'course:delete', 'description' => 'Delete course spaces'], |
||||
['title' => 'Download Course Content', 'slug' => 'course:downloadcoursecontent', 'description' => 'Download all course content'], |
||||
['title' => 'Edit Own Course Properties', 'slug' => 'course:edit', 'description' => 'Edit own course\'s properties'], |
||||
['title' => 'Edit All Course Properties', 'slug' => 'course:editall', 'description' => 'Edit all course\'s properties'], |
||||
['title' => 'Manage Plugins', 'slug' => 'plugin:manage', 'description' => 'Enable/disable/configure plugins'], |
||||
['title' => 'Create Quiz', 'slug' => 'quiz:create', 'description' => 'Create quizzes'], |
||||
['title' => 'Delete Quiz', 'slug' => 'quiz:delete', 'description' => 'Delete quizzes'], |
||||
['title' => 'Edit Quiz', 'slug' => 'quiz:edit', 'description' => 'Edit quizzes'], |
||||
['title' => 'Grade Quiz', 'slug' => 'quiz:grade', 'description' => 'Grade quizzes'], |
||||
['title' => 'View Live Quiz Results', 'slug' => 'quiz:viewliveresults', 'description' => 'View live quiz results'], |
||||
['title' => 'Manage Question Bank', 'slug' => 'quiz:managequestionbank', 'description' => 'Manage question bank'], |
||||
['title' => 'Create Role', 'slug' => 'role:create', 'description' => 'Create roles'], |
||||
['title' => 'Manage Role Permissions', 'slug' => 'role:managepermissions', 'description' => 'Assign or remove permissions from roles'], |
||||
['title' => 'Create Session', 'slug' => 'session:create', 'description' => 'Create sessions'], |
||||
['title' => 'Delete Session', 'slug' => 'session:delete', 'description' => 'Delete sessions'], |
||||
['title' => 'Edit Own Session Properties', 'slug' => 'session:edit', 'description' => 'Edit own session\'s properties'], |
||||
['title' => 'Edit All Session Properties', 'slug' => 'session:editall', 'description' => 'Edit all session\'s properties'], |
||||
['title' => 'Assign Course to Session', 'slug' => 'session:assigncourse', 'description' => 'Assign a course to a session'], |
||||
['title' => 'Edit Site Settings', 'slug' => 'site:editsettings', 'description' => 'Manage settings of the platform'], |
||||
['title' => 'Access Site Maintenance', 'slug' => 'site:maintenanceaccess', 'description' => 'Access site maintenance'], |
||||
['title' => 'Manage Course Competency', 'slug' => 'skill:coursecompetencymanage', 'description' => 'Assign skills through course gradebooks'], |
||||
['title' => 'Review User Competency', 'slug' => 'skill:usercompetencyreview', 'description' => 'Add comments on other user\'s acquired skills'], |
||||
['title' => 'Assign Skill', 'slug' => 'skill:assign', 'description' => 'Assign a skill to a user'], |
||||
['title' => 'Create Skill', 'slug' => 'skill:create', 'description' => 'Create skills'], |
||||
['title' => 'Delete Skill', 'slug' => 'skill:delete', 'description' => 'Delete skills'], |
||||
['title' => 'Edit Skill', 'slug' => 'skill:edit', 'description' => 'Edit skills'], |
||||
['title' => 'View Skill', 'slug' => 'skill:view', 'description' => 'View all skills acquired by users in my context'], |
||||
['title' => 'View All Skills', 'slug' => 'skill:viewall', 'description' => 'View all skills acquired by users of the platform'], |
||||
['title' => 'Create Survey', 'slug' => 'survey:create', 'description' => 'Add a survey (global or inside own course)'], |
||||
['title' => 'Delete Survey', 'slug' => 'survey:delete', 'description' => 'Delete surveys'], |
||||
['title' => 'Edit Survey', 'slug' => 'survey:edit', 'description' => 'Edit surveys'], |
||||
['title' => 'Submit Survey', 'slug' => 'survey:submit', 'description' => 'Submit surveys'], |
||||
['title' => 'View Survey Results', 'slug' => 'survey:viewresults', 'description' => 'View survey results'], |
||||
['title' => 'Comment on Ticket', 'slug' => 'ticket:comment', 'description' => 'Comment on tickets'], |
||||
['title' => 'Manage Tickets', 'slug' => 'ticket:manage', 'description' => 'Manage the tickets system'], |
||||
['title' => 'Report Ticket', 'slug' => 'ticket:report', 'description' => 'Report tickets'], |
||||
['title' => 'See Ticket Issues', 'slug' => 'ticket:seeissues', 'description' => 'See issue details for issues where they are involved'], |
||||
['title' => 'View All Ticket Issues', 'slug' => 'ticket:viewallissues', 'description' => 'View all issues'], |
||||
['title' => 'Edit Tool Visibility', 'slug' => 'tool:editvisibility', 'description' => 'Allow setting the visibility of a tool in a course'], |
||||
['title' => 'Manage URL', 'slug' => 'url:manage', 'description' => 'Manage Multi-URL configuration'], |
||||
['title' => 'Assign Classes to URL', 'slug' => 'url:assignclass', 'description' => 'Assign classes to URL'], |
||||
['title' => 'Assign Courses to URL', 'slug' => 'url:assigncourse', 'description' => 'Assign courses to URL'], |
||||
['title' => 'Assign Users to URL', 'slug' => 'url:assignuser', 'description' => 'Assign users to URL'], |
||||
['title' => 'Assign User to Class', 'slug' => 'user:assignclass', 'description' => 'Assign a user to a class'], |
||||
['title' => 'Assign User to Course', 'slug' => 'user:assigncourse', 'description' => 'Assign a user to a course'], |
||||
['title' => 'Assign User to Session', 'slug' => 'user:assignsession', 'description' => 'Assign a user to a session'], |
||||
['title' => 'Create User', 'slug' => 'user:create', 'description' => 'Create users'], |
||||
['title' => 'Delete User', 'slug' => 'user:delete', 'description' => 'Delete users'], |
||||
['title' => 'Edit User', 'slug' => 'user:edit', 'description' => 'Edit users'], |
||||
['title' => 'Edit User Role', 'slug' => 'user:editrole', 'description' => 'Edit user roles'], |
||||
['title' => 'Login As User', 'slug' => 'user:loginas', 'description' => 'Login as another user'], |
||||
]; |
||||
} |
||||
|
||||
public static function getRoles(): array |
||||
{ |
||||
return [ |
||||
'ROLE_INVITEE' => 'INV', |
||||
'ROLE_STUDENT' => 'STU', |
||||
'ROLE_TEACHER' => 'TEA', |
||||
'ROLE_ADMIN' => 'ADM', |
||||
'ROLE_SUPER_ADMIN' => 'SUA', |
||||
'ROLE_GLOBAL_ADMIN' => 'GLO', |
||||
'ROLE_RRHH' => 'HRM', |
||||
'ROLE_QUESTION_MANAGER' => 'QBM', |
||||
'ROLE_SESSION_MANAGER' => 'SSM', |
||||
'ROLE_STUDENT_BOSS' => 'STB', |
||||
]; |
||||
} |
||||
|
||||
public static function getPermissionsMapping(): array |
||||
{ |
||||
return [ |
||||
'analytics:view' => ['INV', 'STU', 'TEA', 'ADM', 'SUA', 'GLO', 'HRM', 'QBM', 'SSM', 'STB'], |
||||
'analytics:viewassigned' => ['TEA', 'ADM', 'SUA', 'GLO', 'HRM', 'SSM', 'STB'], |
||||
'analytics:viewall' => ['ADM', 'SUA', 'GLO', 'SSM', 'STB'], |
||||
'assignment:create' => ['TEA'], |
||||
'assignment:delete' => ['TEA', 'ADM', 'SUA', 'GLO'], |
||||
'assignment:edit' => ['TEA', 'ADM', 'SUA', 'GLO'], |
||||
'assignment:grade' => ['TEA'], |
||||
'assignment:submit' => ['STU'], |
||||
'assignment:view' => ['INV', 'STU', 'TEA', 'ADM', 'SUA', 'GLO', 'HRM', 'SSM', 'STB'], |
||||
'backup:backup' => ['TEA', 'ADM', 'SUA', 'GLO', 'SSM'], |
||||
'backup:copy' => ['TEA', 'ADM', 'SUA', 'GLO', 'SSM'], |
||||
'backup:restore' => ['TEA', 'ADM', 'SUA', 'GLO', 'SSM'], |
||||
'badge:configurecriteria' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'badge:create' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'badge:edit' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'badge:delete' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'badge:view' => ['INV', 'STU', 'TEA', 'ADM', 'SUA', 'GLO', 'SSM', 'STB'], |
||||
'calendar:create' => ['ADM', 'SUA', 'GLO'], |
||||
'calendar:edit' => ['ADM', 'SUA', 'GLO'], |
||||
'calendar:delete' => ['ADM', 'SUA', 'GLO'], |
||||
'catalogue:view' => ['INV', 'STU', 'TEA', 'ADM', 'SUA', 'GLO', 'HRM', 'QBM', 'SSM', 'STB'], |
||||
'certificate:create' => ['TEA', 'SSM'], |
||||
'certificate:delete' => ['TEA', 'SSM'], |
||||
'certificate:edit' => ['TEA', 'SSM'], |
||||
'certificate:generate' => ['STU', 'TEA', 'SSM'], |
||||
'certificate:generateall' => ['TEA', 'HRM', 'SSM'], |
||||
'certificate:viewall' => ['TEA', 'HRM', 'SSM', 'STB'], |
||||
'class:assigncourse' => ['TEA', 'ADM', 'SUA', 'GLO'], |
||||
'class:assignsession' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'class:assignuser' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'class:create' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'class:delete' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'class:edit' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'class:view' => ['STU', 'TEA', 'ADM', 'SUA', 'GLO', 'SSM'], |
||||
'cms:create' => ['ADM', 'SUA', 'GLO'], |
||||
'cms:delete' => ['ADM', 'SUA', 'GLO'], |
||||
'cms:edit' => ['ADM', 'SUA', 'GLO'], |
||||
'course:create' => ['TEA', 'ADM', 'SUA', 'GLO', 'SSM'], |
||||
'course:delete' => ['TEA', 'ADM', 'SUA', 'GLO'], |
||||
'course:downloadcoursecontent' => ['TEA', 'ADM', 'SUA', 'GLO', 'SSM'], |
||||
'course:edit' => ['TEA', 'SSM'], |
||||
'course:editall' => ['ADM', 'SUA', 'GLO'], |
||||
'plugin:manage' => ['ADM', 'SUA', 'GLO'], |
||||
'quiz:create' => ['TEA', 'QBM'], |
||||
'quiz:delete' => ['TEA', 'QBM'], |
||||
'quiz:edit' => ['TEA', 'QBM'], |
||||
'quiz:grade' => ['TEA'], |
||||
'quiz:viewliveresults' => ['TEA', 'SSM'], |
||||
'quiz:managequestionbank' => ['ADM', 'SUA', 'GLO', 'QBM'], |
||||
'role:create' => ['ADM', 'SUA', 'GLO'], |
||||
'role:managepermissions' => ['ADM', 'SUA', 'GLO'], |
||||
'session:create' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'session:delete' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'session:edit' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'session:editall' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'session:assigncourse' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'site:editsettings' => ['ADM', 'SUA', 'GLO'], |
||||
'site:maintenanceaccess' => ['ADM', 'SUA', 'GLO'], |
||||
'skill:coursecompetencymanage' => ['TEA', 'ADM', 'SUA', 'GLO', 'HRM'], |
||||
'skill:usercompetencyreview' => ['STU', 'TEA', 'ADM', 'SUA', 'GLO'], |
||||
'skill:assign' => ['ADM', 'SUA', 'GLO'], |
||||
'skill:create' => ['GLO'], |
||||
'skill:delete' => ['GLO'], |
||||
'skill:edit' => ['GLO'], |
||||
'skill:view' => ['ADM', 'SUA', 'GLO', 'SSM', 'STB'], |
||||
'skill:viewall' => ['ADM', 'SUA', 'GLO', 'SSM', 'STB'], |
||||
'survey:create' => ['TEA'], |
||||
'survey:delete' => ['TEA'], |
||||
'survey:edit' => ['TEA'], |
||||
'survey:submit' => ['INV', 'STU', 'TEA', 'ADM', 'SUA', 'GLO', 'SSM', 'STB'], |
||||
'survey:viewresults' => ['TEA', 'HRM', 'SSM', 'STB'], |
||||
'ticket:comment' => ['STU', 'TEA', 'ADM', 'SUA', 'GLO', 'HRM', 'QBM', 'SSM', 'STB'], |
||||
'ticket:manage' => ['ADM', 'SUA', 'GLO'], |
||||
'ticket:report' => ['STU', 'TEA', 'ADM', 'SUA', 'GLO', 'HRM', 'QBM', 'SSM', 'STB'], |
||||
'ticket:seeissues' => ['STU', 'TEA', 'ADM', 'SUA', 'GLO', 'SSM', 'STB'], |
||||
'ticket:viewallissues' => ['ADM', 'SUA', 'GLO', 'SSM', 'STB'], |
||||
'tool:editvisibility' => ['TEA', 'ADM', 'SUA', 'GLO', 'SSM'], |
||||
'url:manage' => ['GLO'], |
||||
'url:assignclass' => ['GLO'], |
||||
'url:assigncourse' => ['GLO'], |
||||
'url:assignuser' => ['GLO'], |
||||
'user:assignclass' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'user:assigncourse' => ['TEA', 'ADM', 'SUA', 'GLO'], |
||||
'user:assignsession' => ['ADM', 'SUA', 'GLO', 'SSM'], |
||||
'user:create' => ['ADM', 'SUA', 'GLO'], |
||||
'user:delete' => ['ADM', 'SUA', 'GLO'], |
||||
'user:edit' => ['ADM', 'SUA', 'GLO'], |
||||
'user:editrole' => ['ADM', 'SUA', 'GLO'], |
||||
'user:loginas' => ['SUA', 'GLO'], |
||||
]; |
||||
} |
||||
} |
@ -0,0 +1,81 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Entity; |
||||
|
||||
use Chamilo\CoreBundle\Repository\PermissionRepository; |
||||
use Doctrine\ORM\Mapping as ORM; |
||||
use Stringable; |
||||
use Symfony\Component\Validator\Constraints as Assert; |
||||
|
||||
|
||||
#[ORM\Entity(repositoryClass: PermissionRepository::class)] |
||||
#[ORM\Table(name: 'permission')] |
||||
/** |
||||
* A Permission defines something a user role can do. |
||||
* The permissions a role has is determined by the PermissionRelRole entity. |
||||
*/ |
||||
class Permission implements Stringable |
||||
{ |
||||
#[ORM\Id] |
||||
#[ORM\GeneratedValue(strategy: 'AUTO')] |
||||
#[ORM\Column(type: 'integer')] |
||||
private ?int $id = null; |
||||
|
||||
#[Assert\NotBlank] |
||||
#[ORM\Column(type: 'string', length: 255)] |
||||
private string $title; |
||||
|
||||
#[Assert\NotBlank] |
||||
#[ORM\Column(type: 'string', length: 255, unique: true)] |
||||
private string $slug; |
||||
|
||||
#[ORM\Column(type: 'text', nullable: true)] |
||||
private ?string $description = null; |
||||
|
||||
public function getId(): ?int |
||||
{ |
||||
return $this->id; |
||||
} |
||||
|
||||
public function getTitle(): string |
||||
{ |
||||
return $this->title; |
||||
} |
||||
|
||||
public function setTitle(string $title): self |
||||
{ |
||||
$this->title = $title; |
||||
return $this; |
||||
} |
||||
|
||||
public function getSlug(): string |
||||
{ |
||||
return $this->slug; |
||||
} |
||||
|
||||
public function setSlug(string $slug): self |
||||
{ |
||||
$this->slug = $slug; |
||||
return $this; |
||||
} |
||||
|
||||
public function getDescription(): ?string |
||||
{ |
||||
return $this->description; |
||||
} |
||||
|
||||
public function setDescription(?string $description): self |
||||
{ |
||||
$this->description = $description; |
||||
return $this; |
||||
} |
||||
|
||||
public function __toString(): string |
||||
{ |
||||
return $this->title; |
||||
} |
||||
} |
@ -0,0 +1,89 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Entity; |
||||
|
||||
use Chamilo\CoreBundle\Repository\PermissionRelRoleRepository; |
||||
use Doctrine\ORM\Mapping as ORM; |
||||
use Symfony\Component\Validator\Constraints as Assert; |
||||
|
||||
#[ORM\Entity(repositoryClass: PermissionRelRoleRepository::class)] |
||||
#[ORM\Table(name: 'permission_rel_role')] |
||||
/** |
||||
* The PermissionRelRole entity makes the link between roles |
||||
* (defined in security.yaml) and permissions (defined by the |
||||
* Permission entity) to define which user role can do what. |
||||
*/ |
||||
class PermissionRelRole |
||||
{ |
||||
#[ORM\Id] |
||||
#[ORM\GeneratedValue(strategy: 'AUTO')] |
||||
#[ORM\Column(type: 'integer')] |
||||
private ?int $id = null; |
||||
|
||||
#[ORM\ManyToOne(targetEntity: Permission::class)] |
||||
#[ORM\JoinColumn(nullable: false)] |
||||
private Permission $permission; |
||||
|
||||
#[Assert\NotBlank] |
||||
#[ORM\Column(type: 'string', length: 50)] |
||||
private string $roleCode; |
||||
|
||||
#[ORM\Column(type: 'boolean')] |
||||
private bool $changeable; |
||||
|
||||
#[ORM\Column(type: 'datetime')] |
||||
private \DateTime $updatedAt; |
||||
|
||||
public function getId(): ?int |
||||
{ |
||||
return $this->id; |
||||
} |
||||
|
||||
public function getPermission(): Permission |
||||
{ |
||||
return $this->permission; |
||||
} |
||||
|
||||
public function setPermission(Permission $permission): self |
||||
{ |
||||
$this->permission = $permission; |
||||
return $this; |
||||
} |
||||
|
||||
public function getRoleCode(): string |
||||
{ |
||||
return $this->roleCode; |
||||
} |
||||
|
||||
public function setRoleCode(string $roleCode): self |
||||
{ |
||||
$this->roleCode = $roleCode; |
||||
return $this; |
||||
} |
||||
|
||||
public function isChangeable(): bool |
||||
{ |
||||
return $this->changeable; |
||||
} |
||||
|
||||
public function setChangeable(bool $changeable): self |
||||
{ |
||||
$this->changeable = $changeable; |
||||
return $this; |
||||
} |
||||
|
||||
public function getUpdatedAt(): \DateTime |
||||
{ |
||||
return $this->updatedAt; |
||||
} |
||||
|
||||
public function setUpdatedAt(\DateTime $updatedAt): self |
||||
{ |
||||
$this->updatedAt = $updatedAt; |
||||
return $this; |
||||
} |
||||
} |
@ -0,0 +1,33 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Form; |
||||
|
||||
use Symfony\Component\Form\AbstractType; |
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; |
||||
use Symfony\Component\Form\FormBuilderInterface; |
||||
use Symfony\Component\OptionsResolver\OptionsResolver; |
||||
|
||||
class PermissionType extends AbstractType |
||||
{ |
||||
public function buildForm(FormBuilderInterface $builder, array $options): void |
||||
{ |
||||
$roles = $options['roles']; |
||||
|
||||
foreach ($roles as $role) { |
||||
$builder->add($role, CheckboxType::class, [ |
||||
'required' => false, |
||||
]); |
||||
} |
||||
} |
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void |
||||
{ |
||||
$resolver->setDefaults([ |
||||
'roles' => [], |
||||
]); |
||||
} |
||||
} |
@ -0,0 +1,51 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Migrations\Schema\V200; |
||||
|
||||
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo; |
||||
use Doctrine\DBAL\Schema\Schema; |
||||
|
||||
final class Version20240709222600 extends AbstractMigrationChamilo |
||||
{ |
||||
public function getDescription(): string |
||||
{ |
||||
return 'Create permission and permission_rel_role tables'; |
||||
} |
||||
|
||||
public function up(Schema $schema): void |
||||
{ |
||||
$this->addSql(' |
||||
CREATE TABLE IF NOT EXISTS permission ( |
||||
id INT AUTO_INCREMENT NOT NULL, |
||||
title VARCHAR(255) NOT NULL, |
||||
slug VARCHAR(255) NOT NULL, |
||||
description LONGTEXT DEFAULT NULL, |
||||
UNIQUE INDEX UNIQ_2DEDCC6F989D9B62 (slug), |
||||
PRIMARY KEY(id) |
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB ROW_FORMAT = DYNAMIC |
||||
'); |
||||
|
||||
$this->addSql(' |
||||
CREATE TABLE IF NOT EXISTS permission_rel_role ( |
||||
id INT AUTO_INCREMENT NOT NULL, |
||||
permission_id INT NOT NULL, |
||||
role_code VARCHAR(50) NOT NULL, |
||||
changeable TINYINT(1) NOT NULL, |
||||
updated_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime)\', |
||||
INDEX IDX_43723A27FED90CCA (permission_id), |
||||
PRIMARY KEY(id), |
||||
CONSTRAINT FK_43723A27FED90CCA FOREIGN KEY (permission_id) REFERENCES permission (id) |
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB ROW_FORMAT = DYNAMIC |
||||
'); |
||||
} |
||||
|
||||
public function down(Schema $schema): void |
||||
{ |
||||
$this->addSql('DROP TABLE IF EXISTS permission_rel_role'); |
||||
$this->addSql('DROP TABLE IF EXISTS permission'); |
||||
} |
||||
} |
@ -0,0 +1,74 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Migrations\Schema\V200; |
||||
|
||||
use Chamilo\CoreBundle\DataFixtures\PermissionFixtures; |
||||
use Chamilo\CoreBundle\Entity\Permission; |
||||
use Chamilo\CoreBundle\Entity\PermissionRelRole; |
||||
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo; |
||||
use Doctrine\DBAL\Schema\Schema; |
||||
|
||||
final class Version20240709222700 extends AbstractMigrationChamilo |
||||
{ |
||||
public function getDescription(): string |
||||
{ |
||||
return 'Insert default data into permission and permission_rel_role tables'; |
||||
} |
||||
|
||||
public function up(Schema $schema): void |
||||
{ |
||||
$permissions = PermissionFixtures::getPermissions(); |
||||
$roles = PermissionFixtures::getRoles(); |
||||
$permissionsMapping = PermissionFixtures::getPermissionsMapping(); |
||||
|
||||
foreach ($permissions as $permData) { |
||||
$permissionRepository = $this->entityManager->getRepository(Permission::class); |
||||
$existingPermission = $permissionRepository->findOneBy(['slug' => $permData['slug']]); |
||||
|
||||
if ($existingPermission) { |
||||
$permission = $existingPermission; |
||||
} else { |
||||
$permission = new Permission(); |
||||
$permission->setTitle($permData['title']); |
||||
$permission->setSlug($permData['slug']); |
||||
$permission->setDescription($permData['description']); |
||||
|
||||
$this->entityManager->persist($permission); |
||||
$this->entityManager->flush(); |
||||
} |
||||
|
||||
foreach ($roles as $roleName => $roleCode) { |
||||
if (in_array($roleCode, $permissionsMapping[$permData['slug']])) { |
||||
$permissionRelRoleRepository = $this->entityManager->getRepository(PermissionRelRole::class); |
||||
$existingRelation = $permissionRelRoleRepository->findOneBy([ |
||||
'permission' => $permission, |
||||
'roleCode' => $roleName |
||||
]); |
||||
|
||||
if ($existingRelation) { |
||||
continue; |
||||
} |
||||
|
||||
$permissionRelRole = new PermissionRelRole(); |
||||
$permissionRelRole->setPermission($permission); |
||||
$permissionRelRole->setRoleCode($roleName); |
||||
$permissionRelRole->setChangeable(true); |
||||
$permissionRelRole->setUpdatedAt(new \DateTime()); |
||||
|
||||
$this->entityManager->persist($permissionRelRole); |
||||
$this->entityManager->flush(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public function down(Schema $schema): void |
||||
{ |
||||
$this->addSql('DELETE FROM permission_rel_role'); |
||||
$this->addSql('DELETE FROM permission'); |
||||
} |
||||
} |
@ -0,0 +1,23 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Repository; |
||||
|
||||
use Chamilo\CoreBundle\Entity\PermissionRelRole; |
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; |
||||
use Doctrine\Persistence\ManagerRegistry; |
||||
|
||||
/** |
||||
* @extends ServiceEntityRepository<PermissionRelRole> |
||||
*/ |
||||
class PermissionRelRoleRepository extends ServiceEntityRepository |
||||
{ |
||||
public function __construct(ManagerRegistry $registry) |
||||
{ |
||||
parent::__construct($registry, PermissionRelRole::class); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,23 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Repository; |
||||
|
||||
use Chamilo\CoreBundle\Entity\Permission; |
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; |
||||
use Doctrine\Persistence\ManagerRegistry; |
||||
|
||||
/** |
||||
* @extends ServiceEntityRepository<Permission> |
||||
*/ |
||||
class PermissionRepository extends ServiceEntityRepository |
||||
{ |
||||
public function __construct(ManagerRegistry $registry) |
||||
{ |
||||
parent::__construct($registry, Permission::class); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,49 @@ |
||||
{% extends "@ChamiloCore/Layout/layout_one_col.html.twig" %} |
||||
|
||||
{% block content %} |
||||
<h1>{{ 'Permissions Management'|trans }}</h1> |
||||
<form method="post"> |
||||
<button type="submit" class="save-button btn btn--primary hover:bg-blue-700 text-white font-bold py-2 px-4 rounded cursor-pointer mt-4 mb-4">{{ 'Save permissions'|trans }}</button> |
||||
<table class="permissions-table"> |
||||
<thead> |
||||
<tr> |
||||
<th>{{ 'Permission '|trans }} <br> ({{ 'slug'|trans }})</th> |
||||
{% for role in roles %} |
||||
<th> |
||||
{{ role|trans }}<br> |
||||
<input type="checkbox" class="select-all" data-role="{{ role }}" style="margin-top: 5px;"> |
||||
</th> |
||||
{% endfor %} |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{% for permission in permissions %} |
||||
<tr> |
||||
<td>{{ permission.title|trans }} <br> ({{ permission.slug }})</td> |
||||
{% for role in roles %} |
||||
<td> |
||||
<input type="checkbox" name="permissions[{{ permission.slug }}][{{ role }}]" |
||||
{% if forms[permission.slug].vars.value[role] %}checked="checked"{% endif %}> |
||||
</td> |
||||
{% endfor %} |
||||
</tr> |
||||
{% endfor %} |
||||
</tbody> |
||||
</table> |
||||
<button type="submit" class="save-button btn btn--primary hover:bg-blue-700 text-white font-bold py-2 px-4 rounded cursor-pointer mt-4">{{ 'Save permissions'|trans }}</button> |
||||
</form> |
||||
<script> |
||||
document.addEventListener('DOMContentLoaded', (event) => { |
||||
document.querySelectorAll('.select-all').forEach((checkbox) => { |
||||
checkbox.addEventListener('click', function() { |
||||
const role = this.getAttribute('data-role'); |
||||
const checkboxes = document.querySelectorAll(`input[name*="[${role}]"]`); |
||||
const isChecked = this.checked; |
||||
checkboxes.forEach((cb) => { |
||||
cb.checked = isChecked; |
||||
}); |
||||
}); |
||||
}); |
||||
}); |
||||
</script> |
||||
{% endblock %} |
@ -0,0 +1,35 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Service; |
||||
|
||||
use Chamilo\CoreBundle\Repository\PermissionRelRoleRepository; |
||||
|
||||
class PermissionService |
||||
{ |
||||
private PermissionRelRoleRepository $permissionRelRoleRepository; |
||||
|
||||
public function __construct(PermissionRelRoleRepository $permissionRelRoleRepository) |
||||
{ |
||||
$this->permissionRelRoleRepository = $permissionRelRoleRepository; |
||||
} |
||||
|
||||
public function hasPermission(string $permissionSlug, array $roles): bool |
||||
{ |
||||
$queryBuilder = $this->permissionRelRoleRepository->createQueryBuilder('prr') |
||||
->innerJoin('prr.permission', 'p') |
||||
->where('p.slug = :permissionSlug') |
||||
->andWhere('prr.roleCode IN (:roles)') |
||||
->andWhere('prr.changeable = :changeable') |
||||
->setParameter('permissionSlug', $permissionSlug) |
||||
->setParameter('roles', $roles) |
||||
->setParameter('changeable', true); |
||||
|
||||
$results = $queryBuilder->getQuery()->getResult(); |
||||
|
||||
return count($results) > 0; |
||||
} |
||||
} |
Loading…
Reference in new issue