From d13434bb082205513b00a94c40f8d3b4cadb047a Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Mon, 21 Oct 2013 19:11:42 +0200 Subject: [PATCH] permissions --- core/lib/Thelia/Command/GenerateResources.php | 92 +++++++++++++++++ core/lib/Thelia/Config/Resources/config.xml | 1 + .../Core/Security/Resource/AdminResources.php | 2 + .../Thelia/Core/Security/SecurityContext.php | 61 ++++++------ core/lib/Thelia/Model/Admin.php | 24 +++++ .../lib/Thelia/Model/Map/ResourceTableMap.php | 2 +- install/insert.sql | 98 +++++++++++++++++++ install/thelia.sql | 2 +- local/config/schema.xml | 2 +- 9 files changed, 251 insertions(+), 33 deletions(-) create mode 100644 core/lib/Thelia/Command/GenerateResources.php diff --git a/core/lib/Thelia/Command/GenerateResources.php b/core/lib/Thelia/Command/GenerateResources.php new file mode 100644 index 000000000..217672797 --- /dev/null +++ b/core/lib/Thelia/Command/GenerateResources.php @@ -0,0 +1,92 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Command; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +use Thelia\Command\ContainerAwareCommand; +use Thelia\Model\Admin; +use Thelia\Model\Map\ResourceTableMap; + +class GenerateResources extends ContainerAwareCommand +{ + /** + * Configure the command + */ + protected function configure() + { + $this + ->setName("thelia:generate-resources") + ->setDescription("Outputs admin resources") + ->setHelp("The thelia:generate-resources outputs admin resources.") + ->addOption( + 'output', + null, + InputOption::VALUE_OPTIONAL, + 'Output format amid (string, sql)', + null + ) + ; + + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $class = new \ReflectionClass('Thelia\Core\Event\AdminResources'); + + $constants = $class->getConstants(); + + if(count($constants) == 0) { + $output->writeln('No resources found'); + exit; + } + + switch($input->getOption("output")) { + case 'sql': + $output->writeln( + 'INSERT INTO ' . ResourceTableMap::TABLE_NAME . ' (`id`, `code`, `created_at`, `updated_at`) VALUES ' + ); + foreach($constants as $constant => $value) { + if($constant == 'SUPERADMINISTRATOR') { + continue; + } + $output->writeln( + "(NULL, '$value', NOW(), NOW())" . ($constant === key( array_slice( $constants, -1, 1, TRUE ) ) ? '' : ',') + ); + } + break; + default : + foreach($constants as $constant => $value) { + if($constant == 'SUPERADMINISTRATOR') { + continue; + } + $output->writeln('[' . $constant . "] => " . $value); + } + break; + } + } + +} diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 192b6f368..2caf016e2 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -158,6 +158,7 @@ + diff --git a/core/lib/Thelia/Core/Security/Resource/AdminResources.php b/core/lib/Thelia/Core/Security/Resource/AdminResources.php index f23d26a4e..8e8a24e3c 100644 --- a/core/lib/Thelia/Core/Security/Resource/AdminResources.php +++ b/core/lib/Thelia/Core/Security/Resource/AdminResources.php @@ -50,6 +50,8 @@ final class AdminResources } } + const SUPERADMINISTRATOR = "SUPERADMINISTRATOR"; + const ADDRESS_VIEW = "admin.address.view"; const ADDRESS_CREATE = "admin.address.create"; const ADDRESS_UPDATE = "admin.address.update"; diff --git a/core/lib/Thelia/Core/Security/SecurityContext.php b/core/lib/Thelia/Core/Security/SecurityContext.php index 742bd648b..1dc216dd7 100755 --- a/core/lib/Thelia/Core/Security/SecurityContext.php +++ b/core/lib/Thelia/Core/Security/SecurityContext.php @@ -23,8 +23,12 @@ namespace Thelia\Core\Security; +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Event\AdminResources; use Thelia\Core\Security\User\UserInterface; use Thelia\Core\HttpFoundation\Request; +use Thelia\Model\ProfileQuery; +use Thelia\Model\ProfileResourceQuery; /** * A simple security manager, in charge of checking user @@ -124,6 +128,10 @@ class SecurityContext */ final public function isGranted(array $roles, array $permissions) { + if (empty($permissions)) { + return true; + } + // Find a user which matches the required roles. $user = $this->getCustomerUser(); @@ -135,38 +143,31 @@ class SecurityContext } } - if ($user != null) { - - if (empty($permissions)) { - return true; - } - - // Get permissions from profile - // $userPermissions = $user->getPermissions(); FIXME - - // TODO: Finalize permissions system !; - - $userPermissions = array('*'); // FIXME ! - - $permissionsFound = true; - - // User have all permissions ? - if (in_array('*', $userPermissions)) - return true; - - // Check that user's permissions matches required permissions - foreach ($permissions as $permission) { - if (! in_array($permission, $userPermissions)) { - $permissionsFound = false; - - break; - } - } - - return $permissionsFound; + if (null === $user) { + return false; } - return false; + if( !method_exists($user, 'getProfileId') ) { + return false; + } + + $userPermissions = $user->getPermissions(); + + if($userPermissions === AdminResources::SUPERADMINISTRATOR) { + return true; + } + + foreach($permissions as $permission) { + if($permission === '') { + continue; + } + + if(! in_array($permission, $userPermissions)) { + return false; + } + } + + return true; } /** diff --git a/core/lib/Thelia/Model/Admin.php b/core/lib/Thelia/Model/Admin.php index 2712eb95c..d4fa2a02d 100755 --- a/core/lib/Thelia/Model/Admin.php +++ b/core/lib/Thelia/Model/Admin.php @@ -2,6 +2,8 @@ namespace Thelia\Model; +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Event\AdminResources; use Thelia\Core\Security\User\UserInterface; use Thelia\Core\Security\Role\Role; @@ -21,6 +23,28 @@ use Propel\Runtime\Connection\ConnectionInterface; */ class Admin extends BaseAdmin implements UserInterface { + public function getPermissions() + { + $profileId = $this->getProfileId(); + + if( null === $profileId ) { + return AdminResources::SUPERADMINISTRATOR; + } + + $userPermissionsQuery = ProfileResourceQuery::create() + ->joinResource("resource", Criteria::LEFT_JOIN) + ->withColumn('resource.code', 'code') + ->filterByProfileId($profileId) + ->find(); + + $userPermissions = array(); + foreach($userPermissionsQuery as $userPermission) { + $userPermissions[] = $userPermission->getVirtualColumn('code'); + } + + return $userPermissions; + } + /** * {@inheritDoc} */ diff --git a/core/lib/Thelia/Model/Map/ResourceTableMap.php b/core/lib/Thelia/Model/Map/ResourceTableMap.php index 16c9421d6..d3ad2c60a 100644 --- a/core/lib/Thelia/Model/Map/ResourceTableMap.php +++ b/core/lib/Thelia/Model/Map/ResourceTableMap.php @@ -150,7 +150,7 @@ class ResourceTableMap extends TableMap $this->setUseIdGenerator(true); // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addColumn('CODE', 'Code', 'VARCHAR', true, 30, null); + $this->addColumn('CODE', 'Code', 'VARCHAR', true, 255, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() diff --git a/install/insert.sql b/install/insert.sql index 991eb7892..17707c299 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -1191,3 +1191,101 @@ INSERT INTO `order_status_i18n` (`id`, `locale`, `title`, `description`, `chapo` (4, 'fr_FR', 'Envoyée', '', '', ''), (5, 'en_US', 'Canceled', '', '', ''), (5, 'fr_FR', 'Annulée', '', '', ''); + + +/** +generated with command : php Thelia thelia:generate-resources --output sql + */ +INSERT INTO resource (`id`, `code`, `created_at`, `updated_at`) VALUES +(NULL, 'admin.address.view', NOW(), NOW()), +(NULL, 'admin.address.create', NOW(), NOW()), +(NULL, 'admin.address.update', NOW(), NOW()), +(NULL, 'admin.address.delete', NOW(), NOW()), +(NULL, 'admin.configuration.admin.view', NOW(), NOW()), +(NULL, 'admin.configuration.admin.create', NOW(), NOW()), +(NULL, 'admin.configuration.admin.update', NOW(), NOW()), +(NULL, 'admin.configuration.admin.delete', NOW(), NOW()), +(NULL, 'admin.configuration.area.view', NOW(), NOW()), +(NULL, 'admin.configuration.area.create', NOW(), NOW()), +(NULL, 'admin.configuration.area.update', NOW(), NOW()), +(NULL, 'admin.configuration.area.delete', NOW(), NOW()), +(NULL, 'admin.configuration.attribute.view', NOW(), NOW()), +(NULL, 'admin.configuration.attribute.create', NOW(), NOW()), +(NULL, 'admin.configuration.attribute.update', NOW(), NOW()), +(NULL, 'admin.configuration.attribute.delete', NOW(), NOW()), +(NULL, 'admin.category.view', NOW(), NOW()), +(NULL, 'admin.category.create', NOW(), NOW()), +(NULL, 'admin.category.update', NOW(), NOW()), +(NULL, 'admin.category.delete', NOW(), NOW()), +(NULL, 'admin.configuration.view', NOW(), NOW()), +(NULL, 'admin.configuration.create', NOW(), NOW()), +(NULL, 'admin.configuration.update', NOW(), NOW()), +(NULL, 'admin.configuration.delete', NOW(), NOW()), +(NULL, 'admin.content.view', NOW(), NOW()), +(NULL, 'admin.content.create', NOW(), NOW()), +(NULL, 'admin.content.update', NOW(), NOW()), +(NULL, 'admin.content.delete', NOW(), NOW()), +(NULL, 'admin.configuration.country.view', NOW(), NOW()), +(NULL, 'admin.configuration.country.create', NOW(), NOW()), +(NULL, 'admin.configuration.country.update', NOW(), NOW()), +(NULL, 'admin.configuration.country.delete', NOW(), NOW()), +(NULL, 'admin.coupon.view', NOW(), NOW()), +(NULL, 'admin.coupon.create', NOW(), NOW()), +(NULL, 'admin.coupon.update', NOW(), NOW()), +(NULL, 'admin.coupon.delete', NOW(), NOW()), +(NULL, 'admin.configuration.currency.view', NOW(), NOW()), +(NULL, 'admin.configuration.currency.create', NOW(), NOW()), +(NULL, 'admin.configuration.currency.update', NOW(), NOW()), +(NULL, 'admin.configuration.currency.delete', NOW(), NOW()), +(NULL, 'admin.customer.view', NOW(), NOW()), +(NULL, 'admin.customer.create', NOW(), NOW()), +(NULL, 'admin.customer.update', NOW(), NOW()), +(NULL, 'admin.customer.delete', NOW(), NOW()), +(NULL, 'admin.configuration.feature.view', NOW(), NOW()), +(NULL, 'admin.configuration.feature.create', NOW(), NOW()), +(NULL, 'admin.configuration.feature.update', NOW(), NOW()), +(NULL, 'admin.configuration.feature.delete', NOW(), NOW()), +(NULL, 'admin.folder.view', NOW(), NOW()), +(NULL, 'admin.folder.create', NOW(), NOW()), +(NULL, 'admin.folder.update', NOW(), NOW()), +(NULL, 'admin.folder.delete', NOW(), NOW()), +(NULL, 'admin.configuration.language.view', NOW(), NOW()), +(NULL, 'admin.configuration.language.create', NOW(), NOW()), +(NULL, 'admin.configuration.language.update', NOW(), NOW()), +(NULL, 'admin.configuration.language.delete', NOW(), NOW()), +(NULL, 'admin.configuration.mailing-system.view', NOW(), NOW()), +(NULL, 'admin.configuration.mailing-system.create', NOW(), NOW()), +(NULL, 'admin.configuration.mailing-system.update', NOW(), NOW()), +(NULL, 'admin.configuration.mailing-system.delete', NOW(), NOW()), +(NULL, 'admin.configuration.message.view', NOW(), NOW()), +(NULL, 'admin.configuration.message.create', NOW(), NOW()), +(NULL, 'admin.configuration.message.update', NOW(), NOW()), +(NULL, 'admin.configuration.message.delete', NOW(), NOW()), +(NULL, 'admin.configuration.module.view', NOW(), NOW()), +(NULL, 'admin.configuration.module.create', NOW(), NOW()), +(NULL, 'admin.configuration.module.update', NOW(), NOW()), +(NULL, 'admin.configuration.module.delete', NOW(), NOW()), +(NULL, 'admin.order.view', NOW(), NOW()), +(NULL, 'admin.order.create', NOW(), NOW()), +(NULL, 'admin.order.update', NOW(), NOW()), +(NULL, 'admin.order.delete', NOW(), NOW()), +(NULL, 'admin.product.view', NOW(), NOW()), +(NULL, 'admin.product.create', NOW(), NOW()), +(NULL, 'admin.product.update', NOW(), NOW()), +(NULL, 'admin.product.delete', NOW(), NOW()), +(NULL, 'admin.configuration.profile.view', NOW(), NOW()), +(NULL, 'admin.configuration.profile.create', NOW(), NOW()), +(NULL, 'admin.configuration.profile.update', NOW(), NOW()), +(NULL, 'admin.configuration.profile.delete', NOW(), NOW()), +(NULL, 'admin.configuration.shipping-zone.view', NOW(), NOW()), +(NULL, 'admin.configuration.shipping-zone.create', NOW(), NOW()), +(NULL, 'admin.configuration.shipping-zone.update', NOW(), NOW()), +(NULL, 'admin.configuration.shipping-zone.delete', NOW(), NOW()), +(NULL, 'admin.configuration.tax.view', NOW(), NOW()), +(NULL, 'admin.configuration.tax.create', NOW(), NOW()), +(NULL, 'admin.configuration.tax.update', NOW(), NOW()), +(NULL, 'admin.configuration.tax.delete', NOW(), NOW()), +(NULL, 'admin.configuration.template.view', NOW(), NOW()), +(NULL, 'admin.configuration.template.create', NOW(), NOW()), +(NULL, 'admin.configuration.template.update', NOW(), NOW()), +(NULL, 'admin.configuration.template.delete', NOW(), NOW()); \ No newline at end of file diff --git a/install/thelia.sql b/install/thelia.sql index 545e235cd..1e96ee783 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -955,7 +955,7 @@ DROP TABLE IF EXISTS `resource`; CREATE TABLE `resource` ( `id` INTEGER NOT NULL AUTO_INCREMENT, - `code` VARCHAR(30) NOT NULL, + `code` VARCHAR(255) NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), diff --git a/local/config/schema.xml b/local/config/schema.xml index e5ff3b31d..7c2cf4b97 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -740,7 +740,7 @@ - +