PHP code example of makinacorpus / access-control

1. Go to this page and download the library: Download makinacorpus/access-control library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

makinacorpus / access-control example snippets


namespace MyVendor\MyApp\SomeBoundingContext\Entity;

use MakinaCorpus\AccessControl\AccessRole;

#[AccessRole("ROLE_USER")]
class FooEntity
{
    public function canDoThat(UserInterface $subject)
    {
        if ($this->owner !== $subject->getUsername()) {
            return false;
        }
        return true;
    }
}

namespace MyVendor\MyApp\AccessControl;

use MakinaCorpus\AccessControl\RoleChecker\RoleChecker;
use MyVendor\MyApp\Entity\SomeUserImplementation;

class MyRoleChecker implement RoleChecker
{
    public function subjectHasRole($subject, string $role): bool
    {
        return $subject instanceof SomeUserImplementation && $subject->hasRole($role);
    }
}

namespace MyVendor\MyApp\SomeBoundingContext\Entity;

use MakinaCorpus\AccessControl\AccessPermission;

#[AccessPermission("do_that_with_foo")]
class FooEntity
{
    public function canDoThat(UserInterface $subject)
    {
        if ($this->owner !== $subject->getUsername()) {
            return false;
        }
        return true;
    }
}

namespace MyVendor\MyApp\AccessControl;

use MakinaCorpus\AccessControl\PermissionChecker\PermissionChecker;
use MyVendor\MyApp\Entity\SomeUserImplementation;

class MyPermissionChecker implement PermissionChecker
{
    public function subjectHasPermission($subject, string $$permission): bool
    {
        return $subject instanceof SomeUserImplementation && $subject->hasPermission($permission);
    }
}

namespace MyVendor\MyApp\SomeBoundingContext\Entity;

use MakinaCorpus\AccessControl\AccessMethod;

#[AccessMethod("canDoThat(subject)")]
class FooEntity
{
    public function canDoThat(UserInterface $subject)
    {
        if ($this->owner !== $subject->getUsername()) {
            return false;
        }
        return true;
    }
}

namespace MyVendor\MyApp\SomeBoundingContext\Entity;

class Product
{
    private int $quantityInStock;

    public function hasEnoughQuantity(int $needed): bool
    {
        return $this->quantityInStock > $needed;
    }
}

namespace MyVendor\MyApp\SomeBoundingContext\Entity;

use MakinaCorpus\AccessControl\AccessMethod;

#[AccessMethod("product.hasEnoughQuantity(quantityRequired)")]
public function addToCart(Product $product, int $quantityRequired)
{
    // Do something.
}

namespace MyVendor\MyApp\SomeBoundingContext\Command;

use MakinaCorpus\AccessControl\AccessService;

#[AccessService("ThatService.canDoThat(subject, resource)")]
class DoThisOrThatCommand
{
}

namespace MyVendor\MyApp\SomeBoundingContext\AccessControl;

class ThatService
{
    public function canDoThat(UserInterface $subject, $resource)
    {
        if ($resource->issuer !== $subject->getUsername()) {
            return false;
        }
        return true;
    }
}

namespace MyVendor\MyApp\Bus;

use MakinaCorpus\AccessControl\Authorization;

class MyBusAccessDecorator implements MyBus
{
    private Authorization $authorization;
    private MyBus $decorated;

    public function dispatch(object $command): void
    {
        if (!$this->authorization->isGranted($command)) {
            throw new \Exception("YOU SHALL NOT PASS");
        }
        $this->decorated->dispatch($command);
    }
}

namespace MyVendor\MyApp\SomeBoundingContext\AccessControl;

class ThatService
{
    public function canDoThat(UserInterface $myBusinessUser, $myDomainEntity)
    {
        if ($myDomainEntity->issuer !== $myBusinessUser->getUsername()) {
            return false;
        }
        return true;
    }
}

use MakinaCorpus\AccessControl\AccessService;

#[AccessService("ThatService.canDoThat(myBusinessUser: subject, myDomainEntity: resource)")]
class DoThisOrThatCommand
{
}

namespace MyVendor\MyApp\SomeBoundingContext\AccessControl;

class ThatService
{
    public function canDoThat(UserInterface $myBusinessUser, $resource)
    {
        if ($someId !== $resource) {
            return false;
        }
        return true;
    }
}

use MakinaCorpus\AccessControl\AccessService;

#[AccessService("ThatService.canDoThat(myBusinessUser: subject, myDomainEntity: resource.entityId)")]
class DoThisOrThatCommand
{
    public $entityId;
}

