diff --git a/config/permissions.yaml b/config/permissions.yaml
index c7eefd4b..8c96a3a8 100644
--- a/config/permissions.yaml
+++ b/config/permissions.yaml
@@ -27,7 +27,7 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
'currencies.read', 'attachment_types.read', 'measurement_units.read']
edit:
label: "perm.edit"
- alsoSet: ['read', 'parts_stock.withdraw', 'parts_stock.add', 'parts_stock.move']
+ alsoSet: ['read'] #['read', 'parts_stock.withdraw', 'parts_stock.add', 'parts_stock.move']
create:
label: "perm.create"
alsoSet: ['read', 'edit']
diff --git a/src/Controller/GroupController.php b/src/Controller/GroupController.php
index 69099dbd..63d32c7b 100644
--- a/src/Controller/GroupController.php
+++ b/src/Controller/GroupController.php
@@ -32,6 +32,7 @@ use App\Services\ImportExportSystem\EntityExporter;
use App\Services\ImportExportSystem\EntityImporter;
use App\Services\Trees\StructuralElementRecursionHelper;
use App\Services\UserSystem\PermissionPresetsHelper;
+use App\Services\UserSystem\PermissionSchemaUpdater;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -54,8 +55,11 @@ 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, PermissionPresetsHelper $permissionPresetsHelper, ?string $timestamp = null): Response
+ public function edit(Group $entity, Request $request, EntityManagerInterface $em, PermissionPresetsHelper $permissionPresetsHelper, PermissionSchemaUpdater $permissionSchemaUpdater, ?string $timestamp = null): Response
{
+ //Do an upgrade of the permission schema if needed (so the user can see the permissions a user get on next request (even if it was not done yet)
+ $permissionSchemaUpdater->groupUpgradeSchemaRecursively($entity);
+
//Handle permissions presets
if ($request->request->has('permission_preset')) {
$this->denyAccessUnlessGranted('edit_permissions', $entity);
diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php
index c72ea7fe..826510b5 100644
--- a/src/Controller/UserController.php
+++ b/src/Controller/UserController.php
@@ -35,6 +35,7 @@ use App\Services\ImportExportSystem\EntityExporter;
use App\Services\ImportExportSystem\EntityImporter;
use App\Services\Trees\StructuralElementRecursionHelper;
use App\Services\UserSystem\PermissionPresetsHelper;
+use App\Services\UserSystem\PermissionSchemaUpdater;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use InvalidArgumentException;
@@ -82,10 +83,12 @@ class UserController extends AdminPages\BaseAdminController
*
* @throws Exception
*/
- public function edit(User $entity, Request $request, EntityManagerInterface $em, PermissionPresetsHelper $permissionPresetsHelper, ?string $timestamp = null): Response
+ public function edit(User $entity, Request $request, EntityManagerInterface $em, PermissionPresetsHelper $permissionPresetsHelper, PermissionSchemaUpdater $permissionSchemaUpdater, ?string $timestamp = null): Response
{
- //Handle 2FA disabling
+ //Do an upgrade of the permission schema if needed (so the user can see the permissions a user get on next request (even if it was not done yet)
+ $permissionSchemaUpdater->userUpgradeSchemaRecursively($entity);
+ //Handle 2FA disabling
if ($request->request->has('reset_2fa')) {
//Check if the admin has the needed permissions
$this->denyAccessUnlessGranted('set_password', $entity);
diff --git a/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php b/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php
new file mode 100644
index 00000000..cda163c4
--- /dev/null
+++ b/src/EventSubscriber/UserSystem/UpgradePermissionsSchemaSubscriber.php
@@ -0,0 +1,73 @@
+.
+ */
+
+namespace App\EventSubscriber\UserSystem;
+
+use App\Entity\UserSystem\User;
+use App\Services\UserSystem\PermissionSchemaUpdater;
+use Doctrine\ORM\EntityManagerInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
+use Symfony\Component\HttpKernel\Event\RequestEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\Security\Core\Security;
+
+/**
+ * The purpose of this event subscriber is to check if the permission schema of the current user is up to date and upgrade it automatically if needed.
+ */
+class UpgradePermissionsSchemaSubscriber implements EventSubscriberInterface
+{
+ private Security $security;
+ private PermissionSchemaUpdater $permissionSchemaUpdater;
+ private EntityManagerInterface $entityManager;
+ private FlashBagInterface $flashBag;
+
+ public function __construct(Security $security, PermissionSchemaUpdater $permissionSchemaUpdater, EntityManagerInterface $entityManager, FlashBagInterface $flashBag)
+ {
+ $this->security = $security;
+ $this->permissionSchemaUpdater = $permissionSchemaUpdater;
+ $this->entityManager = $entityManager;
+ $this->flashBag = $flashBag;
+ }
+
+ public function onRequest(RequestEvent $event): void
+ {
+ if (!$event->isMainRequest()) {
+ return;
+ }
+
+ $user = $this->security->getUser();
+ if (null === $user) {
+ //Retrieve anonymous user
+ $user = $this->entityManager->getRepository(User::class)->getAnonymousUser();
+ }
+
+ if ($this->permissionSchemaUpdater->isSchemaUpdateNeeded($user)) {
+ $this->permissionSchemaUpdater->userUpgradeSchemaRecursively($user);
+ $this->entityManager->flush();
+ $this->flashBag->add('notice', 'user.permissions_schema_updated');
+ }
+ }
+
+ public static function getSubscribedEvents(): array
+ {
+ return [KernelEvents::REQUEST => 'onRequest'];
+ }
+}
\ No newline at end of file
diff --git a/src/Services/UserSystem/PermissionSchemaUpdater.php b/src/Services/UserSystem/PermissionSchemaUpdater.php
index fabad3db..634d63d8 100644
--- a/src/Services/UserSystem/PermissionSchemaUpdater.php
+++ b/src/Services/UserSystem/PermissionSchemaUpdater.php
@@ -20,7 +20,9 @@
namespace App\Services\UserSystem;
+use App\Entity\UserSystem\Group;
use App\Entity\UserSystem\PermissionData;
+use App\Entity\UserSystem\User;
use App\Security\Interfaces\HasPermissionsInterface;
class PermissionSchemaUpdater
@@ -42,7 +44,8 @@ class PermissionSchemaUpdater
}
/**
- * Upgrades the permission schema of the given user/group to the chosen version
+ * Upgrades the permission schema of the given user/group to the chosen version.
+ * Please note that this function does not flush the changes to DB!
* @param HasPermissionsInterface $holder
* @param int $target_version
* @return bool True, if an upgrade was done, false if it was not needed.
@@ -76,6 +79,42 @@ class PermissionSchemaUpdater
return true;
}
+ /**
+ * Upgrades the permission schema of the given group and all of its parent groups to the chosen version.
+ * Please note that this function does not flush the changes to DB!
+ * @param Group $group
+ * @param int $target_version
+ * @return bool True if an upgrade was done, false if it was not needed.
+ */
+ public function groupUpgradeSchemaRecursively(Group $group, int $target_version = PermissionData::CURRENT_SCHEMA_VERSION): bool
+ {
+ $updated = $this->upgradeSchema($group, $target_version);
+
+ /** @var Group $parent */
+ $parent = $group->getParent();
+ while ($parent) {
+ $updated = $this->upgradeSchema($parent, $target_version) || $updated;
+ $parent = $parent->getParent();
+ }
+
+ return $updated;
+ }
+
+ /**
+ * Upgrades the permissions schema of the given users and its parent (including parent groups) to the chosen version.
+ * Please note that this function does not flush the changes to DB!
+ * @param User $user
+ * @param int $target_version
+ * @return bool True if an upgrade was done, false if it was not needed.
+ */
+ public function userUpgradeSchemaRecursively(User $user, int $target_version = PermissionData::CURRENT_SCHEMA_VERSION): bool
+ {
+ $updated = $this->upgradeSchema($user, $target_version);
+ $updated = $this->groupUpgradeSchemaRecursively($user->getGroup(), $target_version) || $updated;
+
+ return $updated;
+ }
+
private function upgradeSchemaToVersion1(HasPermissionsInterface $holder): void
{
//Use the part edit permission to set the preset value for the new part stock permission
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 585cf567..072af113 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -10217,5 +10217,11 @@ Element 3
Move parts between lots
+
+
+ user.permissions_schema_updated
+ The permission schema of your user were upgraded to the latest version.
+
+