manoyeche/imaccessible

Imaccessible - Adds protection to controller methods instead of routes using list of access provided to user.

v0.0.12 2021-03-09 04:01 UTC

This package is auto-updated.

Last update: 2024-06-09 03:50:43 UTC


README

Adds protection to controller methods instead of routes using list of dynamic access provided to user.

Installation

Composer:

    composer require manoyeche/imaccessible

Configuration

User Model:

Add Imaccessible Trait to User model

    use Imaccessible\Traits\Imaccessible;

    class User extends Authenticatable
    {
        use Imaccessible;

    .....

You can now use the access_names attribute and accessibles() hasMany relation to your user model.

    auth()->user()->access_names;

    .....

    User::find($id)->access_names;

    .....

    $user = User::find($id);

    $user->createAccess('USER_EDIT');

    .....

    $user->revokeAccess('USER_EDIT');

UserAccessible Migration:

Using database table to dynamically changes access names.

    php artisan vendor:publish --provider="Imaccessible\Providers\ImaccessibleServiceProvider" --tag="migrations"

    php artisan migrate
    use Imaccessible\Models\UserAccessible;

    .....

    UserAccessible::create([
        'user_id' => $user_id,
        'name' => 'USER_EDIT'
    ]);

Protecting Contoller Methods

Middleware:

Add condition to your middleware.

    use Imaccessible\Imaccessible;

    class AuthMember
    {

        public function handle(Request $request, Closure $next)
        {
            // if (!auth()->check()) {
            //     return redirect()->route('login');
            // }

            if (!Imaccessible::verifyAccess(auth()->user()->access_names)) {
                abort(404);
            }

            return $next($request);
        }
    .....

Controller:

Create a static function accessRules() that returns an array of Access Names. This are called when the middleware verfiy access based on current action from route.

    public function __construct()
    {
        $this->middleware([
            'authMember',
        ]);
    }

    public static function accessRules() {
        return [
            'USER_EDIT' => [  // -- Access Name
                'editForm',   // -- Methods
                'edit'
            ],
            'USER_CREATE' => [
                ...
            ]
        ];
    }

    public function editForm() {
        .....
    }

    public function edit(Request $request) {
        .....
    }

Alternatives

Simple way of protecting method without setting up middleware and controller accessRules.

Call auth()->guardAccess($accessName) inside of controller method, throwing 404 to block access.

    public function editForm() {
        auth()->guardAccess('USER_EDIT');

        ...
    }

You can also add error callback,

    public function editForm() {
        auth()->guardAccess('USER_EDIT', function() {
            throw new Exception("Access Denied");
        });

        ... 
    }

Or use the helper

    public function editForm() {
        if (!auth()->hasAccess('USER_EDIT')) {
            return [
                "error" => "Access Denied."
            ];
        }

        ... 
    }

Helpers

Blade Directive:

Organize blade layout by Access Name

    @hasAccess('USER_EDIT') 
        .....
    @endhasAccess

Auth Helper:

If you need to check if the current user has access to specific Access Name

    auth()->hasAccess('USER_EDIT');