Skip to content

Commit

Permalink
🔒️ restrain contributor access to their own resources
Browse files Browse the repository at this point in the history
  • Loading branch information
Jérémy Riverain committed Aug 26, 2024
1 parent 68c28ec commit 08ce671
Show file tree
Hide file tree
Showing 14 changed files with 58 additions and 32 deletions.
13 changes: 7 additions & 6 deletions symfony/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions symfony/src/Controller/BoulderAreaCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

namespace App\Controller;

use App\Controller\Utils\Roles;
use App\Utils\AllowContributionExpression;
use App\Utils\Roles;
use App\Entity\BoulderArea;
use App\Field\GeoPointField;
use Doctrine\ORM\EntityManagerInterface;
Expand Down Expand Up @@ -75,6 +76,8 @@ public function configureActions(Actions $actions): Actions
->remove(Crud::PAGE_NEW, Action::SAVE_AND_ADD_ANOTHER)
->remove(Crud::PAGE_EDIT, Action::SAVE_AND_CONTINUE)
->remove(Crud::PAGE_INDEX, Action::BATCH_DELETE)
->add(Crud::PAGE_INDEX, Action::DETAIL);
->add(Crud::PAGE_INDEX, Action::DETAIL)
->setPermission(Action::DELETE, new AllowContributionExpression())
->setPermission(Action::EDIT, new AllowContributionExpression());
}
}
14 changes: 12 additions & 2 deletions symfony/src/Controller/BoulderCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

namespace App\Controller;

use App\Controller\Utils\Roles;
use App\Utils\AllowContributionExpression;
use App\Utils\Roles;
use App\Entity\Boulder;
use App\Entity\Media;
use App\Field\GeoPointField;
Expand All @@ -23,6 +24,7 @@
use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter;
use EasyCorp\Bundle\EasyAdminBundle\Filter\EntityFilter;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class BoulderCrudController extends AbstractCrudController
{
Expand Down Expand Up @@ -74,7 +76,11 @@ public function configureActions(Actions $actions): Actions
->add(Crud::PAGE_INDEX, $this->drawLineActionFactory())
->add(Crud::PAGE_DETAIL, $this->drawLineActionFactory()->addCssClass('btn'))
->reorder(Crud::PAGE_DETAIL, [Action::DELETE, Action::INDEX, Action::EDIT, 'drawLine'])
->reorder(Crud::PAGE_INDEX, [Action::DETAIL, Action::EDIT, 'drawLine', Action::DELETE]);
->reorder(Crud::PAGE_INDEX, [Action::DETAIL, Action::EDIT, 'drawLine', Action::DELETE])
->setPermission(Action::DELETE, new AllowContributionExpression())
->setPermission(Action::EDIT, new AllowContributionExpression())
->setPermission('drawLine', new AllowContributionExpression())
;
}

public function configureFilters(Filters $filters): Filters
Expand All @@ -93,6 +99,10 @@ public function drawLine(AdminContext $context): Response
if (!$entity instanceof Boulder) {
throw new \Exception("Instance of App\Entity\Boulder expected");
}

if (!$this->isGranted(Roles::ADMIN) && $entity->getCreatedBy() !== $context->getUser()) {
throw new AccessDeniedException();
}
/** @var \App\Repository\MediaRepository **/
$repository = $this->em->getRepository(Media::class);
$rockPictures = $entity->getRock() ? $repository->findByRockAndBoulder($entity->getRock(), $entity) : new ArrayCollection();
Expand Down
6 changes: 2 additions & 4 deletions symfony/src/Controller/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Controller;

