InvalidArgumentException in ability middleware in Zizaco / entrust

26 Views Asked by At

I am using middleware on my route like below

Route::get('posts', 'PostControlle@index')->middleware('ability:super_admin,canViewPost,false');

but I am getting an InvalidArgumentException.

1

There are 1 best solutions below

0
On

I believe the problem is in ability() method of vendor\zizaco\entrust\src\Entrust\Traits\EntrustUserTrait.php class. So, I've overridden this method in User.php model class.

The third parameter will string value If we pass third parameter in Ability middleware from route or controller class. Like:

Route::get('posts', 'PostController@index')->middleware("ability:super_admin,access-posts,true");

But if we use Blade Directive then it will Boolean

@ability('super_admin','access-posts,access-comments',true)

So, we should pass it as string in @Ability Blade Directive. Like:

@ability('super_admin','access-posts,access-comments',['validate_all' => 'true'])

and we need to override the Ability Method. Put below method in User.php file

public function ability($roles, $permissions, $options = [])
{
    
    // Convert string to array if that's what is passed in.
    if (!is_array($roles)) {
        $roles = explode(',', $roles);
    }
    if (!is_array($permissions)) {
        $permissions = explode(',', $permissions);
    }

    // Set up default values and validate options.
    $validateAll = (isset($options['validate_all']) && $options['validate_all'] === 'true') ? true : false;

    if ($validateAll !== true && $validateAll !== false) {
        throw new InvalidArgumentException();
    }

    if (!isset($options['return_type'])) {
        $options['return_type'] = 'boolean';
    } else {
        if ($options['return_type'] != 'boolean' &&
            $options['return_type'] != 'array' &&
            $options['return_type'] != 'both') {
            throw new InvalidArgumentException();
        }
    }

    // Loop through roles and permissions and check each.
    $checkedRoles = [];
    $checkedPermissions = [];
    foreach ($roles as $role) {
        $checkedRoles[$role] = $this->hasRole($role);
    }
    foreach ($permissions as $permission) {
        $checkedPermissions[$permission] = $this->can($permission);
    }

    // If validate all and there is a false in either
    // Check that if validate all, then there should not be any false.
    // Check that if not validate all, there must be at least one true.
    if(($validateAll && (in_array(true,$checkedRoles) && in_array(true,$checkedPermissions))) ||
        (!$validateAll && (in_array(true,$checkedRoles) || in_array(true,$checkedPermissions)))) {
        $validateAll = true;
    } else {
        $validateAll = false;
    }
    
    // Return based on option
    if ($options['return_type'] == 'boolean') {
        return $validateAll;
    } elseif ($options['return_type'] == 'array') {
        return ['roles' => $checkedRoles, 'permissions' => $checkedPermissions];
    } else {
        return [$validateAll, ['roles' => $checkedRoles, 'permissions' => $checkedPermissions]];
    }

}