mirror of
https://github.com/flarum/core.git
synced 2025-10-12 23:44:27 +02:00
Fix permission logic priorities
This helps to fix a bug in flarum-ext-tags where a user could not rename or edit the tags of their own discussion if it was in a restricted tag. This was due to the order of GetPermission event listeners – the logic that determines that a user *can't* perform an action because of a restrictive tag was running before (and thus instead of) the logic that determines that a user *can* edit their own stuff. The solution is to change the "catch-all" methods on Policies to "after" instead of "before" – that is, they will run only if the per-ability methods return null. We also simplify the GetPermission event by passing the model as a sole "argument", as I can't imagine any cases where we'll need more than one argument.
This commit is contained in:
@@ -29,19 +29,12 @@ class PostPolicy extends AbstractPolicy
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @var Gate
|
||||
*/
|
||||
protected $gate;
|
||||
|
||||
/**
|
||||
* @param SettingsRepositoryInterface $settings
|
||||
* @param Gate $gate
|
||||
*/
|
||||
public function __construct(SettingsRepositoryInterface $settings, Gate $gate)
|
||||
public function __construct(SettingsRepositoryInterface $settings)
|
||||
{
|
||||
$this->settings = $settings;
|
||||
$this->gate = $gate;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,9 +53,9 @@ class PostPolicy extends AbstractPolicy
|
||||
* @param Post $post
|
||||
* @return bool|null
|
||||
*/
|
||||
public function before(User $actor, $ability, Post $post)
|
||||
public function after(User $actor, $ability, Post $post)
|
||||
{
|
||||
if ($this->discussionAllows($actor, $ability, $post)) {
|
||||
if ($actor->can($ability.'Posts', $post->discussion)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -75,7 +68,7 @@ class PostPolicy extends AbstractPolicy
|
||||
// When fetching a discussion's posts: if the user doesn't have permission
|
||||
// to moderate the discussion, then they can't see posts that have been
|
||||
// hidden by someone other than themself.
|
||||
if ($this->gate->forUser($event->actor)->denies('editPosts', $event->discussion)) {
|
||||
if ($event->actor->cannot('editPosts', $event->discussion)) {
|
||||
$event->query->where(function ($query) use ($event) {
|
||||
$query->whereNull('hide_time')
|
||||
->orWhere('user_id', $event->actor->id);
|
||||
@@ -90,10 +83,6 @@ class PostPolicy extends AbstractPolicy
|
||||
*/
|
||||
public function edit(User $actor, Post $post)
|
||||
{
|
||||
if ($this->discussionAllows($actor, 'edit', $post)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// A post is allowed to be edited if the user has permission to moderate
|
||||
// the discussion which it's in, or if they are the author and the post
|
||||
// hasn't been deleted by someone else.
|
||||
@@ -107,15 +96,4 @@ class PostPolicy extends AbstractPolicy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param string $ability
|
||||
* @param Post $post
|
||||
* @return bool
|
||||
*/
|
||||
protected function discussionAllows(User $actor, $ability, Post $post)
|
||||
{
|
||||
return $this->gate->forUser($actor)->allows($ability.'Posts', $post->discussion);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user