Example #1
0
 /**
  * Checks whether a eventConfig is appropriate to be called (subject fits, condition fits)
  *
  * @param Event $eventConfig
  * @param GenericEvent $event
  * @return bool
  */
 public function isCallable(Event $eventConfig, GenericEvent $event)
 {
     if ($eventConfig->getSubject() && $event->getSubject() != $eventConfig->getSubject()) {
         return false;
     }
     if ($eventConfig->getCondition()) {
         $args = $event->getArguments() ?: [];
         if ($eventConfig->getCondition() && !$this->conditionOperator->satisfy($eventConfig->getCondition(), $args)) {
             return false;
         }
     }
     return true;
 }
Example #2
0
 /**
  * @param ModelCriteria $query
  * @param \Jarves\Configuration\Condition $condition
  * @return \PDOStatement
  * @throws \PDOException
  */
 public function getStm(ModelCriteria $query, Condition $condition = null)
 {
     $params = [];
     $condition2Params = [];
     $id = hexdec(uniqid()) / mt_rand() + mt_rand();
     // check that the columns of the main class are already added (if this is the primary ModelCriteria)
     if (!$query->hasSelectClause() && !$query->getPrimaryCriteria()) {
         $query->addSelfSelectColumns();
     }
     $con = RuntimePropel::getServiceContainer()->getReadConnection($query->getDbName());
     $query->configureSelectColumns();
     $dbMap = RuntimePropel::getServiceContainer()->getDatabaseMap($query->getDbName());
     $db = RuntimePropel::getServiceContainer()->getAdapter($query->getDbName());
     $model = $query->getModelName();
     $tableMap = constant($model . '::TABLE_MAP');
     $query->setPrimaryTableName(constant($tableMap . '::TABLE_NAME'));
     //        $query->find($con);
     if ($condition) {
         $query->where($id . ' = ' . $id);
     }
     $sql = $query->createSelectSql($params);
     $conditionSql = '';
     if ($condition) {
         $condition2Params = $params;
         $conditionSql = $this->conditionOperator->standardConditionToSql($condition, $condition2Params, $this->getObjectKey());
     }
     if ($condition && $conditionSql) {
         $sql = str_replace($id . ' = ' . $id, '(' . $conditionSql . ')', $sql);
     }
     /** @var \PDOStatement $stmt */
     try {
         $stmt = $con->prepare($sql);
     } catch (\PDOException $e) {
         throw new PropelException('Could not execute query ' . $sql, 0, $e);
     }
     $db->bindValues($stmt, $params, $dbMap);
     if ($condition2Params) {
         foreach ($condition2Params as $idx => $v) {
             if (!is_array($v)) {
                 //propel uses arrays as bind values, we with Condition->toSql not.
                 $stmt->bindValue($idx, $v);
             }
         }
     }
     try {
         $stmt->execute();
     } catch (\PDOException $e) {
         throw new \PDOException($e->getMessage() . "\nSQL: {$sql}");
     }
     return $stmt;
 }
Example #3
0
 /**
  * @param ACLRequest $aclRequest
  *
  * @return bool
  */
 public function check(ACLRequest $aclRequest)
 {
     $objectKey = Objects::normalizeObjectKey($aclRequest->getObjectKey());
     $targetType = $aclRequest->getTargetType();
     $targetId = $aclRequest->getTargetId();
     $pk = $aclRequest->getPrimaryKey();
     $field = $aclRequest->getField();
     $pk = $this->objects->normalizePkString($objectKey, $pk);
     if (ACL::TARGET_TYPE_USER === $targetType && null === $targetId) {
         //0 means guest
         $targetId = $this->pageStack->getUser() ? $this->pageStack->getUser()->getId() : 0;
     }
     $user = $this->pageStack->getUser();
     if ($user) {
         $groupIds = $user->getGroupIds();
         if (false !== strpos(',' . $groupIds . ',', ',1,')) {
             //user is in the admin group, so he has always access.
             return true;
         }
     }
     if (ACL::TARGET_TYPE_USER === $targetType && 1 === $targetId) {
         //user admin has always access
         return true;
     }
     if (ACL::TARGET_TYPE_GROUP === $targetType && 1 === $targetId) {
         //group admin has always access
         return true;
     }
     if (0 === $targetId) {
         //guests do always have no access
         return false;
     }
     if (ACL::TARGET_TYPE_GROUP === $targetType && !$targetId) {
         throw new \InvalidArgumentException('For type TARGET_TYPE_GROUP a targetId is required.');
     }
     $cacheKey = null;
     if ($pk && $this->getCaching()) {
         $pkString = $this->objects->getObjectUrlId($objectKey, $pk);
         $cacheKey = md5($targetType . '.' . $targetId . '.' . $objectKey . '/' . $pkString . '/' . json_encode($field));
         $cached = $this->cacher->getDistributedCache('core/acl/' . $cacheKey);
         if (null !== $cached) {
             return $cached;
         }
     }
     $rules = self::getRules($objectKey, $aclRequest->getMode(), $targetType, $targetId);
     if (count($rules) === 0) {
         //no rules found, so we have no access
         return false;
     }
     $access = null;
     $currentObjectPk = $pk;
     $definition = $this->objects->getDefinition($objectKey);
     $not_found = true;
     //starts directly as if we were in the parent checking.
     $parent_acl = $aclRequest->isAsParent();
     $fCount = null;
     $fKey = null;
     $fValue = null;
     $fIsArray = is_array($field);
     if ($fIsArray) {
         $fCount = count($field);
         $fKey = key($field);
         $fValue = current($field);
         if (is_int($fKey)) {
             $fKey = $fValue;
             $fValue = null;
         }
     }
     $depth = 0;
     $match = false;
     $originObjectItemPk = $currentObjectPk;
     while ($not_found) {
         $currentObjectPkString = null;
         if ($currentObjectPk) {
             $currentObjectPkString = $this->objects->getObjectUrlId($objectKey, $currentObjectPk);
         }
         $depth++;
         if ($depth > 50) {
             $not_found = false;
             break;
         }
         foreach ($rules as $aclRule) {
             if ($parent_acl && !$aclRule['sub']) {
                 //as soon we enter the parent_acl mode we only take acl rules into consideration
                 //that are also valid for children (sub=true)
                 continue;
             }
             $match = false;
             /*
              * CUSTOM CONSTRAINT
              */
             if ($aclRule['constraint_type'] === ACL::CONSTRAINT_CONDITION) {
                 $objectItem = null;
                 if ($originObjectItemPk === $currentObjectPk && null !== $aclRequest->getPrimaryObjectItem()) {
                     $objectItem = $aclRequest->getPrimaryObjectItem();
                 } else {
                     if ($originObjectItemPk) {
                         $objectItem = $this->objects->get($objectKey, $currentObjectPk);
                     }
                 }
                 if ($objectItem && $this->conditionOperator->satisfy($aclRule['constraint_code'], $objectItem, $objectKey)) {
                     $match = true;
                 }
                 /*
                  * EXACT
                  */
             } else {
                 if ($aclRule['constraint_type'] === ACL::CONSTRAINT_EXACT) {
                     if ($currentObjectPk && $aclRule['constraint_code'] === $currentObjectPkString) {
                         $match = true;
                     }
                     /**
                      * ALL
                      */
                 } else {
                     $match = true;
                 }
             }
             if (!$match && $aclRule['sub'] && $currentObjectPk) {
                 // we need to check if a parent matches this $acl as we have sub=true
                 $parentItem = $this->objects->normalizePkString($objectKey, $currentObjectPk);
                 $parentCondition = Condition::create($aclRule['constraint_code']);
                 $parentOptions['fields'] = $this->conditionOperator->extractFields($parentCondition);
                 while ($parentItem = $this->objects->getParent($objectKey, $this->objects->getObjectPk($objectKey, $parentItem), $parentOptions)) {
                     if ($aclRule['constraint_type'] === ACL::CONSTRAINT_CONDITION && $this->conditionOperator->satisfy($parentCondition, $parentItem)) {
                         $match = true;
                         break;
                     } else {
                         if ($aclRule['constraint_type'] === ACL::CONSTRAINT_EXACT && $aclRule['constraint_code'] === $this->objects->getObjectUrlId($objectKey, $parentItem)) {
                             $match = true;
                             break;
                         }
                     }
                 }
             }
             if ($match) {
                 //match, check all $field
                 $field2Key = $field;
                 if ($field) {
                     if ($fIsArray && $fCount === 1) {
                         if (is_string($fKey) && is_array($aclRule['fields'][$fKey])) {
                             //this field has limits
                             if (($field2Acl = $aclRule['fields'][$fKey]) !== null) {
                                 if (is_array($field2Acl[0])) {
                                     //complex field rule, $field2Acl = ([{access: no, condition: [['id', '>', 2], ..]}, {}, ..])
                                     foreach ($field2Acl as $fRule) {
                                         $satisfy = false;
                                         if (($f = $definition->getField($fKey)) && $f->getType() === 'object') {
                                             $uri = $f->getObject() . '/' . $fValue;
                                             $uriObject = $this->objects->getFromUrl($uri);
                                             $satisfy = $this->conditionOperator->satisfy($fRule['condition'], $uriObject);
                                         } else {
                                             if (null !== $fValue) {
                                                 $satisfy = $this->conditionOperator->satisfy($fRule['condition'], $field);
                                             }
                                         }
                                         if ($satisfy) {
                                             return $fRule['access'] === 1 ? true : false;
                                         }
                                     }
                                     //if no field rules fits, we consider the whole rule
                                     if ($aclRule['access'] !== 2) {
                                         return $aclRule['access'] === 1 ? true : false;
                                     }
                                 } else {
                                     //simple field rule $field2Acl = ({"value1": yes, "value2": no}
                                     if ($field2Acl[$fKey] !== null) {
                                         return $field2Acl[$fKey] === 1 ? true : false;
                                     } else {
                                         //current($field) is not exactly defined in $field2Acl, so we set $access to $acl['access']
                                         //
                                         //if access = 2 then wo do not know it, cause 2 means 'inherited', so maybe
                                         //a other rule has more detailed rule
                                         if ($aclRule['access'] !== 2) {
                                             $access = $aclRule['access'] === 1 ? true : false;
                                             break;
                                         }
                                     }
                                 }
                             }
                         } else {
                             //this field has only true or false
                             $field2Key = $fKey;
                         }
                     }
                     if (!is_array($field2Key)) {
                         if ($aclRule['fields'] && ($field2Acl = $aclRule['fields'][$field2Key]) !== null && !is_array($aclRule['fields'][$field2Key])) {
                             $access = $field2Acl === 1 ? true : false;
                             break;
                         } else {
                             //$field is not exactly defined, so we set $access to $acl['access']
                             //and maybe a rule with the same code has the field defined
                             // if access = 2 then this rule is only for exactly define fields
                             if ($aclRule['access'] !== 2) {
                                 $access = $aclRule['access'] === 1 ? true : false;
                                 break;
                             }
                         }
                     }
                 } else {
                     $access = $aclRule['access'] === 1 ? true : false;
                     break;
                 }
             }
         }
         //foreach
         if (null === $access && $definition->isNested() && $pk) {
             //$access has not defined yet (no rule matched yet). Check if nested and $pk is given
             //load its root and check again
             if (null === ($currentObjectPk = $this->objects->getParentPk($objectKey, $currentObjectPk))) {
                 $access = $aclRequest->isRootHasAccess() ? true : $access;
                 break;
             }
             $parent_acl = true;
         } else {
             break;
         }
     }
     $access = (bool) $access;
     if ($pk && $this->getCaching()) {
         $this->cacher->setDistributedCache('core/acl/' . $cacheKey, $access);
     }
     return $access;
 }
