final class TeamPermissionHandler in Apigee Edge 8
Provides the available team permissions based on yml files.
To define team permissions you can use a $module.team_permissions.yml file.
If your module needs to define dynamic permissions you can use the permission_providers key to declare a class that implements DynamicTeamPermissionProviderInterface that will return an array of team permissions. Each item in the array can contain the same keys as an entry in $module.team_permissions.yml.
Here is an example (comments have been added):
# The key is the team permission machine name, and is required.
manage team members:
# (required) The human-readable name of the team permission, to be shown
# on the team permission administration page.
title: 'Manage team members'
# (optional) Additional description for the team permission used in the UI.
description: 'Add/remove team members.'
# (optional) The category that the team permission belongs (ex.: Team Apps)
# to be shown on the team permission administration page.
# Default is the name of the provider module.
category: 'Members'
# An array of classes used to generate dynamic team permissions.
permission_providers:
# Each item in the array must implement
# DynamicTeamPermissionProviderInterface interface.
- Drupal\apigee_edge_teams\DefaultTeamPermissionsProvider
Based on Drupal core's PermissionHandler with a bunch of improvements.
Hierarchy
- class \Drupal\apigee_edge_teams\TeamPermissionHandler implements TeamPermissionHandlerInterface uses StringTranslationTrait
Expanded class hierarchy of TeamPermissionHandler
See also
\Drupal\user\PermissionHandler
\Drupal\apigee_edge_teams\DynamicTeamPermissionProviderInterface
1 string reference to 'TeamPermissionHandler'
- apigee_edge_teams.services.yml in modules/
apigee_edge_teams/ apigee_edge_teams.services.yml - modules/apigee_edge_teams/apigee_edge_teams.services.yml
1 service uses TeamPermissionHandler
- apigee_edge_teams.team_permissions in modules/
apigee_edge_teams/ apigee_edge_teams.services.yml - Drupal\apigee_edge_teams\TeamPermissionHandler
File
- modules/
apigee_edge_teams/ src/ TeamPermissionHandler.php, line 72
Namespace
Drupal\apigee_edge_teamsView source
final class TeamPermissionHandler implements TeamPermissionHandlerInterface {
use StringTranslationTrait;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
private $moduleHandler;
/**
* The class resolver.
*
* @var \Drupal\Core\DependencyInjection\ClassResolverInterface
*/
private $classResolver;
/**
* The YAML discovery object instance cache.
*
* Yaml discovery to find all .team_permissions.yml files.
*
* Use getYamlDiscovery() instead.
*
* @var \Drupal\Core\Discovery\YamlDiscovery|null
*/
private $yamlDiscovery;
/**
* The team membership manager service.
*
* @var \Drupal\apigee_edge_teams\TeamMembershipManagerInterface
*/
private $teamMembershipManager;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
private $entityTypeManager;
/**
* TeamPermissionHandler constructor.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
* The class resolver.
* @param \Drupal\apigee_edge_teams\TeamMembershipManagerInterface $team_membership_manager
* The team membership manager service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(ModuleHandlerInterface $module_handler, ClassResolverInterface $class_resolver, TeamMembershipManagerInterface $team_membership_manager, EntityTypeManagerInterface $entity_type_manager) {
$this->moduleHandler = $module_handler;
$this->classResolver = $class_resolver;
$this->teamMembershipManager = $team_membership_manager;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public function getPermissions() : array {
$all_permissions = $this
->buildPermissionsYaml();
return $this
->sortPermissions($all_permissions);
}
/**
* {@inheritdoc}
*/
public function getDeveloperPermissionsByTeam(TeamInterface $team, AccountInterface $account) : array {
if ($account
->isAnonymous()) {
throw new InvalidArgumentException('Anonymous user can not be member of a team.');
}
$permissions = [];
try {
$developer_team_ids = $this->teamMembershipManager
->getTeams($account
->getEmail());
} catch (\Exception $e) {
$developer_team_ids = [];
}
// Only add team membership based permissions to the list if the developer
// is still member of the team in Apigee Edge.
if (in_array($team
->id(), $developer_team_ids)) {
/** @var \Drupal\apigee_edge_teams\Entity\TeamRoleInterface $member_role */
$member_role = $this->entityTypeManager
->getStorage('team_role')
->load(TeamRoleInterface::TEAM_MEMBER_ROLE);
$permissions += $member_role
->getPermissions();
/** @var \Drupal\apigee_edge_teams\Entity\TeamMemberRoleInterface|null $dev_team_role */
$dev_team_role = $this->entityTypeManager
->getStorage('team_member_role')
->loadByDeveloperAndTeam($account, $team);
if ($dev_team_role) {
foreach ($dev_team_role
->getTeamRoles() as $role) {
$permissions = array_merge($permissions, $role
->getPermissions());
}
}
}
// Allow 3rd-party modules to modify a developer's team-level permissions
// withing a team.
// WARNING: Alter hooks gets called even if the developer is not member
// of a team (company) in Apigee Edge. This allows to grant team-level
// permissions to a developer (Drupal user) to a team without adding it as a
// member to the team (company) in Apigee Edge. (Ex.: for team management
// purposes, etc.)
$this->moduleHandler
->alter('apigee_edge_teams_developer_permissions_by_team', $permissions, $team, $account);
return array_unique($permissions);
}
/**
* Gets the YAML discovery.
*
* @return \Drupal\Core\Discovery\YamlDiscovery
* The YAML discovery.
*/
private function getYamlDiscovery() : YamlDiscovery {
if (!isset($this->yamlDiscovery)) {
$this->yamlDiscovery = new YamlDiscovery('team_permissions', $this->moduleHandler
->getModuleDirectories());
}
return $this->yamlDiscovery;
}
/**
* Builds all team permissions provided by .team_permissions.yml files.
*
* @return \Drupal\apigee_edge_teams\Structure\TeamPermission[]
* Array of team permissions.
*
* @throws \Drupal\apigee_edge_teams\Exception\InvalidArgumentException
* If permission provider class does not implement
* DynamicTeamPermissionProviderInterface.
* @throws \InvalidArgumentException
* If permission provider class does not exist.
*/
protected function buildPermissionsYaml() : array {
$all_permissions = [];
$all_dynamic_permissions = [];
$module_names = $this
->getModuleNames();
foreach ($this
->getYamlDiscovery()
->findAll() as $provider => $permissions) {
if (isset($permissions['permission_providers'])) {
foreach ($permissions['permission_providers'] as $fqcn) {
// Thanks for class resolver permission providers can implement
// ContainerInjectionInterface and access services. This should be
// a better approach than what PermissionHandler does with controller
// resolver.
$permission_provider = $this->classResolver
->getInstanceFromDefinition($fqcn);
if ($permission_provider instanceof DynamicTeamPermissionProviderInterface) {
/** @var \Drupal\apigee_edge_teams\Structure\TeamPermission $dynamic_permission */
foreach ($permission_provider
->permissions() as $dynamic_permission) {
$all_dynamic_permissions[$dynamic_permission
->getName()] = $dynamic_permission;
}
}
else {
throw new InvalidArgumentException(sprintf('%s must implement %s.', $fqcn, DynamicTeamPermissionProviderInterface::class));
}
}
unset($permissions['permission_providers']);
}
foreach ($permissions as $name => $permission) {
if (!is_array($permission)) {
$permission = [
'title' => $permission,
];
}
$permission['name'] = $name;
$permission['title'] = $this
->t($permission['title']);
$permission['description'] = isset($permission['description']) ? $this
->t($permission['description']) : NULL;
$permission['category'] = !empty($permission['category']) ? $this
->t($permission['category']) : $this
->t($module_names[$provider]);
$all_permissions[$name] = $permission;
}
}
return array_map(function (array $permission) {
return new TeamPermission($permission['name'], $permission['title'], $permission['category'], $permission['description']);
}, $all_permissions) + $all_dynamic_permissions;
}
/**
* Sorts the given team permissions by category and title.
*
* @param array $all_permissions
* The team permissions to be sorted.
*
* @return \Drupal\apigee_edge_teams\Structure\TeamPermission[]
* Sorted team permissions.
*/
protected function sortPermissions(array $all_permissions = []) {
uasort($all_permissions, function (TeamPermission $permission_a, TeamPermission $permission_b) {
if ($permission_a
->getCategory() == $permission_b
->getCategory()) {
return $permission_a
->getLabel() > $permission_b
->getLabel();
}
else {
return $permission_a
->getCategory() > $permission_b
->getCategory();
}
});
return $all_permissions;
}
/**
* Returns all module names.
*
* @return string[]
* Returns the human readable names of all modules keyed by machine name.
*/
protected function getModuleNames() : array {
$modules = [];
foreach (array_keys($this->moduleHandler
->getModuleList()) as $module) {
$modules[$module] = $this->moduleHandler
->getName($module);
}
asort($modules);
return $modules;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
TeamPermissionHandler:: |
private | property | The class resolver. | |
TeamPermissionHandler:: |
private | property | The entity type manager. | |
TeamPermissionHandler:: |
private | property | The module handler. | |
TeamPermissionHandler:: |
private | property | The team membership manager service. | |
TeamPermissionHandler:: |
private | property | The YAML discovery object instance cache. | |
TeamPermissionHandler:: |
protected | function | Builds all team permissions provided by .team_permissions.yml files. | |
TeamPermissionHandler:: |
public | function |
Returns team permissions of a developer within a team. Overrides TeamPermissionHandlerInterface:: |
|
TeamPermissionHandler:: |
protected | function | Returns all module names. | |
TeamPermissionHandler:: |
public | function |
Gets all available team permissions. Overrides TeamPermissionHandlerInterface:: |
|
TeamPermissionHandler:: |
private | function | Gets the YAML discovery. | |
TeamPermissionHandler:: |
protected | function | Sorts the given team permissions by category and title. | |
TeamPermissionHandler:: |
public | function | TeamPermissionHandler constructor. |