Skip to content

Commit

Permalink
fixup! feat(cardav): support result truncation for addressbook federa…
Browse files Browse the repository at this point in the history
…tion

Signed-off-by: Hamza Mahjoubi <[email protected]>
  • Loading branch information
hamza221 committed Jan 12, 2025
1 parent 1cb4891 commit e93752a
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 12 deletions.
17 changes: 14 additions & 3 deletions apps/dav/lib/CardDAV/CardDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
use OCA\DAV\Events\CardUpdatedEvent;
use OCP\AppFramework\Db\TTransactional;
use OCP\DB\Exception;
use Psr\Log\LoggerInterface;
use OCP\IConfig;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IDBConnection;
Expand Down Expand Up @@ -59,6 +61,8 @@ public function __construct(
private IUserManager $userManager,
private IEventDispatcher $dispatcher,
private Sharing\Backend $sharingBackend,
private LoggerInterface $logger,
private IConfig $config,
) {
}

Expand Down Expand Up @@ -851,6 +855,10 @@ public function deleteCard($addressBookId, $cardUri) {
* @return array
*/
public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, $limit = null) {
if($limit === null){
$limit = $this->config->getSystemValueInt('carddav_sync_request_limit',1);

}
// Current synctoken
return $this->atomic(function () use ($addressBookId, $syncToken, $syncLevel, $limit) {
$qb = $this->db->getQueryBuilder();
Expand All @@ -873,6 +881,7 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
'modified' => [],
'deleted' => [],
];
$this->logger->error('getChangesForAddressBook', ['syncToken' => $syncToken, 'currentToken' => $currentToken, 'limit' => $limit]);
if(str_starts_with($syncToken, "init_")) {
$syncValues = explode("_", $syncToken);
$lastID = $syncValues[1];
Expand Down Expand Up @@ -949,17 +958,19 @@ public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel,
if (is_int($limit) && $limit > 0) {
$qb->setMaxResults($limit);
$stmt = $qb->executeQuery();
$values = $stmt->fetchAll(\PDO::FETCH_KEY_PAIR);
$lastID = array_key_last($values);
$values = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$lastID = end($values)['id'];
if(count(array_values($values)) === $limit ){
$result['syncToken'] = 'init_'. $lastID.'_'.$currentToken;
$result['result_truncated'] = true;
}
}
else {
$stmt = $qb->executeQuery();
$values = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$this->logger->error('getChangesForAddressBook', ['values' => $values]);
}
$result['added'] = array_values($values);
$result['added'] =array_column($values, 'uri');

$stmt->closeCursor();
}
Expand Down
9 changes: 2 additions & 7 deletions apps/dav/lib/CardDAV/SyncService.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public function syncRemoteAddressBook(string $url, string $userName, string $add
$this->logger->error('Client exception:', ['app' => 'dav', 'exception' => $ex]);
throw $ex;
}
$this->logger->error('sync response',[$response]);

// 3. apply changes
// TODO: use multi-get for download
Expand Down Expand Up @@ -162,7 +163,7 @@ protected function requestSyncReport(string $url, string $userName, string $addr
'auth' => [$userName, $sharedSecret],
'body' => $this->buildSyncCollectionRequestBody($syncToken),
'headers' => ['Content-Type' => 'application/xml'],
'timeout' => $this->config->getSystemValueInt('carddav_sync_request_timeout', IClient::DEFAULT_REQUEST_TIMEOUT),
'timeout' => $this->config->getSystemValueInt('carddav_sync_request_timeout', IClient::DEFAULT_REQUEST_TIMEOUT)
];

$response = $client->request(
Expand Down Expand Up @@ -194,23 +195,17 @@ protected function download(string $url, string $userName, string $sharedSecret,
}

private function buildSyncCollectionRequestBody(?string $syncToken): string {

$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;
$root = $dom->createElementNS('DAV:', 'd:sync-collection');
$sync = $dom->createElement('d:sync-token', $syncToken ?? '');
$limit = $dom->createElement('d:limit');
$nresuts = $dom->createElement('d:nresults',$this->config->getSystemValueInt('carddav_sync_request_limit',IClient::DEFAULT_ADDRESSBOOK_INITIAL_SYNC_LIMIT));
$limit->appendChild($nresuts);
$prop = $dom->createElement('d:prop');
$cont = $dom->createElement('d:getcontenttype');
$etag = $dom->createElement('d:getetag');


$prop->appendChild($cont);
$prop->appendChild($etag);
$root->appendChild($sync);
$root->appendChild($limit);
$root->appendChild($prop);
$dom->appendChild($root);
return $dom->saveXML();
Expand Down
2 changes: 1 addition & 1 deletion apps/dav/lib/CardDAV/SystemAddressbook.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public function getChild($name): Card {
$obj['carddata'] = $carddata;
}
return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
}
}
public function getChanges($syncToken, $syncLevel, $limit = null) {

if (!$this->carddavBackend instanceof SyncSupport) {
Expand Down
6 changes: 6 additions & 0 deletions apps/dav/lib/RootCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ public function __construct() {
);

$contactsSharingBackend = \OC::$server->get(\OCA\DAV\CardDAV\Sharing\Backend::class);
$logger = \OC::$server->get(\Psr\Log\LoggerInterface::class);
$config = \OC::$server->get(IConfig::class);

$pluginManager = new PluginManager(\OC::$server, \OC::$server->query(IAppManager::class));
$usersCardDavBackend = new CardDavBackend(
Expand All @@ -132,6 +134,8 @@ public function __construct() {
$userManager,
$dispatcher,
$contactsSharingBackend,
$logger,
$config
);
$usersAddressBookRoot = new AddressBookRoot($userPrincipalBackend, $usersCardDavBackend, $pluginManager, $userSession->getUser(), $groupManager, 'principals/users');
$usersAddressBookRoot->disableListing = $disableListing;
Expand All @@ -142,6 +146,8 @@ public function __construct() {
$userManager,
$dispatcher,
$contactsSharingBackend,
$logger,
$config
);
$systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, $pluginManager, $userSession->getUser(), $groupManager, 'principals/system');
$systemAddressBookRoot->disableListing = $disableListing;
Expand Down
3 changes: 2 additions & 1 deletion apps/dav/lib/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ public function __construct(

$this->server->addPlugin(new ExceptionLoggerPlugin('webdav', $logger));
$this->server->addPlugin(new LockPlugin());
$this->server->addPlugin(new \Sabre\DAV\Sync\Plugin());
$logger = \OC::$server->get(LoggerInterface::class);
$this->server->addPlugin(new \Sabre\DAV\Sync\Plugin($logger));

Check failure on line 164 in apps/dav/lib/Server.php

View workflow job for this annotation

GitHub Actions / static-code-analysis

TooManyArguments

apps/dav/lib/Server.php:164:28: TooManyArguments: Class Sabre\DAV\Sync\Plugin has no __construct, but arguments were passed (see https://psalm.dev/026)

// acl
$acl = new DavAclPlugin();
Expand Down

0 comments on commit e93752a

Please sign in to comment.