-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathNotificationService.php
148 lines (129 loc) · 6.7 KB
/
NotificationService.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<?php
namespace org\gocdb\services;
/*
* Copyright ? 2011 STFC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
require_once __DIR__ . '/AbstractEntityService.php';
require_once __DIR__ . '/Factory.php';
require_once __DIR__ . '/User.php';
/**
* A service layer to aid the sending of notification emails
*
* @author James McCarthy
*/
class NotificationService extends AbstractEntityService {
/**
* This class will take an entity of either site, service group, NGI or Project.
* It will then get the roles from the entity
* and then get the users for each of those roles. Then using the authoriseAction function it will
* ascertain if a given user has the permission to grant a role. If they do there email address is added to an array. This array
* of email addresses will then be sent a notification that they have a pending role request they can approve.
*
* If a site or NGI has no users with roles attached to it due to being newly created then this method will get the parent NGI and
* send an email to those users to approve. It does this by passing the parent entity back into this method recursively.
*
*
* @param OwnedEntity $entity An instance of Site,Service,NGI,Project or other OwnedEntity.
* @return void
*/
public function roleRequest ($roleRequested, $requestingUser, $entity) {
$project = null;
$authorisingUserIds = [];
$projectIds = null;
// For each role the entity has.
foreach ($entity->getRoles() as $role) {
// Get the corresponding user.
$user = $role->getUser();
// Determine if that user has roles that can approve role requests,
// this role may not be the same as the one currently in the $role
// variable.
$enablingRoles = \Factory::getRoleActionAuthorisationService()->authoriseAction(\Action::GRANT_ROLE, $entity, $user)->getGrantingRoles();
// If they can, add their user id to the list of authorising user
// ids.
if (count($enablingRoles) > 0) {
$authorisingUserIds [] = $user->getId();
}
}
// If there are no users that are able to grant the role over this entity,
// we will email the parent entity for approval.
if (count($authorisingUserIds) == 0) {
if ($entity instanceof \Site) {
// Sites can only have a single parent NGI.
$this->roleRequest ( $roleRequested, $requestingUser, $entity->getNgi () ); // Recursivly call this function to send email to the NGI users
} else if ($entity instanceof \NGI) {
/*
* NGIs can belong to multiple Projects.
* It is important to remove duplicate projects here otherwise we will spam the same addresses as we recursively call this method.
*/
$projects = $entity->getProjects (); // set project with the NGI's parent project and later recurse with this
$projectIds = array();
// Get the ID's of each project so we can remove duplicates
foreach ( $projects as $project ) {
$projectIds [] = $project->getId ();
}
$projectIds = array_unique ( $projectIds );
}
} else {
// If the entity has valid users who can approve the role then send the email notification.
// Remove duplicate user ids from array
$authorisingUserIds = array_unique ( $authorisingUserIds );
// Send email to all users who can approve this role request
foreach ( $authorisingUserIds as $userId ) {
$approvingUser = \Factory::getUserService()->getUser($userId);
$this->sendEmail($roleRequested, $requestingUser, $entity->getName(), $approvingUser);
}
}
/**
* For each project ID get the entity and run this function again for each entity so
* that for each NGI the email notification is sent to all users who hold roles over the parent
* NGI(s).
*/
if ($projectIds != null) {
foreach ( $projectIds as $pid ) {
$project = \Factory::getOwnedEntityService ()->getOwnedEntityById ( $pid );
$this->roleRequest ( $roleRequested, $requestingUser, $project );
}
}
}
/**
* Return the PortalURL to enable an accurate link to the role approval view to be created
*/
private function getWebPortalURL() {
return \Factory::getConfigService()->GetPortalURL();
}
private function sendEmail($roleRequested, $requestingUser, $entityName, $approvingUser) {
$subject = sprintf(
'GOCDB: A Role request from %1$s %2$s over %3$s requires your attention',
$requestingUser->getForename(),
$requestingUser->getSurname(),
$roleRequested->getOwnedEntity()->getName()
);
$configService = \Factory::getConfigService();
$body = sprintf(
implode("\n", array(
'Dear %1$s,',
'',
'%2$s %3$s requested the "%4$s" role over %5$s which requires your attention.',
'',
'You can approve or deny the request here:',
' %6$s/index.php?Page_Type=Role_Requests',
'',
'Note: This role could already have been approved or denied by another GOCDB User',
'',
'Please do not reply to this email. If you would like to get in touch with the ' .
'GOCDB admins please send an email to: %7$s',
)),
$approvingUser->getForename(),
$requestingUser->getForename(),
$requestingUser->getSurname(),
$roleRequested->getRoleType()->getName(),
$roleRequested->getOwnedEntity()->getName(),
$this->getWebPortalURL(),
$configService->getEmailTo()
);
$emailAddress = $approvingUser->getEmail();
$emailSentFrom = $configService->getEmailFrom();
$headers = "From: GOCDB <" . $emailSentFrom . ">";
\Factory::getEmailService()->send($emailAddress, $subject, $body, $headers);
}
}