Added various useful presets for permissions

This commit is contained in:
Jan Böhmer 2022-11-14 00:02:37 +01:00
parent 5829d42968
commit 1de88e0494
13 changed files with 369 additions and 231 deletions

View file

@ -51,6 +51,7 @@ use App\Form\AdminPages\GroupAdminForm;
use App\Services\EntityExporter;
use App\Services\EntityImporter;
use App\Services\StructuralElementRecursionHelper;
use App\Services\UserSystem\PermissionPresetsHelper;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
@ -73,8 +74,27 @@ class GroupController extends BaseAdminController
* @Route("/{id}/edit/{timestamp}", requirements={"id"="\d+"}, name="group_edit")
* @Route("/{id}/", requirements={"id"="\d+"})
*/
public function edit(Group $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
public function edit(Group $entity, Request $request, EntityManagerInterface $em, PermissionPresetsHelper $permissionPresetsHelper, ?string $timestamp = null): Response
{
//Handle permissions presets
if ($request->request->has('permission_preset')) {
$this->denyAccessUnlessGranted('edit_permissions', $entity);
if ($this->isCsrfTokenValid('group'.$entity->getId(), $request->request->get('_token'))) {
$preset = $request->request->get('permission_preset');
$permissionPresetsHelper->applyPreset($entity, $preset);
$em->flush();
$this->addFlash('success', 'user.edit.permission_success');
//We need to stop the execution here, or our permissions changes will be overwritten by the form values
return $this->redirectToRoute('group_edit', ['id' => $entity->getID()]);
} else {
$this->addFlash('danger', 'csfr_invalid');
}
}
return $this->_edit($entity, $request, $em, $timestamp);
}

View file

@ -54,6 +54,7 @@ use App\Form\UserAdminForm;
use App\Services\EntityExporter;
use App\Services\EntityImporter;
use App\Services\StructuralElementRecursionHelper;
use App\Services\UserSystem\PermissionPresetsHelper;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use InvalidArgumentException;
@ -101,7 +102,7 @@ class UserController extends AdminPages\BaseAdminController
*
* @throws Exception
*/
public function edit(User $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
public function edit(User $entity, Request $request, EntityManagerInterface $em, PermissionPresetsHelper $permissionPresetsHelper, ?string $timestamp = null): Response
{
//Handle 2FA disabling
@ -132,6 +133,25 @@ class UserController extends AdminPages\BaseAdminController
}
}
//Handle permissions presets
if ($request->request->has('permission_preset')) {
$this->denyAccessUnlessGranted('edit_permissions', $entity);
if ($this->isCsrfTokenValid('reset_2fa'.$entity->getId(), $request->request->get('_token'))) {
$preset = $request->request->get('permission_preset');
$permissionPresetsHelper->applyPreset($entity, $preset);
$em->flush();
$this->addFlash('success', 'user.edit.permission_success');
//We need to stop the execution here, or our permissions changes will be overwritten by the form values
return $this->redirectToRoute('user_edit', ['id' => $entity->getID()]);
} else {
$this->addFlash('danger', 'csfr_invalid');
}
}
return $this->_edit($entity, $request, $em, $timestamp);
}

View file

