fix: only allow no one if configured, fallback to admin otherwise

This commit is contained in:
Daniël Klabbers 2023-03-26 22:07:08 +02:00
parent 7dcbbf29ab
commit 3c82a887a8
6 changed files with 64 additions and 17 deletions

View File

@ -48,16 +48,16 @@ export default class PermissionDropdown<CustomAttrs extends IPermissionDropdownA
view(vnode: Mithril.Vnode<CustomAttrs, this>) {
const children = [];
let groupIds = app.data.permissions[this.attrs.permission] || [Group.NO_ONE_ID];
let groupIds = app.data.permissions[this.attrs.permission] || [];
groupIds = filterByRequiredPermissions(groupIds, this.attrs.permission);
const no_one = groupIds.includes(Group.NO_ONE_ID);
const no_one = groupIds.length === 0;
const everyone = groupIds.includes(Group.GUEST_ID);
const members = groupIds.includes(Group.MEMBER_ID);
const adminGroup = app.store.getById<Group>('groups', Group.ADMINISTRATOR_ID)!;
if (no_one) {
if (this.attrs.allowNoOne && no_one) {
this.attrs.label = Badge.component({ icon: 'fas fa-user-slash' });
} else if (everyone) {
this.attrs.label = Badge.component({ icon: 'fas fa-globe' });
@ -74,7 +74,6 @@ export default class PermissionDropdown<CustomAttrs extends IPermissionDropdownA
{
icon: no_one ? 'fas fa-check' : true,
onclick: () => this.save([Group.NO_ONE_ID]),
disabled: this.isGroupDisabled(Group.NO_ONE_ID),
},
[Badge.component({ icon: 'fas fa-user-slash' }), ' ', app.translator.trans('core.admin.permissions_controls.no_one_button')]
)

View File

@ -0,0 +1,22 @@
<?php
namespace Flarum\Extend;
use Flarum\Extension\Extension;
use Flarum\User\Access\AdminPolicy;
use Illuminate\Contracts\Container\Container;
class Permission implements ExtenderInterface
{
public function extend(Container $container, Extension $extension = null)
{
// TODO: Implement extend() method.
}
public function allowsNoOne(string $permission): self
{
AdminPolicy::allowNoOneOnPermission($permission);
return $this;
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace Flarum\User\Access;
use Flarum\User\User;
class AdminPolicy extends AbstractPolicy
{
static array $allowNoOnePermissions = [];
/**
* @param string|array<string> $permissions
* @return void
*/
public static function allowNoOneOnPermission($permissions)
{
self::$allowNoOnePermissions[] = array_merge(
static::$allowNoOnePermissions,
(array) $permissions
);
}
/**
* @param User $actor
* @param string $ability
* @return bool|null
*/
public function can(User $actor, $ability)
{
if (! in_array($ability, static::$allowNoOnePermissions)
&& $actor->isAdmin()) {
return $this->forceAllow();
}
}
}

View File

@ -87,11 +87,7 @@ class Gate
// If no policy covered this permission query, we will only grant
// the permission if the actor's groups have it. Otherwise, we will
// not allow the user to perform this action.
if ($actor->isAdmin() || $actor->hasPermission($ability)) {
return true;
}
return false;
return $actor->hasPermission($ability);
}
/**

View File

@ -380,9 +380,7 @@ class User extends AbstractModel
*/
public function hasPermission($permission)
{
if ($this->isAdmin()) {
return true;
}
return in_array($permission, $this->getPermissions());
}
@ -396,10 +394,6 @@ class User extends AbstractModel
*/
public function hasPermissionLike($match)
{
if ($this->isAdmin()) {
return true;
}
foreach ($this->getPermissions() as $permission) {
if (substr($permission, -strlen($match)) === $match) {
return true;

View File

@ -20,6 +20,7 @@ use Flarum\Http\AccessToken;
use Flarum\Post\Access\PostPolicy;
use Flarum\Post\Post;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\Access\AdminPolicy;
use Flarum\User\Access\ScopeUserVisibility;
use Flarum\User\DisplayName\DriverInterface;
use Flarum\User\DisplayName\UsernameDriver;
@ -49,7 +50,7 @@ class UserServiceProvider extends AbstractServiceProvider
$this->container->singleton('flarum.policies', function () {
return [
Access\AbstractPolicy::GLOBAL => [],
Access\AbstractPolicy::GLOBAL => [AdminPolicy::class],
AccessToken::class => [AccessTokenPolicy::class],
Discussion::class => [DiscussionPolicy::class],
Group::class => [GroupPolicy::class],