diff --git a/htdocs/web_portal/controllers/site/edit_api_auth.php b/htdocs/web_portal/controllers/site/edit_api_auth.php index e84c1b451..30398ee9f 100644 --- a/htdocs/web_portal/controllers/site/edit_api_auth.php +++ b/htdocs/web_portal/controllers/site/edit_api_auth.php @@ -1,10 +1,11 @@ getUserByPrinciple($dn); - //Check the portal is not in read only mode, returns exception if it is and user is not an admin + /** + * Check the portal is not in read only mode, + * returns exception if it is and user is not an admin + */ checkPortalIsNotReadOnlyOrUserIsAdmin($user); - if (!isset($_REQUEST['authentityid']) || !is_numeric($_REQUEST['authentityid']) ){ - throw new Exception("A authentication entity id must be specified in the url"); + if ( + !isset($_REQUEST['authentityid']) + || !is_numeric($_REQUEST['authentityid']) + ) { + throw new Exception( + "A authentication entity id must be specified in the url" + ); } $serv = \Factory::getSiteService(); @@ -47,48 +62,67 @@ function edit_entity() { // Validate the user has permission to edit properties if (!$serv->userCanEditSite($user, $site)) { - throw new \Exception("Permission denied: a site role is required to edit authentication entities at " . $site->getShortName()); + throw new Exception( + "Permission denied: a site role is required to edit " + . "authentication entities at " + . $site->getShortName() + ); } - if($_POST) { // If we receive a POST request it's to edit an authentication entity + // If we receive a POST request it's to edit an authentication entity + if ($_POST) { submit($user, $authEnt, $site, $serv); - } else { // If there is no post data, draw the edit authentication entity form + } else { + // If there is no post data, draw the edit authentication entity form draw($user, $authEnt, $site); } } -function draw(\User $user = null, \APIAuthentication $authEnt = null, \Site $site = null) { - if(is_null($user)){ - throw new Exception("Unregistered users can't edit authentication credentials"); +function draw( + \User $user = null, + \APIAuthentication $authEnt = null, + \Site $site = null +) { + if (is_null($user)) { + throw new Exception( + "Unregistered users can't edit authentication credentials" + ); } $params = array(); $params['site'] = $site; $params['authEnt'] = $authEnt; $params['authTypes'] = array(); - $params['authTypes'][]='X.509'; - $params['authTypes'][]='OIDC Subject'; + $params['authTypes'][] = 'X.509'; + $params['authTypes'][] = 'OIDC Subject'; $params['user'] = $user; show_view("site/edit_api_auth.php", $params); + die(); } -function submit(\User $user, \APIAuthentication $authEnt, \Site $site, org\gocdb\services\Site $serv) { +function submit( + \User $user, + \APIAuthentication $authEnt, + \Site $site, + org\gocdb\services\Site $serv +) { $newValues = getAPIAuthenticationFromWeb(); try { $authEnt = $serv->editAPIAuthEntity($authEnt, $user, $newValues); - } catch(Exception $e) { + } catch (Exception $e) { show_view('error.php', $e->getMessage()); + die(); } $params = array(); $params['apiAuthenticationEntity'] = $authEnt; $params['site'] = $site; - show_view("site/edited_api_auth.php", $params); - die(); + show_view("site/edited_api_auth.php", $params); + die(); } diff --git a/htdocs/web_portal/views/site/edit_api_auth.php b/htdocs/web_portal/views/site/edit_api_auth.php index 9663b898b..3806076fa 100644 --- a/htdocs/web_portal/views/site/edit_api_auth.php +++ b/htdocs/web_portal/views/site/edit_api_auth.php @@ -1,6 +1,5 @@
getUser(); @@ -9,7 +8,6 @@ echo(''); if (!is_null($entUser)) { - echo('

This credential is linked to GOCDB user '); echo('getFullname()); echo("'. Click the browser Back button to cancel the edit.

"); - } - - } else { - // This clause should be deleted or replaced with exception after all - // authentication entities are assigned a user. - echo('
'); - echo("WARNING: editing will link user '"); - xecho($user->getFullname()); - echo("' to this credential. Click the browser Back button to cancel the edit.
"); + } + } else { + /** + * This clause should be deleted or replaced with exception after + * all authentication entities are assigned a user. + */ + echo('
'); + echo("WARNING: editing will link user '"); + xecho($user->getFullname()); + echo( + "' to this credential. Click the browser Back button " + . "to cancel the edit.
" + ); } ?> -
+
- Identifier (e.g. Certificate DN or OIDC Subject)* - + + Identifier (e.g. Certificate DN or OIDC Subject)* + + +
+
Credential type* +
+
- WARNING: it is possible to delete information using the write functionality of the API. Leave Allow API write unchecked if + WARNING: it is possible to delete information using the write + functionality of the API. Leave Allow API write unchecked if you do not need to write data.
+
- getAllowAPIWrite()) { echo('checked="checked"');} + if ($params['authEnt']->getAllowAPIWrite()) { + echo('checked="checked"'); + } ?> /> - +
+
diff --git a/htdocs/web_portal/views/site/edited_api_auth.php b/htdocs/web_portal/views/site/edited_api_auth.php index 7e84ef18d..69782c257 100644 --- a/htdocs/web_portal/views/site/edited_api_auth.php +++ b/htdocs/web_portal/views/site/edited_api_auth.php @@ -1,7 +1,14 @@

Success


- The API authenication credential has now been updated. Type:getType()) ?>, identifier: getIdentifier()) ?>. + The API authenication credential has now been updated. + Type: getType()); ?>, + identifier: getIdentifier()); + ?>.
-
- View site + getID(); + ?>" + >View site
diff --git a/htdocs/web_portal/views/site/view_site.php b/htdocs/web_portal/views/site/view_site.php index 6c0a5b24c..9089bbcbe 100644 --- a/htdocs/web_portal/views/site/view_site.php +++ b/htdocs/web_portal/views/site/view_site.php @@ -1,6 +1,7 @@ getId(); @@ -12,174 +13,270 @@ ?>
- +
+
-

Site: getShortName()) ?>

- getOfficialName()) ?>
- getDescription()) ?> +

+ Site: getShortName()); ?> +

