ac/kalinka-bundle
Symfony2 bundle integrating the Kalinka authorization library. Configure role/action policies via YAML, set default/anonymous/authenticated roles, inject the kalinka.authorizer service to check permissions, and register custom guards with the kalinka.guard tag.
Installation:
composer require ac/kalinka-bundle:~0.1.0
Register the bundle in config/bundles.php:
return [
// ...
AC\KalinkaBundle\ACKalinkaBundle::class => ['all' => true],
];
Basic Configuration (config/packages/ac_kalinka.yaml):
ac_kalinka:
authorizers:
default:
roles:
authenticated:
document:
read: 'allow'
First Use Case:
Inject the KalinkaAuthorizer service in a controller/service and check permissions:
use AC\KalinkaBundle\Authorizer\KalinkaAuthorizerInterface;
public function __construct(private KalinkaAuthorizerInterface $authorizer) {}
public function showDocument(Document $document)
{
if (!$this->authorizer->isAllowed('document:read', $this->getUser())) {
throw $this->createAccessDeniedException();
}
// ...
}
Define granular permissions in YAML:
ac_kalinka:
authorizers:
default:
roles:
admin:
system:
backup: 'allow'
restore: ['admin', 'super_admin'] # Multi-condition
Usage:
// Single condition
$this->authorizer->isAllowed('system:backup', $user);
// Multi-condition (evaluates as OR)
$this->authorizer->isAllowed('system:restore', $user, ['admin', 'super_admin']);
Extend the KalinkaAuthorizer to fetch roles from a database:
public function getUserRoles(User $user)
{
return $this->userRoleRepository->findByUser($user);
}
Use custom logic for complex rules:
roles:
teacher:
document:
update: ['owner', 'unlocked'] # Calls `isOwner()` and `isUnlocked()`
Implementation:
// In a service
public function isOwner(User $user, Document $document)
{
return $user->id === $document->owner_id;
}
Override Voter for seamless security integration:
use AC\KalinkaBundle\Security\KalinkaVoter;
class DocumentVoter extends KalinkaVoter
{
protected function configure(AclBuilder $builder)
{
$builder->addPermission('document:read');
$builder->addPermission('document:update', ['owner', 'unlocked']);
}
}
YAML Syntax Errors:
roles are properly nested under authorizers.<name>.'allow' vs allow).Caching:
php bin/console cache:clear
User Object:
User object must implement AC\KalinkaBundle\Model\UserInterface or have a getRoles() method.Multi-Condition Logic:
GuardPolicy for AND logic:
update: ['owner', 'unlocked'] # OR
// Custom GuardPolicy for AND
public function isAllowed($user, $object, array $attributes)
{
return $this->isOwner($user, $object) && $this->isUnlocked($object);
}
ac_kalinka:
debug: true # Logs denied permissions to `var/log/kalinka.log`
$this->authorizer->getAllowedPermissions($user); // List all allowed permissions
$this->authorizer->getDeniedPermissions($user); // List denied permissions
Custom Authorizers: Create a new authorizer class and register it in services:
services:
app.custom_authorizer:
class: App\Service\CustomAuthorizer
tags: ['ac_kalinka.authorizer']
Override Guard Policies:
Extend AC\KalinkaBundle\GuardPolicy\GuardPolicyInterface and bind it in config:
ac_kalinka:
guard_policies:
owner: App\GuardPolicy\OwnerGuardPolicy
Event Listeners:
Listen for ac_kalinka.authorization_check events to modify authorization logic dynamically:
public function onAuthorizationCheck(GetResponseEvent $event)
{
$token = $event->getToken();
if ($token && $this->isSpecialUser($token->getUser())) {
$event->setResponse(new Response('Allowed!'));
}
}
How can I help you explore Laravel packages today?