Просмотр исходного кода

added WFS GetFeature recurse field list read access validation

Piotr Labudda 8 лет назад
Родитель
Сommit
3f1a7d5827
2 измененных файлов с 51 добавлено и 104 удалено
  1. 36 5
      SE/se-lib/AntAclBase.php
  2. 15 99
      SE/se-lib/Api/Wfs/GetFeature.php

+ 36 - 5
SE/se-lib/AntAclBase.php

@@ -161,19 +161,50 @@ class AntAclBase extends Core_AclBase {
 	}
 
 	public function canWriteField($fieldName) {
-		return false; // TODO: return $this->getPerms($fieldName)->canWrite()
+		return false; // TODO: $this->getAclInfo($fieldName); @see canReadField
 	}
 	public function canCreateField($fieldName) {
-		return false; // TODO: return $this->getPerms($fieldName)->canCreate()
+		return false; // TODO: $this->getAclInfo($fieldName); @see canReadField
 	}
 	public function canReadField($fieldName) {
-		return true; // TODO: return $this->getPerms($fieldName)->canRead()
+		try {
+			$fieldAclInfo = $this->getAclInfo($fieldName);
+			DBG::log($fieldAclInfo, 'array', "AntAclBase: canReadField({$fieldName})...");
+			return ($fieldAclInfo['PERM_R'] > 0);
+		} catch (Exception $e) {
+			DBG::log($e);
+			return false;
+		}
+		return false;
 	}
 	public function canReadObjectField($fieldName, $object) {
-		return true; // TODO: return $this->getPerms($fieldName, $object)->canRead()
+		return true; // TODO: $this->getAclInfo($fieldName); @see canReadField
 	}
 	public function canWriteObjectField($fieldName, $record) {
-		return false; // TODO: return $this->getPerms($fieldName, $object)->canWrite()
+		return false; // TODO: $this->getAclInfo($fieldName); @see canReadField
+	}
+	public function getAclInfo($fieldName = null) {
+		static $_aclInfo = null; // [ fieldName => [ id => {idZasob}, perms => 'RWX...' ] // TODO: , sort_prio => {SORT_PRIO}, label => {CELL_LABEL}  ]
+		if (null === $_aclInfo) {
+			$_aclInfo = [];
+			$fieldsConfig = User::getAcl()->getPermsForTable($this->getID()); // @returns [ permInfo group by ID_CELL ]; permInfo = [ ID_CELL, CELL_NAME, CELL_LABEL, SORT_PRIO, PERM_R, PERM_W, PERM_... ]
+			DBG::log($fieldsConfig, 'array', "AntAclBase: User::getAcl()->getPermsForTable(".$this->getID().");");
+			// $this->initFieldsFromConfig($fieldsConfig);
+			$permCols = [ 'PERM_R', 'PERM_W', 'PERM_X', 'PERM_C', 'PERM_S', 'PERM_O', 'PERM_V', 'PERM_E' ];
+			foreach ($fieldsConfig as $row) {
+				$nameField = $row['CELL_NAME'];
+				$_aclInfo[ $nameField ] = [
+					'idZasob' => $row['ID_CELL'],
+					'label' => $row['CELL_LABEL'],
+					'sort_prio' => $row['SORT_PRIO'],
+				];
+				foreach ($permCols as $colPerm) $_aclInfo[ $nameField ][ $colPerm ] = (int)$row[ $colPerm ];
+			}
+		}
+		if ($fieldName && !array_key_exists($fieldName, $_aclInfo)) {
+			throw new Exception("Field not exists or missing access '{$fieldName}'");
+		}
+		return ($fieldName) ? $_aclInfo[$fieldName] : $_aclInfo;
 	}
 
 	public function getFields() { // TODO: conflict return structure with TableAcl

+ 15 - 99
SE/se-lib/Api/Wfs/GetFeature.php

@@ -5,9 +5,12 @@ Lib::loadClass('Core_AclHelper');
 
 class Api_Wfs_GetFeature {
 
-	public static function convertOgcPropertyListToFeatureQueryColsRecurseDBG(&$schemaCache, $ogcPropertyList, $aclOrSchema, $dbgLoopNr = 0) {
+	public static function convertOgcPropertyListToFeatureQueryCols(&$schemaCache, $ogcPropertyList, $acl) {
+		return self::convertOgcPropsRecurse($schemaCache, $ogcPropertyList, $acl);
+	}
+	public static function convertOgcPropsRecurse(&$schemaCache, $ogcPropertyList, $aclOrSchema, $dbgLoopNr = 0) {
 		if ($dbgLoopNr > 10) {
-			DBG::log($ogcPropertyList, 'array', 'TODO: split $ogcPropertyList to acl fields and nested fields - DBG LOOP LIMIT 10');
+			DBG::log($ogcPropertyList, 'array', 'convertOgcPropsRecurse: LOOP LIMIT 10! - return []');
 			return [];
 		}
 		$acl = null;
@@ -18,12 +21,12 @@ class Api_Wfs_GetFeature {
 		} else throw new Exception("Missing acl");
 
 		if (empty($ogcPropertyList)) {
-			// DBG::log($acl->getFields(), '', "TODO: \$ogcPropertyList = \$acl->getFields()");
-			// DBG::log($acl->getFieldListByIdZasob(), 'array', "TODO: \$ogcPropertyList = \$acl->getFieldListByIdZasob()");
 			$ogcPropertyList = array_values($acl->getFieldListByIdZasob());
+			$ogcPropertyList = array_filter($ogcPropertyList, function ($fieldName) use ($acl) {
+				return $acl->canReadField($fieldName);
+			});
 		}
 
-		DBG::log($ogcPropertyList, 'array', 'TODO: split $ogcPropertyList to acl fields and nested fields');
 		$aclFields = array_filter($ogcPropertyList, function ($prop) { return ( false === strpos($prop, '/') ); });
 		$nestedFields = array_reduce(
 			array_filter($ogcPropertyList, function ($prop) { return ( false !== strpos($prop, '/') ); }),
@@ -38,10 +41,12 @@ class Api_Wfs_GetFeature {
 		if (!empty($nestedFields)) {
 			$aclFields = array_unique(array_merge($aclFields, array_keys($nestedFields)));
 		}
-		DBG::log([$aclFields, $nestedFields], 'array', 'TODO: splited $ogcPropertyList to acl fields and nested fields');
+		DBG::log([$aclFields, $nestedFields], 'array', 'convertOgcPropsRecurse: splited to acl fields and nested fields');
 
-		// TODO: convert '*' to local fields
-		// TODO: validate $aclFields is in $acl->getFields() or in $schemaCache[ nsLocal ]
+		// TODO: convert '*' to fields (only local?)
+		foreach ($aclFields as $fieldName) {
+			if (!$acl->canReadField($fieldName)) throw new Exception("Access Denied to read field '{$fieldName}' from '" . $acl->getNamespace() . "'");
+		}
 
 		$contextFieldList = $aclFields;
 		foreach ($nestedFields as $childName => $nestedProps) {
@@ -53,99 +58,10 @@ class Api_Wfs_GetFeature {
 	   			$contextFieldList,
 	   			array_map(function ($childCtxFld) use ($childName) {
 					return "{$childName}/{$childCtxFld}";
-				}, self::convertOgcPropertyListToFeatureQueryColsRecurseDBG($schemaCache, $nestedProps, $schemaCache[$childNs], $dbgLoopNr + 1))
+				}, self::convertOgcPropsRecurse($schemaCache, $nestedProps, $schemaCache[$childNs], $dbgLoopNr + 1))
 	   		);
 		}
-		DBG::log($contextFieldList, 'array', 'TODO: splited $ogcPropertyList return $contextFieldList');
-		return $contextFieldList;
-		// $acl__getAllFieldNames = function ($listFields) {
-		// 	return array_map(function ($field) {
-		// 		return $field['fieldNamespace'];
-		// 	}, $listFields);
-		// };
-		// $acl__getLocalFieldNames = function ($listFields) {
-		// 	return array_map(function ($field) {
-		// 		return $field['fieldNamespace'];
-		// 	}, array_filter($listFields, function ($field) {
-		// 		return $field['isLocal'];
-		// 	}));
-		// };
-	}
-	public static function convertOgcPropertyListToFeatureQueryCols(&$schemaCache, $ogcPropertyList, $acl) {
-		$contextFieldList = [];
-		$acl__getAllFieldNames = function ($listFields) {
-			return array_map(function ($field) {
-				return $field['fieldNamespace'];
-			}, $listFields);
-		};
-		$acl__getLocalFieldNames = function ($listFields) {
-			return array_map(function ($field) {
-				return $field['fieldNamespace'];
-			}, array_filter($listFields, function ($field) {
-				return $field['isLocal'];
-			}));
-		};
-		// DBG::log($acl->getFields(), 'array', "\$contextFieldList ACL fields");
-		// if (empty($ogcPropertyList)) { // get all local fields
-		// 	// $contextFieldList = $acl__getLocalFieldNames($acl->getFields());
-		// 	$contextFieldList = $acl__getAllFieldNames($acl->getFields());
-		// } else {
-		// 	foreach ($ogcPropertyList as $fieldXPath) {
-		// 		if ('*' === $fieldXPath) {
-		// 			$contextFieldList = array_merge($contextFieldList, $acl__getLocalFieldNames($acl->getFields()));
-		// 		} else if (false === strpos($fieldXPath, '/') && false === strpos($fieldXPath, ':')) {
-		// 			$contextFieldList[] = $fieldXPath;
-		// 		} else if (false === strpos($fieldXPath, '/') && false !== strpos($fieldXPath, ':')) {
-		// 			$contextFieldList[] = $fieldXPath;
-		// 			$fieldNs = str_replace(['__x3A__', ':'], '/', $fieldXPath);
-		// 			$schemaCache[$fieldNs] = SchemaFactory::loadDefaultObject('SystemObject')->getItem($fieldNs, [ 'propertyName' => '*,field' ]);
-		// 			DBG::log($schemaCache[$fieldNs], 'array', "\$schemaCache[{$fieldNs}]");
-		// 		} else if ('/*' === substr($fieldXPath, -2) && false === strpos(substr($fieldXPath, 0, -2), '/')) {
-		// 			$fieldName = substr($fieldXPath, 0, -2);
-		// 			$contextFieldList[] = $fieldName;
-		// 			$xsdType = $acl->getXsdFieldType($fieldName);
-		// 			if ('ref:' !== substr($xsdType, 0, 4)) throw new Exception("Error Processing Request - field '{$fieldXPath}' type is not ref '/*' is not allowed");
-		// 			$fieldNs = str_replace(['__x3A__', ':'], '/', substr($xsdType, 4));
-		// 			if (!array_key_exists($fieldNs, $schemaCache)) {
-		// 				$schemaCache[$fieldNs] = SchemaFactory::loadDefaultObject('SystemObject')->getItem($fieldNs, [ 'propertyName' => '*,field' ]);
-		// 				DBG::log($schemaCache[$fieldNs], 'array', "\$schemaCache[{$fieldNs}]");
-		// 			}
-		// 			$fieldPrefix = "{$fieldName}";
-		// 			$contextFieldList = array_merge($contextFieldList, array_map(function ($fieldName) use ($fieldPrefix) {
-		// 				return "{$fieldPrefix}/{$fieldName}";
-		// 			}, $acl__getLocalFieldNames($schemaCache[$fieldNs]['field'])));
-		// 		} else {
-		// 			$fieldName = trim($fieldXPath, '*/');
-		// 			DBG::log(['$fieldXPath'=>$fieldXPath, '$fieldName'=>$fieldName], 'array', "\$contextFieldList TODO");
-		// 			if (false !== strpos($fieldName, '/')) {
-		// 				$xpathParts = explode('/', $fieldName);
-		// 				DBG::log($xpathParts, 'array', "\$xpathParts recurse TODO");
-		// 				$localFieldName = array_shift($xpathParts);
-		// 				DBG::log($localFieldName, 'array', "\$xpathParts recurse TODO \$localFieldName");
-		// 				if ('*' === end($xpathParts)) array_pop($xpathParts);
-		// 				if (!empty($xpathParts)) {
-		// 					foreach ($xpathParts as $part) {
-		// 						if (false !== strpos($part, ':')) {
-		// 							$fieldNs = str_replace(['__x3A__', ':'], '/', $part);
-		// 							if (!array_key_exists($fieldNs, $schemaCache)) {
-		// 								$schemaCache[$fieldNs] = SchemaFactory::loadDefaultObject('SystemObject')->getItem($fieldNs, [ 'propertyName' => '*,field' ]);
-		// 								DBG::log($schemaCache[$fieldNs], 'array', "\$schemaCache[{$fieldNs}] recurse TODO");
-		// 							}
-		// 						}
-		// 					}
-		// 					$contextFieldList[] = $localFieldName . "/" . implode("/", $xpathParts) . "/*";
-		// 				}
-		// 				// 'default_db__x3A__CRM_PROCES:PROCES/ID',
-		// 				// 'default_db__x3A__CRM_PROCES:PROCES/default_db__x3A__CRM_WSKAZNIK:CRM_WSKAZNIK/*',
-		// 			}
-		// 		}
-		// 	}
-		// }
-		// DBG::log($contextFieldList, 'array', "\$contextFieldList");
-		// DBG::log(array_keys($schemaCache), 'array', "\$schemaCache keys");
-
-		return self::convertOgcPropertyListToFeatureQueryColsRecurseDBG($schemaCache, $ogcPropertyList, $acl);
-
+		DBG::log($contextFieldList, 'array', 'convertOgcPropsRecurse: return $contextFieldList');
 		return $contextFieldList;
 	}