function testGetGlobalTargetTypeForObject()
 {
     $this->assertEqual('global_plant', Role_Action_Target::getGlobalTargetTypeForObject(new Authoritative_Plant(['DB' => $this->DB])));
     $this->assertEqual('global_plant', Role_Action_Target::getGlobalTargetTypeForObject(new Authoritative_Plant_Extra(['DB' => $this->DB])));
     $this->assertEqual('global_metadata', Role_Action_Target::getGlobalTargetTypeForObject(new Metadata_Structure(['DB' => $this->DB])));
     $this->assertEqual('global_metadata', Role_Action_Target::getGlobalTargetTypeForObject(new Metadata_Term_Set(['DB' => $this->DB])));
     $this->assertEqual('global_metadata', Role_Action_Target::getGlobalTargetTypeForObject(new Metadata_Term_Value(['DB' => $this->DB])));
     $this->assertEqual('global_metadata', Role_Action_Target::getGlobalTargetTypeForObject(new Metadata_Reference(['DB' => $this->DB])));
     $this->assertEqual('global_notebook', Role_Action_Target::getGlobalTargetTypeForObject(new Notebook(['DB' => $this->DB])));
     $this->assertEqual('global_notebook', Role_Action_Target::getGlobalTargetTypeForObject(new Notebook_Page(['DB' => $this->DB])));
     $this->assertEqual('global_notebook', Role_Action_Target::getGlobalTargetTypeForObject(new Notebook_Page_Field(['DB' => $this->DB])));
     $this->assertEqual('global_specimen', Role_Action_Target::getGlobalTargetTypeForObject(new Specimen(['DB' => $this->DB])));
     $this->assertEqual('global_specimen', Role_Action_Target::getGlobalTargetTypeForObject(new Specimen_Image(['DB' => $this->DB])));
     $this->assertEqual(false, Role_Action_Target::getGlobalTargetTypeForObject(new Action(['DB' => $this->DB])));
 }
예제 #2
0
 public function canActOnTarget($action, $target)
 {
     // system admin -> always yes
     // owner of target -> always yes, except for verification
     // all other situatons -> check role action targets
     //   - matching globals -> yes
     //   - specifics
     //      + gets messy
     //   - otherwise -> no
     if (is_string($action)) {
         global $ACTIONS;
         $action = $ACTIONS[$action];
     }
     // system admin -> always yes
     if ($this->flag_is_system_admin) {
         return true;
     }
     //            util_prePrintR($action);
     //            util_prePrintR($target);
     // owner of target -> always yes, except for verification
     if ($target->user_id == $this->user_id) {
         if ($action->name != 'verify') {
             return true;
         }
     }
     // view & list is controlled by flags on the object rather than explicit permissions / access records
     if ($action->name == 'view' || $action->name == 'list') {
         if (array_key_exists('flag_active', $target->fieldValues)) {
             if ($target->flag_active) {
                 return true;
             }
         } elseif (array_key_exists('flag_workflow_published', $target->fieldValues)) {
             if ($target->flag_workflow_published && $target->flag_workflow_validated) {
                 return true;
             }
         }
     }
     // all other situatons -> check role action targets
     $this->cacheRoleActionTargets();
     //   - matching globals -> yes
     $target_global_type = Role_Action_Target::getGlobalTargetTypeForObject($target);
     if (in_array($target_global_type, array_keys($this->cached_role_action_targets_hash_by_target_type_by_id))) {
         foreach ($this->cached_role_action_targets_hash_by_target_type_by_id[$target_global_type] as $glob_rat) {
             if ($glob_rat->action_id == $action->action_id) {
                 return true;
             }
         }
     }
     //            util_prePrintR($this->cached_role_action_targets_hash_by_target_type_by_id);
     //   - specifics
     //      + gets messy
     // if the allowed target types do not contain the specific type of the target in question, then no need to go further
     // get a list of all the specific ids to check. This gets a bit messy as we have to climb or include a hierarchy depending on what exactly the target is
     //            util_prePrintR($target);
     $ids_to_check = array();
     $target_class = get_class($target);
     switch ($target_class) {
         case 'Authoritative_Plant':
             $ids_to_check = array($target->authoritative_plant_id);
             break;
         case 'Authoritative_Plant_Extra':
             // can act on this if can act on the plant
             return $this->canActOnTarget($action, $target->getAuthoritativePlant());
             break;
         case 'Metadata_Structure':
             // can edit this if can edit itself or any parent
             $ids_to_check = Db_Linked::arrayOfAttrValues($target->getLineage(), 'metadata_structure_id');
             break;
         case 'Metadata_Term_Set':
             // can edit if can edit any structure that uses this term set
             $structures = Metadata_Structure::getAllFromDb(['metadata_term_set_id' => $target->metadata_term_set_id], $this->dbConnection);
             $ids_to_check = array();
             foreach ($structures as $s) {
                 $ids_to_check = array_merge($ids_to_check, Db_Linked::arrayOfAttrValues($s->getLineage(), 'metadata_structure_id'));
             }
             break;
         case 'Metadata_Term_Value':
             // can edit if can edit any structure that uses the term set for which this is a value
             return $this->canActOnTarget($action, Metadata_Term_Set::getOneFromDb(['metadata_term_set_id' => $target->metadata_term_set_id], $this->dbConnection));
             break;
         case 'Metadata_Reference':
             // can edit if can edit anything to which this refers
             return $this->canActOnTarget($action, $target->getReferrent());
             break;
         case 'Notebook':
             $ids_to_check = array($target->notebook_id);
             break;
         case 'Notebook_Page':
             // can act on if can act on the notebook that contains this page
             return $this->canActOnTarget($action, $target->getNotebook());
             break;
         case 'Notebook_Page_Field':
             // can act on if can act on the notebook that contains the notebook page that this page field
             return $this->canActOnTarget($action, $target->getNotebookPage()->getNotebook());
             break;
         case 'Specimen':
             $ids_to_check = array($target->specimen_id);
             break;
         case 'Specimen_Image':
             // can act on if can act on the specimen
             return $this->canActOnTarget($action, $target->getSpecimen());
             break;
         default:
             break;
     }
     //            util_prePrintR($ids_to_check);
     //            util_prePrintR($this->cached_role_action_targets_hash_by_target_type_by_id);
     $target_specific_type = Role_Action_Target::getSpecificTargetTypeForObject($target);
     if (!in_array($target_specific_type, array_keys($this->cached_role_action_targets_hash_by_target_type_by_id))) {
         return false;
     }
     foreach ($this->cached_role_action_targets_hash_by_target_type_by_id[$target_specific_type] as $spec_rat) {
         if ($spec_rat->action_id == $action->action_id && in_array($spec_rat->target_id, $ids_to_check)) {
             if ($action->name == 'view') {
                 $actual_target = $spec_rat->getTargets()[0];
                 if (array_key_exists('flag_workflow_published', $actual_target->fieldValues)) {
                     return $actual_target->flag_workflow_published && $actual_target->flag_workflow_validated;
                 }
             }
             return true;
         }
     }
     return false;
 }