Hello,
I'm working on my authorisation system and followed the videos from "what's new in Laravel 5.2".
In the Post Policy update method, I would like to check first if the user has the Permission to edit the forum in general like a site manager would be able to even if he didn't write the post.
Then, I would check if the user is the one who has created the post.
This code below doesn't work but cannot figure out what I'm doing wrong.
I think the issue may come from the hasRole method in my user model on the following line:
return !! $role->intersect($this->roles)->count();
Here is the full code:
Policy:
public function update(User $user, Post $post)
{
if ($user->can('edit_forum', $post)) {
return true;
}
return $user->id === $post->user_id;
}
Role Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
public function givePermissionTo(Permission $permission)
{
return $this->permissions()->save($permission);
}
}
Permission Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Permission extends Model
{
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
User Model
use Illuminate\Foundation\Auth\User as Authenticatable;
use App;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'firstName', 'lastName', 'email', 'photo_path', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function assignRole($role)
{
if(is_string($role))
{
return $this->roles()->save($role);
}
return $this->roles()->save(
Role::whereName($role)->first()
);
}
public function hasRole($role)
{
if(is_string($role))
{
return $this->roles->contains('name', $role);
}
return !! $role->intersect($this->roles)->count();
}
}
AuthServiceProvider
namespace App\Providers;
use App;
use App\Permission;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
App\Post::class => App\Policies\PostPolicy::class,
];
/**
* Register any application authentication / authorization services.
*
* @param \Illuminate\Contracts\Auth\Access\Gate $gate
* @return void
*/
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
foreach ($this->getPermissions() as $permission)
{
$gate->define($permission->name, function($user) use ($permission)
{
return $user->hasRole($permission->roles);
});
}
}
protected function getPermissions()
{
return Permission::with('roles')->get();
}
}