3 # FILE: PrivilegeSet.php
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/
18 # used as a field ID in conditions to test whether a resources is
19 # available as part of the privilege check
31 # if privilege data supplied
34 # if data is in legacy form (an array of privileges)
37 # set internal privilege set from array
38 $this->Privileges = $Data;
42 # set internal values from data
43 $this->LoadFromData($Data);
57 function Data($NewValue = NULL)
59 # if new data supplied
60 if ($NewValue !== NULL)
62 # unpack privilege data and load
63 $this->LoadFromData($NewValue);
66 # serialize current data and return to caller
68 if (count($this->Privileges))
70 foreach ($this->Privileges as $Priv)
72 $Data[
"Privileges"][] = is_object($Priv)
73 ? array(
"SUBSET" => $Priv->Data())
77 $Data[
"Logic"] = $this->Logic;
78 return serialize($Data);
93 # when there are no requirements, then every user meets them
96 # for each privilege requirement
97 foreach ($this->Privileges as $Priv)
99 # if privilege is actually a privilege subgroup
100 if (is_object($Priv))
102 # check if the subgroup is satisfied
103 $Satisfied = $Priv->MeetsRequirements($User, $Resource);
105 # else if privilege is actually a condition
106 elseif (is_array($Priv))
108 # check if condition is satisfied for the given resource
109 $Satisfied = $this->MeetsCondition($Priv, $Resource, $User);
111 # else privilege is actually a privilege
114 # check if user has the spcified privilege
115 $Satisfied = $User->
HasPriv( $Priv );
118 # for AND logic, we can bail as soon as the first
119 # condition is not met
120 if ($this->Logic ==
"AND")
127 # conversely, for OR logic, we can bail as soon as any
138 # report result of the test back to caller
150 # convert incoming value to array if needed
151 if (!is_array($Privileges))
153 $Privileges = array($Privileges);
156 # for each privilege passed in
157 foreach ($Privileges as $Privilege)
159 # add privilege if not currently in set
162 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
163 $this->Privileges[] = $Privilege;
176 # remove privilege if currently in set
179 if (is_object($Privilege)) { $Privilege = $Privilege->Id(); }
180 $Index = array_search($Privilege, $this->Privileges);
181 unset($this->Privileges[$Index]);
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;
207 # grab privilege information and add logic
208 $Info = $this->Privileges;
209 $Info[
"Logic"] = $this->Logic;
211 # return privilege info array to caller
223 # create list of privileges with conditions stripped out
225 foreach ($this->Privileges as $Priv)
227 if (!is_array($Priv)) { $List[] = $Priv; }
230 # return list of privileges to caller
251 $FieldId = is_object($Field) ? $Field->Id() : $Field;
253 # set up condition array
255 "FieldId" => intval($FieldId),
256 "Operator" => trim($Operator),
259 # if condition is not already in set
260 if (!$this->IsInPrivilegeData($Condition))
262 # add condition to privilege set
263 $this->Privileges[] = $Condition;
281 $FieldId = is_object($Field) ? $Field->Id() : $Field;
283 # set up condition array
285 "FieldId" => intval($FieldId),
286 "Operator" => trim($Operator),
289 # if condition is in set
290 if ($this->IsInPrivilegeData($Condition))
292 # remove condition from privilege set
293 $Index = array_search($Condition, $this->Privileges);
294 unset($this->Privileges[$Index]);
304 # if subgroup is not already in set
305 if (!$this->IsInPrivilegeData($Set))
307 # add subgroup to privilege set
308 $this->Privileges[] = $Set;
323 if ($NewValue !== NULL)
325 $this->Logic = $NewValue ?
"AND" :
"OR";
327 return ($this->Logic ==
"AND") ? TRUE : FALSE;
338 unset ($Info[
"Logic"]);
341 foreach ($Info as $Item)
343 if (is_object($Item))
345 $Result = array_merge($Result, $Item->PrivilegeFlagsChecked() );
347 elseif (!is_array($Item))
352 return array_unique($Result);
364 unset ($Info[
"Logic"]);
367 foreach ($Info as $Item)
369 if (is_object($Item))
371 $Result = array_merge(
373 $Item->FieldsWithUserComparisons( $ComparisonType ) );
375 elseif (is_array($Item))
377 if ($Item[
"Operator"] == $ComparisonType &&
378 $Item[
"FieldId"] > 0 )
384 $Result []= $Item[
"FieldId"];
390 return array_unique($Result);
393 # ---- PRIVATE INTERFACE -------------------------------------------------
395 private $Privileges = array();
396 private $Logic =
"OR";
404 private function LoadFromData($Serialized)
406 # save calling context in case load causes out-of-memory crash
407 $GLOBALS[
"AF"]->RecordContextInCaseOfCrash();
410 $Data = unserialize($Serialized);
412 # unpack privilege data (if available) and load
413 if (array_key_exists(
"Privileges", $Data))
415 $this->Privileges = array();
416 foreach ($Data[
"Privileges"] as $Priv)
418 if (is_array($Priv) && array_key_exists(
"SUBSET", $Priv))
421 $Subset->LoadFromData($Priv[
"SUBSET"]);
422 $this->Privileges[] = $Subset;
426 $this->Privileges[] = $Priv;
431 # load logic if available
432 if (array_key_exists(
"Logic", $Data))
434 $this->Logic = $Data[
"Logic"];
445 private function MeetsCondition($Condition, $Resource, $User)
447 # if condition is a check for whether a resource is available
448 if ($Condition[
"FieldId"] == self::HAVE_RESOURCE)
450 # return a result based on whether a resource is available
451 return ((
bool)($Resource == self::NO_RESOURCE)
452 != (
bool)$Condition[
"Value"]) ? TRUE : FALSE;
454 # else if no resource is available
455 elseif ($Resource == self::NO_RESOURCE)
457 # return a result that in effect ignores the condition
458 return ($this->Logic ==
"AND") ? TRUE : FALSE;
460 # else if resource is valid
461 elseif ($Resource instanceof
Resource)
463 # pre-process condition parameters based on type of field
470 # if the field in a condition was invalid, the condition fails
474 $Operator = $Condition[
"Operator"];
475 $Value = $Condition[
"Value"];
476 $FieldValue = $Resource->Get($Field, TRUE);
477 switch ($Field->Type())
480 # if supplied value is NULL
483 $Value = $User->Id();
486 # convert field value to user ID
487 $FieldValue = $FieldValue->Id();
492 # date field values are Date objects, so handle those
493 if ($FieldValue instanceof
Date)
495 $FieldValue = strtotime($FieldValue->Formatted());
498 # timestamp field values are just the date/time string
501 $FieldValue = strtotime($FieldValue);
504 # use the current time for the value if it's NULL
510 # otherwise, parse the value to get a numeric timestamp
513 $Value = strtotime($Value);
522 # for options, construct a list of the CNIDs in this field
524 foreach ($FieldValue as $CName)
526 $NewValue []= $CName->Id();
528 $FieldValue = $NewValue;
532 throw new Exception(
"Unsupported metadata field type ("
533 .print_r($Field->Type(), TRUE)
534 .
") for condition in privilege set.");
538 # compare field value and supplied value using specified operator
542 if (is_array($FieldValue))
544 # equality against an option field is a 'contains' condition,
545 # true if the specified value is one of those set
547 foreach ($FieldValue as $FieldValue_i)
549 $Result |= ($FieldValue_i == $Value);
554 $Result = ($FieldValue == $Value);
559 if (is_array($FieldValue))
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
564 foreach ($FieldValue as $FieldValue_i)
566 $Result &= ($FieldValue_i != $Value);
571 $Result = ($FieldValue != $Value);
576 $Result = ($FieldValue < $Value);
580 $Result = ($FieldValue > $Value);
584 $Result = ($FieldValue <= $Value);
588 $Result = ($FieldValue >= $Value);
592 throw new Exception(
"Unsupported condition operator ("
593 .print_r($Operator, TRUE).
") in privilege set.");
597 # report to caller whether condition was met
598 return $Result ? TRUE : FALSE;
602 # error out because resource was illegal
603 throw new Exception(
"Invalid Resource passed in for privilege"
604 .
" set comparison.");
616 private function IsInPrivilegeData($Item)
618 # step through privilege data
619 foreach ($this->Privileges as $Priv)
621 # report to caller if item is found
622 if (is_object($Item))
624 if (is_object($Priv) && ($Item == $Priv)) {
return TRUE; }
626 elseif (is_array($Item))
628 if (is_array($Priv) && ($Item == $Priv)) {
return TRUE; }
630 elseif ($Item == $Priv) {
return TRUE; }
633 # report to caller that item is not in privilege data
AddSet(PrivilegeSet $Set)
Add subgroup of privileges/conditions to set.
HasPriv($Privilege, $Privileges=NULL)
Determine if a user has a given privilege, or satisfies the conditions specified by a given privilege...
Set of privileges used to access resource information or other parts of the system.
MeetsRequirements(CWUser $User, $Resource=self::NO_RESOURCE)
Determine if a given user meets the requirements specified by this PrivilegeSet.
__construct($Data=NULL)
Class constructor, used to create a new set or reload an existing set from previously-constructed dat...
IncludesPrivilege($Privilege)
Check whether this privilege set includes the specified privilege.
GetPrivilegeInfo()
Get privilege information as an array, with numerical indexes except for the logic, which is contained in a element with the index "Logic".
AddPrivilege($Privileges)
Add specified privilege to set.
PrivilegeFlagsChecked()
List which privilege flags (e.g.
GetPrivilegeList()
Get list of privileges.
Data($NewValue=NULL)
Get/set privilege set data, in the form of an opaque string.
Represents a "resource" in CWIS.
FieldsWithUserComparisons($ComparisonType)
List which fields in this privset are involved in UserIs or UserIsNot comparisons for this privilege ...
CWIS-specific user class.
AddCondition($Field, $Value=NULL, $Operator="==")
Add condition to privilege set.
RemovePrivilege($Privilege)
Remove specified privilege from set.
AllRequired($NewValue=NULL)
Get/set whether all privileges/conditions in set are required (i.e.
RemoveCondition($Field, $Value=NULL, $Operator="==")
Remove condition from privilege set.