Exemplo n.º 1
0
 /**
  * Create
  *
  * $ref may be nullRef, then auto increment is used.
  */
 protected function create(Reference $ref, $properties)
 {
     // filter out unknown keys
     $properties = array_intersect_key($properties, $this->properties);
     if (!$ref->isNullRef()) {
         $properties = array_merge($properties, array_combine($this->describeId(), (array) $ref->id));
     }
     // Set times
     if ($this->time_created_table_column) {
         $properties[$this->time_created_table_column] = new \Smalldb\Flupdo\FlupdoRawSql('CURRENT_TIMESTAMP');
     }
     if ($this->time_modified_table_column) {
         $properties[$this->time_modified_table_column] = new \Smalldb\Flupdo\FlupdoRawSql('CURRENT_TIMESTAMP');
     }
     if (empty($properties)) {
         throw new \InvalidArgumentException('No valid properties provided.');
     }
     // Set owner
     if ($this->user_id_table_column) {
         $properties[$this->user_id_table_column] = $this->backend->getAuth()->getUserId();
     }
     // Check permission of owning machine
     if ($this->owner_relation && $this->owner_create_transition) {
         $ref_ref = $this->resolveMachineReference($this->owner_relation, $properties);
         if (!$ref_ref->machine->isTransitionAllowed($ref_ref, $this->owner_create_transition)) {
             throw new \RuntimeException(sprintf('Permission denied to create machine %s because transition %s of %s is not allowed.', $this->machine_type, $this->owner_create_transition, $ref->machine_type));
         }
     }
     // Insert
     $data = $this->encodeProperties($properties);
     $q = $this->flupdo->insert()->into($this->flupdo->quoteIdent($this->table));
     foreach ($data as $k => $v) {
         $q->insert($this->flupdo->quoteIdent($k));
     }
     $q->values([$data]);
     $n = $q->debugDump()->exec();
     if (!$n) {
         // Insert failed
         return false;
     }
     // Return ID of inserted row
     if ($ref->isNullRef()) {
         $id_keys = $this->describeId();
         $id = array();
         foreach ($id_keys as $k) {
             if (isset($properties[$k])) {
                 $id[] = $properties[$k];
             } else {
                 // If part of ID is missing, it must be autoincremented
                 // column, otherwise the insert would have failed.
                 $id[] = $this->flupdo->lastInsertId();
             }
         }
     } else {
         $id = $ref->id;
     }
     if ($this->nested_sets_enabled) {
         $this->recalculateTree();
     }
     return $id;
 }
Exemplo n.º 2
0
 /**
  * Returns true if user has required access_policy.
  *
  * TODO: Caching ? Reference object has property cache. It would be
  * 	nice to pass it here.
  */
 protected function checkAccessPolicy($access_policy_name, Reference $ref)
 {
     // Allow by default
     if (empty($access_policy_name)) {
         return true;
     }
     if (!isset($this->access_policies[$access_policy_name])) {
         throw new \InvalidArgumentException('Unknown policy: ' . $access_policy_name);
     }
     $access_policy = $this->access_policies[$access_policy_name];
     //debug_dump($access_policy, 'POLICY: '.$access_policy_name.' @ '.get_class($this));
     if ($this->auth->isAllMighty()) {
         return true;
     }
     switch ($access_policy['type']) {
         // anyone: Completely open for anyone
         case 'anyone':
             return true;
             // nobody: Nobody is allowed, except all mighty users.
         // nobody: Nobody is allowed, except all mighty users.
         case 'nobody':
             return false;
             // anonymous: Only anonymous users allowed (not logged in)
         // anonymous: Only anonymous users allowed (not logged in)
         case 'anonymous':
             $user_id = $this->auth->getUserId();
             return $user_id === null;
             // user: All logged-in users allowed
         // user: All logged-in users allowed
         case 'user':
             $user_id = $this->auth->getUserId();
             return $user_id !== null;
             // owner: Owner must match current user
         // owner: Owner must match current user
         case 'owner':
             if ($ref->isNullRef()) {
                 // Everyone owns nothing :)
                 return true;
             }
             $properties = $ref->properties;
             $user_id = $this->auth->getUserId();
             $owner_property = $access_policy['owner_property'];
             if (isset($access_policy['session_state'])) {
                 if ($this->auth->getSessionMachine()->state != $access_policy['session_state']) {
                     return false;
                 }
             }
             return $user_id !== null ? $user_id == $properties[$owner_property] : $properties[$owner_property] === null;
             // role: Current user must have specified role ($ref is ignored)
         // role: Current user must have specified role ($ref is ignored)
         case 'role':
             return $this->auth->hasUserRoles($access_policy['required_role']);
             // These are done by SQL select.
         // These are done by SQL select.
         case 'condition':
             if ($ref->isNullRef()) {
                 // Nonexistent entity has nulls everywhere
                 // FIXME: Are we sure?
                 return false;
             }
             $properties = $ref->properties;
             return !empty($properties['_access_policy_' . $access_policy_name]);
             // These are done by SQL select.
         // These are done by SQL select.
         case 'user_relation':
             if ($ref->isNullRef()) {
                 // No relation to nonexistent entity.
                 return false;
             }
             $properties = $ref->properties;
             return !empty($properties['_access_policy_' . $access_policy_name]);
             // unknown policies are considered unsafe
         // unknown policies are considered unsafe
         default:
             return false;
     }
     // This should not happen.
     throw new \RuntimeException('Policy ' . $policy . ' did not decide.');
 }