View source
<?php
namespace Drupal\oauth2_server\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\oauth2_server\Utility;
class ClientForm extends EntityForm {
protected $entity;
protected $storage;
protected $entityQuery;
public function __construct(EntityTypeManager $entity_type_manager) {
$this->storage = $entity_type_manager
->getStorage('oauth2_server_client');
$this->entityQuery = $this->storage
->getQuery();
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'));
}
public function form(array $form, FormStateInterface $form_state) {
$client = $this->entity;
$server = $form_state
->get('oauth2_server');
if (!$server) {
throw new \Exception('OAuth2 server was not set');
}
$form['#tree'] = TRUE;
$form['server_id'] = [
'#type' => 'value',
'#value' => $server
->id(),
];
$form['name'] = [
'#title' => $this
->t('Label'),
'#type' => 'textfield',
'#default_value' => $client->name,
'#description' => $this
->t('The human-readable name of this client.'),
'#required' => TRUE,
'#weight' => -50,
];
$form['client_id'] = [
'#title' => $this
->t('Client ID'),
'#type' => 'machine_name',
'#default_value' => $client
->id(),
'#required' => TRUE,
'#weight' => -40,
'#machine_name' => [
'exists' => [
$this,
'exists',
],
],
];
$form['require_client_secret'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Require a client secret'),
'#default_value' => !empty($client
->isNew()) || !empty($client->client_secret),
'#weight' => -35,
];
$grant_types = array_filter($client->settings['override_grant_types'] ? $client->settings['grant_types'] : $server->settings['grant_types']);
$jwt_bearer_enabled = isset($grant_types['urn:ietf:params:oauth:grant-type:jwt-bearer']);
$form['client_secret'] = [
'#title' => $this
->t('Client secret'),
'#type' => 'password',
'#weight' => -30,
'#access' => count($grant_types) != 1 || !$jwt_bearer_enabled,
'#states' => [
'required' => [
'input[name="require_client_secret"]' => [
'checked' => TRUE,
],
],
'visible' => [
'input[name="require_client_secret"]' => [
'checked' => TRUE,
],
],
],
];
if (!empty($client->client_secret)) {
$form['client_secret']['#description'] = $this
->t('Leave this blank, and leave "Require a client secret" checked, to use the previously saved secret.');
unset($form['client_secret']['#states']['required']);
}
$form['public_key'] = [
'#title' => $this
->t('Public key'),
'#type' => 'textarea',
'#default_value' => $client->public_key,
'#required' => TRUE,
'#description' => $this
->t('Used to decode the JWT when the %JWT grant type is used.', [
'%JWT' => $this
->t('JWT bearer'),
]),
'#weight' => -20,
'#access' => $jwt_bearer_enabled,
];
$form['redirect_uri'] = [
'#title' => $this
->t('Redirect URIs'),
'#type' => 'textarea',
'#default_value' => $client->redirect_uri,
'#description' => $this
->t('The absolute URIs to validate against. Enter one value per line.'),
'#required' => TRUE,
'#weight' => -10,
];
$form['automatic_authorization'] = [
'#title' => $this
->t('Automatically authorize this client'),
'#type' => 'checkbox',
'#default_value' => $client->automatic_authorization,
'#description' => $this
->t('This will cause the authorization form to be skipped. <b>Warning:</b> Give to trusted clients only!'),
'#weight' => 39,
];
$form['settings'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Advanced settings'),
'#collapsible' => TRUE,
'#weight' => 40,
];
$form['settings']['override_grant_types'] = [
'#title' => $this
->t('Override available grant types'),
'#type' => 'checkbox',
'#default_value' => !empty($client->settings['override_grant_types']),
];
$form['settings']['allow_implicit'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Allow the implicit flow'),
'#description' => $this
->t('Allows clients to receive an access token without the need for an authorization request token.'),
'#default_value' => !empty($client->settings['allow_implicit']),
'#states' => [
'visible' => [
'#edit-settings-override-grant-types' => [
'checked' => TRUE,
],
],
],
];
$grant_types = Utility::getGrantTypes();
$grant_type_options = [];
foreach ($grant_types as $type => $grant_type) {
$grant_type_options[$type] = $grant_type['name'];
}
$form['settings']['grant_types'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Enabled grant types'),
'#options' => $grant_type_options,
'#default_value' => $client->settings['grant_types'],
'#states' => [
'visible' => [
'#edit-settings-override-grant-types' => [
'checked' => TRUE,
],
],
],
];
foreach ($grant_types as $type => $grant_type) {
if (isset($grant_type['default settings'])) {
$client->settings += $grant_type['default settings'];
}
if (isset($grant_type['settings callback'])) {
$dom_ids = [];
$dom_ids[] = 'edit-settings-override-grant-types';
$dom_ids[] = 'edit-settings-grant-types-' . str_replace('_', '-', $type);
$form['settings'] += $grant_type['settings callback']($client->settings, $dom_ids);
}
}
return parent::form($form, $form_state);
}
public function exists($client_id) {
$entity = $this->entityQuery
->condition('client_id', $client_id)
->execute();
return (bool) $entity;
}
protected function actions(array $form, FormStateInterface $form_state) {
$actions = parent::actions($form, $form_state);
$actions['submit']['#value'] = $this
->t('Save client');
return $actions;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$client_secret = '';
if (!empty($form_state
->getValue('require_client_secret'))) {
if (!empty($form_state
->getValue('client_secret'))) {
$client_secret = $this->entity
->hashClientSecret($form_state
->getValue('client_secret'));
if (!$client_secret) {
throw new \Exception("Failed to hash client secret");
}
}
elseif (!empty($this->entity->client_secret)) {
$client_secret = $this->entity->client_secret;
}
else {
$form_state
->setErrorByName('client_secret', $this
->t('A client secret is required.'));
}
}
$form_state
->setValue('client_secret', $client_secret);
}
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$this
->messenger()
->addMessage($this
->t('The client configuration has been saved.'));
$form_state
->setRedirect('entity.oauth2_server.clients', [
'oauth2_server' => $form_state
->get('oauth2_server')
->id(),
]);
}
}