feat: use queue to update contacts with carddav (#5575)

This commit is contained in:
Alexis Saettler
2021-10-08 22:51:47 +02:00
committed by GitHub
parent dd7970ca51
commit 0e989fec35
4 changed files with 69 additions and 44 deletions
@@ -3,11 +3,11 @@
namespace App\Http\Controllers\DAV\Backend\CardDAV;
use Sabre\DAV;
use Illuminate\Support\Arr;
use App\Jobs\Dav\UpdateVCard;
use App\Models\Contact\Contact;
use App\Models\Account\AddressBook;
use App\Services\VCard\ExportVCard;
use App\Services\VCard\ImportVCard;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Log;
use Sabre\DAV\Server as SabreServer;
use Sabre\CardDAV\Backend\SyncSupport;
@@ -19,6 +19,7 @@ use App\Services\Contact\Contact\SetMeContact;
use App\Http\Controllers\DAV\Backend\IDAVBackend;
use App\Http\Controllers\DAV\Backend\SyncDAVBackend;
use App\Http\Controllers\DAV\DAVACL\PrincipalBackend;
use App\Services\DavClient\Utils\Model\ContactUpdateDto;
class CardDAVBackend extends AbstractBackend implements SyncSupport, IDAVBackend
{
@@ -185,13 +186,7 @@ class CardDAVBackend extends AbstractBackend implements SyncSupport, IDAVBackend
$carddata = $contact->vcard;
try {
if (empty($carddata)) {
$vcard = app(ExportVCard::class)
->execute([
'account_id' => $this->user->account_id,
'contact_id' => $contact->id,
]);
$carddata = $vcard->serialize();
$carddata = $this->refreshObject($contact);
}
return [
@@ -369,36 +364,13 @@ class CardDAVBackend extends AbstractBackend implements SyncSupport, IDAVBackend
*/
public function updateCard($addressBookId, $cardUri, $cardData): ?string
{
$contact_id = null;
if ($cardUri) {
$contact = $this->getObject($addressBookId, $cardUri);
$dto = new ContactUpdateDto($cardUri, '"'.md5($cardData).'"', $cardData);
if ($contact) {
$contact_id = $contact->id;
}
}
$job = new UpdateVCard($this->user, $addressBookId, $dto);
try {
$result = app(ImportVCard::class)
->execute([
'account_id' => $this->user->account_id,
'user_id' => $this->user->id,
'contact_id' => $contact_id,
'entry' => $cardData,
'behaviour' => ImportVCard::BEHAVIOUR_REPLACE,
'addressBookName' => $addressBookId == $this->backendUri() ? null : $addressBookId,
]);
if (! Arr::has($result, 'error')) {
$contact = Contact::where('account_id', $this->user->account_id)
->find($result['contact_id']);
return '"'.md5($contact->vcard).'"';
}
} catch (\Exception $e) {
Log::debug(__CLASS__.' updateCard: '.(string) $e, [$e]);
throw $e;
}
Bus::batch([$job])
->allowFailures()
->dispatch();
return null;
}
+58 -5
View File
@@ -3,8 +3,11 @@
namespace App\Jobs\Dav;
use App\Models\User\User;
use Illuminate\Support\Arr;
use Illuminate\Bus\Batchable;
use Illuminate\Bus\Queueable;
use App\Models\Contact\Contact;
use App\Services\VCard\ImportVCard;
use Illuminate\Support\Facades\Log;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
@@ -57,13 +60,63 @@ class UpdateVCard implements ShouldQueue
return;
}
Log::info(__CLASS__.' update '.$this->contact->uri);
$backend = app(CardDAVBackend::class)->init($this->user);
$newtag = $backend->updateCard($this->addressBookName, $this->contact->uri, $this->contact->card);
$newtag = $this->updateCard($this->addressBookName, $this->contact->uri, $this->contact->card);
if ($newtag !== $this->contact->etag) {
Log::warning(__CLASS__.' wrong etag when updating contact. Expected '.$this->contact->etag.', get '.$newtag);
Log::warning(__CLASS__.' wrong etag when updating contact. Expected '.$this->contact->etag.', get '.$newtag, [
'contacturl' => $this->contact->uri,
'carddata' => $this->contact->card,
]);
}
}
/**
* Update the contact with the carddata.
*
* @param mixed $addressBookId
* @param string $cardUri
* @param string $cardData
* @return string|null
*/
private function updateCard($addressBookId, $cardUri, $cardData): ?string
{
$backend = app(CardDAVBackend::class)->init($this->user);
$contact_id = null;
if ($cardUri) {
$contact = $backend->getObject($addressBookId, $cardUri);
if ($contact) {
$contact_id = $contact->id;
}
}
try {
$result = app(ImportVCard::class)
->execute([
'account_id' => $this->user->account_id,
'user_id' => $this->user->id,
'contact_id' => $contact_id,
'entry' => $cardData,
'behaviour' => ImportVCard::BEHAVIOUR_REPLACE,
'addressBookName' => $addressBookId === $backend->backendUri() ? null : $addressBookId,
]);
if (! Arr::has($result, 'error')) {
$contact = Contact::where('account_id', $this->user->account_id)
->find($result['contact_id']);
return '"'.md5($contact->vcard).'"';
}
} catch (\Exception $e) {
Log::debug(__CLASS__.' updateCard: '.(string) $e, [
$e,
'contacturl' => $cardUri,
'carddata' => $cardData,
]);
throw $e;
}
return null;
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ sonar.organization=monicahq
sonar.sources=app,bootstrap,config,database,public,resources,routes
sonar.exclusions=bootstrap/cache/*,public/vendor/**,resources/lang/**
sonar.tests=tests
sonar.coverage.exclusions=routes/*.php,config/*.php,bootstrap/**,resources/**/*.php,database/factories/**/*.php,database/migrations/*.php,public/*.php,resources/**/*.vue,resources/**/*.js
sonar.coverage.exclusions=routes/*.php,config/**/*.php,bootstrap/**,resources/**/*.php,database/**/*.php,public/*.php,resources/**/*.vue,resources/**/*.js
sonar.cpd.exclusions=routes/*.php,config/*.php,bootstrap/**,resources/**/*.php,database/**/*.php
# Encoding of the source code. Default is default system encoding
+1 -1
View File
@@ -331,7 +331,7 @@ class VCardContactTest extends ApiTestCase
$response->assertStatus(204);
$response->assertHeader('X-Sabre-Version');
$response->assertHeader('ETag');
//$response->assertHeader('ETag'); // etag no more sent
}
public function test_carddav_contacts_report_version4()