CWIS Developer Documentation

- Home
- Main Page
- Namespaces
- 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($Privileges)
149 {
150 # convert incoming value to array if needed
151 if (!is_array($Privileges))
152 {
153 $Privileges = array($Privileges);
154 }
155
156 # for each privilege passed in
157 foreach ($Privileges as $Privilege)
158 {
159 # add privilege if not currently in set
160 if (!$this->IncludesPrivilege($Privilege))
161 {
162 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
163 $this->Privileges[] = $Privilege;
164 }
165 }
166 }
167
174 function RemovePrivilege($Privilege)
175 {
176 # remove privilege if currently in set
177 if ($this->IncludesPrivilege($Privilege))
178 {
179 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
180 $Index = array_search($Privilege, $this->Privileges);
181 unset($this->Privileges[$Index]);
182 }
183 }
184
190 function IncludesPrivilege($Privilege)
191 {
192 # check whether privilege is in our list and report to caller
193 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
194 return $this->IsInPrivilegeData($Privilege) ? TRUE : FALSE;
195 }
196
205 function GetPrivilegeInfo()
206 {
207 # grab privilege information and add logic
208 $Info = $this->Privileges;
209 $Info["Logic"] = $this->Logic;
210
211 # return privilege info array to caller
212 return $Info;
213 }
214
221 function GetPrivilegeList()
222 {
223 # create list of privileges with conditions stripped out
224 $List = array();
225 foreach ($this->Privileges as $Priv)
226 {
227 if (!is_array($Priv)) { $List[] = $Priv; }
228 }
229
230 # return list of privileges to caller
231 return $List;
232 }
233
248 function AddCondition($Field, $Value = NULL, $Operator = "==")
249 {
250 # get field ID
251 $FieldId = is_object($Field) ? $Field->Id() : $Field;
252
253 # set up condition array
254 $Condition = array(
255 "FieldId" => intval($FieldId),
256 "Operator" => trim($Operator),
257 "Value" => $Value);
258
259 # if condition is not already in set
260 if (!$this->IsInPrivilegeData($Condition))
261 {
262 # add condition to privilege set
263 $this->Privileges[] = $Condition;
264 }
265 }
266
278 function RemoveCondition($Field, $Value = NULL, $Operator = "==")
279 {
280 # get field ID
281 $FieldId = is_object($Field) ? $Field->Id() : $Field;
282
283 # set up condition array
284 $Condition = array(
285 "FieldId" => intval($FieldId),
286 "Operator" => trim($Operator),
287 "Value" => $Value);
288
289 # if condition is in set
290 if ($this->IsInPrivilegeData($Condition))
291 {
292 # remove condition from privilege set
293 $Index = array_search($Condition, $this->Privileges);
294 unset($this->Privileges[$Index]);
295 }
296 }
297
302 function AddSet(PrivilegeSet $Set)
303 {
304 # if subgroup is not already in set
305 if (!$this->IsInPrivilegeData($Set))
306 {
307 # add subgroup to privilege set
308 $this->Privileges[] = $Set;
309 }
310 }
311
321 function AllRequired($NewValue = NULL)
322 {
323 if ($NewValue !== NULL)
324 {
325 $this->Logic = $NewValue ? "AND" : "OR";
326 }
327 return ($this->Logic == "AND") ? TRUE : FALSE;
328 }
329
335 function PrivilegeFlagsChecked()
336 {
337 $Info = $this->GetPrivilegeInfo();
338 unset ($Info["Logic"]);
339
340 $Result = array();
341 foreach ($Info as $Item)
342 {
343 if (is_object($Item))
344 {
345 $Result = array_merge($Result, $Item->PrivilegeFlagsChecked() );
346 }
347 elseif (!is_array($Item))
348 {
349 $Result []= $Item;
350 }
351 }
352 return array_unique($Result);
353 }
354
361 function FieldsWithUserComparisons($ComparisonType)
362 {
363 $Info = $this->GetPrivilegeInfo();
364 unset ($Info["Logic"]);
365
366 $Result = array();
367 foreach ($Info as $Item)
368 {
369 if (is_object($Item))
370 {
371 $Result = array_merge(
372 $Result,
373 $Item->FieldsWithUserComparisons( $ComparisonType ) );
374 }
375 elseif (is_array($Item))
376 {
377 if ($Item["Operator"] == $ComparisonType &&
378 $Item["FieldId"] > 0 )
379 {
380 $Field = new MetadataField($Item["FieldId"]);
381
382 if ($Field->Type() == MetadataSchema::MDFTYPE_USER)
383 {
384 $Result []= $Item["FieldId"];
385 }
386 }
387 }
388 }
389
390 return array_unique($Result);
391 }
392
393 # ---- PRIVATE INTERFACE -------------------------------------------------
394
395 private $Privileges = array();
396 private $Logic = "OR";
397
398 const NO_RESOURCE = "XXX NO RESOURCE XXX";
399
404 private function LoadFromData($Serialized)
405 {
406 # save calling context in case load causes out-of-memory crash
407 $GLOBALS["AF"]->RecordContextInCaseOfCrash();
408
409 # unpack new data
410 $Data = unserialize($Serialized);
411
412 # unpack privilege data (if available) and load
413 if (array_key_exists("Privileges", $Data))
414 {
415 $this->Privileges = array();
416 foreach ($Data["Privileges"] as $Priv)
417 {
418 if (is_array($Priv) && array_key_exists("SUBSET", $Priv))
419 {
420 $Subset = new PrivilegeSet();
421 $Subset->LoadFromData($Priv["SUBSET"]);
422 $this->Privileges[] = $Subset;
423 }
424 else
425 {
426 $this->Privileges[] = $Priv;
427 }
428 }
429 }
430
431 # load logic if available
432 if (array_key_exists("Logic", $Data))
433 {
434 $this->Logic = $Data["Logic"];
435 }
436 }
437
445 private function MeetsCondition($Condition, $Resource, $User)
446 {
447 # if condition is a check for whether a resource is available
448 if ($Condition["FieldId"] == self::HAVE_RESOURCE)
449 {
450 # return a result based on whether a resource is available
451 return ((bool)($Resource == self::NO_RESOURCE)
452 != (bool)$Condition["Value"]) ? TRUE : FALSE;
453 }
454 # else if no resource is available
455 elseif ($Resource == self::NO_RESOURCE)
456 {
457 # return a result that in effect ignores the condition
458 return ($this->Logic == "AND") ? TRUE : FALSE;
459 }
460 # else if resource is valid
461 elseif ($Resource instanceof Resource)
462 {
463 # pre-process condition parameters based on type of field
464 try
465 {
466 $Field = new MetadataField($Condition["FieldId"]);
467 }
468 catch (Exception $e)
469 {
470 # if the field in a condition was invalid, the condition fails
471 return FALSE;
472 }
473
474 $Operator = $Condition["Operator"];
475 $Value = $Condition["Value"];
476 $FieldValue = $Resource->Get($Field, TRUE);
477 switch ($Field->Type())
478 {
479 case MetadataSchema::MDFTYPE_USER:
480 # if supplied value is NULL
481 if ($Value === NULL)
482 {
483 $Value = $User->Id();
484 }
485
486 # convert field value to user ID
487 $FieldValue = $FieldValue->Id();
488 break;
489
490 case MetadataSchema::MDFTYPE_DATE:
491 case MetadataSchema::MDFTYPE_TIMESTAMP:
492 # date field values are Date objects, so handle those
493 if ($FieldValue instanceof Date)
494 {
495 $FieldValue = strtotime($FieldValue->Formatted());
496 }
497
498 # timestamp field values are just the date/time string
499 else
500 {
501 $FieldValue = strtotime($FieldValue);
502 }
503
504 # use the current time for the value if it's NULL
505 if ($Value === NULL)
506 {
507 $Value = time();
508 }
509
510 # otherwise, parse the value to get a numeric timestamp
511 else
512 {
513 $Value = strtotime($Value);
514 }
515 break;
516
517 case MetadataSchema::MDFTYPE_NUMBER:
518 case MetadataSchema::MDFTYPE_FLAG:
519 break;
520
521 case MetadataSchema::MDFTYPE_OPTION:
522 # for options, construct a list of the CNIDs in this field
523 $NewValue = array();
524 foreach ($FieldValue as $CName)
525 {
526 $NewValue []= $CName->Id();
527 }
528 $FieldValue = $NewValue;
529 break;
530
531 default:
532 throw new Exception("Unsupported metadata field type ("
533 .print_r($Field->Type(), TRUE)
534 .") for condition in privilege set.");
535 break;
536 }
537
538 # compare field value and supplied value using specified operator
539 switch ($Operator)
540 {
541 case "==":
542 if (is_array($FieldValue))
543 {
544 # equality against an option field is a 'contains' condition,
545 # true if the specified value is one of those set
546 $Result = FALSE;
547 foreach ($FieldValue as $FieldValue_i)
548 {
549 $Result |= ($FieldValue_i == $Value);
550 }
551 }
552 else
553 {
554 $Result = ($FieldValue == $Value);
555 }
556 break;
557
558 case "!=":
559 if (is_array($FieldValue))
560 {
561 # not equal against an option field is 'does not contains',
562 # true as long as the spcified value is not one of those set
563 $Result = TRUE;
564 foreach ($FieldValue as $FieldValue_i)
565 {
566 $Result &= ($FieldValue_i != $Value);
567 }
568 }
569 else
570 {
571 $Result = ($FieldValue != $Value);
572 }
573 break;
574
575 case "<":
576 $Result = ($FieldValue < $Value);
577 break;
578
579 case ">":
580 $Result = ($FieldValue > $Value);
581 break;
582
583 case "<=":
584 $Result = ($FieldValue <= $Value);
585 break;
586
587 case ">=":
588 $Result = ($FieldValue >= $Value);
589 break;
590
591 default:
592 throw new Exception("Unsupported condition operator ("
593 .print_r($Operator, TRUE).") in privilege set.");
594 break;
595 }
596
597 # report to caller whether condition was met
598 return $Result ? TRUE : FALSE;
599 }
600 else
601 {
602 # error out because resource was illegal
603 throw new Exception("Invalid Resource passed in for privilege"
604 ." set comparison.");
605 }
606 }
607
616 private function IsInPrivilegeData($Item)
617 {
618 # step through privilege data
619 foreach ($this->Privileges as $Priv)
620 {
621 # report to caller if item is found
622 if (is_object($Item))
623 {
624 if (is_object($Priv) && ($Item == $Priv)) { return TRUE; }
625 }
626 elseif (is_array($Item))
627 {
628 if (is_array($Priv) && ($Item == $Priv)) { return TRUE; }
629 }
630 elseif ($Item == $Priv) { return TRUE; }
631 }
632
633 # report to caller that item is not in privilege data
634 return FALSE;
635 }
636 }
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:302
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:398
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
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:190
PHP
PHP
Definition: RSSClient--Test.php:12
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:205
PrivilegeSet\AddPrivilege
AddPrivilege($Privileges)
Add specified privilege to set.
Definition: PrivilegeSet.php:148
PrivilegeSet\PrivilegeFlagsChecked
PrivilegeFlagsChecked()
List which privilege flags (e.g.
Definition: PrivilegeSet.php:335
PrivilegeSet\GetPrivilegeList
GetPrivilegeList()
Get list of privileges.
Definition: PrivilegeSet.php:221
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:361
CWUser
CWIS-specific user class.
Definition: CWUser.php:13
PrivilegeSet\AddCondition
AddCondition($Field, $Value=NULL, $Operator="==")
Add condition to privilege set.
Definition: PrivilegeSet.php:248
PrivilegeSet\RemovePrivilege
RemovePrivilege($Privilege)
Remove specified privilege from set.
Definition: PrivilegeSet.php:174
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:321
PrivilegeSet\RemoveCondition
RemoveCondition($Field, $Value=NULL, $Operator="==")
Remove condition from privilege set.
Definition: PrivilegeSet.php:278