Skip to content
Snippets Groups Projects
Commit 3fa1eefa authored by Eirik Morland's avatar Eirik Morland
Browse files

Issue #3427184 by eiriksm: Add an access service for team access

parent 010ab253
No related branches found
No related tags found
1 merge request!38Add service and definition
Pipeline #117427 passed with warnings
<?php
namespace Drupal\violinist_teams\Access;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\violinist_teams\TeamNode;
use Symfony\Component\Routing\Route;
/**
* Access service for team access.
*/
final class TeamAccess implements AccessInterface {
public function __construct(
private AccountProxyInterface $currentUser,
) {}
/**
* Controls the access for this service.
*/
public function access(Route $route, RouteMatchInterface $route_match) : AccessResult {
$access_type = $route->getRequirement('_violinist_teams_access');
$result = AccessResult::forbidden();
$team = $route_match->getParameter('team');
if (!$team instanceof TeamNode) {
return AccessResult::neutral('No team node found');
}
// @todo In theory we could add more types here. For example, it could
// theoretically be wanted to show something to members only, but not to
// admins. Currently that is not really needed though.
switch ($access_type) {
case 'admin':
$result = AccessResult::allowedIf($team->isAdmin($this->currentUser));
break;
default:
// The default is to only allow if you are part of the team. Either as a
// member or as an admin.
$result = AccessResult::allowedIf($team->isMemberOrAdminFromUserId($this->currentUser->id()));
break;
}
return $result;
}
}
<?php
namespace Drupal\Tests\violinist_teams\Kernel;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\node\Entity\Node;
use Drupal\user\Entity\User;
use Symfony\Component\Routing\Route;
/**
* Tests for the team access service.
*
* @group violinist_teams
*/
class TeamAccessTest extends KernelTestBase {
/**
* Test access.
*
* @dataProvider accessProvider
*/
public function testAdminAccessUserMember($user_index, $type, $expected_class) {
/** @var \Drupal\violinist_teams\TeamNode $node */
$node = Node::create([
'type' => $this->nodeType->id(),
'title' => 'test',
]);
$node->save();
/** @var \Drupal\violinist_teams\Access\TeamAccess $access_service */
$access_service = $this->container->get('violinist_teams.access_check');
$users = [];
$user = User::create([
'name' => 'test',
'mail' => 'test@test.com',
]);
$user->save();
$node->appendMember($user)->save();
$users[] = $user;
$user = User::create([
'name' => 'test2',
'mail' => 'test2@test.com',
]);
$user->save();
$node->appendAdmin($user)->save();
$users[] = $user;
$use_user = $users[$user_index];
$this->container->get('current_user')->setAccount($use_user);
$route = $this->createMock(Route::class);
$route->method('getRequirement')->willReturn($type);
$route_match = $this->createMock(RouteMatchInterface::class);
$route_match->method('getParameter')->willReturn($node);
$access = $access_service->access($route, $route_match);
self::assertInstanceOf($expected_class, $access);
}
/**
* Data provider for access tests.
*/
public function accessProvider() {
return [
[0, 'admin', 'Drupal\Core\Access\AccessResultNeutral'],
[0, 'member', 'Drupal\Core\Access\AccessResultAllowed'],
[1, 'admin', 'Drupal\Core\Access\AccessResultAllowed'],
[1, 'member', 'Drupal\Core\Access\AccessResultAllowed'],
];
}
}
......@@ -5,3 +5,9 @@ services:
- '@entity_type.manager'
- '@state'
Drupal\violinist_teams\TeamManager: '@violinist_teams.team_manager'
violinist_teams.access_check:
class: Drupal\violinist_teams\Access\TeamAccess
autowire: true
tags:
- { name: access_check, applies_to: _violinist_teams_access }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment