diff --git a/collabora_online.module b/collabora_online.module
index fd2cc452..75d34f77 100644
--- a/collabora_online.module
+++ b/collabora_online.module
@@ -33,42 +33,42 @@ use Drupal\media\MediaInterface;
function collabora_online_theme($existing, $type, $theme, $path) {
return [
- 'collabora_online' => [
- 'render element' => 'children',
- 'template' => 'collabora-online',
- 'variables' => [
- 'accessToken' => 'test',
- 'accessTokenTtl' => '86400',
- 'iFrameStyle' => 'width:95%;',
- 'closebutton' => '',
- 'allowfullscreen' => '',
- 'wopiSrc' => 'http://localhost:9980/',
- 'wopiClient' => 'https://localhost:9980/',
- ],
+ 'collabora_online' => [
+ 'render element' => 'children',
+ 'template' => 'collabora-online',
+ 'variables' => [
+ 'accessToken' => 'test',
+ 'accessTokenTtl' => '86400',
+ 'iFrameStyle' => 'width:95%;',
+ 'closebutton' => '',
+ 'allowfullscreen' => '',
+ 'wopiSrc' => 'http://localhost:9980/',
+ 'wopiClient' => 'https://localhost:9980/',
],
- // This is the template for the field preview.
- 'collabora_online_preview' => [
- 'render element' => 'children',
- 'template' => 'collabora-online-preview',
- 'variables' => [
- 'editorUrl' => 'about:blank',
- 'fileName' => '',
- ],
+ ],
+ // This is the template for the field preview.
+ 'collabora_online_preview' => [
+ 'render element' => 'children',
+ 'template' => 'collabora-online-preview',
+ 'variables' => [
+ 'editorUrl' => 'about:blank',
+ 'fileName' => '',
],
- // This is the template for the complete page with embedding.
- 'collabora_online_full' => [
- 'template' => 'collabora-online-full',
- 'variables' => [
- 'accessToken' => 'test',
- 'accessTokenTtl' => '86400',
- 'iFrameStyle' => '',
- 'closebutton' => '',
- 'allowfullscreen' => '',
- 'wopiSrc' => '/wopi/files/123',
- 'wopiClient' => 'https://localhost:9980/',
- ],
- 'file' => 'collabora_online.theme.inc',
+ ],
+ // This is the template for the complete page with embedding.
+ 'collabora_online_full' => [
+ 'template' => 'collabora-online-full',
+ 'variables' => [
+ 'accessToken' => 'test',
+ 'accessTokenTtl' => '86400',
+ 'iFrameStyle' => '',
+ 'closebutton' => '',
+ 'allowfullscreen' => '',
+ 'wopiSrc' => '/wopi/files/123',
+ 'wopiClient' => 'https://localhost:9980/',
],
+ 'file' => 'collabora_online.theme.inc',
+ ],
];
}
@@ -79,42 +79,42 @@ function collabora_online_theme($existing, $type, $theme, $path) {
* open the viewer/editor directly.
*/
function collabora_online_entity_operation(EntityInterface $entity) {
- if (($entity->getEntityTypeId() != "media") ||
- ($entity->getSource()->getPluginId() != "file")) {
- return [];
- }
+ if (($entity->getEntityTypeId() != "media") ||
+ ($entity->getSource()->getPluginId() != "file")) {
+ return [];
+ }
- /** @var \Drupal\media\MediaInterface $media */
- $media = $entity;
+ /** @var \Drupal\media\MediaInterface $media */
+ $media = $entity;
- if (!$media->access('preview in collabora')) {
- return [];
- }
+ if (!$media->access('preview in collabora')) {
+ return [];
+ }
- $file = CoolUtils::getFile($media);
- $type = CoolUtils::getDocumentType($file);
+ $file = CoolUtils::getFile($media);
+ $type = CoolUtils::getDocumentType($file);
- if ($type == NULL) {
- return [];
- }
+ if ($type == NULL) {
+ return [];
+ }
- $entries = [
- 'collabora_online_view' => [
- 'title' => t("View in Collabora Online"),
- 'weight' => 50,
- 'url' => CoolUtils::getEditorUrl($media, FALSE),
- ],
- ];
+ $entries = [
+ 'collabora_online_view' => [
+ 'title' => t("View in Collabora Online"),
+ 'weight' => 50,
+ 'url' => CoolUtils::getEditorUrl($media, FALSE),
+ ],
+ ];
- if (CoolUtils::canEdit($file) && $media->access('edit in collabora')) {
- $entries['collabora_online_edit'] = [
- 'title' => t("Edit in Collabora Online"),
- 'weight' => 50,
- 'url' => CoolUtils::getEditorUrl($media, TRUE),
- ];
- }
+ if (CoolUtils::canEdit($file) && $media->access('edit in collabora')) {
+ $entries['collabora_online_edit'] = [
+ 'title' => t("Edit in Collabora Online"),
+ 'weight' => 50,
+ 'url' => CoolUtils::getEditorUrl($media, TRUE),
+ ];
+ }
- return $entries;
+ return $entries;
}
/**
@@ -123,56 +123,56 @@ function collabora_online_entity_operation(EntityInterface $entity) {
* Checks access for the new media operations provided by this module.
*/
function collabora_online_media_access(MediaInterface $media, string $operation, AccountInterface $account): AccessResultInterface {
- $type = $media->bundle();
- switch ($operation) {
- case 'preview in collabora':
- if ($media->isPublished()) {
- return AccessResult::allowedIfHasPermission($account, "preview $type in collabora")
- ->addCacheableDependency($media);
- }
- $preview_own_permission = "preview own unpublished $type in collabora";
- $access_result = AccessResult::allowedIfHasPermission($account, $preview_own_permission)
- ->addCacheableDependency($media);
- if (!$access_result->isAllowed()) {
- return $access_result;
- }
- // Use '==' because Drupal sometimes loads integers as strings.
- $is_owner = ($account->id() && $account->id() == $media->getOwnerId());
- if ($is_owner) {
- $access_result = AccessResult::allowed();
- }
- else {
- $access_result = AccessResult::neutral()
- ->setReason("The user has the '$preview_own_permission' permission, but is not the owner of the media item.");
- }
- return $access_result
- ->cachePerUser()
- ->addCacheableDependency($media);
+ $type = $media->bundle();
+ switch ($operation) {
+ case 'preview in collabora':
+ if ($media->isPublished()) {
+ return AccessResult::allowedIfHasPermission($account, "preview $type in collabora")
+ ->addCacheableDependency($media);
+ }
+ $preview_own_permission = "preview own unpublished $type in collabora";
+ $access_result = AccessResult::allowedIfHasPermission($account, $preview_own_permission)
+ ->addCacheableDependency($media);
+ if (!$access_result->isAllowed()) {
+ return $access_result;
+ }
+ // Use '==' because Drupal sometimes loads integers as strings.
+ $is_owner = ($account->id() && $account->id() == $media->getOwnerId());
+ if ($is_owner) {
+ $access_result = AccessResult::allowed();
+ }
+ else {
+ $access_result = AccessResult::neutral()
+ ->setReason("The user has the '$preview_own_permission' permission, but is not the owner of the media item.");
+ }
+ return $access_result
+ ->cachePerUser()
+ ->addCacheableDependency($media);
- case 'edit in collabora':
- if ($account->hasPermission("edit any $type in collabora")) {
- return AccessResult::allowed()
- ->cachePerPermissions();
- }
- $edit_own_permission = "edit own $type in collabora";
- $access_result = AccessResult::allowedIfHasPermission($account, $edit_own_permission);
- if (!$access_result->isAllowed()) {
- return $access_result;
- }
- // Use '==' because Drupal sometimes loads integers as strings.
- $is_owner = ($account->id() && $account->id() == $media->getOwnerId());
- if (!$is_owner) {
- $access_result = AccessResult::neutral()
- ->setReason("The user has the '$edit_own_permission' permission, but is not the owner of the media item.");
- }
- else {
- $access_result = AccessResult::allowed();
- }
- return $access_result
- ->cachePerUser()
- ->addCacheableDependency($media);
+ case 'edit in collabora':
+ if ($account->hasPermission("edit any $type in collabora")) {
+ return AccessResult::allowed()
+ ->cachePerPermissions();
+ }
+ $edit_own_permission = "edit own $type in collabora";
+ $access_result = AccessResult::allowedIfHasPermission($account, $edit_own_permission);
+ if (!$access_result->isAllowed()) {
+ return $access_result;
+ }
+ // Use '==' because Drupal sometimes loads integers as strings.
+ $is_owner = ($account->id() && $account->id() == $media->getOwnerId());
+ if (!$is_owner) {
+ $access_result = AccessResult::neutral()
+ ->setReason("The user has the '$edit_own_permission' permission, but is not the owner of the media item.");
+ }
+ else {
+ $access_result = AccessResult::allowed();
+ }
+ return $access_result
+ ->cachePerUser()
+ ->addCacheableDependency($media);
- default:
- return AccessResult::neutral();
- }
+ default:
+ return AccessResult::neutral();
+ }
}
diff --git a/collabora_online.theme.inc b/collabora_online.theme.inc
index 3a9966c0..1dae081f 100644
--- a/collabora_online.theme.inc
+++ b/collabora_online.theme.inc
@@ -14,7 +14,7 @@ use Drupal\Core\Extension\ExtensionPathResolver;
* Theme hook variables.
*/
function template_preprocess_collabora_online_full(array &$variables): void {
- /** @var \Drupal\Core\Extension\ExtensionPathResolver $path_resolver */
- $path_resolver = \Drupal::service(ExtensionPathResolver::class);
- $variables['module_path'] = $path_resolver->getPath('module', 'collabora_online');
+ /** @var \Drupal\Core\Extension\ExtensionPathResolver $path_resolver */
+ $path_resolver = \Drupal::service(ExtensionPathResolver::class);
+ $variables['module_path'] = $path_resolver->getPath('module', 'collabora_online');
}
diff --git a/collabora_online.views.inc b/collabora_online.views.inc
index 275511b5..01e9c2c6 100644
--- a/collabora_online.views.inc
+++ b/collabora_online.views.inc
@@ -11,18 +11,18 @@ declare(strict_types=1);
* Implements hook_views_data_alter().
*/
function collabora_online_views_data_alter(array &$data): void {
- $data['media']['collabora_preview'] = [
- 'title' => t('Link to view in Collabora Online'),
- 'group' => t('Media'),
- 'field' => [
- 'id' => 'media_collabora_preview',
- ],
- ];
- $data['media']['collabora_edit'] = [
- 'title' => t('Link to edit in Collabora Online'),
- 'group' => t('Media'),
- 'field' => [
- 'id' => 'media_collabora_edit',
- ],
- ];
+ $data['media']['collabora_preview'] = [
+ 'title' => t('Link to view in Collabora Online'),
+ 'group' => t('Media'),
+ 'field' => [
+ 'id' => 'media_collabora_preview',
+ ],
+ ];
+ $data['media']['collabora_edit'] = [
+ 'title' => t('Link to edit in Collabora Online'),
+ 'group' => t('Media'),
+ 'field' => [
+ 'id' => 'media_collabora_edit',
+ ],
+ ];
}
diff --git a/css/cool.css b/css/cool.css
index 5b5c6395..1b829c4c 100644
--- a/css/cool.css
+++ b/css/cool.css
@@ -14,30 +14,30 @@
}
.cool-frame__preview {
- width: 100%;
- height: 100%;
- border: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
}
.cool-frame__iframe {
- border: 1px solid;
- width: 100%;
- height: 100%;
- position: absolute;
- box-sizing: border-box;
+ border: 1px solid;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ box-sizing: border-box;
}
.cool-editor__dialog {
- resize: both;
- position: fixed;
- top: 250px;
- width: 100%;
- height: calc(100% - 250px);
- /* seems to be a reasonable value to be above of it all */
- z-index: 501;
- box-sizing: border-box;
+ resize: both;
+ position: fixed;
+ top: 250px;
+ width: 100%;
+ height: calc(100% - 250px);
+ /* seems to be a reasonable value to be above of it all */
+ z-index: 501;
+ box-sizing: border-box;
}
.cool-editor__body {
- margin: 0;
+ margin: 0;
}
diff --git a/js/cool.js b/js/cool.js
index 95dd249d..80a49dd7 100644
--- a/js/cool.js
+++ b/js/cool.js
@@ -10,60 +10,60 @@
*/
function loadDocument(wopiClient, wopiSrc, options = null) {
- let hasCloseButton = false;
- let wopiUrl = `${wopiClient}WOPISrc=${wopiSrc}`;
- if (options && options.closebutton == true) {
- wopiUrl += '&closebutton=true';
- hasCloseButton = true;
- }
+ let hasCloseButton = false;
+ let wopiUrl = `${wopiClient}WOPISrc=${wopiSrc}`;
+ if (options && options.closebutton == true) {
+ wopiUrl += '&closebutton=true';
+ hasCloseButton = true;
+ }
- window.addEventListener("message", receiveMessage.bind(null, hasCloseButton), false);
+ window.addEventListener("message", receiveMessage.bind(null, hasCloseButton), false);
- let formElem = document.getElementById("collabora-submit-form");
+ let formElem = document.getElementById("collabora-submit-form");
- if (!formElem) {
- console.log("error: submit form not found");
- return;
- }
- formElem.action = wopiUrl;
- formElem.submit();
+ if (!formElem) {
+ console.log("error: submit form not found");
+ return;
+ }
+ formElem.action = wopiUrl;
+ formElem.submit();
}
function postMessage(msg) {
- document.getElementById("collabora-online-viewer").contentWindow.postMessage(JSON.stringify(msg), '*');
+ document.getElementById("collabora-online-viewer").contentWindow.postMessage(JSON.stringify(msg), '*');
}
function postReady() {
- postMessage({ MessageId: "Host_PostmessageReady" });
+ postMessage({ MessageId: "Host_PostmessageReady" });
}
function receiveMessage(hasCloseButton, event) {
- let msg = JSON.parse(event.data);
- if (!msg) {
- return;
- }
+ let msg = JSON.parse(event.data);
+ if (!msg) {
+ return;
+ }
- switch (msg.MessageId) {
+ switch (msg.MessageId) {
case "App_LoadingStatus":
- if (msg.Values && msg.Values.Status == "Document_Loaded") {
- postReady();
- }
- break;
+ if (msg.Values && msg.Values.Status == "Document_Loaded") {
+ postReady();
+ }
+ break;
case "UI_Close":
- if (hasCloseButton) {
- if (msg.Values && msg.Values.EverModified) {
- let reply = { MessageId: "Action_Close" };
- postMessage(reply);
- }
- if (window.parent.location == window.location) {
- history.back();
- } else {
- /* we send back the UI_Close message to the parent frame. */
- window.parent.postMessage(event.data);
- }
+ if (hasCloseButton) {
+ if (msg.Values && msg.Values.EverModified) {
+ let reply = { MessageId: "Action_Close" };
+ postMessage(reply);
+ }
+ if (window.parent.location == window.location) {
+ history.back();
+ } else {
+ /* we send back the UI_Close message to the parent frame. */
+ window.parent.postMessage(event.data);
}
- break;
- }
+ }
+ break;
+ }
}
diff --git a/js/previewer.js b/js/previewer.js
index fdf072c5..eebdb781 100644
--- a/js/previewer.js
+++ b/js/previewer.js
@@ -10,35 +10,35 @@
*/
function previewField(coolUrl) {
- let iframe = document.querySelector("#cool-editor__dialog > .cool-frame__preview");
- iframe.src = coolUrl;
- document.querySelector("#cool-editor__dialog").show();
+ let iframe = document.querySelector("#cool-editor__dialog > .cool-frame__preview");
+ iframe.src = coolUrl;
+ document.querySelector("#cool-editor__dialog").show();
}
function closePreview() {
- let iframe = document.querySelector("#cool-editor__dialog > .cool-frame__preview");
- iframe.src = "about:blank";
- document.querySelector('#cool-editor__dialog').close();
+ let iframe = document.querySelector("#cool-editor__dialog > .cool-frame__preview");
+ iframe.src = "about:blank";
+ document.querySelector('#cool-editor__dialog').close();
}
(function () {
- function receiveMessage(event) {
- let msg = JSON.parse(event.data);
- if (!msg) {
- return;
- }
+ function receiveMessage(event) {
+ let msg = JSON.parse(event.data);
+ if (!msg) {
+ return;
+ }
- switch (msg.MessageId) {
- case "App_LoadingStatus":
- if (msg.Values && msg.Values.Status == "Document_Loaded") {
- postReady();
- }
- break;
- case "UI_Close":
- closePreview();
- break;
+ switch (msg.MessageId) {
+ case "App_LoadingStatus":
+ if (msg.Values && msg.Values.Status == "Document_Loaded") {
+ postReady();
}
+ break;
+ case "UI_Close":
+ closePreview();
+ break;
}
+ }
- window.addEventListener("message", receiveMessage, false);
+ window.addEventListener("message", receiveMessage, false);
})()
diff --git a/modules/collabora_online_group/tests/src/Kernel/AccessTest.php b/modules/collabora_online_group/tests/src/Kernel/AccessTest.php
index b4d6e231..830837a6 100644
--- a/modules/collabora_online_group/tests/src/Kernel/AccessTest.php
+++ b/modules/collabora_online_group/tests/src/Kernel/AccessTest.php
@@ -17,316 +17,316 @@
*/
class AccessTest extends GroupKernelTestBase {
- use MediaTypeCreationTrait;
- use UserCreationTrait;
- use MediaCreationTrait;
- use GroupRelationTrait;
+ use MediaTypeCreationTrait;
+ use UserCreationTrait;
+ use MediaCreationTrait;
+ use GroupRelationTrait;
- /**
- * {@inheritdoc}
- */
- protected static $modules = [
- 'file',
- 'media',
- 'image',
- 'group',
- 'groupmedia',
- 'collabora_online',
- 'collabora_online_group',
- 'user',
- ];
+ /**
+ * {@inheritdoc}
+ */
+ protected static $modules = [
+ 'file',
+ 'media',
+ 'image',
+ 'group',
+ 'groupmedia',
+ 'collabora_online',
+ 'collabora_online_group',
+ 'user',
+ ];
- /**
- * {@inheritdoc}
- */
- protected function setUp(): void {
- parent::setUp();
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp(): void {
+ parent::setUp();
- $this->installEntitySchema('file');
- $this->installEntitySchema('media');
- $this->installEntitySchema('group_role');
- $this->installSchema('file', ['file_usage']);
- }
+ $this->installEntitySchema('file');
+ $this->installEntitySchema('media');
+ $this->installEntitySchema('group_role');
+ $this->installSchema('file', ['file_usage']);
+ }
- /**
- * Tests that access to Collabora group permissions is handled.
- */
- public function testCollaboraAccess(): void {
- // Create group type, media type and enable plugin.
- $group_type = $this->createGroupType();
- $group_role = $this->createGroupRole([
- 'group_type' => $group_type->id(),
- 'scope' => PermissionScopeInterface::INSIDER_ID,
- 'global_role' => RoleInterface::AUTHENTICATED_ID,
- 'permissions' => [],
- ]);
- $this->createMediaType('file', ['id' => 'document']);
- $this->createPluginRelation($group_type, 'group_media:document', [
- 'group_cardinality' => 0,
- 'entity_cardinality' => 1,
- 'use_creation_wizard' => FALSE,
- ]);
+ /**
+ * Tests that access to Collabora group permissions is handled.
+ */
+ public function testCollaboraAccess(): void {
+ // Create group type, media type and enable plugin.
+ $group_type = $this->createGroupType();
+ $group_role = $this->createGroupRole([
+ 'group_type' => $group_type->id(),
+ 'scope' => PermissionScopeInterface::INSIDER_ID,
+ 'global_role' => RoleInterface::AUTHENTICATED_ID,
+ 'permissions' => [],
+ ]);
+ $this->createMediaType('file', ['id' => 'document']);
+ $this->createPluginRelation($group_type, 'group_media:document', [
+ 'group_cardinality' => 0,
+ 'entity_cardinality' => 1,
+ 'use_creation_wizard' => FALSE,
+ ]);
- // Add group, media and relation between both.
- $group = $this->createGroup(['type' => $group_type->id()]);
- $media = $this->createMediaEntity('document');
- $group->addRelationship($media, 'group_media:document');
+ // Add group, media and relation between both.
+ $group = $this->createGroup(['type' => $group_type->id()]);
+ $media = $this->createMediaEntity('document');
+ $group->addRelationship($media, 'group_media:document');
- // Iterate over each scenario.
- foreach ($this->getTestScenarios() as $scenario_name => $scenario) {
- // Apply status to media.
- $media->set('status', $scenario['status'])->save();
- // Set the current permissions for the existing role.
- $group_role->set('permissions', $scenario['group_permissions'])->save();
- // Create the user with the given permissions and as member of the
- // group.
- $user = $this->createUser($scenario['permissions']);
- $group->addMember($user);
- // Set user as owner if the scope is 'own'.
- $owner = $scenario['scope'] === 'own' ? $user->id() : 0;
- $media->setOwnerId($owner)->save();
+ // Iterate over each scenario.
+ foreach ($this->getTestScenarios() as $scenario_name => $scenario) {
+ // Apply status to media.
+ $media->set('status', $scenario['status'])->save();
+ // Set the current permissions for the existing role.
+ $group_role->set('permissions', $scenario['group_permissions'])->save();
+ // Create the user with the given permissions and as member of the
+ // group.
+ $user = $this->createUser($scenario['permissions']);
+ $group->addMember($user);
+ // Set user as owner if the scope is 'own'.
+ $owner = $scenario['scope'] === 'own' ? $user->id() : 0;
+ $media->setOwnerId($owner)->save();
- // Check access.
- $this->assertEquals(
- $scenario['result'],
- $media->access($scenario['operation'], $user),
- sprintf('Access check failed for scenario: "%s"', $scenario_name)
- );
- }
+ // Check access.
+ $this->assertEquals(
+ $scenario['result'],
+ $media->access($scenario['operation'], $user),
+ sprintf('Access check failed for scenario: "%s"', $scenario_name)
+ );
}
+ }
- /**
- * Retrieves the scenarios to be tested.
- *
- * @return array
- * An array of test scenarios.
- */
- protected function getTestScenarios(): array {
- // The scenario keys contains values used for each scenario:
- // 'operation:status:scope:global_permission:group_permission'.
- return [
- // Preview no permissions cases.
- 'preview:published:any::' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => [],
- 'operation' => 'preview in collabora',
- 'status' => 1,
- 'scope' => 'any',
- ],
- 'preview:published:own::' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => [],
- 'operation' => 'preview in collabora',
- 'status' => 1,
- 'scope' => 'own',
- ],
- // The global permissions that would allow to preview, doesn't work
- // in a media related to a group.
- 'preview:published:any:preview:' => [
- 'result' => FALSE,
- 'permissions' => ['preview document in collabora'],
- 'group_permissions' => [],
- 'operation' => 'preview in collabora',
- 'status' => 1,
- 'scope' => 'any',
- ],
- 'preview:published:own:preview:' => [
- 'result' => FALSE,
- 'permissions' => ['preview document in collabora'],
- 'group_permissions' => [],
- 'operation' => 'preview in collabora',
- 'status' => 1,
- 'scope' => 'own',
- ],
- // User can only see published entities with the group preview
- // permission.
- 'preview:published:any::preview' => [
- 'result' => TRUE,
- 'permissions' => [],
- 'group_permissions' => ['preview group_media:document in collabora'],
- 'operation' => 'preview in collabora',
- 'status' => 1,
- 'scope' => 'any',
- ],
- 'preview:published:own::preview' => [
- 'result' => TRUE,
- 'permissions' => [],
- 'group_permissions' => ['preview group_media:document in collabora'],
- 'operation' => 'preview in collabora',
- 'status' => 1,
- 'scope' => 'own',
- ],
- 'preview:unpublished:any::preview' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => ['preview group_media:document in collabora'],
- 'operation' => 'preview in collabora',
- 'status' => 0,
- 'scope' => 'any',
- ],
- 'preview:unpublished:own::preview' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => ['preview group_media:document in collabora'],
- 'operation' => 'preview in collabora',
- 'status' => 0,
- 'scope' => 'own',
- ],
- // The global preview unpublished doesn't affect to medias related
- // to a group.
- 'preview:unpublished:own:preview_own_unpublished:' => [
- 'result' => FALSE,
- 'permissions' => ['preview own unpublished document in collabora'],
- 'group_permissions' => [],
- 'operation' => 'preview in collabora',
- 'status' => 0,
- 'scope' => 'own',
- ],
- // The group permission to preview own unpublished permission allows
- // to see only entities with such properties.
- 'preview:published:any::preview_own_unpublished' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => ['preview own unpublished group_media:document in collabora'],
- 'operation' => 'preview in collabora',
- 'status' => 1,
- 'scope' => 'any',
- ],
- 'preview:published:own::preview_own_unpublished' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => ['preview own unpublished group_media:document in collabora'],
- 'operation' => 'preview in collabora',
- 'status' => 1,
- 'scope' => 'own',
- ],
- 'preview:unpublished:own::preview_own_unpublished' => [
- 'result' => TRUE,
- 'permissions' => [],
- 'group_permissions' => ['preview own unpublished group_media:document in collabora'],
- 'operation' => 'preview in collabora',
- 'status' => 0,
- 'scope' => 'own',
- ],
- 'preview:unpublished:any::preview_own_unpublished' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => ['preview own unpublished group_media:document in collabora'],
- 'operation' => 'preview in collabora',
- 'status' => 0,
- 'scope' => 'any',
- ],
- // Edit no permissions cases.
- 'edit:published:any::' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => [],
- 'operation' => 'edit in collabora',
- 'status' => 1,
- 'scope' => 'any',
- ],
- 'edit:published:own::' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => [],
- 'operation' => 'edit in collabora',
- 'status' => 1,
- 'scope' => 'own',
- ],
- // The global permission doesn't grant access to edit in a group.
- 'edit:published:any:edit_any:' => [
- 'result' => FALSE,
- 'permissions' => ['edit any document in collabora'],
- 'group_permissions' => [],
- 'operation' => 'edit in collabora',
- 'status' => 1,
- 'scope' => 'any',
- ],
- 'edit:published:own:edit_any:' => [
- 'result' => FALSE,
- 'permissions' => ['edit any document in collabora'],
- 'group_permissions' => [],
- 'operation' => 'edit in collabora',
- 'status' => 1,
- 'scope' => 'own',
- ],
- 'edit:published:own:edit_own:' => [
- 'result' => FALSE,
- 'permissions' => ['edit own document in collabora'],
- 'group_permissions' => [],
- 'operation' => 'edit in collabora',
- 'status' => 1,
- 'scope' => 'own',
- ],
- // Only users with edit any permission in a group can edit all.
- 'edit:published:any::edit_any' => [
- 'result' => TRUE,
- 'permissions' => [],
- 'group_permissions' => ['edit any group_media:document in collabora'],
- 'operation' => 'edit in collabora',
- 'status' => 1,
- 'scope' => 'any',
- ],
- 'edit:published:own::edit_any' => [
- 'result' => TRUE,
- 'permissions' => [],
- 'group_permissions' => ['edit any group_media:document in collabora'],
- 'operation' => 'edit in collabora',
- 'status' => 1,
- 'scope' => 'own',
- ],
- 'edit:unpublished:any::edit_any' => [
- 'result' => TRUE,
- 'permissions' => [],
- 'group_permissions' => ['edit any group_media:document in collabora'],
- 'operation' => 'edit in collabora',
- 'status' => 0,
- 'scope' => 'any',
- ],
- 'edit:unpublished:own::edit_any' => [
- 'result' => TRUE,
- 'permissions' => [],
- 'group_permissions' => ['edit any group_media:document in collabora'],
- 'operation' => 'edit in collabora',
- 'status' => 0,
- 'scope' => 'own',
- ],
- // Or edit own permission for the entities the user owns.
- 'edit:published:own::edit_own' => [
- 'result' => TRUE,
- 'permissions' => [],
- 'group_permissions' => ['edit own group_media:document in collabora'],
- 'operation' => 'edit in collabora',
- 'status' => 1,
- 'scope' => 'own',
- ],
- 'edit:unpublished:own::edit_own' => [
- 'result' => TRUE,
- 'permissions' => [],
- 'group_permissions' => ['edit own group_media:document in collabora'],
- 'operation' => 'edit in collabora',
- 'status' => 0,
- 'scope' => 'own',
- ],
- 'edit:published:any::edit_own' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => ['edit own group_media:document in collabora'],
- 'operation' => 'edit in collabora',
- 'status' => 1,
- 'scope' => 'any',
- ],
- 'edit:unpublished:any::edit_own' => [
- 'result' => FALSE,
- 'permissions' => [],
- 'group_permissions' => ['edit own group_media:document in collabora'],
- 'operation' => 'edit in collabora',
- 'status' => 0,
- 'scope' => 'any',
- ],
- ];
- }
+ /**
+ * Retrieves the scenarios to be tested.
+ *
+ * @return array
+ * An array of test scenarios.
+ */
+ protected function getTestScenarios(): array {
+ // The scenario keys contains values used for each scenario:
+ // 'operation:status:scope:global_permission:group_permission'.
+ return [
+ // Preview no permissions cases.
+ 'preview:published:any::' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => [],
+ 'operation' => 'preview in collabora',
+ 'status' => 1,
+ 'scope' => 'any',
+ ],
+ 'preview:published:own::' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => [],
+ 'operation' => 'preview in collabora',
+ 'status' => 1,
+ 'scope' => 'own',
+ ],
+ // The global permissions that would allow to preview, doesn't work
+ // in a media related to a group.
+ 'preview:published:any:preview:' => [
+ 'result' => FALSE,
+ 'permissions' => ['preview document in collabora'],
+ 'group_permissions' => [],
+ 'operation' => 'preview in collabora',
+ 'status' => 1,
+ 'scope' => 'any',
+ ],
+ 'preview:published:own:preview:' => [
+ 'result' => FALSE,
+ 'permissions' => ['preview document in collabora'],
+ 'group_permissions' => [],
+ 'operation' => 'preview in collabora',
+ 'status' => 1,
+ 'scope' => 'own',
+ ],
+ // User can only see published entities with the group preview
+ // permission.
+ 'preview:published:any::preview' => [
+ 'result' => TRUE,
+ 'permissions' => [],
+ 'group_permissions' => ['preview group_media:document in collabora'],
+ 'operation' => 'preview in collabora',
+ 'status' => 1,
+ 'scope' => 'any',
+ ],
+ 'preview:published:own::preview' => [
+ 'result' => TRUE,
+ 'permissions' => [],
+ 'group_permissions' => ['preview group_media:document in collabora'],
+ 'operation' => 'preview in collabora',
+ 'status' => 1,
+ 'scope' => 'own',
+ ],
+ 'preview:unpublished:any::preview' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => ['preview group_media:document in collabora'],
+ 'operation' => 'preview in collabora',
+ 'status' => 0,
+ 'scope' => 'any',
+ ],
+ 'preview:unpublished:own::preview' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => ['preview group_media:document in collabora'],
+ 'operation' => 'preview in collabora',
+ 'status' => 0,
+ 'scope' => 'own',
+ ],
+ // The global preview unpublished doesn't affect to medias related
+ // to a group.
+ 'preview:unpublished:own:preview_own_unpublished:' => [
+ 'result' => FALSE,
+ 'permissions' => ['preview own unpublished document in collabora'],
+ 'group_permissions' => [],
+ 'operation' => 'preview in collabora',
+ 'status' => 0,
+ 'scope' => 'own',
+ ],
+ // The group permission to preview own unpublished permission allows
+ // to see only entities with such properties.
+ 'preview:published:any::preview_own_unpublished' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => ['preview own unpublished group_media:document in collabora'],
+ 'operation' => 'preview in collabora',
+ 'status' => 1,
+ 'scope' => 'any',
+ ],
+ 'preview:published:own::preview_own_unpublished' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => ['preview own unpublished group_media:document in collabora'],
+ 'operation' => 'preview in collabora',
+ 'status' => 1,
+ 'scope' => 'own',
+ ],
+ 'preview:unpublished:own::preview_own_unpublished' => [
+ 'result' => TRUE,
+ 'permissions' => [],
+ 'group_permissions' => ['preview own unpublished group_media:document in collabora'],
+ 'operation' => 'preview in collabora',
+ 'status' => 0,
+ 'scope' => 'own',
+ ],
+ 'preview:unpublished:any::preview_own_unpublished' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => ['preview own unpublished group_media:document in collabora'],
+ 'operation' => 'preview in collabora',
+ 'status' => 0,
+ 'scope' => 'any',
+ ],
+ // Edit no permissions cases.
+ 'edit:published:any::' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => [],
+ 'operation' => 'edit in collabora',
+ 'status' => 1,
+ 'scope' => 'any',
+ ],
+ 'edit:published:own::' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => [],
+ 'operation' => 'edit in collabora',
+ 'status' => 1,
+ 'scope' => 'own',
+ ],
+ // The global permission doesn't grant access to edit in a group.
+ 'edit:published:any:edit_any:' => [
+ 'result' => FALSE,
+ 'permissions' => ['edit any document in collabora'],
+ 'group_permissions' => [],
+ 'operation' => 'edit in collabora',
+ 'status' => 1,
+ 'scope' => 'any',
+ ],
+ 'edit:published:own:edit_any:' => [
+ 'result' => FALSE,
+ 'permissions' => ['edit any document in collabora'],
+ 'group_permissions' => [],
+ 'operation' => 'edit in collabora',
+ 'status' => 1,
+ 'scope' => 'own',
+ ],
+ 'edit:published:own:edit_own:' => [
+ 'result' => FALSE,
+ 'permissions' => ['edit own document in collabora'],
+ 'group_permissions' => [],
+ 'operation' => 'edit in collabora',
+ 'status' => 1,
+ 'scope' => 'own',
+ ],
+ // Only users with edit any permission in a group can edit all.
+ 'edit:published:any::edit_any' => [
+ 'result' => TRUE,
+ 'permissions' => [],
+ 'group_permissions' => ['edit any group_media:document in collabora'],
+ 'operation' => 'edit in collabora',
+ 'status' => 1,
+ 'scope' => 'any',
+ ],
+ 'edit:published:own::edit_any' => [
+ 'result' => TRUE,
+ 'permissions' => [],
+ 'group_permissions' => ['edit any group_media:document in collabora'],
+ 'operation' => 'edit in collabora',
+ 'status' => 1,
+ 'scope' => 'own',
+ ],
+ 'edit:unpublished:any::edit_any' => [
+ 'result' => TRUE,
+ 'permissions' => [],
+ 'group_permissions' => ['edit any group_media:document in collabora'],
+ 'operation' => 'edit in collabora',
+ 'status' => 0,
+ 'scope' => 'any',
+ ],
+ 'edit:unpublished:own::edit_any' => [
+ 'result' => TRUE,
+ 'permissions' => [],
+ 'group_permissions' => ['edit any group_media:document in collabora'],
+ 'operation' => 'edit in collabora',
+ 'status' => 0,
+ 'scope' => 'own',
+ ],
+ // Or edit own permission for the entities the user owns.
+ 'edit:published:own::edit_own' => [
+ 'result' => TRUE,
+ 'permissions' => [],
+ 'group_permissions' => ['edit own group_media:document in collabora'],
+ 'operation' => 'edit in collabora',
+ 'status' => 1,
+ 'scope' => 'own',
+ ],
+ 'edit:unpublished:own::edit_own' => [
+ 'result' => TRUE,
+ 'permissions' => [],
+ 'group_permissions' => ['edit own group_media:document in collabora'],
+ 'operation' => 'edit in collabora',
+ 'status' => 0,
+ 'scope' => 'own',
+ ],
+ 'edit:published:any::edit_own' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => ['edit own group_media:document in collabora'],
+ 'operation' => 'edit in collabora',
+ 'status' => 1,
+ 'scope' => 'any',
+ ],
+ 'edit:unpublished:any::edit_own' => [
+ 'result' => FALSE,
+ 'permissions' => [],
+ 'group_permissions' => ['edit own group_media:document in collabora'],
+ 'operation' => 'edit in collabora',
+ 'status' => 0,
+ 'scope' => 'any',
+ ],
+ ];
+ }
}
diff --git a/modules/collabora_online_group/tests/src/Kernel/PermissionTest.php b/modules/collabora_online_group/tests/src/Kernel/PermissionTest.php
index 4938b508..d7daa4bd 100644
--- a/modules/collabora_online_group/tests/src/Kernel/PermissionTest.php
+++ b/modules/collabora_online_group/tests/src/Kernel/PermissionTest.php
@@ -13,112 +13,112 @@
*/
class PermissionTest extends GroupKernelTestBase {
- use MediaTypeCreationTrait;
- use GroupRelationTrait;
+ use MediaTypeCreationTrait;
+ use GroupRelationTrait;
- /**
- * {@inheritdoc}
- */
- protected static $modules = [
- 'file',
- 'media',
- 'group',
- 'groupmedia',
- ];
+ /**
+ * {@inheritdoc}
+ */
+ protected static $modules = [
+ 'file',
+ 'media',
+ 'group',
+ 'groupmedia',
+ ];
- /**
- * Tests that group permissions are properly created.
- */
- public function testGroupPermissions(): void {
- // Generate types: groups and medias.
- $group_type_1 = $this->createGroupType();
- $group_type_2 = $this->createGroupType();
- $group_type_3 = $this->createGroupType();
- $this->createMediaType('file', ['id' => 'document']);
- $this->createMediaType('file', ['id' => 'spreadsheet']);
+ /**
+ * Tests that group permissions are properly created.
+ */
+ public function testGroupPermissions(): void {
+ // Generate types: groups and medias.
+ $group_type_1 = $this->createGroupType();
+ $group_type_2 = $this->createGroupType();
+ $group_type_3 = $this->createGroupType();
+ $this->createMediaType('file', ['id' => 'document']);
+ $this->createMediaType('file', ['id' => 'spreadsheet']);
- // Enable relation plugins in groups.
- $this->createPluginRelation(
- $group_type_1,
- 'group_media:document',
- [
- 'group_cardinality' => 0,
- 'entity_cardinality' => 1,
- 'use_creation_wizard' => FALSE,
- ]);
- $this->createPluginRelation(
- $group_type_2,
- 'group_media:document',
- [
- 'group_cardinality' => 0,
- 'entity_cardinality' => 1,
- 'use_creation_wizard' => FALSE,
- ]);
- $this->createPluginRelation(
- $group_type_2,
- 'group_media:spreadsheet',
- [
- 'group_cardinality' => 0,
- 'entity_cardinality' => 1,
- 'use_creation_wizard' => FALSE,
- ]);
+ // Enable relation plugins in groups.
+ $this->createPluginRelation(
+ $group_type_1,
+ 'group_media:document',
+ [
+ 'group_cardinality' => 0,
+ 'entity_cardinality' => 1,
+ 'use_creation_wizard' => FALSE,
+ ]);
+ $this->createPluginRelation(
+ $group_type_2,
+ 'group_media:document',
+ [
+ 'group_cardinality' => 0,
+ 'entity_cardinality' => 1,
+ 'use_creation_wizard' => FALSE,
+ ]);
+ $this->createPluginRelation(
+ $group_type_2,
+ 'group_media:spreadsheet',
+ [
+ 'group_cardinality' => 0,
+ 'entity_cardinality' => 1,
+ 'use_creation_wizard' => FALSE,
+ ]);
- // Check that permissions are generated for the groups.
- // Save current permissions.
- /** @var \Drupal\group\Access\GroupPermissionHandlerInterface $permission_handler */
- $permission_handler = \Drupal::service('group.permissions');
- $permissions_before_1 = $permission_handler->getPermissionsByGroupType($group_type_1);
- $permissions_before_2 = $permission_handler->getPermissionsByGroupType($group_type_2);
- $permissions_before_3 = $permission_handler->getPermissionsByGroupType($group_type_3);
+ // Check that permissions are generated for the groups.
+ // Save current permissions.
+ /** @var \Drupal\group\Access\GroupPermissionHandlerInterface $permission_handler */
+ $permission_handler = \Drupal::service('group.permissions');
+ $permissions_before_1 = $permission_handler->getPermissionsByGroupType($group_type_1);
+ $permissions_before_2 = $permission_handler->getPermissionsByGroupType($group_type_2);
+ $permissions_before_3 = $permission_handler->getPermissionsByGroupType($group_type_3);
- // Get permissions difference after enabling the module.
- $this->enableModules(['collabora_online_group']);
- $permission_handler = \Drupal::service('group.permissions');
- $permissions_after_1 = $permission_handler->getPermissionsByGroupType($group_type_1);
- $new_permissions_1 = array_diff_key($permissions_after_1, $permissions_before_1);
- ksort($new_permissions_1);
- $permissions_after_2 = $permission_handler->getPermissionsByGroupType($group_type_2);
- $new_permissions_2 = array_diff_key($permissions_after_2, $permissions_before_2);
- ksort($new_permissions_2);
- $permissions_after_3 = $permission_handler->getPermissionsByGroupType($group_type_3);
- $new_permissions_3 = array_diff_key($permissions_after_3, $permissions_before_3);
- ksort($new_permissions_3);
+ // Get permissions difference after enabling the module.
+ $this->enableModules(['collabora_online_group']);
+ $permission_handler = \Drupal::service('group.permissions');
+ $permissions_after_1 = $permission_handler->getPermissionsByGroupType($group_type_1);
+ $new_permissions_1 = array_diff_key($permissions_after_1, $permissions_before_1);
+ ksort($new_permissions_1);
+ $permissions_after_2 = $permission_handler->getPermissionsByGroupType($group_type_2);
+ $new_permissions_2 = array_diff_key($permissions_after_2, $permissions_before_2);
+ ksort($new_permissions_2);
+ $permissions_after_3 = $permission_handler->getPermissionsByGroupType($group_type_3);
+ $new_permissions_3 = array_diff_key($permissions_after_3, $permissions_before_3);
+ ksort($new_permissions_3);
- // The 'group_1' has only 'document' permissions.
- $this->assertSame(
- [
- 'edit any group_media:document in collabora' => 'Entity: Edit any media item in collabora',
- 'edit own group_media:document in collabora' => 'Entity: Edit own media item in collabora',
- 'preview group_media:document in collabora' => 'Entity: Preview published media item in collabora',
- 'preview own unpublished group_media:document in collabora' => 'Entity: Preview own unpublished media item in collabora',
- ],
- array_map(
- fn($permission) => (string) $permission['title'],
- $new_permissions_1,
- ));
- // The 'group_2' has 'document' and 'spreadsheet' permissions.
- $this->assertSame(
- [
- 'edit any group_media:document in collabora' => 'Entity: Edit any media item in collabora',
- 'edit any group_media:spreadsheet in collabora' => 'Entity: Edit any media item in collabora',
- 'edit own group_media:document in collabora' => 'Entity: Edit own media item in collabora',
- 'edit own group_media:spreadsheet in collabora' => 'Entity: Edit own media item in collabora',
- 'preview group_media:document in collabora' => 'Entity: Preview published media item in collabora',
- 'preview group_media:spreadsheet in collabora' => 'Entity: Preview published media item in collabora',
- 'preview own unpublished group_media:document in collabora' => 'Entity: Preview own unpublished media item in collabora',
- 'preview own unpublished group_media:spreadsheet in collabora' => 'Entity: Preview own unpublished media item in collabora',
- ],
- array_map(
- fn($permission) => (string) $permission['title'],
- $new_permissions_2,
- ));
- // The 'group_3' doesn't have any new permissions.
- $this->assertSame(
- [],
- array_map(
- fn($permission) => (string) $permission['title'],
- $new_permissions_3,
- ));
- }
+ // The 'group_1' has only 'document' permissions.
+ $this->assertSame(
+ [
+ 'edit any group_media:document in collabora' => 'Entity: Edit any media item in collabora',
+ 'edit own group_media:document in collabora' => 'Entity: Edit own media item in collabora',
+ 'preview group_media:document in collabora' => 'Entity: Preview published media item in collabora',
+ 'preview own unpublished group_media:document in collabora' => 'Entity: Preview own unpublished media item in collabora',
+ ],
+ array_map(
+ fn($permission) => (string) $permission['title'],
+ $new_permissions_1,
+ ));
+ // The 'group_2' has 'document' and 'spreadsheet' permissions.
+ $this->assertSame(
+ [
+ 'edit any group_media:document in collabora' => 'Entity: Edit any media item in collabora',
+ 'edit any group_media:spreadsheet in collabora' => 'Entity: Edit any media item in collabora',
+ 'edit own group_media:document in collabora' => 'Entity: Edit own media item in collabora',
+ 'edit own group_media:spreadsheet in collabora' => 'Entity: Edit own media item in collabora',
+ 'preview group_media:document in collabora' => 'Entity: Preview published media item in collabora',
+ 'preview group_media:spreadsheet in collabora' => 'Entity: Preview published media item in collabora',
+ 'preview own unpublished group_media:document in collabora' => 'Entity: Preview own unpublished media item in collabora',
+ 'preview own unpublished group_media:spreadsheet in collabora' => 'Entity: Preview own unpublished media item in collabora',
+ ],
+ array_map(
+ fn($permission) => (string) $permission['title'],
+ $new_permissions_2,
+ ));
+ // The 'group_3' doesn't have any new permissions.
+ $this->assertSame(
+ [],
+ array_map(
+ fn($permission) => (string) $permission['title'],
+ $new_permissions_3,
+ ));
+ }
}
diff --git a/phpcs.xml b/phpcs.xml
index b98b14a9..a0eca955 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -9,13 +9,6 @@
.
-
-
-
-
-
-
-
diff --git a/src/CollaboraMediaPermissions.php b/src/CollaboraMediaPermissions.php
index 2eecaf31..77541d85 100644
--- a/src/CollaboraMediaPermissions.php
+++ b/src/CollaboraMediaPermissions.php
@@ -27,68 +27,68 @@
*/
class CollaboraMediaPermissions implements ContainerInjectionInterface {
- use AutowireTrait;
- use BundlePermissionHandlerTrait;
- use StringTranslationTrait;
+ use AutowireTrait;
+ use BundlePermissionHandlerTrait;
+ use StringTranslationTrait;
- /**
- * Constructor.
- *
- * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
- * The entity type manager service.
- */
- public function __construct(
- protected readonly EntityTypeManagerInterface $entityTypeManager,
- ) {}
+ /**
+ * Constructor.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
+ * The entity type manager service.
+ */
+ public function __construct(
+ protected readonly EntityTypeManagerInterface $entityTypeManager,
+ ) {}
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container) {
- return new static($container->get('entity_type.manager'));
- }
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ return new static($container->get('entity_type.manager'));
+ }
- /**
- * Returns an array of media type permissions.
- *
- * @return array
- * The media type permissions.
- *
- * @see \Drupal\user\PermissionHandlerInterface::getPermissions()
- */
- public function mediaTypePermissions(): array {
- // Generate media permissions for all media types.
- $media_types = $this->entityTypeManager->getStorage('media_type')->loadMultiple();
- return $this->generatePermissions($media_types, [$this, 'buildPermissions']);
- }
+ /**
+ * Returns an array of media type permissions.
+ *
+ * @return array
+ * The media type permissions.
+ *
+ * @see \Drupal\user\PermissionHandlerInterface::getPermissions()
+ */
+ public function mediaTypePermissions(): array {
+ // Generate media permissions for all media types.
+ $media_types = $this->entityTypeManager->getStorage('media_type')->loadMultiple();
+ return $this->generatePermissions($media_types, [$this, 'buildPermissions']);
+ }
- /**
- * Returns a list of permissions for a given media type.
- *
- * @param \Drupal\media\MediaTypeInterface $type
- * The media type.
- *
- * @return array
- * An associative array of permission names and descriptions.
- */
- protected function buildPermissions(MediaTypeInterface $type) {
- $type_id = $type->id();
- $type_params = ['%type_name' => $type->label()];
+ /**
+ * Returns a list of permissions for a given media type.
+ *
+ * @param \Drupal\media\MediaTypeInterface $type
+ * The media type.
+ *
+ * @return array
+ * An associative array of permission names and descriptions.
+ */
+ protected function buildPermissions(MediaTypeInterface $type) {
+ $type_id = $type->id();
+ $type_params = ['%type_name' => $type->label()];
- return [
- "preview $type_id in collabora" => [
- 'title' => $this->t('%type_name: Preview published media file in Collabora', $type_params),
- ],
- "preview own unpublished $type_id in collabora" => [
- 'title' => $this->t('%type_name: Preview own unpublished media file in Collabora', $type_params),
- ],
- "edit own $type_id in collabora" => [
- 'title' => $this->t('%type_name: Edit own media file in Collabora', $type_params),
- ],
- "edit any $type_id in collabora" => [
- 'title' => $this->t('%type_name: Edit any media file in Collabora', $type_params),
- ],
- ];
- }
+ return [
+ "preview $type_id in collabora" => [
+ 'title' => $this->t('%type_name: Preview published media file in Collabora', $type_params),
+ ],
+ "preview own unpublished $type_id in collabora" => [
+ 'title' => $this->t('%type_name: Preview own unpublished media file in Collabora', $type_params),
+ ],
+ "edit own $type_id in collabora" => [
+ 'title' => $this->t('%type_name: Edit own media file in Collabora', $type_params),
+ ],
+ "edit any $type_id in collabora" => [
+ 'title' => $this->t('%type_name: Edit any media file in Collabora', $type_params),
+ ],
+ ];
+ }
}
diff --git a/src/Controller/ViewerController.php b/src/Controller/ViewerController.php
index 083b9166..951f0ffd 100644
--- a/src/Controller/ViewerController.php
+++ b/src/Controller/ViewerController.php
@@ -24,68 +24,68 @@
*/
class ViewerController extends ControllerBase {
- /**
- * The renderer service.
- *
- * @var \Drupal\Core\Render\RendererInterface
- */
- private $renderer;
+ /**
+ * The renderer service.
+ *
+ * @var \Drupal\Core\Render\RendererInterface
+ */
+ private $renderer;
- /**
- * The controller constructor.
- *
- * @param \Drupal\Core\Render\RendererInterface $renderer
- * The renderer service.
- */
- public function __construct(RendererInterface $renderer) {
- $this->renderer = $renderer;
- }
+ /**
+ * The controller constructor.
+ *
+ * @param \Drupal\Core\Render\RendererInterface $renderer
+ * The renderer service.
+ */
+ public function __construct(RendererInterface $renderer) {
+ $this->renderer = $renderer;
+ }
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container): self {
- return new self(
- $container->get('renderer'),
- );
- }
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container): self {
+ return new self(
+ $container->get('renderer'),
+ );
+ }
- /**
- * Returns a raw page for the iframe embed.
- *
- * @param \Drupal\media\Entity\Media $media
- * Media entity.
- * @param bool $edit
- * TRUE to open Collabora Online in edit mode.
- * FALSE to open Collabora Online in readonly mode.
- *
- * @return \Symfony\Component\HttpFoundation\Response
- * Response suitable for iframe, without the usual page decorations.
- */
- public function editor(Media $media, $edit = FALSE) {
- $options = [
- 'closebutton' => 'true',
- ];
+ /**
+ * Returns a raw page for the iframe embed.
+ *
+ * @param \Drupal\media\Entity\Media $media
+ * Media entity.
+ * @param bool $edit
+ * TRUE to open Collabora Online in edit mode.
+ * FALSE to open Collabora Online in readonly mode.
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ * Response suitable for iframe, without the usual page decorations.
+ */
+ public function editor(Media $media, $edit = FALSE) {
+ $options = [
+ 'closebutton' => 'true',
+ ];
- $render_array = CoolUtils::getViewerRender($media, $edit, $options);
+ $render_array = CoolUtils::getViewerRender($media, $edit, $options);
- if (!$render_array || array_key_exists('error', $render_array)) {
- $error_msg = 'Viewer error: ' . ($render_array ? $render_array['error'] : 'NULL');
- \Drupal::logger('cool')->error($error_msg);
- return new Response(
- $error_msg,
- Response::HTTP_BAD_REQUEST,
- ['content-type' => 'text/plain']
- );
- }
+ if (!$render_array || array_key_exists('error', $render_array)) {
+ $error_msg = 'Viewer error: ' . ($render_array ? $render_array['error'] : 'NULL');
+ \Drupal::logger('cool')->error($error_msg);
+ return new Response(
+ $error_msg,
+ Response::HTTP_BAD_REQUEST,
+ ['content-type' => 'text/plain']
+ );
+ }
- $render_array['#theme'] = 'collabora_online_full';
- $render_array['#attached']['library'][] = 'collabora_online/cool.frame';
+ $render_array['#theme'] = 'collabora_online_full';
+ $render_array['#attached']['library'][] = 'collabora_online/cool.frame';
- $response = new Response();
- $response->setContent($this->renderer->renderRoot($render_array));
+ $response = new Response();
+ $response->setContent($this->renderer->renderRoot($render_array));
- return $response;
- }
+ return $response;
+ }
}
diff --git a/src/Controller/WopiController.php b/src/Controller/WopiController.php
index 103316c8..1fca5d7b 100644
--- a/src/Controller/WopiController.php
+++ b/src/Controller/WopiController.php
@@ -26,256 +26,256 @@
*/
class WopiController extends ControllerBase {
- /**
- * Creates a failure response that is understood by Collabora.
- *
- * @return \Symfony\Component\HttpFoundation\Response
- * Response object.
- */
- public static function permissionDenied(): Response {
- return new Response(
- 'Authentication failed.',
- Response::HTTP_FORBIDDEN,
- ['content-type' => 'text/plain'],
- );
+ /**
+ * Creates a failure response that is understood by Collabora.
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ * Response object.
+ */
+ public static function permissionDenied(): Response {
+ return new Response(
+ 'Authentication failed.',
+ Response::HTTP_FORBIDDEN,
+ ['content-type' => 'text/plain'],
+ );
+ }
+
+ /**
+ * Handles the WOPI 'info' request for a media entity.
+ *
+ * @param string $id
+ * Media id from url.
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * Request object with query parameters.
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ * The response with file contents.
+ */
+ public function wopiCheckFileInfo(string $id, Request $request) {
+ $token = $request->query->get('access_token');
+
+ $jwt_payload = CoolUtils::verifyTokenForId($token, $id);
+ if ($jwt_payload == NULL) {
+ return static::permissionDenied();
}
- /**
- * Handles the WOPI 'info' request for a media entity.
- *
- * @param string $id
- * Media id from url.
- * @param \Symfony\Component\HttpFoundation\Request $request
- * Request object with query parameters.
- *
- * @return \Symfony\Component\HttpFoundation\Response
- * The response with file contents.
- */
- public function wopiCheckFileInfo(string $id, Request $request) {
- $token = $request->query->get('access_token');
-
- $jwt_payload = CoolUtils::verifyTokenForId($token, $id);
- if ($jwt_payload == NULL) {
- return static::permissionDenied();
- }
-
- /** @var \Drupal\media\MediaInterface|null $media */
- $media = \Drupal::entityTypeManager()->getStorage('media')->load($id);
- if (!$media) {
- return static::permissionDenied();
- }
-
- $file = CoolUtils::getFileById($id);
- $mtime = date_create_immutable_from_format('U', $file->getChangedTime());
- // @todo What if the uid in the payload is not set?
- // @todo What if $user is NULL?
- $user = User::load($jwt_payload->uid);
- $can_write = $jwt_payload->wri;
-
- if ($can_write && !$media->access('edit in collabora', $user)) {
- \Drupal::logger('cool')->error('Token and user permissions do not match.');
- return static::permissionDenied();
- }
-
- $payload = [
- 'BaseFileName' => $file->getFilename(),
- 'Size' => $file->getSize(),
- 'LastModifiedTime' => $mtime->format('c'),
- 'UserId' => $jwt_payload->uid,
- 'UserFriendlyName' => $user->getDisplayName(),
- 'UserExtraInfo' => [
- 'mail' => $user->getEmail(),
- ],
- 'UserCanWrite' => $can_write,
- 'IsAdminUser' => $user->hasPermission('administer collabora instance'),
- 'IsAnonymousUser' => $user->isAnonymous(),
- ];
-
- $user_picture = $user->user_picture?->entity;
- if ($user_picture) {
- /** @var \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator */
- $file_url_generator = \Drupal::service('file_url_generator');
- $payload['UserExtraInfo']['avatar'] = $file_url_generator->generateAbsoluteString($user_picture->getFileUri());
- }
-
- $jsonPayload = json_encode($payload);
-
- $response = new Response(
- $jsonPayload,
- Response::HTTP_OK,
- ['content-type' => 'application/json']
- );
- return $response;
+ /** @var \Drupal\media\MediaInterface|null $media */
+ $media = \Drupal::entityTypeManager()->getStorage('media')->load($id);
+ if (!$media) {
+ return static::permissionDenied();
}
- /**
- * Handles the wopi "content" request for a media entity.
- *
- * @param string $id
- * Media id from url.
- * @param \Symfony\Component\HttpFoundation\Request $request
- * Request object with query parameters.
- *
- * @return \Symfony\Component\HttpFoundation\Response
- * The response with file contents.
- */
- public function wopiGetFile(string $id, Request $request) {
- $token = $request->query->get('access_token');
-
- $jwt_payload = CoolUtils::verifyTokenForId($token, $id);
- if ($jwt_payload == NULL) {
- return static::permissionDenied();
- }
-
- $user = User::load($jwt_payload->uid);
- $accountSwitcher = \Drupal::service('account_switcher');
- $accountSwitcher->switchTo($user);
-
- $file = CoolUtils::getFileById($id);
- $mimetype = $file->getMimeType();
-
- $response = new BinaryFileResponse(
- $file->getFileUri(),
- Response::HTTP_OK,
- ['content-type' => $mimetype]
- );
- $accountSwitcher->switchBack();
- return $response;
+ $file = CoolUtils::getFileById($id);
+ $mtime = date_create_immutable_from_format('U', $file->getChangedTime());
+ // @todo What if the uid in the payload is not set?
+ // @todo What if $user is NULL?
+ $user = User::load($jwt_payload->uid);
+ $can_write = $jwt_payload->wri;
+
+ if ($can_write && !$media->access('edit in collabora', $user)) {
+ \Drupal::logger('cool')->error('Token and user permissions do not match.');
+ return static::permissionDenied();
}
- /**
- * Handles the wopi "save" request for a media entity.
- *
- * @param string $id
- * Media id from url.
- * @param \Symfony\Component\HttpFoundation\Request $request
- * Request object with headers, query parameters and payload.
- *
- * @return \Symfony\Component\HttpFoundation\Response
- * The response.
- */
- public function wopiPutFile(string $id, Request $request) {
- $token = $request->query->get('access_token');
- $timestamp = $request->headers->get('x-cool-wopi-timestamp');
- $modified_by_user = $request->headers->get('x-cool-wopi-ismodifiedbyuser') == 'true';
- $autosave = $request->headers->get('x-cool-wopi-isautosave') == 'true';
- $exitsave = $request->headers->get('x-cool-wopi-isexitsave') == 'true';
-
- $jwt_payload = CoolUtils::verifyTokenForId($token, $id);
- if ($jwt_payload == NULL || !$jwt_payload->wri) {
- return static::permissionDenied();
- }
-
- $fs = \Drupal::service('file_system');
-
- $media = \Drupal::entityTypeManager()->getStorage('media')->load($id);
- $user = User::load($jwt_payload->uid);
-
- $accountSwitcher = \Drupal::service('account_switcher');
- $accountSwitcher->switchTo($user);
-
- $file = CoolUtils::getFile($media);
-
- if ($timestamp) {
- $wopi_stamp = date_create_immutable_from_format(\DateTimeInterface::ISO8601, $timestamp);
- $file_stamp = date_create_immutable_from_format('U', $file->getChangedTime());
-
- if ($wopi_stamp != $file_stamp) {
- \Drupal::logger('cool')->error('Conflict saving file ' . $id . ' wopi: ' . $wopi_stamp->format('c') . ' differs from file: ' . $file_stamp->format('c'));
-
- return new Response(
- json_encode(['COOLStatusCode' => 1010]),
- Response::HTTP_CONFLICT,
- ['content-type' => 'application/json'],
- );
- }
- }
-
- $dir = $fs->dirname($file->getFileUri());
- $dest = $dir . '/' . $file->getFilename();
-
- $content = $request->getContent();
- $owner_id = $file->getOwnerId();
- $uri = $fs->saveData($content, $dest, FileSystemInterface::EXISTS_RENAME);
-
- $file = File::create(['uri' => $uri]);
- $file->setOwnerId($owner_id);
- if (is_file($dest)) {
- $file->setFilename($fs->basename($dest));
- }
- $file->setPermanent();
- $file->setSize(strlen($content));
- $file->save();
- $mtime = date_create_immutable_from_format('U', $file->getChangedTime());
-
- CoolUtils::setMediaSource($media, $file);
- $media->setRevisionUser($user);
- $media->setRevisionCreationTime(\Drupal::service('datetime.time')->getRequestTime());
-
- $save_reason = 'Saved by Collabora Online';
- $reasons = [];
- if ($modified_by_user) {
- $reasons[] = 'Modified by user';
- }
- if ($autosave) {
- $reasons[] = 'Autosaved';
- }
- if ($exitsave) {
- $reasons[] = 'Save on Exit';
- }
- if (count($reasons) > 0) {
- $save_reason .= ' (' . implode(', ', $reasons) . ')';
- }
- \Drupal::logger('cool')->error('Save reason: ' . $save_reason);
- $media->setRevisionLogMessage($save_reason);
- $media->save();
-
- $payload = json_encode([
- 'LastModifiedTime' => $mtime->format('c'),
- ]);
-
- $response = new Response(
- $payload,
- Response::HTTP_OK,
- ['content-type' => 'application/json']
- );
+ $payload = [
+ 'BaseFileName' => $file->getFilename(),
+ 'Size' => $file->getSize(),
+ 'LastModifiedTime' => $mtime->format('c'),
+ 'UserId' => $jwt_payload->uid,
+ 'UserFriendlyName' => $user->getDisplayName(),
+ 'UserExtraInfo' => [
+ 'mail' => $user->getEmail(),
+ ],
+ 'UserCanWrite' => $can_write,
+ 'IsAdminUser' => $user->hasPermission('administer collabora instance'),
+ 'IsAnonymousUser' => $user->isAnonymous(),
+ ];
+
+ $user_picture = $user->user_picture?->entity;
+ if ($user_picture) {
+ /** @var \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator */
+ $file_url_generator = \Drupal::service('file_url_generator');
+ $payload['UserExtraInfo']['avatar'] = $file_url_generator->generateAbsoluteString($user_picture->getFileUri());
+ }
- $accountSwitcher->switchBack();
- return $response;
+ $jsonPayload = json_encode($payload);
+
+ $response = new Response(
+ $jsonPayload,
+ Response::HTTP_OK,
+ ['content-type' => 'application/json']
+ );
+ return $response;
+ }
+
+ /**
+ * Handles the wopi "content" request for a media entity.
+ *
+ * @param string $id
+ * Media id from url.
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * Request object with query parameters.
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ * The response with file contents.
+ */
+ public function wopiGetFile(string $id, Request $request) {
+ $token = $request->query->get('access_token');
+
+ $jwt_payload = CoolUtils::verifyTokenForId($token, $id);
+ if ($jwt_payload == NULL) {
+ return static::permissionDenied();
}
- /**
- * The WOPI entry point.
- *
- * @param string $action
- * One of 'info', 'content' or 'save', depending with path is visited.
- * @param string $id
- * Media id from url.
- * @param \Symfony\Component\HttpFoundation\Request $request
- * Request object for headers and query parameters.
- *
- * @return \Symfony\Component\HttpFoundation\Response
- * Response to be consumed by Collabora Online.
- */
- public function wopi(string $action, string $id, Request $request) {
- $returnCode = Response::HTTP_BAD_REQUEST;
- switch ($action) {
- case 'info':
- return $this->wopiCheckFileInfo($id, $request);
-
- case 'content':
- return $this->wopiGetFile($id, $request);
-
- case 'save':
- return $this->wopiPutFile($id, $request);
- }
-
- $response = new Response(
- 'Invalid WOPI action ' . $action,
- $returnCode,
- ['content-type' => 'text/plain']
+ $user = User::load($jwt_payload->uid);
+ $accountSwitcher = \Drupal::service('account_switcher');
+ $accountSwitcher->switchTo($user);
+
+ $file = CoolUtils::getFileById($id);
+ $mimetype = $file->getMimeType();
+
+ $response = new BinaryFileResponse(
+ $file->getFileUri(),
+ Response::HTTP_OK,
+ ['content-type' => $mimetype]
+ );
+ $accountSwitcher->switchBack();
+ return $response;
+ }
+
+ /**
+ * Handles the wopi "save" request for a media entity.
+ *
+ * @param string $id
+ * Media id from url.
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * Request object with headers, query parameters and payload.
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ * The response.
+ */
+ public function wopiPutFile(string $id, Request $request) {
+ $token = $request->query->get('access_token');
+ $timestamp = $request->headers->get('x-cool-wopi-timestamp');
+ $modified_by_user = $request->headers->get('x-cool-wopi-ismodifiedbyuser') == 'true';
+ $autosave = $request->headers->get('x-cool-wopi-isautosave') == 'true';
+ $exitsave = $request->headers->get('x-cool-wopi-isexitsave') == 'true';
+
+ $jwt_payload = CoolUtils::verifyTokenForId($token, $id);
+ if ($jwt_payload == NULL || !$jwt_payload->wri) {
+ return static::permissionDenied();
+ }
+
+ $fs = \Drupal::service('file_system');
+
+ $media = \Drupal::entityTypeManager()->getStorage('media')->load($id);
+ $user = User::load($jwt_payload->uid);
+
+ $accountSwitcher = \Drupal::service('account_switcher');
+ $accountSwitcher->switchTo($user);
+
+ $file = CoolUtils::getFile($media);
+
+ if ($timestamp) {
+ $wopi_stamp = date_create_immutable_from_format(\DateTimeInterface::ISO8601, $timestamp);
+ $file_stamp = date_create_immutable_from_format('U', $file->getChangedTime());
+
+ if ($wopi_stamp != $file_stamp) {
+ \Drupal::logger('cool')->error('Conflict saving file ' . $id . ' wopi: ' . $wopi_stamp->format('c') . ' differs from file: ' . $file_stamp->format('c'));
+
+ return new Response(
+ json_encode(['COOLStatusCode' => 1010]),
+ Response::HTTP_CONFLICT,
+ ['content-type' => 'application/json'],
);
- return $response;
+ }
+ }
+
+ $dir = $fs->dirname($file->getFileUri());
+ $dest = $dir . '/' . $file->getFilename();
+
+ $content = $request->getContent();
+ $owner_id = $file->getOwnerId();
+ $uri = $fs->saveData($content, $dest, FileSystemInterface::EXISTS_RENAME);
+
+ $file = File::create(['uri' => $uri]);
+ $file->setOwnerId($owner_id);
+ if (is_file($dest)) {
+ $file->setFilename($fs->basename($dest));
}
+ $file->setPermanent();
+ $file->setSize(strlen($content));
+ $file->save();
+ $mtime = date_create_immutable_from_format('U', $file->getChangedTime());
+
+ CoolUtils::setMediaSource($media, $file);
+ $media->setRevisionUser($user);
+ $media->setRevisionCreationTime(\Drupal::service('datetime.time')->getRequestTime());
+
+ $save_reason = 'Saved by Collabora Online';
+ $reasons = [];
+ if ($modified_by_user) {
+ $reasons[] = 'Modified by user';
+ }
+ if ($autosave) {
+ $reasons[] = 'Autosaved';
+ }
+ if ($exitsave) {
+ $reasons[] = 'Save on Exit';
+ }
+ if (count($reasons) > 0) {
+ $save_reason .= ' (' . implode(', ', $reasons) . ')';
+ }
+ \Drupal::logger('cool')->error('Save reason: ' . $save_reason);
+ $media->setRevisionLogMessage($save_reason);
+ $media->save();
+
+ $payload = json_encode([
+ 'LastModifiedTime' => $mtime->format('c'),
+ ]);
+
+ $response = new Response(
+ $payload,
+ Response::HTTP_OK,
+ ['content-type' => 'application/json']
+ );
+
+ $accountSwitcher->switchBack();
+ return $response;
+ }
+
+ /**
+ * The WOPI entry point.
+ *
+ * @param string $action
+ * One of 'info', 'content' or 'save', depending with path is visited.
+ * @param string $id
+ * Media id from url.
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * Request object for headers and query parameters.
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ * Response to be consumed by Collabora Online.
+ */
+ public function wopi(string $action, string $id, Request $request) {
+ $returnCode = Response::HTTP_BAD_REQUEST;
+ switch ($action) {
+ case 'info':
+ return $this->wopiCheckFileInfo($id, $request);
+
+ case 'content':
+ return $this->wopiGetFile($id, $request);
+
+ case 'save':
+ return $this->wopiPutFile($id, $request);
+ }
+
+ $response = new Response(
+ 'Invalid WOPI action ' . $action,
+ $returnCode,
+ ['content-type' => 'text/plain']
+ );
+ return $response;
+ }
}
diff --git a/src/Cool/CoolRequest.php b/src/Cool/CoolRequest.php
index 631457aa..c93f906d 100644
--- a/src/Cool/CoolRequest.php
+++ b/src/Cool/CoolRequest.php
@@ -22,22 +22,22 @@
* The full contents of discovery.xml, or FALSE on failure.
*/
function getDiscovery($server) {
- $discovery_url = $server . '/hosting/discovery';
-
- $default_config = \Drupal::config('collabora_online.settings');
- if ($default_config === NULL) {
- return FALSE;
- }
- $disable_checks = (bool) $default_config->get('cool')['disable_cert_check'];
-
- $stream_context = stream_context_create([
- 'ssl' => [
- 'verify_peer' => !$disable_checks,
- 'verify_peer_name' => !$disable_checks,
- ],
- ]);
- $res = file_get_contents($discovery_url, FALSE, $stream_context);
- return $res;
+ $discovery_url = $server . '/hosting/discovery';
+
+ $default_config = \Drupal::config('collabora_online.settings');
+ if ($default_config === NULL) {
+ return FALSE;
+ }
+ $disable_checks = (bool) $default_config->get('cool')['disable_cert_check'];
+
+ $stream_context = stream_context_create([
+ 'ssl' => [
+ 'verify_peer' => !$disable_checks,
+ 'verify_peer_name' => !$disable_checks,
+ ],
+ ]);
+ $res = file_get_contents($discovery_url, FALSE, $stream_context);
+ return $res;
}
/**
@@ -54,14 +54,14 @@ function getDiscovery($server) {
* was found for the given MIME type.
*/
function getWopiSrcUrl($discovery_parsed, $mimetype) {
- if ($discovery_parsed === NULL || $discovery_parsed == FALSE) {
- return NULL;
- }
- $result = $discovery_parsed->xpath(sprintf('/wopi-discovery/net-zone/app[@name=\'%s\']/action', $mimetype));
- if ($result && count($result) > 0) {
- return $result[0]['urlsrc'];
- }
+ if ($discovery_parsed === NULL || $discovery_parsed == FALSE) {
return NULL;
+ }
+ $result = $discovery_parsed->xpath(sprintf('/wopi-discovery/net-zone/app[@name=\'%s\']/action', $mimetype));
+ if ($result && count($result) > 0) {
+ return $result[0]['urlsrc'];
+ }
+ return NULL;
}
/**
@@ -78,8 +78,8 @@ function getWopiSrcUrl($discovery_parsed, $mimetype) {
* @see str_starts_with()
*/
function strStartsWith($s, $ss) {
- $res = strrpos($s, $ss);
- return !is_bool($res) && $res == 0;
+ $res = strrpos($s, $ss);
+ return !is_bool($res) && $res == 0;
}
/**
@@ -87,94 +87,94 @@ function strStartsWith($s, $ss) {
*/
class CoolRequest {
- /**
- * Error code from last attempt to fetch the client WOPI url.
- *
- * @var int
- */
- private $error_code;
-
- const ERROR_MSG = [
- 0 => 'Success',
- 101 => 'GET Request not found.',
- 201 => 'Collabora Online server address is not valid.',
- 202 => 'Collabora Online server address scheme does not match the current page url scheme.',
- 203 => 'Not able to retrieve the discovery.xml file from the Collabora Online server.',
- 102 => 'The retrieved discovery.xml file is not a valid XML file.',
- 103 => 'The requested mime type is not handled.',
- 204 => 'Warning! You have to specify the scheme protocol too (http|https) for the server address.',
- ];
-
- /**
- * The WOPI url that was last fetched, or '' as initial value.
- *
- * @var int
- */
- private $wopi_src;
-
- /**
- * Constructor.
- */
- public function __construct() {
- $this->error_code = 0;
- $this->wopi_src = '';
+ /**
+ * Error code from last attempt to fetch the client WOPI url.
+ *
+ * @var int
+ */
+ private $error_code;
+
+ const ERROR_MSG = [
+ 0 => 'Success',
+ 101 => 'GET Request not found.',
+ 201 => 'Collabora Online server address is not valid.',
+ 202 => 'Collabora Online server address scheme does not match the current page url scheme.',
+ 203 => 'Not able to retrieve the discovery.xml file from the Collabora Online server.',
+ 102 => 'The retrieved discovery.xml file is not a valid XML file.',
+ 103 => 'The requested mime type is not handled.',
+ 204 => 'Warning! You have to specify the scheme protocol too (http|https) for the server address.',
+ ];
+
+ /**
+ * The WOPI url that was last fetched, or '' as initial value.
+ *
+ * @var int
+ */
+ private $wopi_src;
+
+ /**
+ * Constructor.
+ */
+ public function __construct() {
+ $this->error_code = 0;
+ $this->wopi_src = '';
+ }
+
+ /**
+ * Gets an error string from the last attempt to fetch the WOPI url.
+ *
+ * @return string
+ * Error string containing int error code and a message.
+ */
+ public function errorString() {
+ return $this->error_code . ': ' . static::ERROR_MSG[$this->error_code];
+ }
+
+ /**
+ * Gets the URL for the WOPI client.
+ *
+ * @return string|null
+ * The WOPI client url, or NULL on failure.
+ */
+ public function getWopiClientURL() {
+ $_HOST_SCHEME = isset($_SERVER['HTTPS']) ? 'https' : 'http';
+ $default_config = \Drupal::config('collabora_online.settings');
+ $wopi_client_server = $default_config->get('cool')['server'];
+ if (!$wopi_client_server) {
+ $this->error_code = 201;
+ return NULL;
}
+ $wopi_client_server = trim($wopi_client_server);
- /**
- * Gets an error string from the last attempt to fetch the WOPI url.
- *
- * @return string
- * Error string containing int error code and a message.
- */
- public function errorString() {
- return $this->error_code . ': ' . static::ERROR_MSG[$this->error_code];
+ if (!strStartsWith($wopi_client_server, 'http')) {
+ $this->error_code = 204;
+ return NULL;
}
- /**
- * Gets the URL for the WOPI client.
- *
- * @return string|null
- * The WOPI client url, or NULL on failure.
- */
- public function getWopiClientURL() {
- $_HOST_SCHEME = isset($_SERVER['HTTPS']) ? 'https' : 'http';
- $default_config = \Drupal::config('collabora_online.settings');
- $wopi_client_server = $default_config->get('cool')['server'];
- if (!$wopi_client_server) {
- $this->error_code = 201;
- return NULL;
- }
- $wopi_client_server = trim($wopi_client_server);
-
- if (!strStartsWith($wopi_client_server, 'http')) {
- $this->error_code = 204;
- return NULL;
- }
-
- if (!strStartsWith($wopi_client_server, $_HOST_SCHEME . '://')) {
- $this->error_code = 202;
- return NULL;
- }
-
- $discovery = getDiscovery($wopi_client_server);
- if ($discovery === FALSE) {
- $this->error_code = 203;
- return NULL;
- }
-
- $discovery_parsed = simplexml_load_string($discovery);
- if (!$discovery_parsed) {
- $this->error_code = 102;
- return NULL;
- }
-
- $this->wopi_src = strval(getWopiSrcUrl($discovery_parsed, 'text/plain')[0]);
- if (!$this->wopi_src) {
- $this->error_code = 103;
- return NULL;
- }
-
- return $this->wopi_src;
+ if (!strStartsWith($wopi_client_server, $_HOST_SCHEME . '://')) {
+ $this->error_code = 202;
+ return NULL;
}
+ $discovery = getDiscovery($wopi_client_server);
+ if ($discovery === FALSE) {
+ $this->error_code = 203;
+ return NULL;
+ }
+
+ $discovery_parsed = simplexml_load_string($discovery);
+ if (!$discovery_parsed) {
+ $this->error_code = 102;
+ return NULL;
+ }
+
+ $this->wopi_src = strval(getWopiSrcUrl($discovery_parsed, 'text/plain')[0]);
+ if (!$this->wopi_src) {
+ $this->error_code = 103;
+ return NULL;
+ }
+
+ return $this->wopi_src;
+ }
+
}
diff --git a/src/Cool/CoolUtils.php b/src/Cool/CoolUtils.php
index f8c4b8e3..f1a548b0 100644
--- a/src/Cool/CoolUtils.php
+++ b/src/Cool/CoolUtils.php
@@ -23,261 +23,261 @@
*/
class CoolUtils {
- /**
- * Gets the file referenced by a media entity.
- *
- * @param \Drupal\media\Entity\Media $media
- * The media entity.
- *
- * @return \Drupal\file\FileInterface|null
- * The file entity, or NULL if not found.
- */
- public static function getFile(Media $media) {
- $fid = $media->getSource()->getSourceFieldValue($media);
- $file = File::load($fid);
+ /**
+ * Gets the file referenced by a media entity.
+ *
+ * @param \Drupal\media\Entity\Media $media
+ * The media entity.
+ *
+ * @return \Drupal\file\FileInterface|null
+ * The file entity, or NULL if not found.
+ */
+ public static function getFile(Media $media) {
+ $fid = $media->getSource()->getSourceFieldValue($media);
+ $file = File::load($fid);
- return $file;
- }
+ return $file;
+ }
- /**
- * Gets a file based on the media id.
- *
- * @param int|string $id
- * Media id which might be in strong form like '123'.
- *
- * @return \Drupal\file\FileInterface|null
- * File referenced by the media entity, or NULL if not found.
- */
- public static function getFileById($id) {
- /** @var \Drupal\media\MediaInterface|null $media */
- $media = \Drupal::entityTypeManager()->getStorage('media')->load($id);
- return CoolUtils::getFile($media);
- }
+ /**
+ * Gets a file based on the media id.
+ *
+ * @param int|string $id
+ * Media id which might be in strong form like '123'.
+ *
+ * @return \Drupal\file\FileInterface|null
+ * File referenced by the media entity, or NULL if not found.
+ */
+ public static function getFileById($id) {
+ /** @var \Drupal\media\MediaInterface|null $media */
+ $media = \Drupal::entityTypeManager()->getStorage('media')->load($id);
+ return CoolUtils::getFile($media);
+ }
- /**
- * Sets the file entity reference for a media entity.
- *
- * @param \Drupal\media\Entity\Media $media
- * Media entity to be modified.
- * @param \Drupal\file\Entity\File $source
- * File entity to reference.
- */
- public static function setMediaSource(Media $media, File $source) {
- $name = $media->getSource()->getSourceFieldDefinition($media->bundle->entity)->getName();
- $media->set($name, $source);
- }
+ /**
+ * Sets the file entity reference for a media entity.
+ *
+ * @param \Drupal\media\Entity\Media $media
+ * Media entity to be modified.
+ * @param \Drupal\file\Entity\File $source
+ * File entity to reference.
+ */
+ public static function setMediaSource(Media $media, File $source) {
+ $name = $media->getSource()->getSourceFieldDefinition($media->bundle->entity)->getName();
+ $media->set($name, $source);
+ }
- /**
- * Obtains the signing key from the key storage.
- *
- * @return string
- * The key value.
- */
- public static function getKey() {
- $default_config = \Drupal::config('collabora_online.settings');
- $key_id = $default_config->get('cool')['key_id'];
+ /**
+ * Obtains the signing key from the key storage.
+ *
+ * @return string
+ * The key value.
+ */
+ public static function getKey() {
+ $default_config = \Drupal::config('collabora_online.settings');
+ $key_id = $default_config->get('cool')['key_id'];
- $key = \Drupal::service('key.repository')->getKey($key_id)->getKeyValue();
- return $key;
- }
+ $key = \Drupal::service('key.repository')->getKey($key_id)->getKeyValue();
+ return $key;
+ }
- /**
- * Decodes and verifies a JWT token.
- *
- * Verification include:
- * - matching $id with fid in the payload
- * - verifying the expiration.
- *
- * @param string $token
- * The token to verify.
- * @param int|string $id
- * Media id for which the token was created.
- * This could be in string form like '123'.
- *
- * @return \stdClass|null
- * Data decoded from the token, or NULL on failure or if the token has
- * expired.
- */
- public static function verifyTokenForId(
- #[\SensitiveParameter]
- string $token,
- $id,
- ) {
- $key = static::getKey();
- try {
- $payload = JWT::decode($token, new Key($key, 'HS256'));
+ /**
+ * Decodes and verifies a JWT token.
+ *
+ * Verification include:
+ * - matching $id with fid in the payload
+ * - verifying the expiration.
+ *
+ * @param string $token
+ * The token to verify.
+ * @param int|string $id
+ * Media id for which the token was created.
+ * This could be in string form like '123'.
+ *
+ * @return \stdClass|null
+ * Data decoded from the token, or NULL on failure or if the token has
+ * expired.
+ */
+ public static function verifyTokenForId(
+ #[\SensitiveParameter]
+ string $token,
+ $id,
+ ) {
+ $key = static::getKey();
+ try {
+ $payload = JWT::decode($token, new Key($key, 'HS256'));
- if ($payload && ($payload->fid == $id) && ($payload->exp >= gettimeofday(TRUE))) {
- return $payload;
- }
- }
- catch (\Exception $e) {
- \Drupal::logger('cool')->error($e->getMessage());
- }
- return NULL;
+ if ($payload && ($payload->fid == $id) && ($payload->exp >= gettimeofday(TRUE))) {
+ return $payload;
+ }
}
-
- /**
- * Gets the TTL of the token in seconds, from the EPOCH.
- *
- * @return int
- * Token TTL in seconds.
- */
- public static function getAccessTokenTtl() {
- $default_config = \Drupal::config('collabora_online.settings');
- $ttl = $default_config->get('cool')['access_token_ttl'];
-
- return gettimeofday(TRUE) + $ttl;
+ catch (\Exception $e) {
+ \Drupal::logger('cool')->error($e->getMessage());
}
+ return NULL;
+ }
- /**
- * Creates a JWT token for a media entity.
- *
- * The token will carry the following:
- *
- * - fid: the Media id in Drupal.
- * - uid: the User id for the token. Permissions should be checked
- * whenever.
- * - exp: the expiration time of the token.
- * - wri: if true, then this token has write permissions.
- *
- * The signing key is stored in Drupal key management.
- *
- * @param int|string $id
- * Media id, which could be in string form like '123'.
- * @param int $ttl
- * Access token TTL in seconds.
- * @param bool $can_write
- * TRUE if the token is for an editor in write/edit mode.
- *
- * @return string
- * The access token.
- */
- public static function tokenForFileId($id, $ttl, $can_write = FALSE) {
- $payload = [
- "fid" => $id,
- "uid" => \Drupal::currentUser()->id(),
- "exp" => $ttl,
- "wri" => $can_write,
- ];
- $key = static::getKey();
- $jwt = JWT::encode($payload, $key, 'HS256');
+ /**
+ * Gets the TTL of the token in seconds, from the EPOCH.
+ *
+ * @return int
+ * Token TTL in seconds.
+ */
+ public static function getAccessTokenTtl() {
+ $default_config = \Drupal::config('collabora_online.settings');
+ $ttl = $default_config->get('cool')['access_token_ttl'];
- return $jwt;
- }
+ return gettimeofday(TRUE) + $ttl;
+ }
- /**
- * List of read only formats. Currently limited to the one Drupal accept.
- */
- const READ_ONLY = [
- 'application/x-iwork-keynote-sffkey' => TRUE,
- 'application/x-iwork-pages-sffpages' => TRUE,
- 'application/x-iwork-numbers-sffnumbers' => TRUE,
+ /**
+ * Creates a JWT token for a media entity.
+ *
+ * The token will carry the following:
+ *
+ * - fid: the Media id in Drupal.
+ * - uid: the User id for the token. Permissions should be checked
+ * whenever.
+ * - exp: the expiration time of the token.
+ * - wri: if true, then this token has write permissions.
+ *
+ * The signing key is stored in Drupal key management.
+ *
+ * @param int|string $id
+ * Media id, which could be in string form like '123'.
+ * @param int $ttl
+ * Access token TTL in seconds.
+ * @param bool $can_write
+ * TRUE if the token is for an editor in write/edit mode.
+ *
+ * @return string
+ * The access token.
+ */
+ public static function tokenForFileId($id, $ttl, $can_write = FALSE) {
+ $payload = [
+ "fid" => $id,
+ "uid" => \Drupal::currentUser()->id(),
+ "exp" => $ttl,
+ "wri" => $can_write,
];
+ $key = static::getKey();
+ $jwt = JWT::encode($payload, $key, 'HS256');
- /**
- * Determines if we can edit that media file.
- *
- * There are few types that Collabora Online only views.
- *
- * @param \Drupal\file\Entity\File $file
- * File entity.
- *
- * @return bool
- * TRUE if the file has a file type that is supported for editing.
- * FALSE if the file can only be opened as read-only.
- */
- public static function canEdit(File $file) {
- $mimetype = $file->getMimeType();
- return !array_key_exists($mimetype, static::READ_ONLY);
- }
+ return $jwt;
+ }
- /**
- * Gets the mime type for the document.
- *
- * Drupal will figure it out for us.
- *
- * @param \Drupal\file\Entity\File $file
- * File entity.
- *
- * @return string|null
- * The mime type, or NULL if it cannot be determined.
- */
- public static function getDocumentType(File $file) {
- return $file->getMimeType();
- }
+ /**
+ * List of read only formats. Currently limited to the one Drupal accept.
+ */
+ const READ_ONLY = [
+ 'application/x-iwork-keynote-sffkey' => TRUE,
+ 'application/x-iwork-pages-sffpages' => TRUE,
+ 'application/x-iwork-numbers-sffnumbers' => TRUE,
+ ];
- /**
- * Gets the editor / viewer Drupal URL from the routes configured.
- *
- * @param \Drupal\media\Entity\Media $media
- * Media entity that holds the file to open in the editor.
- * @param bool $can_write
- * TRUE for an edit url, FALSE for a read-only preview url.
- *
- * @return \Drupal\Core\Url
- * Editor url to visit as full-page, or to embed in an iframe.
- */
- public static function getEditorUrl(Media $media, $can_write = FALSE) {
- if ($can_write) {
- return Url::fromRoute('collabora-online.edit', ['media' => $media->id()]);
- }
- else {
- return Url::fromRoute('collabora-online.view', ['media' => $media->id()]);
- }
- }
+ /**
+ * Determines if we can edit that media file.
+ *
+ * There are few types that Collabora Online only views.
+ *
+ * @param \Drupal\file\Entity\File $file
+ * File entity.
+ *
+ * @return bool
+ * TRUE if the file has a file type that is supported for editing.
+ * FALSE if the file can only be opened as read-only.
+ */
+ public static function canEdit(File $file) {
+ $mimetype = $file->getMimeType();
+ return !array_key_exists($mimetype, static::READ_ONLY);
+ }
+
+ /**
+ * Gets the mime type for the document.
+ *
+ * Drupal will figure it out for us.
+ *
+ * @param \Drupal\file\Entity\File $file
+ * File entity.
+ *
+ * @return string|null
+ * The mime type, or NULL if it cannot be determined.
+ */
+ public static function getDocumentType(File $file) {
+ return $file->getMimeType();
+ }
- /**
- * Gets a render array for a cool viewer.
- *
- * @param \Drupal\media\Entity\Media $media
- * The media entity to view / edit.
- * @param bool $can_write
- * Whether this is a viewer (false) or an edit (true). Permissions will
- * also be checked.
- * @param array{closebutton: bool} $options
- * Options for the renderer. Current values:
- * - "closebutton" if "true" will add a close box. (see COOL SDK)
- *
- * @return array|array{error: string}
- * A stub render element array, or an array with an error on failure.
- */
- public static function getViewerRender(Media $media, bool $can_write, $options = NULL) {
- $default_config = \Drupal::config('collabora_online.settings');
- $wopi_base = $default_config->get('cool')['wopi_base'];
- $allowfullscreen = $default_config->get('cool')['allowfullscreen'] ?? FALSE;
+ /**
+ * Gets the editor / viewer Drupal URL from the routes configured.
+ *
+ * @param \Drupal\media\Entity\Media $media
+ * Media entity that holds the file to open in the editor.
+ * @param bool $can_write
+ * TRUE for an edit url, FALSE for a read-only preview url.
+ *
+ * @return \Drupal\Core\Url
+ * Editor url to visit as full-page, or to embed in an iframe.
+ */
+ public static function getEditorUrl(Media $media, $can_write = FALSE) {
+ if ($can_write) {
+ return Url::fromRoute('collabora-online.edit', ['media' => $media->id()]);
+ }
+ else {
+ return Url::fromRoute('collabora-online.view', ['media' => $media->id()]);
+ }
+ }
- $req = new CoolRequest();
- $wopi_client = $req->getWopiClientURL();
- if ($wopi_client === NULL) {
- return [
- 'error' => t('The Collabora Online server is not available: ') . $req->errorString(),
- ];
- }
+ /**
+ * Gets a render array for a cool viewer.
+ *
+ * @param \Drupal\media\Entity\Media $media
+ * The media entity to view / edit.
+ * @param bool $can_write
+ * Whether this is a viewer (false) or an edit (true). Permissions will
+ * also be checked.
+ * @param array{closebutton: bool} $options
+ * Options for the renderer. Current values:
+ * - "closebutton" if "true" will add a close box. (see COOL SDK)
+ *
+ * @return array|array{error: string}
+ * A stub render element array, or an array with an error on failure.
+ */
+ public static function getViewerRender(Media $media, bool $can_write, $options = NULL) {
+ $default_config = \Drupal::config('collabora_online.settings');
+ $wopi_base = $default_config->get('cool')['wopi_base'];
+ $allowfullscreen = $default_config->get('cool')['allowfullscreen'] ?? FALSE;
- $id = $media->id();
+ $req = new CoolRequest();
+ $wopi_client = $req->getWopiClientURL();
+ if ($wopi_client === NULL) {
+ return [
+ 'error' => t('The Collabora Online server is not available: ') . $req->errorString(),
+ ];
+ }
- $ttl = static::getAccessTokenTtl();
- if ($ttl == 0) {
- $ttl = 86400;
- }
- $access_token = static::tokenForFileId($id, $ttl, $can_write);
+ $id = $media->id();
- $render_array = [
- '#wopiClient' => $wopi_client,
- '#wopiSrc' => urlencode($wopi_base . '/cool/wopi/files/' . $id),
- '#accessToken' => $access_token,
- // It's in usec. The JWT is in sec.
- '#accessTokenTtl' => $ttl * 1000,
- '#allowfullscreen' => $allowfullscreen ? 'allowfullscreen' : '',
- ];
- if ($options) {
- if (isset($options['closebutton']) && $options['closebutton'] == 'true') {
- $render_array['#closebutton'] = 'true';
- }
- }
+ $ttl = static::getAccessTokenTtl();
+ if ($ttl == 0) {
+ $ttl = 86400;
+ }
+ $access_token = static::tokenForFileId($id, $ttl, $can_write);
- return $render_array;
+ $render_array = [
+ '#wopiClient' => $wopi_client,
+ '#wopiSrc' => urlencode($wopi_base . '/cool/wopi/files/' . $id),
+ '#accessToken' => $access_token,
+ // It's in usec. The JWT is in sec.
+ '#accessTokenTtl' => $ttl * 1000,
+ '#allowfullscreen' => $allowfullscreen ? 'allowfullscreen' : '',
+ ];
+ if ($options) {
+ if (isset($options['closebutton']) && $options['closebutton'] == 'true') {
+ $render_array['#closebutton'] = 'true';
+ }
}
+ return $render_array;
+ }
+
}
diff --git a/src/Form/ConfigForm.php b/src/Form/ConfigForm.php
index 9d559fd9..284e54d9 100644
--- a/src/Form/ConfigForm.php
+++ b/src/Form/ConfigForm.php
@@ -20,89 +20,89 @@
*/
class ConfigForm extends ConfigFormBase {
- const SETTINGS = 'collabora_online.settings';
-
- /**
- * {@inheritdoc}
- */
- public function getFormId() {
- return 'collabora_configform';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getEditableConfigNames() {
- return [
- static::SETTINGS,
- ];
- }
-
- /**
- * {@inheritdoc}
- */
- public function buildForm(array $form, FormStateInterface $form_state) {
- $config = $this->config(static::SETTINGS);
-
- $form['server'] = [
- '#type' => 'textfield',
- '#title' => $this->t('Collabora Online server URL'),
- '#default_value' => $config->get('cool')['server'],
- '#required' => TRUE,
- ];
-
- $form['wopi_base'] = [
- '#type' => 'textfield',
- '#title' => $this->t('WOPI host URL. Likely https://<drupal_server>'),
- '#default_value' => $config->get('cool')['wopi_base'],
- '#required' => TRUE,
- ];
-
- $form['key_id'] = [
- '#type' => 'textfield',
- '#title' => $this->t('JWT private key ID'),
- '#default_value' => $config->get('cool')['key_id'],
- '#required' => TRUE,
- ];
-
- $form['access_token_ttl'] = [
- '#type' => 'textfield',
- '#title' => $this->t('Access Token Expiration (in seconds)'),
- '#default_value' => $config->get('cool')['access_token_ttl'],
- '#required' => TRUE,
- ];
-
- $form['disable_cert_check'] = [
- '#type' => 'checkbox',
- '#title' => $this->t('Disable TLS certificate check for COOL.'),
- '#default_value' => $config->get('cool')['disable_cert_check'],
- ];
-
- $form['allowfullscreen'] = [
- '#type' => 'checkbox',
- '#title' => $this->t('Allow COOL to use fullscreen mode.'),
- '#default_value' => $config->get('cool')['allowfullscreen'] ?? FALSE,
- ];
-
- return parent::buildForm($form, $form_state);
- }
-
- /**
- * {@inheritdoc}
- */
- public function submitForm(array &$form, FormStateInterface $form_state) {
- $wopi_base = rtrim($form_state->getValue('wopi_base'), '/');
-
- $this->config(static::SETTINGS)
- ->set('cool.server', $form_state->getValue('server'))
- ->set('cool.wopi_base', $wopi_base)
- ->set('cool.key_id', $form_state->getValue('key_id'))
- ->set('cool.access_token_ttl', $form_state->getValue('access_token_ttl'))
- ->set('cool.disable_cert_check', $form_state->getValue('disable_cert_check'))
- ->set('cool.allowfullscreen', $form_state->getValue('allowfullscreen'))
- ->save();
-
- parent::submitForm($form, $form_state);
- }
+ const SETTINGS = 'collabora_online.settings';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'collabora_configform';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getEditableConfigNames() {
+ return [
+ static::SETTINGS,
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, FormStateInterface $form_state) {
+ $config = $this->config(static::SETTINGS);
+
+ $form['server'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Collabora Online server URL'),
+ '#default_value' => $config->get('cool')['server'],
+ '#required' => TRUE,
+ ];
+
+ $form['wopi_base'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('WOPI host URL. Likely https://<drupal_server>'),
+ '#default_value' => $config->get('cool')['wopi_base'],
+ '#required' => TRUE,
+ ];
+
+ $form['key_id'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('JWT private key ID'),
+ '#default_value' => $config->get('cool')['key_id'],
+ '#required' => TRUE,
+ ];
+
+ $form['access_token_ttl'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Access Token Expiration (in seconds)'),
+ '#default_value' => $config->get('cool')['access_token_ttl'],
+ '#required' => TRUE,
+ ];
+
+ $form['disable_cert_check'] = [
+ '#type' => 'checkbox',
+ '#title' => $this->t('Disable TLS certificate check for COOL.'),
+ '#default_value' => $config->get('cool')['disable_cert_check'],
+ ];
+
+ $form['allowfullscreen'] = [
+ '#type' => 'checkbox',
+ '#title' => $this->t('Allow COOL to use fullscreen mode.'),
+ '#default_value' => $config->get('cool')['allowfullscreen'] ?? FALSE,
+ ];
+
+ return parent::buildForm($form, $form_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, FormStateInterface $form_state) {
+ $wopi_base = rtrim($form_state->getValue('wopi_base'), '/');
+
+ $this->config(static::SETTINGS)
+ ->set('cool.server', $form_state->getValue('server'))
+ ->set('cool.wopi_base', $wopi_base)
+ ->set('cool.key_id', $form_state->getValue('key_id'))
+ ->set('cool.access_token_ttl', $form_state->getValue('access_token_ttl'))
+ ->set('cool.disable_cert_check', $form_state->getValue('disable_cert_check'))
+ ->set('cool.allowfullscreen', $form_state->getValue('allowfullscreen'))
+ ->save();
+
+ parent::submitForm($form, $form_state);
+ }
}
diff --git a/src/Plugin/Field/FieldFormatter/CoolPreview.php b/src/Plugin/Field/FieldFormatter/CoolPreview.php
index bbdf382b..766ab314 100644
--- a/src/Plugin/Field/FieldFormatter/CoolPreview.php
+++ b/src/Plugin/Field/FieldFormatter/CoolPreview.php
@@ -31,49 +31,49 @@
*/
class CoolPreview extends EntityReferenceFormatterBase {
- /**
- * {@inheritdoc}
- */
- public function settingsSummary() {
- $summary = [];
- $summary[] = $this->t('Preview Collabora Online documents.');
- return $summary;
- }
+ /**
+ * {@inheritdoc}
+ */
+ public function settingsSummary() {
+ $summary = [];
+ $summary[] = $this->t('Preview Collabora Online documents.');
+ return $summary;
+ }
- /**
- * {@inheritdoc}
- */
- public function viewElements(FieldItemListInterface $items, $langcode) {
- /** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $items */
- $elements = [];
- $media = $items->getEntity();
- if (!$media instanceof MediaInterface) {
- // Entity types other than 'media' are not supported.
- return [];
- }
+ /**
+ * {@inheritdoc}
+ */
+ public function viewElements(FieldItemListInterface $items, $langcode) {
+ /** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $items */
+ $elements = [];
+ $media = $items->getEntity();
+ if (!$media instanceof MediaInterface) {
+ // Entity types other than 'media' are not supported.
+ return [];
+ }
- $access_result = $media->access('preview in collabora', NULL, TRUE);
- (new CacheableMetadata())
- ->addCacheableDependency($access_result)
- ->applyTo($elements);
+ $access_result = $media->access('preview in collabora', NULL, TRUE);
+ (new CacheableMetadata())
+ ->addCacheableDependency($access_result)
+ ->applyTo($elements);
- if (!$access_result->isAllowed()) {
- return $elements;
- }
+ if (!$access_result->isAllowed()) {
+ return $elements;
+ }
- foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) {
- $url = CoolUtils::getEditorUrl($media, FALSE);
+ foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) {
+ $url = CoolUtils::getEditorUrl($media, FALSE);
- $render_array = [
- '#editorUrl' => $url,
- '#fileName' => $media->getName(),
- ];
- $render_array['#theme'] = 'collabora_online_preview';
- $render_array['#attached']['library'][] = 'collabora_online/cool.previewer';
- // Render each element as markup.
- $elements[$delta] = $render_array;
- }
- return $elements;
+ $render_array = [
+ '#editorUrl' => $url,
+ '#fileName' => $media->getName(),
+ ];
+ $render_array['#theme'] = 'collabora_online_preview';
+ $render_array['#attached']['library'][] = 'collabora_online/cool.previewer';
+ // Render each element as markup.
+ $elements[$delta] = $render_array;
}
+ return $elements;
+ }
}
diff --git a/src/Plugin/views/field/CollaboraEdit.php b/src/Plugin/views/field/CollaboraEdit.php
index 328ebc76..e1698a4d 100644
--- a/src/Plugin/views/field/CollaboraEdit.php
+++ b/src/Plugin/views/field/CollaboraEdit.php
@@ -19,25 +19,25 @@
#[ViewsField('media_collabora_edit')]
class CollaboraEdit extends LinkBase {
- /**
- * {@inheritdoc}
- */
- protected function getUrlInfo(ResultRow $row): Url|null {
- /** @var \Drupal\media\MediaInterface $entity */
- $entity = $this->getEntity($row);
-
- if ($entity === NULL) {
- return NULL;
- }
-
- return CoolUtils::getEditorUrl($entity, TRUE);
+ /**
+ * {@inheritdoc}
+ */
+ protected function getUrlInfo(ResultRow $row): Url|null {
+ /** @var \Drupal\media\MediaInterface $entity */
+ $entity = $this->getEntity($row);
+
+ if ($entity === NULL) {
+ return NULL;
}
- /**
- * {@inheritdoc}
- */
- protected function getDefaultLabel(): TranslatableMarkup {
- return $this->t('Edit in Collabora Online');
- }
+ return CoolUtils::getEditorUrl($entity, TRUE);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getDefaultLabel(): TranslatableMarkup {
+ return $this->t('Edit in Collabora Online');
+ }
}
diff --git a/src/Plugin/views/field/CollaboraPreview.php b/src/Plugin/views/field/CollaboraPreview.php
index f636b359..a4b2d65a 100644
--- a/src/Plugin/views/field/CollaboraPreview.php
+++ b/src/Plugin/views/field/CollaboraPreview.php
@@ -19,25 +19,25 @@
#[ViewsField('media_collabora_preview')]
class CollaboraPreview extends LinkBase {
- /**
- * {@inheritdoc}
- */
- protected function getUrlInfo(ResultRow $row): Url|null {
- /** @var \Drupal\media\MediaInterface $entity */
- $entity = $this->getEntity($row);
-
- if ($entity === NULL) {
- return NULL;
- }
-
- return CoolUtils::getEditorUrl($entity, FALSE);
+ /**
+ * {@inheritdoc}
+ */
+ protected function getUrlInfo(ResultRow $row): Url|null {
+ /** @var \Drupal\media\MediaInterface $entity */
+ $entity = $this->getEntity($row);
+
+ if ($entity === NULL) {
+ return NULL;
}
- /**
- * {@inheritdoc}
- */
- protected function getDefaultLabel(): TranslatableMarkup {
- return $this->t('View in Collabora Online');
- }
+ return CoolUtils::getEditorUrl($entity, FALSE);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getDefaultLabel(): TranslatableMarkup {
+ return $this->t('View in Collabora Online');
+ }
}
diff --git a/tests/src/ExistingSiteJavascript/CollaboraIntegrationTest.php b/tests/src/ExistingSiteJavascript/CollaboraIntegrationTest.php
index 2ae06bdb..afde4eb0 100644
--- a/tests/src/ExistingSiteJavascript/CollaboraIntegrationTest.php
+++ b/tests/src/ExistingSiteJavascript/CollaboraIntegrationTest.php
@@ -21,71 +21,71 @@
*/
class CollaboraIntegrationTest extends ExistingSiteSelenium2DriverTestBase {
- /**
- * Tests the Collabora editor in readonly mode.
- */
- public function testCollaboraPreview(): void {
- $user = $this->createUser([
- 'preview document in collabora',
- ]);
- $this->drupalLogin($user);
- $media = $this->createDocumentMedia('Shopping list', 'shopping-list', 'Chocolate, pickles');
- $this->drupalGet('/cool/view/' . $media->id());
- $this->getSession()->switchToIFrame('collabora-online-viewer');
+ /**
+ * Tests the Collabora editor in readonly mode.
+ */
+ public function testCollaboraPreview(): void {
+ $user = $this->createUser([
+ 'preview document in collabora',
+ ]);
+ $this->drupalLogin($user);
+ $media = $this->createDocumentMedia('Shopping list', 'shopping-list', 'Chocolate, pickles');
+ $this->drupalGet('/cool/view/' . $media->id());
+ $this->getSession()->switchToIFrame('collabora-online-viewer');
- $assert_session = $this->assertSession();
- $canvas = $assert_session->waitForElement('css', 'canvas#document-canvas');
- $this->assertNotNull($canvas, 'The canvas element was not found after 10 seconds.');
+ $assert_session = $this->assertSession();
+ $canvas = $assert_session->waitForElement('css', 'canvas#document-canvas');
+ $this->assertNotNull($canvas, 'The canvas element was not found after 10 seconds.');
- $document_field = $assert_session->waitForElement('css', 'input#document-name-input');
- $this->assertNotNull($document_field, 'The document name input was not found after 10 seconds.');
- $this->getCurrentPage()->waitFor(10, function () use ($document_field) {
- return $document_field->getValue() === 'shopping-list.txt';
- });
- $this->assertEquals('shopping-list.txt', $document_field->getValue(), 'The document name input did not contain the correct value after 10 seconds.');
+ $document_field = $assert_session->waitForElement('css', 'input#document-name-input');
+ $this->assertNotNull($document_field, 'The document name input was not found after 10 seconds.');
+ $this->getCurrentPage()->waitFor(10, function () use ($document_field) {
+ return $document_field->getValue() === 'shopping-list.txt';
+ });
+ $this->assertEquals('shopping-list.txt', $document_field->getValue(), 'The document name input did not contain the correct value after 10 seconds.');
- $word_count_element = $assert_session->waitForElement('css', 'div#StateWordCount');
- $this->assertNotNull($word_count_element, 'The word count element was not found after 10 seconds.');
- $this->getCurrentPage()->waitFor(10, function () use ($word_count_element) {
- return $word_count_element->getText() === '2 words, 18 characters';
- });
- $this->assertEquals('2 words, 18 characters', $word_count_element->getText(), 'The word count element did not contain the correct text after 10 seconds.');
- }
+ $word_count_element = $assert_session->waitForElement('css', 'div#StateWordCount');
+ $this->assertNotNull($word_count_element, 'The word count element was not found after 10 seconds.');
+ $this->getCurrentPage()->waitFor(10, function () use ($word_count_element) {
+ return $word_count_element->getText() === '2 words, 18 characters';
+ });
+ $this->assertEquals('2 words, 18 characters', $word_count_element->getText(), 'The word count element did not contain the correct text after 10 seconds.');
+ }
- /**
- * Creates a media entity with an attached *.txt file.
- *
- * The *.txt format is enough to test the basic functionality.
- *
- * @param string $media_name
- * Media label.
- * @param string $file_basename
- * File name without the extension.
- * @param string $text_content
- * Content for the attached *.txt file.
- *
- * @return \Drupal\media\MediaInterface
- * New media entity.
- */
- protected function createDocumentMedia(string $media_name, string $file_basename, string $text_content): MediaInterface {
- $file_uri = 'public://' . $file_basename . '.txt';
- file_put_contents($file_uri, $text_content);
- $file = File::create([
- 'uri' => $file_uri,
- ]);
- $file->save();
- $this->markEntityForCleanup($file);
- $values = [
- 'bundle' => 'document',
- 'name' => $media_name,
- 'title' => $media_name,
- 'label' => $media_name,
- 'field_media_file' => $file->id(),
- ];
- $media = Media::create($values);
- $media->save();
- $this->markEntityForCleanup($media);
- return $media;
- }
+ /**
+ * Creates a media entity with an attached *.txt file.
+ *
+ * The *.txt format is enough to test the basic functionality.
+ *
+ * @param string $media_name
+ * Media label.
+ * @param string $file_basename
+ * File name without the extension.
+ * @param string $text_content
+ * Content for the attached *.txt file.
+ *
+ * @return \Drupal\media\MediaInterface
+ * New media entity.
+ */
+ protected function createDocumentMedia(string $media_name, string $file_basename, string $text_content): MediaInterface {
+ $file_uri = 'public://' . $file_basename . '.txt';
+ file_put_contents($file_uri, $text_content);
+ $file = File::create([
+ 'uri' => $file_uri,
+ ]);
+ $file->save();
+ $this->markEntityForCleanup($file);
+ $values = [
+ 'bundle' => 'document',
+ 'name' => $media_name,
+ 'title' => $media_name,
+ 'label' => $media_name,
+ 'field_media_file' => $file->id(),
+ ];
+ $media = Media::create($values);
+ $media->save();
+ $this->markEntityForCleanup($media);
+ return $media;
+ }
}
diff --git a/tests/src/Kernel/CollaboraMediaAccessTest.php b/tests/src/Kernel/CollaboraMediaAccessTest.php
index b9b6d814..91c9aaac 100644
--- a/tests/src/Kernel/CollaboraMediaAccessTest.php
+++ b/tests/src/Kernel/CollaboraMediaAccessTest.php
@@ -19,276 +19,276 @@
*/
class CollaboraMediaAccessTest extends KernelTestBase {
- use MediaTypeCreationTrait;
- use UserCreationTrait;
- use MediaCreationTrait;
+ use MediaTypeCreationTrait;
+ use UserCreationTrait;
+ use MediaCreationTrait;
- /**
- * {@inheritdoc}
- */
- protected static $modules = [
- 'collabora_online',
- 'user',
- 'media',
- 'field',
- 'image',
- 'system',
- 'file',
- ];
+ /**
+ * {@inheritdoc}
+ */
+ protected static $modules = [
+ 'collabora_online',
+ 'user',
+ 'media',
+ 'field',
+ 'image',
+ 'system',
+ 'file',
+ ];
- /**
- * {@inheritdoc}
- */
- protected function setUp(): void {
- parent::setUp();
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp(): void {
+ parent::setUp();
- $this->installEntitySchema('user');
- $this->installEntitySchema('file');
- $this->installSchema('file', 'file_usage');
- $this->installEntitySchema('media');
- $this->installConfig([
- 'field',
- 'system',
- 'user',
- 'image',
- 'file',
- 'media',
- ]);
+ $this->installEntitySchema('user');
+ $this->installEntitySchema('file');
+ $this->installSchema('file', 'file_usage');
+ $this->installEntitySchema('media');
+ $this->installConfig([
+ 'field',
+ 'system',
+ 'user',
+ 'image',
+ 'file',
+ 'media',
+ ]);
- $this->createMediaType('file', ['id' => 'document']);
- $this->createMediaType('file', ['id' => 'book']);
+ $this->createMediaType('file', ['id' => 'document']);
+ $this->createMediaType('file', ['id' => 'book']);
- // Consume the user id 1.
- $this->createUser();
- }
+ // Consume the user id 1.
+ $this->createUser();
+ }
- /**
- * Tests media access for Collabora routes and operations.
- */
- public function testCollaboraMediaAccess(): void {
- $this->assertCollaboraMediaAccess(
- [],
- new AnonymousUserSession(),
- 'No access for anonymous without permissions',
- );
+ /**
+ * Tests media access for Collabora routes and operations.
+ */
+ public function testCollaboraMediaAccess(): void {
+ $this->assertCollaboraMediaAccess(
+ [],
+ new AnonymousUserSession(),
+ 'No access for anonymous without permissions',
+ );
- // Check authenticated with irrelevant permissions.
- // This also covers the "no permissions" case.
- $this->assertCollaboraMediaAccess(
- [],
- $this->createUser([
- // Add general 'media' permissions.
- 'administer media types',
- 'view media',
- 'update any media',
- 'view own unpublished media',
- // Add Collabora permissions for a different media type.
- 'preview book in collabora',
- 'preview own unpublished book in collabora',
- 'edit any book in collabora',
- 'edit own book in collabora',
- ]),
- 'No access with irrelevant permissions',
- );
+ // Check authenticated with irrelevant permissions.
+ // This also covers the "no permissions" case.
+ $this->assertCollaboraMediaAccess(
+ [],
+ $this->createUser([
+ // Add general 'media' permissions.
+ 'administer media types',
+ 'view media',
+ 'update any media',
+ 'view own unpublished media',
+ // Add Collabora permissions for a different media type.
+ 'preview book in collabora',
+ 'preview own unpublished book in collabora',
+ 'edit any book in collabora',
+ 'edit own book in collabora',
+ ]),
+ 'No access with irrelevant permissions',
+ );
- $this->assertCollaboraMediaAccessForPermission(
- [
- 'published document' => ['preview'],
- 'own published document' => ['preview'],
- ],
- 'preview document in collabora',
- );
+ $this->assertCollaboraMediaAccessForPermission(
+ [
+ 'published document' => ['preview'],
+ 'own published document' => ['preview'],
+ ],
+ 'preview document in collabora',
+ );
- $this->assertCollaboraMediaAccessForPermission(
- [
- 'own unpublished document' => ['preview'],
- ],
- 'preview own unpublished document in collabora',
- );
+ $this->assertCollaboraMediaAccessForPermission(
+ [
+ 'own unpublished document' => ['preview'],
+ ],
+ 'preview own unpublished document in collabora',
+ );
- $this->assertCollaboraMediaAccessForPermission(
- [
- 'published document' => ['edit'],
- 'unpublished document' => ['edit'],
- 'own published document' => ['edit'],
- 'own unpublished document' => ['edit'],
- ],
- 'edit any document in collabora',
- );
+ $this->assertCollaboraMediaAccessForPermission(
+ [
+ 'published document' => ['edit'],
+ 'unpublished document' => ['edit'],
+ 'own published document' => ['edit'],
+ 'own unpublished document' => ['edit'],
+ ],
+ 'edit any document in collabora',
+ );
- $this->assertCollaboraMediaAccessForPermission(
- [
- 'own published document' => ['edit'],
- 'own unpublished document' => ['edit'],
- ],
- 'edit own document in collabora',
- );
+ $this->assertCollaboraMediaAccessForPermission(
+ [
+ 'own published document' => ['edit'],
+ 'own unpublished document' => ['edit'],
+ ],
+ 'edit own document in collabora',
+ );
- // The 'administer media' permission grants access to everything.
- $this->assertCollaboraMediaAccessForPermission(
- [
- 'published document' => ['preview', 'edit'],
- 'unpublished document' => ['preview', 'edit'],
- 'own published document' => ['preview', 'edit'],
- 'own unpublished document' => ['preview', 'edit'],
- ],
- 'administer media',
- );
+ // The 'administer media' permission grants access to everything.
+ $this->assertCollaboraMediaAccessForPermission(
+ [
+ 'published document' => ['preview', 'edit'],
+ 'unpublished document' => ['preview', 'edit'],
+ 'own published document' => ['preview', 'edit'],
+ 'own unpublished document' => ['preview', 'edit'],
+ ],
+ 'administer media',
+ );
- $this->assertCollaboraMediaAccess(
- [
- 'published document' => ['preview', 'edit'],
- 'unpublished document' => ['preview', 'edit'],
- 'own published document' => ['preview', 'edit'],
- 'own unpublished document' => ['preview', 'edit'],
- ],
- $this->createUser(admin: TRUE),
- "Access for admin user",
- );
- }
+ $this->assertCollaboraMediaAccess(
+ [
+ 'published document' => ['preview', 'edit'],
+ 'unpublished document' => ['preview', 'edit'],
+ 'own published document' => ['preview', 'edit'],
+ 'own unpublished document' => ['preview', 'edit'],
+ ],
+ $this->createUser(admin: TRUE),
+ "Access for admin user",
+ );
+ }
- /**
- * Tests scenarios where the anonymous user has more permissions.
- *
- * This verifies the special treatment of uid 0 to determine the owner of a
- * media entity.
- */
- public function testAnonymousOwnAccess(): void {
- user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, [
- 'preview own unpublished document in collabora',
- 'edit own document in collabora',
- ]);
- $this->assertCollaboraMediaAccess(
- [],
- new AnonymousUserSession(),
- "Anonymous user with '... own ...' permissions.",
- );
+ /**
+ * Tests scenarios where the anonymous user has more permissions.
+ *
+ * This verifies the special treatment of uid 0 to determine the owner of a
+ * media entity.
+ */
+ public function testAnonymousOwnAccess(): void {
+ user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, [
+ 'preview own unpublished document in collabora',
+ 'edit own document in collabora',
+ ]);
+ $this->assertCollaboraMediaAccess(
+ [],
+ new AnonymousUserSession(),
+ "Anonymous user with '... own ...' permissions.",
+ );
- user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, [
- 'preview document in collabora',
- 'edit any document in collabora',
- ]);
- $this->assertCollaboraMediaAccess(
- [
- 'published document' => ['preview', 'edit'],
- 'unpublished document' => ['edit'],
- 'own published document' => ['preview', 'edit'],
- 'own unpublished document' => ['edit'],
- ],
- new AnonymousUserSession(),
- "Anonymous user with all Collabora media permissions.",
- );
- }
+ user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, [
+ 'preview document in collabora',
+ 'edit any document in collabora',
+ ]);
+ $this->assertCollaboraMediaAccess(
+ [
+ 'published document' => ['preview', 'edit'],
+ 'unpublished document' => ['edit'],
+ 'own published document' => ['preview', 'edit'],
+ 'own unpublished document' => ['edit'],
+ ],
+ new AnonymousUserSession(),
+ "Anonymous user with all Collabora media permissions.",
+ );
+ }
- /**
- * Creates a user with one permission, and asserts access to media entities.
- *
- * @param array> $expected
- * Expected access.
- * @param string $permission
- * Permission machine name.
- */
- protected function assertCollaboraMediaAccessForPermission(array $expected, string $permission): void {
- $account = $this->createUser([$permission]);
- $message = "User with '$permission' permission.";
- $this->assertCollaboraMediaAccess($expected, $account, $message);
- }
+ /**
+ * Creates a user with one permission, and asserts access to media entities.
+ *
+ * @param array> $expected
+ * Expected access.
+ * @param string $permission
+ * Permission machine name.
+ */
+ protected function assertCollaboraMediaAccessForPermission(array $expected, string $permission): void {
+ $account = $this->createUser([$permission]);
+ $message = "User with '$permission' permission.";
+ $this->assertCollaboraMediaAccess($expected, $account, $message);
+ }
- /**
- * Asserts Collabora media access for a user account.
- *
- * @param array $expected
- * Expected access matrix.
- * The keys identify media entities that are created in this test.
- * The values identify operations.
- * @param \Drupal\Core\Session\AccountInterface $account
- * Account to check access for.
- * @param string $message
- * Message for the assertion.
- */
- protected function assertCollaboraMediaAccess(array $expected, AccountInterface $account, string $message): void {
- $other_user = $this->createUser();
- $entities = [
- "published document" => $this->createMediaEntity('document', [
- 'uid' => $other_user->id(),
- ]),
- "unpublished document" => $this->createMediaEntity('document', [
- 'uid' => $other_user->id(),
- 'status' => 0,
- ]),
- "own published document" => $this->createMediaEntity('document', [
- 'uid' => $account->id(),
- ]),
- "own unpublished document" => $this->createMediaEntity('document', [
- 'uid' => $account->id(),
- 'status' => 0,
- ]),
- ];
+ /**
+ * Asserts Collabora media access for a user account.
+ *
+ * @param array $expected
+ * Expected access matrix.
+ * The keys identify media entities that are created in this test.
+ * The values identify operations.
+ * @param \Drupal\Core\Session\AccountInterface $account
+ * Account to check access for.
+ * @param string $message
+ * Message for the assertion.
+ */
+ protected function assertCollaboraMediaAccess(array $expected, AccountInterface $account, string $message): void {
+ $other_user = $this->createUser();
+ $entities = [
+ "published document" => $this->createMediaEntity('document', [
+ 'uid' => $other_user->id(),
+ ]),
+ "unpublished document" => $this->createMediaEntity('document', [
+ 'uid' => $other_user->id(),
+ 'status' => 0,
+ ]),
+ "own published document" => $this->createMediaEntity('document', [
+ 'uid' => $account->id(),
+ ]),
+ "own unpublished document" => $this->createMediaEntity('document', [
+ 'uid' => $account->id(),
+ 'status' => 0,
+ ]),
+ ];
- // Test $entity->access() with different operations on all entities.
- $operations = [
- 'preview' => 'preview in collabora',
- 'edit' => 'edit in collabora',
- ];
- $actual_entity_access = [];
- foreach ($entities as $entity_key => $entity) {
- foreach ($operations as $operation_key => $operation) {
- $has_entity_access = $entity->access($operation, $account);
- if ($has_entity_access) {
- $actual_entity_access[$entity_key][] = $operation_key;
- }
- }
+ // Test $entity->access() with different operations on all entities.
+ $operations = [
+ 'preview' => 'preview in collabora',
+ 'edit' => 'edit in collabora',
+ ];
+ $actual_entity_access = [];
+ foreach ($entities as $entity_key => $entity) {
+ foreach ($operations as $operation_key => $operation) {
+ $has_entity_access = $entity->access($operation, $account);
+ if ($has_entity_access) {
+ $actual_entity_access[$entity_key][] = $operation_key;
}
- $this->assertSameYaml(
- $expected,
- $actual_entity_access,
- 'Entity access: ' . $message,
- );
+ }
+ }
+ $this->assertSameYaml(
+ $expected,
+ $actual_entity_access,
+ 'Entity access: ' . $message,
+ );
- // Test path access.
- // The result is expected to be exactly the same, due to how the route
- // access is configured.
- // Testing the paths like this introduces some level of redundancy or
- // duplication, but it is cheap and easy, so for now this is what we do.
- $sprintf_path_patterns = [
- 'preview' => '/cool/view/%s',
- 'edit' => '/cool/edit/%s',
- ];
- $actual_path_access = [];
- foreach ($entities as $entity_key => $entity) {
- foreach ($sprintf_path_patterns as $pattern_key => $sprintf_path_pattern) {
- $path = sprintf($sprintf_path_pattern, $entity->id());
- $has_path_access = Url::fromUserInput($path)->access($account);
- if ($has_path_access) {
- $actual_path_access[$entity_key][] = $pattern_key;
- }
- }
+ // Test path access.
+ // The result is expected to be exactly the same, due to how the route
+ // access is configured.
+ // Testing the paths like this introduces some level of redundancy or
+ // duplication, but it is cheap and easy, so for now this is what we do.
+ $sprintf_path_patterns = [
+ 'preview' => '/cool/view/%s',
+ 'edit' => '/cool/edit/%s',
+ ];
+ $actual_path_access = [];
+ foreach ($entities as $entity_key => $entity) {
+ foreach ($sprintf_path_patterns as $pattern_key => $sprintf_path_pattern) {
+ $path = sprintf($sprintf_path_pattern, $entity->id());
+ $has_path_access = Url::fromUserInput($path)->access($account);
+ if ($has_path_access) {
+ $actual_path_access[$entity_key][] = $pattern_key;
}
- $this->assertSameYaml(
- $expected,
- $actual_path_access,
- 'Path access: ' . $message,
- );
+ }
}
+ $this->assertSameYaml(
+ $expected,
+ $actual_path_access,
+ 'Path access: ' . $message,
+ );
+ }
- /**
- * Asserts that two values are the same when exported to yaml.
- *
- * This provides a nicer diff output, without numeric array keys.
- *
- * @param mixed $expected
- * Expected value.
- * @param mixed $actual
- * Actual value.
- * @param string $message
- * Message.
- */
- protected function assertSameYaml(mixed $expected, mixed $actual, string $message = ''): void {
- $this->assertSame(
- "\n" . Yaml::encode($expected),
- "\n" . Yaml::encode($actual),
- $message,
- );
- }
+ /**
+ * Asserts that two values are the same when exported to yaml.
+ *
+ * This provides a nicer diff output, without numeric array keys.
+ *
+ * @param mixed $expected
+ * Expected value.
+ * @param mixed $actual
+ * Actual value.
+ * @param string $message
+ * Message.
+ */
+ protected function assertSameYaml(mixed $expected, mixed $actual, string $message = ''): void {
+ $this->assertSame(
+ "\n" . Yaml::encode($expected),
+ "\n" . Yaml::encode($actual),
+ $message,
+ );
+ }
}
diff --git a/tests/src/Kernel/PermissionTest.php b/tests/src/Kernel/PermissionTest.php
index 20f9739a..aa0a8be1 100644
--- a/tests/src/Kernel/PermissionTest.php
+++ b/tests/src/Kernel/PermissionTest.php
@@ -24,87 +24,87 @@
*/
class PermissionTest extends KernelTestBase {
- use MediaTypeCreationTrait;
- use UserCreationTrait;
+ use MediaTypeCreationTrait;
+ use UserCreationTrait;
- /**
- * {@inheritdoc}
- */
- protected static $modules = [
- 'collabora_online',
- 'media',
- 'user',
- 'field',
- 'system',
- 'file',
- 'image',
- ];
+ /**
+ * {@inheritdoc}
+ */
+ protected static $modules = [
+ 'collabora_online',
+ 'media',
+ 'user',
+ 'field',
+ 'system',
+ 'file',
+ 'image',
+ ];
- /**
- * {@inheritdoc}
- */
- protected function setUp(): void {
- parent::setUp();
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp(): void {
+ parent::setUp();
- $this->installEntitySchema('user');
- $this->installEntitySchema('file');
- $this->installSchema('file', 'file_usage');
- $this->installEntitySchema('media');
- $this->installConfig(['field', 'system', 'user', 'file', 'media']);
- }
+ $this->installEntitySchema('user');
+ $this->installEntitySchema('file');
+ $this->installSchema('file', 'file_usage');
+ $this->installEntitySchema('media');
+ $this->installConfig(['field', 'system', 'user', 'file', 'media']);
+ }
- /**
- * Tests that dynamic permissions are properly created.
- */
- public function testDynamicPermissions(): void {
- $this->createMediaType('file', [
- 'id' => 'public_wiki',
- 'label' => 'Public wiki',
- ]);
- /** @var \Drupal\user\PermissionHandlerInterface $permission_handler */
- $permission_handler = \Drupal::service(PermissionHandlerInterface::class);
- $permissions = $permission_handler->getPermissions();
- $permissions = array_filter(
- $permissions,
- fn (array $permission) => $permission['provider'] === 'collabora_online',
- );
- // Remove noise that is hard to diff.
- $permissions = array_map(
- static function (array $permission) {
- $permission['title'] = (string) $permission['title'];
- if ($permission['description'] === NULL) {
- unset($permission['description']);
- }
- if ($permission['provider'] === 'collabora_online') {
- unset($permission['provider']);
- }
- return $permission;
- },
- $permissions,
- );
- ksort($permissions);
- $this->assertSame([
- 'administer collabora instance' => [
- 'title' => 'Administer the Collabora instance',
- 'restrict access' => TRUE,
- ],
- 'edit any public_wiki in collabora' => [
- 'title' => 'Public wiki: Edit any media file in Collabora',
- 'dependencies' => ['config' => ['media.type.public_wiki']],
- ],
- 'edit own public_wiki in collabora' => [
- 'title' => 'Public wiki: Edit own media file in Collabora',
- 'dependencies' => ['config' => ['media.type.public_wiki']],
- ],
- 'preview own unpublished public_wiki in collabora' => [
- 'title' => 'Public wiki: Preview own unpublished media file in Collabora',
- 'dependencies' => ['config' => ['media.type.public_wiki']],
- ],
- 'preview public_wiki in collabora' => [
- 'title' => 'Public wiki: Preview published media file in Collabora',
- 'dependencies' => ['config' => ['media.type.public_wiki']],
- ],
- ], $permissions);
- }
+ /**
+ * Tests that dynamic permissions are properly created.
+ */
+ public function testDynamicPermissions(): void {
+ $this->createMediaType('file', [
+ 'id' => 'public_wiki',
+ 'label' => 'Public wiki',
+ ]);
+ /** @var \Drupal\user\PermissionHandlerInterface $permission_handler */
+ $permission_handler = \Drupal::service(PermissionHandlerInterface::class);
+ $permissions = $permission_handler->getPermissions();
+ $permissions = array_filter(
+ $permissions,
+ fn (array $permission) => $permission['provider'] === 'collabora_online',
+ );
+ // Remove noise that is hard to diff.
+ $permissions = array_map(
+ static function (array $permission) {
+ $permission['title'] = (string) $permission['title'];
+ if ($permission['description'] === NULL) {
+ unset($permission['description']);
+ }
+ if ($permission['provider'] === 'collabora_online') {
+ unset($permission['provider']);
+ }
+ return $permission;
+ },
+ $permissions,
+ );
+ ksort($permissions);
+ $this->assertSame([
+ 'administer collabora instance' => [
+ 'title' => 'Administer the Collabora instance',
+ 'restrict access' => TRUE,
+ ],
+ 'edit any public_wiki in collabora' => [
+ 'title' => 'Public wiki: Edit any media file in Collabora',
+ 'dependencies' => ['config' => ['media.type.public_wiki']],
+ ],
+ 'edit own public_wiki in collabora' => [
+ 'title' => 'Public wiki: Edit own media file in Collabora',
+ 'dependencies' => ['config' => ['media.type.public_wiki']],
+ ],
+ 'preview own unpublished public_wiki in collabora' => [
+ 'title' => 'Public wiki: Preview own unpublished media file in Collabora',
+ 'dependencies' => ['config' => ['media.type.public_wiki']],
+ ],
+ 'preview public_wiki in collabora' => [
+ 'title' => 'Public wiki: Preview published media file in Collabora',
+ 'dependencies' => ['config' => ['media.type.public_wiki']],
+ ],
+ ], $permissions);
+ }
}
diff --git a/tests/src/Kernel/ViewsLinkFieldsTest.php b/tests/src/Kernel/ViewsLinkFieldsTest.php
index 10c4cbc2..a5db12a3 100644
--- a/tests/src/Kernel/ViewsLinkFieldsTest.php
+++ b/tests/src/Kernel/ViewsLinkFieldsTest.php
@@ -18,157 +18,157 @@
*/
class ViewsLinkFieldsTest extends KernelTestBase {
- use UserCreationTrait;
- use MediaCreationTrait;
- use MediaTypeCreationTrait;
+ use UserCreationTrait;
+ use MediaCreationTrait;
+ use MediaTypeCreationTrait;
- /**
- * {@inheritdoc}
- */
- protected static $modules = [
- 'collabora_online',
- 'collabora_online_test',
- 'field',
- 'file',
- 'image',
- 'media',
- 'system',
- 'user',
- 'views',
- ];
+ /**
+ * {@inheritdoc}
+ */
+ protected static $modules = [
+ 'collabora_online',
+ 'collabora_online_test',
+ 'field',
+ 'file',
+ 'image',
+ 'media',
+ 'system',
+ 'user',
+ 'views',
+ ];
- /**
- * {@inheritdoc}
- */
- protected function setUp(): void {
- parent::setUp();
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp(): void {
+ parent::setUp();
- $this->installEntitySchema('file');
- $this->installEntitySchema('media');
- $this->installEntitySchema('user');
- $this->installConfig(['user', 'views', 'collabora_online_test']);
- $this->installSchema('file', ['file_usage']);
- // Install user module to avoid user 1 permissions bypass.
- \Drupal::moduleHandler()->loadInclude('user', 'install');
- user_install();
- }
+ $this->installEntitySchema('file');
+ $this->installEntitySchema('media');
+ $this->installEntitySchema('user');
+ $this->installConfig(['user', 'views', 'collabora_online_test']);
+ $this->installSchema('file', ['file_usage']);
+ // Install user module to avoid user 1 permissions bypass.
+ \Drupal::moduleHandler()->loadInclude('user', 'install');
+ user_install();
+ }
- /**
- * Tests link fields.
- */
- public function testLinks(): void {
- // User without permissions can't see links.
- $this->doTestLinks(
- [
- 'preview' => [FALSE, FALSE, FALSE, FALSE],
- 'edit' => [FALSE, FALSE, FALSE, FALSE],
- ],
- $this->createUser([])
- );
- // User with 'Preview' permission can see preview link.
- $this->doTestLinks(
- [
- 'preview' => [TRUE, FALSE, TRUE, FALSE],
- 'edit' => [FALSE, FALSE, FALSE, FALSE],
- ],
- $this->createUser([
- 'preview document in collabora',
- ])
- );
- // User with 'Preview own unpublished' permission can see preview link
- // for unpublished entity they own.
- $this->doTestLinks(
- [
- 'preview' => [FALSE, FALSE, FALSE, TRUE],
- 'edit' => [FALSE, FALSE, FALSE, FALSE],
- ],
- $this->createUser([
- 'preview own unpublished document in collabora',
- ])
- );
- // User with 'Edit any' permission can see edit link.
- $this->doTestLinks(
- [
- 'preview' => [FALSE, FALSE, FALSE, FALSE],
- 'edit' => [TRUE, TRUE, TRUE, TRUE],
- ],
- $this->createUser([
- 'edit any document in collabora',
- ])
- );
- // User with 'Edit own' permission can see edit link for entities they
- // own.
- $this->doTestLinks(
- [
- 'preview' => [FALSE, FALSE, FALSE, FALSE],
- 'edit' => [FALSE, FALSE, TRUE, TRUE],
- ],
- $this->createUser([
- 'edit own document in collabora',
- ])
- );
- }
+ /**
+ * Tests link fields.
+ */
+ public function testLinks(): void {
+ // User without permissions can't see links.
+ $this->doTestLinks(
+ [
+ 'preview' => [FALSE, FALSE, FALSE, FALSE],
+ 'edit' => [FALSE, FALSE, FALSE, FALSE],
+ ],
+ $this->createUser([])
+ );
+ // User with 'Preview' permission can see preview link.
+ $this->doTestLinks(
+ [
+ 'preview' => [TRUE, FALSE, TRUE, FALSE],
+ 'edit' => [FALSE, FALSE, FALSE, FALSE],
+ ],
+ $this->createUser([
+ 'preview document in collabora',
+ ])
+ );
+ // User with 'Preview own unpublished' permission can see preview link
+ // for unpublished entity they own.
+ $this->doTestLinks(
+ [
+ 'preview' => [FALSE, FALSE, FALSE, TRUE],
+ 'edit' => [FALSE, FALSE, FALSE, FALSE],
+ ],
+ $this->createUser([
+ 'preview own unpublished document in collabora',
+ ])
+ );
+ // User with 'Edit any' permission can see edit link.
+ $this->doTestLinks(
+ [
+ 'preview' => [FALSE, FALSE, FALSE, FALSE],
+ 'edit' => [TRUE, TRUE, TRUE, TRUE],
+ ],
+ $this->createUser([
+ 'edit any document in collabora',
+ ])
+ );
+ // User with 'Edit own' permission can see edit link for entities they
+ // own.
+ $this->doTestLinks(
+ [
+ 'preview' => [FALSE, FALSE, FALSE, FALSE],
+ 'edit' => [FALSE, FALSE, TRUE, TRUE],
+ ],
+ $this->createUser([
+ 'edit own document in collabora',
+ ])
+ );
+ }
- /**
- * Tests that links behave as expected.
- *
- * @param array $expected_results
- * An associative array of expected results keyed by operation.
- * @param \Drupal\Core\Session\AccountInterface $account
- * The user account to be used to run the test.
- */
- protected function doTestLinks(array $expected_results, AccountInterface $account): void {
- $this->setCurrentUser($account);
- // Create medias: cover all combinations of status and ownership.
- $this->createMediaEntity('document', [
- 'uid' => $this->createUser(),
- ]);
- $this->createMediaEntity('document', [
- 'uid' => $this->createUser(),
- 'status' => 0,
- ]);
- $this->createMediaEntity('document', [
- 'uid' => $account->id(),
- ]);
- $this->createMediaEntity('document', [
- 'uid' => $account->id(),
- 'status' => 0,
- ]);
+ /**
+ * Tests that links behave as expected.
+ *
+ * @param array $expected_results
+ * An associative array of expected results keyed by operation.
+ * @param \Drupal\Core\Session\AccountInterface $account
+ * The user account to be used to run the test.
+ */
+ protected function doTestLinks(array $expected_results, AccountInterface $account): void {
+ $this->setCurrentUser($account);
+ // Create medias: cover all combinations of status and ownership.
+ $this->createMediaEntity('document', [
+ 'uid' => $this->createUser(),
+ ]);
+ $this->createMediaEntity('document', [
+ 'uid' => $this->createUser(),
+ 'status' => 0,
+ ]);
+ $this->createMediaEntity('document', [
+ 'uid' => $account->id(),
+ ]);
+ $this->createMediaEntity('document', [
+ 'uid' => $account->id(),
+ 'status' => 0,
+ ]);
- $view = Views::getView('test_collabora_links');
- $view->preview();
+ $view = Views::getView('test_collabora_links');
+ $view->preview();
- $info = [
- 'preview' => [
- 'label' => 'View in Collabora Online',
- 'field_id' => 'collabora_preview',
- 'route' => 'collabora-online.view',
- ],
- 'edit' => [
- 'label' => 'Edit in Collabora Online',
- 'field_id' => 'collabora_edit',
- 'route' => 'collabora-online.edit',
- ],
- ];
+ $info = [
+ 'preview' => [
+ 'label' => 'View in Collabora Online',
+ 'field_id' => 'collabora_preview',
+ 'route' => 'collabora-online.view',
+ ],
+ 'edit' => [
+ 'label' => 'Edit in Collabora Online',
+ 'field_id' => 'collabora_edit',
+ 'route' => 'collabora-online.edit',
+ ],
+ ];
- // Check each expected results for every media.
- $i = 0;
- foreach (Media::loadMultiple() as $media) {
- foreach ($expected_results as $operation => $expected_result) {
- $expected_link = '';
- // The operations array contains results for each entity.
- if ($expected_result[$i]) {
- $path = Url::fromRoute($info[$operation]['route'], ['media' => $media->id()])->toString();
- $expected_link = '' . $info[$operation]['label'] . '';
- }
- // We check the output: link HTML or empty (access denied).
- $link = $view->style_plugin->getField($i, $info[$operation]['field_id']);
- $this->assertEquals($expected_link, (string) $link);
- }
- $i++;
- // Clean medias as we check results.
- $media->delete();
+ // Check each expected results for every media.
+ $i = 0;
+ foreach (Media::loadMultiple() as $media) {
+ foreach ($expected_results as $operation => $expected_result) {
+ $expected_link = '';
+ // The operations array contains results for each entity.
+ if ($expected_result[$i]) {
+ $path = Url::fromRoute($info[$operation]['route'], ['media' => $media->id()])->toString();
+ $expected_link = '' . $info[$operation]['label'] . '';
}
+ // We check the output: link HTML or empty (access denied).
+ $link = $view->style_plugin->getField($i, $info[$operation]['field_id']);
+ $this->assertEquals($expected_link, (string) $link);
+ }
+ $i++;
+ // Clean medias as we check results.
+ $media->delete();
}
+ }
}
diff --git a/tests/src/Traits/MediaCreationTrait.php b/tests/src/Traits/MediaCreationTrait.php
index 32b59310..f4ae1317 100644
--- a/tests/src/Traits/MediaCreationTrait.php
+++ b/tests/src/Traits/MediaCreationTrait.php
@@ -27,12 +27,12 @@ trait MediaCreationTrait {
protected function createMediaEntity(string $type, array $values = []): MediaInterface {
file_put_contents('public://test.txt', 'Hello test');
$file = File::create([
- 'uri' => 'public://test.txt',
+ 'uri' => 'public://test.txt',
]);
$file->save();
$values += [
- 'bundle' => $type,
- 'field_media_file' => $file->id(),
+ 'bundle' => $type,
+ 'field_media_file' => $file->id(),
];
$media = Media::create($values);
$media->save();