Skip to content

Commit

Permalink
Merge pull request #10 from donquixote/group-integration-services
Browse files Browse the repository at this point in the history
Issue #52: Collabora access on group media
  • Loading branch information
donquixote committed Nov 27, 2024
2 parents ab13218 + 140647a commit 88ce891
Show file tree
Hide file tree
Showing 9 changed files with 455 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,8 @@ jobs:
- name: PhpUnit
run: |
docker-compose exec -T web ./vendor/bin/phpunit -vvv --debug
- name: PhpUnit - groupmedia 3
run: |
docker-compose exec -T web composer require --dev drupal/groupmedia:^3 -W
docker-compose exec -T web ./vendor/bin/phpunit -vvv --debug --testsuite "Collabora Online Group"
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"drupal/core-composer-scaffold": "^10.3.6",
"drupal/core-dev": "^10.3.6",
"drupal/core-recommended": "^10.3.6",
"drupal/groupmedia": "^4",
"drupal/groupmedia": "^3 || ^4",
"drush/drush": "^12.4",
"openeuropa/task-runner": "^2@dev",
"openeuropa/task-runner-drupal-project-symlink": "^1.0.0-beta6",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
services:
group.relation_handler.permission_provider.collabora_group_media:
class: 'Drupal\collabora_online_group\Plugin\Group\RelationHandler\CollaboraPermissionProvider'
decorates: group.relation_handler.permission_provider.group_media
arguments: [ '@group.relation_handler.permission_provider.collabora_group_media.inner' ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Drupal\collabora_online_group\Plugin\Group\RelationHandler;

use Drupal\groupmedia\Plugin\Group\RelationHandler\GroupMediaPermissionProvider;

/**
* Provides Collabora permissions for group.
*/
class CollaboraPermissionProvider extends GroupMediaPermissionProvider {

/**
* {@inheritdoc}
*/
public function buildPermissions(): array {
$permissions = $this->parent->buildPermissions();

/* @see \Drupal\group\Plugin\Group\RelationHandlerDefault\PermissionProvider::buildPermissions() */
$provider_chain = $this->groupRelationTypeManager()->getPermissionProvider($this->pluginId);

// Add Collabora permissions.
$prefix = 'Entity:';
if ($name = $provider_chain->getPermission('preview in collabora', 'entity')) {
$permissions[$name] = $this->buildPermission("$prefix Preview %entity_type in collabora");
}
if ($name = $provider_chain->getPermission('edit in collabora', 'entity')) {
$permissions[$name] = $this->buildPermission("$prefix Edit any %entity_type in collabora");
}
if ($name = $provider_chain->getPermission('edit in collabora', 'entity', 'own')) {
$permissions[$name] = $this->buildPermission("$prefix Edit own %entity_type in collabora");
}

return $permissions;
}

/**
* {@inheritdoc}
*/
public function getPermission($operation, $target, $scope = 'any'): bool|string {
if ($target === 'entity') {
switch ($operation) {
case 'preview in collabora':
return "preview $this->pluginId in collabora";

case 'edit in collabora':
if (
$this->definesEntityPermissions &&
($this->implementsOwnerInterface || $scope === 'any')
) {
return "edit $scope $this->pluginId in collabora";
}

return FALSE;
}
}

return $this->parent->getPermission($operation, $target, $scope);
}

}
169 changes: 169 additions & 0 deletions modules/collabora_online_group/tests/src/Kernel/AccessTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<?php

declare(strict_types=1);

namespace Drupal\Tests\collabora_online_group\Kernel;

use Drupal\group\PermissionScopeInterface;
use Drupal\Tests\collabora_online\Traits\MediaCreationTrait;
use Drupal\Tests\collabora_online_group\Traits\GroupRelationTrait;
use Drupal\Tests\group\Kernel\GroupKernelTestBase;
use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
use Drupal\Tests\user\Traits\UserCreationTrait;
use Drupal\user\RoleInterface;

/**
* Tests Collabora group access.
*/
class AccessTest extends GroupKernelTestBase {

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 function setUp(): void {
parent::setUp();

$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,
]);

// 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) {
// 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)
);
}
}

/**
* Retrieves the scenarios to be tested.
*
* @return array
* An array of test scenarios.
*/
protected function getTestScenarios(): array {
return [
'preview_no_permisions' => [
'result' => FALSE,
'permissions' => [],
'group_permissions' => [],
'operation' => 'preview in collabora',
'scope' => 'any'
],
'preview_global_permisions' => [
'result' => FALSE,
'permissions' => ['preview document in collabora'],
'group_permissions' => [],
'operation' => 'preview in collabora',
'scope' => 'any'
],
'preview_group_permisions' =>[
'result' => TRUE,
'permissions' => [],
'group_permissions' => ['preview group_media:document in collabora'],
'operation' => 'preview in collabora',
'scope' => 'any'
],
'edit_any_no_permisions' => [
'result' => FALSE,
'permissions' => [],
'group_permissions' => [],
'operation' => 'edit in collabora',
'scope' => 'any'
],
'edit_any_global_permisions' => [
'result' => FALSE,
'permissions' => ['edit any document in collabora'],
'group_permissions' => [],
'operation' => 'edit in collabora',
'scope' => 'any'
],
'edit_any_group_permisions' => [
'result' => TRUE,
'permissions' => [],
'group_permissions' => ['edit any group_media:document in collabora'],
'operation' => 'edit in collabora',
'scope' => 'any'
],
'edit_own_no_permisions' => [
'result' => FALSE,
'permissions' => [],
'group_permissions' => [],
'operation' => 'edit in collabora',
'scope' => 'own'
],
'edit_own_global_permisions' => [
'result' => FALSE,
'permissions' => ['edit own document in collabora'],
'group_permissions' => [],
'operation' => 'edit in collabora',
'scope' => 'own'
],
'edit_own_group_permisions' => [
'result' => TRUE,
'permissions' => [],
'group_permissions' => ['edit own group_media:document in collabora'],
'operation' => 'edit in collabora',
'scope' => 'own'
],
];
}

}
120 changes: 120 additions & 0 deletions modules/collabora_online_group/tests/src/Kernel/PermissionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

declare(strict_types=1);

namespace Drupal\Tests\collabora_online_group\Kernel;

use Drupal\Tests\collabora_online_group\Traits\GroupRelationTrait;
use Drupal\Tests\group\Kernel\GroupKernelTestBase;
use Drupal\Tests\media\Traits\MediaTypeCreationTrait;

/**
* Tests group permissions.
*/
class PermissionTest extends GroupKernelTestBase {

use MediaTypeCreationTrait;
use GroupRelationTrait;

/**
* {@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']);

// 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);

// 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 <em class="placeholder">media item</em> in collabora',
'edit own group_media:document in collabora' => 'Entity: Edit own <em class="placeholder">media item</em> in collabora',
'preview group_media:document in collabora' => 'Entity: Preview <em class="placeholder">media item</em> 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 <em class="placeholder">media item</em> in collabora',
'edit any group_media:spreadsheet in collabora' => 'Entity: Edit any <em class="placeholder">media item</em> in collabora',
'edit own group_media:document in collabora' => 'Entity: Edit own <em class="placeholder">media item</em> in collabora',
'edit own group_media:spreadsheet in collabora' => 'Entity: Edit own <em class="placeholder">media item</em> in collabora',
'preview group_media:document in collabora' => 'Entity: Preview <em class="placeholder">media item</em> in collabora',
'preview group_media:spreadsheet in collabora' => 'Entity: Preview <em class="placeholder">media item</em> 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,
));
}
}
Loading

0 comments on commit 88ce891

Please sign in to comment.