bakery.module in Bakery Single Sign-On System 8.2
Same filename and directory in other branches
For implementing different hooks for bakery SSO functionality.
File
bakery.moduleView source
<?php
/**
* @file
* For implementing different hooks for bakery SSO functionality.
*/
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\user\UserInterface;
/**
* Implements hook_user_login().
*/
function bakery_user_login(UserInterface $account) {
\Drupal::service('bakery.user_service')
->login($account);
}
/**
* Implements hook_user_logout().
*/
function bakery_user_logout(AccountInterface $account) {
\Drupal::service('bakery.user_service')
->logout($account);
}
/**
* Implements hook_ENTITY_TYPE_presave() for user entities.
*/
function bakery_user_presave(UserInterface $account) {
\Drupal::service('bakery.user_service')
->presave($account);
}
/**
* Implements hook_ENTITY_TYPE_update() for user entities.
*/
function bakery_user_update(UserInterface $account) {
\Drupal::service('bakery.user_service')
->update($account);
}
/**
* Implements hook_ENTITY_TYPE_view() for user entities.
*/
function bakery_user_view(array &$build, $account, EntityViewDisplayInterface $display) {
\Drupal::service('bakery.user_service')
->view($account, $build);
}
/**
* Implements hook_form_alter().
*/
function bakery_form_alter(&$form, FormStateInterface $form_state, $form_id) {
switch ($form_id) {
case 'user_profile_form':
case 'user_form':
$config = \Drupal::config('bakery.settings');
/** @var \Drupal\bakery\BakeryService $bakery */
$bakery = \Drupal::service('bakery.bakery_service');
if (!\Drupal::currentUser()
->hasPermission('administer users') && $bakery
->isChild()) {
$master_uri = $config
->get('bakery_master');
// $init_url = _bakery_init_field_url($form['#user']->init);.
if (isset($form['account'])) {
\Drupal::messenger()
->addStatus(t('You can change the name, mail, and password <a href=":url">at the master site</a>.', [
':url' => $master_uri,
]), FALSE);
$form['account']['#access'] = FALSE;
$form['account']['name']['#access'] = FALSE;
$form['account']['pass']['#access'] = FALSE;
$form['account']['mail']['#access'] = FALSE;
}
foreach (\Drupal::config('bakery.settings')
->get('bakery_supported_fields') as $type => $value) {
if ($value) {
switch ($type) {
case 'mail':
case 'name':
break;
case 'picture':
if (isset($form['picture'])) {
$form['picture']['picture_delete']['#access'] = FALSE;
$form['picture']['picture_upload']['#access'] = FALSE;
$form['picture']['#description'] = t('You can change the image <a href=":url">at the master site</a>.', [
':url' => $master_uri,
]);
}
break;
case 'language':
if (isset($form['locale'][$type])) {
$form['locale'][$type]['#disabled'] = TRUE;
$form['locale'][$type]['#description'] .= ' ' . t('You can change the language setting <a href=":url">at the master site</a>.', [
':url' => $master_uri,
]);
}
break;
case 'signature':
if (isset($form['signature_settings'][$type])) {
$form['signature_settings'][$type]['#disabled'] = TRUE;
$form['signature_settings'][$type]['#description'] .= ' ' . t('You can change the signature <a href=":url">at the master site</a>.', [
':url' => $master_uri,
]);
}
break;
default:
if (isset($form[$type])) {
$form[$type]['#disabled'] = TRUE;
}
if (isset($form[$type][$type])) {
$form[$type][$type]['#disabled'] = TRUE;
$form[$type][$type]['#description'] .= ' ' . t('You can change this setting <a href=":url">at the master site</a>.', [
':url' => $master_uri,
]);
}
break;
}
}
}
}
break;
case 'user_login_form':
$config = \Drupal::config('bakery.settings');
if ($config
->get('bakery_is_master')) {
// Use both validate and submit, in case other modules like TFA are
// also altering the login process.
$form['#validate'][] = '_bakery_login_redirect';
$form['#submit'][] = '_bakery_login_redirect';
}
else {
if ($config
->get('subsite_login')) {
// TODO allow login...
// Replace two validators from user module because they log the user in
// and test if account exists. We want to check if the account exists on
// the master instead.
// dpm($form['#validate']);.
$form['#validate'] = array_diff($form['#validate'], [
'::validateAuthentication',
'::validateFinal',
]);
// Also replace the submit handler with our own to
// set a redirect cookie.
$form['#submit'] = [
'_bakery_login_submit',
];
}
else {
// Remove all form elements and just link to main site for login.
// We _could_ redirect but because this form is shared with the login
// block in 8+ this would lead to some really weird behaviors.
$link = Link::fromTextAndUrl('Log in on main site', Url::fromUri($config
->get('bakery_master') . 'user', [
'query' => [
'bd' => \Drupal::getContainer()
->get('bakery.redirect')
->get(),
],
])
->setAbsolute(TRUE))
->toRenderable();
unset($form['name'], $form['pass'], $form['actions']);
$link['#cache']['tags'] = [
'config:bakery.settings',
];
$form['login'] = $link;
}
}
break;
}
}
function _bakery_login_redirect($form, FormStateInterface $form_state) {
$dest = \Drupal::service('bakery.redirect')
->get();
if ($dest) {
$response = new TrustedRedirectResponse($dest);
// Ensure check_logged_in logic doesn't break our redirect.
\Drupal::request()
->getSession()
->remove('check_logged_in');
$form_state
->setResponse($response);
}
}
/**
* Implements hook_form_FORM_ID_alter() for 'user_register_form'.
*/
function bakery_form_user_register_form_alter(&$form, FormStateInterface $form_state) {
/** @var \Drupal\bakery\BakeryService $bakery */
$bakery = \Drupal::service('bakery.bakery_service');
// Provide register ability on the slave sites.
if ($bakery
->isChild()) {
if (\Drupal::service('router.admin_context')
->isAdminRoute(\Drupal::routeMatch()
->getRouteObject())) {
$config = \Drupal::config('bakery.settings');
// Admin create user form. Add a note about account synchronization.
$form['account']['bakery_help'] = [
'#value' => t('<strong>Note:</strong> Only use this form to create accounts for users who exist on <a href="!url">@master</a> and not on this site. Be sure to use the exact same username and e-mail for the account here that they have on @master.', [
'!url' => $config
->get('bakery_master'),
'@master' => $config
->get('bakery_master'),
]),
'#weight' => -100,
];
}
else {
if (\Drupal::config('bakery.settings')
->get('subsite_login')) {
// Anonymous user registration form.
// Populate fields if set from previous attempt.
if (isset($_SESSION['bakery']['register'])) {
$form['account']['name']['#default_value'] = $_SESSION['bakery']['register']['name'];
$form['account']['mail']['#default_value'] = $_SESSION['bakery']['register']['mail'];
unset($_SESSION['bakery']['register']);
}
// Replace the submit handler with our own.
// $form['#submit'] = array('_bakery_register_submit');.
}
else {
// TODO replace route so this can't happen.
exit;
}
}
}
}
/**
* Implements hook_form_FORM_ID_alter() for 'user_pass'.
*/
function bakery_form_user_pass_alter(&$form, FormStateInterface $form_state) {
/** @var \Drupal\bakery\BakeryService $bakery */
$bakery = \Drupal::service('bakery.bakery_service');
// Child sites need to make sure the local account exists, if the master
// account exists.
if ($bakery
->isChild()) {
array_unshift($form['#validate'], '_bakery_pass_validate');
}
}
/**
* Validate handler for the password reset login.
*/
function _bakery_pass_validate($form, FormStateInterface &$form_state) {
// Attempt to copy account from master.
\Drupal::service('bakery.bakery_service')
->requestAccount(trim($form_state
->getValue('name')), TRUE);
}
/**
* Handle registration by redirecting to master.
*/
function _bakery_register_submit($form, &$form_state) {
// Create an array of fields to send to the master.
// Save values to cookie.
$data = [
"name" => $form_state
->getValue('name'),
"pass" => $form_state
->getValue('pass'),
"mail" => $form_state
->getValue('mail'),
];
_bakery_save_destination_param($form, $data);
unset($_GET['destination']);
// Store name and email in case of error and return from master.
$_SESSION['bakery']['register'] = [
'name' => $data['name'],
'mail' => $data['mail'],
];
// Create cookie and redirect to master.
\Drupal::service('bakery.bakery_service')
->bakeOatmealCookie($form_state
->getValue('name'), $data);
// Remove unneeded values.
$form_state
->cleanValues();
$master_uri = \Drupal::config('bakery.settings')
->get('bakery_master') . 'bakery';
$form_state
->setFormState([
'redirect' => new TrustedRedirectResponse($master_uri),
]);
}
/**
* Handle login by redirecting to master.
*/
function _bakery_login_submit($form, &$form_state) {
return;
// Get rid of all the values we don't explicitly know we want. While this may
// break some modules it ensures we don't send sensitive data between sites.
// login data to master site.
$data = [
"name" => $form_state
->getValue('name'),
"pass" => $form_state
->getValue('pass'),
];
_bakery_save_destination_param($form, $data);
unset($_GET['destination']);
// Create cookie and redirect to master.
\Drupal::service('bakery.bakery_service')
->bakeOatmealCookie($form_state
->getValue('name'), $data);
// Remove unneeded values.
$form_state
->cleanValues();
$master_uri = \Drupal::config('bakery.settings')
->get('bakery_master') . 'bakery/login';
$form_state
->setFormState([
'redirect' => new TrustedRedirectResponse($master_uri),
]);
}
/**
* Check if a form destination is set and save it in $data array.
*
* Used to preserve destination in Bakery redirection to master and slave
* during login and registration.
*
* @param array $form
* Form definition to check.
* @param array $data
* Array to store the detected destination value, if any.
*/
function _bakery_save_destination_param($form, &$data) {
// Hold on to destination if set.
if (strpos($form['#action'], 'destination=') !== FALSE) {
// If an absolute URL is in destination parse_url() will issue a warning
// and not populate $url_args so no further protection is needed.
parse_str(parse_url($form['#action'], PHP_URL_QUERY), $url_args);
if (!empty($url_args['destination'])) {
$data['destination'] = $url_args['destination'];
}
}
}
/**
* Build full init url to master.
*/
function _bakery_init_field_url($init) {
$scheme = parse_url(\Drupal::config('bakery.settings')
->get('bakery_master'), PHP_URL_SCHEME);
return $scheme . '://' . $init;
}
Functions
Name![]() |
Description |
---|---|
bakery_form_alter | Implements hook_form_alter(). |
bakery_form_user_pass_alter | Implements hook_form_FORM_ID_alter() for 'user_pass'. |
bakery_form_user_register_form_alter | Implements hook_form_FORM_ID_alter() for 'user_register_form'. |
bakery_user_login | Implements hook_user_login(). |
bakery_user_logout | Implements hook_user_logout(). |
bakery_user_presave | Implements hook_ENTITY_TYPE_presave() for user entities. |
bakery_user_update | Implements hook_ENTITY_TYPE_update() for user entities. |
bakery_user_view | Implements hook_ENTITY_TYPE_view() for user entities. |
_bakery_init_field_url | Build full init url to master. |
_bakery_login_redirect | |
_bakery_login_submit | Handle login by redirecting to master. |
_bakery_pass_validate | Validate handler for the password reset login. |
_bakery_register_submit | Handle registration by redirecting to master. |
_bakery_save_destination_param | Check if a form destination is set and save it in $data array. |