Search code examples
phplaravelauthorizationlaravel-7scopes

Gracefully exiting Laravel scopes


I have a scope which is acting in a limiting fashion depending on a user role in a way that you can forward a set of rules to the scope limiting the final output from the DB.

A really simplified role limit example:

{
    "first_name": "=foo%"
}

will only return records whose first_name begins with foo%, which effectively means that I have forbidden the user with that role to see any records which do not begin with foo%.

The issue with this approach is that if someone has no limits imposed, he will see everything. I am aware that this is a valid assumption, but I would like to forbid everything if there are no limits imposed, so that if new role is created, it has no rights whatsoever.

Currently I am throwing an exception for this case:

public function apply(Builder $builder, Model $model)
{
    $input = $this->getAuthValues(get_class($model));

    if (count($input) < 1) {
        throw new \Exception('No rights for you');
    }

    $jsonQuery = new JsonQuery($builder, $input); <-- class responsible for assembling the queries based on the input
    $jsonQuery->search();
}

But this of course is no exception. I would like empty array to be returned in that case.

Can I use some method to gracefully exit the scope together with an empty result, without actually executing the query afterwards?


Solution

  • I came to a solution to make an impossible query which would return 0 results.

    public function apply(Builder $builder, Model $model)
    {
        $input = $this->getAuthValues(get_class($model));
    
        if (count($input) < 1) {
            $builder->whereRaw('1 = 0');
            return;
        }
    
        $jsonQuery = new JsonQuery($builder, $input);
        $jsonQuery->search();
    }