Git Product home page Git Product logo

mateusjunges / laravel-acl Goto Github PK

View Code? Open in Web Editor NEW
560.0 17.0 55.0 1.67 MB

This package helps you to associate users with permissions and permission groups with laravel framework

Home Page: https://junges.dev/documentation/laravel-acl/

License: MIT License

PHP 96.88% Blade 3.12%
laravel package acl php7 authorization authentication security access-control access-management hacktoberfest

laravel-acl's Introduction

Readme banner

Caution

As of January 2024, this package is no longer maintained. Please use spatie/laravel-permission instead.

Latest Version on Packagist Total Downloads MIT Licensed Check & fix styling

Laravel ACL

This package allows you to manage user permissions and groups in a database, and is compatible with Laravel v5.8 or higher. Please check the documentations.

Sponsor my work!

If you think this package helped you in any way, you can sponsor me on GitHub!

Sponsor Me

Tests

Run composer test to test this package.

Contributing

Thank you for considering contributing for the Laravel ACL package! The contribution guide can be found here.

Changelog

Please see changelog for more information about the changes on this package.

Credits

License

The Laravel ACL package is open-sourced software licenced under the MIT License. Please see the License File for more information.

laravel-acl's People

Contributors

alangiacomin avatar dependabot[bot] avatar justzerooo avatar kimyvgy avatar laravel-shift avatar mateusjunges avatar mikew1 avatar niladam avatar ohchiko avatar r3l4x3 avatar realrashid avatar reecem avatar reed-jones avatar vsc55 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-acl's Issues

Permissions hierarchy middleware

Let's look at what permissions there are for this example:

  • admin
  • admin.auth
  • admin.auth.user
  • admin.auth.user.modify
  • admin.auth.user.modify.create

Checks permissions in a hierarchical structure, this permission admin.auth.user.modify.create will check for all of above permissions.

Inspirated on this issue

can't sync group from user

the UsersTrait needs have syncGroup method
i know i can use some thing like

$user->groups()->sync($request->groups);

but code has syncPermissions so i think u should add this one too

Wrong User class used by artisan command

Hi,

we can modify the User class to use in acl.php config file but UserPermisison command file (Console/Commands/UserPermissions.php) is still using the default App\User class. Which leads in error when running artisan command php artisan user:permissions 1.

