View source
<?php
declare (strict_types=1);
namespace Drupal\authorization\Form;
use Drupal\authorization\Entity\AuthorizationProfile;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\authorization\Provider\ProviderPluginManager;
use Drupal\authorization\Consumer\ConsumerPluginManager;
class AuthorizationProfileForm extends EntityForm {
protected $providerPluginManager;
protected $consumerPluginManager;
protected $provider;
protected $consumer;
protected $storage;
public function __construct(EntityTypeManagerInterface $entity_type_manager, ProviderPluginManager $provider_plugin_manager, ConsumerPluginManager $consumer_plugin_manager) {
$this->storage = $entity_type_manager
->getStorage('authorization_profile');
$this->providerPluginManager = $provider_plugin_manager;
$this->consumerPluginManager = $consumer_plugin_manager;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('plugin.manager.authorization.provider'), $container
->get('plugin.manager.authorization.consumer'));
}
public function getEntity() : AuthorizationProfile {
return parent::getEntity();
}
protected function getProviderPluginManager() : ProviderPluginManager {
return $this->providerPluginManager;
}
protected function getConsumerPluginManager() : ConsumerPluginManager {
return $this->consumerPluginManager;
}
public function form(array $form, FormStateInterface $form_state) : array {
$form = parent::form($form, $form_state);
$this
->buildEntityForm($form, $form_state);
if ($form) {
$this
->buildProviderConfigForm($form, $form_state);
$this
->buildConsumerConfigForm($form, $form_state);
$this
->buildConditionsForm($form, $form_state);
$this
->buildMappingForm($form, $form_state);
$form['#prefix'] = "<div id='authorization-profile-form'>";
$form['#suffix'] = "</div>";
}
return $form;
}
public function buildEntityForm(array &$form, FormStateInterface $form_state) : void {
$authorization_profile = $this
->getEntity();
$form['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Profile name'),
'#maxlength' => 255,
'#default_value' => $authorization_profile
->label(),
'#required' => TRUE,
];
$form['id'] = [
'#type' => 'machine_name',
'#default_value' => $authorization_profile
->id(),
'#machine_name' => [
'exists' => '\\Drupal\\authorization\\Entity\\AuthorizationProfile::load',
],
'#disabled' => !$authorization_profile
->isNew(),
];
$form['status'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Enabled'),
'#default_value' => $authorization_profile
->get('status'),
];
$provider_options = $this
->getProviderOptions();
if ($provider_options) {
if (count($provider_options) === 1) {
$authorization_profile
->set('provider', key($provider_options));
}
$form['provider'] = [
'#type' => 'radios',
'#title' => $this
->t('Provider'),
'#options' => $provider_options,
'#default_value' => $authorization_profile
->getProviderId(),
'#required' => TRUE,
'#ajax' => [
'callback' => [
get_class($this),
'buildAjaxProviderConfigForm',
],
'wrapper' => 'authorization-profile-form',
'method' => 'replace',
'effect' => 'fade',
],
];
}
else {
$this
->messenger()
->addError($this
->t('There are no provider plugins available. You will need to install and enable something like the LDAP Authorization Provider module that ships with LDAP.'));
$form['#access'] = FALSE;
$form['#markup'] = $this
->t('Authorization profile cannot be created.');
$form['#cache'] = [
'tags' => [],
'contexts' => [],
'max-age' => 0,
];
}
$consumer_options = $this
->getConsumerOptions();
if ($consumer_options) {
if (count($consumer_options) == 1) {
$authorization_profile
->set('consumer', key($consumer_options));
}
$form['consumer'] = [
'#type' => 'radios',
'#title' => $this
->t('Consumer'),
'#options' => $consumer_options,
'#default_value' => $authorization_profile
->getConsumerId(),
'#required' => TRUE,
'#ajax' => [
'callback' => [
get_class($this),
'buildAjaxConsumerConfigForm',
],
'wrapper' => 'authorization-profile-form',
'method' => 'replace',
'effect' => 'fade',
],
];
}
else {
$this
->messenger()
->addError($this
->t('There are no consumer plugins available. You can enable the Authorization Drupal Roles submodule to provide integration with core user roles or write your own using that as a template.'));
$form['#access'] = FALSE;
$form['#markup'] = $this
->t('Authorization profile cannot be created.');
$form['#cache'] = [
'tags' => [],
'contexts' => [],
'max-age' => 0,
];
}
}
protected function getProviderOptions() : array {
$options = [];
foreach ($this
->getProviderPluginManager()
->getDefinitions() as $plugin_id => $plugin_definition) {
$options[$plugin_id] = Html::escape($plugin_definition['label']);
}
return $options;
}
private function buildProviderConfigForm(array &$form, FormStateInterface $form_state) : void {
$authorization_profile = $this
->getEntity();
$form['provider_config'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'authorization-provider-config-form',
],
'#tree' => TRUE,
];
if ($authorization_profile
->hasValidProvider()) {
$provider = $authorization_profile
->getProvider();
if ($provider_form = $provider
->buildConfigurationForm([], $form_state)) {
if (!empty($form_state
->getValues()['provider']) && count($this
->getProviderOptions()) > 1) {
$this
->messenger()
->addWarning($this
->t('You changed the provider, please review its configuration.'));
}
$form['provider_config']['#type'] = 'details';
$form['provider_config']['#title'] = $this
->t('Configure %plugin provider', [
'%plugin' => $provider
->label(),
]);
$form['provider_config']['#description'] = $provider
->getDescription();
$form['provider_config']['#open'] = TRUE;
$form['provider_config'] += $provider_form;
}
}
elseif (!$authorization_profile
->isNew()) {
$this
->messenger()
->addError($this
->t('The provider plugin is missing or invalid.'));
}
}
private function buildConsumerConfigForm(array &$form, FormStateInterface $form_state) : void {
$authorization_profile = $this
->getEntity();
$form['consumer_config'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'authorization-consumer-config-form',
],
'#tree' => TRUE,
];
if ($authorization_profile
->hasValidConsumer()) {
$consumer = $authorization_profile
->getConsumer();
if ($consumer_form = $consumer
->buildConfigurationForm([], $form_state)) {
if (!empty($form_state
->getValues()['consumer']) && count($this
->getConsumerOptions()) > 1) {
$this
->messenger()
->addWarning($this
->t('You changed the consumer, please review its configuration.'));
}
$form['consumer_config']['#type'] = 'details';
$form['consumer_config']['#title'] = $this
->t('Configure %plugin consumer', [
'%plugin' => $consumer
->label(),
]);
$form['consumer_config']['#description'] = $consumer
->getDescription();
$form['consumer_config']['#open'] = TRUE;
$form['consumer_config'] += $consumer_form;
}
}
elseif (!$authorization_profile
->isNew()) {
$this
->messenger()
->addError($this
->t('The consumer plugin is missing or invalid.'));
}
}
protected function getConsumerOptions() : array {
$options = [];
foreach ($this
->getConsumerPluginManager()
->getDefinitions() as $plugin_id => $plugin_definition) {
$options[$plugin_id] = Html::escape($plugin_definition['label']);
}
return $options;
}
public static function buildAjaxProviderConfigForm(array $form, FormStateInterface $form_state) : array {
return $form;
}
public static function buildAjaxProviderRowForm(array $form, FormStateInterface $form_state) : array {
return $form['provider_mappings'];
}
public static function buildAjaxConsumerConfigForm(array $form, FormStateInterface $form_state) : array {
return $form;
}
public static function buildAjaxConsumerRowForm(array $form, FormStateInterface $form_state) : array {
return $form['consumer_mappings'];
}
private function buildConditionsForm(array &$form, FormStateInterface $form_state) : void {
$authorization_profile = $this
->getEntity();
if (!$authorization_profile
->hasValidProvider() || !$authorization_profile
->hasValidConsumer()) {
return;
}
if (!property_exists($this, 'provider') || !$this->provider) {
$this->provider = $authorization_profile
->getProvider();
}
if (!property_exists($this, 'consumer') || !$this->consumer) {
$this->consumer = $authorization_profile
->getConsumer();
}
$tokens = [];
$tokens += $authorization_profile
->getProvider()
->getTokens();
$tokens += $authorization_profile
->getConsumer()
->getTokens();
$form['conditions'] = [
'#type' => 'details',
'#title' => $this
->t('Configure conditions'),
'#open' => TRUE,
];
$synchronization_modes = [];
if ($this->provider
->isSyncOnLogonSupported()) {
$synchronization_modes['user_logon'] = $this
->t('When a user logs on via <em>@provider_name</em>.', $tokens);
}
$form['conditions']['synchronization_modes'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('When should <em>@consumer_name</em> be granted/revoked from a user?', $tokens),
'#options' => $synchronization_modes,
'#default_value' => $authorization_profile
->get('synchronization_modes') ? $authorization_profile
->get('synchronization_modes') : [],
'#description' => '',
];
$synchronization_actions = [];
if ($this->provider
->revocationSupported()) {
$synchronization_actions['revoke_provider_provisioned'] = $this
->t('Revoke <em>@consumer_name</em> grants previously granted by <em>@provider_name</em> in this profile.', $tokens);
}
if ($this->consumer
->consumerTargetCreationAllowed()) {
$synchronization_actions['create_consumers'] = $this
->t('Create <em>@consumer_name</em> targets if they do not exist.', $tokens);
}
$form['conditions']['synchronization_actions'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('What actions would you like performed when <em>@consumer_name</em> are granted/revoked from a user?', $tokens),
'#options' => $synchronization_actions,
'#default_value' => $authorization_profile
->get('synchronization_actions') ? $authorization_profile
->get('synchronization_actions') : [],
];
}
private function buildMappingForm(array &$form, FormStateInterface $form_state) : void {
$authorization_profile = $this
->getEntity();
if (($authorization_profile
->hasValidProvider() || $form_state
->getValue('provider')) && ($authorization_profile
->hasValidConsumer() || $form_state
->getValue('consumer'))) {
$provider = $authorization_profile
->getProvider();
$consumer = $authorization_profile
->getConsumer();
$tokens = [];
$tokens += $provider
->getTokens();
$tokens += $consumer
->getTokens();
$form['mappings'] = [
'#type' => 'table',
'#responsive' => TRUE,
'#weight' => 100,
'#title' => $this
->t('Configure mapping from @provider_name to @consumer_name', $tokens),
'#header' => [
$provider
->label(),
$consumer
->label(),
$this
->t('Delete'),
],
'#prefix' => '<div id="authorization-mappings-wrapper">',
'#suffix' => '</div>',
];
$mappings_fields = $form_state
->get('mappings_fields');
if (empty($mappings_fields)) {
$count_current_mappings = max(count($authorization_profile
->getProviderMappings()), count($authorization_profile
->getConsumerMappings()));
$mappings_fields = $count_current_mappings > 0 ? $count_current_mappings - 1 : 1;
$form_state
->set('mappings_fields', $mappings_fields);
}
for ($row_key = 0; $row_key <= $mappings_fields; $row_key++) {
$form['mappings'][$row_key]['provider_mappings'] = $provider
->buildRowForm($form, $form_state, $row_key);
$form['mappings'][$row_key]['consumer_mappings'] = $consumer
->buildRowForm($form, $form_state, $row_key);
$form['mappings'][$row_key]['delete'] = [
'#type' => 'checkbox',
'#default_value' => 0,
];
}
$form['mappings'][]['mappings_add_another'] = [
'#type' => 'submit',
'#value' => $this
->t('Add Another'),
'#submit' => [
'::mappingsAddAnother',
],
'#limit_validation_errors' => [],
'#ajax' => [
'callback' => '::mappingsAjaxCallback',
'wrapper' => 'authorization-mappings-wrapper',
],
'#weight' => 103,
'#wrapper_attributes' => [
'colspan' => 3,
],
];
$form['mappings_provider_help'] = [
'#type' => 'markup',
'#markup' => $provider
->buildRowDescription($form, $form_state),
'#weight' => 101,
];
$form['mappings_consumer_help'] = [
'#type' => 'markup',
'#markup' => $consumer
->buildRowDescription($form, $form_state),
'#weight' => 102,
];
}
}
public function validateForm(array &$form, FormStateInterface $form_state) : void {
parent::validateForm($form, $form_state);
$authorization_profile = $this
->getEntity();
if ($authorization_profile
->getProviderId() !== $form_state
->getValues()['provider']) {
$input = $form_state
->getUserInput();
$input['provider_config'] = [];
$form_state
->set('input', $input);
}
elseif ($form['provider_config']['#type'] === 'details' && $authorization_profile
->hasValidProvider()) {
$provider_form_state = new SubFormState($form_state, [
'provider_config',
]);
$authorization_profile
->getProvider()
->validateConfigurationForm($form['provider_config'], $provider_form_state);
}
if ($authorization_profile
->getConsumerId() !== $form_state
->getValues()['consumer']) {
$input = $form_state
->getUserInput();
$input['consumer_config'] = [];
$form_state
->set('input', $input);
}
elseif ($form['consumer_config']['#type'] === 'details' && $authorization_profile
->hasValidConsumer()) {
$consumer_form_state = new SubFormState($form_state, [
'consumer_config',
]);
$authorization_profile
->getConsumer()
->validateConfigurationForm($form['consumer_config'], $consumer_form_state);
}
if ($form_state
->getValue('mappings')) {
$mappings_form_state = new SubFormState($form_state, [
'mappings',
]);
$authorization_profile
->getConsumer()
->validateRowForm($form['mappings'], $mappings_form_state);
$authorization_profile
->getProvider()
->validateRowForm($form['mappings'], $mappings_form_state);
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$authorization_profile = $this
->getEntity();
if ($form['provider_config']['#type'] === 'details' && $authorization_profile
->hasValidProvider()) {
$provider_form_state = new SubFormState($form_state, [
'provider_config',
]);
$authorization_profile
->getProvider()
->submitConfigurationForm($form['provider_config'], $provider_form_state);
}
if ($form['consumer_config']['#type'] === 'details' && $authorization_profile
->hasValidConsumer()) {
$consumer_form_state = new SubFormState($form_state, [
'consumer_config',
]);
$authorization_profile
->getConsumer()
->submitConfigurationForm($form['consumer_config'], $consumer_form_state);
}
if ($form['mappings']) {
$mappings_form_state = new SubFormState($form_state, [
'mappings',
]);
$authorization_profile
->getConsumer()
->submitRowForm($form['mappings'], $mappings_form_state);
$authorization_profile
->getProvider()
->submitRowForm($form['mappings'], $mappings_form_state);
$values = $form_state
->getValues();
$provider_mappings = $this
->extractArrayByName($values['mappings'], 'provider_mappings');
$consumer_mappings = $this
->extractArrayByName($values['mappings'], 'consumer_mappings');
foreach ($values['mappings'] as $key => $value) {
if (empty($value) || $value['delete'] == 1) {
unset($provider_mappings[$key]);
unset($consumer_mappings[$key]);
}
}
if ($provider_mappings && $consumer_mappings) {
$authorization_profile
->setProviderMappings(array_values($provider_mappings));
$authorization_profile
->setConsumerMappings(array_values($consumer_mappings));
}
}
return $authorization_profile;
}
private function extractArrayByName(array $data, $name) : array {
$mapping = [];
foreach ($data as $value) {
if (isset($value[$name])) {
$mapping[] = $value[$name];
}
}
return $mapping;
}
public function save(array $form, FormStateInterface $form_state) : void {
$authorization_profile = $this->entity;
$status = $authorization_profile
->save();
switch ($status) {
case SAVED_NEW:
$this
->messenger()
->addStatus($this
->t('Created the %label Authorization profile.', [
'%label' => $authorization_profile
->label(),
]));
break;
default:
$this
->messenger()
->addStatus($this
->t('Saved the %label Authorization profile.', [
'%label' => $authorization_profile
->label(),
]));
}
$form_state
->setRedirectUrl($authorization_profile
->toUrl('collection'));
}
public function mappingsAjaxCallback(array &$form, FormStateInterface $form_state) : array {
return $form['mappings'];
}
public function mappingsAddAnother(array &$form, FormStateInterface $form_state) : void {
$form_state
->set('mappings_fields', $form_state
->get('mappings_fields') + 1);
$form_state
->setRebuild();
}
}