diff --git a/src/Controller/PartListsController.php b/src/Controller/PartListsController.php
index fdd01821..af18aeea 100644
--- a/src/Controller/PartListsController.php
+++ b/src/Controller/PartListsController.php
@@ -175,6 +175,8 @@ class PartListsController extends AbstractController
*/
public function showCategory(Category $category, Request $request)
{
+ $this->denyAccessUnlessGranted('@categories.read');
+
return $this->showListWithFilter($request,
'Parts/lists/category_list.html.twig',
function (PartFilter $filter) use ($category) {
@@ -195,6 +197,8 @@ class PartListsController extends AbstractController
*/
public function showFootprint(Footprint $footprint, Request $request)
{
+ $this->denyAccessUnlessGranted('@footprints.read');
+
return $this->showListWithFilter($request,
'Parts/lists/footprint_list.html.twig',
function (PartFilter $filter) use ($footprint) {
@@ -215,6 +219,8 @@ class PartListsController extends AbstractController
*/
public function showManufacturer(Manufacturer $manufacturer, Request $request)
{
+ $this->denyAccessUnlessGranted('@manufacturers.read');
+
return $this->showListWithFilter($request,
'Parts/lists/manufacturer_list.html.twig',
function (PartFilter $filter) use ($manufacturer) {
@@ -235,6 +241,8 @@ class PartListsController extends AbstractController
*/
public function showStorelocation(Storelocation $storelocation, Request $request)
{
+ $this->denyAccessUnlessGranted('@storelocations.read');
+
return $this->showListWithFilter($request,
'Parts/lists/store_location_list.html.twig',
function (PartFilter $filter) use ($storelocation) {
@@ -255,6 +263,8 @@ class PartListsController extends AbstractController
*/
public function showSupplier(Supplier $supplier, Request $request)
{
+ $this->denyAccessUnlessGranted('@suppliers.read');
+
return $this->showListWithFilter($request,
'Parts/lists/supplier_list.html.twig',
function (PartFilter $filter) use ($supplier) {
diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php
index 16f530dd..eb9798b6 100644
--- a/src/DataTables/PartsDataTable.php
+++ b/src/DataTables/PartsDataTable.php
@@ -163,20 +163,29 @@ final class PartsDataTable implements DataTableTypeInterface
])
->add('description', MarkdownColumn::class, [
'label' => $this->translator->trans('part.table.description'),
- ])
- ->add('category', EntityColumn::class, [
+ ]);
+
+ if ($this->security->isGranted('@categories.read')) {
+ $dataTable->add('category', EntityColumn::class, [
'label' => $this->translator->trans('part.table.category'),
'property' => 'category',
- ])
- ->add('footprint', EntityColumn::class, [
+ ]);
+ }
+
+ if ($this->security->isGranted('@footprints.read')) {
+ $dataTable->add('footprint', EntityColumn::class, [
'property' => 'footprint',
'label' => $this->translator->trans('part.table.footprint'),
- ])
- ->add('manufacturer', EntityColumn::class, [
+ ]);
+ }
+ if ($this->security->isGranted('@manufacturers.read')) {
+ $dataTable->add('manufacturer', EntityColumn::class, [
'property' => 'manufacturer',
'label' => $this->translator->trans('part.table.manufacturer'),
- ])
- ->add('storelocation', TextColumn::class, [
+ ]);
+ }
+ if ($this->security->isGranted('@storelocations.read')) {
+ $dataTable->add('storelocation', TextColumn::class, [
'label' => $this->translator->trans('part.table.storeLocations'),
'render' => function ($value, Part $context) {
$tmp = [];
@@ -194,32 +203,38 @@ final class PartsDataTable implements DataTableTypeInterface
return implode('
', $tmp);
},
- ])
- ->add('amount', TextColumn::class, [
- 'label' => $this->translator->trans('part.table.amount'),
- 'render' => function ($value, Part $context) {
- $amount = $context->getAmountSum();
+ ]);
+ }
- return $this->amountFormatter->format($amount, $context->getPartUnit());
- },
- 'orderField' => 'amountSum'
- ])
+ $dataTable->add('amount', TextColumn::class, [
+ 'label' => $this->translator->trans('part.table.amount'),
+ 'render' => function ($value, Part $context) {
+ $amount = $context->getAmountSum();
+
+ return $this->amountFormatter->format($amount, $context->getPartUnit());
+ },
+ 'orderField' => 'amountSum'
+ ])
->add('minamount', TextColumn::class, [
'label' => $this->translator->trans('part.table.minamount'),
'visible' => false,
'render' => function ($value, Part $context) {
return $this->amountFormatter->format($value, $context->getPartUnit());
},
- ])
- ->add('partUnit', TextColumn::class, [
+ ]);
+
+ if ($this->security->isGranted('@footprints.read')) {
+ $dataTable->add('partUnit', TextColumn::class, [
'field' => 'partUnit.name',
'label' => $this->translator->trans('part.table.partUnit'),
'visible' => false,
- ])
- ->add('addedDate', LocaleDateTimeColumn::class, [
- 'label' => $this->translator->trans('part.table.addedDate'),
- 'visible' => false,
- ])
+ ]);
+ }
+
+ $dataTable->add('addedDate', LocaleDateTimeColumn::class, [
+ 'label' => $this->translator->trans('part.table.addedDate'),
+ 'visible' => false,
+ ])
->add('lastModified', LocaleDateTimeColumn::class, [
'label' => $this->translator->trans('part.table.lastModified'),
'visible' => false,
diff --git a/src/Security/Voter/PermissionVoter.php b/src/Security/Voter/PermissionVoter.php
index 7632d39d..86ca99f2 100644
--- a/src/Security/Voter/PermissionVoter.php
+++ b/src/Security/Voter/PermissionVoter.php
@@ -80,7 +80,12 @@ class PermissionVoter extends ExtendedVoter
$attribute = ltrim($attribute, '@');
[$perm, $op] = explode('.', $attribute);
- return $this->resolver->isValidOperation($perm, $op);
+ $valid = $this->resolver->isValidOperation($perm, $op);
+
+ //if an invalid operation is encountered, throw an exception so the developer knows it
+ //throw new \RuntimeException('Encountered invalid permission operation "'.$op.'" for permission "'.$perm.'"!');
+
+ return true;
}
return false;
diff --git a/src/Services/Parts/PartsTableActionHandler.php b/src/Services/Parts/PartsTableActionHandler.php
index a30bd9d2..5fde6992 100644
--- a/src/Services/Parts/PartsTableActionHandler.php
+++ b/src/Services/Parts/PartsTableActionHandler.php
@@ -76,9 +76,11 @@ final class PartsTableActionHandler
switch ($action) {
case 'favorite':
+ $this->denyAccessUnlessGranted('change_favorite', $part);
$part->setFavorite(true);
break;
case 'unfavorite':
+ $this->denyAccessUnlessGranted('change_favorite', $part);
$part->setFavorite(false);
break;
case 'delete':
@@ -86,19 +88,19 @@ final class PartsTableActionHandler
$this->entityManager->remove($part);
break;
case 'change_category':
- $this->denyAccessUnlessGranted('category.edit', $part);
+ $this->denyAccessUnlessGranted('@categories.read');
$part->setCategory($this->entityManager->find(Category::class, $target_id));
break;
case 'change_footprint':
- $this->denyAccessUnlessGranted('footprint.edit', $part);
+ $this->denyAccessUnlessGranted('@footprints.read');
$part->setFootprint(null === $target_id ? null : $this->entityManager->find(Footprint::class, $target_id));
break;
case 'change_manufacturer':
- $this->denyAccessUnlessGranted('manufacturer.edit', $part);
+ $this->denyAccessUnlessGranted('@manufacturers.read');
$part->setManufacturer(null === $target_id ? null : $this->entityManager->find(Manufacturer::class, $target_id));
break;
case 'change_unit':
- $this->denyAccessUnlessGranted('unit.edit', $part);
+ $this->denyAccessUnlessGranted('@measurement_units.read');
$part->setPartUnit(null === $target_id ? null : $this->entityManager->find(MeasurementUnit::class, $target_id));
break;
diff --git a/templates/components/datatables.macro.html.twig b/templates/components/datatables.macro.html.twig
index 8299529e..f08bdf27 100644
--- a/templates/components/datatables.macro.html.twig
+++ b/templates/components/datatables.macro.html.twig
@@ -35,15 +35,15 @@
-
+