From 3941f2482e26590e7f0f24147bc87740ab7f18af Mon Sep 17 00:00:00 2001 From: Udo Walter Date: Tue, 3 Oct 2017 20:07:15 +0200 Subject: [locations] implemented new permission system --- modules-available/locations/inc/location.inc.php | 3 +- modules-available/locations/page.inc.php | 102 +++++++++++++++++++-- .../locations/permissions/permissions.json | 9 ++ modules-available/locations/style.css | 13 ++- .../locations/templates/location-subnets.html | 40 ++++---- .../locations/templates/locations.html | 17 ++-- modules-available/locations/templates/subnets.html | 10 +- .../permissionmanager/inc/permissionutil.inc.php | 2 +- 8 files changed, 154 insertions(+), 42 deletions(-) create mode 100644 modules-available/locations/permissions/permissions.json diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php index 8b2ef262..c2bf14ef 100644 --- a/modules-available/locations/inc/location.inc.php +++ b/modules-available/locations/inc/location.inc.php @@ -352,7 +352,8 @@ class Location */ public static function getSubnets() { - $res = Database::simpleQuery("SELECT startaddr, endaddr, locationid FROM subnet"); + $res = Database::simpleQuery("SELECT startaddr, endaddr, locationid FROM subnet WHERE locationid IN (:locations)", + array("locations" => User::getAllowedLocations("subnetlist.view"))); $subnets = array(); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { settype($row['locationid'], 'int'); diff --git a/modules-available/locations/page.inc.php b/modules-available/locations/page.inc.php index 20af7b63..ed78a6c7 100644 --- a/modules-available/locations/page.inc.php +++ b/modules-available/locations/page.inc.php @@ -12,7 +12,7 @@ class Page_Locations extends Page protected function doPreprocess() { User::load(); - if (!User::hasPermission('superadmin')) { + if (!User::isLoggedIn()) { Message::addError('main.no-permission'); Util::redirect('?do=Main'); } @@ -47,6 +47,12 @@ class Page_Locations extends Page Message::addError('main.value-invalid', 'locationid', $loc); continue; } + + $oldLoc = Database::queryFirst("SELECT locationid FROM subnet WHERE subnetid = :subnetid", array("subnetid" => $subnetid))["locationid"]; + if (($loc == $oldLoc && !User::hasPermission("subnet.edit", $loc)) || + ($loc != $oldLoc && (!User::hasPermission("subnet.delete", $oldLoc) || !User::hasPermission("subnet.add", $loc)))) + continue; + $range = $this->rangeToLongVerbose($start, $end); if ($range === false) continue; @@ -57,7 +63,7 @@ class Page_Locations extends Page } AutoLocation::rebuildAll(); Message::addSuccess('subnets-updated', $count); - Util::redirect('?do=Locations'); + Util::redirect('?do=Locations&action=showsubnets'); } private function addLocations() @@ -75,6 +81,8 @@ class Page_Locations extends Page if (empty($name)) continue; $parent = isset($parents[$idx]) ? (int)$parents[$idx] : 0; + if (!User::hasPermission("location.add", $parent)) + continue; if ($parent !== 0) { $ok = false; foreach ($locs as $loc) { @@ -115,15 +123,25 @@ class Page_Locations extends Page $change = false; // Delete location? if ($locationId === $del) { + if (!User::hasPermission("location.delete", $locationId)) { + Message::addError('main.no-permission', 'locationid', $locationId); + Util::redirect('?do=Locations'); + } $this->deleteLocation($location); $change = true; } // Update subnets $change |= $this->updateLocationSubnets(); - // Insert subnets - $change |= $this->addNewLocationSubnets($location); - // Update location! - $change |= $this->updateLocationData($location); + + if (User::hasPermission("subnet.add", $locationId)) { + // Insert subnets + $change |= $this->addNewLocationSubnets($location); + } + if (User::hasPermission("location.edit", $locationId)) { + // Update location! + $change |= $this->updateLocationData($location); + } + if ($change) { // In case subnets or tree layout changed, recalc this AutoLocation::rebuildAll(); @@ -195,9 +213,12 @@ class Page_Locations extends Page private function updateLocationSubnets() { $change = false; + + $locationId = Request::post('locationid', false, 'integer'); + // Deletion first $dels = Request::post('deletesubnet', false); - if (is_array($dels)) { + if (is_array($dels) && User::hasPermission("subnet.delete", $locationId)) { $count = 0; $stmt = Database::prepare('DELETE FROM subnet WHERE subnetid = :id'); foreach ($dels as $key => $value) { @@ -212,6 +233,9 @@ class Page_Locations extends Page $change = true; } } + if (!User::hasPermission("subnet.edit", $locationId)) + return $change; + // Now actual updates $starts = Request::post('startaddr', false); $ends = Request::post('endaddr', false); @@ -291,15 +315,28 @@ class Page_Locations extends Page Util::redirect('?do=Locations&action=showlocations'); } if ($getAction === 'showsubnets') { - $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr, locationid FROM subnet"); + $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr, locationid FROM subnet + WHERE locationid IN (:locations)", + array("locations" => User::getAllowedLocations("location.view"))); $rows = array(); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $row['startaddr'] = long2ip($row['startaddr']); $row['endaddr'] = long2ip($row['endaddr']); $row['locations'] = Location::getLocations($row['locationid']); + + $allowedLocs = User::getAllowedLocations("subnet.add"); + foreach ($row['locations'] as &$loc) { + if (!(in_array($loc["locationid"], $allowedLocs) || $loc["locationid"] == $row['locationid'])) { + $loc["disabled"] = "disabled"; + } + } + + $row['editThisSubnetAllowed'] = User::hasPermission("subnet.edit", $row['locationid']); + $row['deleteThisSubnetAllowed'] = User::hasPermission("subnet.delete", $row['locationid']); $rows[] = $row; } - Render::addTemplate('subnets', array('list' => $rows)); + + Render::addTemplate('subnets', array('list' => $rows, 'editSubnetAllowed' => User::hasPermission("subnet.edit"))); } elseif ($getAction === 'showlocations') { $this->showLocationList(); } @@ -388,6 +425,32 @@ class Page_Locations extends Page } } } + + $allowedLocs = User::getAllowedLocations("location.view"); + $withParents = array(); + foreach ($allowedLocs as $loc) { + $withParents = array_merge($withParents, Location::getLocationRootChain($loc)); + } + + foreach ($locs as $key => $loc) { + if (!in_array($loc["locationid"], $withParents)) { + unset($locs[$key]); + } elseif (!in_array($loc["locationid"], $allowedLocs)) { + $id = $locs[$key]["locationid"]; + $name = $locs[$key]["locationname"]; + $depth = $locs[$key]["depth"]; + $locs[$key] = array("locationid" => $id, "locationname" => $name, "depth" => $depth, "linkClass" => "not-allowed"); + } + } + + $addAllowedLocs = User::getAllowedLocations("location.add"); + $addAllowedList = Location::getLocations(0, 0, True); + foreach ($addAllowedList as &$loc) { + if (!in_array($loc["locationid"], $addAllowedLocs)) { + $loc["disabled"] = "disabled"; + } + } + // Output Render::addTemplate('locations', array( 'list' => array_values($locs), @@ -400,6 +463,8 @@ class Page_Locations extends Page 'haveOverlapOther' => !empty($overlapOther), 'unassignedCount' => $unassigned, 'defaultConfig' => $defaultConfig, + 'addAllowed' => User::hasPermission("location.add"), + 'addAllowedList' => array_values($addAllowedList) )); } @@ -422,6 +487,11 @@ class Page_Locations extends Page private function ajaxShowLocation() { $locationId = Request::any('locationid', 0, 'integer'); + + if (!User::hasPermission("location.view", $locationId)) { + die('Permission denied'); + } + $loc = Database::queryFirst('SELECT locationid, parentlocationid, locationname FROM location WHERE locationid = :lid', array('lid' => $locationId)); if ($loc === false) { @@ -442,6 +512,14 @@ class Page_Locations extends Page 'roomplanner' => Module::get('roomplanner') !== false && Location::isLeaf($locationId), 'parents' => Location::getLocations($loc['parentlocationid'], $locationId, true) ); + + $allowedLocs = User::getAllowedLocations("location.edit"); + foreach ($data['parents'] as &$parent) { + if (!(in_array($parent["locationid"], $allowedLocs) || $parent["locationid"] == $loc['parentlocationid'])) { + $parent["disabled"] = "disabled"; + } + } + if (Module::get('dozmod') !== false) { $lectures = Database::queryFirst('SELECT Count(*) AS cnt FROM sat.lecture l ' . ' INNER JOIN sat.lecture_x_location ll ON (l.lectureid = ll.lectureid AND ll.locationid = :lid)', @@ -474,6 +552,12 @@ class Page_Locations extends Page $data['havebaseconfig'] = Module::get('baseconfig') !== false; $data['havesysconfig'] = Module::get('sysconfig') !== false; + $data['editAllowed'] = User::hasPermission("location.edit", $locationId); + $data['deleteAllowed'] = User::hasPermission("location.delete", $locationId); + $data['editSubnetAllowed'] = User::hasPermission("subnet.edit", $locationId); + $data['deleteSubnetAllowed'] = User::hasPermission("subnet.delete", $locationId); + $data['addSubnetAllowed'] = User::hasPermission("subnet.add", $locationId); + $data['saveButton'] = $data['editAllowed'] || $data['editSubnetAllowed'] || $data['deleteSubnetAllowed'] || $data['addSubnetAllowed']; // echo '
';
 		// var_dump($data);
diff --git a/modules-available/locations/permissions/permissions.json b/modules-available/locations/permissions/permissions.json
new file mode 100644
index 00000000..db0ac5f6
--- /dev/null
+++ b/modules-available/locations/permissions/permissions.json
@@ -0,0 +1,9 @@
+{
+	"location.view": "View locations.",
+	"location.edit": "Edit locations.",
+	"location.add": "Add locations.",
+	"location.delete": "Delete locations.",
+	"subnet.edit": "Edit subnets.",
+	"subnet.add": "Add subnets.",
+	"subnet.delete": "Delete subnets."
+}
\ No newline at end of file
diff --git a/modules-available/locations/style.css b/modules-available/locations/style.css
index 86f9dfca..042ac4d1 100644
--- a/modules-available/locations/style.css
+++ b/modules-available/locations/style.css
@@ -1,3 +1,14 @@
 table.locations tbody td:nth-of-type(even) {
     background-color: rgba(0, 0, 0, 0.025);
-}
\ No newline at end of file
+}
+
+.not-allowed {
+    pointer-events: none;
+    cursor: default;
+    color: inherit;
+}
+
+.disabled {
+    pointer-events: none;
+    opacity: 0.6;
+}
diff --git a/modules-available/locations/templates/location-subnets.html b/modules-available/locations/templates/location-subnets.html
index 9cfa5cc8..754616c6 100644
--- a/modules-available/locations/templates/location-subnets.html
+++ b/modules-available/locations/templates/location-subnets.html
@@ -8,24 +8,26 @@
 			
 		
 		
-
-
- {{lang_name}} - +
+
+
+ {{lang_name}} + +
-
-
-
- {{lang_parentLocation}} - +
+
+ {{lang_parentLocation}} + +
- +

@@ -41,11 +43,11 @@ {{#list}} {{subnetid}} - - + +
- +
@@ -53,7 +55,7 @@ {{/list}} - @@ -86,7 +88,7 @@
- +
diff --git a/modules-available/locations/templates/locations.html b/modules-available/locations/templates/locations.html index 451d8add..afbca3c6 100644 --- a/modules-available/locations/templates/locations.html +++ b/modules-available/locations/templates/locations.html @@ -24,9 +24,10 @@
- {{locationname}} + {{locationname}}{{^linkClass}} {{/linkClass}} + {{^linkClass}} {{#havestatistics}} {{clientCount}} @@ -35,13 +36,17 @@ {{/havestatistics}} + {{/linkClass}} + {{^linkClass}} {{#havestatistics}} {{clientLoad}} {{/havestatistics}} + {{/linkClass}} + {{^linkClass}} {{#havebaseconfig}}
@@ -50,8 +55,10 @@ {{lang_overrideCount}}: {{overriddenVars}}   {{/overriddenVars}} {{/havebaseconfig}} + {{/linkClass}} + {{^linkClass}} {{#havesysconfig}}
@@ -60,6 +67,7 @@ {{configName}}   {{/havesysconfig}} + {{/linkClass}} {{/list}} @@ -90,12 +98,10 @@ - - - @@ -122,8 +128,7 @@ function slxAddLocationRow() { tr.before('\ \ \ \ '); diff --git a/modules-available/locations/templates/subnets.html b/modules-available/locations/templates/subnets.html index 4c96cc4d..0a1eca21 100644 --- a/modules-available/locations/templates/subnets.html +++ b/modules-available/locations/templates/subnets.html @@ -17,12 +17,12 @@ {{#list}} {{subnetid}} - - - + + + @@ -30,7 +30,7 @@ {{/list}}
- +
diff --git a/modules-available/permissionmanager/inc/permissionutil.inc.php b/modules-available/permissionmanager/inc/permissionutil.inc.php index df877520..5c3eef58 100644 --- a/modules-available/permissionmanager/inc/permissionutil.inc.php +++ b/modules-available/permissionmanager/inc/permissionutil.inc.php @@ -45,7 +45,7 @@ class PermissionUtil } $allowedLocations = array_keys($allowedLocations); $locations = Location::getTree(); - if (count($allowedLocations) == 1 && $allowedLocations[0] == "0") { + if (in_array("0", $allowedLocations)) { $allowedLocations = array_map("intval", Location::extractIds($locations)); } else { $allowedLocations = self::getSublocations($locations, $allowedLocations); -- cgit v1.2.3-55-g7522