Example #4
0
 /**
  * {@inheritDoc}
  */
 public function getBranch($pk = null, Condition $condition = null, $depth = 1, $scope = null, $options = null)
 {
     $result = null;
     $path = $pk['path'];
     if ($depth === null) {
         $depth = 1;
     }
     if ($path) {
         $path = '@' . trim($path, '/@');
         $path = str_replace(':', '/', $path);
     }
     $c = 0;
     $offset = $options['offset'];
     $limit = $options['limit'];
     $result = array();
     if (!$path) {
         $result = array();
         $bundles = array_keys($this->jarves->getBundles());
         foreach ($bundles as $bundleName) {
             $directory = $this->jarves->resolvePath('@' . $bundleName, 'Resources/views', true);
             if (!$this->localFilesystem->has($directory)) {
                 continue;
             }
             $file = $this->localFilesystem->getFile($directory);
             if (!$file) {
                 $result[] = $directory;
                 continue;
             }
             $file = $file->toArray();
             $file['name'] = $bundleName;
             $file['path'] = $bundleName;
             if ($offset && $offset > $c) {
                 continue;
             }
             if ($limit && $limit < $c) {
                 continue;
             }
             if ($condition && $condition->hasRules() && !$this->conditionOperator->satisfy($condition, $file)) {
                 $result[] = $directory;
                 continue;
             }
             $c++;
             if ($depth > 0) {
                 $children = self::getBranch(array('path' => $bundleName), $condition, $depth - 1);
                 $file['_childrenCount'] = count($children);
                 if ($depth > 1 && $file['type'] == 'dir') {
                     $file['_children'] = $children;
                 }
             }
         }
     } else {
         if (!($bundleName = $this->jarves->getBundleFromPath($path))) {
             return [];
         }
         $directory = $this->jarves->resolvePath($path, 'Resources/views', true) . '/';
         if (!$this->localFilesystem->has($directory)) {
             return [];
         }
         $files = $this->localFilesystem->getFiles($directory);
         foreach ($files as $file) {
             $item = $file->toArray();
             if ($condition && $condition->hasRules() && !$this->conditionOperator->satisfy($condition, $item, 'jarves/file')) {
                 continue;
             }
             $c++;
             if ($offset && $offset >= $c) {
                 continue;
             }
             if ($limit && $limit < $c) {
                 continue;
             }
             $item = array('name' => $this->buildPath($path . '/' . Tools::getRelativePath($item['path'], $directory)), 'path' => $this->buildPath($path . '/' . Tools::getRelativePath($item['path'], $directory)));
             if ($file->isDir()) {
                 $children = self::getBranch(array('path' => $item['path']), $condition, $depth - 1);
                 foreach ($children as $child) {
                     //                        $child['name'] = $item['name'] . '/' . $child['name'];
                     $result[] = $child;
                 }
             }
             if ($file->isFile()) {
                 $result[] = $item;
             }
         }
     }
     return $result;
 }