Class 'App\User' not found

  at vendor/mateusjunges/laravel-acl/src/Console/Commands/UserPermissions.php:45
    41|     {
    42|         try {
    43|             $userParameter = $this->argument('user');
    44|             if (is_numeric($userParameter)) {
  > 45|                 $user = User::find((int) $userParameter);
    46|             } elseif (is_string($userParameter)) {
    47|                 $table = config('acl.tables.users');
    48|                 $columns = $this->verifyColumns($table);
    49| 

      +14 vendor frames 
  15  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

Scope user to permission model

Add new scope to the permission Model

  • Add new user scope to the permission model, to certain queries only to permissions assigned to the specified user

Show permissions

  • Create an artisan command to show all the permissions on the database

Facade\IgnitionContracts\SolutionProviderRepository not instantiable

Due to the recent 2.2.0 update, which added ignition solutions, I can't get your package to work 😅
At least I think this is the culprit. Here's the stack trace:

Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

   Illuminate\Contracts\Container\BindingResolutionException  : Target [Facade\IgnitionContracts\SolutionProviderRepository] is not instantiable.

  at /opt/vendor/laravel/framework/src/Illuminate/Container/Container.php:979
    975|         } else {
    976|             $message = "Target [$concrete] is not instantiable.";
    977|         }
    978| 
  > 979|         throw new BindingResolutionException($message);
    980|     }
    981| 
    982|     /**
    983|      * Throw an exception for an unresolvable primitive.

  Exception trace:

  1   Illuminate\Container\Container::notInstantiable("Facade\IgnitionContracts\SolutionProviderRepository")
      /opt/vendor/laravel/framework/src/Illuminate/Container/Container.php:813

  2   Illuminate\Container\Container::build("Facade\IgnitionContracts\SolutionProviderRepository")
      /opt/vendor/laravel/framework/src/Illuminate/Container/Container.php:682

  Please use the argument -v to see more details.
Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

When I revert to version 2.1.1 the bug goes away.

Probably bug with group() scope in UsersTrait

I want to get users who belong to admin group. I use this method:
$users = User::group('admin')->get();

Unfortunately this method returns a list of all users. So here's the bug or am I doing something wrong?

PHP 7.4 TravisCI failures

The package tests for PHP 7.4 on TravisCI return 3 errors:

There were 3 errors:
1) Junges\Tests\CommandsTest::it_can_create_a_permission
ErrorException: Trying to access array offset on value of type int
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Input/ArrayInput.php:135
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Input/Input.php:55
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Application.php:208
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Application.php:149
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Console/Application.php:89
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Console/Application.php:188
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:250
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:237
/home/travis/build/jungessolutions/laravel-acl/tests/CommandsTest.php:26
2) Junges\Tests\CommandsTest::it_can_create_a_group
ErrorException: Trying to access array offset on value of type int
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Input/ArrayInput.php:135
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Input/Input.php:55
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Application.php:208
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Application.php:149
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Console/Application.php:89
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Console/Application.php:188
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:250
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:237
/home/travis/build/jungessolutions/laravel-acl/tests/CommandsTest.php:41
3) Junges\Tests\InstallCommandTest::test_installation_command
ErrorException: Trying to access array offset on value of type int
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Input/ArrayInput.php:135
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Input/Input.php:55
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Application.php:208
/home/travis/build/jungessolutions/laravel-acl/vendor/symfony/console/Application.php:149
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Console/Application.php:89
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Console/Application.php:188
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:250
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:136
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:220
/home/travis/build/jungessolutions/laravel-acl/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php:55
/home/travis/build/jungessolutions/laravel-acl/tests/InstallCommandTest.php:21
ERRORS!
Tests: 49, Assertions: 51, Errors: 3.

Add exceptions and Fix README

  • Add explanations on how to capture and handle exceptions generated in the package.
  • Fix README documentation about permissionOrGroup middleware. It is showing \Junges\ACL\Middlewares\PermissionOrGroup::class instead of \Junges\ACL\Middlewares\PermissionOrGroupMiddleware::class.

seeder programatically

1st, i tried to use artisan command with phpstorm, but the command seems to be not registered(no autocomplete).
2nd, when trying to call artisan command programmatically, it cant bypass the confirm function inside the CreateGroup.php(console\commands).
also, there is Portuguese language in that confirmation prompt, maybe use English so its easier to understand? PS: i use google translate to understand that prompt message.

the point is, i want to be able to seed my permission database such as admin permissions and regular member/user permissions with different group without the need to manually issuing command to artisan for each and every one of the group or permission.

Laravel v5.8.16
ACL v1.6.0

Error in $user->syncPermissions

I am testing the $user->syncPermissions(); but when you not send any permission (Null) it giving me:

Argument 1 passed to App\User::syncPermissions() must be of the type array, null given, called in

The problem is this function:

public function syncPermissions(array $permissions)
{
$permissions = $this->convertToPermissionIds($permissions);
if ($permissions->count() == 0)
return false;
$this->permissions()->sync($permissions);
return $this;

}

So I suggest to add null parameter.

Exception at UsersTrait:200 when revokingGroup from User

When trying to revoke groups from user by passing an array of slugs there is an exception (notice) and group isnt revoked:

$user->revokeGroup(['petty-cash-user'])
PHP Notice:  Trying to get property 'id' of non-object in D:/Proyectos/software/vendor/mateusjunges/laravel-acl/src/Traits/UsersTrait.php on line 200

image

Line 200 should be return $_group->id instead of return $group->id;
image

Typo on ACLServiceProvider

Fix typo on ACLServiceProvider

//Load translations
$this->loadTranlations();

instead of

//Load translations
$this->loadTranslations();

And

public function loadTranlations(){
    //
}

instead of

public function loadTranslations(){
    //
}

is_numeric and is_string verification

is_numeric and is_string conflicts

Change

if (is_string($permission))
    //
else if (is_numeric($permission))
    //

for

if (is_numeric($permission))
    //
else if (is_string($permission))
    //

because is_string('5') returns true, and the check for is_numeric is not executed.

Throw exception while creating duplicate group

Throw new exception while creating duplicate group.

Currently returnin SQL error:

SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint "groups_name_unique"
DETAIL:  Key (name)=(teste) already exists. (SQL: insert into "groups" ("name", "slug", "description", "updated_at", "created_at") values (teste, teste, teste, 2019-04-28 06:06:20, 2019-04-28 06:06:20) returning "id")

Catching the denied permissions/groups list in the custom handler's exception

Is your feature request related to a problem? Please describe.

When permissions are denied using the built-in middlewares, there is no list of denied permissions/groups being passed on with the exception to the custom handler. I would like to catch them along with the 403 denied message.

Example:

Route::middleware('permissions:One', 'permissions:Two', 'permissions:Three')->group(function(){

	Route::get('/', 'IndexController@index')->name('home');

});

When permissions One and Three gets denied, I would like the exception to show them.
Currently the exception is like below:

Junges\ACL\Exceptions\UnauthorizedException ~statusCode: 403~headers: Array(0)*message: "This user does not have the necessary permissions to access this route"...
~statusCode: 403
~headers: Array(0)
*message: "This user does not have the necessary permissions to access this route"
~string: ""
*code: 0
*file: "<application-path>\vendor\mateusjunges\laravel-acl\src\Exceptions\UnauthorizedException.php"
*line: 33
~trace: Array(43)
~previous: null

I would like it to be, for the above case : (refer after *message)

Junges\ACL\Exceptions\UnauthorizedException ~statusCode: 403~headers: Array(0)*message: "This user does not have the necessary permissions to access this route"...
~statusCode: 403
~headers: Array(0)
*message: "This user does not have the necessary permissions to access this route"

    * denied : Array [
        0: One
        1: Three
    ]

~string: ""
*code: 0
*file: "<application-path>\vendor\mateusjunges\laravel-acl\src\Exceptions\UnauthorizedException.php"
*line: 33
~trace: Array(43)
~previous: null

Describe the solution you'd like

I have gone this far in catching the denied permissions list

PermissionMiddleware.php

public function handle($request, Closure $next, $permissions)
	{
		if (Auth::guest()) {
			throw UnauthorizedException::notLoggedIn();
		}

                // New Array
		$denied_permissions = [];

		$permissions = is_array($permissions)
			? $permissions
			: explode('|', $permissions);
		foreach ($permissions as $permission) {
			if (Auth::user()->can($permission)) {
				return $next($request);
			} else {
				array_push($denied_permissions, $permission);
			}
		}

		throw UnauthorizedException::forPermissions($denied_permissions);
	}

And, receiving it in

UnauthorizedException.php

public static function forPermissions($denied_permissions): self
	{
		$message = trans('acl::acl.forPermissions');

		$denied = $denied_permissions;

		return new static(Response::HTTP_FORBIDDEN, $message, null, $denied);
	}

But, I am unable to pass it to the Laravel Response.

Describe alternatives you've considered
None.
I am not sure, this is the right approach. I tried some way to make it work for me.
This is my first time contributing in the forum. Pardon if anything is not right.

Additional context
Add any other context or screenshots about the feature request here.

Check permissions based on wildcards

Check permissions based on wildcards

Using strings allows us to write permissions with wildcards, like
users.* (check for users who has any permissions related to users, like users.create or users.delete).
To make this work, her's an example of code we could use to check if a given User has permissions for something:

public function hasPermission($permission) : bool
{
    $permissions = $this->getPermissions();
    $permission = $permissions->filter(function($permission) use ($permission){
     //Escape dots, replace * with valid regex substitution
       $regex = str_replace(
            '.', '\.', str_replace(
                '*', '[^\.]+', $permission->name
            )
       );
        return preg_match("/^$regex$/", $permission); 
    })
    ->first();
    return !is_null($permission);
}

Iterating through permissions filtering those which correspond to the pattern;
If there is one, we can grant access.
To preserve code brevity, we need to ensure that a wildcard replace a whole segment. Something like u*.create is not allowed.

Move facade/ignition to composer require

Hi Mateus,

With regards the latest addition of the ignition solutions (#141) to the package and the addition of the facade/ignition package (#144) to make the ignition contracts work because they are bound to the container in the actual ignition package, I initially added it to the require-dev section of laravel-acl's composer file as it functioned locally, 'it worked for me' situation .... 😄

In hindsight and in light of #143, the latest comment by the @ACvijic there after it was closed, I figure that it should be added to the main require section of the composer file.

I didn't do that originally as that seemed maybe a bit rude to force that need upon a person as it would suddenly result in them having a completely different error page than what they had unexpectedly.

This may be a bit confusing to a new person starting, or irritation to developers who might not have wanted ignition installed.

Could there be a discussion of how that could be solved?

I am thinking of the following options:

  • Move the facade/ignition requirement to the require part of the composer file.
    • make a note about it installing this in the documents, then people know.
  • or, add a suggests section of the composer file for the facade/ignition package, encouraging them to install it, but this would still result in a failure on first install (may not work/ give best install experience)
  • or, make the ignition solutions an opt-in thing via the config file, and suggest the use of the facade/ignition package
    • this would fix the fact of 'suggesting' the use of ignition.

I thought this would be better to check here instead of opening another PR to just change the composer file again. It may be practical to make this more useful and functional.

Throw exception while creating duplicate permission

Throw exception while creating duplicate permission.
Is currently returning the following error:

SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint "permissions_name_unique"
DETAIL:  Key (name)=(teste) already exists. (SQL: insert into "permissions" ("name", "slug", "description", "updated_at", "created_at") values (teste, teste, teste, 2019-04-28 06:01:14, 2019-04-28 06:01:14) returning "id")

Uma tabela a mais para atribuir setores

Ola Mateus tudo bem? Obrigado pelo seu conhecimento e fornece-lo pra todos!

Gostaria de tirar uma duvida e talvez essa dúvida pode surgir uma nova funcionalidade no ACL.

Tenho uma necessidade de criar uma tabela de setores (setores de uma empresa, RH, Diretoria, Marketing, etc) e em cada setor os usuários teriam "Roles" e "Permissions".
EX:
João - Diretoria -Admin - todas as permissões

Mas ele também pode fazer parte de outro setor.

João - Marketing - supervisor - permissões de supervisor de marketing.

Não sei se deu pra entender, mas a ideia seria de adicionar regras e permissões para um setor, onde usuário podem fazer parte de mais de um setor.

Não sei se consegui ser claro, mas como conseguiria fazer isso utilizando o ACL?

Obrigado desde já!!

Customize Migration Problem

Describe the bug
Customized migration table doesn't get reflected when running php artisan migrate.
Migration process will use migration defined in [root]/vendor/mateusjunges/laravel-acl/src/database/migrations/***.php and not from [root]/database/migrations/vendor/junges/acl/***.php.

To Reproduce
Test using version 1.7.1
Steps to reproduce the behavior:

  1. Run command php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider" --tag="migrations"
  2. Edit and add a new column $table->uuid('uuid') in [root]/database/migrations/vendor/junges/acl/create_permissions_table.php
  3. Run command php artisan migrate
  4. Check database for changes

Eager loading Permissions & Groups

Issue:

When checking for permissions via blade directives, each check results in a new DB query. Granted, these queries take between 200 & 500 μs, but consider the following use-case:
I have a sidebar. For each link in that sidebar, I want to check user permissions. How many links I have there equals to how many queries I'll have when rendering each page.

Sugestions:

I tried eager loading permissions and groups.permissions, then I checked the code and figured out that that didn't matter. The hasPermission() makes a new DB query anyway.
It would be great if the Junges\ACL\Traits\UsersTrait could be changed to use eager-loaded relations, instead of making new queries.
The other solution would be to register a singleton via your service provider, which would query the database at least two times, to load all Permissions & Groups.

New blade directives

Create following new custom blade directives:

  • elsegroup
  • elsepermission
  • anypermission
  • anygroup
  • allpermissions
  • allgroups

Error on Install Migrations

Hi, I was trying to install your package, but I have an error and your migration and config publish don't work:

error_laravel-acl

Migrating: 2019_03_16_005237_create_permissions_table

Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1103 Incorrect table name '' (SQL: create table `` (id int unsigned not null auto_increment primary key, `name` varchar(255) not null, `slug` varchar(255) not null, `description` text not null, `deleted_at` timestamp null, `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')

at C:-----
660| // If an exception occurs when attempting to run a query, we'll format the error
661| // message to include the bindings with SQL, which will make this exception a
662| // lot more helpful to the developer instead of just the database's errors.
663| catch (Exception $e) {

664| throw new QueryException(
665| $query, $this->prepareBindings($bindings), $e
666| );
667| }
668|

Exception trace:

1 PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1103 Incorrect table name ''")
C:-----

2 PDO::prepare("create table `` (id int unsigned not null auto_increment primary key, `name` varchar(255) not null, `slug` varchar(255) not null, `description` text not null, `deleted_at` timestamp null, `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci'")
C:-----

Please use the argument -v to see more details.

C:------
λ php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider::class" --tag="config"
Publishing complete.

C:-------
λ php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider::class" --tag="config"
Publishing complete.

I hope you can help because I want to use your package.

Thank you

New methods to handle permissions and groups

Add new methods on package traits to handle user permission and groups

    • Add method revokeAllPermissions in UsersTrait (remove all user permissions)
      • Add method revokeAllGroups in UsersTrait (remove all user groups)
    • Add method revokeAllPermissions in GroupsTrait (remove all group permissions)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.