You are here

public function CasSettings::buildForm in CAS 8

Same name and namespace in other branches
  1. 2.x src/Form/CasSettings.php \Drupal\cas\Form\CasSettings::buildForm()

Form constructor.

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Return value

array The form structure.

Overrides ConfigFormBase::buildForm

File

src/Form/CasSettings.php, line 82

Class

CasSettings
Class CasSettings.

Namespace

Drupal\cas\Form

Code

public function buildForm(array $form, FormStateInterface $form_state) {
  $config = $this
    ->config('cas.settings');
  $form['server'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('CAS server'),
    '#open' => TRUE,
    '#tree' => TRUE,
    '#description' => $this
      ->t('Enter the details of your CAS server.'),
  ];
  $form['server']['version'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('CAS Protocol version'),
    '#options' => [
      '1.0' => $this
        ->t('1.0'),
      '2.0' => $this
        ->t('2.0'),
      '3.0' => $this
        ->t('3.0 or higher'),
    ],
    '#default_value' => $config
      ->get('server.version'),
    '#description' => $this
      ->t('The CAS protocol version your CAS server supports. If unsure, ask your CAS server administrator.'),
  ];
  $form['server']['protocol'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('HTTP Protocol'),
    '#options' => [
      'http' => $this
        ->t('HTTP (non-secure)'),
      'https' => $this
        ->t('HTTPS (secure)'),
    ],
    '#default_value' => $config
      ->get('server.protocol'),
    '#description' => $this
      ->t('HTTP protocol type of the CAS server. WARNING: Do not use HTTP on production environments!'),
  ];
  $form['server']['hostname'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Hostname'),
    '#description' => $this
      ->t('Hostname or IP Address of the CAS server.'),
    '#size' => 30,
    '#default_value' => $config
      ->get('server.hostname'),
  ];
  $form['server']['port'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Port'),
    '#size' => 5,
    '#description' => $this
      ->t('443 is the standard SSL port. 8443 is the standard non-root port for Tomcat.'),
    '#default_value' => $config
      ->get('server.port'),
  ];
  $form['server']['path'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Path'),
    '#description' => $this
      ->t('If the CAS server paths (like /login) are not at the root of the host, specify the base path (e.g., /cas).'),
    '#size' => 30,
    '#default_value' => $config
      ->get('server.path'),
  ];
  $form['server']['verify'] = [
    '#type' => 'radios',
    '#title' => 'SSL Verification',
    '#description' => $this
      ->t("Choose an appropriate option for verifying the SSL/TLS certificate of your CAS server."),
    '#options' => [
      CasHelper::CA_DEFAULT => $this
        ->t("Verify using your web server's default certificate authority (CA) chain."),
      CasHelper::CA_NONE => $this
        ->t('Do not verify. (Note: this should NEVER be used in production.)'),
      CasHelper::CA_CUSTOM => $this
        ->t('Verify using a specific CA certificate. Use the field below to provide path (recommended).'),
    ],
    '#default_value' => $config
      ->get('server.verify'),
  ];
  $form['server']['cert'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Custom Certificate Authority PEM Certificate'),
    '#description' => $this
      ->t('The PEM certificate of the Certificate Authority that issued the certificate on the CAS server, used only with the custom certificate option above.'),
    '#default_value' => $config
      ->get('server.cert'),
    '#states' => [
      'visible' => [
        ':input[name="server[verify]"]' => [
          'value' => CasHelper::CA_CUSTOM,
        ],
      ],
    ],
  ];
  $form['general'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('General Settings'),
    '#open' => TRUE,
    '#tree' => TRUE,
  ];
  $form['general']['login_link_enabled'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Place a link to log in via CAS on the standard /user/login form'),
    '#description' => $this
      ->t('Note that even when enabled, the CAS module will not hide the standard Drupal login. If CAS is the primary way your users will log in, it is recommended to alter the login page in a custom module to hide the standard form.'),
    '#default_value' => $config
      ->get('login_link_enabled'),
  ];
  $form['general']['login_link_label'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Login link text'),
    '#default_value' => $config
      ->get('login_link_label'),
    '#states' => [
      'visible' => [
        ':input[name="general[login_link_enabled]"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];
  $form['general']['login_success_message'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Login success message'),
    '#description' => $this
      ->t('The message to output to users upon successful login. Leave blank to output no message.'),
    '#default_value' => $config
      ->get('login_success_message'),
  ];
  $form['user_accounts'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('User Account Handling'),
    '#open' => TRUE,
    '#tree' => TRUE,
  ];
  $form['user_accounts']['prevent_normal_login'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Prevent normal login for CAS users (recommended)'),
    '#description' => $this
      ->t('Prevents any user associated with CAS from authenticating using the normal login form. If attempted, users will be presented with an error message and a link to login via CAS instead.'),
    '#default_value' => $config
      ->get('user_accounts.prevent_normal_login'),
  ];
  $form['user_accounts']['restrict_password_management'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Restrict password management (recommended)'),
    '#description' => $this
      ->t('Prevents CAS users from changing their Drupal password by removing the password fields on the user profile form and disabling the "forgot password" functionality. Admins will still be able to change Drupal passwords for CAS users.'),
    '#default_value' => $config
      ->get('user_accounts.restrict_password_management'),
  ];
  $form['user_accounts']['restrict_email_management'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Restrict email management (recommended)'),
    '#description' => $this
      ->t("Prevents CAS users from changing their email by disabling the email field on the user profile form. Admins will still be able to change email addresses for CAS users. Note that Drupal requires a user enter their current password before changing their email, which your users may not know. Enable the restricted password management feature above to remove this password requirement."),
    '#default_value' => $config
      ->get('user_accounts.restrict_email_management'),
  ];
  $form['user_accounts']['auto_register'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Automatically register users'),
    '#description' => $this
      ->t('Enable to automatically create local Drupal accounts for first-time CAS logins. If disabled, users must be pre-registered before being allowed to log in.'),
    '#default_value' => $config
      ->get('user_accounts.auto_register'),
  ];
  if (!$this->moduleHandler
    ->moduleExists('cas_attributes')) {
    $form['user_accounts']['cas_attributes_callout'] = [
      '#prefix' => '<p class="messages messages--status">',
      '#markup' => $this
        ->t('If your CAS server supports <a href="@attributes" target="_blank">attributes</a>, you can install the <a href="@module" target="_blank">CAS Attributes</a> module to map them to user fields and roles during login and auto-registration.', [
        '@attributes' => 'https://apereo.github.io/cas/5.1.x/protocol/CAS-Protocol-Specification.html#255-attributes-cas-30',
        '@module' => 'https://drupal.org/project/cas_attributes',
      ]),
      '#suffix' => '</p>',
    ];
  }
  $form['user_accounts']['email_assignment_strategy'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Email address assignment'),
    '#description' => $this
      ->t("Drupal requires every user have an email address. Select how you'd like to assign an email to automatically registered users."),
    '#default_value' => $config
      ->get('user_accounts.email_assignment_strategy'),
    '#options' => [
      CasUserManager::EMAIL_ASSIGNMENT_STANDARD => $this
        ->t('Use the CAS username combined with a custom domain name you specify.'),
      CasUserManager::EMAIL_ASSIGNMENT_ATTRIBUTE => $this
        ->t("Use a CAS attribute that contains the user's complete email address."),
    ],
    '#states' => [
      'visible' => [
        'input[name="user_accounts[auto_register]"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];
  $form['user_accounts']['email_hostname'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Email hostname'),
    '#description' => $this
      ->t("The email domain name used to combine with the username to form the user's email address."),
    '#field_prefix' => $this
      ->t('username@'),
    '#default_value' => $config
      ->get('user_accounts.email_hostname'),
    '#states' => [
      'visible' => [
        'input[name="user_accounts[auto_register]"]' => [
          'checked' => TRUE,
        ],
        'input[name="user_accounts[email_assignment_strategy]"]' => [
          'value' => CasUserManager::EMAIL_ASSIGNMENT_STANDARD,
        ],
      ],
    ],
  ];
  $form['user_accounts']['email_attribute'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Email attribute'),
    '#description' => $this
      ->t("The CAS attribute name (case sensitive) that contains the user's email address. If unsure, check with your CAS server administrator to see a list of attributes that are returned during login."),
    '#default_value' => $config
      ->get('user_accounts.email_attribute'),
    '#states' => [
      'visible' => [
        'input[name="user_accounts[auto_register]"]' => [
          'checked' => TRUE,
        ],
        'input[name="user_accounts[email_assignment_strategy]"]' => [
          'value' => CasUserManager::EMAIL_ASSIGNMENT_ATTRIBUTE,
        ],
      ],
    ],
  ];
  $auto_assigned_roles = $config
    ->get('user_accounts.auto_assigned_roles');
  $form['user_accounts']['auto_assigned_roles_enable'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Automatically assign roles on user registration'),
    '#description' => $this
      ->t('To provide role mappings based on CAS attributes, install and configure the optional <a href="@module" target="_blank">CAS Attributes</a> module.', [
      '@module' => 'https://drupal.org/project/cas_attributes',
    ]),
    '#default_value' => count($auto_assigned_roles) > 0,
    '#states' => [
      'invisible' => [
        'input[name="user_accounts[auto_register]"]' => [
          'checked' => FALSE,
        ],
      ],
    ],
  ];
  $roles = user_role_names(TRUE);
  unset($roles[RoleInterface::AUTHENTICATED_ID]);
  $form['user_accounts']['auto_assigned_roles'] = [
    '#type' => 'select',
    '#multiple' => TRUE,
    '#title' => $this
      ->t('Roles'),
    '#description' => $this
      ->t('The selected roles will be automatically assigned to each CAS user on login. Use this to automatically give CAS users additional privileges or to identify CAS users to other modules.'),
    '#default_value' => $auto_assigned_roles,
    '#options' => $roles,
    '#states' => [
      'invisible' => [
        'input[name="user_accounts[auto_assigned_roles_enable]"]' => [
          'checked' => FALSE,
        ],
      ],
    ],
  ];
  $form['error_handling'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Error Handling'),
    '#tree' => TRUE,
  ];
  $form['error_handling']['login_failure_page'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Login failure page'),
    '#description' => $this
      ->t('If CAS login fails for any reason (e.g. validation failure or some other module prevents login), redirect the user to this page. If empty, users will be redirected to the homepage or to the original page they were on when initiating a login sequence. If your site is configured to automatically log users in via CAS when accessing a restricted page, you should set this to a page that does not require authentication to view. Otherwise you will create a redirect loop for users that that experience login failures as CAS continuously attempts to log them in as it returns them to the restricted page.'),
    '#default_value' => $config
      ->get('error_handling.login_failure_page'),
  ];
  $form['error_handling']['messages'] = [
    '#type' => 'fieldset',
    '#title' => $this
      ->t('Error messages'),
  ];
  $form['error_handling']['messages']['help'] = [
    [
      '#markup' => $this
        ->t('Replacement tokens can be used to customize the messages.'),
    ],
  ];
  if (!$this->moduleHandler
    ->moduleExists('token')) {
    $form['error_handling']['messages']['help'][] = [
      '#prefix' => ' ',
      '#markup' => $this
        ->t('Install the <a href="https://www.drupal.org/project/token">Token</a> module to see what tokens are available.'),
    ];
  }
  $form['error_handling']['messages']['message_validation_failure'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Ticket validation failure'),
    '#description' => $this
      ->t('During the CAS authentication process, the CAS server provides Drupal with a "ticket" which is then exchanged for user details (e.g. username and other attributes). This message will be displayed if there is a problem during this process.'),
    '#default_value' => $config
      ->get('error_handling.message_validation_failure'),
  ];
  $form['error_handling']['messages']['message_no_local_account'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Local account does not exist'),
    '#description' => $this
      ->t('Displayed when a new user attempts to login via CAS and automatic registration is disabled.'),
    '#default_value' => $config
      ->get('error_handling.message_no_local_account'),
  ];
  $form['error_handling']['messages']['message_subscriber_denied_reg'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Denied registration'),
    '#description' => $this
      ->t('Displayed when some other module (like CAS Attributes) denies automatic registration of a new user.'),
    '#default_value' => $config
      ->get('error_handling.message_subscriber_denied_reg'),
  ];
  $form['error_handling']['messages']['message_subscriber_denied_login'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Denied login'),
    '#description' => $this
      ->t('Displayed when some other module (like CAS Attributes) denies login of a user.'),
    '#default_value' => $config
      ->get('error_handling.message_subscriber_denied_login'),
  ];
  $form['error_handling']['messages']['message_account_blocked'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Local account is blocked'),
    '#description' => $this
      ->t('Displayed when the Drupal user account belonging to the user logging in via CAS is blocked.'),
    '#default_value' => $config
      ->get('error_handling.message_account_blocked'),
  ];
  $form['error_handling']['messages']['message_username_already_exists'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Local account username already exists'),
    '#description' => $this
      ->t('Displayed when automatic registraton of new user fails because an existing Drupal user is using the same username.'),
    '#default_value' => $config
      ->get('error_handling.message_username_already_exists'),
  ];
  $form['error_handling']['messages']['message_prevent_normal_login'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Prevent normal login error message'),
    '#description' => $this
      ->t('Displayed when prevent normal login for CAS users is on and a CAS user tries to logon using the normal Drupal login form.'),
    '#default_value' => $config
      ->get('error_handling.message_prevent_normal_login'),
    '#maxlength' => 512,
    '#states' => [
      'disabled' => [
        ':input[name="user_accounts[prevent_normal_login]"]' => [
          'checked' => FALSE,
        ],
      ],
    ],
  ];
  $form['error_handling']['messages']['message_restrict_password_management'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Restrict password management error message'),
    '#description' => $this
      ->t('Displayed when restrict password management is on and a CAS user tries to reset their Drupal password.'),
    '#default_value' => $config
      ->get('error_handling.message_restrict_password_management'),
    '#maxlength' => 512,
    '#states' => [
      'disabled' => [
        ':input[name="user_accounts[restrict_password_management]"]' => [
          'checked' => FALSE,
        ],
      ],
    ],
  ];
  if ($this->moduleHandler
    ->moduleExists('token')) {
    $form['error_handling']['messages']['tokens'] = [
      '#theme' => 'token_tree_link',
      '#token_types' => [
        'cas',
      ],
      '#global_types' => TRUE,
      '#dialog' => TRUE,
    ];
  }
  $form['gateway'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Gateway Feature (Auto Login)'),
    '#open' => FALSE,
    '#tree' => TRUE,
    '#description' => $this
      ->t('This implements the <a href="@cas-gateway">Gateway feature</a> of the CAS Protocol. When enabled, Drupal will check if a visitor is already logged into your CAS server before serving a page request. If they have an active CAS session, they will be automatically logged into the Drupal site. This is done by quickly redirecting them to the CAS server to perform the active session check, and then redirecting them back to page they initially requested.<br/><br/>If enabled, all pages on your site will trigger this feature by default. It is strongly recommended that you specify specific pages to trigger this feature below.<br/><br/><strong>WARNING:</strong> This feature will disable page caching on pages it is active on.', [
      '@cas-gateway' => 'https://wiki.jasig.org/display/CAS/gateway',
    ]),
  ];
  $form['gateway']['check_frequency'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Check frequency'),
    '#default_value' => $config
      ->get('gateway.check_frequency'),
    '#options' => [
      CasHelper::CHECK_NEVER => 'Disable gateway feature',
      CasHelper::CHECK_ONCE => 'Once per browser session',
      CasHelper::CHECK_ALWAYS => 'Every page load (not recommended)',
    ],
  ];
  $this->gatewayPaths
    ->setConfiguration($config
    ->get('gateway.paths'));
  $form['gateway']['paths'] = $this->gatewayPaths
    ->buildConfigurationForm([], $form_state);
  $form['forced_login'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Forced login'),
    '#open' => FALSE,
    '#tree' => TRUE,
    '#description' => $this
      ->t('Anonymous users will be forced to login through CAS when enabled. This differs from the "gateway feature" in that it will force a user to log in if they are not.'),
  ];
  $form['forced_login']['enabled'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Enable'),
    '#description' => $this
      ->t('If enabled, all pages on your site will trigger this feature. It is strongly recommended that you specify specific pages to trigger this feature below.'),
    '#default_value' => $config
      ->get('forced_login.enabled'),
  ];
  $this->forcedLoginPaths
    ->setConfiguration($config
    ->get('forced_login.paths'));
  $form['forced_login']['paths'] = $this->forcedLoginPaths
    ->buildConfigurationForm([], $form_state);
  $form['logout'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Log out behavior'),
    '#open' => FALSE,
    '#tree' => TRUE,
  ];
  $form['logout']['cas_logout'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Drupal logout triggers CAS logout'),
    '#description' => $this
      ->t('When enabled, users that log out of your Drupal site will then be logged out of your CAS server as well. This is done by redirecting the user to the CAS logout page.'),
    '#default_value' => $config
      ->get('logout.cas_logout'),
  ];
  $form['logout']['logout_destination'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Log out destination'),
    '#description' => $this
      ->t('Drupal path or URL. Enter a destination if you want the CAS Server to redirect the user after logging out of CAS.'),
    '#default_value' => $config
      ->get('logout.logout_destination'),
  ];
  $form['logout']['enable_single_logout'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Enable single log out?'),
    '#default_value' => $config
      ->get('logout.enable_single_logout'),
    '#description' => $this
      ->t('If enabled (and your CAS server supports it), users will be logged out of your Drupal site when they log out of your CAS server. <strong>WARNING:</strong> THIS WILL BYPASS A SECURITY HARDENING FEATURE ADDED IN DRUPAL 8, causing session IDs to be stored unhashed in the database.'),
  ];
  $form['logout']['single_logout_session_lifetime'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Max lifetime of session mapping data'),
    '#description' => $this
      ->t("This module stores a mapping of Drupal session IDs to CAS server session IDs to support single logout. Normally this data is cleared automatically when a user is logged out, but not always. To make sure this storage doesn't grow out of control, session mapping data older than the specified amout of days is cleared during cron. This should be a length of time slightly longer than the session lifetime of your Drupal site or CAS server."),
    '#default_value' => $config
      ->get('logout.single_logout_session_lifetime'),
    '#field_suffix' => $this
      ->t('days'),
    '#size' => 4,
    '#states' => [
      'visible' => [
        'input[name="logout[enable_single_logout]"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];
  $form['proxy'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Proxy'),
    '#open' => FALSE,
    '#tree' => TRUE,
    '#description' => $this
      ->t('These options relate to the proxy feature of the CAS protocol, including configuring this client as a proxy and configuring this client to accept proxied connections from other clients.'),
  ];
  $form['proxy']['initialize'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Initialize this client as a proxy?'),
    '#description' => $this
      ->t('Initializing this client as a proxy allows it to access CAS-protected resources from other clients that have been configured to accept it as a proxy.'),
    '#default_value' => $config
      ->get('proxy.initialize'),
  ];
  $form['proxy']['can_be_proxied'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Allow this client to be proxied?'),
    '#description' => $this
      ->t("Allow other CAS clients to access this site's resources via the CAS proxy protocol. You will need to configure a list of allowed proxies below."),
    '#default_value' => $config
      ->get('proxy.can_be_proxied'),
  ];
  $form['proxy']['proxy_chains'] = [
    '#type' => 'textarea',
    '#title' => $this
      ->t('Allowed proxy chains'),
    '#description' => $this
      ->t('A list of proxy chains to allow proxy connections from. Each line is a chain, and each chain is a whitespace delimited list of URLs for an allowed proxy in the chain, listed from most recent (left) to first (right). Each URL in the chain can be either a plain URL or a URL-matching regular expression (delimited only by slashes). Only if the proxy list returned by the CAS Server exactly matches a chain in this list will a proxy connection be allowed.'),
    '#default_value' => $config
      ->get('proxy.proxy_chains'),
  ];
  $form['advanced'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Advanced'),
    '#open' => FALSE,
    '#tree' => TRUE,
  ];
  $form['advanced']['debug_log'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Log debug information?'),
    '#description' => $this
      ->t('This is not meant for production sites! Enable this to log debug information about the interactions with the CAS Server to the Drupal log.'),
    '#default_value' => $config
      ->get('advanced.debug_log'),
  ];
  $form['advanced']['connection_timeout'] = [
    '#type' => 'textfield',
    '#size' => 3,
    '#title' => $this
      ->t('Connection timeout'),
    '#field_suffix' => $this
      ->t('seconds'),
    '#description' => $this
      ->t('This module makes HTTP requests to your CAS server and, if configured as a proxy, to a proxied service. This value determines the maximum amount of time to wait on those requests before canceling them.'),
    '#default_value' => $config
      ->get('advanced.connection_timeout'),
  ];
  return parent::buildForm($form, $form_state);
}