3

we are developing an application based on Laravel Spark. as part of this we want to tie resources to a specfic team.

I know that we can add a global scope such as:

<?php


namespace App\Scopes;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class TeamScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        $builder->where('team_id', '=',Auth()->user()->currentTeam->id );
    }
}

but according to the docs we have to add that to each model that we want to restrict like so:

protected static function boot()
{
    parent::boot();
    static::addGlobalScope(new TeamScope);
}

my issue with this is that it will be possible to create future models and forget to apply this code. Which could give us a security hole?

is there any way to enforce the scope across the board?

JaChNo
  • 1,493
  • 9
  • 28
  • 56

3 Answers3

1

I am not sure if there's a way to globally add the Scope.

In my particular application, we have had to add more responsiblities to our Models. So we created a BaseModel class that extends Laravel's Illuminate\Database\Eloquent\Model.

All new Models then extends the BaseModel instead of Laravel's one.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class BaseModel extends Model
{
    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope(new TeamScope);
    }

}

For example:

<?php

namespace App;

class Attribute extends BaseModel
{

}

You could also have a trait that you can just use to add this scope to your Model. For example:

trait HasTeamScope
{
    protected static function boot()
        {
            parent::boot();
            static::addGlobalScope(new TeamScope);
        }
    }
}

... and then you can easily re-use that in your Model.

For example:

<?php

namespace App;

class Attribute extends BaseModel
{
    use HasTeamScope;
}

Now, based on your question, you might also forget to extend the BaseModel in the first instance or add the Trait in the second one whenever you create a new model.

To solve this, you could easily create a new command to produce models that will use your own stub (which extends the BaseModel or adds the trait whenever you create a new model)

Mozammil
  • 8,520
  • 15
  • 29
  • yeah I had considered those two options. I guess i was hoping for the magic bullet that would make it something that could not be forgotted. We have added a command for now to generate the models. Thanks – JaChNo Jan 29 '19 at 14:11
0

You could create your own base model with the desired global scope that future models would extend.

0

You should create trait with boot function. Trait named BelongsToTeam.

And in all models add only: use BelongsToTeam;

fsmdev
  • 11
  • 1
  • This still has the same issue, if someone forgets to add the trait then that model can be access across teams – JaChNo Jan 29 '19 at 14:07