Parcourir la source

added wfs proces filtr api link, fixed wfs error msg

Piotr Labudda il y a 9 ans
Parent
commit
ee8d51d77c
3 fichiers modifiés avec 143 ajouts et 41 suppressions
  1. 69 0
      SE/se-lib/Api/WfsException.php
  2. 22 35
      SE/se-lib/Api/WfsQgis.php
  3. 52 6
      SE/se-lib/Api/WfsServerBase.php

+ 69 - 0
SE/se-lib/Api/WfsException.php

@@ -1,4 +1,73 @@
 <?php
 
+// @usage: throw new Api_WfsException("Access Denied to Create field '{$fieldName}' in object '{$typeName}.{$pkObject}'", __LINE__, null, 'MissingFieldPermCreate', 'request');
+
+// <xsd:schema
+//     targetNamespace="http://www.opengis.net/ogc"
+//     xmlns:ogc="http://www.opengis.net/ogc"
+//     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+//     elementFormDefault="qualified">
+//
+//     <xsd:element name="ServiceExceptionReport">
+//        <xsd:complexType>
+//           <xsd:sequence>
+//              <xsd:element name="ServiceException"
+//                           type="ogc:ServiceExceptionType"
+//                           minOccurs="0" maxOccurs="unbounded"/>
+//           </xsd:sequence>
+//           <xsd:attribute name="version" type="xsd:string" fixed="1.3.0"/>
+//        </xsd:complexType>
+//     </xsd:element>
+//
+//     <xsd:complexType name="ServiceExceptionType">
+//        <xsd:simpleContent>
+//           <xsd:extension base="xsd:string">
+//              <xsd:attribute name="code" type="xsd:string"/>
+//              <xsd:attribute name="locator" type="xsd:string"/>
+//           </xsd:extension>
+//        </xsd:simpleContent>
+//     </xsd:complexType>
+// </xsd:schema>
 class Api_WfsException extends Exception {
+
+  public $wfsCode = '';
+  public $wfsLocator = '';
+
+  public function __construct($message, $code = 0, Exception $previous = null, $wfsCode = '', $wfsLocator = '') {
+    $this->wfsCode = $wfsCode;
+    $this->wfsLocator = $wfsLocator;
+    parent::__construct($message, $code, $previous);
+  }
+
+  public function generateResponseXml() {
+    $xmlWriter = new XMLWriter();
+    if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404);
+		// $xmlWriter->openUri('php://output');
+		$xmlWriter->openMemory();
+		$xmlWriter->setIndent(true);
+		$xmlWriter->startDocument('1.0','UTF-8');
+		$xmlWriter->startElement('ServiceExceptionReport');
+    {
+      $xmlWriter->writeAttribute('xmlns', 'http://www.opengis.net/ogc');
+      $xmlWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
+      $xmlWriter->writeAttribute('xsi:schemaLocation', 'http://www.opengis.net/ogc http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd');
+      $xmlWriter->writeAttribute('version', '1.2.0');
+      $xmlWriter->startElement('ServiceException');
+      {
+        if ($this->wfsCode) $xmlWriter->writeAttribute('code', $this->wfsCode);
+        if ($this->wfsLocator) $xmlWriter->writeAttribute('locator', $this->wfsLocator);
+        $xmlWriter->text($this->message);
+      }
+      $xmlWriter->endElement();// ServiceException
+    }
+    $xmlWriter->endElement();// ServiceExceptionReport
+    $xmlWriter->endDocument();
+    return $xmlWriter->outputMemory(true);
+  }
+
+  public function sendResponseXml() {
+    header('Content-type: application/xml');
+    echo $this->generateResponseXml();
+  }
+
 }

+ 22 - 35
SE/se-lib/Api/WfsQgis.php

