diff --git a/Controller/DocumentPersonController.php b/Controller/DocumentPersonController.php index f6f074610..350069ed9 100644 --- a/Controller/DocumentPersonController.php +++ b/Controller/DocumentPersonController.php @@ -5,6 +5,7 @@ namespace Chill\DocStoreBundle\Controller; use Chill\DocStoreBundle\Entity\PersonDocument; use Chill\DocStoreBundle\Form\PersonDocumentType; use Chill\DocStoreBundle\Repository\DocumentRepository; +use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\PersonBundle\Privacy\PrivacyEvent; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -36,16 +37,26 @@ class DocumentPersonController extends Controller */ protected $eventDispatcher; + /** + * @var AuthorizationHelper + */ + protected $authorizationHelper; + /** * DocumentPersonController constructor. - * + * @param TranslatorInterface $translator * @param EventDispatcherInterface $eventDispatcher + * @param AuthorizationHelper $authorizationHelper */ - public function __construct(TranslatorInterface $translator, EventDispatcherInterface $eventDispatcher) - { + public function __construct( + TranslatorInterface $translator, + EventDispatcherInterface $eventDispatcher, + AuthorizationHelper $authorizationHelper + ) { $this->translator = $translator; $this->eventDispatcher = $eventDispatcher; + $this->authorizationHelper = $authorizationHelper; } /** @@ -61,7 +72,7 @@ class DocumentPersonController extends Controller $this->denyAccessUnlessGranted(PersonVoter::SEE, $person); - $reachableScopes = $this->get('chill.main.security.authorization.helper') + $reachableScopes = $this->authorizationHelper ->getReachableScopes( $this->getUser(), new Role(PersonDocumentVoter::SEE), $person->getCenter()); diff --git a/DataFixtures/ORM/LoadDocumentACL.php b/DataFixtures/ORM/LoadDocumentACL.php index c17e795e6..0f4577ffd 100644 --- a/DataFixtures/ORM/LoadDocumentACL.php +++ b/DataFixtures/ORM/LoadDocumentACL.php @@ -21,7 +21,7 @@ namespace Chill\DocStoreBundle\DataFixtures\ORM; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; -use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\Persistence\ObjectManager; use Chill\MainBundle\DataFixtures\ORM\LoadPermissionsGroup; use Chill\MainBundle\Entity\RoleScope; use Chill\MainBundle\DataFixtures\ORM\LoadScopes; diff --git a/DataFixtures/ORM/LoadDocumentCategory.php b/DataFixtures/ORM/LoadDocumentCategory.php index 37e55c5b7..2eb6e7181 100644 --- a/DataFixtures/ORM/LoadDocumentCategory.php +++ b/DataFixtures/ORM/LoadDocumentCategory.php @@ -19,7 +19,7 @@ namespace Chill\DocStoreBundle\DataFixtures\ORM; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; -use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\Persistence\ObjectManager; use Chill\DocStoreBundle\Entity\DocumentCategory; /** diff --git a/DependencyInjection/ChillDocStoreExtension.php b/DependencyInjection/ChillDocStoreExtension.php index ed36f1845..63de15f8b 100644 --- a/DependencyInjection/ChillDocStoreExtension.php +++ b/DependencyInjection/ChillDocStoreExtension.php @@ -24,13 +24,13 @@ class ChillDocStoreExtension extends Extension implements PrependExtensionInterf $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('services.yml'); - $loader->load('services/media.yml'); - $loader->load('services/controller.yml'); - $loader->load('services/menu.yml'); - $loader->load('services/fixtures.yml'); - $loader->load('services/form.yml'); + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config')); + $loader->load('services.yaml'); + $loader->load('services/media.yaml'); + $loader->load('services/controller.yaml'); + $loader->load('services/menu.yaml'); + $loader->load('services/fixtures.yaml'); + $loader->load('services/form.yaml'); } public function prepend(ContainerBuilder $container) @@ -46,8 +46,8 @@ class ChillDocStoreExtension extends Extension implements PrependExtensionInterf $container->prependExtensionConfig('chill_main', array( 'routing' => array( 'resources' => array( - '@ChillDocStoreBundle/Resources/config/routing.yml', - '@ChampsLibresAsyncUploaderBundle/Resources/config/routing.yml' + '@ChillDocStoreBundle/config/routes.yaml', + '@ChampsLibresAsyncUploaderBundle/config/routes.yaml' ) ) )); diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 162f6ce99..6c4fa7477 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -17,8 +17,8 @@ class Configuration implements ConfigurationInterface */ public function getConfigTreeBuilder() { - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('chill_doc_store'); + $treeBuilder = new TreeBuilder('chill_doc_store'); + $rootNode = $treeBuilder->getRootNode('chill_doc_store'); // Here you should define the parameters that are allowed to // configure your bundle. See the documentation linked above for diff --git a/Resources/views/DocumentCategory/edit.html.twig b/Resources/views/DocumentCategory/edit.html.twig index 68c74a29d..cc4d8223b 100644 --- a/Resources/views/DocumentCategory/edit.html.twig +++ b/Resources/views/DocumentCategory/edit.html.twig @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . #} -{% extends "ChillMainBundle::Admin/layout.html.twig" %} +{% extends "@ChillMain/Admin/layout.html.twig" %} {% block title %}{{ 'Document category edit'|trans }}{% endblock title %} diff --git a/Resources/views/DocumentCategory/index.html.twig b/Resources/views/DocumentCategory/index.html.twig index 3aaa7fcf0..612afb2fb 100644 --- a/Resources/views/DocumentCategory/index.html.twig +++ b/Resources/views/DocumentCategory/index.html.twig @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . #} -{% extends "ChillMainBundle::Admin/layout.html.twig" %} +{% extends "@ChillMain/Admin/layout.html.twig" %} {% block title %}{{ 'Document category list' | trans }}{% endblock title %} diff --git a/Resources/views/DocumentCategory/new.html.twig b/Resources/views/DocumentCategory/new.html.twig index a87d42585..8b3f55182 100644 --- a/Resources/views/DocumentCategory/new.html.twig +++ b/Resources/views/DocumentCategory/new.html.twig @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . #} -{% extends "ChillMainBundle::Admin/layout.html.twig" %} +{% extends "@ChillMain/Admin/layout.html.twig" %} {% block title %}{{ 'Create new document category' | trans }}{% endblock title %} diff --git a/Resources/views/DocumentCategory/show.html.twig b/Resources/views/DocumentCategory/show.html.twig index cf323781d..2ba2a301b 100644 --- a/Resources/views/DocumentCategory/show.html.twig +++ b/Resources/views/DocumentCategory/show.html.twig @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . #} -{% extends "ChillMainBundle::Admin/layout.html.twig" %} +{% extends "@ChillMain/Admin/layout.html.twig" %} {% block title %}{{ 'Document category show'|trans }}{% endblock title %} diff --git a/Resources/views/PersonDocument/edit.html.twig b/Resources/views/PersonDocument/edit.html.twig index 704031abb..4cc84bd7d 100644 --- a/Resources/views/PersonDocument/edit.html.twig +++ b/Resources/views/PersonDocument/edit.html.twig @@ -15,7 +15,7 @@ * along with this program. If not, see . #} -{% extends "ChillPersonBundle::layout.html.twig" %} +{% extends "@ChillPerson/layout.html.twig" %} {% set activeRouteKey = '' %} diff --git a/Resources/views/PersonDocument/index.html.twig b/Resources/views/PersonDocument/index.html.twig index 5f6f3632a..f30bf3558 100644 --- a/Resources/views/PersonDocument/index.html.twig +++ b/Resources/views/PersonDocument/index.html.twig @@ -15,7 +15,7 @@ * along with this program. If not, see . #} -{% extends "ChillPersonBundle::layout.html.twig" %} +{% extends "@ChillPerson/layout.html.twig" %} {% set activeRouteKey = '' %} diff --git a/Resources/views/PersonDocument/new.html.twig b/Resources/views/PersonDocument/new.html.twig index 7a643b985..f16f53794 100644 --- a/Resources/views/PersonDocument/new.html.twig +++ b/Resources/views/PersonDocument/new.html.twig @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . #} -{% extends "ChillPersonBundle::layout.html.twig" %} +{% extends "@ChillPerson/layout.html.twig" %} {% set activeRouteKey = '' %} diff --git a/Resources/views/PersonDocument/show.html.twig b/Resources/views/PersonDocument/show.html.twig index 5a929d5ea..ac1b18601 100644 --- a/Resources/views/PersonDocument/show.html.twig +++ b/Resources/views/PersonDocument/show.html.twig @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . #} -{% extends "ChillPersonBundle::layout.html.twig" %} +{% extends "@ChillPerson/layout.html.twig" %} {% set activeRouteKey = '' %} diff --git a/Security/Authorization/PersonDocumentVoter.php b/Security/Authorization/PersonDocumentVoter.php index 47bfed38b..78429b439 100644 --- a/Security/Authorization/PersonDocumentVoter.php +++ b/Security/Authorization/PersonDocumentVoter.php @@ -24,6 +24,12 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\ProvideRoleHierarchyInterface; use Chill\DocStoreBundle\Entity\PersonDocument; use Chill\PersonBundle\Entity\Person; +use Chill\MainBundle\Entity\User; +use Chill\PersonBundle\Security\Authorization\PersonVoter; +use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Role\Role; +use Psr\Log\LoggerInterface; /** * @@ -37,16 +43,31 @@ class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHiera const DELETE = 'CHILL_PERSON_DOCUMENT_DELETE'; /** - * * @var AuthorizationHelper */ - protected $helper; + protected $authorizationHelper; - public function __construct(AuthorizationHelper $helper) + /** + * @var AccessDecisionManagerInterface + */ + protected $accessDecisionManager; + + /** + * @var LoggerInterface + */ + protected $logger; + + public function __construct( + AccessDecisionManagerInterface $accessDecisionManager, + AuthorizationHelper $authorizationHelper, + LoggerInterface $logger + ) { - $this->helper = $helper; + $this->accessDecisionManager = $accessDecisionManager; + $this->authorizationHelper = $authorizationHelper; + $this->logger = $logger; } - + public function getRoles() { return [ @@ -71,9 +92,51 @@ class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHiera return false; } + /** + * + * @param string $attribute + * @param PersonDocument $subject + * @param TokenInterface $token + * @return boolean + */ + protected function voteOnAttribute($attribute, $subject, TokenInterface $token) + { + $this->logger->debug(sprintf("Voting from %s class", self::class)); + + if (!$token->getUser() instanceof User) { + return false; + } + + if ($subject instanceof PersonDocument) { + return $this->authorizationHelper->userHasAccess($token->getUser(), $subject, $attribute); + + } elseif ($subject instanceof Person) { + return $this->authorizationHelper->userHasAccess($token->getUser(), $subject, $attribute); + + } else { + + // subject is null. We check that at least one center is reachable + $centers = $this->authorizationHelper + ->getReachableCenters($token->getUser(), new Role($attribute)); + + return count($centers) > 0; + } + + if (!$this->accessDecisionManager->decide($token, [PersonVoter::SEE], $person)) { + return false; + } + + return $this->authorizationHelper->userHasAccess( + $token->getUser(), + $subject, + $attribute + ); + + } + protected function isGranted($attribute, $report, $user = null) { - if (! $user instanceof \Chill\MainBundle\Entity\User){ + if (! $user instanceof User){ return false; } diff --git a/composer.json b/composer.json index 32cc7695d..384f6c093 100644 --- a/composer.json +++ b/composer.json @@ -6,8 +6,6 @@ "psr-4": { "Chill\\DocStoreBundle\\" : "" } }, "require": { - "chill-project/person": "~1.5.0", - "champs-libres/async-uploader-bundle": "~1.0" }, "license": "AGPL-3.0" } diff --git a/Resources/config/routing.yml b/config/routes.yaml similarity index 100% rename from Resources/config/routing.yml rename to config/routes.yaml diff --git a/Resources/config/services.yml b/config/services.yaml similarity index 92% rename from Resources/config/services.yml rename to config/services.yaml index 4439c8dbb..79aa64ffa 100644 --- a/Resources/config/services.yml +++ b/config/services.yaml @@ -18,7 +18,9 @@ services: Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter: class: Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter arguments: + - "@security.access.decision_manager" - "@chill.main.security.authorization.helper" + - "@logger" tags: - { name: security.voter } - { name: chill.role } diff --git a/Resources/config/services/controller.yml b/config/services/controller.yaml similarity index 51% rename from Resources/config/services/controller.yml rename to config/services/controller.yaml index 0a2798508..9899ffa2e 100644 --- a/Resources/config/services/controller.yml +++ b/config/services/controller.yaml @@ -1,9 +1,11 @@ services: Chill\DocStoreBundle\Controller\: - resource: '../../../Controller' + resource: '../../Controller' tags: ['controller.service_arguments'] Chill\DocStoreBundle\Controller\DocumentPersonController: - autowire: true arguments: + $translator: '@Symfony\Component\Translation\TranslatorInterface' $eventDispatcher: '@Symfony\Component\EventDispatcher\EventDispatcherInterface' + $authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper' + tags: ['controller.service_arguments'] \ No newline at end of file diff --git a/Resources/config/services/fixtures.yml b/config/services/fixtures.yaml similarity index 68% rename from Resources/config/services/fixtures.yml rename to config/services/fixtures.yaml index c9bc451d6..8a5b299ba 100644 --- a/Resources/config/services/fixtures.yml +++ b/config/services/fixtures.yaml @@ -1,4 +1,4 @@ services: Chill\DocStoreBundle\DataFixtures\ORM\: - resource: ../../../DataFixtures/ORM + resource: ../../DataFixtures/ORM tags: [ 'doctrine.fixture.orm' ] diff --git a/Resources/config/services/form.yml b/config/services/form.yaml similarity index 100% rename from Resources/config/services/form.yml rename to config/services/form.yaml diff --git a/Resources/config/services/media.yml b/config/services/media.yaml similarity index 100% rename from Resources/config/services/media.yml rename to config/services/media.yaml diff --git a/Resources/config/services/menu.yml b/config/services/menu.yaml similarity index 100% rename from Resources/config/services/menu.yml rename to config/services/menu.yaml diff --git a/Resources/migrations/Version20180605102533.php b/migrations/Version20180605102533.php similarity index 95% rename from Resources/migrations/Version20180605102533.php rename to migrations/Version20180605102533.php index 5661277e2..5b9fe27c3 100644 --- a/Resources/migrations/Version20180605102533.php +++ b/migrations/Version20180605102533.php @@ -2,7 +2,7 @@ namespace Application\Migrations; -use Doctrine\DBAL\Migrations\AbstractMigration; +use Doctrine\Migrations\AbstractMigration; use Doctrine\DBAL\Schema\Schema; /** @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; */ final class Version20180605102533 extends AbstractMigration { - public function up(Schema $schema) : void + public function up(Schema $schema): void { $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); @@ -29,7 +29,7 @@ final class Version20180605102533 extends AbstractMigration $this->addSql('ALTER TABLE chill_doc.person_document ADD CONSTRAINT FK_41DA53C217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); } - public function down(Schema $schema) : void + public function down(Schema $schema): void { $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); diff --git a/Resources/migrations/Version20180606133338.php b/migrations/Version20180606133338.php similarity index 93% rename from Resources/migrations/Version20180606133338.php rename to migrations/Version20180606133338.php index 43dae7aa4..3902ad78b 100644 --- a/Resources/migrations/Version20180606133338.php +++ b/migrations/Version20180606133338.php @@ -2,7 +2,7 @@ namespace Application\Migrations; -use Doctrine\DBAL\Migrations\AbstractMigration; +use Doctrine\Migrations\AbstractMigration; use Doctrine\DBAL\Schema\Schema; /** @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; */ final class Version20180606133338 extends AbstractMigration { - public function up(Schema $schema) : void + public function up(Schema $schema): void { $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); @@ -25,7 +25,7 @@ final class Version20180606133338 extends AbstractMigration $this->addSql('CREATE INDEX IDX_41DA53C232D562B ON chill_doc.person_document (object_id)'); } - public function down(Schema $schema) : void + public function down(Schema $schema): void { $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.'); diff --git a/Resources/translations/messages.fr.yml b/translations/messages.fr.yml similarity index 95% rename from Resources/translations/messages.fr.yml rename to translations/messages.fr.yml index 3d69655d7..44ef5e337 100644 --- a/Resources/translations/messages.fr.yml +++ b/translations/messages.fr.yml @@ -1,4 +1,5 @@ Document: Document +Documents: Documents Documents for %name%: Documents de %name% Preparing: En préparation Ready to show: Prêt à être visualisé @@ -9,7 +10,6 @@ New document for %name%: Nouveau document pour %name% Editing document for %name%: Modification d'un document pour %name% Edit Document: Modification d'un document Existing document: Document existant -The document is successfully updated: Le document est mis à jour No document to download: Aucun document à télécharger 'Choose a document category': Choisissez une catégorie de document Any document found: Aucun document trouvé diff --git a/Resources/translations/validators.fr.yml b/translations/validators.fr.yml similarity index 100% rename from Resources/translations/validators.fr.yml rename to translations/validators.fr.yml