@ -88,6 +88,16 @@ final class PermissionData implements \JsonSerializable
return $this;
}
/**
* Resets the saved permissions and set all operations to inherit (which means they are not defined).
* @return $this
*/
public function resetPermissions(): self
{
$this->data = [];
return $this;
}
/**
* Creates a new Permission Data Instance using the given JSON encoded data
* @param string $json

View file

@ -64,6 +64,7 @@ class GroupAdminForm extends BaseEntityAdminForm
'mapped' => false,
'data' => $builder->getData(),
'disabled' => !$this->security->isGranted('edit_permissions', $entity),
'show_presets' => $this->security->isGranted('edit_permissions', $entity) && !$is_new,
]);
}
}

View file

@ -66,6 +66,7 @@ class PermissionsType extends AbstractType
{
$resolver->setDefaults([
'show_legend' => true,
'show_presets' => false,
'constraints' => static function (Options $options) {
if (!$options['disabled']) {
return [new NoLockout()];
@ -80,6 +81,7 @@ class PermissionsType extends AbstractType
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$view->vars['show_legend'] = $options['show_legend'];
$view->vars['show_presets'] = $options['show_presets'];
}
public function buildForm(FormBuilderInterface $builder, array $options): void

View file

@ -227,6 +227,7 @@ class UserAdminForm extends AbstractType
'mapped' => false,
'data' => $builder->getData(),
'disabled' => !$this->security->isGranted('edit_permissions', $entity),
'show_presets' => $this->security->isGranted('edit_permissions', $entity) && !$is_new,
])
;
/*->add('comment', CKEditorType::class, ['required' => false,

View file

@ -206,7 +206,7 @@ class PermissionResolver
/**
* This functions sets all operations mentioned in the alsoSet value of a permission, so that the structure is always valid.
* @param User $user
* @param HasPermissionsInterface $user
* @return void
*/
public function ensureCorrectSetOperations(HasPermissionsInterface $user): void
@ -261,6 +261,26 @@ class PermissionResolver
}
}
/**
* Sets all operations of the given permissions to the given value.
* Please note that you have to call ensureCorrectSetOperations() after this function, to ensure that all alsoSet values are set.
*
* @param HasPermissionsInterface $perm_holder
* @param string $permission
* @param bool|null $new_value
* @return void
*/
public function setAllOperationsOfPermission(HasPermissionsInterface $perm_holder, string $permission, ?bool $new_value): void
{
if (!$this->isValidPermission($permission)) {
throw new InvalidArgumentException(sprintf('A permission with that name is not existing! Got %s.', $permission));
}
foreach ($this->permission_structure['perms'][$permission]['operations'] as $op_key => $op) {
$this->setPermission($perm_holder, $permission, $op_key, $new_value);
}
}
protected function generatePermissionStructure()
{
$cache = new ConfigCache($this->cache_file, $this->is_debug);

View file

@ -0,0 +1,143 @@
<?php
namespace App\Services\UserSystem;
use App\Entity\UserSystem\PermissionData;
use App\Entity\UserSystem\User;
use App\Security\Interfaces\HasPermissionsInterface;
use App\Services\PermissionResolver;
class PermissionPresetsHelper
{
private PermissionResolver $permissionResolver;
public function __construct(PermissionResolver $permissionResolver)
{
$this->permissionResolver = $permissionResolver;
}
/**
* Apply the given preset to the permission holding entity (like a user)
* The permission data will be reset during the process and then the preset will be applied.
*
* @param
* @param string $preset_name The name of the preset to use
* @return PermissionData
*/
public function applyPreset(HasPermissionsInterface $perm_holder, string $preset_name): HasPermissionsInterface
{
//We need to reset the permission data first (afterwards all values are inherit)
$perm_holder->getPermissions()->resetPermissions();
switch($preset_name) {
case 'all_inherit':
//Do nothing, all values are inherit after reset
break;
case 'all_forbid':
$this->allForbid($perm_holder);
break;
case 'all_allow':
$this->allAllow($perm_holder);
break;
case 'read_only':
$this->readOnly($perm_holder);
break;
case 'editor':
$this->editor($perm_holder);
break;
case 'admin':
$this->admin($perm_holder);
break;
default:
throw new \InvalidArgumentException('Unknown permission preset name: '.$preset_name);
}
//Ensure that permissions are valid (alsoSet values are set), this allows us to use the permission inheritance system to keep the presets short
$this->permissionResolver->ensureCorrectSetOperations($perm_holder);
return $perm_holder;
}
private function admin(HasPermissionsInterface $perm_holder): void
{
//Apply everything from editor permission
$this->editor($perm_holder);
//Allow user and group access
$this->permissionResolver->setAllOperationsOfPermission($perm_holder, 'users', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($perm_holder, 'groups', PermissionData::ALLOW);
//Allow access to system log and server infos
$this->permissionResolver->setPermission($perm_holder, 'system', 'show_logs', PermissionData::ALLOW);
$this->permissionResolver->setPermission($perm_holder, 'system', 'server_infos', PermissionData::ALLOW);
}
private function editor(HasPermissionsInterface $permHolder): HasPermissionsInterface
{
//Apply everything from read-only
$this->readOnly($permHolder);
//Set datastructures
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'parts', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'categories', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'storelocations', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'footprints', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'manufacturers', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'attachment_types', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'currencies', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'measurement_units', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'suppliers', PermissionData::ALLOW);
//Attachments permissions
$this->permissionResolver->setPermission($permHolder, 'attachments', 'show_private', PermissionData::ALLOW);
//Labels permissions (allow all except use twig)
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'labels', PermissionData::ALLOW);
$this->permissionResolver->setPermission($permHolder,'labels', 'use_twig', PermissionData::INHERIT);
//Self permissions
$this->permissionResolver->setPermission($permHolder, 'self', 'edit_infos', PermissionData::ALLOW);
//Various other permissions
$this->permissionResolver->setPermission($permHolder, 'tools', 'lastActivity', PermissionData::ALLOW);
return $permHolder;
}
private function readOnly(HasPermissionsInterface $perm_holder): HasPermissionsInterface
{
//It is sufficient to only set the read operation to allow, read operations for datastructures are inherited
$this->permissionResolver->setPermission($perm_holder, 'parts', 'read', PermissionData::ALLOW);
//Set tools permissions
$this->permissionResolver->setPermission($perm_holder, 'tools', 'statistics', PermissionData::ALLOW);
$this->permissionResolver->setPermission($perm_holder, 'tools', 'label_scanner', PermissionData::ALLOW);
$this->permissionResolver->setPermission($perm_holder, 'tools', 'reel_calculator', PermissionData::ALLOW);
//Set attachments permissions
$this->permissionResolver->setPermission($perm_holder, 'attachments', 'list_attachments', PermissionData::ALLOW);
//Set user (self) permissions
$this->permissionResolver->setPermission($perm_holder, 'self', 'show_permissions', PermissionData::ALLOW);
//Label permissions
$this->permissionResolver->setPermission($perm_holder, 'labels', 'create_labels', PermissionData::ALLOW);
$this->permissionResolver->setPermission($perm_holder, 'labels', 'edit_options', PermissionData::ALLOW);
return $perm_holder;
}
private function AllForbid(HasPermissionsInterface $perm_holder): HasPermissionsInterface
{
$this->permissionResolver->setAllPermissions($perm_holder, PermissionData::DISALLOW);
return $perm_holder;
}
private function AllAllow(HasPermissionsInterface $perm_holder): HasPermissionsInterface
{
$this->permissionResolver->setAllPermissions($perm_holder, PermissionData::ALLOW);
return $perm_holder;
}
}

View file

@ -12,6 +12,7 @@
{% block additional_panes %}
<div class="tab-pane" id="tab_permissions">
<input type="hidden" name="_token" value="{{ csrf_token('group' ~ entity.id) }}">
{{ form_row(form.permissions) }}
</div>
{% endblock %}

View file

@ -48,8 +48,9 @@
{% block permissions_row %}
{{ form_errors(form) }}
<div class="row mb-2">
{% if show_legend %}
<div class="mb-2">
<div class="col">
<label><b>{% trans %}permission.legend.title{% endtrans %}:</b></label>
<div>
<div class="form-check form-check-inline">
@ -66,9 +67,28 @@
</div>
</div>
</div>
{% endif %}
{% if show_presets %}
<div class="col text-end">
<div class="btn-group">
<button type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
{% trans %}permission.preset.button{% endtrans %}
</button>
<ul class="dropdown-menu">
<li><button type="submit" name="permission_preset" value="read_only" class="dropdown-item" >{% trans %}permission.preset.read_only{% endtrans%} <br><small class="text-muted">{% trans %}permission.preset.read_only.desc{% endtrans%}</small></button></li>
<li><button type="submit" name="permission_preset" value="editor" class="dropdown-item" >{% trans %}permission.preset.editor{% endtrans%} <br><small class="text-muted">{% trans %}permission.preset.editor.desc{% endtrans%}</small></button></li>
<li><button type="submit" name="permission_preset" value="admin" class="dropdown-item" >{% trans %}permission.preset.admin{% endtrans%} <br><small class="text-muted">{% trans %}permission.preset.admin.desc{% endtrans%}</small></button></li>
<li><hr class="dropdown-divider"></li>
<li><button type="submit" name="permission_preset" value="all_inherit" class="dropdown-item" >{% trans %}permission.preset.all_inherit{% endtrans%}<br><small class="text-muted">{% trans %}permission.preset.all_inherit.desc{% endtrans%}</small></button></li>
<li><button type="submit" name="permission_preset" value="all_forbid" class="dropdown-item" >{% trans %}permission.preset.all_forbid{% endtrans%}<br><small class="text-muted">{% trans %}permission.preset.all_forbid.desc{% endtrans%}</small></button></li>
<li><button type="submit" name="permission_preset" value="all_allow" class="dropdown-item" >{% trans %}permission.preset.all_allow{% endtrans%}<br><small class="text-muted">{% trans %}permission.preset.all_allow.desc{% endtrans%}</small></button></li>
</ul>
</div>
</div>
{% endif %}
</div>
<ul class="nav nav-tabs">
{% for group in form %}
<li class="nav-item">

View file

@ -101,4 +101,31 @@ class PermissionDataTest extends TestCase
$this->assertTrue($perm_data->getPermissionValue('perm1', 'op1'));
$this->assertFalse($perm_data->getPermissionValue('perm2', 'op2'));
}
public function testResetPermissions()
{
$data = new PermissionData();
$data->setPermissionValue('perm1', 'op1', PermissionData::ALLOW);
$data->setPermissionValue('perm1', 'op2', PermissionData::DISALLOW);
$data->setPermissionValue('perm1', 'op3', PermissionData::INHERIT);
//Ensure that values were set correctly
$this->assertTrue($data->isPermissionSet('perm1', 'op1'));
$this->assertTrue($data->isPermissionSet('perm1', 'op2'));
$this->assertFalse($data->isPermissionSet('perm1', 'op3'));
//Reset the permissions
$data->resetPermissions();
//Afterwards all values must be set to inherit (null)
$this->assertNull($data->getPermissionValue('perm1', 'op1'));
$this->assertNull($data->getPermissionValue('perm1', 'op2'));
$this->assertNull($data->getPermissionValue('perm1', 'op3'));
//And be undefined
$this->assertFalse($data->isPermissionSet('perm1', 'op1'));
$this->assertFalse($data->isPermissionSet('perm1', 'op2'));
$this->assertFalse($data->isPermissionSet('perm1', 'op3'));
}
}

View file