@@ -11,6 +11,7 @@ class Api_WfsQgis extends ApiRouteBase {// TODO: extends Api_WfsBase which exten
 
 	public $_apiUser;
 	public $_apiBaseUri;
+	public $_idFiltrProces;
 	public $_dataSourceName;
 	public $_tblName;
 	public $_tblSchema;
@@ -21,33 +22,27 @@ class Api_WfsQgis extends ApiRouteBase {// TODO: extends Api_WfsBase which exten
 		$this->setLogger($wfsLogger);
 		$this->reqDBG($request);
 
-		/* TODO: return response xml document
-		$responseDocument = null;
-		try {
-			$responseDocument = $this->wfsServerAction($request);
-		} catch (Api_WfsException $e) {// TODO: create WfsException - http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd
-		//} catch (Exception $e) {// TODO: create WfsException - http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd
-			$responseDocument = $this->wfsExceptionAction($request, $e);
-		}
-		return $responseDocument;
-		*/
-
 		if (empty($request->segments)) {
 			//$this->mainWpsAction($request);// show list of posible data source
 			throw new HttpException("Bad Request", 400);
 		} else {
-			$this->_dataSourceName = array_shift($request->segments);
+			$pathPart = array_shift($request->segments);
+			if ('filtr_proces_' == substr($pathPart, 0, 13)) {
+				$this->_idFiltrProces = (int)substr($pathPart, 13);
+				if (!$this->_idFiltrProces) throw new Api_WfsException("Wrong filtr process number");
+				$this->DBG("filtr procesu({$idProcesFiltr})", __LINE__, __FUNCTION__, __CLASS__);
+
+				$pathPart = array_shift($request->segments);
+			}
+			$this->_dataSourceName = $pathPart;
 			$this->DBG("_dataSourceName:$this->_dataSourceName", __LINE__, __FUNCTION__, __CLASS__);
 			try {
 				$this->dataSourceAction($request);
 			} catch (Api_WfsException $e) {
-				$responseDocument = $this->wfsExceptionAction($e);
-				header('Content-type: application/xml');
-				echo $responseDocument;
+				$e->sendResponseXml();
 			} catch (Exception $e) {
-				$responseDocument = $this->wfsExceptionAction($e);
-				header('Content-type: application/xml');
-				echo $responseDocument;
+				$wfsException = new Api_WfsException($e->getMessage(), $e->getCode(), $e);
+				$wfsException->sendResponseXml();
 			}
 			$this->DBG("END", __LINE__, __FUNCTION__, __CLASS__);
 		}
@@ -59,29 +54,21 @@ class Api_WfsQgis extends ApiRouteBase {// TODO: extends Api_WfsBase which exten
 	public function wfsServerAction($request) {
 	}
 
-	public function wfsExceptionAction($e) {
-		$dom = new DOMDocument('1.0', 'utf-8');
-		$dom->formatOutput = true;
-		$dom->preserveWhiteSpace = false;
-		$rootNode = $dom->createElementNS('http://www.opengis.net/ogc', 'ServiceExceptionReport');
-		$dom->appendChild($rootNode);
-		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
-		$rootNode->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation', 'http://www.opengis.net/ogc http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd');
-		$rootNode->setAttribute('version', '1.2.0');
-
-		$srvExNode = $dom->createElement('ServiceException', $e->getMessage());
-		$rootNode->appendChild($srvExNode);
-
-		return $dom->saveXML();
-	}
-
 	public function dataSourceAction($request) {
 		$document = '';
 		//$userAcl = User::getAcl();
 		IF(V::get('DBG','',$_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">user (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_apiUser);echo'</pre>';}
 		$userAcl = new UserAcl($this->_apiUser->getID(), $use_cache = true);
 		$userAcl->fetchGroups();
-		$userAcl->fetchAllPerms(true);
+		if ($this->_idFiltrProces) {
+			if (!$userAcl->canExecuteProcesInit($this->_idFiltrProces)) {
+				throw new Api_WfsException("Access Denied for given process");
+			}
+			$userAcl->fetchProcesPerms($this->_idFiltrProces, true);
+		} else {
+			$userAcl->fetchAllPerms(true);
+		}
+
 		DBG::_('DBG', '>2', 'userAcl', $userAcl, __CLASS__, __FUNCTION__, __LINE__);
 
 		$this->DBG("usr:" . $this->_apiUser->getID(), __LINE__, __FUNCTION__, __CLASS__);

+ 52 - 6
SE/se-lib/Api/WfsServerBase.php

@@ -590,7 +590,7 @@ class Api_WfsServerBase {
 		$DBG = (V::get('DBG_XML', '', $_GET) > 0);// TODO: Profiler
 		$rootTagName = V::get('tag', '', $requestXmlTags[0]);
 		if ('Transaction' != $rootTagName) {
-			throw new Exception("Parse Request xml error #" . __LINE__);
+			throw new Api_WfsException("Parse Request XML Error - Missing Transaction as root xml tag", __LINE__, null, 'TransactionParseError', 'request');
 		}
 
 		// 1. convert request: wfs.transaction.convert-wfs-request.xsl
@@ -649,18 +649,64 @@ class Api_WfsServerBase {
 			}
 		}
 		if (empty($usedSourceNsList)) {
-			throw new Exception("Parse Request xml error #" . __LINE__ . ": not implemented");
+			throw new Api_WfsException("Parse Request XML Error - Empty source NS list", __LINE__, null, 'TransactionParseError', 'request');
 		}
 
 		$convertedTransaction = $this->_convertTransactionXml($requestXml, $usedSourceNsList);
 if($DBG){echo 'L.' . __LINE__ . ' $convertedTransaction:';print_r($convertedTransaction);echo "\n";}
 		if (empty($convertedTransaction)) {
-			throw new Exception("Parse Request xml error #" . __LINE__ . ": convert Transaction");
+			throw new Api_WfsException("Parse Request XML Error - Empty transaction", __LINE__, null, 'TransactionParseError', 'request');
 		}
-//echo "\ntags[0]:\n" . json_encode($requestXmlTags[0]) . "\n";
-//echo "\nconvertedTransaction:\n" . $convertedTransaction . "\n";
-//echo "\nsourceNsList:\n" . json_encode($sourceNsList) . "\n";
 		if (!$this->_validateConvertedTransactionXml($convertedTransaction, $usedSourceNsList)) {
+			// <Transaction version="1.0.0" service="WFS">
+			//     <InsertNs0 typeName="TEST_PERMS">
+			//         <ID>41</ID>
+			//         <ADM_ADMIN_LEVEL>3</ADM_ADMIN_LEVEL>
+			//     </InsertNs0>
+			// </Transaction>
+			$transXml = @simplexml_load_string($convertedTransaction);
+			foreach ($transXml->children() as $funcXml) {
+				$funcName = substr($funcXml->getName(), 0, 6);// Insert... , Update... , Delete...
+				if (empty($funcXml['typeName'][0])) throw new Api_WfsException("Missing typeName for function '{$funcName}'", __LINE__, null, 'MissingTypeName', 'request');
+				$typeName = $funcXml['typeName'][0];
+				$acl = $this->getAclFromTypeName("p5_default_db:{$typeName}");
+				$primaryKey = $acl->getPrimaryKeyField();
+				$pkObject = null;
+				foreach ($funcXml->children() as $fieldXml) {
+					if ($primaryKey == $fieldXml->getName()) $pkObject = $fieldXml[0];
+				}
+				if ('Insert' == $funcName && $pkObject) $funcName = 'Update';
+
+				if ('Update' == $funcName) {// check perm W - skip $primaryKey
+					if (!$pkObject) throw new Api_WfsException("Missing primary key ({$primaryKey}) for action Update", __LINE__, null, 'MissingPrimaryKey', 'request');
+					$toUpdateFields = array();
+					foreach ($funcXml->children() as $fieldXml) {
+						if ($primaryKey == $fieldXml->getName()) continue;// skip primary key
+						$toUpdateFields[] = $fieldXml->getName();
+					}
+					if (empty($toUpdateFields)) throw new Api_WfsException("Missing fields to update", __LINE__, null, 'MissingFieldToUpdate', 'request');
+					$oldObject = $acl->getItem($pkObject);
+					if (!$oldObject) throw new Api_WfsException("Object '{$typeName}.{$pkObject}' not exists", __LINE__, null, 'ObjectNotExists', 'request');
+					if (!$acl->canWriteRecord($oldObject) && !$acl->hasPermSuperWrite()) {
+						throw new Api_WfsException("Access Denied to Update object '{$typeName}.{$pkObject}'", __LINE__, null, 'MissingObjectPermUpdate', 'request');
+					}
+					foreach ($toUpdateFields as $fieldName) {
+						$aclIdFld = $acl->getFieldIdByName($fieldName);
+						if (!$acl->isAllowed($aclIdFld, 'W', $oldObject)) {
+							throw new Api_WfsException("Access Denied to Update field '{$fieldName}' in object '{$typeName}.{$pkObject}'", __LINE__, null, 'MissingFieldPermWrite', 'request');
+						}
+					}
+				} else if ('Insert' == $funcName) {// check perm C
+					foreach ($funcXml->children() as $fieldXml) {
+						$aclIdFld = $acl->getFieldIdByName($fieldXml->getName());
+						if (!$acl->isAllowed($aclIdFld, 'C')) {
+							throw new Api_WfsException("Access Denied to Create field '{$fieldName}' in object '{$typeName}.{$pkObject}'", __LINE__, null, 'MissingFieldPermCreate', 'request');
+						}
+					}
+				} else {
+					// TODO: Delete, ... ?
+				}
+			}
 			throw new Exception("Parse Request xml error #" . __LINE__ . ": schema validation failed");
 		}