+ + + getOfficialName()); ?>
+ getDescription()); ?>
-
+
-
- - - -
- Admin
Delete
+
+ + + + +
+ Admin
Delete
+
- - -
-
- Edit +
+ +
+
+ Edit
- -
+
-
- +
+ Contact Info - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
E-Mail - - - getEmail()) ?> - - -
TelephonegetTelephone()); - } else { - echo(getInfoMessage()); - } - ?>
Emergency TelgetEmergencyTel()); - } else { - echo(getInfoMessage()); - } - ?>
CSIRT TelgetCsirtTel()); - } else { - echo(getInfoMessage()); - } - ?>
CSIRT E-Mail - - - getCsirtEmail()) ?> - - -
Emergency E-Mail - - - getEmergencyEmail()) ?> - - -
Helpdesk E-Mail - - - getHelpdeskEmail()) ?> - - -
Notifications - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
E-Mail + + + getEmail()); ?> + + +
Telephone + getTelephone()); + } else { + echo(getInfoMessage()); + } + ?> +
Emergency Tel + getEmergencyTel()); + } else { + echo(getInfoMessage()); + } + ?> +
CSIRT Tel + getCsirtTel()); + } else { + echo(getInfoMessage()); + } + ?> +
CSIRT E-Mail + + + getCsirtEmail()); ?> + + +
Emergency E-Mail + + + getEmergencyEmail()); ?> + + +
Helpdesk E-Mail + + + getHelpdeskEmail()); ?> + + +
Notifications + +
- + Project Data - + + + + + getNgi()->getName()); ?> + + + + @@ -188,28 +285,42 @@ $count = 0; $numScopes = sizeof($params['Scopes']); $scopeString = ''; - foreach ($params['Scopes'] as $scopeName => $sharedWithParent) { + + foreach ( + $params['Scopes'] as $scopeName => $sharedWithParent + ) { if ($sharedWithParent) { $scopeString .= $scopeName; } else { $scopeString .= $scopeName . '(x)'; } + if (++$count != $numScopes) { $scopeString .= ", "; } } ?> -
NGI/ROC - - getNgi()->getName()) ?> - -
Infrastructure getInfrastructure()->getName()) ?>
Certification Status - - getCertificationStatus()->getName()) ?> -   - - - Change - - + + getCertificationStatus()->getName()); + ?> +   + + + Change + +
- + " + > Scope Tags - +
@@ -218,59 +329,73 @@
- + Networking - + + - + + + + - + + + + + + +
Home URL - - - getHomeUrl()) ?> - - - + + + getHomeUrl()); ?> + + +
GIIS URL - getGiisUrl()); - } else { - echo(getInfoMessage()); - } - ?> + getGiisUrl()); + } else { + echo(getInfoMessage()); + } + ?>
IP Range - getIpRange()); - } else { - echo(getInfoMessage()); - } - ?> + getIpRange()); + } else { + echo(getInfoMessage()); + } + ?>
IP v6 RangeIP v6 Range - getIpV6Range()); - } else { - echo(getInfoMessage()); - } - ?> + getIpV6Range()); + } else { + echo(getInfoMessage()); + } + ?>
Domain @@ -288,64 +413,83 @@
- + Location - + + - + + - + + - + + - + + - +
Country - getCountry()->getName()); - } else { - echo getInfoMessage(); - } - ?> + Country + getCountry()->getName()); + } else { + echo getInfoMessage(); + } + ?>
Latitude - getLatitude()); - } else { - echo getInfoMessage(); - } - ?> + Latitude + getLatitude()); + } else { + echo getInfoMessage(); + } + ?>
Longitude - getLongitude()); - } else { - echo getInfoMessage(); - } - ?> + Longitude + getLongitude()); + } else { + echo getInfoMessage(); + } + ?>
Time Zone - getTimezoneId()); - } else { - echo getInfoMessage(); - } - ?> + Time Zone + getTimezoneId()); + } else { + echo getInfoMessage(); + } + ?>
Location - getLocation()); - } else { - echo getInfoMessage(); - } - ?> + Location + getLocation()); + } else { + echo getInfoMessage(); + } + ?>
@@ -359,55 +503,87 @@ $addPropertiesPage = "Add_Site_Properties"; $editPropertyPage = "Edit_Site_Property"; - require_once __DIR__ . '/../fragments/viewPropertiesTable.php'; ?> -
- - Services (Note, Service scope values marked with (x) indicate the Site does not share that scope) - - - - - - - - - - - - - - +
+ + Services (Note, Service scope values marked with (x) + indicate the Site does not share that scope) + + + +
Hostname (service type)URLProductionMonitoredScope Tags
+ + + + + + + + + + + - + + +
Hostname (service type)URLProductionMonitoredScope Tags
- - getHostname() . " (" . $se->getServiceType()->getName() . ")"); ?> + + getHostname() + . " (" + . $se->getServiceType()->getName() + . ")" + ); ?> getProduction()) { case true: - echo ''; + echo ''; break; case false: - echo ''; + echo ''; break; } ?> @@ -416,12 +592,14 @@ getMonitored()) { case true: - echo ''; + echo ''; break; case false: - echo ''; + echo ''; break; } ?> @@ -431,39 +609,51 @@ $count = 0; $numScopes = sizeof($scopes); $scopeString = ''; + foreach ($scopes as $scopeName => $sharedWithParent) { if ($sharedWithParent) { $scopeString .= $scopeName; } else { $scopeString .= $scopeName . '(x)'; } + if (++$count != $numScopes) { $scopeString .= ", "; } } ?> - -
- - + Add Service @@ -472,50 +662,77 @@ class="header"
-
+ getRoleType()->getName()); + ?> +
-
- - Recent Downtimes Affecting getShortName()) ?> Sevices and Endpoints - - (View all Downtimes) - +
+ + Recent Downtimes Affecting getShortName()); ?> + Sevices and Endpoints">(View all Downtimes) - + - +
@@ -546,6 +781,7 @@ class="person" + - getDescription()) ?> + href="index.php?Page_Type=Downtime&id=getId(); + ?>" + > + getDescription()); ?> - - + + - + + style="float: left; + padding-top: 0.9em; + padding-left: 1.2em; + padding-bottom: 0.9em;" + /> - Add Downtime + style="vertical-align: middle; + float: left; + padding-top: 1.1em; + padding-left: 1em; + padding-bottom: 0.9em;" + > + Add Downtime @@ -595,102 +859,180 @@ class="header" -
- +
+ Credentials authorised to use the GOCDB read and write APIs (Only shown if you have the relevant permissions) - -
DescriptionTo
getStartDate()->format('Y-m-d H:i'/*$dt::DATE_FORMAT*/)) ?>getEndDate()->format('Y-m-d H:i'/*$dt::DATE_FORMAT*/)) ?> + getStartDate() + ->format('Y-m-d H:i'/*$dt::DATE_FORMAT*/) + ); + ?> + + getEndDate() + ->format('Y-m-d H:i'/*$dt::DATE_FORMAT*/) + ); + ?> +
+ + +
- + + getIdentifier() == Get_User_Principle()) { - // If the owning user is making the request, we always allow them to - // delete the credential + + if ( + $APIAuthEnt->getIdentifier() == Get_User_Principle() + ) { + /** + * If the owning user is making the request, + * we always allow them to delete the credential + */ $disableDelete = false; } ?> - - + @@ -701,33 +1043,41 @@ class="header" - + + style="float: left; + padding-top: 0.9em; + padding-left: 1.2em; + padding-bottom: 0.9em;" + /> + style="vertical-align: middle; + float: left; + padding-top: 1.1em; + padding-left: 1em; + padding-bottom: 0.9em;" + > Add API credential - - - diff --git a/lib/Gocdb_Services/APIAuthenticationService.php b/lib/Gocdb_Services/APIAuthenticationService.php index 79a73ddc2..1ec986270 100644 --- a/lib/Gocdb_Services/APIAuthenticationService.php +++ b/lib/Gocdb_Services/APIAuthenticationService.php @@ -30,6 +30,7 @@ use Doctrine\ORM\QueryBuilder; use org\gocdb\services\Validate; +use Exception; class APIAuthenticationService extends AbstractEntityService { @@ -39,20 +40,24 @@ public function __construct() } /** - * Returns the APIAuthentication entity associated with the given identifier. + * Returns the APIAuthentication entity + * associated with the given identifier. * * @param string $ident Identifier (e.g. X.509 DN as string) - * @return \APIAuthentication[] APIAuthentication associated with this identifier + * + * @return \APIAuthentication[] APIAuthentication associated + * with this identifier */ public function getAPIAuthentication($ident) { - if (!is_string($ident)) { - throw new \LogicException("Expected string APIAuthentication identifier."); + throw new \LogicException( + "Expected string APIAuthentication identifier." + ); } - $dql = "SELECT a FROM APIAuthentication a " . - "WHERE (a.identifier = :ident)" ; + $dql = "SELECT a FROM APIAuthentication a " + . "WHERE (a.identifier = :ident)" ; /* @var $qry \Doctine\DBAL\query */ $qry = $this->em->createQuery($dql); @@ -63,35 +68,40 @@ public function getAPIAuthentication($ident) return $apiAuths; } - /** - * Update the fields of an APIAuthentication entity and commit the resulting entity + /** + * Update the fields of an APIAuthentication entity + * and commit the resulting entity * * @param \Site Parent site * @param \User Owning user * @param array Array containing new values + * * @throws \Exception on error with commit rolled back * @return \APIAuthentication */ public function addAPIAuthentication(\Site $site, \User $user, $newValues) { - $identifier = $newValues['IDENTIFIER']; $type = $newValues['TYPE']; $allowWrite = $newValues['ALLOW_WRITE']; - //Check that an identifier has been provided + // Check that an identifier has been provided if (empty($identifier)) { - throw new \Exception("A value must be provided for the identifier"); + throw new Exception( + "A value must be provided for the identifier" + ); } - //validate the values against the schema + // validate the values against the schema $this->validate($newValues, $identifier, $type); - - //Check there isn't already a credential with that identifier for that Site + /** + * Check there isn't already a credential + * with that identifier for that Site + */ $this->uniqueAPIAuthEnt($site, $identifier); - //Add the properties $this->em->getConnection()->beginTransaction(); + try { $authEnt = new \APIAuthentication(); $authEnt->setIdentifier($identifier); @@ -108,6 +118,7 @@ public function addAPIAuthentication(\Site $site, \User $user, $newValues) } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } @@ -115,22 +126,27 @@ public function addAPIAuthentication(\Site $site, \User $user, $newValues) } /** - * Update the fields of an APIAuthentication entity and commit the resulting entity + * Update the fields of an APIAuthentication entity + * and commit the resulting entity * * @param \APIAuthentication Entity to delete + * * @throws \Exception on error with commit rolled back */ public function deleteAPIAuthentication(\APIAuthentication $authEntity) { - $this->em->getConnection()->beginTransaction(); $parentSite = $authEntity->getParentSite(); $user = $authEntity->getUser(); try { - //Remove the authentication entity from the site then remove the entity - $parentSite->getAPIAuthenticationEntities()->removeElement($authEntity); + /** + * Remove the authentication entity from + * the site then remove the entity + */ + $parentSite->getAPIAuthenticationEntities() + ->removeElement($authEntity); $user->getAPIAuthenticationEntities()->removeElement($authEntity); $this->em->remove($authEntity); @@ -143,41 +159,53 @@ public function deleteAPIAuthentication(\APIAuthentication $authEntity) } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } } - /** - * Update the fields of an APIAuthentication entity and commit the resulting entity + /** + * Update the fields of an APIAuthentication entity + * and commit the resulting entity * * @param \APIAuthentication Entity to update * @param \User Owning user * @param array Array containing new values - * @throws \Exception on error with commit rolled back + * + * @throws Exception on error with commit rolled back * @return \APIAuthentication */ - public function editAPIAuthentication(\APIAuthentication $authEntity, \User $user, $newValues) - { - + public function editAPIAuthentication( + \APIAuthentication $authEntity, + \User $user, + $newValues + ) { $identifier = $newValues['IDENTIFIER']; $type = $newValues['TYPE']; $allowWrite = $newValues['ALLOW_WRITE']; - //Check that an identifier ha been provided + // Check that an identifier ha been provided if (empty($identifier)) { - throw new \Exception("A value must be provided for the identifier"); + throw new Exception( + "A value must be provided for the identifier" + ); } - //validate the values against the schema + // validate the values against the schema $this->validate($newValues, $identifier, $type); - //Edit the property + // Edit the property $this->em->getConnection()->beginTransaction(); + try { - // This would probably be the place hook for any future policy acceptance tracking + /** + * This would probably be the place hook + * for any future policy acceptance tracking + */ if ($user->getId() != $authEntity->getUser()) { $authEntity->setLastRenewTime(); } + $authEntity->setIdentifier($identifier); $authEntity->setType($type); $authEntity->setAllowAPIWrite($allowWrite); @@ -191,13 +219,16 @@ public function editAPIAuthentication(\APIAuthentication $authEntity, \User $use } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } } + /** * Set the last use time field to the current UTC time * * @param \APIAuthentication[] $authEntities entity to update + * * @throws \Exception if the update fails */ public function updateLastUseTime(array $authEntities) @@ -216,9 +247,11 @@ public function updateLastUseTime(array $authEntities) } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } } + /** * Fail if there is already an API credential with a given identifier * for a given Site. @@ -228,22 +261,23 @@ public function updateLastUseTime(array $authEntities) * * @param \Site $site field values for an APIAuthentication object * @param string $identifier to check - * @throws \Exception if the data can't be validated. + * + * @throws Exception if the data can't be validated. */ public function uniqueAPIAuthEnt(\Site $site, $identifier) { - $authEntities = $this->getAPIAuthentication($identifier); foreach ($authEntities as $authEnt) { if ($authEnt->getParentSite()->getId() == $site->getId()) { - throw new \Exception( - "An authentication credential with identifier " . - "\"$identifier\" already exists for " . $site->getName() + throw new Exception( + "An authentication credential with identifier " + . "\"$identifier\" already exists for " . $site->getName() ); } } } + /** * Validates the user inputted site data against the * checks in the gocdb_schema.xml and applies additional logic checks @@ -251,32 +285,55 @@ public function uniqueAPIAuthEnt(\Site $site, $identifier) * * @param array $data field values for an APIAuthentication object * @param mixed $type a valid - * @throws \Exception if the data can't be validated. + * + * @throws Exception if the data can't be validated. * @return null */ private function validate($data, $identifier, $type) { - $serv = new Validate(); + foreach ($data as $field => $value) { $valid = $serv->validate('APIAUTHENTICATION', $field, $value); + if (!$valid) { $error = "$field contains an invalid value: $value"; - throw new \Exception($error); + + throw new Exception($error); } } - //If the entity is of type X.509, do a more thorough check than the validate service (as we know the type) - //Note that we are allowing ':' as they can appear in robot DN's - if ($type == 'X.509' && !preg_match("/^(\/[A-Za-z]+=[a-zA-Z0-9\/\-\_\s\.,'@:\/]+)*$/", $identifier)) { - throw new \Exception("Invalid X.509 DN"); + + /** + * If the entity is of type X.509, do a more thorough + * check than the validate service (as we know the type) + * + * Note that we are allowing ':' as they can appear in robot DN's + */ + if ( + $type == 'X.509' + && !preg_match( + "/^(\/[A-Za-z]+=[a-zA-Z0-9\/\-\_\s\.,'@:\/]+)*$/", + $identifier + ) + ) { + throw new Exception("Invalid X.509 DN"); } - //If the entity is of type OIDC subject, do a more thorough check again + /** + * If the entity is of type OIDC subject, + * do a more thorough check again + */ if ( - $type == 'OIDC Subject' && - !preg_match("/^([a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12})$/", $identifier) + $type == 'OIDC Subject' + && !preg_match( + ( + "/^([a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}" + . "\-[a-f0-9]{4}\-[a-f0-9]{12})$/" + ), + $identifier + ) ) { - throw new \Exception("Invalid OIDC Subject"); + throw new Exception("Invalid OIDC Subject"); } } } diff --git a/lib/Gocdb_Services/Site.php b/lib/Gocdb_Services/Site.php index ecced35d4..b2030325c 100644 --- a/lib/Gocdb_Services/Site.php +++ b/lib/Gocdb_Services/Site.php @@ -1,5 +1,9 @@ roleActionAuthorisationService = $roleActionAuthorisationService; - //$this->scopeService = $scopeService; $this->configService = \Factory::getConfigService(); } /** * Set class dependency (REQUIRED). * @todo Mandatory objects should be injected via constructor. - * @param \org\gocdb\services\RoleActionAuthorisationService $roleActionAuthService + * + * @param \org\gocdb\services\RoleActionAuthorisationService + * $roleActionAuthService */ - public function setRoleActionAuthorisationService(RoleActionAuthorisationService $roleActionAuthService){ + public function setRoleActionAuthorisationService( + RoleActionAuthorisationService $roleActionAuthService + ) { $this->roleActionAuthorisationService = $roleActionAuthService; } /** * Set class dependency (REQUIRED). * @todo Mandatory objects should be injected via constructor. + * * @param \org\gocdb\services\Scope $scopeService */ - public function setScopeService(Scope $scopeService){ + public function setScopeService(Scope $scopeService) + { $this->scopeService = $scopeService; } @@ -71,15 +80,19 @@ public function setScopeService(Scope $scopeService){ /** * Finds a single site by ID and returns its entity + * * @param int $id the site ID + * * @return \Site a site object */ - public function getSite($id) { + public function getSite($id) + { $dql = "SELECT s FROM Site s WHERE s.id = :id"; $site = $this->em - ->createQuery($dql) - ->setParameter('id', $id) - ->getSingleResult(); + ->createQuery($dql) + ->setParameter('id', $id) + ->getSingleResult(); + return $site; } @@ -122,24 +135,36 @@ public function getSite($id) { * * [COBJECTID] => 706 * ) + * * @param Site $site The site entity to be updated * @param array $newValues Array of updated site data, specified above. * @param org\gocdb\services\User $user The current user - * return Site The updated site entity + * + * @return Site $site The updated site entity */ - function editSite(\Site $site, $newValues, \User $user = null) { - //Check the portal is not in read only mode, throws exception if it is + function editSite(\Site $site, $newValues, \User $user = null) + { + // Check the portal is not in read only mode, throws exception if it is $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); - if($user == null){ - throw new \Exception("Null user can't edit site"); + if ($user == null) { + throw new Exception("Null user can't edit site"); } + // Check to see whether the user has a role that covers this site - //$this->edit Authorization($site, $user); - //if(count($this->authorize Action(\Action::EDIT_OBJECT, $site, $user))==0){ - if($this->roleActionAuthorisationService->authoriseAction( - \Action::EDIT_OBJECT, $site, $user)->getGrantAction()==FALSE){ - throw new \Exception("You don't have permission over ". $site->getShortName()); + if ( + ( + $this->roleActionAuthorisationService + ->authoriseAction( + \Action::EDIT_OBJECT, + $site, + $user + )->getGrantAction() + ) == false + ) { + throw new Exception( + "You don't have permission over " . $site->getShortName() + ); } $this->validate($newValues['Site'], 'site'); @@ -148,46 +173,76 @@ function editSite(\Site $site, $newValues, \User $user = null) { // EDIT SCOPE TAGS: // collate selected scopeIds (reserved and non-reserved) $scopeIdsToApply = array(); - foreach($newValues['Scope_ids'] as $sid){ + + foreach ($newValues['Scope_ids'] as $sid) { $scopeIdsToApply[] = $sid; } - foreach($newValues['ReservedScope_ids'] as $sid){ + + foreach ($newValues['ReservedScope_ids'] as $sid) { $scopeIdsToApply[] = $sid; } - $selectedScopesToApply = $this->scopeService->getScopes($scopeIdsToApply); - - // If not admin, Check user edits to the site's Reserved scopes: - // Required to prevent users manually crafting a POST request in an attempt - // to select reserved scopes, this is unlikely but it is a possible hack. - // Site can only have reserved tags that are already assigned or assigned to the parent. - if (!$user->isAdmin()) { - $selectedReservedScopes = $this->scopeService->getScopesFilterByParams( - array('excludeNonReserved' => true), $selectedScopesToApply); - $existingReservedScopes = $this->scopeService->getScopesFilterByParams( - array('excludeNonReserved' => true), $site->getScopes()->toArray()); + $selectedScopesToApply = $this->scopeService + ->getScopes($scopeIdsToApply); - $existingReservedScopesParent = $this->scopeService->getScopesFilterByParams( - array('excludeNonReserved' => true), $site->getNgi()->getScopes()->toArray()); - - foreach($selectedReservedScopes as $sc){ + /** + * If not admin, Check user edits to the site's Reserved scopes: + * + * Required to prevent users manually + * crafting a POST request in an attempt to select reserved scopes, + * this is unlikely but it is a possible hack. + * + * Site can only have reserved tags that are already assigned + * or assigned to the parent. + */ + if (!$user->isAdmin()) { + $selectedReservedScopes = $this->scopeService + ->getScopesFilterByParams( + array('excludeNonReserved' => true), + $selectedScopesToApply + ); + + $existingReservedScopes = $this->scopeService + ->getScopesFilterByParams( + array('excludeNonReserved' => true), + $site->getScopes()->toArray() + ); + + $existingReservedScopesParent = $this->scopeService + ->getScopesFilterByParams( + array('excludeNonReserved' => true), + $site->getNgi()->getScopes()->toArray() + ); + + foreach ($selectedReservedScopes as $sc) { // Reserved scopes must already be assigned to site or parent - if(!in_array($sc, $existingReservedScopes) && !in_array($sc, $existingReservedScopesParent)){ - throw new \Exception("A reserved Scope Tag was selected that is " - . "not assigned to the Site or to the Parent NGI"); + if ( + !in_array($sc, $existingReservedScopes) + && !in_array($sc, $existingReservedScopesParent) + ) { + throw new Exception( + "A reserved Scope Tag was selected that is " + . "not assigned to the Site or to the Parent NGI" + ); } } } - //check there are the required number of optional scopes specified - $this->checkNumberOfScopes($this->scopeService->getScopesFilterByParams( - array('excludeReserved' => true), $selectedScopesToApply)); + // Check there are the required number of optional scopes specified + $this->checkNumberOfScopes( + $this->scopeService->getScopesFilterByParams( + array('excludeReserved' => true), + $selectedScopesToApply + ) + ); // check childServiceScopeAction is a known value - if($newValues['childServiceScopeAction'] != 'noModify' && - $newValues['childServiceScopeAction'] != 'inherit' && - $newValues['childServiceScopeAction'] != 'override' ){ - throw new \Exception("Invalid scope update action"); + if ( + $newValues['childServiceScopeAction'] != 'noModify' + && $newValues['childServiceScopeAction'] != 'inherit' + && $newValues['childServiceScopeAction'] != 'override' + ) { + throw new Exception("Invalid scope update action"); } // Replace lat/long with null if no value entered @@ -195,6 +250,7 @@ function editSite(\Site $site, $newValues, \User $user = null) { $this->emptyStringToNull($newValues['Site']['LONGITUDE']); $this->em->getConnection()->beginTransaction(); + try { // Set the site's member variables $site->setOfficialName($newValues['Site']['OFFICIAL_NAME']); @@ -218,41 +274,56 @@ function editSite(\Site $site, $newValues, \User $user = null) { $site->setHelpdeskEmail($newValues['Site']['HELPDESKEMAIL']); $site->setTimezoneId($newValues['Site']['TIMEZONE']); - //Set notify flag for site - if (!isset($newValues['NOTIFY'])){ + if (!isset($newValues['NOTIFY'])) { $notify = false; - } - elseif ($newValues['NOTIFY'] == "Yes") { + } elseif ($newValues['NOTIFY'] == "Yes") { $notify = true; } else { $notify = false; } - $site->setNotify ($notify); + + $site->setNotify($notify); // update the target infrastructure $dql = "SELECT i FROM Infrastructure i WHERE i.name = :name"; - $inf = $this->em->createQuery($dql)->setParameter('name', $newValues['ProductionStatus'])->getSingleResult(); + $inf = $this->em->createQuery($dql) + ->setParameter( + 'name', + $newValues['ProductionStatus'] + )->getSingleResult(); $site->setInfrastructure($inf); // Update the site's scope // firstly remove all existing scope links $scopes = $site->getScopes(); - foreach($scopes as $s) { + + foreach ($scopes as $s) { $site->removeScope($s); } // Link the requested scopes to the site - foreach($selectedScopesToApply as $scope){ + foreach ($selectedScopesToApply as $scope) { $site->addScope($scope); } - // Remove reserved scopes from child services that are not applied on site - $siteReservedScopes = $this->scopeService->getScopesFilterByParams( - array('excludeNonReserved' => true), $site->getScopes()->toArray()); + /** + * Remove reserved scopes from child + * services that are not applied on site + */ + $siteReservedScopes = $this->scopeService + ->getScopesFilterByParams( + array('excludeNonReserved' => true), + $site->getScopes()->toArray() + ); + foreach ($site->getServices() as $service) { - $serviceReservedScopes = $this->scopeService->getScopesFilterByParams( - array('excludeNonReserved' => true), $service->getScopes()->toArray()); + $serviceReservedScopes = $this->scopeService + ->getScopesFilterByParams( + array('excludeNonReserved' => true), + $service->getScopes()->toArray() + ); + foreach ($serviceReservedScopes as $seReservedScope) { if (!in_array($seReservedScope, $siteReservedScopes)) { $service->removeScope($seReservedScope); @@ -262,45 +333,47 @@ function editSite(\Site $site, $newValues, \User $user = null) { // Optionally update the child service scopes - if($newValues['childServiceScopeAction'] == 'noModify'){ + if ($newValues['childServiceScopeAction'] == 'noModify') { // do nothing to child service scopes, leave intact - } else if($newValues['childServiceScopeAction'] == 'inherit'){ + } elseif ($newValues['childServiceScopeAction'] == 'inherit') { // iterate each child service and ensure it has all the site scopes $services = $site->getServices(); - /* @var $service \Service */ - foreach($services as $service){ + + foreach ($services as $service) { // for this service, see if it has each siteScope, if not add it - foreach($site->getScopes() as $siteScope){ + foreach ($site->getScopes() as $siteScope) { $addScope = true; - foreach($service->getScopes() as $servScope){ - if($siteScope == $servScope){ + + foreach ($service->getScopes() as $servScope) { + if ($siteScope == $servScope) { $addScope = false; break; } } - if($addScope){ - $service->addScope($siteScope); + + if ($addScope) { + $service->addScope($siteScope); } } } - } else if($newValues['childServiceScopeAction'] == 'override'){ + } elseif ($newValues['childServiceScopeAction'] == 'override') { // force child service scopes to be same as site $services = $site->getServices(); - /* @var $service \Service */ - foreach($services as $service){ + + foreach ($services as $service) { // remove all service's existing scopes - foreach($service->getScopes() as $servScope){ + foreach ($service->getScopes() as $servScope) { $service->removeScope($servScope); } + // add all site scopes - foreach($site->getScopes() as $siteScope){ + foreach ($site->getScopes() as $siteScope) { $service->addScope($siteScope); } } - } else { - throw new \Exception("Invalid scope update action"); + throw new Exception("Invalid scope update action"); } // get / set the country @@ -313,15 +386,16 @@ function editSite(\Site $site, $newValues, \User $user = null) { $this->em->merge($site); $this->em->flush(); $this->em->getConnection()->commit(); - } catch(\Exception $ex){ + } catch (\Exception $ex) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $ex; } + return $site; } - /** * Validates the user inputted site data against the * checks in the gocdb_schema.xml and applies additional logic checks @@ -329,36 +403,46 @@ function editSite(\Site $site, $newValues, \User $user = null) { * * @param array $siteData containing all the fields for a GOCDB_SITE * object - * @throws \Exception if the site data can't be + * @throws Exception if the site data can't be * validated. The \Exception message will contain a human * readable description of which field failed validation. * @return null */ - private function validate($siteData, $type) { - require_once __DIR__.'/Validate.php'; + private function validate($siteData, $type) + { + require_once __DIR__ . '/Validate.php'; + $serv = new \org\gocdb\services\Validate(); - foreach($siteData as $field => $value) { + + foreach ($siteData as $field => $value) { $valid = $serv->validate($type, $field, $value); - if(!$valid) { + + if (!$valid) { $error = "$field contains an invalid value: $value"; - throw new \Exception($error); + throw new Exception($error); } } - // Apply additional logic for validation that can't be captured solely using gocdb_schema.xml + /** + * Apply additional logic for validation that can't + * be captured solely using gocdb_schema.xml + */ if (!empty($siteData['IP_V6_RANGE'])) { - require_once __DIR__.'/validation/IPv6Validator.php'; + require_once __DIR__ . '/validation/IPv6Validator.php'; + $validator = new \IPv6Validator(); $errors = array(); $errors = $validator->validate($siteData['IP_V6_RANGE'], $errors); + if (count($errors) > 0) { - throw new \Exception($errors[0]); // show the first message. + throw new Exception($errors[0]); // show the first message. } } } // Replaces empty string with null - private function emptyStringToNull(&$var) { + private function emptyStringToNull(&$var) + { if ($var === '') { $var = null; } @@ -372,51 +456,68 @@ private function emptyStringToNull(&$var) { * 'sitename' => String site name * 'roc' => String name of parent NGI/ROC * 'country' => String country name - * 'certification_status' => String certification status value e.g. 'Certified' - * 'exclude_certification_status' => String exclude sites with this certification status + * 'certification_status' => String certification + * status value e.g. 'Certified' + * 'exclude_certification_status' => String exclude + * sites with this certification status * 'production_status' => String site production status value * 'scope' => 'String,comma,sep,list,of,scopes,e.g.,egi,wlcg' * 'scope_match' => String 'any' or 'all' - * 'extensions' => String extensions expression to filter custom key=value pairs + * 'extensions' => String extensions expression + * to filter custom key=value pairs * * @param array $filterParams + * * @return array Site array */ - public function getSitesFilterByParams($filterParams){ - require_once __DIR__.'/PI/GetSite.php'; + public function getSitesFilterByParams($filterParams) + { + require_once __DIR__ . '/PI/GetSite.php'; + $getSite = new GetSite($this->em); $getSite->validateParameters($filterParams); $getSite->createQuery(); $sites = $getSite->executeQuery(); + return $sites; } - /** * Returns all Sites filtered by the given parameters with the following * joined relations: CertificationStatus, Scope, NGI, Infrastructure. * - * Sites are matched using SQL 'like' statements so you can for e.g. specify - * $ngiName = '%_ngi' to select all Sites whose parent NGI's name ends in '_ngi'. - * All parametes are nullable. Null params are not used for filtering results. + * Sites are matched using SQL 'like' + * statements so you can for e.g. specify + * $ngiName = '%_ngi' to select all Sites whose parent + * NGI's name ends in '_ngi'. + * All parametes are nullable. Null params are + * not used for filtering results. * * @param string $ngiName NGI name - * @param string $prodStatus Production status/target infrastructure, usually Test or Production - * @param string $certStatus Certification status value (Certified, Uncertified, Candidate, Suspended, Closed) + * @param string $prodStatus Production status/target infrastructure, + * usually Test or Production + * @param string $certStatus Certification status value (Certified, + * Uncertified, Candidate, Suspended, Closed) * @param string $scopeName Name of a scope value * @param boolean $showClosed true or false * @param integer $siteId Site id or null * @param string $siteExtPropKeyName Site extension property name * @param string $siteExtPropKeyValue Site extension property value * @param string $apiAuthId Authentication entity identifier + * * @return array An array of site objects with joined entities. */ public function getSitesBy( - $ngiName=NULL, $prodStatus=NULL, $certStatus=NULL, - $scopeName=NULL, $showClosed=NULL, $siteId=NULL, - $siteExtPropKeyName=NULL, $siteExtPropKeyValue=NULL, - $apiAuthId=NULL) { - + $ngiName = null, + $prodStatus = null, + $certStatus = null, + $scopeName = null, + $showClosed = null, + $siteId = null, + $siteExtPropKeyName = null, + $siteExtPropKeyValue = null, + $apiAuthId = null + ) { $qb = $this->em->createQueryBuilder(); $qb ->select('DISTINCT s', 'sc', 'n', 'i') ->from('Site', 's') @@ -426,61 +527,67 @@ public function getSitesBy( ->leftjoin('s.infrastructure', 'i') ->orderBy('s.shortName'); - if($scopeName != null && $scopeName != '%%'){ + if ($scopeName != null && $scopeName != '%%') { $qb->andWhere($qb->expr()->like('sc.name', ':scope')) ->setParameter(':scope', $scopeName); } - if($ngiName != null && $ngiName != '%%'){ + if ($ngiName != null && $ngiName != '%%') { $qb->andWhere($qb->expr()->like('n.name', ':ngi')) ->setParameter(':ngi', $ngiName); } - if($prodStatus != null && $prodStatus != '%%'){ + if ($prodStatus != null && $prodStatus != '%%') { $qb->andWhere($qb->expr()->like('i.name', ':prodStatus')) ->setParameter(':prodStatus', $prodStatus); } - if($certStatus != null && $certStatus != '%%'){ + if ($certStatus != null && $certStatus != '%%') { $qb ->andWhere($qb->expr()->like('cs.name', ':certStatus')) ->setParameter(':certStatus', $certStatus); } - if($siteId != null && $siteId != '%%'){ + if ($siteId != null && $siteId != '%%') { $qb->andWhere($qb->expr()->like('s.id', ':siteId')) ->setParameter(':siteId', $siteId); } - if($showClosed != 1){ - $qb->andWhere( $qb->expr()->not($qb->expr()->like('cs.name', ':closed'))) - ->setParameter(':closed', 'Closed'); + if ($showClosed != 1) { + $qb->andWhere( + $qb->expr()->not( + $qb->expr()->like( + 'cs.name', + ':closed' + ) + ) + )->setParameter(':closed', 'Closed'); } - if($siteExtPropKeyName != null && $siteExtPropKeyName != '%%'){ - if($siteExtPropKeyValue == null || $siteExtPropKeyValue == ''){ - $siteExtPropKeyValue='%%'; + if ($siteExtPropKeyName != null && $siteExtPropKeyName != '%%') { + if ($siteExtPropKeyValue == null || $siteExtPropKeyValue == '') { + $siteExtPropKeyValue = '%%'; } $sQ = $this->em->createQueryBuilder(); - $sQ ->select('s1'.'.id') - ->from('Site', 's1') - ->join('s1.siteProperties', 'sp') - ->andWhere($sQ->expr()->andX( + $sQ->select('s1' . '.id') + ->from('Site', 's1') + ->join('s1.siteProperties', 'sp') + ->andWhere($sQ->expr()->andX( $sQ->expr()->eq('sp.keyName', ':keyname'), - $sQ->expr()->like('sp.keyValue', ':keyvalue'))); - - $qb ->andWhere($qb->expr()->in('s', $sQ->getDQL())); - $qb ->setParameter(':keyname', $siteExtPropKeyName) - ->setParameter(':keyvalue', $siteExtPropKeyValue); + $sQ->expr()->like('sp.keyValue', ':keyvalue') + )); + $qb->andWhere($qb->expr()->in('s', $sQ->getDQL())); + $qb->setParameter(':keyname', $siteExtPropKeyName) + ->setParameter(':keyvalue', $siteExtPropKeyValue); } if ($apiAuthId != null && $apiAuthId != '%%') { $sQ = $this->em->createQueryBuilder(); - $sQ ->select('s1'.'.id') - ->from('Site', 's1') - ->join('s1.APIAuthenticationEntities', 'authEnt') - ->andWhere($sQ->expr()->eq('authEnt.identifier', ':authid')); + $sQ->select('s1' . '.id') + ->from('Site', 's1') + ->join('s1.APIAuthenticationEntities', 'authEnt') + ->andWhere($sQ->expr()->eq('authEnt.identifier', ':authid')); $qb->andWhere($qb->expr()->in('s', $sQ->getDQL())); $qb->setParameter('authid', $apiAuthId); @@ -495,81 +602,108 @@ public function getSitesBy( /** * @return array of all properties for a site */ - public function getProperties($id) { + public function getProperties($id) + { $dql = "SELECT p FROM SiteProperty p WHERE p.parentSite = :ID"; - $properties = $this->em->createQuery ( $dql )->setParameter ( 'ID', $id )->getOneOrNullResult (); + $properties = $this->em->createQuery($dql) + ->setParameter( + 'ID', + $id + )->getOneOrNullResult(); + return $properties; } /** * @return a single site property */ - public function getProperty($id) { + public function getProperty($id) + { $dql = "SELECT p FROM SiteProperty p WHERE p.id = :ID"; - $property = $this->em->createQuery ( $dql )->setParameter ( 'ID', $id )->getOneOrNullResult (); + $property = $this->em->createQuery($dql) + ->setParameter( + 'ID', + $id + )->getOneOrNullResult(); + return $property; } /** * @return \SiteProperty a single site property */ - public function getPropertyByKeyAndParent($key, $parentSite) { + public function getPropertyByKeyAndParent($key, $parentSite) + { $parentSiteID = $parentSite->getId(); - $dql = "SELECT p FROM SiteProperty p WHERE p.keyName = :KEY AND p.parentSite = :PARENTSITEID"; + $dql = "SELECT p FROM SiteProperty p WHERE p.keyName = :KEY " + . "AND p.parentSite = :PARENTSITEID"; $property = $this->em - ->createQuery ($dql) - ->setParameter ('KEY', $key) - ->setParameter ('PARENTSITEID', $parentSiteID) - ->getOneOrNullResult (); + ->createQuery($dql) + ->setParameter('KEY', $key) + ->setParameter('PARENTSITEID', $parentSiteID) + ->getOneOrNullResult(); + return $property; } /** * @return array of NGIs */ - public function getNGIs() { + public function getNGIs() + { $dql = "SELECT n from NGI n"; $ngis = $this->em ->createQuery($dql) ->getResult(); + return $ngis; } /** - * Returns all certification statues in GOCDB - * @return array An array of CertificationStatus objects + * Returns all certification statues in GOCDB + * + * @return array An array of CertificationStatus objects */ - public function getCertStatuses() { + public function getCertStatuses() + { $dql = "SELECT c from CertificationStatus c"; $certStatuses = $this->em ->createQuery($dql) ->getResult(); + return $certStatuses; } /** * Return all production statuses in the DB + * * @return Array an array of ProductionStatus objects */ - public function getProdStatuses() { + public function getProdStatuses() + { $dql = "SELECT i from Infrastructure i"; $prodStatuses = $this->em ->createQuery($dql) ->getResult(); + return $prodStatuses; } /** * Return doctrine production status entity from name - * @return production status with sepcified name, throws error if multiple results + * + * @return production status with sepcified name, + * throws error if multiple results */ - public function getProdStatusByName($name) { + public function getProdStatusByName($name) + { $dql = "SELECT i from Infrastructure i WHERE i.name = :Name"; $prodStatuses = $this->em ->createQuery($dql) ->setParameter('Name', $name) ->getOneOrNullResult(); + return $prodStatuses; } @@ -577,25 +711,30 @@ public function getProdStatusByName($name) { * Return all countries in the DB * @return Array an array of Country objects */ - public function getCountries() { + public function getCountries() + { $dql = "SELECT c from Country c ORDER BY c.name"; $countries = $this->em - ->createQuery($dql) - ->getResult(); + ->createQuery($dql) + ->getResult(); + return $countries; } /** * Returns the downtimes linked to a site. * @param integer $id Site ID - * @param integer $dayLimit Limit to downtimes that are only $dayLimit old (can be null) */ - public function getDowntimes($id, $dayLimit) { - if($dayLimit != null) { - $di = \DateInterval::createFromDateString($dayLimit . 'days'); - $dayLimit = new \DateTime(); - $dayLimit->sub($di); - } + * @param integer $dayLimit Limit to downtimes that + * are only $dayLimit old (can be null) + */ + public function getDowntimes($id, $dayLimit) + { + if ($dayLimit != null) { + $di = \DateInterval::createFromDateString($dayLimit . 'days'); + $dayLimit = new \DateTime(); + $dayLimit->sub($di); + } $dql = "SELECT d FROM Downtime d WHERE d.id IN ( @@ -610,13 +749,13 @@ public function getDowntimes($id, $dayLimit) { ) ORDER BY d.startDate DESC"; - $downtimes = $this->em - ->createQuery($dql) - ->setParameter('siteId', $id) - ->setParameter('dayLimit', $dayLimit) - ->getResult(); + $downtimes = $this->em + ->createQuery($dql) + ->setParameter('siteId', $id) + ->setParameter('dayLimit', $dayLimit) + ->getResult(); - return $downtimes; + return $downtimes; } /** @@ -652,69 +791,107 @@ public function getDowntimes($id, $dayLimit) { * [NOTIFY] => Y * ) * ) + * * @param array $values New Site Values * @param \User $user User making the request */ - public function addSite($values, \User $user =null) { - //Check the portal is not in read only mode, throws exception if it is + public function addSite($values, \User $user = null) + { + /** + * Check the portal is not in read only mode, + * throws exception if it is + */ $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); - if(is_null($user)){ - throw new \Exception("Unregistered users may not add new sites"); + if (is_null($user)) { + throw new Exception( + "Unregistered users may not add new sites" + ); } // get the parent NGI entity - /* @var $parentNgi \NGI */ - $parentNgi = $this->em->createQuery("SELECT n FROM NGI n WHERE n.id = :id") - ->setParameter('id', $values['NGI']) - ->getSingleResult(); // throws NonUniqueResultException throws, NoResultException + // throws NonUniqueResultException throws, NoResultException + $parentNgi = $this->em + ->createQuery( + "SELECT n FROM NGI n WHERE n.id = :id" + )->setParameter( + 'id', + $values['NGI'] + )->getSingleResult(); - if(!$user->isAdmin()){ + if (!$user->isAdmin()) { // Check that user has permission to add site to the chosen NGI - if(!$this->roleActionAuthorisationService->authoriseAction( - \Action::NGI_ADD_SITE, $parentNgi, $user)->getGrantAction()){ - throw new \Exception("You do not have permission to add a new site to the selected NGI" - . " To add a new site you require a managing role over an NGI"); + if ( + !$this->roleActionAuthorisationService + ->authoriseAction( + \Action::NGI_ADD_SITE, + $parentNgi, + $user + )->getGrantAction() + ) { + throw new Exception( + "You do not have permission to add a new " + . "site to the selected NGI. " + . "To add a new site you require " + . "a managing role over an NGI" + ); } } - - // do as much validation before starting a new db tx - // check the site object data is valid + /** + * do as much validation before starting a new db tx + * check the site object data is valid + */ $this->validate($values['Site'], 'site'); $this->uniqueCheck($values['Site']['SHORT_NAME']); // ADD SCOPE TAGS: // collate selected reserved and non-reserved scopeIds $allSelectedScopeIds = array(); - foreach($values['Scope_ids'] as $sid){ + + foreach ($values['Scope_ids'] as $sid) { $allSelectedScopeIds[] = $sid; } - foreach($values['ReservedScope_ids'] as $sid){ + foreach ($values['ReservedScope_ids'] as $sid) { $allSelectedScopeIds[] = $sid; } - $selectedScopesToApply = $this->scopeService->getScopes($allSelectedScopeIds); + $selectedScopesToApply = $this->scopeService + ->getScopes($allSelectedScopeIds); - // If not admin, check that requested reserved scopes are already implemented by the parent NGI. - // Required to prevent users manually crafting a POST request in an attempt - // to select reserved scopes, this is unlikely but it is a possible hack. + /** + * If not admin, check that requested reserved scopes + * are already implemented by the parent NGI. + * + * Required to prevent users manually crafting + * a POST request in an attempt to select reserved scopes, + * this is unlikely but it is a possible hack. + */ if (!$user->isAdmin()) { - $selectedReservedScopes = $this->scopeService->getScopesFilterByParams( - array('excludeNonReserved' => true), $selectedScopesToApply); - - $existingReservedScopesParent = $this->scopeService->getScopesFilterByParams( - array('excludeNonReserved' => true), $parentNgi->getScopes()->toArray()); - - foreach($selectedReservedScopes as $sc){ + $selectedReservedScopes = $this->scopeService + ->getScopesFilterByParams( + array('excludeNonReserved' => true), + $selectedScopesToApply + ); + + $existingReservedScopesParent = $this->scopeService + ->getScopesFilterByParams( + array('excludeNonReserved' => true), + $parentNgi->getScopes()->toArray() + ); + + foreach ($selectedReservedScopes as $sc) { // Reserved scopes must already be assigned to parent - if(!in_array($sc, $existingReservedScopesParent)){ - throw new \Exception("A reserved Scope Tag was selected that is not assigned to the Parent NGI"); + if (!in_array($sc, $existingReservedScopesParent)) { + throw new Exception( + "A reserved Scope Tag was selected " + . "that is not assigned to the Parent NGI" + ); } } } - //check there are the required number of OPTIONAL scopes specified + // check there are the required number of OPTIONAL scopes specified $this->checkNumberOfScopes($values['Scope_ids']); // Replace lat/long with null if no value entered @@ -731,7 +908,10 @@ public function addSite($values, \User $user =null) { $this->em->getConnection()->beginTransaction(); $pk = new \PrimaryKey(); $this->em->persist($pk); - // flush synchronizes the in-memory state of managed objects with the database + /** + * flush synchronizes the in-memory state + * of managed objects with the database + */ // but we can still rollback $this->em->flush(); $site = new \Site(); @@ -757,15 +937,15 @@ public function addSite($values, \User $user =null) { $site->setTimezoneId($values['Site']['TIMEZONE']); //Set notify flag for site - if (!isset($values['NOTIFY'])){ + if (!isset($values['NOTIFY'])) { $notify = false; - } - elseif ($values['NOTIFY'] == "Yes") { + } elseif ($values['NOTIFY'] == "Yes") { $notify = true; } else { $notify = false; } - $site->setNotify ($notify); + + $site->setNotify($notify); // join the site to the parent NGI $site->setNgiDoJoin($parentNgi); @@ -773,15 +953,20 @@ public function addSite($values, \User $user =null) { // get the target infrastructure $dql = "SELECT i FROM Infrastructure i WHERE i.id = :id"; $inf = $this->em->createQuery($dql) - ->setParameter('id', $values['ProductionStatus']) - ->getSingleResult(); + ->setParameter('id', $values['ProductionStatus']) + ->getSingleResult(); $site->setInfrastructure($inf); // get the cert status - if(!isset($values['Certification_Status']) || - $values['Certification_Status'] == null || $values['Certification_Status'] == ''){ + if ( + !isset($values['Certification_Status']) + || $values['Certification_Status'] == null + || $values['Certification_Status'] == '' + ) { throw new \LogicException( - "Missing seed data - No certification status values in the DB (required data)"); + "Missing seed data - No certification " + . "status values in the DB (required data)" + ); } $dql = "SELECT c FROM CertificationStatus c WHERE c.id = :id"; $certStatus = $this->em->createQuery($dql) @@ -802,45 +987,51 @@ public function addSite($values, \User $user =null) { $this->em->persist($certLog); $site->addCertificationStatusLog($certLog); - // Set the scopes - foreach($selectedScopesToApply as $scope){ + foreach ($selectedScopesToApply as $scope) { $site->addScope($scope); } // get the country $dql = "SELECT c FROM Country c WHERE c.id = :id"; $country = $this->em->createQuery($dql) - ->setParameter('id', $values['Country']) - ->getSingleResult(); + ->setParameter('id', $values['Country']) + ->getSingleResult(); $site->setCountry($country); $this->em->persist($site); - // flush synchronizes the in-memory state of managed objects with the database + /** + * flush synchronizes the in-memory state + * of managed objects with the database + */ // but we can still rollback $this->em->flush(); $this->em->getConnection()->commit(); - } catch(\Exception $ex){ + } catch (\Exception $ex) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $ex; } - return $site; + return $site; } - /** * Is there a site in the database named $siteName? * @param string $siteName Site name */ - private function uniqueCheck($shortName) { + private function uniqueCheck($shortName) + { $dql = "SELECT s from Site s WHERE s.shortName = :name"; $query = $this->em->createQuery($dql) ->setParameter('name', $shortName); - if(count($query->getResult()) > 0) { - throw new \Exception("A site named " . $shortName . " already exists."); + + if (count($query->getResult()) > 0) { + throw new Exception( + "A site named " . $shortName . " already exists." + ); } } @@ -851,101 +1042,129 @@ private function uniqueCheck($shortName) { * * @param \site $site site to be moved * @param \NGI $ngi NGI to which $site is to be moved + * * @return null */ - public function moveSite(\Site $site, \NGI $ngi, \User $user = null) { - //Check the portal is not in read only mode, throws exception if it is + public function moveSite(\Site $site, \NGI $ngi, \User $user = null) + { + // Check the portal is not in read only mode, throws exception if it is $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); - //Throws exception if user is not an administrator + // Throws exception if user is not an administrator $this->checkUserIsAdmin($user); $this->em->getConnection()->beginTransaction(); // suspend auto-commit + try { - //If the NGI or site have no ID - throw logic exception + // If the NGI or site have no ID - throw logic exception $siteId = $site->getId(); + if (empty($siteId)) { throw new \LogicException('Site has no ID'); } + $ngiId = $ngi->getId(); + if (empty($ngiId)) { throw new \LogicException('NGI has no ID'); } - //find old NGI + + // find old NGI $oldNgi = $site->getNgi(); - //If the NGI has changed, then we move the site. + // If the NGI has changed, then we move the site. if ($oldNgi != $ngi) { - - //Remove the site from the old NGI FIRST if it has an old NGI + // Remove the site from the old NGI FIRST if it has an old NGI if (!empty($oldNgi)) { $oldNgi->getSites()->removeElement($site); } + //Add site to new NGI $ngi->addSiteDoJoin($site); - //$site->setNgiDoJoin($ngi); //persist $this->em->merge($ngi); $this->em->merge($oldNgi); - }//close if + } $this->em->flush(); $this->em->getConnection()->commit(); } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } } - private function checkNumberOfScopes(array $myArray){ - $minumNumberOfScopes = $this->configService->getMinimumScopesRequired('site'); - if(sizeof($myArray)<$minumNumberOfScopes){ - throw new \Exception("A site must have at least " . $minumNumberOfScopes . " optional scope(s) assigned to it."); + private function checkNumberOfScopes(array $myArray) + { + $minumNumberOfScopes = $this->configService + ->getMinimumScopesRequired('site'); + + if (sizeof($myArray) < $minumNumberOfScopes) { + throw new Exception( + "A site must have at least " + . $minumNumberOfScopes . " optional scope(s) assigned to it." + ); } } /** * Delete a site. Only available to admins. + * * @param \Site $s site for deletion * @param \User $user user doing the deleting - * @param $logSiteAndServicesInArchive Archive the site and its services or not. - * Useful for testing - an incomplete site or its service can easily cause errors when archiving. - * @throws \Exception + * @param $logSiteAndServicesInArchive Archive the site + * and its services or not. + * + * Useful for testing - an incomplete site or its service can easily + * cause errors when archiving. + * + * @throws Exception */ - public function deleteSite(\Site $s, \User $user =null, $logSiteAndServicesInArchive=true) { + public function deleteSite( + \Site $s, + \User $user = null, + $logSiteAndServicesInArchive = true + ) { require_once __DIR__ . '/../DAOs/SiteDAO.php'; require_once __DIR__ . '/../DAOs/ServiceDAO.php'; - //Check the portal is not in read only mode, throws exception if it is + + // Check the portal is not in read only mode, throws exception if it is $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); - //Throws exception if user is not an administrator + // Throws exception if user is not an administrator $this->checkUserIsAdmin($user); $this->em->getConnection()->beginTransaction(); + try { $siteDAO = new \SiteDAO(); $siteDAO->setEntityManager($this->em); $serviceDAO = new \ServiceDAO(); $serviceDAO->setEntityManager($this->em); - //Archive site - if($logSiteAndServicesInArchive){ + // Archive site + if ($logSiteAndServicesInArchive) { $siteDAO->addSiteToArchive($s, $user); } - //delete each child service - foreach($s->getServices() as $service){ - if($logSiteAndServicesInArchive){ - //archive the srvice - $serviceDAO->addServiceToArchive($service, $user); + // delete each child service + foreach ($s->getServices() as $service) { + if ($logSiteAndServicesInArchive) { + // archive the srvice + $serviceDAO->addServiceToArchive($service, $user); } - //remove the service (and any downtimes associated with it and only it) - $serviceDAO->removeService($service); + + /** + * remove the service (and any downtimes + * associated with it and only it) + */ + $serviceDAO->removeService($service); } - //remove the site + // remove the site $siteDAO->removeSite($s); $this->em->flush(); @@ -953,40 +1172,52 @@ public function deleteSite(\Site $s, \User $user =null, $logSiteAndServicesInArc } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } } /** - * This method will check that a user has edit permissions over a site before allowing a user to add, edit or delete + * This method will check that a user has edit permissions + * over a site before allowing a user to add, edit or delete * a site property. * * @param \User $user * @param \Site $site - * @throws \Exception + * + * @throws Exception */ - public function validatePropertyActions(\User $user, \Site $site) { + public function validatePropertyActions(\User $user, \Site $site) + { // Check to see whether the user has a role that covers this site - //if(count($this->authorize Action(\Action::EDIT_OBJECT, $site, $user))==0){ if (!$this->userCanEditSite($user, $site)) { - throw new \Exception("You don't have permission over " . $site->getShortName()); + throw new Exception( + "You don't have permission over " . $site->getShortName() + ); } } - /** + /** * Returns true if the user has permission to edit the Site * * @param \User $user * @param \Site $site - * @return boolian + * + * @return boolean */ - public function userCanEditSite(\User $user, \Site $site) { - + public function userCanEditSite(\User $user, \Site $site) + { if (is_null($user)) { return false; } - if ($this->roleActionAuthorisationService->authoriseAction(\Action::EDIT_OBJECT, $site, $user)->getGrantAction() == TRUE) { + if ( + $this->roleActionAuthorisationService->authoriseAction( + \Action::EDIT_OBJECT, + $site, + $user + )->getGrantAction() == true + ) { return true; } @@ -995,21 +1226,29 @@ public function userCanEditSite(\User $user, \Site $site) { /** * Adds sets of extension property key/value pairs to a site. + * * @param \Site $site * @param \User $user * @param array $propArr * @param bool $preventOverwrite + * * @throws \Exception */ - public function addProperties(\Site $site, \User $user, array $propArr, $preventOverwrite = false) { - //Check the portal is not in read only mode, throws exception if it is + public function addProperties( + \Site $site, + \User $user, + array $propArr, + $preventOverwrite = false + ) { + // Check the portal is not in read only mode, throws exception if it is $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); // Validate the user has permission to add properties $this->validatePropertyActions($user, $site); - //Add the properties + // Add the properties $this->em->getConnection()->beginTransaction(); + try { $this->addPropertiesLogic($site, $propArr, $preventOverwrite); $this->em->flush(); @@ -1017,35 +1256,58 @@ public function addProperties(\Site $site, \User $user, array $propArr, $prevent } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } } /** - * Adds sets of extension property key/value pairs to a site, following a request through the API + * Adds sets of extension property key/value pairs to a site, + * following a request through the API + * * @param \Site $site * @param array $propArr * @param bool $preventOverwrite * @param string $authenticationType * @param string $authenticationIdentifier + * * @throws \Exception */ - public function addPropertiesAPI(\Site $site, array $propKVArr, $preventOverwrite, $authenticationType, $authenticationIdentifier) { - //Check the portal is not in read only mode, throws exception if it is + public function addPropertiesAPI( + \Site $site, + array $propKVArr, + $preventOverwrite, + $authenticationType, + $authenticationIdentifier + ) { + // Check the portal is not in read only mode, throws exception if it is $this->checkGOCDBIsNotReadOnly(); // Validate the user has permission to add properties - $this->checkAuthorisedAPIIdentifier($site, $authenticationIdentifier, $authenticationType); + $this->checkAuthorisedAPIIdentifier( + $site, + $authenticationIdentifier, + $authenticationType + ); - //Convert the property array into the format used by the webportal logic - #TODO: make the web portal use a more sensible format (e.g. array(key=> value), rather than array([1]=>key,array[2]=>value)) - $propArr=array(); + /** + * Convert the property array into the format + * used by the webportal logic + */ + /** + * @TODO + * Make the web portal use a more sensible format + * (e.g. array(key=> value), rather than + * array([1]=>key,array[2]=>value)) + */ + $propArr = array(); foreach ($propKVArr as $key => $value) { - $propArr[]= array(0=>$key,1=>$value); + $propArr[] = array(0 => $key, 1 => $value); } - //Add the properties + // Add the properties $this->em->getConnection()->beginTransaction(); + try { $this->addPropertiesLogic($site, $propArr, $preventOverwrite); $this->em->flush(); @@ -1053,50 +1315,69 @@ public function addPropertiesAPI(\Site $site, array $propKVArr, $preventOverwrit } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } } - - /** * Logic to sets of extension property key/value pairs to a site. + * * @param \Site $site * @param array $propArr * @param bool $preventOverwrite - * @throws \Exception + * + * @throws Exception */ - protected function addPropertiesLogic(\Site $site, array $propArr, $preventOverwrite = false) { + protected function addPropertiesLogic( + \Site $site, + array $propArr, + $preventOverwrite = false + ) { $existingProperties = $site->getSiteProperties(); - //We will use this variable to track the keys as we go along, this will be used check they are all unique later - $keys=array(); + /** + * We will use this variable to track the keys as we go along, + * this will be used check they are all unique later + */ + $keys = array(); - //We will use this variable to track teh final number of properties and ensure we do not exceede the specified limit + /** + * We will use this variable to track the final number of properties + * and ensure we do not exceed the specified limit + */ $propertyCount = sizeof($existingProperties); - foreach ($propArr as $i => $prop) { - /*Trim off trailing and leading whitspace - as we currently don't want this. - *The input array is awkwardly formatted as keys didn't use to have to be unique. - */ + foreach ($propArr as $prop) { + /** + * Trim off trailing and leading whitspace - as we currently + * don't want this. + * The input array is awkwardly formatted as keys didn't use to + * have to be unique. + */ $key = trim($prop[0]); $value = trim($prop[1]); - /*Find out if a property with the provided key already exists, if - *we are preventing overwrites, this will be a problem. If we are not, - *we will want to edit the existing property later, rather than create it. + /** + * Find out if a property with the provided key already exists, if + * we are preventing overwrites, this will be a problem. + * If we are not, we will want to edit the existing property later, + * rather than create it. */ $property = null; + foreach ($existingProperties as $existProp) { if ($existProp->getKeyName() == $key) { $property = $existProp; } } - /*If the property doesn't already exist, we add it. If it exists - *and we are not preventing overwrites, we edit the existing one. - *If it exists and we are preventing overwrites, we throw an exception - */ + /** + * If the property doesn't already exist, we add it. If it exists + * and we are not preventing overwrites, we edit the existing one. + * If it exists and we are preventing overwrites, + * we throw an exception + */ if (is_null($property)) { //validate key value $validateArray['NAME'] = $key; @@ -1110,49 +1391,76 @@ protected function addPropertiesLogic(\Site $site, array $propArr, $preventOverw $site->addSitePropertyDoJoin($property); $this->em->persist($property); - //increment the property counter to enable check against property limit + /** + * Increment the property counter to enable + * check against property limit + */ $propertyCount++; } elseif (!$preventOverwrite) { - $this->editSitePropertyLogic($site, $property, array('SITEPROPERTIES'=>array('NAME'=>$key,'VALUE'=>$value))); + $this->editSitePropertyLogic( + $site, + $property, + array( + 'SITEPROPERTIES' => array( + 'NAME' => $key, + 'VALUE' => $value + ) + ) + ); } else { - throw new \Exception("A property with name \"$key\" already exists for this object, no properties were added."); + throw new Exception( + "A property with name \"$key\" already exists for this " + . "object, no properties were added." + ); } - //Add the key to the keys array, to enable unique check - $keys[]=$key; + // Add the key to the keys array, to enable unique check + $keys[] = $key; } - - //Keys should be unique, create an exception if they are not - if(count(array_unique($keys))!=count($keys)) { - throw new \Exception( - "Property names should be unique. The requested new properties include multiple properties with the same name." + // Keys should be unique, create an exception if they are not + if (count(array_unique($keys)) != count($keys)) { + throw new Exception( + "Property names should be unique. The requested new " + . "properties include multiple properties with the same name." ); } - //Check to see if adding the new properties will exceed the max limit defined in local_info.xml, and throw an exception if so + /** + * Check to see if adding the new properties will exceed the + * max limit defined in local_info.xml, and throw an exception if so + */ $extensionLimit = $this->configService->getExtensionsLimit(); - if ($propertyCount > $extensionLimit){ - throw new \Exception("Property(s) could not be added due to the property limit of $extensionLimit"); + if ($propertyCount > $extensionLimit) { + throw new Exception( + "Property(s) could not be added due to the property limit of " + . "$extensionLimit" + ); } } /** - * Deletes site properties: validates the user has permission then calls the - * required logic + * Deletes site properties: validates the user has permission then calls + * the required logic + * * @param \Site $site * @param \User $user * @param array $propArr */ - public function deleteSiteProperties(\Site $site, \User $user, array $propArr) { - //Check the portal is not in read only mode, throws exception if it is + public function deleteSiteProperties( + \Site $site, + \User $user, + array $propArr + ) { + // Check the portal is not in read only mode, throws exception if it is $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); // Validate the user has permission to delete a property $this->validatePropertyActions($user, $site); - //Make the change + // Make the change $this->em->getConnection()->beginTransaction(); + try { $this->deleteSitePropertiesLogic($site, $propArr); $this->em->flush(); @@ -1160,31 +1468,47 @@ public function deleteSiteProperties(\Site $site, \User $user, array $propArr) { } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } } /** - * Deletes site properties: validates the user has permission then calls the - * required logic + * Deletes site properties: validates the user + * has permission then calls the required logic + * * @param \Site $site * @param \User $user * @param array $propArr */ - public function deleteSitePropertiesAPI(\Site $site, array $propArr, $authIdentifierType, $authIdentifier) { - //Check the portal is not in read only mode, throws exception if it is + public function deleteSitePropertiesAPI( + \Site $site, + array $propArr, + $authIdentifierType, + $authIdentifier + ) { + // Check the portal is not in read only mode, throws exception if it is $this->checkGOCDBIsNotReadOnly(); // Validate the user has permission to delete a property foreach ($propArr as $prop) { if ($prop->getParentSite() != $site) { - throw new \Exception("Internal error: property parent site and site do not match."); + throw new Exception( + "Internal error: property parent site and site do not " + . "match." + ); } } - $this->checkAuthorisedAPIIdentifier($site, $authIdentifier, $authIdentifierType); - //Make the change + $this->checkAuthorisedAPIIdentifier( + $site, + $authIdentifier, + $authIdentifierType + ); + + // Make the change $this->em->getConnection()->beginTransaction(); + try { $this->deleteSitePropertiesLogic($site, $propArr); $this->em->flush(); @@ -1192,24 +1516,31 @@ public function deleteSitePropertiesAPI(\Site $site, array $propArr, $authIdenti } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); + throw $e; } } /** - * All the logic to delete a site's properties, before deletion a check is done to confirm the property - * is from the parent site specified by the request, and an exception is thrown if this is - * not the case + * All the logic to delete a site's properties, before deletion a check is + * done to confirm the property is from the parent site specified by the + * request, and an exception is thrown if this is not the case + * * @param \Site $site + * * @param array $propArr */ - protected function deleteSitePropertiesLogic(\Site $site, array $propArr) { + protected function deleteSitePropertiesLogic(\Site $site, array $propArr) + { foreach ($propArr as $prop) { - //Check that the properties parent site the same as the one given - if ($prop->getParentSite() != $site){ + // Check that the properties parent site the same as the one given + if ($prop->getParentSite() != $site) { $id = $prop->getId(); - throw new \Exception("Property {$id} does not belong to the specified site"); + throw new Exception( + "Property {$id} does not belong to the specified site" + ); } + // Site is the owning side so remove elements from the site $site->getSiteProperties()->removeElement($prop); // Once relationship is removed delete the actual element @@ -1218,111 +1549,152 @@ protected function deleteSitePropertiesLogic(\Site $site, array $propArr) { } /** - * Edit a site's property. The user is validated then the logic to make the - * change called + * Edit a site's property. The user is validated then + * the logic to make the change called * * @param \Site $site * @param \User $user * @param \SiteProperty $prop * @param array $newValues + * * @throws \Exception */ - public function editSiteProperty(\Site $site,\User $user,\SiteProperty $prop, $newValues) { + public function editSiteProperty( + \Site $site, + \User $user, + \SiteProperty $prop, + $newValues + ) { // Check the portal is not in read only mode, throws exception if it is - $this->checkPortalIsNotReadOnlyOrUserIsAdmin ( $user ); + $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); - //Validate User to perform this action + // Validate User to perform this action $this->validatePropertyActions($user, $site); - //Make the change + // Make the change $this->em->getConnection()->beginTransaction(); + try { $this->editSitePropertyLogic($site, $prop, $newValues); - $this->em->flush (); - $this->em->getConnection ()->commit (); - } catch ( \Exception $ex ) { - $this->em->getConnection ()->rollback (); - $this->em->close (); + $this->em->flush(); + $this->em->getConnection()->commit(); + } catch (\Exception $ex) { + $this->em->getConnection()->rollback(); + $this->em->close(); + throw $ex; } } /** * All the logic to edit a site's property, without the user validation. - * A check is performed to confirm the given property is from the parent site - * specified by the request, and an exception is thrown if this is not the case. + * A check is performed to confirm the given property is from + * the parent site specified by the request, + * and an exception is thrown if this is not the case. * * @param \Site $site * @param \SiteProperty $prop * @param array $newValues + * * @throws \Exception */ - protected function editSitePropertyLogic(\Site $site,\SiteProperty $prop, $newValues) { - + protected function editSitePropertyLogic( + \Site $site, + \SiteProperty $prop, + $newValues + ) { $this->validate($newValues['SITEPROPERTIES'], 'siteproperty'); - //We don't currently want trailing or leading whitespace, so we trim it + /** + * We don't currently want trailing + * or leading whitespace, so we trim it + */ $keyname = trim($newValues['SITEPROPERTIES']['NAME']); $keyvalue = trim($newValues ['SITEPROPERTIES'] ['VALUE']); - //Check that the prop is from the site - if ($prop->getParentSite() != $site){ + // Check that the prop is from the site + if ($prop->getParentSite() != $site) { $id = $prop->getId(); - throw new \Exception("Property {$id} does not belong to the specified site"); + + throw new Exception( + "Property {$id} does not belong to the specified site" + ); } - //If the properties key has changed, check there isn't an existing property with that key - if ($keyname != $prop->getKeyName()){ + /** + * If the properties key has changed, check there isn't an + * existing property with that key + */ + if ($keyname != $prop->getKeyName()) { $existingProperties = $site->getSiteProperties(); + foreach ($existingProperties as $existingProp) { if ($existingProp->getKeyName() == $keyname) { - throw new \Exception("A property with that name already exists for this object"); + throw new Exception( + "A property with that name already exists for this " + . "object" + ); } } } // Set the site propertys new member variables - $prop->setKeyName ( $keyname ); - $prop->setKeyValue ( $keyvalue ); + $prop->setKeyName($keyname); + $prop->setKeyValue($keyvalue); - $this->em->merge ( $prop ); + $this->em->merge($prop); } /** * For a given site, returns an array containing the names of all the * scopes that site has as keys and a boolean as value. The bool is true * if the scope is shared with the parent ngi, false if not. + * * @param \Service $service + * * @return associative array */ - public function getScopesWithParentScopeInfo(\Site $site){ + public function getScopesWithParentScopeInfo(\Site $site) + { $parentNgi = $site->getNgi(); $parentScopes = $parentNgi->getScopes(); $childScopes = $site->getScopes(); $parentScopesNames = array(); - foreach($parentScopes as $parentScope){ - $parentScopesNames[] =$parentScope->getName(); + + foreach ($parentScopes as $parentScope) { + $parentScopesNames[] = $parentScope->getName(); } $childScopesNames = array(); - foreach($childScopes as $childScope){ - $childScopesNames[] =$childScope->getName(); + + foreach ($childScopes as $childScope) { + $childScopesNames[] = $childScope->getName(); } - $sharedScopesNames = array_intersect($childScopesNames, $parentScopesNames); + $sharedScopesNames = array_intersect( + $childScopesNames, + $parentScopesNames + ); - $scopeNamesNotShared = array_diff($childScopesNames, $parentScopesNames); + $scopeNamesNotShared = array_diff( + $childScopesNames, + $parentScopesNames + ); $scopeNamesAndParentShareInfo = array(); - foreach($sharedScopesNames as $sharedScopesName){ - $scopeNamesAndParentShareInfo[$sharedScopesName]=true; + + foreach ($sharedScopesNames as $sharedScopesName) { + $scopeNamesAndParentShareInfo[$sharedScopesName] = true; } - foreach($scopeNamesNotShared as $scopeNameNotShared){ - $scopeNamesAndParentShareInfo[$scopeNameNotShared]=false; + foreach ($scopeNamesNotShared as $scopeNameNotShared) { + $scopeNamesAndParentShareInfo[$scopeNameNotShared] = false; } - //can be replaced with ksort($scopeNamesAndParentShareInfo, SORT_NATURAL); in php>=5.5 + /** + * can be replaced with + * ksort($scopeNamesAndParentShareInfo, SORT_NATURAL); in php>=5.5 + */ uksort($scopeNamesAndParentShareInfo, 'strcasecmp'); return $scopeNamesAndParentShareInfo; @@ -1331,14 +1703,18 @@ public function getScopesWithParentScopeInfo(\Site $site){ /** * Returns those sites which have valid longitudes and latitudes specified * and are not closed + * * @return arraycollection collection of sites */ - public function getSitesWithGeoInfo() { - //Note - we remove any site with 0,0 as it's location, as we have no - //sites in the middle of the pacific ocean. We also remove sites with - //invaid (too large) longs and lats (these are legacy values, new values - // entered through the webportal have to be within expected range, - // historical values may not) + public function getSitesWithGeoInfo() + { + /** + * Note - we remove any site with 0,0 as it's location, as we have no + * sites in the middle of the pacific ocean. + * We also remove sites with invaid (too large) longs and lats + * (these are legacy values, new values entered through the webportal + * have to be within expected range historical values may not) + */ $dql = "SELECT s FROM Site s JOIN s.certificationStatus c @@ -1358,65 +1734,87 @@ public function getSitesWithGeoInfo() { return $sites; } - /* - * @return string xml string containing information required by the front map + /** + * @return string xml string containing + * information required by the front map */ - public function getMapXMLString(){ + public function getMapXMLString() + { $sites = $this->getSitesWithGeoInfo(); $portalUrl = $this->configService->GetPortalURL(); $xml = new \SimpleXMLElement(""); - foreach($sites as $site) { + + foreach ($sites as $site) { $xmlSite = $xml->addChild('Site'); $xmlSite->addAttribute('ShortName', $site->getShortName()); $xmlSite->addAttribute('OfficialName', $site->getOfficialName()); - $sitePortalUrl = $portalUrl . '/index.php?Page_Type=Site&id=' . $site->getId(); - $xmlSite->addAttribute('PortalURL', htmlspecialchars($sitePortalUrl)); - $xmlSite->addAttribute('Description', htmlspecialchars($site->getDescription())); + + $sitePortalUrl = $portalUrl . '/index.php?Page_Type=Site&id=' + . $site->getId(); + + $xmlSite->addAttribute( + 'PortalURL', + htmlspecialchars($sitePortalUrl) + ); + $xmlSite->addAttribute( + 'Description', + htmlspecialchars($site->getDescription()) + ); $xmlSite->addAttribute('Latitude', $site->getLatitude()); $xmlSite->addAttribute('Longitude', $site->getLongitude()); - } + } - $domXmlMapElement = dom_import_simplexml($xml); - $dom = new \DOMDocument('1.0'); - $dom->encoding='UTF-8'; - $domXmlMapElement = $dom->importNode($domXmlMapElement, true); - $domXmlMapElement = $dom->appendChild($domXmlMapElement); - $dom->formatOutput = true; - $xmlString = $dom->saveXML(); + $domXmlMapElement = dom_import_simplexml($xml); + $dom = new \DOMDocument('1.0'); + $dom->encoding = 'UTF-8'; + $domXmlMapElement = $dom->importNode($domXmlMapElement, true); + $domXmlMapElement = $dom->appendChild($domXmlMapElement); + $dom->formatOutput = true; + $xmlString = $dom->saveXML(); return $xmlString; } /** * Finds a single API authentication entity by ID and returns its entity + * * @param int $id the authentication entity ID + * * @return APIAuthentication an API authentcation entity */ - public function getAPIAuthenticationEntity($id) { + public function getAPIAuthenticationEntity($id) + { $dql = "SELECT a FROM APIAuthentication a WHERE a.id = :id"; $authEnt = $this->em ->createQuery($dql) ->setParameter('id', $id) ->getSingleResult(); + return $authEnt; } - public function addAPIAuthEntity(\Site $site, \User $user, $newValues) { - + public function addAPIAuthEntity(\Site $site, \User $user, $newValues) + { // Validate the user has permission to add properties - $this->checkUserAuthz ($user, $site); + $this->checkUserAuthz($user, $site); $authEntServ = \Factory::getAPIAuthenticationService(); $authEntServ->setEntityManager($this->em); - $authEnt = $authEntServ->addAPIAuthentication($site, $user, $newValues); + $authEnt = $authEntServ->addAPIAuthentication( + $site, + $user, + $newValues + ); return $authEnt; } - public function deleteAPIAuthEntity(\APIAuthentication $authEntity, \User $user) { - + public function deleteAPIAuthEntity( + \APIAuthentication $authEntity, + \User $user + ) { // Validate the user has permission to delete properties $parentSite = $authEntity->getParentSite(); @@ -1429,8 +1827,11 @@ public function deleteAPIAuthEntity(\APIAuthentication $authEntity, \User $user) $authEntServ->deleteAPIAuthentication($authEntity); } - public function editAPIAuthEntity(\APIAuthentication $authEntity, \User $user, $newValues) { - + public function editAPIAuthEntity( + \APIAuthentication $authEntity, + \User $user, + $newValues + ) { $parentSite = $authEntity->getParentSite(); // Check the user can do this. Thows exception if not. @@ -1439,15 +1840,21 @@ public function editAPIAuthEntity(\APIAuthentication $authEntity, \User $user, $ $identifier = $newValues['IDENTIFIER']; $type = $newValues['TYPE']; - /** - @var org\gocdb\services\APIAuthenticationService - */ $authEntServ = \Factory::getAPIAuthenticationService(); $authEntServ->setEntityManager($this->em); - //If the entity is of type OIDC subject, do a more thorough check again - if ($type == 'OIDC Subject' && !preg_match("/^([a-z0-9]{8}\-[a-z0-9]{4}\-[a-z0-9]{4}\-[a-z0-9]{4}\-[a-z0-9]{12})$/", $identifier)) { - throw new \Exception("Invalid OIDC Subject"); + /** + * If the entity is of type OIDC subject, + * do a more thorough check again + */ + $pattern = "/^([a-z0-9]{8}\-[a-z0-9]{4}" + . "\-[a-z0-9]{4}\-[a-z0-9]{4}\-[a-z0-9]{12})$/"; + + if ( + $type == 'OIDC Subject' + && !preg_match($pattern, $identifier) + ) { + throw new Exception("Invalid OIDC Subject"); } /** @@ -1468,13 +1875,17 @@ public function editAPIAuthEntity(\APIAuthentication $authEntity, \User $user, $ * * @throws \Exception */ - private function checkUserAuthz (\User $user, \Site $site) { - + private function checkUserAuthz(\User $user, \Site $site) + { $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); // Validate the user has permission to edit properties if (!$this->userCanEditSite($user, $site)) { - throw new \Exception("Permission denied: a site role is required to modify authentication entities on site " . $site->getShortName()); + throw new Exception( + "Permission denied: a site role is required to " + . "modify authentication entities on site " + . $site->getShortName() + ); } } } diff --git a/resources/ManageAPICredentials/ManageAPICredentialsActions.php b/resources/ManageAPICredentials/ManageAPICredentialsActions.php index 51e2b895b..f0fd21c72 100644 --- a/resources/ManageAPICredentials/ManageAPICredentialsActions.php +++ b/resources/ManageAPICredentials/ManageAPICredentialsActions.php @@ -1,14 +1,16 @@ dryRun = $dryRun; $this->entityManager = $entityManager; $this->baseTime = $baseTime; } + /** * Find API credentials unused for a number of months. * - * Find API credentials which have not been used for a number of months prior to a given base time based - * on the credential property lastUseTime. + * Find API credentials which have not been used for a number of months + * prior to a given base time based on the credential property lastUseTime. * - * @param int $threshold The number of months of no-use prior to $baseTime to use for selection + * @param int $threshold The number of months of no-use + * prior to $baseTime to use for selection */ public function getCreds($threshold, $propertyName) { $qbl = $this->entityManager->createQueryBuilder(); + // `$qbl->expr()->isNotNull("cred.user")` => cope with legacy entities $qbl->select('cred') ->from('APIAuthentication', 'cred') - ->where($qbl->expr()->isNotNull("cred.user")) // cope with legacy entities + ->where($qbl->expr()->isNotNull("cred.user")) ->andWhere('cred.' . $propertyName . '< :threshold'); $timeThresh = clone $this->baseTime; @@ -62,18 +70,23 @@ public function getCreds($threshold, $propertyName) return $creds; } + /** * Select API credentials for deletion. * - * Find API credentials which have not been used for a given number of months - * and delete them or, if dry-run option is true, generate a summary report - * of the credentils found. + * Find API credentials which have not been used for a given + * number of months and delete them or, if dry-run option is true, + * generate a summary report of the credentils found. + * + * @param array $creds Array of credentials to process. + * @param \Doctrine\Orm\EntityManager $entitymanager A valid Doctrine + * Entity Manager + * @param \DateTime $baseTime Time from which interval of + * no-use is measured + * @param int $deleteThreshold The number of months of no-use + * which will trigger deletion * - * @param array $creds Array of credentials to process. - * @param \Doctrine\Orm\EntityManager $entitymanager A valid Doctrine Entity Manager - * @param \DateTime $baseTime Time from which interval of no-use is measured - * @param int $deleteThreshold The number of months of no-use which will trigger deletion - * @return array Credentials which were not deleted. + * @return array Credentials which were not deleted. */ public function deleteCreds($creds, $deleteThreshold) { @@ -82,36 +95,60 @@ public function deleteCreds($creds, $deleteThreshold) $serv = new APIAuthenticationService(); $serv->setEntityManager($this->entityManager); - /* @var $apiCred APIAuthentication */ foreach ($creds as $apiCred) { - if ($this->isOverThreshold($apiCred, $this->baseTime, $deleteThreshold)) { + if ( + $this->isOverThreshold( + $apiCred, + $this->baseTime, + $deleteThreshold + ) + ) { $deletedCreds[] = $apiCred; + if (!$this->dryRun) { $serv->deleteAPIAuthentication($apiCred); } } } + if ($this->dryRun) { $this->reportDryRun($deletedCreds, "deleting"); } - return array_udiff($creds, $deletedCreds, array($this, 'compareCredIds')); + return array_udiff( + $creds, + $deletedCreds, + array( + $this, + 'compareCredIds' + ) + ); } + /** - * Send of warning emails where credentials have not been used for a given number of months + * Send of warning emails where credentials have not + * been used for a given number of months + * + * Find API credentials from the input array which have not been used for + * a given number of months and send emails to the owners and site address, + * taken from the credential object, warning of impending deletion if the + * period of no-use reaches a given threshold. + * If dry-run option is true, generate a summary report of the + * credentials found instead of sending emails. * - * Find API credentials from the input array which have not been used for a given number of months - * and send emails to the owners and site address, taken from the credential object, - * warning of impending deletion if the period of no-use reaches a given threshold. - * If dry-run option is true, generate a summary report of the credentials found - * instead of sending emails. + * @param array $creds Array of credentials + * to process. + * @param int $warningThreshold The number of months of no-use + * which triggers warning emails + * @param int $deleteThreshold The number of months of no-use + * which will trigger deletion + * @param string $fromEmail Email address to use + * as sender's (From:) address + * @param string $replyToEmail Email address for + * replies (Reply-To:) * - * @param array $creds Array of credentials to process. - * @param int $warningThreshold The number of months of no-use which triggers warning emails - * @param int $deleteThreshold The number of months of no-use which will trigger deletion - * @param string $fromEmail Email address to use as sender's (From:) address - * @param string $replyToEmail Email address for replies (Reply-To:) - * @return array Array of credentials identifed for sending warning emails + * @return array Array of credentials identifed + * for sending warning emails */ public function warnUsers( $creds, @@ -122,13 +159,21 @@ public function warnUsers( ) { $warnedCreds = []; - /* @var $api APIAuthentication */ foreach ($creds as $apiCred) { - // The credentials list is pre-selected based on the given threshold in the query - // so this check is probably redundant. - if ($this->isOverThreshold($apiCred, $this->baseTime, $warningThreshold)) { + /** + * The credentials list is pre-selected based on the given + * threshold in the query so this check is probably redundant. + */ + if ( + $this->isOverThreshold( + $apiCred, + $this->baseTime, + $warningThreshold + ) + ) { $lastUsed = $apiCred->getLastUseTime(); - $lastUseMonths = $this->baseTime->diff($lastUsed)->format('%m'); + $lastUseMonths = $this->baseTime->diff($lastUsed) + ->format('%m'); if (!$this->dryRun) { $this->sendWarningEmail( @@ -148,13 +193,25 @@ public function warnUsers( $this->reportDryRun($warnedCreds, "sending warning emails"); } - return array_udiff($creds, $warnedCreds, array($this, 'compareCredIds')); + return array_udiff( + $creds, + $warnedCreds, + array( + $this, + 'compareCredIds' + ) + ); } -/** - * @return boolean true if the credential has not been used within $threshold months, else false - */ - private function isOverThreshold(APIAuthentication $cred, DateTime $baseTime, $threshold) - { + + /** + * @return boolean true if the credential has not been + * used within $threshold months, else false + */ + private function isOverThreshold( + APIAuthentication $cred, + DateTime $baseTime, + $threshold + ) { $lastUsed = $cred->getLastUseTime(); $diffTime = $baseTime->diff($lastUsed); @@ -162,14 +219,17 @@ private function isOverThreshold(APIAuthentication $cred, DateTime $baseTime, $t return $lastUseMonths >= $threshold; } -/** - * Helper function to check if two API credentials have the same id. - * - * @return integer zero if equal, -1 if id1 < id2, 1 if id1 > id2 - * -*/ - private function compareCredIds(APIAuthentication $cred1, APIAuthentication $cred2) - { + + /** + * Helper function to check if two API credentials have the same id. + * + * @return integer zero if equal, -1 if id1 < id2, 1 if id1 > id2 + * + */ + private function compareCredIds( + APIAuthentication $cred1, + APIAuthentication $cred2 + ) { $id1 = $cred1->getId(); $id2 = $cred2->getId(); @@ -180,19 +240,26 @@ private function compareCredIds(APIAuthentication $cred1, APIAuthentication $cre return $id1 > $id2 ? 1 : -1; } -/** - * Format and send warning emails. - * - * Send emails to API credential owner and the registered site address warning of impending credential deletion - * if the credential remains unused until a given threshold of months. - * - * @param string $fromEmail Email address to use as sender's (From:) address - * @param string $replyToEmail Email address for replies (Reply-To:) - * @param \APIAuthentication $api Credential to warn about - * @param int $elapsedMonths The number of months of non-use so far. - * @param int $deleteionThreshold The number of months of no-use which will trigger deletion if reached. - * @return void - */ + /** + * Format and send warning emails. + * + * Send emails to API credential owner and the registered site address + * warning of impending credential deletion if the credential remains + * unused until a given threshold of months. + * + * @param string $fromEmail Email address to use as sender's + * (From:) address + * @param string $replyToEmail Email address for replies + * (Reply-To:) + * @param \APIAuthentication $api Credential to warn about + * @param int $elapsedMonths The number of months of + * non-use so far. + * @param int $deleteionThreshold The number of months of no-use + * which will trigger deletion + * if reached. + * + * @return void + */ private function sendWarningEmail( $fromEmail, $replyToEmail, @@ -207,9 +274,11 @@ private function sendWarningEmail( $headersArray = array ("From: $fromEmail", "Cc: $siteEmail"); + if (strlen($replyToEmail) > 0 && $fromEmail !== $replyToEmail) { $headersArray[] = "Reply-To: $replyToEmail"; } + $headers = join("\r\n", $headersArray); $subject = "GOCDB: Site API credential deletion notice"; @@ -230,21 +299,27 @@ private function sendWarningEmail( // Send the email (or not, according to local configuration) Factory::getEmailService()->send($userEmail, $subject, $body, $headers); } -/** - * Generate a summary report. - * - * Generate a report to stdout summarising information about each credential in an array when - * a dry-run operation is in progress. - * - * @param array $creds Array of API credential objects to be summarised. - * @param string $text Brief description of the operation which would have been - * performed without dry-run to be included in the report. - * @return void - */ + + /** + * Generate a summary report. + * + * Generate a report to stdout summarising information about each + * credential in an array when a dry-run operation is in progress. + * + * @param array $creds Array of API credential objects + * to be summarised. + * @param string $text Brief description of the operation + * which would have been + * performed without dry-run to be + * included in the report. + * + * @return void + */ private function reportDryRun(array $creds, $text) { if (count($creds) == 0) { print("Dry run: No matching credentials found for $text.\n"); + return; } diff --git a/resources/ManageAPICredentials/ManageUnusedAPICredentials.php b/resources/ManageAPICredentials/ManageUnusedAPICredentials.php index 88009d04f..c4dd2a8fb 100644 --- a/resources/ManageAPICredentials/ManageUnusedAPICredentials.php +++ b/resources/ManageAPICredentials/ManageUnusedAPICredentials.php @@ -3,21 +3,25 @@ /** * Maintenance utility for API credential management. * - * Finds API credentials that have not been used for a given number of months and - * deletes them, then finds credentials that have not been used for a different, - * smaller number of months and sends warning email messages to the owners telling - * them the credentials will be deleted if not used before the larger month - * deadline is reached. A dry-run option is provided to report what would have been - * done but without taking any actions. + * Finds API credentials that have not been used for a given + * number of months and deletes them, then finds credentials that have not + * been used for a different, smaller number of months and sends warning email + * messages to the owners telling them the credentials will be deleted if not + * used before the larger month deadline is reached. + * A dry-run option is provided to report what would have been done but without + * taking any actions. * - * Sender and reply-to email addresses are taken from the local_info.xml config file. + * Sender and reply-to email addresses are taken from + * the local_info.xml config file. * * Usage: php ManageUnusedAPICredentials.php [ --help | -h ] [ --dry-run ] \\ * [[ --warning_threshold | -w ] LITTLE_MONTHS ] \\ * [[ --deletion_threshold | -d ] BIG_MONTHS ] * - * Warning and deletion thresholds are optional. If missing the respective action is not taken. - * If both are specified, the deletion threshold MUST be greater than the warning threshold. + * Warning and deletion thresholds are optional. + * If missing the respective action is not taken. + * If both are specified, the deletion threshold MUST be + * greater than the warning threshold. */ namespace org\gocdb\scripts; @@ -34,8 +38,6 @@ // Fetch sender and replyTo email addresses from the local config file. // There is no capability to override based on URL as the webserver does with - -// \Factory::getConfigService()->setLocalInfoOverride($_SERVER['SERVER_NAME']); - $configService = \Factory::getConfigService(); $fromEmail = (string) $configService->getEmailFrom(); $replyToEmail = (string) $configService->getEmailTo(); @@ -49,7 +51,11 @@ $baseTime = new DateTime("now", new DateTimeZone('UTC')); - $actions = new ManageAPICredentialsActions($options->isDryRun(), $entityManager, $baseTime); + $actions = new ManageAPICredentialsActions( + $options->isDryRun(), + $entityManager, + $baseTime + ); $creds = $actions->getCreds($options->getThreshold(), 'lastUseTime'); diff --git a/resources/ManageAPICredentials/ManageUnusedAPICredentialsOptions.php b/resources/ManageAPICredentials/ManageUnusedAPICredentialsOptions.php index 8463c6e8b..2e7025a6c 100644 --- a/resources/ManageAPICredentials/ManageUnusedAPICredentialsOptions.php +++ b/resources/ManageAPICredentials/ManageUnusedAPICredentialsOptions.php @@ -21,8 +21,10 @@ public function __construct() { $this->getOptions(); } + /** - * @throws \InvInvalidArgumentException If errors found in argument processing + * @throws \InvalidArgumentException If errors found in + * argument processing */ public function getOptions() { @@ -35,11 +37,16 @@ public function getOptions() 'deletion_threshold:' ]; - // Beware that getopt is not clever at spotting invalid/misspelled arguments + /** + * Beware that getopt is not clever at + * spotting invalid/misspelled arguments + */ $given = getopt($shortOptions, $longOptions); if ($given === false) { - throw new InvalidArgumentException('failed to parse command line arguments'); + throw new InvalidArgumentException( + 'failed to parse command line arguments' + ); } if ($this->getBoolOption($given, 'help', 'h')) { @@ -60,20 +67,28 @@ public function getOptions() ); } } + return; } + private function getValOption($given, $long, $short) { if (isset($given[$long]) || isset($given[$short])) { - $tValGiven = isset($given[$short]) ? $given[$short] : $given[$long]; + $tValGiven = isset($given[$short]) + ? $given[$short] + : $given[$long]; + return $this->positiveInteger($tValGiven, $long); } + return; } + private function getBoolOption($given, $long, $short) { return isset($given[$long]) || isset($given[$short]); } + private function positiveInteger($val, $txt) { if ((string)abs((int)$val) != $val) { @@ -81,16 +96,16 @@ private function positiveInteger($val, $txt) "$txt must be integer and greater than zero . Received: $val" ); } + return (int)$val; } + public static function usage($message = '') { if ($message != '') { - print - ( - "Error: $message\n" - ); + print("Error: $message\n"); } + print ( "Usage: php ManageAPICredentials.php [--help | -h] [--dry-run] \\\ \n" . @@ -105,32 +120,40 @@ public static function usage($message = '') " for MONTHS months.\n" ); } + public function isShowHelp() { return $this->showHelp; } + public function isDryRun() { return $this->dryRun; } + public function isDeleteEnabled() { return !is_null($this->getDelete()); } + public function isWarnEnabled() { return !is_null($this->getWarn()); } + public function getWarn() { return $this->warn; } + public function getDelete() { return $this->delete; } + /** - * The delete threshold may not be given in which case the warning threshold should be used. + * The delete threshold may not be given in which case + * the warning threshold should be used. * Note that it is an error is delete is greater than warning. */ public function getThreshold() diff --git a/tests/resourcesTests/ManageUnrenewedAPICredentialsTest.php b/tests/resourcesTests/ManageUnrenewedAPICredentialsTest.php index 6065dea04..88a097027 100644 --- a/tests/resourcesTests/ManageUnrenewedAPICredentialsTest.php +++ b/tests/resourcesTests/ManageUnrenewedAPICredentialsTest.php @@ -21,7 +21,8 @@ require_once __DIR__ . '/ManageAPICredentialsTestUtils.php'; require_once __DIR__ . '/../unit/lib/Gocdb_Services/ServiceTestUtil.php'; -require_once __DIR__ . '/../../resources/ManageAPICredentials/ManageAPICredentialsActions.php'; +require_once __DIR__ + . '/../../resources/ManageAPICredentials/ManageAPICredentialsActions.php'; class ManageUnrenewedAPICredentialsTest extends PHPUnit_Extensions_Database_TestCase { @@ -31,10 +32,13 @@ class ManageUnrenewedAPICredentialsTest extends PHPUnit_Extensions_Database_Test public function __construct() { parent::__construct(); - // Use a local instance to avoid Mess Detector's whinging about avoiding - // static access. + /** + * Use a local instance to avoid Mess Detector's + * whinging about avoiding static access. + */ $this->dbOpsFactory = new PHPUnit_Extensions_Database_Operation_Factory(); } + /** * Overridden. */ @@ -44,27 +48,40 @@ public static function setUpBeforeClass() echo "\n\n-------------------------------------------------\n"; echo "Executing ManageUnrenewedAPICredentialsTest. . .\n"; } + /** * Overridden. Returns the test database connection. + * * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection */ protected function getConnection() { require_once __DIR__ . '/../doctrine/bootstrap_pdo.php'; + return getConnectionToTestDB(); } + /** * Overridden. Returns the test dataset. - * Defines how the initial state of the database should look before each test is executed. + * Defines how the initial state of the database + * should look before each test is executed. + * * @return PHPUnit_Extensions_Database_DataSet_IDataSet */ protected function getDataSet() { - $dataset = $this->createFlatXMLDataSet(__DIR__ . '/../doctrine/truncateDataTables.xml'); + $dataset = $this->createFlatXMLDataSet( + __DIR__ . '/../doctrine/truncateDataTables.xml' + ); + return $dataset; - // Use below to return an empty data set if we don't want to truncate and seed - //return new PHPUnit_Extensions_Database_DataSet_DefaultDataSet(); + /** + * Use below to return an empty data set + * if we don't want to truncate and seed. + */ + // return new PHPUnit_Extensions_Database_DataSet_DefaultDataSet(); } + /** * Overridden. */ @@ -75,11 +92,16 @@ protected function getSetUpOperation() //return PHPUnit_Extensions_Database_Operation_Factory::UPDATE(); //return PHPUnit_Extensions_Database_Operation_Factory::NONE(); // - // Issue a DELETE from
Type Identifier UserLast Used + Last Used + Write Edit Delete
- getType())?> + getType()); ?> - getIdentifier())?> + getIdentifier()); ?> getUser() != null) { - // Credentials added prior to 5.8 have no owning user - echo "getUser()->getId(), - "\" "; - echo "title=\"", $APIAuthEnt->getUser()->getFullname(), "\">"; - echo substr($APIAuthEnt->getUser()->getSurname(), 0, 10); + /** + * Credentials added prior to 5.8 + * have no owning user + */ + echo "getUser()->getId(), + "\" "; + echo "title=\"", + $APIAuthEnt->getUser()->getFullname(), + "\">"; + echo substr( + $APIAuthEnt->getUser()->getSurname(), + 0, + 10 + ); echo ""; } ?> + getLastUseTime(); + if ($useTime == null) { - $titleStr = 'Created/Renewed ' . $APIAuthEnt->getLastRenewTime()->format('d-m-Y H:iTP'); - echo '
Unused
'; + $titleStr = 'Created/Renewed ' + . $APIAuthEnt->getLastRenewTime()->format( + 'd-m-Y H:iTP' + ); + + echo '
Unused
'; } else { - $titleStr = 'Last used ' . $useTime->format('d-m-Y H:iTP'); - echo '
' . $useTime->format('d-m-y') . '
'; + $titleStr = 'Last used ' . $useTime->format( + 'd-m-Y H:iTP' + ); + + echo '
', + $useTime->format('d-m-y'), '
'; } ?>
+ getAllowAPIWrite())) { - echo '"' . \GocContextPath::getPath() . 'img/tick.png"'; + echo '"', \GocContextPath::getPath(), + 'img/tick.png"'; echo 'title="API write enabled"'; } else { - echo '"' . \GocContextPath::getPath() . 'img/cross.png"'; + echo '"', \GocContextPath::getPath(), + 'img/cross.png"'; echo 'title="API write disabled"'; } ?> /> -
- + +
-
- + +
which is more portable than a - // TRUNCATE table
(some DBs require high privileges for truncate statements - // and also do not allow truncates across tables with FK contstraints e.g. Oracle) + /** + * Issue a DELETE from
which is more portable than a + * TRUNCATE table
(some DBs require high privileges + * for truncate statements and also do not allow truncates across + * tables with FK contstraints e.g. Oracle) + */ + return $this->dbOpsFactory->DELETE_ALL(); } + /** * Overridden. */ @@ -88,6 +110,7 @@ protected function getTearDownOperation() // NONE is default return $this->dbOpsFactory->NONE(); } + /** * Sets up the fixture, e.g create a new entityManager for each test run * This method is called before each test method is executed. @@ -102,25 +125,32 @@ protected function setUp() date_default_timezone_set("UTC"); } + /** * Run after each test function to prevent pile-up of database connections. */ protected function tearDown() { parent::tearDown(); + if (!is_null($this->entityManager)) { $this->entityManager->getConnection()->close(); } } + /** * @return EntityManager */ private function createEntityManager() { - $entityManager = null; // Initialise in local scope to avoid unused variable warnings + // Initialise in local scope to avoid unused variable warnings + $entityManager = null; + require __DIR__ . '/../doctrine/bootstrap_doctrine.php'; + return $entityManager; } + public function testLastRenewTime() { print __METHOD__ . "\n"; @@ -132,7 +162,11 @@ public function testLastRenewTime() $entityManager = $this->createEntityManager(); - $actions = new ManageAPICredentialsActions(false, $entityManager, $baseTime); + $actions = new ManageAPICredentialsActions( + false, + $entityManager, + $baseTime + ); // Fetch credentials not renewed in the last 5 months - should be 6. $creds = $actions->getCreds(5, 'lastRenewTime'); diff --git a/tests/resourcesTests/ManageUnusedAPICredentialsTest.php b/tests/resourcesTests/ManageUnusedAPICredentialsTest.php index ca5dd4a33..d68210e7b 100644 --- a/tests/resourcesTests/ManageUnusedAPICredentialsTest.php +++ b/tests/resourcesTests/ManageUnusedAPICredentialsTest.php @@ -21,7 +21,8 @@ require_once __DIR__ . '/ManageAPICredentialsTestUtils.php'; require_once __DIR__ . '/../unit/lib/Gocdb_Services/ServiceTestUtil.php'; -require_once __DIR__ . '/../../resources/ManageAPICredentials/ManageAPICredentialsActions.php'; +require_once __DIR__ + . '/../../resources/ManageAPICredentials/ManageAPICredentialsActions.php'; class ManageUnusedAPICredentialsTest extends PHPUnit_Extensions_Database_TestCase { @@ -31,10 +32,14 @@ class ManageUnusedAPICredentialsTest extends PHPUnit_Extensions_Database_TestCas public function __construct() { parent::__construct(); - // Use a local instance to avoid Mess Detector's whinging about avoiding - // static access. - $this->dbOpsFactory = new PHPUnit_Extensions_Database_Operation_Factory(); + /** + * Use a local instance to avoid Mess Detector's + * whinging about avoiding static access. + */ + $this->dbOpsFactory = + new PHPUnit_Extensions_Database_Operation_Factory(); } + /** * Overridden. */ @@ -44,6 +49,7 @@ public static function setUpBeforeClass() echo "\n\n-------------------------------------------------\n"; echo "Executing ManageUnusedAPICredentialsTest. . .\n"; } + /** * Overridden. Returns the test database connection. * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection @@ -51,20 +57,31 @@ public static function setUpBeforeClass() protected function getConnection() { require_once __DIR__ . '/../doctrine/bootstrap_pdo.php'; + return getConnectionToTestDB(); } + /** * Overridden. Returns the test dataset. - * Defines how the initial state of the database should look before each test is executed. + * Defines how the initial state of the database should + * look before each test is executed. + * * @return PHPUnit_Extensions_Database_DataSet_IDataSet */ protected function getDataSet() { - $dataset = $this->createFlatXMLDataSet(__DIR__ . '/../doctrine/truncateDataTables.xml'); + $dataset = $this->createFlatXMLDataSet( + __DIR__ . '/../doctrine/truncateDataTables.xml' + ); + return $dataset; - // Use below to return an empty data set if we don't want to truncate and seed + /** + * Use below to return an empty data set + * if we don't want to truncate and seed + */ //return new PHPUnit_Extensions_Database_DataSet_DefaultDataSet(); } + /** * Overridden. */ @@ -75,19 +92,24 @@ protected function getSetUpOperation() //return PHPUnit_Extensions_Database_Operation_Factory::UPDATE(); //return PHPUnit_Extensions_Database_Operation_Factory::NONE(); // - // Issue a DELETE from
which is more portable than a - // TRUNCATE table
(some DBs require high privileges for truncate statements - // and also do not allow truncates across tables with FK contstraints e.g. Oracle) + /** + * Issue a DELETE from
which is more portable than a + * TRUNCATE table
(some DBs require high privileges + * for truncate statements and also do not allow truncates + * across tables with FK contstraints e.g. Oracle) + */ return $this->dbOpsFactory->DELETE_ALL(); } + /** * Overridden. */ protected function getTearDownOperation() { - // NONE is default + // NONE is default return $this->dbOpsFactory->NONE(); } + /** * Sets up the fixture, e.g create a new entityManager for each test run * This method is called before each test method is executed. @@ -96,31 +118,38 @@ protected function setUp() { parent::setUp(); $this->entityManager = $this->createEntityManager(); - // Pass the Entity Manager into the Factory to allow Gocdb_Services - // to use other Gocdb_Services. + // Pass the Entity Manager into the Factory to allow Gocdb_Services + // to use other Gocdb_Services. \Factory::setEntityManager($this->entityManager); date_default_timezone_set("UTC"); } + /** * Run after each test function to prevent pile-up of database connections. */ protected function tearDown() { parent::tearDown(); + if (!is_null($this->entityManager)) { $this->entityManager->getConnection()->close(); } } + /** * @return EntityManager */ private function createEntityManager() { - $entityManager = null; // Initialise in local scope to avoid unused variable warnings + // Initialise in local scope to avoid unused variable warnings + $entityManager = null; + require __DIR__ . '/../doctrine/bootstrap_doctrine.php'; + return $entityManager; } + public function testLastUseTime() { print __METHOD__ . "\n"; @@ -130,7 +159,11 @@ public function testLastUseTime() $entityManager = $this->createEntityManager(); - $actions = new ManageAPICredentialsActions(false, $entityManager, $baseTime); + $actions = new ManageAPICredentialsActions( + false, + $entityManager, + $baseTime + ); // Fetch credentials not used in the last 7 months - should be 2 $creds = $actions->getCreds(7, 'lastUseTime'); @@ -158,7 +191,10 @@ public function testLastUseTime() $this->assertCount( 1, $creds, - 'Unexpected credential count following deletion based on last use time.' + ( + "Unexpected credential count following " + . "deletion based on last use time." + ) ); } }