Hoa central
Acl.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Acl;
38 
39 use Hoa\Core;
40 use Hoa\Graph;
41 
52 class Acl
53 {
59  const DELETE_CASCADE = true;
60 
66  const DELETE_RESTRICT = false;
67 
73  private static $_instance = null;
74 
80  protected $users = [];
81 
87  protected $groups = null;
88 
94  protected $services = [];
95 
96 
97 
105  private function __construct($loop = Graph::DISALLOW_LOOP)
106  {
107  $this->groups = Graph::getInstance(
109  $loop
110  );
111 
112  return;
113  }
114 
122  public static function getInstance($loop = Graph::DISALLOW_LOOP)
123  {
124  if (null === static::$_instance) {
125  static::$_instance = new static($loop);
126  }
127 
128  return static::$_instance;
129  }
130 
138  public function addUser(User $user)
139  {
140  if ($this->userExists($user->getId())) {
141  throw new Exception(
142  'User %s is already registried.',
143  0,
144  $user->getId()
145  );
146  }
147 
148  $this->users[$user->getId()] = $user;
149 
150  return;
151  }
152 
159  public function deleteUser($user)
160  {
161  if ($user instanceof User) {
162  $user = $user->getId();
163  }
164 
165  unset($this->users[$user]);
166 
167  return;
168  }
169 
180  public function addGroup(Group $group, $inherit = [])
181  {
182  if (!is_array($inherit)) {
183  $inherit = [$inherit];
184  }
185 
186  foreach ($inherit as &$in) {
187  if ($in instanceof Group) {
188  $in = $in->getId();
189  }
190  }
191 
192  try {
193  $this->getGroups()->addNode($group, $inherit);
194  } catch (Graph\Exception $e) {
195  throw new Exception($e->getMessage(), $e->getCode());
196  }
197 
198  return;
199  }
200 
209  public function deleteGroup($groupId, $propagate = self::DELETE_RESTRICT)
210  {
211  if ($groupId instanceof Group) {
212  $groupId = $groupId->getId();
213  }
214 
215  try {
216  $this->getGroups()->deleteNode($groupId, $propagate);
217  } catch (Graph\Exception $e) {
218  throw new Exception($e->getMessage(), $e->getCode());
219  }
220 
221  foreach ($this->getUsers() as $userId => $user) {
222  $user->deleteGroup($groupId);
223  }
224 
225  return;
226  }
227 
235  public function addService(Service $service)
236  {
237  if ($this->serviceExists($service->getId())) {
238  throw new Exception(
239  'Service %s is already registried.',
240  1,
241  $service->getId()
242  );
243  }
244 
245  $this->services[$service->getId()] = $service;
246 
247  return;
248  }
249 
256  public function deleteService($service)
257  {
258  if ($service instanceof Service) {
259  $service = $service->getId();
260  }
261 
262  unset($this->services[$service]);
263 
264  return;
265  }
266 
275  public function allow($groupId, $permissions = [])
276  {
277  if (false === $this->groupExists($groupId)) {
278  throw new Exception(
279  'Group %s does not exist.',
280  2,
281  $groupId
282  );
283  }
284 
285  $this->getGroups()->getNode($groupId)->addPermission($permissions);
286 
287  foreach ($this->getGroups()->getChild($groupId) as $subGroupId => $group) {
288  $this->allow($subGroupId, $permissions);
289  }
290 
291  return;
292  }
293 
302  public function deny($groupId, $permissions = [])
303  {
304  if ($groupId instanceof Group) {
305  $groupId = $groupId->getId();
306  }
307 
308  if (false === $this->groupExists($groupId)) {
309  throw new Exception(
310  'Group %s does not exist.',
311  3,
312  $groupId
313  );
314  }
315 
316  $this->getGroups()->getNode($groupId)->deletePermission($permissions);
317 
318  foreach ($this->getGroups()->getChild($groupId) as $subGroupId => $group) {
319  $this->deny($subGroupId, $permissions);
320  }
321 
322  return;
323  }
324 
339  public function isAllowed(
340  $user,
341  $permission,
342  $service = null,
343  IAcl\Assert $assert = null
344  ) {
345  if ($user instanceof User) {
346  $user = $user->getId();
347  }
348 
349  if ($permission instanceof Permission) {
350  $permission = $permission->getId();
351  }
352 
353  if (is_array($permission)) {
354  throw new Exception(
355  'Should check one permission, not a list of permissions.',
356  4
357  );
358  }
359 
360  if (null !== $service &&
361  !($service instanceof Service)) {
362  $service = $this->getService($service);
363  }
364 
365  $user = $this->getUser($user);
366  $out = false;
367 
368  if (null !== $service &&
369  false === $service->userExists($user->getId())) {
370  return false;
371  }
372 
373  foreach ($user->getGroups() as $groupId) {
374  $out |= $this->isGroupAllowed($groupId, $permission);
375  }
376 
377  $out = (bool) $out;
378 
379  if (null === $assert) {
380  return $out;
381  }
382 
383  return $out && $assert->assert();
384  }
385 
396  public function isGroupAllowed($group, $permission)
397  {
398  if ($group instanceof Group) {
399  $group = $group->getId();
400  }
401 
402  if ($permission instanceof Permission) {
403  $permission = $permission->getId();
404  }
405 
406  if (is_array($permission)) {
407  throw new Exception(
408  'Should check one permission, not a list of permissions.',
409  5
410  );
411  }
412 
413  if (false === $this->groupExists($group)) {
414  throw new Exception(
415  'Group %s does not exist.',
416  6,
417  $group
418  );
419  }
420 
421  return
422  $this
423  ->getGroups()
424  ->getNode($group)
425  ->permissionExists($permission);
426  }
427 
434  public function userExists($userId)
435  {
436  if ($userId instanceof User) {
437  $userId = $userId->getId();
438  }
439 
440  return isset($this->users[$userId]);
441  }
442 
449  public function groupExists($groupId)
450  {
451  if ($groupId instanceof Group) {
452  $groupId = $groupId->getId();
453  }
454 
455  return $this->getGroups()->nodeExists($groupId);
456  }
457 
464  public function serviceExists($serviceId)
465  {
466  if ($serviceId instanceof Service) {
467  $serviceId = $serviceId->getId();
468  }
469 
470  return isset($this->services[$serviceId]);
471  }
472 
480  public function getUser($userId)
481  {
482  if (false === $this->userExists($userId)) {
483  throw new Exception('User %s does not exist.', 7, $userId);
484  }
485 
486  return $this->users[$userId];
487  }
488 
494  protected function getUsers()
495  {
496  return $this->users;
497  }
498 
506  public function getGroup($groupId)
507  {
508  if (false === $this->groupExists($groupId)) {
509  throw new Exception('Group %s does not exist.', 8, $groupId);
510  }
511 
512  return $this->getGroups()->getNode($groupId);
513  }
514 
520  protected function getGroups()
521  {
522  return $this->groups;
523  }
524 
532  public function getService($serviceId)
533  {
534  if (false === $this->serviceExists($serviceId)) {
535  throw new Exception('Service %s does not exist.', 9, $serviceId);
536  }
537 
538  return $this->services[$serviceId];
539  }
540 
546  protected function getServices()
547  {
548  return $this->services;
549  }
550 
556  public function __toString()
557  {
558  return $this->getGroups()->__toString();
559  }
560 }
561 
565 Core\Consistency::flexEntity('Hoa\Acl\Acl');
getGroup($groupId)
Definition: Acl.php:506
const DELETE_RESTRICT
Definition: Acl.php:66
isGroupAllowed($group, $permission)
Definition: Acl.php:396
serviceExists($serviceId)
Definition: Acl.php:464
getUser($userId)
Definition: Acl.php:480
deleteService($service)
Definition: Acl.php:256
deny($groupId, $permissions=[])
Definition: Acl.php:302
__construct($loop=Graph::DISALLOW_LOOP)
Definition: Acl.php:105
__toString()
Definition: Acl.php:556
allow($groupId, $permissions=[])
Definition: Acl.php:275
const TYPE_ADJACENCYLIST
Definition: Graph.php:59
userExists($userId)
Definition: Acl.php:434
Definition: Acl.php:37
static $_instance
Definition: Acl.php:73
addUser(User $user)
Definition: Acl.php:138
static getInstance($type=self::TYPE_ADJACENCYLIST)
Definition: Graph.php:126
addService(Service $service)
Definition: Acl.php:235
getServices()
Definition: Acl.php:546
getService($serviceId)
Definition: Acl.php:532
const DISALLOW_LOOP
Definition: Graph.php:73
groupExists($groupId)
Definition: Acl.php:449
isAllowed($user, $permission, $service=null, IAcl\Assert $assert=null)
Definition: Acl.php:339
addGroup(Group $group, $inherit=[])
Definition: Acl.php:180
$services
Definition: Acl.php:94
getUsers()
Definition: Acl.php:494
deleteGroup($groupId, $propagate=self::DELETE_RESTRICT)
Definition: Acl.php:209
getGroups()
Definition: Acl.php:520
const DELETE_CASCADE
Definition: Acl.php:59
static getInstance($loop=Graph::DISALLOW_LOOP)
Definition: Acl.php:122
deleteUser($user)
Definition: Acl.php:159