laravel-doctrine / acl Goto Github PK
View Code? Open in Web Editor NEWACL for Laravel Doctrine
Home Page: http://laraveldoctrine.org/
License: MIT License
ACL for Laravel Doctrine
Home Page: http://laraveldoctrine.org/
License: MIT License
I'm using the config driver for permissions and adding permissions to my Role entity, but when I update my DB schema no role_user table is created and no permissions column is added to my Role table. Here is are the relevant files...
config/acl.php
<?php
return [
'roles' => [
'entity' => App\Domain\Entities\Role::class,
],
'permissions' => [
'driver' => 'config',
'list' => [
'edit.orders',
'edit.suppliers',
'edit.warehouses',
'edit.partners',
'edit.products',
'view.orders.all',
'view.orders.self',
'view.suppliers',
'view.warehouses',
'view.partners.all',
'view.partners.self',
'view.products',
],
],
];
Role.php
<?php
namespace App\Domain\Entities;
use Doctrine\ORM\Mapping as ORM;
use LaravelDoctrine\ACL\Contracts\Role as RoleContract;
use LaravelDoctrine\ACL\Mappings as ACL;
use LaravelDoctrine\ACL\Permissions\HasPermissions;
/**
* @ORM\Entity()
*/
class Role extends CoreEntity implements RoleContract
{
use HasPermissions;
/**
* @ORM\Id()
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @var int
*/
protected $id;
/**
* @ORM\Column(type="string")
*
* @var string
*/
protected $name;
/**
* @ACL\HasPermissions
*/
protected $permissions;
//...
User.php
<?php
namespace App\Domain\Entities;
use Doctrine\ORM\Mapping as ORM;
use App\Domain\ValueObjects\Name;
use LaravelDoctrine\ACL\Contracts\HasRoles as HasRolesContract;
use LaravelDoctrine\ACL\Mappings as ACL;
use LaravelDoctrine\ACL\Roles\HasRoles;
use LaravelDoctrine\ORM\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
/**
* @ORM\Entity()
*/
class User extends CoreEntity implements AuthenticatableContract, CanResetPasswordContract, AuthorizableContract, HasRolesContract
{
use Authenticatable, CanResetPassword, Authorizable, HasRoles;
/**
* @ORM\Id()
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @var int
*/
protected $id;
/**
* The name value object which holds the
* first and last name of the user
* @ORM\Embedded(class="App\Domain\ValueObjects\Name", columnPrefix=false)
*
* @var Name
*/
protected $name;
/**
* @ORM\Column(type="string",unique=true)
* @var string
*/
protected $email;
/**
* @ACL\HasRoles
*/
protected $roles;
//...
I feel like I'm missing something obvious, but I'm not seeing it.
There is an optional parameter before required in MappedEventSubscriber
. Should look into fixing that.
Target class [App\Http\Middleware\DisablePreventBack] does not exist.
Illuminate\Container\Container::build
:805
vendor/laravel/framework/src/Illuminate/Container/Container.php:805
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function build($concrete)
{
// If the concrete type is actually a Closure, we will just execute it and
// hand back the results of the functions, which allows functions to be
// used as resolvers for more fine-tuned resolution of these objects.
if ($concrete instanceof Closure) {
return $concrete($this, $this->getLastParameterOverride());
}
try {
$reflector = new ReflectionClass($concrete);
} catch (ReflectionException $e) {
throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e);
}
// If the type is not instantiable, the developer is attempting to resolve
// an abstract type such as an Interface or Abstract Class and there is
// no binding registered for the abstractions so we need to bail out.
if (! $reflector->isInstantiable()) {
return $this->notInstantiable($concrete);
}
$this->buildStack[] = $concrete;
$constructor = $reflector->getConstructor();
Any idea how I could debug this issue?
Hi, I'm new on this lib and I have an issue making work.
I post my question on stackoverflow but I thought that I had to ask here too.
The code I have for my Role
class is the following:
namespace App\Entities;
use Doctrine\ORM\Mapping as ORM;
use LaravelDoctrine\ACL\Contracts\Role as RoleContract;
use LaravelDoctrine\ACL\Contracts\HasPermissions as HasPermissionContract;
use LaravelDoctrine\ACL\Permissions\HasPermissions;
/**
* @ORM\Entity
* @ORM\Table(name="role")
*/
class Role implements
RoleContract,
HasPermissionContract
{
use HasPermissions;
/**
* @ACL\HasPermissions
*/
public $permissions;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
}
The documentation says to create a class Role
that implements RoleContract
.
Later on, it says to use HasPermissions
trait, that implements some methods from RoleContract
.
But I got an error that says me I have to implement the 'getPermissions' method.
The documentation don't say what I have to implement here, or what I have to use to fix this.
Can you please make it clear for me?
Thank in advance guys!
Is there any plan to provide attribute support on this repository ?
I have looked around the codebase for this but couldn't find an easy way to make it work, maybe I'm also missing something.
@eigan Do you have an idea how this could be implemented ? I am willing to put in the time for it :)
With the ACL driver set to 'doctrine' Doctrine\DBAL\Exception\TableNotFoundException is thrown when running;
doctrine:migrations:migrate
The error is also thrown for ;
doctrine:schema:update
doctrine:migrations:diff
This makes it impossible to use the 'doctrine' driver from an empty database.
Shouldn't this be optional? So, if I want my role to have permissions, I implement this contract.
Right now, If I implement RoleContract, it will automatically implement HasPermissions (which not necesarily is the expected behaviour).
ACL: v1.0.16
jwt-auth: 1.0.0-rc3
Laravel 5.7
We are seeing quite a slowdown once we upgraded from laravel 5.6 and jwt-auth 1.0.0-rc2 to the latest versions and narrowed it down to a change jwt-auth 1.0.0-rc3 that loads the user provider on each request where this previously wasn't the case. The laravel doctrine user provider will be called and eventually a call to the getAllPermissions function in the PermissionDriver class. This will call the getRepository (https://github.com/laravel-doctrine/acl/blob/1.0/src/Permissions/DoctrinePermissionDriver.php#L91) function which in turn will execute a function to list all tables on the database.
(Doctrine\DBAL\Schema\AbstractSchemaManager::listTableNames)
The query that's being executed is SHOW FULL TABLES WHERE Table_type = ?
. The performance on our environment for this query is terrible unfortunately. A single call takes about 4-5 seconds to execute. This is most likely due to the amount of databases and tables on our environment (±800 databases with 280 tables each).
Is there a way to avoid this query from being executed at all? What are your thoughts on this?
When running the ExampleTest in Laravel 5.8, all TestCases shut down with error "Illuminate\Contracts\Container\BindingResolutionException: Target [Illuminate\Contracts\Auth\Access\Gate] is not instantiable."
I'm getting the following error when upgrading from 1.2.0 to the latest version (1.2.3).
MappingException in MappingException.php line 96: Class 'LaravelDoctrine\ORM\Auth\Passwords\PasswordReminder' does not exist
I've narrowed it down to 1.2.1. So 1.2.0 is the latest version that works for me. I'm running Laravel 5.2
Full (relevant) stack trace:
MappingException in MappingException.php line 96:
Class 'LaravelDoctrine\ORM\Auth\Passwords\PasswordReminder' does not exist
in MappingException.php line 96
at MappingException::nonExistingClass('LaravelDoctrine\ORM\Auth\Passwords\PasswordReminder') in RuntimeReflectionService.php line 41
at RuntimeReflectionService->getParentClasses('LaravelDoctrine\ORM\Auth\Passwords\PasswordReminder') in AbstractClassMetadataFactory.php line 281
at AbstractClassMetadataFactory->getParentClasses('LaravelDoctrine\ORM\Auth\Passwords\PasswordReminder') in AbstractClassMetadataFactory.php line 311
at AbstractClassMetadataFactory->loadMetadata('LaravelDoctrine\ORM\Auth\Passwords\PasswordReminder') in ClassMetadataFactory.php line 78
at ClassMetadataFactory->loadMetadata('LaravelDoctrine\ORM\Auth\Passwords\PasswordReminder') in AbstractClassMetadataFactory.php line 216
at AbstractClassMetadataFactory->getMetadataFor('LaravelDoctrine\ORM\Auth\Passwords\PasswordReminder') in AbstractClassMetadataFactory.php line 115
at AbstractClassMetadataFactory->getAllMetadata() in IlluminateRegistry.php line 361
at IlluminateRegistry->getManagerForClass('MyApp\Domain\Account\User') in DoctrineServiceProvider.php line 224
at DoctrineServiceProvider->LaravelDoctrine\ORM\{closure}(object(Application), array('driver' => 'doctrine', 'model' => 'MyApp\Domain\Account\User'))
at call_user_func(object(Closure), object(Application), array('driver' => 'doctrine', 'model' => 'MyApp\Domain\Account\User')) in CreatesUserProviders.php line 30
at AuthManager->createUserProvider('users') in AuthManager.php line 123
at AuthManager->createSessionDriver('web', array('driver' => 'session', 'provider' => 'users')) in AuthManager.php line 95
at AuthManager->resolve('web') in AuthManager.php line 70
Not sure if you're following semver, but I didn't expect a patch update to break this. Is there anything I can do to help fix this?
So, it's been approximately 6+ hours and this person has finally tracked down why @ACL\HasRole
and @ACL\HasPermission
is failing to be mapped on our entities, and with that the pivot tables migrations aren't being generated and the properties aren't ArrayCollections.
When config/auth.php
has auth.driver
or auth.providers.users.driver
set to doctrine
the annotations fail to subscribe to events when the laravel auth driver is set to doctrine.
From my understanding, all managers are singletons in the registry, so once they're booted and resolved that's it. As the auth driver is booted up before the ACL is able to boot, which I presume itself , the subscribers are never resolved.
I've tried moving the ACL Service Provider to above the ORM's in my config/app.php
providers, however, I started receiving errors about Gedmo annotations not existing. One solution that I've found to work for me is to move all code in from boot method, minus the config publishes, into the register method, however, I'm not sure if that is the solution here.
You can find an example repo with this setup here.
Sidenote: This may also affect the BeberleiExtensionsServiceProvider
as it also injects the DoctrineManager
class add a callback, but I haven't tested it.
I have a service provider into which a doctrine entity manager is injected using type hinting in boot method, like this:
public function boot(EntityManagerInterface $entity_manager)
This works, unless LaravelDoctrine\ACL\AclServiceProvider::class is included before this provider in app.php. Then, when "composer update" is run this error is returned:
[ReflectionException]
Class App\Permission does not exist
If I move my provider above the LaravelDoctrine\ACL\AclServiceProvider::class entry, I do not get an error, but I get the issue that I described here:
#31
Using PHPUnit 4.8.26 on Laravel 5.2 I get the following on certain routes:
Illuminate\Contracts\Container\BindingResolutionException: Target [Illuminate\Contracts\Container\Container] is not instantiable while building [LaravelDoctrine\ACL\RegisterMappedEventSubscribers, LaravelDoctrine\ACL\RegisterMappedEventSubscribers, LaravelDoctrine\ACL\RegisterMappedEventSubscribers, LaravelDoctrine\ACL\RegisterMappedEventSubscribers]
Full stack trace:
Illuminate\Contracts\Container\BindingResolutionException: Target [Illuminate\Contracts\Container\Container] is not instantiable while building [LaravelDoctrine\ACL\RegisterMappedEventSubscribers, LaravelDoctrine\ACL\RegisterMappedEventSubscribers, LaravelDoctrine\ACL\RegisterMappedEventSubscribers, LaravelDoctrine\ACL\RegisterMappedEventSubscribers].
\vendor\laravel\framework\src\Illuminate\Container\Container.php:748
\vendor\laravel\framework\src\Illuminate\Container\Container.php:629
\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:697
\vendor\laravel\framework\src\Illuminate\Container\Container.php:849
\vendor\laravel\framework\src\Illuminate\Container\Container.php:804
\vendor\laravel\framework\src\Illuminate\Container\Container.php:775
\vendor\laravel\framework\src\Illuminate\Container\Container.php:629
\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:697
\vendor\laravel-doctrine\orm\src\DoctrineManager.php:80
\vendor\laravel-doctrine\orm\src\DoctrineManager.php:61
\vendor\laravel-doctrine\orm\src\DoctrineManager.php:39
\vendor\laravel-doctrine\orm\src\BootChain.php:29
\vendor\laravel-doctrine\orm\src\DoctrineServiceProvider.php:128
\vendor\laravel\framework\src\Illuminate\Container\Container.php:1031
\vendor\laravel\framework\src\Illuminate\Container\Container.php:996
\vendor\laravel\framework\src\Illuminate\Container\Container.php:648
\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:697
\vendor\laravel-doctrine\orm\src\DoctrineServiceProvider.php:98
\vendor\laravel\framework\src\Illuminate\Container\Container.php:731
\vendor\laravel\framework\src\Illuminate\Container\Container.php:629
\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:697
\vendor\laravel\framework\src\Illuminate\Container\Container.php:1174
\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:151
\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:120
\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:108
\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:84
\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:65
\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:51
I've tried a few things that came to mind, but I was wondering if you have any idea what might be causing this?
When updating to version 1.0.11, I get the following error message:
Error Output: PHP Fatal error: Call to undefined method LaravelDoctrine\ORM\DoctrineManager::onResolve() in /home/pablo/Software/php/jobrole-management/vendor/laravel-doctrine/acl/src/AclServiceProvider.php on line 26
After running:
composer require "laravel-doctrine/acl"
and inserting this into config/app.php:
LaravelDoctrine\ACL\AclServiceProvider::class,
I get this:
ErrorException in Manager.php line 8:
Declaration of LaravelDoctrine\ACL\Manager::createDriver($driver, array $settings = Array) should be compatible with LaravelDoctrine\ORM\Configuration\Manager::createDriver($driver, array $settings = Array, $resolve = true)
Laravel 5.3.1
With ALC config settings;
'driver' => 'config'
users.permissions column is not being created when running either;
doctrine:schema:update
doctrine:migrations:diff
As the title says, there are some changes needed to support Laravel 6
Hello!
I tried to update the Permission entity schema, and then I couldn't validate the schema, or clear the metadata cache, or run any other artisan command.
I tried adding the field "isResource" to my permission entity and I would get the following errors when running artisan commands or any api request:
vagrant@homestead:~/Code/project$ php artisan help doctrine:clear:metadata:cache
In AbstractMySQLDriver.php line 80:
An exception occurred while executing 'SELECT t0.id AS id_1, t0.name AS name_2, t0.is_resource AS is_resource_3, t0.created_at AS created_at_4, t0.updated_at AS updated_at_5, t0.deleted_at AS deleted_at_6 FROM core_permissions t0 WHERE ((t0.deleted_at IS NULL))':
SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.is_resource' in 'field list'
In PDOConnection.php line 109:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.is_resource' in 'field list'
In PDOConnection.php line 107:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.is_resource' in 'field list'
It seems that ACL, when it resolves the DoctrineManager class, it attempts to define permissions, even on console. And if the Permission schema is not up to date, it will fail and the application will die.
Not defining permissions in console:
AclServiceProvider.php
<?php
namespace LaravelDoctrine\ACL;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Illuminate\Contracts\Auth\Access\Gate;
use Illuminate\Support\ServiceProvider;
use LaravelDoctrine\ACL\Contracts\HasPermissions;
use LaravelDoctrine\ACL\Mappings\AnnotationLoader;
use LaravelDoctrine\ACL\Permissions\PermissionManager;
use LaravelDoctrine\ORM\DoctrineManager;
class AclServiceProvider extends ServiceProvider
{
/**
* Boot the service provider.
*/
public function boot()
{
if (!$this->isLumen()) {
$this->publishes([
$this->getConfigPath() => config_path('acl.php'),
], 'config');
}
$this->app->make(DoctrineManager::class)->onResolve(function () {
if (!$this->app->runningInConsole()) { // <- here
$this->definePermissions(
$this->app->make(Gate::class),
$this->app->make(PermissionManager::class)
);
}
});
}
/**
* Register the service provider.
* @return void
*/
public function register()
{
$this->mergeConfig();
$this->registerAnnotations();
$manager = $this->app->make(DoctrineManager::class);
$manager->extendAll(RegisterMappedEventSubscribers::class);
$this->registerPaths($manager);
}
/**
* @param Gate $gate
* @param PermissionManager $manager
*/
protected function definePermissions(Gate $gate, PermissionManager $manager)
{
foreach ($manager->getPermissionsWithDotNotation() as $permission) {
$gate->define($permission, function (HasPermissions $user) use ($permission) {
return $user->hasPermissionTo($permission);
});
}
}
/**
* Register annotations.
*/
protected function registerAnnotations()
{
AnnotationRegistry::registerLoader([
new AnnotationLoader,
'loadClass',
]);
}
/**
* Merge config.
*/
protected function mergeConfig()
{
$this->mergeConfigFrom(
$this->getConfigPath(), 'acl'
);
if ($this->isLumen()) {
$this->app->configure('acl');
}
}
/**
* @return string
*/
protected function getConfigPath()
{
return __DIR__ . '/../config/acl.php';
}
/**
* @return bool
*/
protected function isLumen()
{
return str_contains($this->app->version(), 'Lumen');
}
/**
* @param $manager
*/
private function registerPaths($manager)
{
$permissionManager = $this->app->make(PermissionManager::class);
if ($permissionManager->useDefaultPermissionEntity()) {
$manager->addPaths([
__DIR__ . DIRECTORY_SEPARATOR . 'Permissions',
]);
}
}
}
Best regards!
Hi,
How do I add role in User?
When running $ php artisan doctrine:schema:validate
It says:
* The association Services\User\Data\Entities\User\User#roles refers to the inverse side field Services\User\Data\Roles\Role#users which does not exist.
Though the actual checking of roles is working correctly.
Hi there I am using doctrine acl for my laravel 5.3 action.
for login I used larvel's default Auth system,
after login to the system it removes relation of role and user.
can anyone help me about this ?
Hi,
I am trying to implemement database permissions.
No error is thrown when the entity inside the config points to default LaravelDoctrine\ACL\Permissions\Permission::class.
But when I replace it with my own App\Permission::class I get this:
ReflectionException in IlluminateRegistry.php line 330:
Class App\Permission does not exist
From your site:
Using the Gate helper
All permissions are automatically defined inside Laravel's Gate helper.
Gate::allows('create.posts');
@can('create.posts');
$user->can('create.posts');
I cannot get this to work.
So, while this return TRUE:
$user->hasPermissionTo('users.write');
This return FALSE:
\Gate::allows('users.write');
I'm currently looking for an ACL package to implement. Would it be possible to use this package for resource specific permissions?
I want to implement some rules like:
I think it's similar to the connection between user and organisation where an organisation can be seen as category. But It would be hacky to do it like this:
if($user->belongsToOrganisation(['category:travel']) && $user->hasPermissionTo('delete.article')) {
//some action..
}
Maybe something like this would be nice ?:
if($user->hasPermissionTo('delete.article')->inContextTo('category:travel')->validate()) {
//some action..
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.