Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.
 All Data Structures Functions Variables Pages
Permitable.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
37  class Permitable extends Item
38  {
44  private $rightsChanged = false;
45 
51  private $policiesChanged = false;
52 
53  public function contains(Permitable $permitable)
54  {
55  return $this->isSame($permitable);
56  }
57 
63  public function getEffectiveRight($moduleName, $rightName)
64  {
65  assert('is_string($moduleName)');
66  assert('is_string($rightName)');
67  assert('$moduleName != ""');
68  assert('$rightName != ""');
69  return $this->getActualRight($moduleName, $rightName) == Right::ALLOW ? Right::ALLOW : Right::DENY;
70  }
71 
78  public function getActualRight($moduleName, $rightName)
79  {
80  assert('is_string($moduleName)');
81  assert('is_string($rightName)');
82  assert('$moduleName != ""');
83  assert('$rightName != ""');
84  if (!SECURITY_OPTIMIZED)
85  {
86  // The slow way will remain here as documentation
87  // for what the optimized way is doing.
88  $combinedRight = $this->getExplicitActualRight ($moduleName, $rightName) |
89  $this->getInheritedActualRight ($moduleName, $rightName) |
90  $this->getPropagatedActualAllowRight($moduleName, $rightName);
91  if (($combinedRight & Right::DENY) == Right::DENY)
92  {
93  return Right::DENY;
94  }
95  assert('in_array($combinedRight, array(Right::NONE, Right::ALLOW))');
96  return $combinedRight;
97  }
98  else
99  {
100  // You must cast a Permitable down to a User or Group.
101  // This is a limitation of the RedBeanModel's mapping to
102  // the database.
103  throw new NotSupportedException();
104  }
105  }
106 
112  public function getExplicitActualRight($moduleName, $rightName)
113  {
114  assert('is_string($moduleName)');
115  assert('is_string($rightName)');
116  assert('$moduleName != ""');
117  assert('$rightName != ""');
118  if (!SECURITY_OPTIMIZED)
119  {
120  // The slow way will remain here as documentation
121  // for what the optimized way is doing.
122  $combinedRight = Right::NONE;
123  try
124  {
125  foreach ($this->rights as $right)
126  {
127  if ($right->moduleName == $moduleName &&
128  $right->name == $rightName)
129  {
130  $combinedRight |= $right->type;
131  if ($right->type == Right::DENY)
132  {
133  break; // Shortcircuit.
134  }
135  }
136  }
137  }
138  catch (NotSupportedException $e)
139  {
140  //Super Administrator group for example doesn't allow right retrieval.
141  }
142  if (($combinedRight & Right::DENY) == Right::DENY)
143  {
144  return Right::DENY;
145  }
146  assert('in_array($combinedRight, array(Right::NONE, Right::ALLOW))');
147  return $combinedRight;
148  }
149  else
150  {
151  $permitableId = $this->getClassId('Permitable');
152  return intval(ZurmoDatabaseCompatibilityUtil::
153  callFunction("get_permitable_explicit_actual_right($permitableId, '$moduleName', '$rightName')"));
154  }
155  }
156 
157  public function getPropagatedActualAllowRight($moduleName, $rightName)
158  {
159  // You must cast a Permitable down to a User or Group.
160  // This is a limitation of the RedBeanModel's mapping to
161  // the database.
162  throw new NotSupportedException();
163  }
164 
171  public function getInheritedActualRight($moduleName, $rightName)
172  {
173  assert('is_string($moduleName)');
174  assert('is_string($rightName)');
175  assert('$moduleName != ""');
176  assert('$rightName != ""');
177  if (!SECURITY_OPTIMIZED)
178  {
179  // The slow way will remain here as documentation
180  // for what the optimized way is doing.
181  $combinedRight = $this->getInheritedActualRightIgnoringEveryone ($moduleName, $rightName) |
182  Group::getByName(Group::EVERYONE_GROUP_NAME)->getExplicitActualRight($moduleName, $rightName);
183  if (($combinedRight & Right::DENY) == Right::DENY)
184  {
185  return Right::DENY;
186  }
187  assert('in_array($combinedRight, array(Right::NONE, Right::ALLOW))');
188  return $combinedRight;
189  }
190  else
191  {
192  // You must cast a Permitable down to a User or Group.
193  // This is a limitation of the RedBeanModel's mapping to
194  // the database.
195  throw new NotSupportedException();
196  }
197  }
198 
199  protected function getInheritedActualRightIgnoringEveryone($moduleName, $rightName)
200  {
201  // You must cast a Permitable down to a User or Group.
202  // This is a limitation of the RedBeanModel's mapping to
203  // the database.
204  throw new NotSupportedException();
205  }
206 
207  public function setRight($moduleName, $rightName, $type = Right::ALLOW)
208  {
209  assert('is_string($moduleName)');
210  assert('is_string($rightName)');
211  assert('$moduleName != ""');
212  assert('$rightName != ""');
213  assert('in_array($type, array(Right::ALLOW, Right::DENY))');
214  $found = false;
215  foreach ($this->rights as $right)
216  {
217  if ($right->moduleName == $moduleName &&
218  $right->name == $rightName)
219  {
220  $right->type = $type;
221  $found = true;
222  $this->onChangeRights();
223  break;
224  }
225  }
226  if (!$found)
227  {
228  $right = new Right();
229  $right->moduleName = $moduleName;
230  $right->name = $rightName;
231  $right->type = $type;
232  $this->rights->add($right);
233  $this->onChangeRights();
234  }
235  }
236 
237  public function removeRight($moduleName, $rightName, $type = Right::ALLOW)
238  {
239  assert('is_string($moduleName)');
240  assert('is_string($rightName)');
241  assert('$moduleName != ""');
242  assert('$rightName != ""');
243  assert('in_array($type, array(Right::ALLOW, Right::DENY))');
244  foreach ($this->rights as $right)
245  {
246  if ($right->moduleName == $moduleName &&
247  $right->name == $rightName)
248  {
249  $this->rights->remove($right);
250  $this->onChangeRights();
251  }
252  }
253  }
254 
255  public function removeAllRights()
256  {
257  $this->rights->removeAll();
258  $this->onChangeRights();
259  }
260 
261  protected function onChangeRights()
262  {
263  $this->rightsChanged = true;
264  }
265 
266  protected function afterSave()
267  {
268  parent::afterSave();
269  if ($this->rightsChanged)
270  {
271  RightsCache::forgetAll();
272  $this->rightsChanged = false;
273  }
274  if ($this->policiesChanged)
275  {
276  PoliciesCache::forgetAll();
277  $this->policiesChanged = false;
278  }
279  }
280 
286  public function getEffectivePolicy($moduleName, $policyName)
287  {
288  assert('is_string($moduleName)');
289  assert('is_string($policyName)');
290  assert('$moduleName != ""');
291  assert('$policyName != ""');
292  $value = $this->getActualPolicy($moduleName, $policyName);
293  if ($value !== null)
294  {
295  return $value;
296  }
297  return $moduleName::getPolicyDefault($policyName);
298  }
299 
305  public function getActualPolicy($moduleName, $policyName)
306  {
307  assert('is_string($moduleName)');
308  assert('is_string($policyName)');
309  assert('$moduleName != ""');
310  assert('$policyName != ""');
311  $value = $this->getExplicitActualPolicy($moduleName, $policyName);
312  if ($value !== null)
313  {
314  return $value;
315  }
316  $value = $this->getInheritedActualPolicy($moduleName, $policyName);
317  if ($value !== null)
318  {
319  return $value;
320  }
321  if (!SECURITY_OPTIMIZED)
322  {
323  return Group::getByName(Group::EVERYONE_GROUP_NAME)->getExplicitActualPolicy($moduleName, $policyName);
324  }
325  else
326  {
327  $permitableName = 'Everyone';
328  try
329  {
330  // not using $default to save cpu cycles, else default value would have to be computed every time.
331  return PoliciesCache::getEntry($permitableName . $moduleName . $policyName . 'ActualPolicy');
332  }
333  catch (NotFoundException $e)
334  {
335  $actualPolicy = ZurmoDatabaseCompatibilityUtil::
336  callFunction("get_named_group_explicit_actual_policy(
337  'Everyone', '$moduleName', '$policyName')");
338  }
339  PoliciesCache::
340  cacheEntry($permitableName . $moduleName . $policyName . 'ActualPolicy', $actualPolicy);
341  return $actualPolicy;
342  }
343  }
344 
350  public function getExplicitActualPolicy($moduleName, $policyName)
351  {
352  assert('is_string($moduleName)');
353  assert('is_string($policyName)');
354  assert('$moduleName != ""');
355  assert('$policyName != ""');
356  if (!SECURITY_OPTIMIZED)
357  {
358  // The slow way will remain here as documentation
359  // for what the optimized way is doing.
360  foreach ($this->policies as $policy)
361  {
362  if ($policy->moduleName == $moduleName &&
363  $policy->name == $policyName)
364  {
365  return $policy->value;
366  }
367  }
368  return null;
369  }
370  else
371  {
372  $permitableId = $this->getClassId('Permitable');
373  try
374  {
375  // not using $default because computing default value would involve extra cpu cycles each time.
376  return PoliciesCache::getEntry($permitableId . $moduleName . $policyName . 'ExplicitActualPolicy');
377  }
378  catch (NotFoundException $e)
379  {
380  $explictActualPolicy = ZurmoDatabaseCompatibilityUtil::
381  callFunction("get_permitable_explicit_actual_policy(
382  $permitableId, '$moduleName', '$policyName')");
383  }
384  PoliciesCache::
385  cacheEntry($permitableId . $moduleName . $policyName . 'ExplicitActualPolicy', $explictActualPolicy);
386  return $explictActualPolicy;
387  }
388  }
389 
395  public function getInheritedActualPolicy($moduleName, $policyName)
396  {
397  assert('is_string($moduleName)');
398  assert('is_string($policyName)');
399  assert('$moduleName != ""');
400  assert('$policyName != ""');
401  $value = $this->getInheritedActualPolicyIgnoringEveryone($moduleName, $policyName);
402  if ($value !== null)
403  {
404  return $value;
405  }
406  return Group::getByName(Group::EVERYONE_GROUP_NAME)->getExplicitActualPolicy($moduleName, $policyName);
407  }
408 
414  public function setPolicy($moduleName, $policyName, $value)
415  {
416  assert('is_string($moduleName)');
417  assert('is_string($policyName)');
418  assert('$moduleName != ""');
419  assert('$policyName != ""');
420  assert('!is_bool($value)'); // Remember booleans must be specified as 1 & 0 for RedBeanModel.
421  assert('$value !== null');
422  $found = false;
423  foreach ($this->policies as $policy)
424  {
425  if ($policy->moduleName == $moduleName &&
426  $policy->name == $policyName)
427  {
428  $policy->value = $value;
429  $found = true;
430  $this->onChangePolicies();
431  break;
432  }
433  }
434  if (!$found)
435  {
436  $policy = new Policy();
437  $policy->moduleName = $moduleName;
438  $policy->name = $policyName;
439  $policy->value = $value;
440  $this->policies->add($policy);
441  $this->onChangePolicies();
442  }
443  }
444 
449  public function removePolicy($moduleName, $policyName)
450  {
451  assert('is_string($moduleName)');
452  assert('is_string($policyName)');
453  assert('$moduleName != ""');
454  assert('$policyName != ""');
455  foreach ($this->policies as $policy)
456  {
457  if ($policy->moduleName == $moduleName &&
458  $policy->name == $policyName)
459  {
460  $this->policies->remove($policy);
461  $this->onChangePolicies();
462  }
463  }
464  }
465 
466  public function removeAllPolicies()
467  {
468  $this->policies->removeAll();
469  }
470 
471  protected function onChangePolicies()
472  {
473  $this->policiesChanged = true;
474  }
475 
476  public static function getDefaultMetadata()
477  {
478  $metadata = parent::getDefaultMetadata();
479  $metadata[__CLASS__] = array(
480  'relations' => array(
481  'policies' => array(static::HAS_MANY, 'Policy', static::OWNED),
482  'rights' => array(static::HAS_MANY, 'Right', static::OWNED),
483  ),
484  'foreignRelations' => array(
485  'Permission',
486  ),
487  'indexes' => array(
488  'item_id' => array(
489  'members' => array('item_id'),
490  'unique' => false),
491  ),
492  );
493  return $metadata;
494  }
495 
496  public static function isTypeDeletable()
497  {
498  return false;
499  }
500  }
501 ?>
getExplicitActualRight($moduleName, $rightName)
Definition: Permitable.php:112
removePolicy($moduleName, $policyName)
Definition: Permitable.php:449
getClassId($modelClassName)
setPolicy($moduleName, $policyName, $value)
Definition: Permitable.php:414
getActualPolicy($moduleName, $policyName)
Definition: Permitable.php:305
getInheritedActualRight($moduleName, $rightName)
Definition: Permitable.php:171
getEffectiveRight($moduleName, $rightName)
Definition: Permitable.php:63
getInheritedActualPolicy($moduleName, $policyName)
Definition: Permitable.php:395
getExplicitActualPolicy($moduleName, $policyName)
Definition: Permitable.php:350
static getByName($name)
Definition: Group.php:57
Definition: Item.php:37
getActualRight($moduleName, $rightName)
Definition: Permitable.php:78
Definition: Right.php:37
getEffectivePolicy($moduleName, $policyName)
Definition: Permitable.php:286
isSame(RedBeanModel $model)
Generated on Wed Dec 2 2020 07:10:32
Account Suspended
Account Suspended
This Account has been suspended.
Contact your hosting provider for more information.