function _bakery_taste_chocolatechip_cookie in Bakery Single Sign-On System 7.4
Same name and namespace in other branches
- 6.2 bakery.module \_bakery_taste_chocolatechip_cookie()
- 6 bakery.module \_bakery_taste_chocolatechip_cookie()
- 7.2 bakery.module \_bakery_taste_chocolatechip_cookie()
Test identification cookie
1 call to _bakery_taste_chocolatechip_cookie()
- bakery_boot in ./
bakery.module - Implements hook_boot().
File
- ./
bakery.module, line 516
Code
function _bakery_taste_chocolatechip_cookie() {
$destroy_cookie = NULL;
$token = NULL;
try {
$token = _bakery_validate_cookie();
} catch (\Exception $e) {
$destroy_cookie = TRUE;
$GLOBALS['bakery_exception'] = $e;
}
// Continue if this is a valid cookie. That only happens for users who have
// a current valid session on the master site.
if ($token) {
$destroy_cookie = FALSE;
global $user;
// Detect SSO cookie mismatch if there is already a valid session for user.
if ($user->uid && $token
->getClaim('jti') !== $user->name) {
// The SSO cookie doesn't match the existing session so force a logout.
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
_bakery_user_logout();
}
// Bake a fresh cookie. Yum.
_bakery_bake_chocolatechip_cookie($token
->getClaim('jti'), $token
->getClaim('mail'), $token
->getClaim('init'));
if (!$user->uid) {
// Since this might happen in hook_boot we need to bootstrap first.
// Note that this only runs if they have a valid session on the master
// and do not have one on the slave so it only creates the extra load of
// a bootstrap on one pageview per session on the site which is not much.
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
// User is anonymous. If they do not have an account we'll create one by
// requesting their information from the master site. If they do have an
// account we may need to correct some disparant information.
$account = user_load_multiple(array(), array(
'name' => $token
->getClaim('jti'),
'mail' => $token
->getClaim('mail'),
));
$account = reset($account);
// Fix out of sync users with valid init.
if (!$account && !variable_get('bakery_is_master', 0) && $token
->getClaim('master')) {
$count = db_select('users', 'u')
->fields('u', array(
'uid',
))
->condition('init', $token
->getClaim('init'))
->countQuery()
->execute()
->fetchField();
if ($count > 1) {
// Uh oh.
watchdog('bakery', 'Account uniqueness problem: Multiple users found with init %init.', array(
'%init' => $token['init'],
), WATCHDOG_ERROR);
drupal_set_message(t('Account uniqueness problem detected. <a href="@contact">Please contact the site administrator.</a>', array(
'@contact' => variable_get('bakery_master', 'https://drupal.org/') . 'contact',
)), 'error');
}
if ($count == 1) {
$account = user_load_multiple(array(), array(
'init' => $token
->getClaim('init'),
));
if (is_array($account)) {
$account = reset($account);
}
if ($account) {
watchdog('bakery', 'Fixing out of sync uid %uid. Changed name %name_old to %name_new, mail %mail_old to %mail_new.', array(
'%uid' => $account->uid,
'%name_old' => $account->name,
'%name_new' => $token
->getClaim('jti'),
'%mail_old' => $account->mail,
'%mail_new' => $token
->getClaim('mail'),
));
user_save($account, array(
'name' => $token
->getClaim('jti'),
'mail' => $token
->getClaim('mail'),
));
$account = user_load_multiple(array(), array(
'name' => $token
->getClaim('jti'),
'mail' => $token
->getClaim('mail'),
));
$account = reset($account);
}
}
}
// Create the account if it doesn't exist.
if (!$account && !variable_get('bakery_is_master', 0) && $token
->getClaim('master')) {
$checks = TRUE;
$mail_count = db_select('users', 'u')
->fields('u', array(
'uid',
))
->condition('uid', $user->uid, '!=')
->condition('mail', '', '!=')
->where('LOWER(mail) = LOWER(:mail)', array(
':mail' => $token
->getClaim('mail'),
))
->countQuery()
->execute()
->fetchField();
if ($mail_count > 0) {
$checks = FALSE;
}
$name_count = db_select('users', 'u')
->fields('u', array(
'uid',
))
->condition('uid', $user->uid, '!=')
->where('LOWER(name) = LOWER(:name)', array(
':name' => $token
->getClaim('jti'),
))
->countQuery()
->execute()
->fetchField();
if ($name_count > 0) {
$checks = FALSE;
}
$init_count = db_select('users', 'u')
->fields('u', array(
'uid',
))
->condition('uid', $user->uid, '!=')
->condition('init', $token
->getClaim('init'), '=')
->where('LOWER(name) = LOWER(:name)', array(
':name' => $token
->getClaim('jti'),
))
->countQuery()
->execute()
->fetchField();
if ($init_count > 0) {
$checks = FALSE;
}
if ($checks) {
// Request information from master to keep data in sync.
$uid = bakery_request_account($token
->getClaim('jti'));
// In case the account creation failed we want to make sure the user
// gets their bad cookie destroyed by not returning too early.
if ($uid) {
$account = user_load($uid);
}
else {
$destroy_cookie = TRUE;
}
}
else {
drupal_set_message(t('Your user account on %site appears to have problems.', array(
'%site' => variable_get('site_name', 'Drupal'),
)));
drupal_set_message(filter_xss_admin(variable_get('bakery_help_text', 'Please contact the site administrators.')));
}
}
if ($account && $token
->getClaim('master') && $account->uid && !variable_get('bakery_is_master', 0) && $account->init != $token
->getClaim('init')) {
// User existed previously but init is wrong. Fix it to ensure account
// remains in sync.
// Make sure that there aren't any OTHER accounts with this init already.
$count = db_select('users', 'u')
->fields('u', array(
'uid',
))
->condition('init', $token
->getClaim('init'), '=')
->countQuery()
->execute()
->fetchField();
if ($count == 0) {
db_update('users')
->fields(array(
'init' => $token['init'],
))
->condition('uid', $account->uid)
->execute();
watchdog('bakery', 'uid %uid out of sync. Changed init field from %oldinit to %newinit', array(
'%oldinit' => $account->init,
'%newinit' => $token
->getClaim('init'),
'%uid' => $account->uid,
));
}
else {
// Username and email matched, but init belonged to a DIFFERENT account.
// Something got seriously tangled up.
watchdog('bakery', 'Accounts mixed up! Username %user and init %init disagree with each other!', array(
'%user' => $account->name,
'%init' => $token
->getClaim('init'),
), WATCHDOG_CRITICAL);
}
}
if ($account && $user->uid == 0) {
// If the login attempt fails we need to destroy the cookie to prevent
// infinite redirects (with infinite failed login messages).
$login = bakery_user_external_login($account);
if ($login) {
// If an anonymous user has just been logged in, trigger a 'refresh'
// of the current page, ensuring that drupal_goto() does not override
// the current page with the destination query.
$query = drupal_get_query_parameters();
unset($_GET['destination']);
drupal_goto(current_path(), array(
'query' => $query,
));
}
else {
$destroy_cookie = TRUE;
}
}
}
if ($destroy_cookie !== TRUE) {
return TRUE;
}
}
if ($destroy_cookie === TRUE) {
// Destroy the bad cookie. Burp.
_bakery_destroy_cookie();
}
global $user;
// Log out users that have lost their SSO cookie, with the exception of
// roles with permission to bypass.
if ($user->uid > 1) {
// This runs for logged in users. Those folks are going to get a full bootstrap anyway so this isn't a problem.
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
if (!user_access('bypass bakery')) {
watchdog('bakery', 'Logging out the user with the bad cookie.');
_bakery_user_logout();
}
}
return FALSE;
}