@ -1,211 +0,0 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
namespace App\Tests\Entity\UserSystem;
use App\Entity\UserSystem\PermissionsEmbed;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
class PermissionsEmbedTest extends TestCase
{
public function testGetPermissionValue(): void
{
$embed = new PermissionsEmbed();
//For newly created embedded, all things should be set to inherit => null
//Test both normal name and constants
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::CONFIG, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::ATTACHMENT_TYPES, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::CATEGORIES, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::DATABASE, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::DEVICE_PARTS, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::DEVICES, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::FOOTRPINTS, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::GROUPS, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::DATABASE, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::LABELS, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::MANUFACTURERS, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS_ATTACHMENTS, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS_COMMENT, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS_DESCRIPTION, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS_FOOTPRINT, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS_MANUFACTURER, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS_MINAMOUNT, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS_NAME, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS_ORDER, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS_ORDERDETAILS, 0));
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::USERS, 0));
//Set a value for testing to the part property
$reflection = new ReflectionClass($embed);
$property = $reflection->getProperty('parts');
$property->setAccessible(true);
$property->setValue($embed, 0b11011000); // 11 01 10 00
//Test if function is working correctly
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS, 0));
$this->assertFalse($embed->getPermissionValue(PermissionsEmbed::PARTS, 2));
$this->assertTrue($embed->getPermissionValue(PermissionsEmbed::PARTS, 4));
// 11 is reserved, but it should be also treat as INHERIT.
$this->assertNull($embed->getPermissionValue(PermissionsEmbed::PARTS, 6));
}
public function testGetBitValue(): void
{
$embed = new PermissionsEmbed();
//Set a value for testing to the part property
$reflection = new ReflectionClass($embed);
$property = $reflection->getProperty('parts');
$property->setAccessible(true);
$property->setValue($embed, 0b11011000); // 11 01 10 00
//Test if function is working correctly
$this->assertSame(PermissionsEmbed::INHERIT, $embed->getBitValue(PermissionsEmbed::PARTS, 0));
$this->assertSame(PermissionsEmbed::DISALLOW, $embed->getBitValue(PermissionsEmbed::PARTS, 2));
$this->assertSame(PermissionsEmbed::ALLOW, $embed->getBitValue(PermissionsEmbed::PARTS, 4));
// 11 is reserved, but it should be also treat as INHERIT.
$this->assertSame(0b11, $embed->getBitValue(PermissionsEmbed::PARTS, 6));
}
public function testInvalidPermissionName(): void
{
$embed = new PermissionsEmbed();
//When encoutering an unknown permission name the class must throw an exception
$this->expectException(InvalidArgumentException::class);
$embed->getPermissionValue('invalid', 0);
}
public function testInvalidBit1(): void
{
$embed = new PermissionsEmbed();
//When encoutering an negative bit the class must throw an exception
$this->expectException(InvalidArgumentException::class);
$embed->getPermissionValue('parts', -1);
}
public function testInvalidBit2(): void
{
$embed = new PermissionsEmbed();
//When encoutering an odd bit number it must throw an error.
$this->expectException(InvalidArgumentException::class);
$embed->getPermissionValue('parts', 1);
}
public function getStatesBINARY(): array
{
return [
'ALLOW' => [PermissionsEmbed::ALLOW],
'DISALLOW' => [PermissionsEmbed::DISALLOW],
'INHERIT' => [PermissionsEmbed::INHERIT],
'0b11' => [0b11],
];
}
public function getStatesBOOL(): array
{
return [
'ALLOW' => [true],
'DISALLOW' => [false],
'INHERIT' => [null],
'0b11' => [null],
];
}
/**
* @dataProvider getStatesBINARY
*/
public function testTestsetBitValue($value): void
{
$embed = new PermissionsEmbed();
//Check if it returns itself, for chaining.
$this->assertSame($embed, $embed->setBitValue(PermissionsEmbed::PARTS, 0, $value));
$this->assertSame($value, $embed->getBitValue(PermissionsEmbed::PARTS, 0));
}
/**
* @dataProvider getStatesBOOL
*/
public function testSetPermissionValue($value): void
{
$embed = new PermissionsEmbed();
//Check if it returns itself, for chaining.
$this->assertSame($embed, $embed->setPermissionValue(PermissionsEmbed::PARTS, 0, $value));
$this->assertSame($value, $embed->getPermissionValue(PermissionsEmbed::PARTS, 0));
}
public function testSetRawPermissionValue(): void
{
$embed = new PermissionsEmbed();
$embed->setRawPermissionValue(PermissionsEmbed::PARTS, 10);
$this->assertSame(10, $embed->getRawPermissionValue(PermissionsEmbed::PARTS));
}
public function testSetRawPermissionValues(): void
{
$embed = new PermissionsEmbed();
$embed->setRawPermissionValues([
PermissionsEmbed::PARTS => 0,
PermissionsEmbed::USERS => 100,
PermissionsEmbed::CATEGORIES => 1304,
]);
$this->assertSame(0, $embed->getRawPermissionValue(PermissionsEmbed::PARTS));
$this->assertSame(100, $embed->getRawPermissionValue(PermissionsEmbed::USERS));
$this->assertSame(1304, $embed->getRawPermissionValue(PermissionsEmbed::CATEGORIES));
//Test second method to pass perm names and values
$embed->setRawPermissionValues(
[PermissionsEmbed::PARTS, PermissionsEmbed::USERS, PermissionsEmbed::CATEGORIES],
[0, 100, 1304]
);
$this->assertSame(0, $embed->getRawPermissionValue(PermissionsEmbed::PARTS));
$this->assertSame(100, $embed->getRawPermissionValue(PermissionsEmbed::USERS));
$this->assertSame(1304, $embed->getRawPermissionValue(PermissionsEmbed::CATEGORIES));
}
}

