authman-1.x-dev/src/Form/AuthmanAuthForm.php

src/Form/AuthmanAuthForm.php
<?php

declare(strict_types = 1);

namespace Drupal\authman\Form;

use Drupal\authman\AuthmanPluginManager;
use Drupal\authman\Entity\AuthmanAuth;
use Drupal\authman\Entity\AuthmanAuthInterface;
use Drupal\Component\Plugin\ConfigurableInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Plugin\PluginFormFactoryInterface;
use Drupal\Core\Plugin\PluginWithFormsInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\key\Entity\Key;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Authman instance entity form.
 *
 * @method AuthmanAuthInterface getEntity()
 */
class AuthmanAuthForm extends EntityForm {

  /**
   * Logger.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * Messenger.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * Plugin manager.
   *
   * @var \Drupal\authman\AuthmanPluginManager
   */
  protected $pluginManager;

  /**
   * The plugin form factory.
   *
   * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
   */
  protected $pluginFormFactory;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('logger.factory')->get('authman'),
      $container->get('messenger'),
      $container->get('plugin.manager.authman'),
      $container->get('plugin_form.factory')
    );
  }

  /**
   * Constructs a AuthmanAuthForm.
   *
   * @param \Psr\Log\LoggerInterface $logger
   *   Logger.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   Messenger.
   * @param \Drupal\authman\AuthmanPluginManager $pluginManager
   *   Plugin manager.
   * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
   *   The plugin form factory.
   */
  public function __construct(LoggerInterface $logger, MessengerInterface $messenger, AuthmanPluginManager $pluginManager, PluginFormFactoryInterface $pluginFormFactory) {
    $this->logger = $logger;
    $this->messenger = $messenger;
    $this->pluginManager = $pluginManager;
    $this->pluginFormFactory = $pluginFormFactory;
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state): array {
    $form = parent::form($form, $form_state);

    $authmanConfig = $this->getEntity();

    $form['label'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Label'),
      '#maxlength' => 255,
      '#default_value' => $authmanConfig->label(),
      '#required' => TRUE,
    ];
    $form['id'] = [
      '#type' => 'machine_name',
      '#default_value' => $authmanConfig->id(),
      '#machine_name' => [
        'exists' => [AuthmanAuth::class, 'load'],
        'source' => ['label'],
      ],
      '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
      '#disabled' => !$authmanConfig->isNew(),
    ];

    $form['keys'] = [
      '#type' => 'details',
      '#open' => TRUE,
      '#title' => $this->t('Keys'),
    ];

    $form['keys']['client_key'] = [
      '#type' => 'key_select',
      '#required' => TRUE,
      '#default_value' => $authmanConfig->getClientKeyId(),
      '#key_filters' => [
        'type' => 'authman_oauth_client',
      ],
      '#key_description' => FALSE,
      '#title' => new TranslatableMarkup('Client ID and secret'),
      '#description' => new TranslatableMarkup('Select the key to get client credentials from.'),
    ];

    $form['keys']['access_token_key'] = [
      '#type' => 'key_select',
      '#required' => TRUE,
      '#default_value' => $authmanConfig->getAccessTokenKeyId(),
      '#key_filters' => [
        'type' => 'authman_oauth_access_token',
      ],
      '#key_description' => FALSE,
      '#title' => new TranslatableMarkup('Access token'),
      '#description' => new TranslatableMarkup('Select the key to store access tokens in.'),
    ];

    // Auto-create.
    $canAddKeys = Url::fromRoute('entity.key.add_form')->access();
    if ($canAddKeys) {
      $form['keys']['client_key']['#empty_option'] = $this->t('- Create -');
      $form['keys']['client_key']['#empty_value'] = ':create:';
      $form['keys']['access_token_key']['#empty_option'] = $this->t('- Create -');
      $form['keys']['access_token_key']['#empty_value'] = ':create:';
    }

    $form['plugin'] = [
      '#type' => 'select',
      '#title' => $this->t('Provider'),
      '#options' => array_map(function (array $definition) {
        return $definition['label'];
      }, $this->pluginManager->getDefinitions()),
      '#required' => TRUE,
      '#empty_option' => '- Select -',
      '#default_value' => $authmanConfig->getPluginId(),
      '#description' => $this->t('Select a provider to use'),
      '#ajax' => [
        'callback' => '::ajaxPluginConfiguration',
        'trigger_as' => ['name' => 'update_plugin'],
        'effect' => 'fade',
        'method' => 'replaceWith',
        'wrapper' => 'plugin-settings',
      ],
      '#disabled' => !$this->getEntity()->isNew(),
      '#submit' => ['::submitPluginConfiguration'],
      '#executes_submit_callback' => TRUE,
    ];

    $form['update_plugin'] = [
      '#type' => 'submit',
      '#value' => $this->t('Update plugin'),
      '#name' => 'update_plugin',
      '#attributes' => ['class' => ['js-hide']],
      '#limit_validation_errors' => [['update_plugin']],
      '#ajax' => [
        'callback' => '::ajaxPluginConfiguration',
        'method' => 'replaceWith',
        'effect' => 'fade',
        'wrapper' => 'plugin-settings',
      ],
      '#submit' => ['::submitPluginConfiguration'],
    ];

    $form['plugin_configuration'] = [
      '#prefix' => '<div id="plugin-settings">',
      '#suffix' => '</div>',
      '#tree' => TRUE,
      '#type' => 'details',
      '#open' => TRUE,
      '#title' => $this->t('Provider settings'),
      '#group' => 'provider_settings',
    ];

    $plugin = $authmanConfig->getPlugin();
    if ($plugin) {
      $form['plugin_configuration']['grant_type'] = [
        '#type' => 'radios',
        '#title' => $this->t('Grant type'),
        '#required' => TRUE,
        '#options' => [
          AuthmanAuthInterface::GRANT_AUTHORIZATION_CODE => $this->t('Authorization code'),
          AuthmanAuthInterface::GRANT_DEVICE_CODE => $this->t('Device code'),
          AuthmanAuthInterface::GRANT_CLIENT_CREDENTIALS => $this->t('Client credentials'),
        ],
        '#default_value' => $authmanConfig->getGrantType(),
        '#parents' => ['grant_type'],
      ];

      // Filter out grant types not defined by the plugin definition.
      $pluginGrantTypes = $plugin->getPluginDefinition()['grant_types'] ?? [];
      $form['plugin_configuration']['grant_type']['#options'] = array_intersect_key(
        $form['plugin_configuration']['grant_type']['#options'],
        array_flip($pluginGrantTypes),
      );
    }

    $form['plugin_configuration']['plugin_form'] = [];

    if ($plugin && $plugin instanceof PluginWithFormsInterface && $plugin->hasFormClass('configure')) {
      $subform_state = SubformState::createForSubform($form['plugin_configuration']['plugin_form'], $form, $form_state);
      $form['plugin_configuration']['plugin_form'] += $this->pluginFormFactory
        ->createInstance($plugin, 'configure')
        ->buildConfigurationForm($form['plugin_configuration']['plugin_form'], $subform_state);
    }
    else {
      $form['plugin_configuration']['no_settings']['#markup'] = $this->t('No settings for this plugin.');
    }

    $form['actions'] = ['#type' => 'actions'];
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state): void {
    parent::validateForm($form, $form_state);

    $plugin = $this->getEntity()->getPlugin();
    if ($plugin instanceof PluginWithFormsInterface && $plugin->hasFormClass('configure')) {
      $subformState = SubformState::createForSubform($form['plugin_configuration']['plugin_form'], $form, $form_state);
      $this->pluginFormFactory
        ->createInstance($plugin, 'configure')
        ->validateConfigurationForm($form['plugin_configuration']['plugin_form'], $subformState);
    }
  }

  /**
   * Reload contents of plugin configuration subform.
   */
  public function ajaxPluginConfiguration(array &$form, FormStateInterface $form_state): array {
    return $form['plugin_configuration'];
  }

  /**
   * Reload contents of plugin configuration subform.
   */
  public function submitPluginConfiguration(array &$form, FormStateInterface $form_state): void {
    $this->entity = $this->buildEntity($form, $form_state);
    $form_state->setRebuild();
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    $authmanConfig = $this->getEntity();

    $plugin = $authmanConfig->getPlugin();
    if ($plugin->hasFormClass('configure')) {
      $subformState = SubformState::createForSubform($form['plugin_configuration']['plugin_form'], $form, $form_state);
      $this->pluginFormFactory
        ->createInstance($plugin, 'configure')
        ->submitConfigurationForm($form['plugin_configuration']['plugin_form'], $subformState);

      if ($plugin instanceof ConfigurableInterface) {
        $authmanConfig->settings = $plugin->getConfiguration();
      }
    }

    $id = $form_state->getValue('id');
    $label = $form_state->getValue('label');
    if (':create:' === $form_state->getValue('client_key')) {
      $clientKey = Key::create([
        'id' => $this->generateUniqueKeyId('authman_' . $id . '_client'),
        'label' => 'Authman Client IDs for ' . $label,
        'key_type' => 'authman_oauth_client',
      ]);
      $clientKey->save();
      $form_state->setValue('client_key', $clientKey->id());
    }

    if (':create:' === $form_state->getValue('access_token_key')) {
      $accessTokenKey = Key::create([
        'id' => $this->generateUniqueKeyId('authman_' . $id . '_access_token'),
        'label' => 'Authman Access Token for ' . $label,
        'key_type' => 'authman_oauth_access_token',
      ]);
      $accessTokenKey->save();
      $form_state->setValue('access_token_key', $accessTokenKey->id());
    }

    parent::submitForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state): int {
    $authmanConfig = $this->getEntity();

    $status = $authmanConfig->save();

    $edit_link = $this->entity->toLink($this->t('Edit'), 'edit-form')->toString();
    if ($status == SAVED_UPDATED) {
      $form_state->setRedirectUrl($authmanConfig->toUrl('collection'));
      $this->messenger()->addStatus($this->t('Authman instance %label has been updated.', ['%label' => $authmanConfig->label()]));
      $this->logger->notice('Authman instance %label has been updated.', [
        '%label' => $authmanConfig->label(),
        'link' => $edit_link,
      ]);
      return $status;
    }

    $form_state->setRedirectUrl($authmanConfig->toUrl('information'));
    $this->messenger()->addStatus($this->t('Authman instance %label has been added.', ['%label' => $authmanConfig->label()]));
    $this->logger->notice('Authman instance %label has been added.', [
      '%label' => $authmanConfig->label(),
      'link' => $edit_link,
    ]);

    return $status;
  }

  /**
   * Generates a unique Key ID based on a template.
   *
   * @param string $baseKeyId
   *   A ID template.
   *
   * @return string
   *   A unique Key ID.
   */
  protected function generateUniqueKeyId(string $baseKeyId): string {
    $i = 1;
    do {
      $keyId = ($i === 1 ? $baseKeyId : sprintf('%s_%d', $baseKeyId, $i));
      $i++;
      /** @var \Drupal\key\KeyInterface|null $key */
      $key = Key::load($keyId);
    } while ($key);
    return $keyId;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc