diff --git a/config/permissions.yaml b/config/permissions.yaml
index c7eefd4b..41617666 100644
--- a/config/permissions.yaml
+++ b/config/permissions.yaml
@@ -93,9 +93,9 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
<<: *PART_CONTAINING
label: "perm.part.manufacturers"
- devices:
+ projects:
<<: *PART_CONTAINING
- label: "perm.part.devices"
+ label: "perm.projects"
attachment_types:
<<: *PART_CONTAINING
diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php
index 916f32e6..4a78b784 100644
--- a/src/Controller/ProjectController.php
+++ b/src/Controller/ProjectController.php
@@ -80,7 +80,7 @@ class ProjectController extends AbstractController
if($project) {
$this->denyAccessUnlessGranted('edit', $project);
} else {
- $this->denyAccessUnlessGranted('@devices.edit');
+ $this->denyAccessUnlessGranted('@projects.edit');
}
$builder = $this->createFormBuilder();
diff --git a/src/Controller/TreeController.php b/src/Controller/TreeController.php
index f5d8bd81..6ab3b420 100644
--- a/src/Controller/TreeController.php
+++ b/src/Controller/TreeController.php
@@ -138,7 +138,7 @@ class TreeController extends AbstractController
*/
public function deviceTree(?Project $device = null): JsonResponse
{
- if ($this->isGranted('@devices.read')) {
+ if ($this->isGranted('@projects.read')) {
$tree = $this->treeGenerator->getTreeView(Project::class, $device, 'devices');
} else {
return new JsonResponse("Access denied", 403);
diff --git a/src/DataFixtures/GroupFixtures.php b/src/DataFixtures/GroupFixtures.php
index 3a93d14e..93e93b79 100644
--- a/src/DataFixtures/GroupFixtures.php
+++ b/src/DataFixtures/GroupFixtures.php
@@ -72,7 +72,7 @@ class GroupFixtures extends Fixture
private function addDevicesPermissions(Group $group): void
{
- $this->permissionManager->setAllOperationsOfPermission($group, 'devices', true);
+ $this->permissionManager->setAllOperationsOfPermission($group, 'projects', true);
}
}
diff --git a/src/Entity/Parts/PartTraits/ProjectTrait.php b/src/Entity/Parts/PartTraits/ProjectTrait.php
index 19bc0dff..58697427 100644
--- a/src/Entity/Parts/PartTraits/ProjectTrait.php
+++ b/src/Entity/Parts/PartTraits/ProjectTrait.php
@@ -62,7 +62,7 @@ trait ProjectTrait
/**
- * Get all devices which uses this part.
+ * Get all projects which uses this part.
*
* @return Project[] * all devices which uses this part as a one-dimensional array of Device objects
* (empty array if there are no ones)
diff --git a/src/Entity/UserSystem/PermissionData.php b/src/Entity/UserSystem/PermissionData.php
index 30fa48be..2d3292a4 100644
--- a/src/Entity/UserSystem/PermissionData.php
+++ b/src/Entity/UserSystem/PermissionData.php
@@ -40,7 +40,7 @@ final class PermissionData implements \JsonSerializable
/**
* The current schema version of the permission data
*/
- public const CURRENT_SCHEMA_VERSION = 1;
+ public const CURRENT_SCHEMA_VERSION = 2;
/**
* @var array This array contains the permission values for each permission
@@ -69,6 +69,56 @@ final class PermissionData implements \JsonSerializable
}
}
+ /**
+ * Checks if any of the operations of the given permission is defined (meaning it is either ALLOW or DENY)
+ * @param string $permission
+ * @return bool
+ */
+ public function isAnyOperationOfPermissionSet(string $permission): bool
+ {
+ return !empty($this->data[$permission]);
+ }
+
+ /**
+ * Returns an associative array containing all defined (non-INHERIT) operations of the given permission.
+ * @param string $permission
+ * @return array An array in the form ["operation" => value], returns an empty array if no operations are defined
+ */
+ public function getAllDefinedOperationsOfPermission(string $permission): array
+ {
+ if (empty($this->data[$permission])) {
+ return [];
+ }
+
+ return $this->data[$permission];
+ }
+
+ /**
+ * Sets all operations of the given permission via the given array.
+ * The data is an array in the form [$operation => $value], all existing values will be overwritten/deleted.
+ * @param string $permission
+ * @param array $data
+ * @return $this
+ */
+ public function setAllOperationsOfPermission(string $permission, array $data): self
+ {
+ $this->data[$permission] = $data;
+
+ return $this;
+ }
+
+ /**
+ * Removes a whole permission from the data including all operations (effectivly setting them to INHERIT)
+ * @param string $permission
+ * @return $this
+ */
+ public function removePermission(string $permission): self
+ {
+ unset($this->data[$permission]);
+
+ return $this;
+ }
+
/**
* Check if a permission value is set for the given permission and operation (meaning there value is not inherit).
* @param string $permission
diff --git a/src/Security/Voter/ParameterVoter.php b/src/Security/Voter/ParameterVoter.php
index 713a14c9..525a75b6 100644
--- a/src/Security/Voter/ParameterVoter.php
+++ b/src/Security/Voter/ParameterVoter.php
@@ -96,7 +96,7 @@ class ParameterVoter extends ExtendedVoter
} elseif ($subject instanceof CurrencyParameter) {
$param = 'currencies';
} elseif ($subject instanceof ProjectParameter) {
- $param = 'devices';
+ $param = 'projects';
} elseif ($subject instanceof FootprintParameter) {
$param = 'footprints';
} elseif ($subject instanceof GroupParameter) {
diff --git a/src/Security/Voter/StructureVoter.php b/src/Security/Voter/StructureVoter.php
index 6c7bb6a2..df88e113 100644
--- a/src/Security/Voter/StructureVoter.php
+++ b/src/Security/Voter/StructureVoter.php
@@ -40,7 +40,7 @@ class StructureVoter extends ExtendedVoter
protected const OBJ_PERM_MAP = [
AttachmentType::class => 'attachment_types',
Category::class => 'categories',
- Project::class => 'devices',
+ Project::class => 'projects',
Footprint::class => 'footprints',
Manufacturer::class => 'manufacturers',
Storelocation::class => 'storelocations',
diff --git a/src/Services/UserSystem/PermissionPresetsHelper.php b/src/Services/UserSystem/PermissionPresetsHelper.php
index 83ab0026..20ae7248 100644
--- a/src/Services/UserSystem/PermissionPresetsHelper.php
+++ b/src/Services/UserSystem/PermissionPresetsHelper.php
@@ -111,6 +111,7 @@ class PermissionPresetsHelper
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'currencies', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'measurement_units', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($permHolder, 'suppliers', PermissionData::ALLOW);
+ $this->permissionResolver->setAllOperationsOfPermission($permHolder, 'projects', PermissionData::ALLOW);
//Attachments permissions
$this->permissionResolver->setPermission($permHolder, 'attachments', 'show_private', PermissionData::ALLOW);
@@ -150,8 +151,8 @@ class PermissionPresetsHelper
$this->permissionResolver->setPermission($perm_holder, 'labels', 'edit_options', PermissionData::ALLOW);
$this->permissionResolver->setPermission($perm_holder, 'labels', 'read_profiles', PermissionData::ALLOW);
- //Set devices permissions
- $this->permissionResolver->setPermission($perm_holder, 'devices', 'read', PermissionData::ALLOW);
+ //Set projects permissions
+ $this->permissionResolver->setPermission($perm_holder, 'projects', 'read', PermissionData::ALLOW);
return $perm_holder;
}
diff --git a/src/Services/UserSystem/PermissionSchemaUpdater.php b/src/Services/UserSystem/PermissionSchemaUpdater.php
index fa031595..b4320c48 100644
--- a/src/Services/UserSystem/PermissionSchemaUpdater.php
+++ b/src/Services/UserSystem/PermissionSchemaUpdater.php
@@ -133,4 +133,14 @@ class PermissionSchemaUpdater
$holder->getPermissions()->setPermissionValue('parts_stock', 'move', $new_value);
}
}
+
+ private function upgradeSchemaToVersion2(HasPermissionsInterface $holder): void
+ {
+ //If the projects permissions are not defined yet, rename devices permission to projects (just copy its data over)
+ if (!$holder->getPermissions()->isAnyOperationOfPermissionSet('projects')) {
+ $operations_value = $holder->getPermissions()->getAllDefinedOperationsOfPermission('devices');
+ $holder->getPermissions()->setAllOperationsOfPermission('projects', $operations_value);
+ $holder->getPermissions()->removePermission('devices');
+ }
+ }
}
\ No newline at end of file
diff --git a/templates/Parts/info/_projects.html.twig b/templates/Parts/info/_projects.html.twig
index e9d58c6e..7adb2182 100644
--- a/templates/Parts/info/_projects.html.twig
+++ b/templates/Parts/info/_projects.html.twig
@@ -28,7 +28,7 @@
-
{% trans %}part.info.add_part_to_project{% endtrans %}
diff --git a/templates/Parts/info/_tools.html.twig b/templates/Parts/info/_tools.html.twig
index b9d7e0d4..2c76062b 100644
--- a/templates/Parts/info/_tools.html.twig
+++ b/templates/Parts/info/_tools.html.twig
@@ -53,7 +53,7 @@
{{ dropdown.profile_dropdown('part', part.id) }}
-
{% trans %}part.info.add_part_to_project{% endtrans %}
diff --git a/templates/Projects/info/_bom.html.twig b/templates/Projects/info/_bom.html.twig
index ac19c530..42ffd015 100644
--- a/templates/Projects/info/_bom.html.twig
+++ b/templates/Projects/info/_bom.html.twig
@@ -4,7 +4,7 @@
{{ datatables.datatable(datatable, 'elements/datatables/datatables', 'projects') }}
-
{% trans %}project.info.bom_add_parts{% endtrans %}
diff --git a/templates/components/datatables.macro.html.twig b/templates/components/datatables.macro.html.twig
index d6aa19cd..0c5c170c 100644
--- a/templates/components/datatables.macro.html.twig
+++ b/templates/components/datatables.macro.html.twig
@@ -49,7 +49,7 @@
diff --git a/templates/components/tree_macros.html.twig b/templates/components/tree_macros.html.twig
index 4d0846f6..b85fcc88 100644
--- a/templates/components/tree_macros.html.twig
+++ b/templates/components/tree_macros.html.twig
@@ -6,7 +6,7 @@
['footprints', path('tree_footprint_root'), 'footprint.labelp', is_granted('@footprints.read') and is_granted('@parts.read')],
['manufacturers', path('tree_manufacturer_root'), 'manufacturer.labelp', is_granted('@manufacturers.read') and is_granted('@parts.read')],
['suppliers', path('tree_supplier_root'), 'supplier.labelp', is_granted('@suppliers.read') and is_granted('@parts.read')],
- ['devices', path('tree_device_root'), 'project.labelp', is_granted('@devices.read')],
+ ['devices', path('tree_device_root'), 'project.labelp', is_granted('@projects.read')],
['tools', path('tree_tools'), 'tools.label', true],
] %}
diff --git a/tests/Entity/UserSystem/PermissionDataTest.php b/tests/Entity/UserSystem/PermissionDataTest.php
index 681c5082..5107c2a0 100644
--- a/tests/Entity/UserSystem/PermissionDataTest.php
+++ b/tests/Entity/UserSystem/PermissionDataTest.php
@@ -158,4 +158,61 @@ class PermissionDataTest extends TestCase
$data->setSchemaVersion(12345);
$this->assertEquals(12345, $data->getSchemaVersion());
}
+
+ public function testIsAnyOperationOfPermissionSet()
+ {
+ $data = new PermissionData();
+
+ //Initially no operation of any permission is set
+ $this->assertFalse($data->isAnyOperationOfPermissionSet('perm1'));
+
+ $data->setPermissionValue('perm1', 'op1', PermissionData::ALLOW);
+ $this->assertTrue($data->isAnyOperationOfPermissionSet('perm1'));
+ }
+
+ public function testGetAllDefinedOperationsOfPermission()
+ {
+ $data = new PermissionData();
+
+ $this->assertEmpty($data->getAllDefinedOperationsOfPermission('perm1'));
+
+ $data->setPermissionValue('perm1', 'op1', PermissionData::ALLOW);
+ $data->setPermissionValue('perm1', 'op2', PermissionData::DISALLOW);
+
+ $this->assertEquals([
+ 'op1' => PermissionData::ALLOW, 'op2' => PermissionData::DISALLOW,
+ ],
+ $data->getAllDefinedOperationsOfPermission('perm1'));
+ }
+
+ public function testSetAllOperationsOfPermission()
+ {
+ $data = new PermissionData();
+
+ $data->setAllOperationsOfPermission('perm1', [
+ 'op1' => PermissionData::ALLOW,
+ 'op2' => PermissionData::DISALLOW,
+ ]);
+
+ $this->assertEquals([
+ 'op1' => PermissionData::ALLOW, 'op2' => PermissionData::DISALLOW,
+ ],
+ $data->getAllDefinedOperationsOfPermission('perm1'));
+ }
+
+ public function testRemovePermission()
+ {
+ $data = new PermissionData();
+
+ $data->setPermissionValue('perm1', 'op1', PermissionData::ALLOW);
+ $data->setPermissionValue('perm1', 'op2', PermissionData::DISALLOW);
+
+ $this->assertTrue($data->isPermissionSet('perm1', 'op1'));
+ $this->assertTrue($data->isPermissionSet('perm1', 'op2'));
+
+ $data->removePermission('perm1');
+
+ $this->assertFalse($data->isPermissionSet('perm1', 'op1'));
+ $this->assertFalse($data->isPermissionSet('perm1', 'op2'));
+ }
}
diff --git a/tests/Services/UserSystem/PermissionSchemaUpdaterTest.php b/tests/Services/UserSystem/PermissionSchemaUpdaterTest.php
index 3ed48cf5..79abb89c 100644
--- a/tests/Services/UserSystem/PermissionSchemaUpdaterTest.php
+++ b/tests/Services/UserSystem/PermissionSchemaUpdaterTest.php
@@ -97,4 +97,20 @@ class PermissionSchemaUpdaterTest extends WebTestCase
self::assertEquals(PermissionData::ALLOW, $user->getPermissions()->getPermissionValue('parts_stock', 'add'));
self::assertEquals(PermissionData::ALLOW, $user->getPermissions()->getPermissionValue('parts_stock', 'withdraw'));
}
+
+ public function testUpgradeSchemaToVersion2()
+ {
+ $perm_data = new PermissionData();
+ $perm_data->setSchemaVersion(1);
+ $perm_data->setPermissionValue('devices', 'read', PermissionData::ALLOW);
+ $perm_data->setPermissionValue('devices', 'edit', PermissionData::INHERIT);
+ $perm_data->setPermissionValue('devices', 'delete', PermissionData::DISALLOW);
+ $user = new TestPermissionHolder($perm_data);
+
+ //After the upgrade all operations should be available under the name "projects" with the same values
+ self::assertTrue($this->service->upgradeSchema($user, 2));
+ self::assertEquals(PermissionData::ALLOW, $user->getPermissions()->getPermissionValue('projects', 'read'));
+ self::assertEquals(PermissionData::INHERIT, $user->getPermissions()->getPermissionValue('projects', 'edit'));
+ self::assertEquals(PermissionData::DISALLOW, $user->getPermissions()->getPermissionValue('projects', 'delete'));
+ }
}
diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf
index 36b60369..aadc374c 100644
--- a/translations/messages.de.xlf
+++ b/translations/messages.de.xlf
@@ -8111,14 +8111,14 @@ Element 3
Hersteller
-
+
obsolete
obsolete
- perm.part.devices
- Baugruppen
+ perm.projects
+ Projekte
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 5653956e..d66f855a 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -3284,7 +3284,7 @@ Sub elements will be moved upwards.]]>
statistics.devices_count
- Number of devices
+ Number of projects
@@ -8112,14 +8112,14 @@ Element 3
Manufacturers
-
+
obsolete
obsolete
- perm.part.devices
- Devices
+ perm.projects
+ Projects