summaryrefslogtreecommitdiff
path: root/lib/Kolab/CardDAV/Plugin.php
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2014-03-12 11:13:27 (GMT)
committerThomas Bruederli <bruederli@kolabsys.com>2014-03-13 09:18:42 (GMT)
commit3fe616421a8d7340b4dd29ce56dafec4733d4d3c (patch)
treece37ebf1c32e4a716b205d52b4867f590fdb5638 /lib/Kolab/CardDAV/Plugin.php
parent12e71c361fce1e132d35d29d2001f69c34be5e3e (diff)
downloadiRony-3fe616421a8d7340b4dd29ce56dafec4733d4d3c.tar.gz
Implement the CardDAV Directory Gateway Extension for Apple clients (and SOGo connector).
This exposes an LDAP-based address book inside the principals address book collection. According to the spec [1], this should be used for querying only. Listing, however, can be enabled by setting 'searchonly' => false in config. CARDDAV:addressbook-query requests will be translated into LDAP filters and post-processed by SabreDAV internals. [1] http://tools.ietf.org/html/draft-daboo-carddav-directory-gateway-02
Diffstat (limited to 'lib/Kolab/CardDAV/Plugin.php')
-rw-r--r--lib/Kolab/CardDAV/Plugin.php76
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/Kolab/CardDAV/Plugin.php b/lib/Kolab/CardDAV/Plugin.php
index 2abf0a8..1456e78 100644
--- a/lib/Kolab/CardDAV/Plugin.php
+++ b/lib/Kolab/CardDAV/Plugin.php
@@ -24,6 +24,7 @@
namespace Kolab\CardDAV;
use Sabre\DAV;
+use Sabre\DAVACL;
use Sabre\CardDAV;
use Sabre\VObject;
@@ -55,6 +56,25 @@ class Plugin extends CardDAV\Plugin
}
/**
+ * Adds all CardDAV-specific properties
+ *
+ * @param string $path
+ * @param DAV\INode $node
+ * @param array $requestedProperties
+ * @param array $returnedProperties
+ * @return void
+ */
+ public function beforeGetProperties($path, DAV\INode $node, array &$requestedProperties, array &$returnedProperties)
+ {
+ // publish global ldap address book for this principal
+ if ($node instanceof DAVACL\IPrincipal && empty($this->directories) && \rcube::get_instance()->config->get('global_ldap_directory')) {
+ $this->directories[] = self::ADDRESSBOOK_ROOT . '/' . $node->getName() . '/' . LDAPDirectory::DIRECTORY_NAME;
+ }
+
+ parent::beforeGetProperties($path, $node, $requestedProperties, $returnedProperties);
+ }
+
+ /**
* Handler for beforeMethod events
*/
public function beforeMethod($method, $uri)
@@ -124,4 +144,60 @@ class Plugin extends CardDAV\Plugin
}
}
+ /**
+ * This function handles the addressbook-query REPORT
+ *
+ * This report is used by the client to filter an addressbook based on a
+ * complex query.
+ *
+ * @param \DOMNode $dom
+ * @return void
+ */
+ protected function addressbookQueryReport($dom)
+ {
+ $node = $this->server->tree->getNodeForPath(($uri = $this->server->getRequestUri()));
+ console(__METHOD__, $uri);
+
+ // fix some stupid mistakes in queries sent by the SOGo connector
+ $xpath = new \DOMXPath($dom);
+ $xpath->registerNameSpace('card', Plugin::NS_CARDDAV);
+
+ $filters = $xpath->query('/card:addressbook-query/card:filter');
+ if ($filters->length === 1) {
+ $filter = $filters->item(0);
+ $propFilters = $xpath->query('card:prop-filter', $filter);
+ for ($ii=0; $ii < $propFilters->length; $ii++) {
+ $propFilter = $propFilters->item($ii);
+ $name = $propFilter->getAttribute('name');
+
+ // attribute 'mail' => EMAIL
+ if ($name == 'mail') {
+ $propFilter->setAttribute('name', 'EMAIL');
+ }
+
+ $textMatches = $xpath->query('card:text-match', $propFilter);
+ for ($jj=0; $jj < $textMatches->length; $jj++) {
+ $textMatch = $textMatches->item($jj);
+ $collation = $textMatch->getAttribute('collation');
+
+ // 'i;unicasemap' is a non-standard collation
+ if ($collation == 'i;unicasemap') {
+ $textMatch->setAttribute('collation', 'i;unicode-casemap');
+ }
+ }
+ }
+ }
+
+ // query on LDAP node: pass along filter query
+ if ($node instanceof LDAPDirectory) {
+ $query = new CardDAV\AddressBookQueryParser($dom);
+ $query->parse();
+
+ // set query and ...
+ $node->setAddressbookQuery($query);
+ }
+
+ // ... proceed with default action
+ parent::addressbookQueryReport($dom);
+ }
} \ No newline at end of file