namespace MyVendor\MyApp\SomeBoundingContext\AccessControl;

class ThatService
{
    public function canDoThat(string $userId, $resource)
    {
        if ($userId !== $resource->userId) {
            return false;
        }
        return true;
    }
}

use MakinaCorpus\AccessControl\AccessService;

#[AccessService("ThatService.canDoThat(userId: subject.id, resource)")]
class DoThisOrThatCommand
{
}

namespace MyVendor\MyApp\SomeBoundingContext\Model;

class SomeEntity
{
    public int $id;
    public string $name;
}

interface SomeEntityRepository
{
    /* @throws \DomainException */
    public function find(int $id): SomeEntity;
}

namespace MyVendor\MyApp\SomeBoundingContext\Command;

class UpdateSomeEntity
{
    public int $entityId;
    public string $newName;
}

namespace MyVendor\MyApp\SomeBoundingContext\ResourceLocator;

use MakinaCorpus\AccessControl\ResourceLocator\ResourceLocator;
use MyVendor\MyApp\SomeBoundingContext\Model\SomeEntity;
use MyVendor\MyApp\SomeBoundingContext\Model\SomeEntityRepository;

class SomeResourceLocator implements ResourceLocator
{
    private SomeEntityRepository $repository;

    public function __construct(SomeEntityRepository $repository)
    {
        $this->repository = $repository;
    }

    /**
     * {@inheritdoc}
     */
    public function loadResource(string $resourceType, $resourceId)
    {
        try {
            if (SomeEntity::class === $resourceType && \is_int($resourceId) {
                return $this->repository->find($resourceId);
            }
        } catch (\DomainException $e) {
            // Or let the exception pass, but it violates the contract.
        }
        return null;
    }
}

namespace MyVendor\MyApp\SomeBoundingContext\Command;

use MakinaCorpus\AccessControl\AccessResource;
use MakinaCorpus\AccessControl\AccessService;
use MyVendor\MyApp\SomeBoundingContext\Model\SomeEntity;

#[AccessResource(SomeEntity::class, "entityId")]
#[AccessService(ThatService.canDoThat(resource))]
class UpdateSomeEntity
{
    public int $entityId;
    // ... other properties.
}

namespace MyVendor\MyApp\SomeBoundingContext\Command;

use MakinaCorpus\AccessControl\AccessMethod;
use MakinaCorpus\AccessControl\AccessRole;

#[AccessRole("ROLE_ADMIN")]
#[AccessMethod("ThatService.canDoThat(subject, resource)")]
class DoThisOrThatCommand
{
}

namespace MyVendor\MyApp\SomeBoundingContext\Command;

use MakinaCorpus\AccessControl\AccessAllOrNothing;
use MakinaCorpus\AccessControl\AccessMethod;
use MakinaCorpus\AccessControl\AccessRole;

#[AccessAllOrNothing]
#[AccessRole("ROLE_ADMIN")]
#[AccessMethod("ThatService.canDoThat(subject, resource)")]
class DoThisOrThatCommand
{
}

namespace MyVendor\MyApp\SomeBoundingContext\Command;

use MakinaCorpus\AccessControl\AccessRole;

#[AccessRole("ROLE_ADMIN")]
class DoThisOrThatCommand
{
}

namespace MyVendor\MyApp\SomeBoundingContext\Controller;

use MakinaCorpus\AccessControl\AccessDelegate;
use MyVendor\MyApp\SomeBoundingContext\Command\DoThisOrThatCommand

class SomeController
{
    #[AccessDelegate(DoThisOrThatCommand::class)]
    public function doThisOrDoThatAction(Request $request, /* ... */): Response
    {
    }
}


return [
    MakinaCorpus\AccessControl\Bridge\Symfony\AccessControlBundle::class => ['all' => true],
];

namespace App\Controller;

use App\Entity\BlogPost;
use MakinaCorpus\AccessControl\AccessMethod;

class BlogPostController
{
    /**
     * Let's consider that you have an ArgumentValueResolver for the
     * BlogPost class here.
     */
    #[AccessMethod(post.isUserOwner(subject)]
    public function edit(BlogPost $post)
    {
    }
}

namespace App\Controller;

use App\Entity\BlogPost;
use MakinaCorpus\AccessControl\AccessMethod;

class BlogPostController
{
    /**
     * Let's consider that you have an ArgumentValueResolver for the
     * BlogPost class here.
     */
    #[AccessMethod(post.isTokenValid(token: accessToken)]
    public function view(BlogPost $post, string $accessToken)
    {
    }
}