diff --git a/htdocs/web_portal/controllers/downtime/add_downtime.php b/htdocs/web_portal/controllers/downtime/add_downtime.php
index becb0c73f..3c1efdc44 100644
--- a/htdocs/web_portal/controllers/downtime/add_downtime.php
+++ b/htdocs/web_portal/controllers/downtime/add_downtime.php
@@ -125,95 +125,266 @@ function submit(\User $user = null) {
/**
* Draws a form to add a new downtime
+ *
* @param \User $user current user
* @return null
*/
-function draw(\User $user = null) {
- if(is_null($user)) {
- throw new Exception("Unregistered users can't add a downtime.");
+function draw(\User $user = null)
+{
+ if (is_null($user)) {
+ throwPermissionException(
+ "Unregistered users can't add a downtime.",
+ false
+ );
}
$nowUtcDateTime = new \DateTime(null, new \DateTimeZone("UTC"));
- //$twoDaysAgoUtcDateTime = $nowUtcDateTime->sub(\DateInterval::createFromDateString('2 days'));
- //$twoDaysAgoUtc = $twoDaysAgoUtcDateTime->format('d/m/Y H:i'); //e.g. 02/10/2013 13:20
-
-
- // URL mapping
- // Return the specified site's timezone label and the offset from now in UTC
- // Used in ajax requests for display purposes
- if(isset($_GET['siteid_timezone']) && is_numeric($_GET['siteid_timezone'])){
- $site = \Factory::getSiteService()->getSite($_GET['siteid_timezone']);
- if($site != null){
- $siteTzId = $site->getTimeZoneId();
- if( !empty($siteTzId) ){
- $nowInTargetTz = new \DateTime(null, new \DateTimeZone($siteTzId));
- $offsetInSecsFromUtc = $nowInTargetTz->getOffset();
- } else {
- $siteTzId = 'UTC';
- $offsetInSecsFromUtc = 0; // assume 0 (no offset from UTC)
- }
- $timezoneId_Offset = array($siteTzId, $offsetInSecsFromUtc);
- die(json_encode($timezoneId_Offset));
- }
- die(json_encode(array('UTC', 0)));
+
+ /**
+ * URL mapping for `siteid_timezone` params.
+ *
+ * Handles the request to get a specific site's timezone label and offset
+ * from now in UTC sed in ajax requests for display purposes.
+ */
+ $siteId = $_GET['siteid_timezone'];
+
+ if (isset($siteId) && is_numeric($siteId)) {
+ handleSiteTimezoneRequest($siteId);
}
- // URL Mapping
- // If the user wants to add a downtime to a specific site, show only that site's SEs
- else if(isset($_GET['site'])) {
- $site = \Factory::getSiteService()->getSite($_GET['site']);
- if(\Factory::getRoleActionAuthorisationService()->authoriseAction(\Action::EDIT_OBJECT, $site, $user)->getGrantAction() == FALSE){
- throw new \Exception("You don't have permission over $site");
- }
- $ses = $site->getServices();
- $params = array('ses' => $ses, 'nowUtc' => $nowUtcDateTime->format('H:i T'), 'selectAll' => true);
- show_view("downtime/add_downtime.php", $params);
- die();
- }
-
- // URL Mapping
- // If the user wants to add a downtime to a specific SE, show only that SE
- else if(isset($_GET['se'])) {
- $se = \Factory::getServiceService()->getService($_GET['se']);
- $site = \Factory::getSiteService()->getSite($se->getParentSite()->getId());
- if(\Factory::getRoleActionAuthorisationService()->authoriseAction(\Action::EDIT_OBJECT, $se->getParentSite(), $user)->getGrantAction() == FALSE){
- throw new \Exception("You do not have permission over $se.");
- }
+ /**
+ * URL Mapping for `site` and `se` (Service Endpoint).
+ *
+ * If a user wants to add downtime to a specific
+ * `site` and `se` (Service Endpoint), the portal will
+ * pre-select the service endpoint corresponding to the `se` parameter
+ * and the endpoints of that service.
+ */
+ elseif (isset($_GET['site']) && isset($_GET['se'])) {
+ displaySiteAndSeEndpoints($user, $nowUtcDateTime);
+ }
+
+ /**
+ * URL Mapping for `site` ONLY.
+ *
+ * If a user wants to add downtime to a specific `site`, the portal will
+ * pre-select all service endpoints and their corresponding endpoints.
+ */
+ elseif (isset($_GET['site'])) {
+ displaySiteEndpoints($user, $nowUtcDateTime);
+ }
- //$ses = array($se);
- $ses = $site->getServices();
- $params = array('ses' => $ses, 'nowUtc' => $nowUtcDateTime->format('H:i T'), 'selectAll' => true);
- show_view("downtime/add_downtime.php", $params);
- die();
+ /**
+ * URL Mapping for `se` (Service Endpoint) ONLY.
+ *
+ * If the user wants to add downtime to a specific `se` (Service Endpoint),
+ * the portal will pre-select the service endpoint corresponding
+ * to the `se` parameter and the endpoints of that service.
+ */
+ elseif (isset($_GET['se'])) {
+ displaySeEndpoints($user, $nowUtcDateTime);
}
- // If the user doesn't want to add a downtime to a specific SE or site show all SEs
+ /**
+ * Generic URL mapping.
+ *
+ * User should be able to see site name(s) based on their permissions.
+ * The portal will NOT perform pre-selections.
+ */
else {
- $ses = array();
- if($user->isAdmin()){
- //If a user is an admin, return all SEs instead
- $ses = \Factory::getServiceService()->getAllSesJoinParentSites();
+ displayAllServiceEndpoints($user, $nowUtcDateTime);
+ }
+}
+
+/**
+ * Handles the `siteid_timezone` request and
+ * retrieves the timezone label and offset.
+ *
+ * Returns it as a JSON response.
+ */
+function handleSiteTimezoneRequest($siteId)
+{
+ $site = \Factory::getSiteService()->getSite($siteId);
+
+ if (!empty($site)) {
+ $siteTzId = $site->getTimeZoneId();
+
+ if (!empty($siteTzId)) {
+ $nowInTargetTz = new \DateTime(null, new \DateTimeZone($siteTzId));
+ $offsetInSecsFromUtc = $nowInTargetTz->getOffset();
} else {
- //$allSites = \Factory::getUserService()->getSitesFromRoles($user);
-
- // Get all ses where the user has a GRANTED role over one of its
- // parent OwnedObjects (includes Site and NGI but not currently Project)
- $sesAll = \Factory::getRoleService()->getReachableServicesFromOwnedObjectRoles($user);
- // drop the ses where the user does not have edit permissions over
- foreach($sesAll as $se){
- if(\Factory::getRoleActionAuthorisationService()->authoriseAction(\Action::EDIT_OBJECT, $se->getParentSite(), $user)->getGrantAction() ){
- $ses[] = $se;
- }
- }
+ $siteTzId = 'UTC';
+ $offsetInSecsFromUtc = 0; // assume 0 (no offset from UTC)
}
- if(empty($ses)) {
- throw new Exception("You don't hold a role over a NGI "
- . "or site with child services.");
+
+ $timezoneId_Offset = array($siteTzId, $offsetInSecsFromUtc);
+ die(json_encode($timezoneId_Offset));
+ }
+ die(json_encode(array('UTC', 0)));
+}
+
+/**
+ * Helper method to fetch the `se` (Service Endpoint) and `site` details.
+ * This will help portal to pre-select endpoints corresponding
+ * to the `se` (Service Endpoint) provided.
+ */
+function displaySiteAndSeEndpoints($user, $nowUtcDateTime)
+{
+ $se = \Factory::getServiceService()->getService($_GET['se']);
+ $site = \Factory::getSiteService()->getSite($_GET['site']);
+ $ses = $site->getServices();
+
+ if (!hasEditPermission($site, $user)) {
+ throwPermissionException($site, true);
+ }
+
+ $params = [
+ 'serviceID' => $se,
+ 'ses' => $ses,
+ 'nowUtc' => $nowUtcDateTime->format('H:i T'),
+ 'selectAll' => true
+ ];
+
+ show_view("downtime/add_downtime.php", $params);
+ die();
+}
+
+/**
+ * Helper method to fetch site details associated with `site` parameter,
+ * This will help portal to pre-select endpoints corresponding to the
+ * service endpoints belonging to the site.
+ */
+function displaySiteEndpoints($user, $nowUtcDateTime)
+{
+ $site = \Factory::getSiteService()->getSite($_GET['site']);
+ $ses = $site->getServices();
+
+ if (!hasEditPermission($site, $user)) {
+ throwPermissionException($site, true);
+ }
+
+ $params = [
+ 'ses' => $ses,
+ 'nowUtc' => $nowUtcDateTime->format('H:i T'),
+ 'selectAll' => true
+ ];
+
+ show_view("downtime/add_downtime.php", $params);
+ die();
+}
+
+/**
+ * Helper method to fetch the `se` (Service Endpoint) details.
+ * We obtain parent site information from the provided `se` (Service Endpoint).
+ * The portal will pre-select endpoints corresponding
+ * to the `se` (Service Endoint) provided.
+ */
+function displaySeEndpoints($user, $nowUtcDateTime)
+{
+ $se = \Factory::getServiceService()->getService($_GET['se']);
+ $parentSite = $se->getParentSite();
+ $site = \Factory::getSiteService()->getSite($parentSite->getId());
+ $ses = $site->getServices();
+
+ if (!hasEditPermission($parentSite, $user)) {
+ throwPermissionException($se, true);
+ }
+
+ $params = [
+ 'ses' => $ses,
+ 'nowUtc' => $nowUtcDateTime->format('H:i T'),
+ 'selectAll' => true
+ ];
+
+ show_view("downtime/add_downtime.php", $params);
+ die();
+}
+
+/**
+ * Helper method to fetch all service endpoints that the user is eligible to
+ * view when neither the `se` (Service Endpoint) nor the `site` is provided,
+ * or when both are omitted. The portal will NOT perform pre-selections.
+ */
+function displayAllServiceEndpoints($user, $nowUtcDateTime)
+{
+ $ses = getAllServiceEndpoints($user);
+
+ if (empty($ses)) {
+ throwPermissionException(
+ "You don't hold a role over an NGI or site with child services.",
+ false
+ );
+ }
+
+ $params = [
+ 'ses' => $ses,
+ 'nowUtc' => $nowUtcDateTime->format('H:i T'),
+ 'userCannotPreSelect' => true
+ ];
+
+ show_view("downtime/add_downtime.php", $params);
+ die();
+}
+
+/**
+ * Retrieves all service endpoints based on user permissions.
+ *
+ * If the user is an admin, it returns all the service endpoints.
+ * If the user is NOT an admin, it returns the service endpoints
+ * based on the permissions.
+ */
+function getAllServiceEndpoints($user)
+{
+ if ($user->isAdmin()) {
+ return \Factory::getServiceService()->getAllSesJoinParentSites();
+ } else {
+ /**
+ * Get all ses where the user has a GRANTED role over one of its
+ * parent OwnedObjects (includes Site and NGI
+ * but not currently Project)
+ */
+ $sesAll = \Factory::getRoleService()
+ ->getReachableServicesFromOwnedObjectRoles($user);
+ $ses = filterServiceEndpoints($sesAll, $user);
+
+ return $ses;
+ }
+}
+
+// Filters service endpoints based on user's edit permissions.
+function filterServiceEndpoints($sesAll, $user)
+{
+ $ses = [];
+
+ foreach ($sesAll as $se) {
+ if (hasEditPermission($se->getParentSite(), $user)) {
+ $ses[] = $se;
}
- $params = array('ses' => $ses, 'nowUtc' => $nowUtcDateTime->format('H:i T'));
- show_view("downtime/add_downtime.php", $params);
- die();
}
+
+ return $ses;
+}
+
+// Validates if the user has edit permission for the given site.
+function hasEditPermission($site, $user)
+{
+ return \Factory::getRoleActionAuthorisationService()
+ ->authoriseAction(\Action::EDIT_OBJECT, $site, $user)
+ ->getGrantAction();
}
-?>
\ No newline at end of file
+/**
+ * Handles exceptions for permission-related issues.
+ *
+ * @throws \Exception
+ */
+function throwPermissionException($resource, $isGeneric)
+{
+ if ($isGeneric) {
+ $errorMsg = "You do not have permission over $resource";
+ } else {
+ $errorMsg = "$resource";
+ }
+
+ throw new \Exception($errorMsg);
+}
diff --git a/htdocs/web_portal/controllers/downtime/view_endpoint_tree.php b/htdocs/web_portal/controllers/downtime/view_endpoint_tree.php
index eb9f81946..99bf6e328 100644
--- a/htdocs/web_portal/controllers/downtime/view_endpoint_tree.php
+++ b/htdocs/web_portal/controllers/downtime/view_endpoint_tree.php
@@ -19,7 +19,18 @@
* limitations under the License.
*
/*====================================================== */
-function getServiceandEndpointList() {
+use Exception;
+
+/*
+ * This is to authenticate a request, lookup a user object by the
+ * user's principal ID, and determine if the user is an Admin or NOT.
+ *
+ * @return $params['portalIsReadOnly'] = BooleanValue
+ */
+function initAuthRequest()
+{
+ $params = [];
+
require_once __DIR__ . '/../utils.php';
require_once __DIR__ . '/../../../web_portal/components/Get_User_Principle.php';
@@ -27,36 +38,55 @@ function getServiceandEndpointList() {
$user = \Factory::getUserService()->getUserByPrinciple($dn);
$params['portalIsReadOnly'] = portalIsReadOnlyAndUserIsNotAdmin($user);
- if (!isset($_REQUEST['site_id']) || !is_numeric($_REQUEST['site_id']) ){
+ return $params;
+}
+
+function getServiceAndEndpointList()
+{
+ $params = initAuthRequest();
+
+ if (!isset($_REQUEST['site_id']) || !is_numeric($_REQUEST['site_id'])) {
throw new Exception("An id must be specified");
}
+ if (isset($_REQUEST['se'])) {
+ $params['se'] = $_REQUEST['se'];
+ }
+
$site = \Factory::getSiteService()->getSite($_REQUEST['site_id']);
$services = $site->getServices();
$params['services'] = $services;
+
show_view("downtime/view_nested_endpoints_list.php", $params, null, true);
}
-//This is a secondary function to handle the rendering of this page when editing the downtime
-function editDowntimePopulateEndpointTree() {
- require_once __DIR__ . '/../utils.php';
- require_once __DIR__ . '/../../../web_portal/components/Get_User_Principle.php';
-
- $dn = Get_User_Principle();
- $user = \Factory::getUserService()->getUserByPrinciple($dn);
- $params['portalIsReadOnly'] = portalIsReadOnlyAndUserIsNotAdmin($user);
+/**
+ * This is a secondary function to handle
+ * the rendering of this page when editing the downtime.
+ */
+function editDowntimePopulateEndpointTree()
+{
+ $params = initAuthRequest();
- if (!isset($_REQUEST['site_id']) || !is_numeric($_REQUEST['site_id']) ){
+ if (!isset($_REQUEST['site_id']) || !is_numeric($_REQUEST['site_id'])) {
throw new Exception("A site id must be specified");
}
- if (!isset($_REQUEST['dt_id']) || !is_numeric($_REQUEST['dt_id']) ){
+ if (!isset($_REQUEST['dt_id']) || !is_numeric($_REQUEST['dt_id'])) {
throw new Exception("A downtime id must be specified");
}
+
$site = \Factory::getSiteService()->getSite($_REQUEST['site_id']);
$services = $site->getServices();
$params['services'] = $services;
- $downtime = \Factory::getDowntimeService()->getDowntime($_REQUEST['dt_id']);
+ $downtime = \Factory::getDowntimeService()->getDowntime(
+ $_REQUEST['dt_id']
+ );
$params['downtime'] = $downtime;
- show_view("downtime/downtime_edit_view_nested_endpoints_list.php", $params, null, true);
-}
\ No newline at end of file
+ show_view(
+ "downtime/downtime_edit_view_nested_endpoints_list.php",
+ $params,
+ null,
+ true
+ );
+}
diff --git a/htdocs/web_portal/index.php b/htdocs/web_portal/index.php
index 6947b333c..ddef336be 100644
--- a/htdocs/web_portal/index.php
+++ b/htdocs/web_portal/index.php
@@ -373,7 +373,7 @@ function Draw_Page($Page_Type) {
case "Downtime_view_endpoint_tree":
rejectIfNotAuthenticated();
require_once __DIR__.'/controllers/downtime/view_endpoint_tree.php';
- getServiceandEndpointList();
+ getServiceAndEndpointList();
break;
case "Edit_Downtime_view_endpoint_tree":
rejectIfNotAuthenticated();
@@ -793,5 +793,3 @@ function redirect_view($logical_view = null, $absolute_view = null, $params = nu
header("Location: https://$host$uri/$path_params");
exit; // ensure no code gets executed after the redirect
}
-
-?>
diff --git a/htdocs/web_portal/views/downtime/add_downtime.php b/htdocs/web_portal/views/downtime/add_downtime.php
index 35508c0d2..ce62449b5 100644
--- a/htdocs/web_portal/views/downtime/add_downtime.php
+++ b/htdocs/web_portal/views/downtime/add_downtime.php
@@ -156,7 +156,14 @@ class="form-control" id="Select_Sites" name="select_sites" size="10"
$siteName = $site->getName();
$ngiName = $site->getNgi()->getName();
$label = xssafe($site." (".$ngiName.")");
- echo "";
+ echo "";
}
?>
@@ -231,7 +238,11 @@ class="form-control" id="Select_Sites" name="select_sites" size="10"
validate();
});
-
+ /**
+ * This will help us to decide whether to fetch
+ * and `select` all services, endpoints or NOT.
+ */
+ getSitesServices();
});
@@ -493,15 +504,44 @@ function validateUtcDates(){
return datesValid;
}
- function getSitesServices(){
+ function getSitesServices()
+ {
var siteId=$('#Select_Sites').val();
- if(siteId != null){ //If the user clicks on the box but not a specific row there will be no input, so catch that here
- $('#chooseEndpoints').empty(); //Remove any previous content from the endpoints select list
- $('#chooseServices').load('index.php?Page_Type=Downtime_view_endpoint_tree&site_id='+siteId,function( response, status, xhr ) {
- if ( status == "success" ) {
- validate();
- }
- });
+
+ /**
+ * If the user clicks on the box but not a specific row
+ * there will be no input, so catch that here.
+ */
+ if (siteId != null) {
+ // Remove any previous content from the endpoints select list.
+ $('#chooseEndpoints').empty();
+
+ let urlPath;
+ const SE_FROM_QUERY_PARAMS = new URL(
+ this.location.href
+ ).searchParams.get('se');
+
+ if (SE_FROM_QUERY_PARAMS) {
+ /**
+ * NOTE: If you use template literal for string interpolation,
+ * i.e., `${}`. It has to be in one line.
+ */
+ urlPath = 'index.php?Page_Type=Downtime_view_endpoint_tree' +
+ `&se=${SE_FROM_QUERY_PARAMS}` +
+ `&site_id=${siteId}`;
+ } else {
+ urlPath = `index.php?Page_Type=Downtime_view_endpoint_tree` +
+ `&site_id=${siteId}`;
+ }
+
+ $('#chooseServices').load(
+ urlPath,
+ function( response, status, xhr )
+ {
+ if ( status == "success" ) {
+ validate();
+ }
+ });
}
}
@@ -631,21 +671,3 @@ function getURLParameter(name) {
}*/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/htdocs/web_portal/views/downtime/view_nested_endpoints_list.php b/htdocs/web_portal/views/downtime/view_nested_endpoints_list.php
index bef7dcfe5..d5c335320 100644
--- a/htdocs/web_portal/views/downtime/view_nested_endpoints_list.php
+++ b/htdocs/web_portal/views/downtime/view_nested_endpoints_list.php
@@ -1,26 +1,68 @@
+
-