[Pkg-owncloud-commits] [php-sabredav] 256/275: Support for the test attribute in principal searches. Added findByUri to principal backends.
David Prévot
taffit at moszumanska.debian.org
Thu Sep 25 14:56:16 UTC 2014
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository php-sabredav.
commit a1dad6a6bea4e9296979be5101f838833b5c122a
Author: Evert Pot <evert at rooftopsolutions.nl>
Date: Tue Sep 23 18:37:55 2014 +0100
Support for the test attribute in principal searches.
Added findByUri to principal backends.
---
lib/DAVACL/AbstractPrincipalCollection.php | 31 ++++-
lib/DAVACL/IPrincipalCollection.php | 26 +++-
lib/DAVACL/Plugin.php | 45 +++++--
lib/DAVACL/PrincipalBackend/AbstractBackend.php | 34 +++++
lib/DAVACL/PrincipalBackend/BackendInterface.php | 29 ++++-
lib/DAVACL/PrincipalBackend/PDO.php | 11 +-
tests/Sabre/DAVACL/PrincipalBackend/Mock.php | 9 +-
tests/Sabre/DAVACL/PrincipalPropertySearchTest.php | 145 +++++++++++++++++++++
8 files changed, 298 insertions(+), 32 deletions(-)
diff --git a/lib/DAVACL/AbstractPrincipalCollection.php b/lib/DAVACL/AbstractPrincipalCollection.php
index 6b58e9d..366b75e 100644
--- a/lib/DAVACL/AbstractPrincipalCollection.php
+++ b/lib/DAVACL/AbstractPrincipalCollection.php
@@ -133,8 +133,9 @@ abstract class AbstractPrincipalCollection extends DAV\Collection implements IPr
* keys in searchProperties are the WebDAV property names, while the values
* are the property values to search on.
*
- * If multiple properties are being searched on, the search should be
- * AND'ed.
+ * By default, if multiple properties are submitted to this method, the
+ * various properties should be combined with 'AND'. If $test is set to
+ * 'anyof', it should be combined using 'OR'.
*
* This method should simply return a list of 'child names', which may be
* used to call $this->getChild in the future.
@@ -142,9 +143,9 @@ abstract class AbstractPrincipalCollection extends DAV\Collection implements IPr
* @param array $searchProperties
* @return array
*/
- function searchPrincipals(array $searchProperties) {
+ function searchPrincipals(array $searchProperties, $test = 'allof') {
- $result = $this->principalBackend->searchPrincipals($this->principalPrefix, $searchProperties);
+ $result = $this->principalBackend->searchPrincipals($this->principalPrefix, $searchProperties, $test);
$r = [];
foreach($result as $row) {
@@ -155,4 +156,26 @@ abstract class AbstractPrincipalCollection extends DAV\Collection implements IPr
}
+ /**
+ * Finds a principal by its URI.
+ *
+ * This method may receive any type of uri, but mailto: addresses will be
+ * the most common.
+ *
+ * Implementation of this API is optional. It is currently used by the
+ * CalDAV system to find principals based on their email addresses. If this
+ * API is not implemented, some features may not work correctly.
+ *
+ * This method must return a relative principal path, or null, if the
+ * principal was not found or you refuse to find it.
+ *
+ * @param string $uri
+ * @return string
+ */
+ function findByUri($uri) {
+
+ return $this->principalBackend->findByUri($uri);
+
+ }
+
}
diff --git a/lib/DAVACL/IPrincipalCollection.php b/lib/DAVACL/IPrincipalCollection.php
index d09c9d6..238d8ca 100644
--- a/lib/DAVACL/IPrincipalCollection.php
+++ b/lib/DAVACL/IPrincipalCollection.php
@@ -28,15 +28,35 @@ interface IPrincipalCollection extends DAV\ICollection {
* keys in searchProperties are the WebDAV property names, while the values
* are the property values to search on.
*
- * If multiple properties are being searched on, the search should be
- * AND'ed.
+ * By default, if multiple properties are submitted to this method, the
+ * various properties should be combined with 'AND'. If $test is set to
+ * 'anyof', it should be combined using 'OR'.
*
* This method should simply return a list of 'child names', which may be
* used to call $this->getChild in the future.
*
* @param array $searchProperties
+ * @param string $test
* @return array
*/
- function searchPrincipals(array $searchProperties);
+ function searchPrincipals(array $searchProperties, $test = 'allof');
+
+ /**
+ * Finds a principal by its URI.
+ *
+ * This method may receive any type of uri, but mailto: addresses will be
+ * the most common.
+ *
+ * Implementation of this API is optional. It is currently used by the
+ * CalDAV system to find principals based on their email addresses. If this
+ * API is not implemented, some features may not work correctly.
+ *
+ * This method must return a relative principal path, or null, if the
+ * principal was not found or you refuse to find it.
+ *
+ * @param string $uri
+ * @return string
+ */
+ function findByUri($uri);
}
diff --git a/lib/DAVACL/Plugin.php b/lib/DAVACL/Plugin.php
index 7fe452e..a72ac4d 100644
--- a/lib/DAVACL/Plugin.php
+++ b/lib/DAVACL/Plugin.php
@@ -596,20 +596,27 @@ class Plugin extends DAV\ServerPlugin {
*
* This method returns false if the principal could not be found.
*
- * @return string|bool
+ * @return string|null
*/
function getPrincipalByEmail($email) {
- $result = $this->principalSearch(
- ['{http://sabredav.org/ns}email-address' => $email],
- ['{DAV:}principal-URL']
- );
+ $result = null;
+ $uris = $this->principalCollectionSet;
+ foreach($uris as $uri) {
- if (!count($result)) {
- return false;
- }
+ $principalCollection = $this->server->tree->getNodeForPath($uri);
+ if (!$principalCollection instanceof IPrincipalCollection) {
+ // Not a principal collection, we're simply going to ignore
+ // this.
+ continue;
+ }
+
+ $result = $principalCollection->findByUri('mailto:' . $email);
+ if ($result) {
+ return $result;
+ }
- return $result[0][200]['{DAV:}principal-URL'];
+ }
}
@@ -630,12 +637,14 @@ class Plugin extends DAV\ServerPlugin {
* @param string $collectionUri The principal collection to search on.
* If this is ommitted, the standard
* principal collection-set will be used.
+ * @param string $test "allof" to use AND to search the
+ * properties. 'anyof' for OR.
* @return array This method returns an array structure similar to
* Sabre\DAV\Server::getPropertiesForPath. Returned
* properties are index by a HTTP status code.
*
*/
- function principalSearch(array $searchProperties, array $requestedProperties, $collectionUri = null) {
+ function principalSearch(array $searchProperties, array $requestedProperties, $collectionUri = null, $test = 'allof') {
if (!is_null($collectionUri)) {
$uris = [$collectionUri];
@@ -653,7 +662,7 @@ class Plugin extends DAV\ServerPlugin {
continue;
}
- $results = $principalCollection->searchPrincipals($searchProperties);
+ $results = $principalCollection->searchPrincipals($searchProperties, $test);
foreach($results as $result) {
$lookupResults[] = rtrim($uri,'/') . '/' . $result;
}
@@ -1299,13 +1308,18 @@ class Plugin extends DAV\ServerPlugin {
*/
protected function principalPropertySearchReport(\DOMDocument $dom) {
- list($searchProperties, $requestedProperties, $applyToPrincipalCollectionSet) = $this->parsePrincipalPropertySearchReportRequest($dom);
+ list(
+ $searchProperties,
+ $requestedProperties,
+ $applyToPrincipalCollectionSet,
+ $test
+ ) = $this->parsePrincipalPropertySearchReportRequest($dom);
$uri = null;
if (!$applyToPrincipalCollectionSet) {
$uri = $this->server->getRequestUri();
}
- $result = $this->principalSearch($searchProperties, $requestedProperties, $uri);
+ $result = $this->principalSearch($searchProperties, $requestedProperties, $uri, $test);
$prefer = $this->server->getHTTPPRefer();
@@ -1340,6 +1354,8 @@ class Plugin extends DAV\ServerPlugin {
$applyToPrincipalCollectionSet = false;
+ $test = $dom->firstChild->getAttribute('test') === 'anyof' ? 'anyof' : 'allof';
+
// Parsing the search request
foreach($dom->firstChild->childNodes as $searchNode) {
@@ -1382,7 +1398,8 @@ class Plugin extends DAV\ServerPlugin {
return [
$searchProperties,
array_keys(DAV\XMLUtil::parseProperties($dom->firstChild)),
- $applyToPrincipalCollectionSet
+ $applyToPrincipalCollectionSet,
+ $test
];
}
diff --git a/lib/DAVACL/PrincipalBackend/AbstractBackend.php b/lib/DAVACL/PrincipalBackend/AbstractBackend.php
index 984f9ad..f431653 100644
--- a/lib/DAVACL/PrincipalBackend/AbstractBackend.php
+++ b/lib/DAVACL/PrincipalBackend/AbstractBackend.php
@@ -15,4 +15,38 @@ namespace Sabre\DAVACL\PrincipalBackend;
*/
abstract class AbstractBackend implements BackendInterface {
+ /**
+ * Finds a principal by its URI.
+ *
+ * This method may receive any type of uri, but mailto: addresses will be
+ * the most common.
+ *
+ * Implementation of this API is optional. It is currently used by the
+ * CalDAV system to find principals based on their email addresses. If this
+ * API is not implemented, some features may not work correctly.
+ *
+ * This method must return a relative principal path, or null, if the
+ * principal was not found or you refuse to find it.
+ *
+ * @param string $uri
+ * @return string
+ */
+ function findByUri($uri) {
+
+ // Note that the default implementation here is a bit slow and could
+ // likely be optimized.
+ if (substr($uri,0,7)!=='mailto:') {
+ return;
+ }
+ $result = $this->searchPrincipals(
+ '',
+ ['{http://sabredav.org/ns}email-address' => substr($uri,7)]
+ );
+
+ if ($result) {
+ return $result[0];
+ }
+
+ }
+
}
diff --git a/lib/DAVACL/PrincipalBackend/BackendInterface.php b/lib/DAVACL/PrincipalBackend/BackendInterface.php
index 84636d7..6748228 100644
--- a/lib/DAVACL/PrincipalBackend/BackendInterface.php
+++ b/lib/DAVACL/PrincipalBackend/BackendInterface.php
@@ -66,15 +66,15 @@ interface BackendInterface {
* properties.
*
* This search is specifically used by RFC3744's principal-property-search
- * REPORT. You should at least allow searching on
- * http://sabredav.org/ns}email-address.
+ * REPORT.
*
* The actual search should be a unicode-non-case-sensitive search. The
* keys in searchProperties are the WebDAV property names, while the values
* are the property values to search on.
*
- * If multiple properties are being searched on, the search should be
- * AND'ed.
+ * By default, if multiple properties are submitted to this method, the
+ * various properties should be combined with 'AND'. If $test is set to
+ * 'anyof', it should be combined using 'OR'.
*
* This method should simply return an array with full principal uri's.
*
@@ -87,9 +87,28 @@ interface BackendInterface {
*
* @param string $prefixPath
* @param array $searchProperties
+ * @param string $test
* @return array
*/
- function searchPrincipals($prefixPath, array $searchProperties);
+ function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof');
+
+ /**
+ * Finds a principal by its URI.
+ *
+ * This method may receive any type of uri, but mailto: addresses will be
+ * the most common.
+ *
+ * Implementation of this API is optional. It is currently used by the
+ * CalDAV system to find principals based on their email addresses. If this
+ * API is not implemented, some features may not work correctly.
+ *
+ * This method must return a relative principal path, or null, if the
+ * principal was not found or you refuse to find it.
+ *
+ * @param string $uri
+ * @return string
+ */
+ function findByUri($uri);
/**
* Returns the list of members for a group-principal
diff --git a/lib/DAVACL/PrincipalBackend/PDO.php b/lib/DAVACL/PrincipalBackend/PDO.php
index 1ca49fc..61598a6 100644
--- a/lib/DAVACL/PrincipalBackend/PDO.php
+++ b/lib/DAVACL/PrincipalBackend/PDO.php
@@ -232,15 +232,15 @@ class PDO extends AbstractBackend {
* properties.
*
* This search is specifically used by RFC3744's principal-property-search
- * REPORT. You should at least allow searching on
- * http://sabredav.org/ns}email-address.
+ * REPORT.
*
* The actual search should be a unicode-non-case-sensitive search. The
* keys in searchProperties are the WebDAV property names, while the values
* are the property values to search on.
*
- * If multiple properties are being searched on, the search should be
- * AND'ed.
+ * By default, if multiple properties are submitted to this method, the
+ * various properties should be combined with 'AND'. If $test is set to
+ * 'anyof', it should be combined using 'OR'.
*
* This method should simply return an array with full principal uri's.
*
@@ -253,9 +253,10 @@ class PDO extends AbstractBackend {
*
* @param string $prefixPath
* @param array $searchProperties
+ * @param string $test
* @return array
*/
- function searchPrincipals($prefixPath, array $searchProperties) {
+ function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
$query = 'SELECT uri FROM ' . $this->tableName . ' WHERE 1=1 ';
$values = [];
diff --git a/tests/Sabre/DAVACL/PrincipalBackend/Mock.php b/tests/Sabre/DAVACL/PrincipalBackend/Mock.php
index 1ce97c8..d58fe12 100644
--- a/tests/Sabre/DAVACL/PrincipalBackend/Mock.php
+++ b/tests/Sabre/DAVACL/PrincipalBackend/Mock.php
@@ -61,7 +61,7 @@ class Mock extends AbstractBackend {
}
- function searchPrincipals($prefixPath, array $searchProperties) {
+ function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
$matches = array();
foreach($this->getPrincipalsByPrefix($prefixPath) as $principal) {
@@ -75,6 +75,13 @@ class Mock extends AbstractBackend {
continue 2;
}
+ // We have a match for this searchProperty!
+ if ($test === 'allof') {
+ continue;
+ } else {
+ break;
+ }
+
}
$matches[] = $principal['uri'];
diff --git a/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php b/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php
index 39311ef..d01ee56 100644
--- a/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php
+++ b/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php
@@ -176,6 +176,151 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
}
}
+
+ function testAND() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal-property-search xmlns:d="DAV:">
+ <d:apply-to-principal-collection-set />
+ <d:property-search>
+ <d:prop>
+ <d:displayname />
+ </d:prop>
+ <d:match>user</d:match>
+ </d:property-search>
+ <d:property-search>
+ <d:prop>
+ <d:foo />
+ </d:prop>
+ <d:match>bar</d:match>
+ </d:property-search>
+ <d:prop>
+ <d:displayname />
+ <d:getcontentlength />
+ </d:prop>
+</d:principal-property-search>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/',
+ );
+
+ $request = HTTP\Sapi::createFromServerArray($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals(207, $server->httpResponse->status, $server->httpResponse->body);
+ $this->assertEquals(array(
+ 'X-Sabre-Version' => DAV\Version::VERSION,
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ 'Vary' => 'Brief,Prefer',
+ ), $server->httpResponse->getHeaders());
+
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response' => 0,
+ '/d:multistatus/d:response/d:href' => 0,
+ '/d:multistatus/d:response/d:propstat' => 0,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 0,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 0,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 0,
+ '/d:multistatus/d:response/d:propstat/d:status' => 0,
+ );
+
+ $xml = simplexml_load_string($server->httpResponse->body);
+ $xml->registerXPathNamespace('d','DAV:');
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+
+ $count = 1;
+ if (!is_int($v1)) $count = $v2;
+
+ $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+
+ }
+
+ }
+ function testOR() {
+
+ $xml = '<?xml version="1.0"?>
+<d:principal-property-search xmlns:d="DAV:" test="anyof">
+ <d:apply-to-principal-collection-set />
+ <d:property-search>
+ <d:prop>
+ <d:displayname />
+ </d:prop>
+ <d:match>user</d:match>
+ </d:property-search>
+ <d:property-search>
+ <d:prop>
+ <d:foo />
+ </d:prop>
+ <d:match>bar</d:match>
+ </d:property-search>
+ <d:prop>
+ <d:displayname />
+ <d:getcontentlength />
+ </d:prop>
+</d:principal-property-search>';
+
+ $serverVars = array(
+ 'REQUEST_METHOD' => 'REPORT',
+ 'HTTP_DEPTH' => '0',
+ 'REQUEST_URI' => '/',
+ );
+
+ $request = HTTP\Sapi::createFromServerArray($serverVars);
+ $request->setBody($xml);
+
+ $server = $this->getServer();
+ $server->httpRequest = $request;
+
+ $server->exec();
+
+ $this->assertEquals(207, $server->httpResponse->status, $server->httpResponse->body);
+ $this->assertEquals(array(
+ 'X-Sabre-Version' => DAV\Version::VERSION,
+ 'Content-Type' => 'application/xml; charset=utf-8',
+ 'Vary' => 'Brief,Prefer',
+ ), $server->httpResponse->getHeaders());
+
+
+ $check = array(
+ '/d:multistatus',
+ '/d:multistatus/d:response' => 2,
+ '/d:multistatus/d:response/d:href' => 2,
+ '/d:multistatus/d:response/d:propstat' => 4,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 4,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 2,
+ '/d:multistatus/d:response/d:propstat/d:status' => 4,
+ );
+
+ $xml = simplexml_load_string($server->httpResponse->body);
+ $xml->registerXPathNamespace('d','DAV:');
+ foreach($check as $v1=>$v2) {
+
+ $xpath = is_int($v1)?$v2:$v1;
+
+ $result = $xml->xpath($xpath);
+
+ $count = 1;
+ if (!is_int($v1)) $count = $v2;
+
+ $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+
+ }
+
+ }
function testWrongUri() {
$xml = '<?xml version="1.0"?>
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/php-sabredav.git
More information about the Pkg-owncloud-commits
mailing list