aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Steinmetz <richard@steinmetz.cloud>2024-05-20 13:58:56 +0200
committerRichard Steinmetz <richard@steinmetz.cloud>2024-05-20 14:00:21 +0200
commit21a5dc8d1fbe7ef5d7c1ba5f9cc66b3ac78d5c20 (patch)
tree03923d9b44d0a90481c2f4beba2792481ebb1895
parent54afea4b01385106a241a5161b3894e669716107 (diff)
downloadnextcloud-server-fix/dav/image-export-plugin-fallback.tar.gz
nextcloud-server-fix/dav/image-export-plugin-fallback.zip
fix(dav): fall back to generated avatar in image export pluginfix/dav/image-export-plugin-fallback
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
-rw-r--r--apps/dav/appinfo/v1/carddav.php12
-rw-r--r--apps/dav/lib/CardDAV/ImageExportPlugin.php31
-rw-r--r--apps/dav/lib/Server.php10
-rw-r--r--apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php6
4 files changed, 47 insertions, 12 deletions
diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php
index 70e5de1b481..5c6d6906fe0 100644
--- a/apps/dav/appinfo/v1/carddav.php
+++ b/apps/dav/appinfo/v1/carddav.php
@@ -39,6 +39,7 @@ use OCA\DAV\Connector\Sabre\MaintenancePlugin;
use OCA\DAV\Connector\Sabre\Principal;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
+use OCP\IAvatarManager;
use Psr\Log\LoggerInterface;
use Sabre\CardDAV\Plugin;
@@ -104,10 +105,13 @@ if ($debugging) {
$server->addPlugin(new \Sabre\DAV\Sync\Plugin());
$server->addPlugin(new \Sabre\CardDAV\VCFExportPlugin());
-$server->addPlugin(new \OCA\DAV\CardDAV\ImageExportPlugin(new \OCA\DAV\CardDAV\PhotoCache(
- \OC::$server->getAppDataDir('dav-photocache'),
- \OC::$server->get(LoggerInterface::class)
-)));
+$server->addPlugin(new \OCA\DAV\CardDAV\ImageExportPlugin(
+ new \OCA\DAV\CardDAV\PhotoCache(
+ \OC::$server->getAppDataDir('dav-photocache'),
+ \OC::$server->get(LoggerInterface::class)
+ ),
+ \OC::$server->get(IAvatarManager::class),
+));
$server->addPlugin(new ExceptionLoggerPlugin('carddav', \OC::$server->get(LoggerInterface::class)));
// And off we go!
diff --git a/apps/dav/lib/CardDAV/ImageExportPlugin.php b/apps/dav/lib/CardDAV/ImageExportPlugin.php
index 3ebc91e5533..e079a54de4a 100644
--- a/apps/dav/lib/CardDAV/ImageExportPlugin.php
+++ b/apps/dav/lib/CardDAV/ImageExportPlugin.php
@@ -25,11 +25,13 @@
namespace OCA\DAV\CardDAV;
use OCP\Files\NotFoundException;
+use OCP\IAvatarManager;
use Sabre\CardDAV\Card;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
+use Sabre\VObject\Reader;
class ImageExportPlugin extends ServerPlugin {
@@ -38,13 +40,14 @@ class ImageExportPlugin extends ServerPlugin {
/** @var PhotoCache */
private $cache;
+ private IAvatarManager $avatarManager;
+
/**
* ImageExportPlugin constructor.
- *
- * @param PhotoCache $cache
*/
- public function __construct(PhotoCache $cache) {
+ public function __construct(PhotoCache $cache, IAvatarManager $avatarManager) {
$this->cache = $cache;
+ $this->avatarManager = $avatarManager;
}
/**
@@ -99,6 +102,7 @@ class ImageExportPlugin extends ServerPlugin {
$response->setHeader('Cache-Control', 'private, max-age=3600, must-revalidate');
$response->setHeader('Etag', $node->getETag());
+ // Try to use embedded avatar image
try {
$file = $this->cache->get($addressbook->getResourceId(), $node->getName(), $size, $node);
$response->setHeader('Content-Type', $file->getMimeType());
@@ -107,10 +111,29 @@ class ImageExportPlugin extends ServerPlugin {
$response->setStatus(200);
$response->setBody($file->getContent());
+ return false;
} catch (NotFoundException $e) {
- $response->setStatus(404);
+ // Fall back to generated avatar
+ }
+
+ $name = '?';
+ $vObject = Reader::read($node->get());
+ if (isset($vObject->FN)) {
+ $name = $vObject->FN->getValue();
+ } elseif (isset($vObject->N)) {
+ [$lastName, $firstName] = $vObject->N->getParts();
+ $name = "$firstName $lastName";
}
+ $avatar = $this->avatarManager->getGuestAvatar($name);
+ $image = $avatar->get($size);
+
+ $response->setHeader('Content-Type', $image->mimeType());
+ $fileName = $node->getName() . '.' . PhotoCache::ALLOWED_CONTENT_TYPES[$image->mimeType()];
+ $response->setHeader('Content-Disposition', "attachment; filename=$fileName");
+ $response->setStatus(200);
+ $response->setBody($image->data());
+
return false;
}
}
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index 37d04ba8190..c166be5be46 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -80,6 +80,7 @@ use OCP\AppFramework\Http\Response;
use OCP\Diagnostics\IEventLogger;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\FilesMetadata\IFilesMetadataManager;
+use OCP\IAvatarManager;
use OCP\ICacheFactory;
use OCP\IRequest;
use OCP\Profiler\IProfiler;
@@ -204,9 +205,12 @@ class Server {
$this->server->addPlugin(new VCFExportPlugin());
$this->server->addPlugin(new MultiGetExportPlugin());
$this->server->addPlugin(new HasPhotoPlugin());
- $this->server->addPlugin(new ImageExportPlugin(new PhotoCache(
- \OC::$server->getAppDataDir('dav-photocache'),
- $logger)
+ $this->server->addPlugin(
+ new ImageExportPlugin(new PhotoCache(
+ \OC::$server->getAppDataDir('dav-photocache'),
+ $logger,
+ ),
+ \OC::$server->get(IAvatarManager::class),
));
}
diff --git a/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php b/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php
index 6f48927646e..d1b05c5d07e 100644
--- a/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php
+++ b/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php
@@ -30,6 +30,7 @@ use OCA\DAV\CardDAV\ImageExportPlugin;
use OCA\DAV\CardDAV\PhotoCache;
use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\IAvatarManager;
use Sabre\CardDAV\Card;
use Sabre\DAV\Node;
use Sabre\DAV\Server;
@@ -51,6 +52,8 @@ class ImageExportPluginTest extends TestCase {
private $tree;
/** @var PhotoCache|\PHPUnit\Framework\MockObject\MockObject */
private $cache;
+ /** @var IAvatarManager|\PHPUnit\Framework\MockObject\MockObject */
+ private $avatarManager;
protected function setUp(): void {
parent::setUp();
@@ -61,10 +64,11 @@ class ImageExportPluginTest extends TestCase {
$this->tree = $this->createMock(Tree::class);
$this->server->tree = $this->tree;
$this->cache = $this->createMock(PhotoCache::class);
+ $this->avatarManager = $this->createMock(IAvatarManager::class);
$this->plugin = $this->getMockBuilder(ImageExportPlugin::class)
->setMethods(['getPhoto'])
- ->setConstructorArgs([$this->cache])
+ ->setConstructorArgs([$this->cache, $this->avatarManager])
->getMock();
$this->plugin->initialize($this->server);
}