CWIS Developer Documentation

- Home
- Main Page
- Classes
- Files

- File List
- File Members

PrivilegeSet.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: PrivilegeSet.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9
16 class PrivilegeSet {
17
18 # used as a field ID in conditions to test whether a resources is
19 # available as part of the privilege check
20 const HAVE_RESOURCE = -1;
21
29 function __construct($Data = NULL)
30 {
31 # if privilege data supplied
32 if ($Data !== NULL)
33 {
34 # if data is in legacy form (an array of privileges)
35 if (is_array($Data))
36 {
37 # set internal privilege set from array
38 $this->Privileges = $Data;
39 }
40 else
41 {
42 # set internal values from data
43 $this->LoadFromData($Data);
44 }
45 }
46 }
47
57 function Data($NewValue = NULL)
58 {
59 # if new data supplied
60 if ($NewValue !== NULL)
61 {
62 # unpack privilege data and load
63 $this->LoadFromData($NewValue);
64 }
65
66 # serialize current data and return to caller
67 $Data = array();
68 if (count($this->Privileges))
69 {
70 foreach ($this->Privileges as $Priv)
71 {
72 $Data["Privileges"][] = is_object($Priv)
73 ? array("SUBSET" => $Priv->Data())
74 : $Priv;
75 }
76 }
77 $Data["Logic"] = $this->Logic;
78 return serialize($Data);
79 }
80
91 function MeetsRequirements(CWUser $User, $Resource = self::NO_RESOURCE)
92 {
93 # when there are no requirements, then every user meets them
94 $Satisfied = TRUE;
95
96 # for each privilege requirement
97 foreach ($this->Privileges as $Priv)
98 {
99 # if privilege is actually a privilege subgroup
100 if (is_object($Priv))
101 {
102 # check if the subgroup is satisfied
103 $Satisfied = $Priv->MeetsRequirements($User, $Resource);
104 }
105 # else if privilege is actually a condition
106 elseif (is_array($Priv))
107 {
108 # check if condition is satisfied for the given resource
109 $Satisfied = $this->MeetsCondition($Priv, $Resource, $User);
110 }
111 # else privilege is actually a privilege
112 else
113 {
114 # check if user has the spcified privilege
115 $Satisfied = $User->HasPriv( $Priv );
116 }
117
118 # for AND logic, we can bail as soon as the first
119 # condition is not met
120 if ($this->Logic == "AND")
121 {
122 if (!$Satisfied)
123 {
124 break;
125 }
126 }
127 # conversely, for OR logic, we can bail as soon as any
128 # condition is met
129 else
130 {
131 if ($Satisfied)
132 {
133 break;
134 }
135 }
136 }
137
138 # report result of the test back to caller
139 return $Satisfied;
140 }
141
148 function AddPrivilege($Privilege)
149 {
150 # add privilege if not currently in set
151 if (!$this->IncludesPrivilege($Privilege))
152 {
153 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
154 $this->Privileges[] = $Privilege;
155 }
156 }
157
164 function RemovePrivilege($Privilege)
165 {
166 # remove privilege if currently in set
167 if ($this->IncludesPrivilege($Privilege))
168 {
169 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
170 $Index = array_search($Privilege, $this->Privileges);
171 unset($this->Privileges[$Index]);
172 }
173 }
174
180 function IncludesPrivilege($Privilege)
181 {
182 # check whether privilege is in our list and report to caller
183 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
184 return $this->IsInPrivilegeData($Privilege) ? TRUE : FALSE;
185 }
186
195 function GetPrivilegeInfo()
196 {
197 # grab privilege information and add logic
198 $Info = $this->Privileges;
199 $Info["Logic"] = $this->Logic;
200
201 # return privilege info array to caller
202 return $Info;
203 }
204
211 function GetPrivilegeList()
212 {
213 # create list of privileges with conditions stripped out
214 $List = array();
215 foreach ($this->Privileges as $Priv)
216 {
217 if (!is_array($Priv)) { $List[] = $Priv; }
218 }
219
220 # return list of privileges to caller
221 return $List;
222 }
223
238 function AddCondition($Field, $Value = NULL, $Operator = "==")
239 {
240 # get field ID
241 $FieldId = is_object($Field) ? $Field->Id() : $Field;
242
243 # set up condition array
244 $Condition = array(
245 "FieldId" => intval($FieldId),
246 "Operator" => trim($Operator),
247 "Value" => $Value);
248
249 # if condition is not already in set
250 if (!$this->IsInPrivilegeData($Condition))
251 {
252 # add condition to privilege set
253 $this->Privileges[] = $Condition;
254 }
255 }
256
268 function RemoveCondition($Field, $Value = NULL, $Operator = "==")
269 {
270 # get field ID
271 $FieldId = is_object($Field) ? $Field->Id() : $Field;
272
273 # set up condition array
274 $Condition = array(
275 "FieldId" => intval($FieldId),
276 "Operator" => trim($Operator),
277 "Value" => $Value);
278
279 # if condition is in set
280 if ($this->IsInPrivilegeData($Condition))
281 {
282 # remove condition from privilege set
283 $Index = array_search($Condition, $this->Privileges);
284 unset($this->Privileges[$Index]);
285 }
286 }
287
292 function AddSet(PrivilegeSet $Set)
293 {
294 # if subgroup is not already in set
295 if (!$this->IsInPrivilegeData($Set))
296 {
297 # add subgroup to privilege set
298 $this->Privileges[] = $Set;
299 }
300 }
301
311 function AllRequired($NewValue = NULL)
312 {
313 if ($NewValue !== NULL)
314 {
315 $this->Logic = $NewValue ? "AND" : "OR";
316 }
317 return ($this->Logic == "AND") ? TRUE : FALSE;
318 }
319
325 function PrivilegeFlagsChecked()
326 {
327 $Info = $this->GetPrivilegeInfo();
328 unset ($Info["Logic"]);
329
330 $Result = array();
331 foreach ($Info as $Item)
332 {
333 if (is_object($Item))
334 {
335 $Result = array_merge($Result, $Item->PrivilegeFlagsChecked() );
336 }
337 elseif (!is_array($Item))
338 {
339 $Result []= $Item;
340 }
341 }
342 return array_unique($Result);
343 }
344
351 function FieldsWithUserComparisons($ComparisonType)
352 {
353 $Info = $this->GetPrivilegeInfo();
354 unset ($Info["Logic"]);
355
356 $Result = array();
357 foreach ($Info as $Item)
358 {
359 if (is_object($Item))
360 {
361 $Result = array_merge(
362 $Result,
363 $Item->FieldsWithUserComparisons( $ComparisonType ) );
364 }
365 elseif (is_array($Item))
366 {
367 if ($Item["Operator"] == $ComparisonType)
368 {
369 $Field = new MetadataField($Item["FieldId"]);
370
371 if ($Field->Type() == MetadataSchema::MDFTYPE_USER)
372 {
373 $Result []= $Item["FieldId"];
374 }
375 }
376 }
377 }
378
379 return array_unique($Result);
380 }
381
382 # ---- PRIVATE INTERFACE -------------------------------------------------
383
384 private $Privileges = array();
385 private $Logic = "OR";
386
387 const NO_RESOURCE = "XXX NO RESOURCE XXX";
388
393 private function LoadFromData($Serialized)
394 {
395 # save calling context in case load causes out-of-memory crash
396 $GLOBALS["AF"]->RecordContextInCaseOfCrash();
397
398 # unpack new data
399 $Data = unserialize($Serialized);
400
401 # unpack privilege data (if available) and load
402 if (array_key_exists("Privileges", $Data))
403 {
404 $this->Privileges = array();
405 foreach ($Data["Privileges"] as $Priv)
406 {
407 if (is_array($Priv) && array_key_exists("SUBSET", $Priv))
408 {
409 $Subset = new PrivilegeSet();
410 $Subset->LoadFromData($Priv["SUBSET"]);
411 $this->Privileges[] = $Subset;
412 }
413 else
414 {
415 $this->Privileges[] = $Priv;
416 }
417 }
418 }
419
420 # load logic if available
421 if (array_key_exists("Logic", $Data))
422 {
423 $this->Logic = $Data["Logic"];
424 }
425 }
426
434 private function MeetsCondition($Condition, $Resource, $User)
435 {
436 # if condition is a check for whether a resource is available
437 if ($Condition["FieldId"] == self::HAVE_RESOURCE)
438 {
439 # return a result based on whether a resource is available
440 return ((bool)($Resource == self::NO_RESOURCE)
441 != (bool)$Condition["Value"]) ? TRUE : FALSE;
442 }
443 # else if no resource is available
444 elseif ($Resource == self::NO_RESOURCE)
445 {
446 # return a result that in effect ignores the condition
447 return ($this->Logic == "AND") ? TRUE : FALSE;
448 }
449 # else if resource is valid
450 elseif ($Resource instanceof Resource)
451 {
452 # pre-process condition parameters based on type of field
453 try
454 {
455 $Field = new MetadataField($Condition["FieldId"]);
456 }
457 catch (Exception $e)
458 {
459 # if the field in a condition was invalid, the condition fails
460 return FALSE;
461 }
462
463 $Operator = $Condition["Operator"];
464 $Value = $Condition["Value"];
465 $FieldValue = $Resource->Get($Field, TRUE);
466 switch ($Field->Type())
467 {
468 case MetadataSchema::MDFTYPE_USER:
469 # if supplied value is NULL
470 if ($Value === NULL)
471 {
472 $Value = $User->Id();
473 }
474
475 # convert field value to user ID
476 $FieldValue = $FieldValue->Id();
477 break;
478
479 case MetadataSchema::MDFTYPE_DATE:
480 case MetadataSchema::MDFTYPE_TIMESTAMP:
481 # date field values are Date objects, so handle those
482 if ($FieldValue instanceof Date)
483 {
484 $FieldValue = strtotime($FieldValue->Formatted());
485 }
486
487 # timestamp field values are just the date/time string
488 else
489 {
490 $FieldValue = strtotime($FieldValue);
491 }
492
493 # use the current time for the value if it's NULL
494 if ($Value === NULL)
495 {
496 $Value = time();
497 }
498
499 # otherwise, parse the value to get a numeric timestamp
500 else
501 {
502 $Value = strtotime($Value);
503 }
504 break;
505
506 case MetadataSchema::MDFTYPE_NUMBER:
507 case MetadataSchema::MDFTYPE_FLAG:
508 break;
509
510 case MetadataSchema::MDFTYPE_OPTION:
511 # for options, construct a list of the CNIDs in this field
512 $NewValue = array();
513 foreach ($FieldValue as $CName)
514 {
515 $NewValue []= $CName->Id();
516 }
517 $FieldValue = $NewValue;
518 break;
519
520 default:
521 throw new Exception("Unsupported metadata field type ("
522 .print_r($Field->Type(), TRUE)
523 .") for condition in privilege set.");
524 break;
525 }
526
527 # compare field value and supplied value using specified operator
528 switch ($Operator)
529 {
530 case "==":
531 if (is_array($FieldValue))
532 {
533 # equality against an option field is a 'contains' condition,
534 # true if the specified value is one of those set
535 $Result = FALSE;
536 foreach ($FieldValue as $FieldValue_i)
537 {
538 $Result |= ($FieldValue_i == $Value);
539 }
540 }
541 else
542 {
543 $Result = ($FieldValue == $Value);
544 }
545 break;
546
547 case "!=":
548 if (is_array($FieldValue))
549 {
550 # not equal against an option field is 'does not contains',
551 # true as long as the spcified value is not one of those set
552 $Result = TRUE;
553 foreach ($FieldValue as $FieldValue_i)
554 {
555 $Result &= ($FieldValue_i != $Value);
556 }
557 }
558 else
559 {
560 $Result = ($FieldValue != $Value);
561 }
562 break;
563
564 case "<":
565 $Result = ($FieldValue < $Value);
566 break;
567
568 case ">":
569 $Result = ($FieldValue > $Value);
570 break;
571
572 case "<=":
573 $Result = ($FieldValue <= $Value);
574 break;
575
576 case ">=":
577 $Result = ($FieldValue >= $Value);
578 break;
579
580 default:
581 throw new Exception("Unsupported condition operator ("
582 .print_r($Operator, TRUE).") in privilege set.");
583 break;
584 }
585
586 # report to caller whether condition was met
587 return $Result ? TRUE : FALSE;
588 }
589 else
590 {
591 # error out because resource was illegal
592 throw new Exception("Invalid Resource passed in for privilege"
593 ." set comparison.");
594 }
595 }
596
605 private function IsInPrivilegeData($Item)
606 {
607 # step through privilege data
608 foreach ($this->Privileges as $Priv)
609 {
610 # report to caller if item is found
611 if (is_object($Item))
612 {
613 if (is_object($Priv) && ($Item == $Priv)) { return TRUE; }
614 }
615 elseif (is_array($Item))
616 {
617 if (is_array($Priv) && ($Item == $Priv)) { return TRUE; }
618 }
619 elseif ($Item == $Priv) { return TRUE; }
620 }
621
622 # report to caller that item is not in privilege data
623 return FALSE;
624 }
625 }
MetadataSchema\MDFTYPE_TIMESTAMP
const MDFTYPE_TIMESTAMP
Definition: MetadataSchema.php:24
PrivilegeSet\AddSet
AddSet(PrivilegeSet $Set)
Add subgroup of privileges/conditions to set.
Definition: PrivilegeSet.php:292
MetadataSchema\MDFTYPE_NUMBER
const MDFTYPE_NUMBER
Definition: MetadataSchema.php:22
CWUser\HasPriv
HasPriv($Privilege, $Privileges=NULL)
Determine if a user has a given privilege, or satisfies the conditions specified by a given privilege...
Definition: CWUser.php:102
PrivilegeSet\NO_RESOURCE
const NO_RESOURCE
Definition: PrivilegeSet.php:387
PrivilegeSet
Set of privileges used to access resource information or other parts of the system.
Definition: PrivilegeSet.php:16
PrivilegeSet\MeetsRequirements
MeetsRequirements(CWUser $User, $Resource=self::NO_RESOURCE)
Determine if a given user meets the requirements specified by this PrivilegeSet.
Definition: PrivilegeSet.php:91
Date
Definition: Axis--Date.php:18
MetadataSchema\MDFTYPE_OPTION
const MDFTYPE_OPTION
Definition: MetadataSchema.php:28
MetadataSchema\MDFTYPE_FLAG
const MDFTYPE_FLAG
Definition: MetadataSchema.php:25
PHP
PHP
Definition: OAIClient.php:39
PrivilegeSet\__construct
__construct($Data=NULL)
Class constructor, used to create a new set or reload an existing set from previously-constructed dat...
Definition: PrivilegeSet.php:29
PrivilegeSet\IncludesPrivilege
IncludesPrivilege($Privilege)
Check whether this privilege set includes the specified privilege.
Definition: PrivilegeSet.php:180
PrivilegeSet\GetPrivilegeInfo
GetPrivilegeInfo()
Get privilege information as an array, with numerical indexes except for the logic, which is contained in a element with the index "Logic".
Definition: PrivilegeSet.php:195
PrivilegeSet\PrivilegeFlagsChecked
PrivilegeFlagsChecked()
List which privilege flags (e.g.
Definition: PrivilegeSet.php:325
PrivilegeSet\GetPrivilegeList
GetPrivilegeList()
Get list of privileges.
Definition: PrivilegeSet.php:211
MetadataField
Object representing a locally-defined type of metadata field.
Definition: MetadataField.php:13
MetadataSchema\MDFTYPE_DATE
const MDFTYPE_DATE
Definition: MetadataSchema.php:23
PrivilegeSet\Data
Data($NewValue=NULL)
Get/set privilege set data, in the form of an opaque string.
Definition: PrivilegeSet.php:57
Resource
Represents a "resource" in CWIS.
Definition: Resource.php:13
MetadataSchema\MDFTYPE_USER
const MDFTYPE_USER
Definition: MetadataSchema.php:29
PrivilegeSet\FieldsWithUserComparisons
FieldsWithUserComparisons($ComparisonType)
List which fields in this privset are involved in UserIs or UserIsNot comparisons for this privilege ...
Definition: PrivilegeSet.php:351
PrivilegeSet\AddPrivilege
AddPrivilege($Privilege)
Add specified privilege to set.
Definition: PrivilegeSet.php:148
CWUser
CWIS-specific user class.
Definition: CWUser.php:13
PrivilegeSet\AddCondition
AddCondition($Field, $Value=NULL, $Operator="==")
Add condition to privilege set.
Definition: PrivilegeSet.php:238
PrivilegeSet\RemovePrivilege
RemovePrivilege($Privilege)
Remove specified privilege from set.
Definition: PrivilegeSet.php:164
PrivilegeSet\HAVE_RESOURCE
const HAVE_RESOURCE
Definition: PrivilegeSet.php:20
PrivilegeSet\AllRequired
AllRequired($NewValue=NULL)
Get/set whether all privileges/conditions in set are required (i.e.
Definition: PrivilegeSet.php:311
PrivilegeSet\RemoveCondition
RemoveCondition($Field, $Value=NULL, $Operator="==")
Remove condition from privilege set.
Definition: PrivilegeSet.php:268