mirror of
https://github.com/flarum/framework.git
synced 2025-03-03 22:51:55 +08:00
User Extender (prepareGroups functionality) (#2110)
This commit is contained in:
parent
b89ccaf83c
commit
c10ebea00c
@ -12,6 +12,7 @@ namespace Flarum\Event;
|
||||
use Flarum\User\User;
|
||||
|
||||
/**
|
||||
* @deprecated beta 13, remove in beta 14. Use the User extender instead.
|
||||
* The `PrepareUserGroups` event.
|
||||
*/
|
||||
class PrepareUserGroups
|
||||
|
@ -15,9 +15,10 @@ use Illuminate\Contracts\Container\Container;
|
||||
class User implements ExtenderInterface
|
||||
{
|
||||
private $displayNameDrivers = [];
|
||||
private $groupProcessors = [];
|
||||
|
||||
/**
|
||||
* Add a mail driver.
|
||||
* Add a display name driver.
|
||||
*
|
||||
* @param string $identifier Identifier for display name driver. E.g. 'username' for UserNameDriver
|
||||
* @param string $driver ::class attribute of driver class, which must implement Flarum\User\DisplayName\DriverInterface
|
||||
@ -29,10 +30,35 @@ class User implements ExtenderInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically process a user's list of groups when calculating permissions.
|
||||
* This can be used to give a user permissions for groups they aren't actually in, based on context.
|
||||
* It will not change the group badges displayed for the user.
|
||||
*
|
||||
* @param callable $callable
|
||||
*
|
||||
* The callable can be a closure or invokable class, and should accept:
|
||||
* - \Flarum\User\User $user: the user in question.
|
||||
* - array $groupIds: an array of ids for the groups the user belongs to.
|
||||
*
|
||||
* The callable should return:
|
||||
* - array $groupIds: an array of ids for the groups the user belongs to.
|
||||
*/
|
||||
public function permissionGroups(callable $callable)
|
||||
{
|
||||
$this->groupProcessors[] = $callable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function extend(Container $container, Extension $extension = null)
|
||||
{
|
||||
$container->extend('flarum.user.display_name.supported_drivers', function ($existingDrivers) {
|
||||
return array_merge($existingDrivers, $this->displayNameDrivers);
|
||||
});
|
||||
|
||||
$container->extend('flarum.user.group_processors', function ($existingRelations) {
|
||||
return array_merge($existingRelations, $this->groupProcessors);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,12 @@ class User extends AbstractModel
|
||||
*/
|
||||
protected $session;
|
||||
|
||||
/**
|
||||
* An array of callables, through each of which the user's list of groups is passed
|
||||
* before being returned.
|
||||
*/
|
||||
protected static $groupProcessors = [];
|
||||
|
||||
/**
|
||||
* An array of registered user preferences. Each preference is defined with
|
||||
* a key, and its value is an array containing the following keys:.
|
||||
@ -660,8 +666,13 @@ class User extends AbstractModel
|
||||
$groupIds = array_merge($groupIds, [Group::MEMBER_ID], $this->groups->pluck('id')->all());
|
||||
}
|
||||
|
||||
// Deprecated, remove in beta 14.
|
||||
event(new PrepareUserGroups($this, $groupIds));
|
||||
|
||||
foreach (static::$groupProcessors as $processor) {
|
||||
$groupIds = $processor($this, $groupIds);
|
||||
}
|
||||
|
||||
return Permission::whereIn('group_id', $groupIds);
|
||||
}
|
||||
|
||||
@ -751,6 +762,17 @@ class User extends AbstractModel
|
||||
static::$preferences[$key] = compact('transformer', 'default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that processes a user's list of groups.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return array $groupIds
|
||||
*/
|
||||
public static function addGroupProcessor($callback)
|
||||
{
|
||||
static::$groupProcessors[] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key for a preference which flags whether or not the user will
|
||||
* receive a notification for $type via $method.
|
||||
|
@ -31,6 +31,10 @@ class UserServiceProvider extends AbstractServiceProvider
|
||||
{
|
||||
$this->registerAvatarsFilesystem();
|
||||
$this->registerDisplayNameDrivers();
|
||||
|
||||
$this->app->singleton('flarum.user.group_processors', function () {
|
||||
return [];
|
||||
});
|
||||
}
|
||||
|
||||
protected function registerDisplayNameDrivers()
|
||||
@ -72,6 +76,14 @@ class UserServiceProvider extends AbstractServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
foreach ($this->app->make('flarum.user.group_processors') as $callback) {
|
||||
if (is_string($callback)) {
|
||||
$callback = $this->app->make($callback);
|
||||
}
|
||||
|
||||
User::addGroupProcessor($callback);
|
||||
}
|
||||
|
||||
User::setHasher($this->app->make('hash'));
|
||||
User::setGate($this->app->make(Gate::class));
|
||||
User::setDisplayNameDriver($this->app->make('flarum.user.display_name.driver'));
|
||||
|
@ -24,7 +24,9 @@ class UserTest extends TestCase
|
||||
$this->prepareDatabase([
|
||||
'users' => [
|
||||
$this->adminUser(),
|
||||
], 'settings' => [
|
||||
$this->normalUser(),
|
||||
],
|
||||
'settings' => [
|
||||
['key' => 'display_name_driver', 'value' => 'custom'],
|
||||
],
|
||||
]);
|
||||
@ -58,6 +60,34 @@ class UserTest extends TestCase
|
||||
|
||||
$this->assertEquals('admin@machine.local$$$suffix', $user->displayName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function user_has_permissions_for_expected_groups_if_no_processors_added()
|
||||
{
|
||||
$this->prepDb();
|
||||
$user = User::find(2);
|
||||
|
||||
$this->assertContains('viewUserList', $user->getPermissions());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function processor_can_restrict_user_groups()
|
||||
{
|
||||
$this->extend((new Extend\User)->permissionGroups(function (User $user, array $groupIds) {
|
||||
return array_filter($groupIds, function ($id) {
|
||||
return $id != 3;
|
||||
});
|
||||
}));
|
||||
|
||||
$this->prepDb();
|
||||
$user = User::find(2);
|
||||
|
||||
$this->assertNotContains('viewUserList', $user->getPermissions());
|
||||
}
|
||||
}
|
||||
|
||||
class CustomDisplayNameDriver implements DriverInterface
|
||||
|
Loading…
x
Reference in New Issue
Block a user