Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
219 / 219 |
|
100.00% |
18 / 18 |
CRAP | |
100.00% |
1 / 1 |
AuthorizationProfileEditForm | |
100.00% |
219 / 219 |
|
100.00% |
18 / 18 |
53 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
create | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
getFormId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
form | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
1 | |||
buildEntityForm | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
buildProviderConfigForm | |
100.00% |
20 / 20 |
|
100.00% |
1 / 1 |
3 | |||
buildConsumerConfigForm | |
100.00% |
20 / 20 |
|
100.00% |
1 / 1 |
3 | |||
buildAjaxProviderRowForm | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
buildAjaxConsumerRowForm | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
buildConditionsForm | |
100.00% |
37 / 37 |
|
100.00% |
1 / 1 |
8 | |||
getProvider | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
getConsumer | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
buildMappingForm | |
100.00% |
55 / 55 |
|
100.00% |
1 / 1 |
8 | |||
validateForm | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
4 | |||
submitForm | |
100.00% |
28 / 28 |
|
100.00% |
1 / 1 |
9 | |||
extractArrayByName | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
mappingsAjaxCallback | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
mappingsAddAnother | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Drupal\authorization\Form; |
6 | |
7 | use Drupal\Core\Entity\EntityTypeManagerInterface; |
8 | use Drupal\Core\Form\FormStateInterface; |
9 | use Drupal\authorization\Consumer\ConsumerPluginManager; |
10 | use Drupal\authorization\Provider\ProviderPluginManager; |
11 | use Symfony\Component\DependencyInjection\ContainerInterface; |
12 | |
13 | /** |
14 | * Authorization profile form. |
15 | * |
16 | * @package Drupal\authorization\Form |
17 | */ |
18 | final class AuthorizationProfileEditForm extends AuthorizationProfileForm { |
19 | |
20 | /** |
21 | * Constructs a AuthorizationProfileForm. |
22 | * |
23 | * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager |
24 | * The entity manager. |
25 | * @param \Drupal\authorization\Provider\ProviderPluginManager $provider_plugin_manager |
26 | * The Provider plugin manager. |
27 | * @param \Drupal\authorization\Consumer\ConsumerPluginManager $consumer_plugin_manager |
28 | * The Consumer plugin manager. |
29 | */ |
30 | public function __construct( |
31 | EntityTypeManagerInterface $entity_type_manager, |
32 | ProviderPluginManager $provider_plugin_manager, |
33 | ConsumerPluginManager $consumer_plugin_manager, |
34 | ) { |
35 | $this->storage = $entity_type_manager->getStorage('authorization_profile'); |
36 | $this->providerPluginManager = $provider_plugin_manager; |
37 | $this->consumerPluginManager = $consumer_plugin_manager; |
38 | } |
39 | |
40 | /** |
41 | * {@inheritdoc} |
42 | */ |
43 | public static function create(ContainerInterface $container) { |
44 | return new static( |
45 | $container->get('entity_type.manager'), |
46 | $container->get('plugin.manager.authorization.provider'), |
47 | $container->get('plugin.manager.authorization.consumer') |
48 | ); |
49 | } |
50 | |
51 | /** |
52 | * {@inheritdoc} |
53 | */ |
54 | public function getFormId(): string { |
55 | return 'authorization_profile_edit_form'; |
56 | } |
57 | |
58 | /** |
59 | * {@inheritdoc} |
60 | */ |
61 | public function form(array $form, FormStateInterface $form_state): array { |
62 | $form = parent::form($form, $form_state); |
63 | $form['#attached']['library'][] = 'authorization/profile'; |
64 | $form['#prefix'] = "<div id='authorization-profile-form'>"; |
65 | $this->buildEntityForm($form, $form_state, FALSE); |
66 | $form['configuration'] = [ |
67 | '#type' => 'vertical_tabs', |
68 | '#weight' => 10, |
69 | '#default_tab' => 'conditions', |
70 | ]; |
71 | $this->buildProviderConfigForm($form, $form_state); |
72 | $this->buildConsumerConfigForm($form, $form_state); |
73 | $this->buildConditionsForm($form, $form_state); |
74 | $this->buildMappingForm($form, $form_state); |
75 | |
76 | $form['#suffix'] = "</div>"; |
77 | |
78 | return $form; |
79 | } |
80 | |
81 | /** |
82 | * {@inheritdoc} |
83 | */ |
84 | protected function buildEntityForm(array &$form, FormStateInterface $form_state, $is_new): void { |
85 | parent::buildEntityForm($form, $form_state, $is_new); |
86 | unset($form['provider']); |
87 | unset($form['consumer']); |
88 | } |
89 | |
90 | /** |
91 | * Builds the provider-specific configuration form. |
92 | * |
93 | * @param array $form |
94 | * An associative array containing the structure of the form. |
95 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
96 | * The current state of the form. |
97 | */ |
98 | protected function buildProviderConfigForm(array &$form, FormStateInterface $form_state): void { |
99 | /** @var \Drupal\authorization\AuthorizationProfileInterface $authorization_profile */ |
100 | $authorization_profile = $this->getEntity(); |
101 | |
102 | $form['provider_config'] = [ |
103 | '#type' => 'details', |
104 | '#attributes' => [ |
105 | 'id' => 'authorization-provider-config-form', |
106 | ], |
107 | '#tree' => TRUE, |
108 | '#weight' => 0, |
109 | '#group' => 'configuration', |
110 | ]; |
111 | |
112 | if (!$authorization_profile->hasValidProvider()) { |
113 | return; |
114 | } |
115 | $provider = $authorization_profile->getProvider(); |
116 | $provider_form = $provider->buildConfigurationForm([], $form_state); |
117 | if (empty($provider_form)) { |
118 | return; |
119 | } |
120 | // Modify the provider plugin configuration container element. |
121 | $form['provider_config']['#title'] = $this->t('Provider %plugin', ['%plugin' => $provider->label()]); |
122 | $form['provider_config']['#description'] = $provider->getDescription(); |
123 | $form['provider_config']['#open'] = TRUE; |
124 | // Attach the provider plugin configuration form. |
125 | $form['provider_config'] += $provider_form; |
126 | |
127 | } |
128 | |
129 | /** |
130 | * Builds the consumer-specific configuration form. |
131 | * |
132 | * @param array $form |
133 | * An associative array containing the structure of the form. |
134 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
135 | * The current state of the form. |
136 | */ |
137 | protected function buildConsumerConfigForm(array &$form, FormStateInterface $form_state): void { |
138 | /** @var \Drupal\authorization\AuthorizationProfileInterface $authorization_profile */ |
139 | $authorization_profile = $this->getEntity(); |
140 | |
141 | $form['consumer_config'] = [ |
142 | '#type' => 'details', |
143 | '#attributes' => [ |
144 | 'id' => 'authorization-consumer-config-form', |
145 | ], |
146 | '#tree' => TRUE, |
147 | '#weight' => 50, |
148 | '#group' => 'configuration', |
149 | ]; |
150 | |
151 | if (!$authorization_profile->hasValidConsumer()) { |
152 | return; |
153 | } |
154 | |
155 | $consumer = $authorization_profile->getConsumer(); |
156 | $consumer_form = $consumer->buildConfigurationForm([], $form_state); |
157 | if (empty($consumer_form)) { |
158 | return; |
159 | } |
160 | |
161 | $form['consumer_config']['#title'] = $this->t('Consumer %plugin', ['%plugin' => $consumer->label()]); |
162 | $form['consumer_config']['#description'] = $consumer->getDescription(); |
163 | $form['consumer_config']['#open'] = TRUE; |
164 | // Attach the consumer plugin configuration form. |
165 | $form['consumer_config'] += $consumer_form; |
166 | } |
167 | |
168 | /** |
169 | * Handles switching the selected provider plugin. |
170 | * |
171 | * @param array $form |
172 | * An associative array containing the structure of the form. |
173 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
174 | * The current state of the form. |
175 | * |
176 | * @return array |
177 | * Returns the provider mappings. |
178 | */ |
179 | public static function buildAjaxProviderRowForm(array $form, FormStateInterface $form_state): array { |
180 | return $form['provider_mappings']; |
181 | } |
182 | |
183 | /** |
184 | * Handles switching the selected consumer plugin. |
185 | * |
186 | * @param array $form |
187 | * An associative array containing the structure of the form. |
188 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
189 | * The current state of the form. |
190 | * |
191 | * @return array |
192 | * Returns the consumer mappings in the form. |
193 | */ |
194 | public static function buildAjaxConsumerRowForm(array $form, FormStateInterface $form_state): array { |
195 | return $form['consumer_mappings']; |
196 | } |
197 | |
198 | /** |
199 | * Build the conditions form. |
200 | * |
201 | * @param array $form |
202 | * An associative array containing the structure of the form. |
203 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
204 | * The current state of the form. |
205 | */ |
206 | protected function buildConditionsForm(array &$form, FormStateInterface $form_state): void { |
207 | /** @var \Drupal\authorization\AuthorizationProfileInterface $authorization_profile */ |
208 | $authorization_profile = $this->getEntity(); |
209 | |
210 | $profile_is_invalid = !$authorization_profile->hasValidProvider() || !$authorization_profile->hasValidConsumer(); |
211 | if ($profile_is_invalid) { |
212 | return; |
213 | } |
214 | |
215 | $this->getProvider($authorization_profile); |
216 | $this->getConsumer($authorization_profile); |
217 | |
218 | $tokens = []; |
219 | |
220 | $tokens += $authorization_profile->getProvider()->getTokens(); |
221 | $tokens += $authorization_profile->getConsumer()->getTokens(); |
222 | |
223 | $form['conditions'] = [ |
224 | '#type' => 'details', |
225 | '#title' => $this->t('Conditions'), |
226 | '#open' => TRUE, |
227 | '#weight' => -50, |
228 | '#group' => 'configuration', |
229 | ]; |
230 | |
231 | $synchronization_modes = []; |
232 | if ($this->provider->isSyncOnLogonSupported()) { |
233 | $synchronization_modes['user_logon'] = $this->t('When a user logs on via <em>@provider_name</em>.', $tokens); |
234 | } |
235 | |
236 | $form['conditions']['synchronization_modes'] = [ |
237 | '#type' => 'checkboxes', |
238 | '#title' => $this->t('When should <em>@consumer_name</em> be granted/revoked from a user?', $tokens), |
239 | '#options' => $synchronization_modes, |
240 | '#default_value' => $authorization_profile->get('synchronization_modes') ? $authorization_profile->get('synchronization_modes') : [], |
241 | '#description' => '', |
242 | ]; |
243 | |
244 | $synchronization_actions = []; |
245 | |
246 | if ($this->provider->revocationSupported()) { |
247 | $synchronization_actions['revoke_provider_provisioned'] = $this->t('Revoke <em>@consumer_name</em> grants previously granted by <em>@provider_name</em> in this profile.', $tokens); |
248 | } |
249 | |
250 | if ($this->consumer->consumerTargetCreationAllowed()) { |
251 | $synchronization_actions['create_consumers'] = $this->t('Create <em>@consumer_name</em> targets if they do not exist.', $tokens); |
252 | } |
253 | |
254 | $form['conditions']['synchronization_actions'] = [ |
255 | '#type' => 'checkboxes', |
256 | '#title' => $this->t('What actions would you like performed when <em>@consumer_name</em> are granted/revoked from a user?', $tokens), |
257 | '#options' => $synchronization_actions, |
258 | '#default_value' => $authorization_profile->get('synchronization_actions') ? $authorization_profile->get('synchronization_actions') : [], |
259 | ]; |
260 | } |
261 | |
262 | /** |
263 | * Get the provider. |
264 | * |
265 | * @param \Drupal\authorization\AuthorizationProfileInterface $authorization_profile |
266 | * The authorization profile. |
267 | */ |
268 | protected function getProvider($authorization_profile): void { |
269 | $get_provider = !property_exists($this, 'provider') || !$this->provider; |
270 | if ($get_provider) { |
271 | $this->provider = $authorization_profile->getProvider(); |
272 | } |
273 | } |
274 | |
275 | /** |
276 | * Get the consumer. |
277 | * |
278 | * @param \Drupal\authorization\AuthorizationProfileInterface $authorization_profile |
279 | * The authorization profile. |
280 | */ |
281 | protected function getConsumer($authorization_profile): void { |
282 | $get_consumer = !property_exists($this, 'consumer') || !$this->consumer; |
283 | if ($get_consumer) { |
284 | $this->consumer = $authorization_profile->getConsumer(); |
285 | } |
286 | } |
287 | |
288 | /** |
289 | * Build the mapping form. |
290 | * |
291 | * @param array $form |
292 | * An associative array containing the structure of the form. |
293 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
294 | * The current state of the form. |
295 | */ |
296 | protected function buildMappingForm(array &$form, FormStateInterface $form_state): void { |
297 | /** @var \Drupal\authorization\AuthorizationProfileInterface $authorization_profile */ |
298 | $authorization_profile = $this->getEntity(); |
299 | |
300 | if (($authorization_profile->hasValidProvider() || $form_state->getValue('provider')) && |
301 | ($authorization_profile->hasValidConsumer() || $form_state->getValue('consumer'))) { |
302 | |
303 | $provider = $authorization_profile->getProvider(); |
304 | $consumer = $authorization_profile->getConsumer(); |
305 | |
306 | $tokens = []; |
307 | $tokens += $provider->getTokens(); |
308 | $tokens += $consumer->getTokens(); |
309 | |
310 | $form['mappings'] = [ |
311 | '#type' => 'table', |
312 | '#responsive' => TRUE, |
313 | '#weight' => 0, |
314 | '#title' => $this->t('Configure mapping from @provider_name to @consumer_name', $tokens), |
315 | '#header' => [ |
316 | $provider->label(), |
317 | $consumer->label(), |
318 | $this->t('Delete'), |
319 | ], |
320 | '#prefix' => '<div id="authorization-mappings-wrapper" class="authorization-mappings">', |
321 | '#suffix' => '</div>', |
322 | ]; |
323 | |
324 | $mappings_fields = $form_state->get('mappings_fields'); |
325 | if (empty($mappings_fields)) { |
326 | $count_current_mappings = max(count($authorization_profile->getProviderMappings()), count($authorization_profile->getConsumerMappings())); |
327 | $mappings_fields = ($count_current_mappings > 0) ? $count_current_mappings - 1 : 1; |
328 | $form_state->set('mappings_fields', $mappings_fields); |
329 | } |
330 | |
331 | for ($row_key = 0; $row_key <= $mappings_fields; $row_key++) { |
332 | $form['mappings'][$row_key]['provider_mappings'] = $provider->buildRowForm($form, $form_state, $row_key); |
333 | $form['mappings'][$row_key]['consumer_mappings'] = $consumer->buildRowForm($form, $form_state, $row_key); |
334 | $form['mappings'][$row_key]['delete'] = [ |
335 | '#type' => 'checkbox', |
336 | '#default_value' => 0, |
337 | ]; |
338 | } |
339 | |
340 | $form['mappings'][]['mappings_add_another'] = [ |
341 | '#type' => 'submit', |
342 | '#value' => $this->t('Add Another'), |
343 | '#submit' => ['::mappingsAddAnother'], |
344 | '#limit_validation_errors' => [], |
345 | '#ajax' => [ |
346 | 'callback' => '::mappingsAjaxCallback', |
347 | 'wrapper' => 'authorization-mappings-wrapper', |
348 | ], |
349 | '#weight' => 103, |
350 | '#wrapper_attributes' => ['colspan' => 3], |
351 | ]; |
352 | |
353 | $form['mappings_provider_help'] = [ |
354 | '#type' => 'markup', |
355 | '#markup' => $provider->buildRowDescription($form, $form_state), |
356 | '#weight' => 101, |
357 | ]; |
358 | |
359 | $form['mappings_consumer_help'] = [ |
360 | '#type' => 'markup', |
361 | '#markup' => $consumer->buildRowDescription($form, $form_state), |
362 | '#weight' => 102, |
363 | ]; |
364 | } |
365 | } |
366 | |
367 | /** |
368 | * {@inheritdoc} |
369 | */ |
370 | public function validateForm(array &$form, FormStateInterface $form_state): void { |
371 | parent::validateForm($form, $form_state); |
372 | /** @var \Drupal\authorization\AuthorizationProfileInterface $authorization_profile */ |
373 | $authorization_profile = $this->getEntity(); |
374 | |
375 | if ($authorization_profile->hasValidProvider()) { |
376 | $provider_form_state = new SubFormState($form_state, ['provider_config']); |
377 | $authorization_profile->getProvider() |
378 | ->validateConfigurationForm($form['provider_config'], $provider_form_state); |
379 | } |
380 | |
381 | if ($authorization_profile->hasValidConsumer()) { |
382 | $consumer_form_state = new SubFormState($form_state, ['consumer_config']); |
383 | $authorization_profile->getConsumer() |
384 | ->validateConfigurationForm($form['consumer_config'], $consumer_form_state); |
385 | } |
386 | |
387 | if ($form_state->getValue('mappings')) { |
388 | $mappings_form_state = new SubFormState($form_state, ['mappings']); |
389 | $authorization_profile->getConsumer() |
390 | ->validateRowForm($form['mappings'], $mappings_form_state); |
391 | $authorization_profile->getProvider() |
392 | ->validateRowForm($form['mappings'], $mappings_form_state); |
393 | } |
394 | |
395 | } |
396 | |
397 | /** |
398 | * {@inheritdoc} |
399 | */ |
400 | public function submitForm(array &$form, FormStateInterface $form_state) { |
401 | parent::submitForm($form, $form_state); |
402 | /** @var \Drupal\authorization\AuthorizationProfileInterface */ |
403 | $authorization_profile = $this->getEntity(); |
404 | |
405 | // Check before loading the provider plugin so we don't throw an exception. |
406 | if ($authorization_profile->hasValidProvider()) { |
407 | $provider_form_state = new SubFormState($form_state, ['provider_config']); |
408 | $authorization_profile->getProvider() |
409 | ->submitConfigurationForm($form['provider_config'], $provider_form_state); |
410 | } |
411 | // Check before loading the consumer plugin so we don't throw an exception. |
412 | if ($authorization_profile->hasValidConsumer()) { |
413 | $consumer_form_state = new SubFormState($form_state, ['consumer_config']); |
414 | $authorization_profile->getConsumer() |
415 | ->submitConfigurationForm($form['consumer_config'], $consumer_form_state); |
416 | } |
417 | |
418 | if ($form['mappings']) { |
419 | $mappings_form_state = new SubFormState($form_state, ['mappings']); |
420 | $authorization_profile->getConsumer() |
421 | ->submitRowForm($form['mappings'], $mappings_form_state); |
422 | $authorization_profile->getProvider() |
423 | ->submitRowForm($form['mappings'], $mappings_form_state); |
424 | |
425 | $values = $form_state->getValues(); |
426 | |
427 | $provider_mappings = $this->extractArrayByName($values['mappings'], 'provider_mappings'); |
428 | $consumer_mappings = $this->extractArrayByName($values['mappings'], 'consumer_mappings'); |
429 | |
430 | foreach ($values['mappings'] as $key => $value) { |
431 | if (empty($value) || $value['delete'] == 1) { |
432 | unset($provider_mappings[$key]); |
433 | unset($consumer_mappings[$key]); |
434 | } |
435 | } |
436 | $set_mappings = $provider_mappings && $consumer_mappings; |
437 | if ($set_mappings) { |
438 | $authorization_profile->setProviderMappings(array_values($provider_mappings)); |
439 | $authorization_profile->setConsumerMappings(array_values($consumer_mappings)); |
440 | } |
441 | } |
442 | |
443 | return $authorization_profile; |
444 | } |
445 | |
446 | /** |
447 | * Transform the array keyed by row to a separate array for each consumer. |
448 | * |
449 | * @param array $data |
450 | * Source data from form. |
451 | * @param string $name |
452 | * Which provisioner to filter by. |
453 | * |
454 | * @return array |
455 | * Transformed array. |
456 | */ |
457 | private function extractArrayByName(array $data, $name): array { |
458 | $mapping = []; |
459 | foreach ($data as $value) { |
460 | if (isset($value[$name])) { |
461 | $mapping[] = $value[$name]; |
462 | } |
463 | } |
464 | return $mapping; |
465 | } |
466 | |
467 | /** |
468 | * Ajax Callback for the form. |
469 | * |
470 | * @param array $form |
471 | * The form being passed in. |
472 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
473 | * The form state. |
474 | * |
475 | * @return array |
476 | * The form element we are changing via ajax |
477 | */ |
478 | public function mappingsAjaxCallback(array &$form, FormStateInterface $form_state): array { |
479 | return $form['mappings']; |
480 | } |
481 | |
482 | /** |
483 | * Functionality for our ajax callback. |
484 | * |
485 | * @param array $form |
486 | * The form being passed in. |
487 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
488 | * The form state, passed by reference so we can modify. |
489 | */ |
490 | public function mappingsAddAnother(array &$form, FormStateInterface $form_state): void { |
491 | $form_state->set('mappings_fields', ($form_state->get('mappings_fields') + 1)); |
492 | $form_state->setRebuild(); |
493 | } |
494 | |
495 | } |