ai_upgrade_assistant-0.2.0-alpha2/src/Access/DynamicPermissionHandler.php
src/Access/DynamicPermissionHandler.php
<?php
namespace Drupal\ai_upgrade_assistant\Access;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
/**
* Provides dynamic permission handling for AI Upgrade Assistant.
*/
class DynamicPermissionHandler {
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The state service.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Dynamic permission cache.
*
* @var array
*/
protected static $permissionCache = [];
/**
* Constructs a new DynamicPermissionHandler.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\Core\State\StateInterface $state
* The state service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(
ConfigFactoryInterface $config_factory,
StateInterface $state,
ModuleHandlerInterface $module_handler
) {
$this->configFactory = $config_factory;
$this->state = $state;
$this->moduleHandler = $module_handler;
}
/**
* Gets dynamic permissions.
*
* @return array
* Array of permission definitions.
*/
public function getPermissions() {
if (!empty(static::$permissionCache)) {
return static::$permissionCache;
}
$permissions = [];
// Base permissions
$permissions['administer ai upgrade assistant'] = [
'title' => t('Administer AI Upgrade Assistant'),
'description' => t('Full access to all AI Upgrade Assistant features.'),
'restrict access' => TRUE,
];
// Add dynamic module-specific permissions
$modules = $this->moduleHandler->getModuleList();
foreach ($modules as $module_name => $module) {
$permissions["analyze $module_name upgrades"] = [
'title' => t('Analyze @module upgrades', ['@module' => $module_name]),
'description' => t('Run upgrade analysis on the @module module.', ['@module' => $module_name]),
];
}
// Add feature-based permissions
$config = $this->configFactory->get('ai_upgrade_assistant.settings');
$features = $config->get('enabled_features') ?: [];
foreach ($features as $feature => $enabled) {
if ($enabled) {
$permissions["use ai upgrade $feature"] = [
'title' => t('Use @feature feature', ['@feature' => str_replace('_', ' ', $feature)]),
'description' => $this->getFeatureDescription($feature),
];
}
}
// Add environment-specific permissions
if ($config->get('enable_production_mode')) {
$permissions['bypass environment check'] = [
'title' => t('Bypass environment check'),
'description' => t('WARNING: Allow module usage in production environments.'),
'restrict access' => TRUE,
];
}
// Add pattern sharing permissions
if ($config->get('enable_pattern_sharing')) {
$permissions['share upgrade patterns'] = [
'title' => t('Share upgrade patterns'),
'description' => t('Contribute patterns to the community dataset.'),
];
$permissions['moderate shared patterns'] = [
'title' => t('Moderate shared patterns'),
'description' => t('Review and approve patterns before sharing.'),
'restrict access' => TRUE,
];
}
// Add analysis level permissions
foreach (['basic', 'advanced', 'expert'] as $level) {
$permissions["run $level analysis"] = [
'title' => t('Run @level analysis', ['@level' => $level]),
'description' => $this->getAnalysisLevelDescription($level),
];
}
// Cache permissions
static::$permissionCache = $permissions;
return $permissions;
}
/**
* Checks access for a specific operation.
*
* @param string $operation
* The operation to check.
* @param \Drupal\Core\Session\AccountInterface $account
* The user account.
* @param array $context
* Additional context.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function checkAccess($operation, AccountInterface $account, array $context = []) {
// Admin always has access
if ($account->hasPermission('administer ai upgrade assistant')) {
return AccessResult::allowed();
}
// Check environment restrictions
if (!$this->isEnvironmentAllowed($account)) {
return AccessResult::forbidden('Module cannot be used in production environments.');
}
// Check operation-specific permissions
switch ($operation) {
case 'analyze':
return $this->checkAnalysisAccess($account, $context);
case 'share_pattern':
return $this->checkPatternSharingAccess($account, $context);
case 'view_reports':
return $this->checkReportAccess($account, $context);
default:
return AccessResult::neutral();
}
}
/**
* Checks if the current environment is allowed.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The user account.
*
* @return bool
* TRUE if environment is allowed.
*/
protected function isEnvironmentAllowed(AccountInterface $account) {
$config = $this->configFactory->get('ai_upgrade_assistant.settings');
if ($config->get('enable_production_mode')) {
return TRUE;
}
if ($account->hasPermission('bypass environment check')) {
return TRUE;
}
return !$this->state->get('ai_upgrade_assistant.is_production', FALSE);
}
/**
* Checks access for analysis operations.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The user account.
* @param array $context
* Additional context.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
protected function checkAnalysisAccess(AccountInterface $account, array $context) {
$module = $context['module'] ?? NULL;
$level = $context['level'] ?? 'basic';
// Check module-specific permission
if ($module && !$account->hasPermission("analyze $module upgrades")) {
return AccessResult::forbidden();
}
// Check analysis level permission
if (!$account->hasPermission("run $level analysis")) {
return AccessResult::forbidden();
}
return AccessResult::allowed();
}
/**
* Checks access for pattern sharing operations.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The user account.
* @param array $context
* Additional context.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
protected function checkPatternSharingAccess(AccountInterface $account, array $context) {
if (!$this->configFactory->get('ai_upgrade_assistant.settings')->get('enable_pattern_sharing')) {
return AccessResult::forbidden('Pattern sharing is disabled.');
}
if (!$account->hasPermission('share upgrade patterns')) {
return AccessResult::forbidden();
}
// Check if pattern needs moderation
if (!empty($context['needs_moderation']) && !$account->hasPermission('moderate shared patterns')) {
return AccessResult::forbidden('Pattern requires moderation.');
}
return AccessResult::allowed();
}
/**
* Checks access for report viewing operations.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The user account.
* @param array $context
* Additional context.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
protected function checkReportAccess(AccountInterface $account, array $context) {
$report = $context['report'] ?? NULL;
if (!$report) {
return AccessResult::neutral();
}
// Check if user has access to all modules in the report
foreach ($report->getModules() as $module) {
if (!$account->hasPermission("analyze $module upgrades")) {
return AccessResult::forbidden();
}
}
return AccessResult::allowed();
}
/**
* Gets description for a feature permission.
*
* @param string $feature
* Feature name.
*
* @return string
* Feature description.
*/
protected function getFeatureDescription($feature) {
$descriptions = [
'pattern_sharing' => t('Share and contribute upgrade patterns with the community.'),
'advanced_analysis' => t('Use advanced code analysis features.'),
'batch_processing' => t('Process multiple modules in batches.'),
'custom_rules' => t('Create and manage custom upgrade rules.'),
];
return $descriptions[$feature] ?? t('Use @feature functionality.', ['@feature' => str_replace('_', ' ', $feature)]);
}
/**
* Gets description for an analysis level.
*
* @param string $level
* Analysis level.
*
* @return string
* Level description.
*/
protected function getAnalysisLevelDescription($level) {
switch ($level) {
case 'basic':
return t('Run basic compatibility checks and simple upgrades.');
case 'advanced':
return t('Run detailed analysis including deprecated code detection.');
case 'expert':
return t('Run comprehensive analysis with custom rule support.');
default:
return t('Run @level level analysis.', ['@level' => $level]);
}
}
}
