diff --git a/config/schema/uw_cfg_common.schema.yml b/config/schema/uw_cfg_common.schema.yml index 3703b507a7659df161f5b55dedf4e5db3095e607..498b970f8459939a9dfe683b9c15dc4d1c7ffc68 100644 --- a/config/schema/uw_cfg_common.schema.yml +++ b/config/schema/uw_cfg_common.schema.yml @@ -15,3 +15,20 @@ sendgrid_integration.settings: apikey: type: string label: 'API key for sendgrid' +webform.settings.third_party.uw_cfg_common: + type: mapping + label: 'Webform uw_cfg_common configuration' + mapping: + settings: + type: mapping + label: 'uw_cfg_common settings' + mapping: + access_control_method: + type: string + label: 'Choose who can view and submit the form' + ad_require_groups: + type: string + label: 'Limit form submission to these Active Directory groups' + ad_deny_groups: + type: string + label: 'Prevent form submission for these Active Directory groups' diff --git a/uw_cfg_common.module b/uw_cfg_common.module index 20ae4ee7acce3a01d1c44ccbdf7dd51dda8ac811..e5ff0eb86dcbad2709c5a91b4644d825283e083f 100644 --- a/uw_cfg_common.module +++ b/uw_cfg_common.module @@ -130,6 +130,61 @@ function uw_cfg_common_form_webform_admin_config_submissions_form_alter(array &$ * Configure admin/structure/webform/manage/WEBFORM_ID/access. */ function uw_cfg_common_form_webform_settings_access_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void { + /** @var \Drupal\webform\WebformInterface $webform */ + $webform = $form_state->getFormObject()->getEntity(); + + // Choose access control method. + $form['access']['create']['uw_access_control_method'] = [ + '#type' => 'radios', + '#title' => t('Choose who can view and submit the form'), + '#options' => [ + 'all' => t('Everyone'), + 'auth' => t('Users who are logged in'), + 'group' => t('Users specified by Active Directory groups'), + 'user' => t('Users specified below'), + 'anon' => t('Users who are logged out (for anonymous submission)'), + ], + '#default_value' => $webform->getThirdPartySetting('uw_cfg_common', 'access_control_method') ?: 'all', + '#required' => TRUE, + '#weight' => -50, + ]; + + // Access by Active Directory group. + $form['access']['create']['uw_ad_access'] = [ + '#type' => 'details', + '#title' => t('Access control by Active Directory group'), + '#required' => TRUE, + '#open' => TRUE, + '#states' => [ + 'visible' => [ + 'input[name="access[create][uw_access_control_method]"]' => ['value' => 'group'], + ], + ], + ]; + $form['access']['create']['uw_ad_access']['ad_require_groups'] = [ + '#type' => 'textarea', + '#title' => t('Limit form submission to these Active Directory groups'), + '#description' => t('Put one Active Directory group per line. To complete the form, the user must be in at least one of these groups. Leave blank to allow everyone.'), + '#default_value' => implode("\r\n", $webform->getThirdPartySetting('uw_cfg_common', 'ad_require_groups') ?: []), + ]; + $form['access']['create']['uw_ad_access']['ad_deny_groups'] = [ + '#type' => 'textarea', + '#title' => t('Prevent form submission for these Active Directory groups'), + '#description' => t('Put one Active Directory group per line. To complete the form, the user must not be in any of these groups. Leave blank to allow everyone.'), + '#default_value' => implode("\r\n", $webform->getThirdPartySetting('uw_cfg_common', 'ad_deny_groups') ?: []), + ]; + + // Validate and submit handler to save UW settings. + $form['actions']['submit']['#validate'][] = '_uw_cfg_common_form_webform_settings_access_form_validate'; + $form['actions']['submit']['#submit'][] = '_uw_cfg_common_form_webform_settings_access_form_submit'; + + // Users control is hidden or required, the latter when authz by user. + $access_rule = [ + 'input[name="access[create][uw_access_control_method]"]' => ['value' => 'user'], + ]; + $form['access']['create']['users']['#states']['required'][] = $access_rule; + $form['access']['create']['users']['#states']['visible'][] = $access_rule; + // Remove sections for access control that should not be available. $sections_to_remove = [ 'update_any', @@ -162,6 +217,93 @@ function uw_cfg_common_form_webform_settings_access_form_alter(array &$form, For } } +/** + * Form validate handler. + */ +function _uw_cfg_common_form_webform_settings_access_form_validate(array $form, FormStateInterface $form_state): void { + // Validate UW settings. + $access_control_method = [ + 'access', + 'create', + 'uw_access_control_method', + ]; + $access_control_method = $form_state->getValue($access_control_method); + switch ($access_control_method) { + // Validate AD groups. + case 'group': + $fields = [ + 'ad_require_groups' => NULL, + 'ad_deny_groups' => NULL, + ]; + foreach (array_keys($fields) as $field) { + // Get groups. + $setting = [ + 'access', + 'create', + 'uw_ad_access', + $field, + ]; + $fields[$field] = uw_cfg_common_array_split_clean($form_state->getValue($setting)); + $form_state->setValue($setting, $fields[$field]); + + // Raise error for invalid groups. + foreach ($fields[$field] as $group) { + if (!preg_match('/^[A-Za-z0-9_& -]+$/', $group)) { + $form_state->setError($form['access']['create']['uw_ad_access'][$field], t('Invalid group: %group.', ['%group' => substr($group, 0, 100)])); + break; + } + } + } + + // Raise error if no groups are entered. + if (!array_filter($fields)) { + $form_state->setError($form['access']['create']['uw_ad_access'], t('Provide at least one group to use for access control.')); + } + // Fall-through. + case 'all': + case 'auth': + case 'anon': + // Except for case 'user', ensure no user access constraint is set. + $form_state->setValue(['access', 'create', 'users'], NULL); + break; + } +} + +/** + * Form submit handler. + */ +function _uw_cfg_common_form_webform_settings_access_form_submit(array $form, FormStateInterface $form_state): void { + // Save UW settings. + if ($webform = $form_state->getFormObject()->getEntity()) { + // Access control method. + $access_control_method = [ + 'access', + 'create', + 'uw_access_control_method', + ]; + $access_control_method = $form_state->getValue($access_control_method); + $webform->setThirdPartySetting('uw_cfg_common', 'access_control_method', $access_control_method); + + // Only save groups if that is the access method. Otherwise, they would be + // saved without having been validated. + if ($access_control_method === 'group') { + // AD group access. + foreach (['ad_require_groups', 'ad_deny_groups'] as $field) { + $setting = [ + 'access', + 'create', + 'uw_ad_access', + $field, + ]; + $setting = $form_state->getValue($setting); + $webform->setThirdPartySetting('uw_cfg_common', $field, $setting); + } + } + + $webform->save(); + } +} + /** * Implements hook_form_FORM_ID_alter(). *