Преглед изворни кода

fixed security bug in wfs qgis API - skip field values not allowed to read

Piotr Labudda пре 9 година
родитељ
комит
a28bf94310
1 измењених фајлова са 17 додато и 103 уклоњено
  1. 17 103
      SE/se-lib/Api/WfsQgisServer.php

+ 17 - 103
SE/se-lib/Api/WfsQgisServer.php

@@ -67,7 +67,7 @@ class Api_WfsQgisServer extends Api_WfsServerBase {
 		// get BBox from geom_field (only one geom fld is allowed)
 		$geomFld = null;
 		{
-			foreach ($fldList as $fldName) {
+			foreach ($fldList as $idZasob => $fldName) {
 				if ($acl->isGeomField($fldName)) {
 					$geomFld = $fldName;
 				}
@@ -117,7 +117,6 @@ if($DBG){echo 'getItems:';print_r($searchParams);echo "\n";}
 		$items = $acl->getItems($searchParams);
 		$this->DBG("items(" . count($items) . ")", __LINE__, __FUNCTION__, __CLASS__);
 
-if (true) {//1 == V::get('XML_WRITER', 0, $_GET, 'int')) {
 		header('Content-type: application/xml; charset=utf-8');
 		$xmlWriter = new XMLWriter();
 		$xmlWriter->openUri('php://output');
@@ -156,7 +155,7 @@ if($DBG){echo '(geomFld: '.$geomFld.'):';print_r($acl->getFieldType($geomFld));e
 		$this->DBG("before loop...", __LINE__, __FUNCTION__, __CLASS__);
 		foreach ($items as $itemKey => $item) {
 			if (0 == (++$dbgLoop) % 500) $this->DBG("items loop:{$dbgLoop}", __LINE__, __FUNCTION__, __CLASS__);
-if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item->{$geomFld}).'):';print_r($item->{$geomFld});echo "\n";}
+			if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item->{$geomFld}).'):';print_r($item->{$geomFld});echo "\n";}
 			if ($geomFld) {
 				if (empty($item->{$geomFld})) {
 					continue;// QGIS crash when WFS contain features with empty geom field
@@ -165,10 +164,11 @@ if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item->{$geomFld
 			$xmlWriter->startElement('gml:featureMember');
 				$xmlWriter->startElement("{$wfsNs}:{$type}");
 					$xmlWriter->writeAttribute('fid', "{$type}.{$itemKey}");
-					foreach ($fldList as $fldName) {
-						// if ($acl->isGeomField($fldName)) {// BUG: wolno
-						// if($fldName == 'the_geom'){// OK szybko
-						if ($geomFld != null && $fldName == $geomFld){
+					foreach ($fldList as $idZasob => $fldName) {
+						// if (!$acl->isAllowed($idZasob, 'R', $item)) {echo '<!-- '."[{$idZasob}]({$fldName}) not allowed to read: ";print_r($item);echo' -->';}
+						if (!$acl->isAllowed($idZasob, 'R', $item)) continue;
+						// if ($acl->isGeomField($fldName)) // BUG: wolno
+						if ($geomFld != null && $fldName == $geomFld) {
 							$xmlWriter->startElement("{$wfsNs}:{$fldName}");
 								$this->_typeConverter->createGmlFromWkt_xmlWriter($item->{$fldName}, $xmlWriter);
 							$xmlWriter->endElement();// {$wfsNs}:{$fldName}
@@ -189,98 +189,7 @@ if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item->{$geomFld
 		$xmlWriter->endElement();// wfs:FeatureCollection
 		$xmlWriter->endDocument();
 		$this->DBG("items loop END", __LINE__, __FUNCTION__, __CLASS__);
-		//'<!-- .EOF -->';
 		exit;
-}
-
-		$dom = new DOMDocument('1.0', 'utf-8');
-		$dom->formatOutput = true;
-		$dom->preserveWhiteSpace = false;
-		$rootNode = $dom->createElementNS('http://www.opengis.net/wfs', 'wfs:FeatureCollection');
-		$dom->appendChild($rootNode);
-		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.opengis.net/wfs');
-		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:wfs', 'http://www.opengis.net/wfs');
-		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
-		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
-		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
-		$rootNode->setAttribute('xsi:schemaLocation', "{$wfsNsUri} {$featureTypeUri}");
-
-if(0){// TODO: get BBOX for add features
-			$boundedByNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:boundedBy');
-			$rootNode->appendChild($boundedByNode);
-				$boxNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:Box');
-				$boundedByNode->appendChild($boxNode);
-				$boxNode->setAttribute('srsName', "http://www.opengis.net/gml/srs/epsg.xml#4326");// TODO: EPSG
-					$coordinatesNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:coordinates');
-					$boxNode->appendChild($coordinatesNode);
-					$coordinatesNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
-					$coordinatesNode->setAttribute('decimal', '.');
-					$coordinatesNode->setAttribute('cs', ',');
-					$coordinatesNode->setAttribute('ts', ' ');
-					$coordinatesNode->nodeValue = '1544947.6295,4322758.105 1548002.2259,4330464.1001';// TODO: coordinates for all items?
-}
-
-if($DBG){echo '(geomFld: '.$geomFld.'):';print_r($acl->getFieldType($geomFld));echo "\n";}
-		if (empty($items)) {
-			$pKeyField = $acl->getPrimaryKeyField();
-			$fakeItem = new stdClass();
-			$fakeItem->{$pKeyField} = 0;
-			if ('polygon' == $dbGeomType) {
-				$fakeItem->the_geom = "POLYGON(())";
-			} else if ('linestring' == $dbGeomType) {
-				$fakeItem->the_geom = "LINESTRING()";
-			} else if ('point' == $dbGeomType) {
-				$fakeItem->the_geom = "POINT(0,0)";
-			}
-			$items[0] = $fakeItem;
-		}
-		$dbgLoop = 0;
-		foreach ($items as $itemKey => $item) {
-			$dbgLoop++; if (0 == $dbgLoop % 100) $this->DBG("items loop:{$dbgLoop}", __LINE__, __FUNCTION__, __CLASS__);
-if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item->{$geomFld}).'):';print_r($item->{$geomFld});echo "\n";}
-			if ($geomFld) {
-				if (empty($item->{$geomFld})) {
-					continue;// QGIS crash when WFS contain features with empty geom field
-				}
-			}
-
-			$featureMemberNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:featureMember');
-			$rootNode->appendChild($featureMemberNode);
-				$featureNode = $dom->createElementNS($wfsNsUri, "{$wfsNs}:{$type}");
-				$featureMemberNode->appendChild($featureNode);
-				$featureNode->setAttribute('fid', "{$type}.{$itemKey}");
-if(0){// TODO: get BBOX
-					$boundedByNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:boundedBy');
-					$featureNode->appendChild($boundedByNode);
-						$boxNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:Box');
-						$boundedByNode->appendChild($boxNode);
-						$boxNode->setAttribute('srsName', "http://www.opengis.net/gml/srs/epsg.xml#4326");// TODO: EPSG
-							$coordinatesNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:coordinates');
-							$boxNode->appendChild($coordinatesNode);
-							$coordinatesNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
-							$coordinatesNode->setAttribute('decimal', '.');
-							$coordinatesNode->setAttribute('cs', ',');
-							$coordinatesNode->setAttribute('ts', ' ');
-							$coordinatesNode->nodeValue = '1546472.2363,4328949.5775 1548002.2259,4330464.1001';// TODO: coordinates for item?
-}
-					foreach ($fldList as $fldName) {
-						$featureFldNode = $dom->createElementNS($wfsNsUri, "{$wfsNs}:{$fldName}");
-						if ($acl->isGeomField($fldName)) {
-							$geomNode = $this->_typeConverter->createGmlFromWkt($item->{$fldName}, $dom);
-							if (!$geomNode) continue;
-							$featureFldNode->appendChild($geomNode);
-						} else {
-							$featureFldNode->nodeValue = str_replace('&', '&amp;', $item->{$fldName});
-							if (empty($featureFldNode->nodeValue) && '0' !== $featureFldNode->nodeValue) {
-								continue;
-							}
-						}
-						$featureNode->appendChild($featureFldNode);
-					}
-		}
-		$this->DBG("items loop END", __LINE__, __FUNCTION__, __CLASS__);
-
-		return $dom->saveXml();
 	}
 
 	public function describeFeatureTypeAction() {
@@ -342,12 +251,17 @@ if(0){// TODO: get BBOX
 	}
 
 	public function _getFieldListFromAcl($acl) {
-		$fldList = $acl->getRealFieldList();
-		{// mv the_geom to the first place
-			array_unshift($fldList, 'the_geom');
-			$fldList = array_unique($fldList);
+		$fldList = $acl->getRealFieldListByIdZasob();
+		// mv the_geom to the first place
+		$orderedFldList = array();
+		foreach ($fldList as $idZasob => $fldName) {
+			if ('the_geom' == $fldName) $orderedFldList[$idZasob] = $fldName;
+		}
+		foreach ($fldList as $idZasob => $fldName) {
+			if ('the_geom' == $fldName) continue;
+			$orderedFldList[$idZasob] = $fldName;
 		}
-		return $fldList;
+		return $orderedFldList;
 	}
 
 }