View file

@ -9779,5 +9779,89 @@ Element 3</target>
<target>Server Infos</target>
</segment>
</unit>
<unit id="NvclBUL" name="permission.preset.read_only">
<segment>
<source>permission.preset.read_only</source>
<target>Read-Only</target>
</segment>
</unit>
<unit id="HD3j3BW" name="permission.preset.read_only.desc">
<segment>
<source>permission.preset.read_only.desc</source>
<target>Only allow read operations on data</target>
</segment>
</unit>
<unit id="Ge20aJg" name="permission.preset.all_inherit">
<segment>
<source>permission.preset.all_inherit</source>
<target>Inherit all</target>
</segment>
</unit>
<unit id="DJpsLcr" name="permission.preset.all_inherit.desc">
<segment>
<source>permission.preset.all_inherit.desc</source>
<target>Set all permissions to Inherit</target>
</segment>
</unit>
<unit id="lzjvvzm" name="permission.preset.all_forbid">
<segment>
<source>permission.preset.all_forbid</source>
<target>Forbid all</target>
</segment>
</unit>
<unit id="QqQDTyH" name="permission.preset.all_forbid.desc">
<segment>
<source>permission.preset.all_forbid.desc</source>
<target>Set all permissions to Forbid</target>
</segment>
</unit>
<unit id="DV2fh6l" name="permission.preset.all_allow">
<segment>
<source>permission.preset.all_allow</source>
<target>Allow all</target>
</segment>
</unit>
<unit id="_m.Pbza" name="permission.preset.all_allow.desc">
<segment>
<source>permission.preset.all_allow.desc</source>
<target>Set all permissions to allow</target>
</segment>
</unit>
<unit id="VIDdo5K" name="perm.server_infos">
<segment>
<source>perm.server_infos</source>
<target>Server infos</target>
</segment>
</unit>
<unit id="d6SOlzR" name="permission.preset.editor">
<segment>
<source>permission.preset.editor</source>
<target>Editor</target>
</segment>
</unit>
<unit id="8KYl_wh" name="permission.preset.editor.desc">
<segment>
<source>permission.preset.editor.desc</source>
<target>Allow to change parts and data structures</target>
</segment>
</unit>
<unit id="dYudjp." name="permission.preset.admin">
<segment>
<source>permission.preset.admin</source>
<target>Admin</target>
</segment>
</unit>
<unit id="0o2M0uj" name="permission.preset.admin.desc">
<segment>
<source>permission.preset.admin.desc</source>
<target>Allow administrative actions</target>
</segment>
</unit>
<unit id="SnAIVQf" name="permission.preset.button">
<segment>
<source>permission.preset.button</source>
<target>Permission applied successfully. Check if the new permissions fit your needs.</target>
</segment>
</unit>
</file>
</xliff>