Example #5
0
 /**
  * Patches a object entry. This means, only defined fields will be saved. Fields which are not defined will
  * not be overwritten.
  *
  * @param  array $pk
  *
  * @param  Request|array $requestOrData
  * @return bool
  *
  * @throws AccessDeniedException
  * @throws ObjectNotFoundException
  * @throws \Exception
  */
 public function patch($pk, $requestOrData)
 {
     $storageController = $this->objects->getStorageController($this->getObject());
     $pk = $storageController->normalizePrimaryKey($pk);
     $this->primaryKey = $pk;
     $values = $this->collectData($requestOrData);
     $args = ['pk' => $pk, 'values' => &$values, 'controller' => $this, 'mode' => 'update'];
     $eventPre = new GenericEvent($this->getObject(), $args);
     $this->eventDispatcher->dispatch('core/object/modify-pre', $eventPre);
     $this->eventDispatcher->dispatch('core/object/patch-pre', $eventPre);
     $item = $this->getItem($pk);
     if ($this->getPermissionCheck()) {
         if (!$item) {
             return null;
         }
         if (!$this->acl->check(ACLRequest::create($this->getObject(), $pk)->onlyUpdateMode())) {
             return null;
         }
         foreach ($values as $fieldName => $value) {
             $aclRequest = ACLRequest::create($this->getObject(), $pk)->setField([$fieldName => $value])->onlyUpdateMode();
             if (!$this->acl->check($aclRequest)) {
                 throw new AccessDeniedException(sprintf('Not allowed to change `%s`', $fieldName));
             }
         }
     }
     if (($condition = $this->getCondition()) && $condition->hasRules()) {
         if (!$this->conditionOperator->satisfy($condition, $item, $this->getObject())) {
             return null;
         }
     }
     $incomingFields = $requestOrData instanceof Request ? array_keys($requestOrData->request->all()) : array_keys($requestOrData);
     if (!$incomingFields) {
         return false;
     }
     $changedData = $this->mapData($values, $incomingFields, $item);
     if ($this->getWithNewsFeed()) {
         $this->utils->newNewsFeed($this->objects, $this->getObject(), array_merge($values, $pk), 'updated');
     }
     $result = $storageController->patch($pk, $changedData);
     $args['result'] = $result;
     $event = new GenericEvent($this->getObject(), $args);
     $this->eventDispatcher->dispatch('core/object/modify', $event);
     $this->eventDispatcher->dispatch('core/object/patch', $event);
     return $result;
 }