use App\Controller\Utils\Roles;
use App\Utils\Roles;
use App\Entity\Boulder;
use App\Entity\BoulderArea;
use App\Entity\Department;
Expand All @@ -25,9 +25,7 @@
class DashboardController extends AbstractDashboardController
{

public function __construct(private AdminUrlGenerator $adminUrlGenerator)
{
}
public function __construct(private AdminUrlGenerator $adminUrlGenerator) {}

private function redirectAdmin(): Response
{
Expand Down
2 changes: 1 addition & 1 deletion symfony/src/Controller/DepartmentCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Controller;

use App\Controller\Utils\Roles;
use App\Utils\Roles;
use App\Entity\Department;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
Expand Down
2 changes: 1 addition & 1 deletion symfony/src/Controller/GradeCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Controller;

use App\Controller\Utils\Roles;
use App\Utils\Roles;
use App\Entity\Grade;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
Expand Down
2 changes: 1 addition & 1 deletion symfony/src/Controller/MunicipalityCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Controller;

use App\Controller\Utils\Roles;
use App\Utils\Roles;
use App\Entity\Municipality;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
Expand Down
8 changes: 6 additions & 2 deletions symfony/src/Controller/RockCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

namespace App\Controller;

use App\Controller\Utils\Roles;
use App\Utils\AllowContributionExpression;
use App\Utils\Roles;
use App\Entity\Rock;
use App\Field\GeoPointField;
use App\Form\ImageType;
Expand Down Expand Up @@ -67,7 +68,10 @@ public function configureActions(Actions $actions): Actions
->remove(Crud::PAGE_NEW, Action::SAVE_AND_ADD_ANOTHER)
->remove(Crud::PAGE_EDIT, Action::SAVE_AND_CONTINUE)
->remove(Crud::PAGE_INDEX, Action::BATCH_DELETE)
->add(Crud::PAGE_INDEX, Action::DETAIL);
->add(Crud::PAGE_INDEX, Action::DETAIL)
->setPermission(Action::DELETE, new AllowContributionExpression())
->setPermission(Action::EDIT, new AllowContributionExpression())
;
}

public function configureFilters(Filters $filters): Filters
Expand Down
2 changes: 1 addition & 1 deletion symfony/src/Controller/UserCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Controller;

use App\Controller\Utils\Roles;
use App\Utils\Roles;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
Expand Down
2 changes: 1 addition & 1 deletion symfony/src/DataFixtures/UserFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\DataFixtures;

use App\Controller\Utils\Roles;
use App\Utils\Roles;
use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
Expand Down
11 changes: 5 additions & 6 deletions symfony/src/Entity/LineBoulder.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@
)]
#[ApiResource(
openapi: false,
security: "is_granted('ROLE_USER')",
normalizationContext: ['groups' => ['LineBoulder:read']],
denormalizationContext: ['groups' => ['LineBoulder:write']],
operations: [
new GetCollection(uriTemplate: '/admin/line_boulders'),
new Get(uriTemplate: '/admin/line_boulders/{id}'),
new Put(uriTemplate: '/admin/line_boulders/{id}'),
new Delete(uriTemplate: '/admin/line_boulders/{id}'),
new Post(uriTemplate: '/admin/line_boulders', validationContext: ['groups' => ['Default', 'LineBoulder:collection-post']]),
new GetCollection(uriTemplate: '/admin/line_boulders', security: "is_granted('ROLE_CONTRIBUTOR')"),
new Get(uriTemplate: '/admin/line_boulders/{id}', security: "is_granted('ROLE_CONTRIBUTOR')"),
new Put(uriTemplate: '/admin/line_boulders/{id}', security: "is_granted('ROLE_ADMIN') or object.getBoulder()?.getCreatedBy() == user"),
new Delete(uriTemplate: '/admin/line_boulders/{id}', security: "is_granted('ROLE_ADMIN') or object.getBoulder()?.getCreatedBy() == user"),
new Post(uriTemplate: '/admin/line_boulders', validationContext: ['groups' => ['Default', 'LineBoulder:collection-post']], securityPostDenormalize: "is_granted('ROLE_ADMIN') or object.getBoulder()?.getCreatedBy() == user"),
],
)]
class LineBoulder
Expand Down
6 changes: 2 additions & 4 deletions symfony/src/EventSubscriber/EasyAdminUserSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\EventSubscriber;

use App\Controller\Utils\Roles;
use App\Utils\Roles;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityUpdatedEvent;
use Symfony\Bundle\SecurityBundle\Security;
Expand All @@ -12,9 +12,7 @@

class EasyAdminUserSubscriber implements EventSubscriberInterface
{
public function __construct(private Security $security, private AuthorizationCheckerInterface $authorizationChecker)
{
}
public function __construct(private Security $security, private AuthorizationCheckerInterface $authorizationChecker) {}

public static function getSubscribedEvents(): array
{
Expand Down
13 changes: 13 additions & 0 deletions symfony/src/Utils/AllowContributionExpression.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Utils;

use Symfony\Component\ExpressionLanguage\Expression;

class AllowContributionExpression extends Expression
{
function __construct()
{
parent::__construct('"ROLE_ADMIN" in role_names or subject.getCreatedBy()?.getId() == user.getId()');
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Controller\Utils;
namespace App\Utils;

enum Roles: string
{
Expand Down

0 comments on commit 08ce671

Please sign in to comment.