mirror of
https://github.com/nextcloud/richdocuments.git
synced 2025-12-17 21:12:14 +01:00
follow me slideshow: use wopi check file info for presentation leader
to communicate more securely who is leading the presentation, communicate the leader via check file info, currently we restrict file owner to be the presentation leader Signed-off-by: Pranam Lashkari <lpranam@collabora.com>
This commit is contained in:
parent
13a1fb6659
commit
1a034174d2
5 changed files with 50 additions and 8 deletions
|
|
@ -395,7 +395,8 @@ class DocumentController extends Controller {
|
|||
$file = $this->getFileForUser($fileId);
|
||||
|
||||
$this->session->set(self::SESSION_FILE_TARGET, [
|
||||
'fileId' => $file->getId()
|
||||
'fileId' => $file->getId(),
|
||||
'PresentationLeader' => $file->getFileInfo()->getOwner()->getUid()
|
||||
]);
|
||||
|
||||
$filePath = $file->getPath();
|
||||
|
|
@ -425,7 +426,7 @@ class DocumentController extends Controller {
|
|||
}
|
||||
|
||||
$isGuest = $guestName || !$this->userId;
|
||||
$wopi = $this->getToken($file, $share, null, $isGuest);
|
||||
$wopi = $this->getToken($file, $share, null, $isGuest, presentationLeader: $this->session->get(self::SESSION_FILE_TARGET)['PresentationLeader']);
|
||||
|
||||
$this->tokenManager->setGuestName($wopi, $guestName);
|
||||
|
||||
|
|
@ -520,7 +521,7 @@ class DocumentController extends Controller {
|
|||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
private function getToken(File $file, ?IShare $share = null, ?int $version = null, bool $isGuest = false): Wopi {
|
||||
private function getToken(File $file, ?IShare $share = null, ?int $version = null, bool $isGuest = false, ?string $presentationLeader = null): Wopi {
|
||||
// Pass through $version
|
||||
$templateFile = $this->templateManager->getTemplateSource($file->getId());
|
||||
if ($templateFile) {
|
||||
|
|
@ -540,7 +541,7 @@ class DocumentController extends Controller {
|
|||
}
|
||||
|
||||
|
||||
return $this->tokenManager->generateWopiToken($this->getWopiFileId($file->getId(), $version), $share?->getToken(), $this->userId);
|
||||
return $this->tokenManager->generateWopiToken($this->getWopiFileId($file->getId(), $version), $share?->getToken(), $this->userId, presentationLeader: $presentationLeader);
|
||||
}
|
||||
|
||||
private function getWopiFileId(int $fileId, ?int $version = null): string {
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ use OCP\Share\IShare;
|
|||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\ICache;
|
||||
|
||||
#[RestrictToWopiServer]
|
||||
class WopiController extends Controller {
|
||||
|
|
@ -96,6 +98,7 @@ class WopiController extends Controller {
|
|||
private SettingsService $settingsService,
|
||||
private CapabilitiesService $capabilitiesService,
|
||||
private Helper $helper,
|
||||
private ICacheFactory $cacheFactory,
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
}
|
||||
|
|
@ -149,6 +152,17 @@ class WopiController extends Controller {
|
|||
$userId = !$isPublic ? $wopi->getEditorUid() : $guestUserId;
|
||||
|
||||
|
||||
$cache = $this->cacheFactory->createLocal('richdocuments_wopi');
|
||||
$extraJson = $cache->get('wopi_extra_' . $wopi->getToken());
|
||||
if ($extraJson !== false && $extraJson !== '') {
|
||||
$decoded = json_decode($extraJson, true);
|
||||
if (is_array($decoded) && isset($decoded['PresentationLeader'])) {
|
||||
$wopi->setPresentationLeader($decoded['PresentationLeader']);
|
||||
}
|
||||
$cache->remove('wopi_extra_' . $wopi->getToken());
|
||||
}
|
||||
|
||||
|
||||
$response = [
|
||||
'BaseFileName' => $file->getName(),
|
||||
'Size' => $file->getSize(),
|
||||
|
|
@ -181,6 +195,7 @@ class WopiController extends Controller {
|
|||
'EnableRemoteAIContent' => $isTaskProcessingEnabled,
|
||||
'HasContentRange' => true,
|
||||
'ServerPrivateInfo' => [],
|
||||
'PresentationLeader' => $wopi->getPresentationLeader()
|
||||
];
|
||||
|
||||
if ($this->capabilitiesService->hasSettingIframeSupport()) {
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ class Wopi extends Entity implements \JsonSerializable {
|
|||
/** @var int */
|
||||
protected $tokenType = 0;
|
||||
|
||||
protected ?string $presentationLeader = null;
|
||||
|
||||
public function __construct() {
|
||||
$this->addType('ownerUid', Types::STRING);
|
||||
$this->addType('editorUid', Types::STRING);
|
||||
|
|
@ -139,6 +141,7 @@ class Wopi extends Entity implements \JsonSerializable {
|
|||
$this->addType('hideDownload', Types::BOOLEAN);
|
||||
$this->addType('direct', Types::BOOLEAN);
|
||||
$this->addType('tokenType', Types::INTEGER);
|
||||
$this->addType('presentationLeader', Types::STRING);
|
||||
}
|
||||
|
||||
public function hasTemplateId() {
|
||||
|
|
@ -168,6 +171,14 @@ class Wopi extends Entity implements \JsonSerializable {
|
|||
return (bool)$this->direct;
|
||||
}
|
||||
|
||||
public function setPresentationLeader(?string $val): void {
|
||||
$this->presentationLeader = $val;
|
||||
}
|
||||
|
||||
public function getPresentationLeader(): ?string {
|
||||
return $this->presentationLeader;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize() {
|
||||
$properties = get_object_vars($this);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
|
|||
use OCP\IDBConnection;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\ICache;
|
||||
|
||||
/** @template-extends QBMapper<Wopi> */
|
||||
class WopiMapper extends QBMapper {
|
||||
|
|
@ -23,6 +25,7 @@ class WopiMapper extends QBMapper {
|
|||
private LoggerInterface $logger,
|
||||
private ITimeFactory $timeFactory,
|
||||
private AppConfig $appConfig,
|
||||
private ICacheFactory $cacheFactory,
|
||||
) {
|
||||
parent::__construct($db, 'richdocuments_wopi', Wopi::class);
|
||||
}
|
||||
|
|
@ -38,7 +41,7 @@ class WopiMapper extends QBMapper {
|
|||
* @param int $templateDestination
|
||||
* @return Wopi
|
||||
*/
|
||||
public function generateFileToken($fileId, $owner, $editor, $version, $updatable, $serverHost, ?string $guestDisplayname = null, $hideDownload = false, $direct = false, $templateId = 0, $share = null) {
|
||||
public function generateFileToken($fileId, $owner, $editor, $version, $updatable, $serverHost, ?string $guestDisplayname = null, $hideDownload = false, $direct = false, $templateId = 0, $share = null, ?string $presentationLeader = null) {
|
||||
$token = $this->random->generate(32, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
|
||||
|
||||
$wopi = Wopi::fromParams([
|
||||
|
|
@ -57,9 +60,21 @@ class WopiMapper extends QBMapper {
|
|||
'remoteServer' => '',
|
||||
'remoteServerToken' => '',
|
||||
'share' => $share,
|
||||
'tokenType' => $guestDisplayname === null ? Wopi::TOKEN_TYPE_USER : Wopi::TOKEN_TYPE_GUEST
|
||||
'tokenType' => $guestDisplayname === null ? Wopi::TOKEN_TYPE_USER : Wopi::TOKEN_TYPE_GUEST,
|
||||
'presentationLeader' => $presentationLeader
|
||||
]);
|
||||
|
||||
// store transient value in memcache keyed by token with TTL = token expiry - now
|
||||
if ($presentationLeader !== null) {
|
||||
/** @var ICache $cache */
|
||||
$cache = $this->cacheFactory->createLocal('richdocuments_wopi');
|
||||
$ttl = $this->calculateNewTokenExpiry() - $this->timeFactory->getTime();
|
||||
if ($ttl <= 0) {
|
||||
$ttl = 60;
|
||||
}
|
||||
$cache->set('wopi_extra_' . $token, json_encode(['PresentationLeader' => $presentationLeader]), (int)$ttl);
|
||||
}
|
||||
|
||||
/** @var Wopi $wopi */
|
||||
$wopi = $this->insert($wopi);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class TokenManager {
|
|||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generateWopiToken(string $fileId, ?string $shareToken = null, ?string $editoruid = null, bool $direct = false): Wopi {
|
||||
public function generateWopiToken(string $fileId, ?string $shareToken = null, ?string $editoruid = null, bool $direct = false, ?string $presentationLeader = null): Wopi {
|
||||
[$fileId, , $version] = Helper::parseFileId($fileId);
|
||||
$owneruid = null;
|
||||
$hideDownload = false;
|
||||
|
|
@ -121,7 +121,7 @@ class TokenManager {
|
|||
|
||||
$serverHost = $this->urlGenerator->getAbsoluteURL('/');
|
||||
$guestName = $editoruid === null ? $this->prepareGuestName($this->helper->getGuestNameFromCookie()) : null;
|
||||
return $this->wopiMapper->generateFileToken($fileId, $owneruid, $editoruid, $version, $updatable, $serverHost, $guestName, $hideDownload, $direct, 0, $shareToken);
|
||||
return $this->wopiMapper->generateFileToken($fileId, $owneruid, $editoruid, $version, $updatable, $serverHost, $guestName, $hideDownload, $direct, 0, $shareToken, $presentationLeader);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue