mirror of
https://github.com/flarum/core.git
synced 2025-10-12 07:24:27 +02:00
Overhaul permissions
Get rid of Permissible - too complex and inefficient. Replace with: - a “Locked” trait which works similarly but only evaluates logic on hydrated models. - a “VisibleScope” trait which also works similarly but only scopes queries This is all we need, Permissible is overkill. There is only one instance where we have to duplicate some logic (Discussion::scopeVisiblePosts and Post::allow(‘view’, …)) but it’s barely anything. Haven’t decoupled for now, we can definitely look at doing that later. Permissions table seeder slightly updated. Also did a bit of a query audit, there’s still a lot to be done but it’s much better than it was. Some relatively low-hanging fruit detailed in EloquentPostRepository.
This commit is contained in:
57
src/Core/Support/Locked.php
Normal file
57
src/Core/Support/Locked.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php namespace Flarum\Core\Support;
|
||||
|
||||
use Flarum\Core\Exceptions\PermissionDeniedException;
|
||||
use Flarum\Core\Models\User;
|
||||
use Closure;
|
||||
|
||||
trait Locked
|
||||
{
|
||||
protected static $conditions = [];
|
||||
|
||||
protected static function getConditions($action)
|
||||
{
|
||||
$conditions = isset(static::$conditions[$action]) ? static::$conditions[$action] : [];
|
||||
$all = isset(static::$conditions['*']) ? static::$conditions['*'] : [];
|
||||
|
||||
return array_merge($conditions, $all);
|
||||
}
|
||||
|
||||
public static function allow($action, Closure $condition)
|
||||
{
|
||||
foreach ((array) $action as $action) {
|
||||
if (! isset(static::$conditions[$action])) {
|
||||
static::$conditions[$action] = [];
|
||||
}
|
||||
|
||||
static::$conditions[$action][] = $condition;
|
||||
}
|
||||
}
|
||||
|
||||
public function can(User $user, $action)
|
||||
{
|
||||
foreach ($this->getConditions($action) as $condition) {
|
||||
$can = $condition($this, $user, $action);
|
||||
|
||||
if ($can !== null) {
|
||||
return $can;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the user has a certain permission for this model, throwing
|
||||
* an exception if they don't.
|
||||
*
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @param string $permission
|
||||
* @return void
|
||||
*
|
||||
* @throws \Flarum\Core\Exceptions\PermissionDeniedException
|
||||
*/
|
||||
public function assertCan(User $user, $action)
|
||||
{
|
||||
if (! $this->can($user, $action)) {
|
||||
throw new PermissionDeniedException;
|
||||
}
|
||||
}
|
||||
}
|
20
src/Core/Support/VisibleScope.php
Normal file
20
src/Core/Support/VisibleScope.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php namespace Flarum\Core\Support;
|
||||
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
trait VisibleScope
|
||||
{
|
||||
protected static $visibleScopes = [];
|
||||
|
||||
public static function scopeVisible($scope)
|
||||
{
|
||||
static::$visibleScopes[] = $scope;
|
||||
}
|
||||
|
||||
public function scopeWhereVisibleTo($query, User $user)
|
||||
{
|
||||
foreach (static::$visibleScopes as $scope) {
|
||||
$scope($query, $user);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user