View source
<?php
function bakery_menu() {
$items = array();
$items['admin/settings/bakery'] = array(
'title' => 'Bakery',
'access arguments' => array(
'administer bakery',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'bakery_settings',
),
'description' => 'Infrastructure-wide single-sign-on system options.',
);
if (variable_get('bakery_is_master', 0)) {
$items['bakery'] = array(
'title' => 'Register',
'access callback' => 'user_is_anonymous',
'page callback' => 'bakery_register',
'type' => MENU_CALLBACK,
);
$items['bakery/login'] = array(
'title' => 'Login',
'access callback' => 'user_is_anonymous',
'page callback' => 'bakery_login',
'type' => MENU_CALLBACK,
);
$items['bakery/validate'] = array(
'title' => 'Validate',
'access callback' => 'bakery_taste_thinmint_cookie',
'page callback' => 'bakery_eat_thinmint_cookie',
'type' => MENU_CALLBACK,
);
$items['bakery/create'] = array(
'title' => 'Bakery create',
'access callback' => 'bakery_taste_gingerbread_cookie',
'page callback' => 'bakery_eat_gingerbread_cookie',
'type' => MENU_CALLBACK,
);
}
else {
$items['bakery'] = array(
'title' => 'Register',
'access callback' => TRUE,
'page callback' => 'bakery_register_return',
'type' => MENU_CALLBACK,
);
$items['bakery/login'] = array(
'title' => 'Login',
'access callback' => TRUE,
'page callback' => 'bakery_login_return',
'type' => MENU_CALLBACK,
);
$items['bakery/update'] = array(
'title' => 'Update',
'access callback' => 'bakery_taste_stroopwafel_cookie',
'page callback' => 'bakery_eat_stroopwafel_cookie',
'type' => MENU_CALLBACK,
);
$items['bakery/repair'] = array(
'title' => 'Repair account',
'access callback' => 'bakery_uncrumble_access',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'bakery_uncrumble',
),
'type' => MENU_CALLBACK,
);
$items['admin/user/bakery'] = array(
'title' => 'Pull bakery user',
'description' => 'Request an account from the master site',
'access arguments' => array(
'administer users',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'bakery_pull_form',
),
);
}
return $items;
}
function bakery_translated_menu_link_alter(&$item) {
if ($item['href'] == 'bakery') {
$item['localized_options']['query'] = drupal_get_destination();
}
}
function bakery_perm() {
return array(
'administer bakery',
'bypass bakery',
);
}
function bakery_user($op, &$array, &$account, $category = NULL) {
if ($op == 'login') {
if (variable_get('bakery_is_master', 0)) {
$init = _bakery_init_field($account->uid);
_bakery_bake_chocolatechip_cookie($account->name, $account->mail, $init);
}
}
else {
if ($op == 'logout') {
global $user;
$cookie = _bakery_validate_cookie();
if ($user->uid && $cookie && $cookie['name'] === $user->name) {
_bakery_eat_cookie();
}
_bakery_eat_cookie(session_name());
}
else {
if ($op == 'update' && variable_get('bakery_is_master', 0)) {
$newly_saved_user = user_load($account->uid);
$_SESSION['bakery']['data'] = module_invoke_all('bakery_transmit', $array, $account, $category);
foreach (variable_get('bakery_supported_fields', array(
'mail' => 'mail',
'name' => 'name',
)) as $type => $enabled) {
$value = isset($array[$type]) ? $array[$type] : $newly_saved_user->{$type};
if ($enabled && isset($value)) {
$_SESSION['bakery'][$type] = $value;
}
}
}
else {
if ($op == 'after_update' && variable_get('bakery_is_master', 0) && isset($_SESSION['bakery'])) {
global $user;
$type = 'stroopwafel';
$key = variable_get('bakery_key', '');
$payload['data'] = serialize($_SESSION['bakery']);
$payload['timestamp'] = $_SERVER['REQUEST_TIME'];
$payload['uid'] = $account->uid;
$payload['category'] = $category;
$payload['type'] = $type;
$data = bakery_bake_data($payload);
$payload = drupal_query_string_encode(array(
$type => $data,
));
unset($_SESSION['bakery']);
$slaves = variable_get('bakery_slaves', array());
foreach ($slaves as $slave) {
$result = drupal_http_request($slave . 'bakery/update', array(
'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8',
), 'POST', $payload);
if ($result->code != 200) {
$message = 'Error %error for site at %url';
$substitutions = array(
'%error' => $result->code . ' ' . $result->error,
'%url' => $slave,
);
watchdog('bakery', $message, $substitutions, WATCHDOG_ERROR);
if (user_access('administer users')) {
drupal_set_message(t($message, $substitutions), 'error');
}
}
else {
$message = filter_xss($result->data);
if (user_access('administer users')) {
drupal_set_message($message);
}
watchdog('bakery', $message);
_bakery_save_slave_uid($account, $slave, $result->headers['X-Drupal-bakery-UID']);
}
}
if ($user->uid === $account->uid) {
$init = _bakery_init_field($account->uid);
_bakery_bake_chocolatechip_cookie($account->name, $account->mail, $init);
}
}
else {
if ($op == 'view' && !variable_get('bakery_is_master', 0)) {
$master = variable_get('bakery_master', 'http://drupal.org/');
$init_url = _bakery_init_field_url($account->init);
if (parse_url($master, PHP_URL_HOST) == parse_url($init_url, PHP_URL_HOST)) {
$account->content['summary']['master_profile'] = array(
'#type' => 'user_profile_item',
'#title' => t('Primary profile'),
'#value' => l(t('Profile on @master', array(
'@master' => variable_get('bakery_master', 'http://drupal.org'),
)), substr($init_url, 0, strlen($init_url) - 5)),
'#attributes' => array(
'class' => 'og_groups',
),
'#access' => user_access('access user profiles'),
);
}
}
}
}
}
}
}
function bakery_boot() {
_bakery_taste_chocolatechip_cookie();
}
function bakery_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'user_profile_form':
case 'user_edit_form':
if (!variable_get('bakery_is_master', 0) && !user_access('administer users')) {
$init_url = _bakery_init_field_url($form['_account']['#value']->init);
$index = key($form);
if (isset($form['account'])) {
drupal_set_message(t('You can change the name, mail, and password at <a href="!url">@master</a>.', array(
'!url' => check_url($init_url),
'@master' => variable_get('bakery_master', 'http://drupal.org'),
)), 'status', FALSE);
$form['account']['#access'] = FALSE;
$form['account']['name']['#access'] = FALSE;
$form['account']['pass']['#access'] = FALSE;
$form['account']['mail']['#access'] = FALSE;
}
foreach (variable_get('bakery_supported_fields', array(
'mail' => 'mail',
'name' => 'name',
)) 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 at <a href="!url">@master</a>.', array(
'!url' => check_url($init_url),
));
}
break;
case 'language':
if (isset($form['locale'][$type])) {
$form['locale'][$type]['#disabled'] = TRUE;
$form['locale'][$type]['#description'] .= ' ' . t('You can change the language setting at <a href="!url">@master</a>.', array(
'!url' => check_url($init_url),
'@master' => variable_get('bakery_master', 'http://drupal.org'),
));
}
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 at <a href="!url">@master</a>.', array(
'!url' => check_url($init_url),
'@master' => variable_get('bakery_master', 'http://drupal.org'),
));
}
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 at <a href="!url">@master</a>.', array(
'!url' => check_url($init_url),
'@master' => variable_get('bakery_master', 'http://drupal.org'),
));
}
if ($form[$index]['#type'] == 'fieldset' && isset($form[$index][$type])) {
$form[$index][$type]['#disabled'] = TRUE;
$form[$index][$type]['#description'] .= ' ' . t('You can change this setting at <a href="!url">@master</a>.', array(
'!url' => check_url($init_url),
'@master' => variable_get('bakery_master', 'http://drupal.org'),
));
}
break;
}
}
}
}
break;
case 'user_register':
if (!variable_get('bakery_is_master', FALSE)) {
if (arg(0) == 'admin') {
$form['account']['bakery_help'] = array(
'#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.', array(
'!url' => variable_get('bakery_master', 'http://drupal.org'),
'@master' => variable_get('bakery_master', 'http://drupal.org'),
)),
'#weight' => -100,
);
}
else {
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']);
}
$form['#submit'] = array(
'_bakery_register_submit',
);
}
}
break;
case 'user_pass':
if (!variable_get('bakery_is_master', FALSE)) {
array_unshift($form['#validate'], '_bakery_pass_validate');
}
break;
case 'user_pass_reset':
if (!variable_get('bakery_is_master', FALSE)) {
$form['#submit'] = array(
'_bakery_reset_submit',
);
unset($form['#action']);
}
break;
case 'user_login_block':
case 'user_login':
if (!variable_get('bakery_is_master', FALSE)) {
$form['#validate'] = array_diff($form['#validate'], array(
'user_login_authenticate_validate',
'user_login_final_validate',
));
$form['#submit'] = array(
'_bakery_login_submit',
);
}
elseif (arg(0) == 'bakery') {
$form['#validate'] = array_diff($form['#validate'], array(
'user_login_authenticate_validate',
'user_login_final_validate',
));
}
break;
default:
break;
}
}
function _bakery_pass_validate($form, &$form_state) {
$name = trim($form_state['values']['name']);
$account = user_load(array(
'mail' => $name,
));
if (!$account) {
$account = user_load(array(
'name' => $name,
));
}
if (!$account) {
bakery_request_account($name, TRUE);
}
}
function _bakery_reset_submit($form, &$form_state) {
global $base_url;
$master = variable_get('bakery_master', 'http://drupal.org/');
$key = variable_get('bakery_key', '');
$account = user_load(array(
'uid' => arg(2),
));
if ($account->login == 0) {
$type = 'thinmint';
$payload = array();
$payload['name'] = $account->name;
$payload['slave'] = rtrim($base_url, '/') . '/';
$payload['uid'] = $account->uid;
$payload['timestamp'] = $_SERVER['REQUEST_TIME'];
$payload['type'] = $type;
$data = bakery_bake_data($payload);
$payload = drupal_query_string_encode(array(
$type => $data,
));
$result = drupal_http_request($master . 'bakery/validate', array(
'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8',
), 'POST', $payload);
}
if ($account->login > 0 || $result->code == 200) {
$init = _bakery_init_field($account->uid);
_bakery_bake_chocolatechip_cookie($account->name, $account->mail, $init);
global $user;
$user = $account;
$edit = array(
'name' => $user->name,
);
bakery_user_authenticate_finalize($edit);
drupal_set_message(t('You have just used your one-time login link. It is no longer necessary to use this link to login. Please change your password at <a href="!url">@master</a>.', array(
'!url' => check_url(_bakery_init_field_url($user->init)),
'@master' => variable_get('bakery_master', ''),
)));
drupal_goto('user/' . $user->uid);
}
else {
drupal_goto('user/login');
}
}
function _bakery_save_destination_param($form, &$data) {
if (strpos($form['#action'], 'destination=') !== FALSE) {
parse_str(parse_url($form['#action'], PHP_URL_QUERY), $url_args);
if (!empty($url_args['destination'])) {
$data['destination'] = $url_args['destination'];
}
}
}
function _bakery_register_submit($form, &$form_state) {
$allowed = array(
'name',
'mail',
'pass',
'timezone',
);
if (module_exists('profile')) {
$field_names = db_query("SELECT name FROM {profile_fields} WHERE register = 1");
while ($field_name = db_fetch_object($field_names)) {
$allowed[] = $field_name->name;
}
}
foreach ($form_state['values'] as $key => $value) {
if (!in_array($key, $allowed)) {
unset($form_state['values'][$key]);
}
}
$data = $form_state['values'];
_bakery_save_destination_param($form, $data);
unset($_REQUEST['destination']);
$_SESSION['bakery']['register'] = array(
'name' => $data['name'],
'mail' => $data['mail'],
);
bakery_bake_oatmeal_cookie($data['name'], $data);
drupal_goto(variable_get('bakery_master', 'http://drupal.org/') . 'bakery');
}
function _bakery_login_submit($form, &$form_state) {
$allowed = array(
'name',
'pass',
'op',
);
foreach ($form_state['values'] as $key => $value) {
if (!in_array($key, $allowed)) {
unset($form_state['values'][$key]);
}
}
$data = $form_state['values'];
_bakery_save_destination_param($form, $data);
unset($_REQUEST['destination']);
$data['query'] = $_GET;
unset($data['query']['q']);
unset($data['query']['destination']);
bakery_bake_oatmeal_cookie($data['name'], $data);
drupal_goto(variable_get('bakery_master', 'http://drupal.org/') . 'bakery/login');
}
function bakery_settings() {
$form = array(
'#submit' => array(
'bakery_settings_submit',
),
);
$form['bakery_is_master'] = array(
'#type' => 'checkbox',
'#title' => 'Is this the master site?',
'#default_value' => variable_get('bakery_is_master', 0),
'#description' => t('On the master site, accounts need to be created by traditional processes, i.e by a user registering or an admin creating them.'),
);
$form['bakery_master'] = array(
'#type' => 'textfield',
'#title' => 'Master site',
'#default_value' => variable_get('bakery_master', 'http://drupal.org/'),
'#description' => t('Specify the master site for your Bakery network.'),
);
$form['bakery_slaves'] = array(
'#type' => 'textarea',
'#title' => 'Slave sites',
'#default_value' => implode("\n", variable_get('bakery_slaves', array())),
'#description' => t('Specify any slave sites in your bakery network that you want to update if a user changes email or username on the master. Enter one site per line, in the form "http://sub.example.com/".'),
);
$form['bakery_help_text'] = array(
'#type' => 'textarea',
'#title' => 'Help text for users with synch problems',
'#default_value' => variable_get('bakery_help_text', 'Otherwise you can contact the site administrators.'),
'#description' => t('This message will be shown to users if/when they have problems synching their accounts. It is an alternative to the "self repair" option and can be blank.'),
);
$form['bakery_freshness'] = array(
'#type' => 'textfield',
'#title' => 'Seconds of age before a cookie is old',
'#default_value' => variable_get('bakery_freshness', '3600'),
);
$form['bakery_key'] = array(
'#type' => 'textfield',
'#title' => 'Private key for cookie validation',
'#required' => TRUE,
'#default_value' => variable_get('bakery_key', ''),
'#description' => t('Strong and secret key for Bakery cookie use.'),
);
$form['bakery_domain'] = array(
'#type' => 'textfield',
'#title' => 'Cookie domain',
'#required' => TRUE,
'#default_value' => variable_get('bakery_domain', ''),
'#description' => t('Domain for Bakery cookie use. Should be top-level with leading period. Example: .drupal.org'),
);
$default = variable_get('bakery_supported_fields', array(
'mail' => 'mail',
'name' => 'name',
));
$default['mail'] = 'mail';
$default['name'] = 'name';
$options = array(
'name' => t('username'),
'mail' => t('e-mail'),
'status' => t('status'),
'picture' => t('user picture'),
'language' => t('language'),
'signature' => t('signature'),
'timezone' => t('timezone'),
);
if (module_exists('profile')) {
$result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
while ($field = db_fetch_object($result)) {
$options[$field->name] = check_plain($field->title);
}
}
$form['bakery_supported_fields'] = array(
'#type' => 'checkboxes',
'#title' => 'Supported profile fields',
'#default_value' => $default,
'#options' => $options,
'#description' => t('Choose the profile fields that should be exported by the master and imported on the slaves. Username and E-mail are always exported. The correct export of individual fields may depend on the appropriate settings for other modules on both master and slaves. You need to configure this setting on both the master and the slaves.'),
);
return system_settings_form($form);
}
function bakery_settings_submit($form, &$form_state) {
menu_rebuild();
$form_state['values']['bakery_master'] = trim($form_state['values']['bakery_master'], '/') . '/';
if ($form_state['values']['bakery_slaves']) {
$form_state['values']['bakery_slaves'] = explode("\n", trim(str_replace("\r", '', $form_state['values']['bakery_slaves'])));
foreach ($form_state['values']['bakery_slaves'] as &$slave) {
$slave = trim($slave, '/') . '/';
}
}
else {
$form_state['values']['bakery_slaves'] = array();
}
}
function bakery_user_page() {
global $user;
if ($user->uid) {
menu_set_active_item('user/' . $user->uid);
return menu_execute_active_handler();
}
}
function bakery_register() {
$cookie = bakery_taste_oatmeal_cookie();
if ($cookie) {
_bakery_eat_cookie('OATMEAL');
if (variable_get('user_register', 1)) {
$data = array();
$errors = array();
$name = trim($cookie['data']['name']);
$mail = trim($cookie['data']['mail']);
if (drupal_is_denied('user', $name)) {
$errors['name_denied'] = 1;
}
if (drupal_is_denied('mail', $mail)) {
$errors['mail_denied'] = 1;
}
$account = user_load(array(
'mail' => $mail,
));
if ($account) {
$errors['mail'] = 1;
}
else {
$account = user_load(array(
'name' => $name,
));
if ($account) {
$errors['name'] = 1;
}
}
}
else {
watchdog('bakery', 'Master Bakery site user registration is disabled but users are trying to register from a subsite.', array(), WATCHDOG_ERROR);
$errors['register'] = 1;
}
if (empty($errors)) {
$userinfo = $cookie['data'];
if (!$cookie['data']['pass']) {
$pass = user_password();
}
else {
$pass = $cookie['data']['pass'];
}
$userinfo['name'] = $name;
$userinfo['mail'] = $mail;
$userinfo['pass'] = $pass;
$userinfo['init'] = $mail;
$userinfo['status'] = 1;
$userinfo['authname_bakery'] = $name;
$account = user_save('', $userinfo);
$data['uid'] = $account->uid;
$data['mail'] = $mail;
watchdog('user', 'New external user: %name using module bakery from slave !slave.', array(
'%name' => $account->name,
'!slave' => $cookie['slave'],
), WATCHDOG_NOTICE, l(t('edit'), 'user/' . $account->uid . '/edit'));
if (!variable_get('user_email_verification', TRUE)) {
$init = _bakery_init_field($account->uid);
_bakery_bake_chocolatechip_cookie($account->name, $account->mail, $init);
bakery_user_external_login($account);
}
else {
$errors['validate'] = 1;
}
}
else {
session_destroy();
}
$data['errors'] = $errors;
$data['name'] = $name;
if (isset($cookie['data']['destination'])) {
$data['destination'] = $cookie['data']['destination'];
}
bakery_bake_oatmeal_cookie($name, $data);
drupal_goto($cookie['slave'] . 'bakery/register');
}
drupal_access_denied();
}
function bakery_register_return() {
$cookie = bakery_taste_oatmeal_cookie();
if ($cookie) {
_bakery_eat_cookie('OATMEAL');
if (empty($cookie['data']['destination'])) {
$destination = '<front>';
}
else {
$destination = $cookie['data']['destination'];
}
$errors = $cookie['data']['errors'];
if (empty($errors)) {
drupal_set_message(t('Registration successful. You are now logged in.'));
drupal_goto($destination);
}
else {
if (!empty($errors['register'])) {
drupal_set_message(t('Registration is not enabled on @master. Please contact a site administrator.', array(
'@master' => variable_get('bakery_master', 'http://drupal.org/'),
)), 'error');
watchdog('bakery', 'Master Bakery site user registration is disabled', array(), WATCHDOG_ERROR);
}
if (!empty($errors['validate'])) {
$new = array(
'name' => $cookie['name'],
'mail' => $cookie['data']['mail'],
'init' => _bakery_init_field($cookie['data']['uid']),
'status' => 1,
'pass' => user_password(),
);
$account = user_save(new stdClass(), $new);
_user_mail_notify('register_no_approval_required', $account);
unset($_SESSION['bakery']['register']);
drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.'));
}
if (!empty($errors['name'])) {
drupal_set_message(t('Name is already taken.'), 'error');
}
if (!empty($errors['mail'])) {
drupal_set_message(t('E-mail address is already registered.'), 'error');
}
if (!empty($errors['mail_denied'])) {
drupal_set_message(t('The e-mail address has been denied access..'), 'error');
}
if (!empty($errors['name_denied'])) {
drupal_set_message(t('The name has been denied access..'), 'error');
}
drupal_goto('user/register');
}
}
drupal_access_denied();
}
function bakery_login() {
$cookie = bakery_taste_oatmeal_cookie();
if ($cookie) {
$cookie['data'] += array(
'query' => array(),
);
$errors = array();
_bakery_eat_cookie('OATMEAL');
$name = trim($cookie['data']['name']);
$pass = trim($cookie['data']['pass']);
$form_state = array();
$form_state['values'] = $cookie['data'];
drupal_execute('user_login', $form_state);
$errors = form_get_errors();
if (empty($errors)) {
$account = NULL;
if (module_exists('phpass')) {
require_once drupal_get_path('module', 'phpass') . '/password.inc';
$account = _phpass_load_user($name, $pass);
}
else {
$account = user_load(array(
'name' => $name,
'pass' => $pass,
));
}
if ($account->uid) {
if (drupal_is_denied('user', $account->mail)) {
$errors['name'] = t('The name %name is registered using a reserved e-mail address and therefore could not be logged in.', array(
'%name' => $name,
));
}
else {
$init = _bakery_init_field($account->uid);
_bakery_bake_chocolatechip_cookie($account->name, $account->mail, $init);
global $user;
$user = $account;
$edit = array(
'name' => $user->name,
);
bakery_user_authenticate_finalize($edit);
}
}
else {
$errors['incorrect-credentials'] = 1;
}
}
if (!empty($errors)) {
watchdog('user', 'Login attempt failed for %user.', array(
'%user' => $name,
));
drupal_get_messages();
}
$data = array(
'errors' => $errors,
'name' => $name,
);
if (isset($cookie['data']['destination'])) {
$data['destination'] = $cookie['data']['destination'];
}
$data['query'] = $cookie['data']['query'];
bakery_bake_oatmeal_cookie($name, $data);
drupal_goto($cookie['slave'] . 'bakery/login');
}
drupal_access_denied();
}
function bakery_login_return() {
$cookie = bakery_taste_oatmeal_cookie();
if ($cookie) {
$cookie['data'] += array(
'query' => array(),
);
_bakery_eat_cookie('OATMEAL');
$errors = $cookie['data']['errors'];
if (!empty($errors)) {
if (!empty($errors['incorrect-credentials'])) {
drupal_set_message(t('Sorry, unrecognized username or password.'), 'error');
}
elseif (!empty($errors['name'])) {
drupal_set_message(filter_xss($errors['name']), 'error');
}
}
$query = $cookie['data']['query'];
if (empty($cookie['data']['destination'])) {
drupal_goto('user', $query);
}
else {
$_REQUEST['destination'] = $cookie['data']['destination'];
drupal_goto('', $query);
}
}
elseif (user_is_logged_in()) {
drupal_goto();
}
drupal_access_denied();
}
function bakery_bake_data($data) {
$key = variable_get('bakery_key', '');
$data = bakery_encrypt(serialize($data));
$signature = hash_hmac('sha256', $data, $key);
return base64_encode($signature . $data);
}
function bakery_validate_data($data, $type = NULL) {
$key = variable_get('bakery_key', '');
$data = base64_decode($data);
$signature = substr($data, 0, 64);
$encrypted_data = substr($data, 64);
if ($signature !== hash_hmac('sha256', $encrypted_data, $key)) {
return FALSE;
}
$decrypted_data = unserialize(bakery_decrypt($encrypted_data));
if ($type !== NULL && $decrypted_data['type'] !== $type) {
return FALSE;
}
if (variable_get('bakery_freshness', '3600') == 0 || $decrypted_data['timestamp'] + variable_get('bakery_freshness', '3600') >= $_SERVER['REQUEST_TIME']) {
return $decrypted_data;
}
return FALSE;
}
function _bakery_cookie_name($type = 'CHOCOLATECHIP') {
if (ini_get('session.cookie_secure')) {
if (variable_get('bakery_loose_ssl', FALSE)) {
if (isset($_COOKIE[$type . 'SSL'])) {
$type .= 'SSL';
}
}
else {
$type .= 'SSL';
}
}
$extension = variable_get('bakery_cookie_extension', '');
$type .= $extension;
return $type;
}
function _bakery_validate_cookie($type = 'CHOCOLATECHIP') {
$key = variable_get('bakery_key', '');
$type = _bakery_cookie_name($type);
if (!isset($_COOKIE[$type]) || !$key || !variable_get('bakery_domain', '')) {
return NULL;
}
if (($data = bakery_validate_data($_COOKIE[$type], $type)) !== FALSE) {
return $data;
}
return FALSE;
}
function _bakery_taste_chocolatechip_cookie() {
$cookie = _bakery_validate_cookie();
if ($cookie) {
$destroy_cookie = FALSE;
global $user;
if ($user->uid && $cookie['name'] !== $user->name) {
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
bakery_user_logout();
}
_bakery_bake_chocolatechip_cookie($cookie['name'], $cookie['mail'], $cookie['init']);
if (!$user->uid) {
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$account = user_load(array(
'name' => $cookie['name'],
'mail' => $cookie['mail'],
));
if (!$account && !variable_get('bakery_is_master', 0) && $cookie['master']) {
$count = db_result(db_query("SELECT COUNT(*) FROM {users} WHERE init = '%s'", $cookie['init']));
if ($count > 1) {
watchdog('bakery', 'Account uniqueness problem: Multiple users found with init %init.', array(
'%init' => $cookie['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', 'http://drupal.org/') . 'contact',
)), 'error');
}
if ($count == 1) {
$account = user_load(array(
'init' => $cookie['init'],
));
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' => $cookie['name'],
'%mail_old' => $account->mail,
'%mail_new' => $cookie['mail'],
));
user_save($account, array(
'name' => $cookie['name'],
'mail' => $cookie['mail'],
));
$account = user_load(array(
'name' => $cookie['name'],
'mail' => $cookie['mail'],
));
}
}
}
if (!$account && !variable_get('bakery_is_master', 0) && $cookie['master']) {
$checks = TRUE;
if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND mail != '' AND LOWER(mail) = LOWER('%s')", $user->uid, $cookie['mail'])) > 0) {
$checks = FALSE;
}
if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND LOWER(name) = LOWER('%s')", $user->uid, $cookie['name'])) > 0) {
$checks = FALSE;
}
if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND init = '%s'", $user->uid, $cookie['init'])) > 0) {
$checks = FALSE;
}
if ($checks) {
$uid = bakery_request_account($cookie['name']);
if ($uid) {
$account = user_load($uid);
}
else {
$destroy_cookie = TRUE;
}
}
else {
drupal_set_message(t('Your user account on %site appears to have problems. Would you like to try to <a href="@url">repair it yourself</a>?', array(
'%site' => variable_get('site_name', 'Drupal'),
'@url' => url('bakery/repair'),
)));
drupal_set_message(filter_xss_admin(variable_get('bakery_help_text', 'Otherwise you can contact the site administrators.')));
$_SESSION['BAKERY_CRUMBLED'] = TRUE;
}
}
if ($account && $cookie['master'] && $account->uid && !variable_get('bakery_is_master', 0) && $account->init != $cookie['init']) {
if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE init = '%s'", $cookie['init'])) == 0) {
db_query("UPDATE {users} SET init = '%s' WHERE uid = %d", $cookie['init'], $account->uid);
watchdog('bakery', 'uid %uid out of sync. Changed init field from %oldinit to %newinit', array(
'%oldinit' => $account->init,
'%newinit' => $cookie['init'],
'%uid' => $account->uid,
));
}
else {
watchdog('bakery', 'Accounts mixed up! Username %user and init %init disagree with each other!', array(
'%user' => $account->name,
'%init' => $cookie['init'],
), WATCHDOG_CRITICAL);
}
}
if ($account && $user->uid == 0) {
$login = bakery_user_external_login($account);
if ($login) {
if (isset($_REQUEST['destination'])) {
$destination = $_REQUEST['destination'];
}
else {
$destination = isset($_GET['q']) ? $_GET['q'] : '';
$query = drupal_query_string_encode($_GET, array(
'q',
));
}
drupal_goto($destination, $query);
}
else {
$destroy_cookie = TRUE;
}
}
}
if ($destroy_cookie !== TRUE) {
return TRUE;
}
}
if ($cookie === FALSE) {
_bakery_eat_cookie();
}
if (!$cookie) {
global $user;
if ($user->uid > 1) {
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;
}
function bakery_taste_stroopwafel_cookie() {
$type = 'stroopwafel';
if (empty($_POST[$type])) {
return FALSE;
}
if (($payload = bakery_validate_data($_POST[$type], $type)) === FALSE) {
return FALSE;
}
$_SESSION['bakery'] = unserialize($payload['data']);
$_SESSION['bakery']['uid'] = $payload['uid'];
$_SESSION['bakery']['category'] = $payload['category'];
return TRUE;
}
function _bakery_bake_chocolatechip_cookie($name, $mail, $init) {
$key = variable_get('bakery_key', '');
if (!empty($key)) {
$cookie = array();
$cookie['name'] = $name;
$cookie['mail'] = $mail;
$cookie['init'] = $init;
$cookie['master'] = variable_get('bakery_is_master', 0);
$cookie['calories'] = 480;
$cookie['timestamp'] = $_SERVER['REQUEST_TIME'];
$cookie_secure = !variable_get('bakery_loose_ssl', FALSE) && ini_get('session.cookie_secure');
$type = _bakery_cookie_name('CHOCOLATECHIP');
$cookie['type'] = $type;
$data = bakery_bake_data($cookie);
$expire = variable_get('bakery_freshness', '3600') > 0 ? $_SERVER['REQUEST_TIME'] + variable_get('bakery_freshness', '3600') : '0';
setcookie($type, $data, $expire, '/', variable_get('bakery_domain', ''), $cookie_secure, TRUE);
}
}
function bakery_taste_oatmeal_cookie() {
$key = variable_get('bakery_key', '');
$type = _bakery_cookie_name('OATMEAL');
if (!isset($_COOKIE[$type]) || !$key || !variable_get('bakery_domain', '')) {
return FALSE;
}
if (($data = bakery_validate_data($_COOKIE[$type], $type)) !== FALSE) {
return $data;
}
return FALSE;
}
function bakery_bake_oatmeal_cookie($name, $data) {
$key = variable_get('bakery_key', '');
if (!empty($key)) {
global $base_url;
$cookie = array(
'data' => $data,
'name' => $name,
'calories' => 320,
'timestamp' => $_SERVER['REQUEST_TIME'],
);
if (variable_get('bakery_is_master', FALSE)) {
$cookie['master'] = 1;
}
else {
$cookie['master'] = 0;
$cookie['slave'] = $base_url . '/';
}
$cookie_secure = !variable_get('bakery_loose_ssl', FALSE) && ini_get('session.cookie_secure');
$type = _bakery_cookie_name('OATMEAL');
$cookie['type'] = $type;
$data = bakery_bake_data($cookie);
$expire = variable_get('bakery_freshness', '3600') > 0 ? $_SERVER['REQUEST_TIME'] + variable_get('bakery_freshness', '3600') : '0';
setcookie($type, $data, $expire, '/', variable_get('bakery_domain', ''), empty($cookie_secure) ? FALSE : TRUE, TRUE);
}
}
function bakery_eat_stroopwafel_cookie() {
$stroopwafel = $_SESSION['bakery'];
unset($_SESSION['bakery']);
$init = _bakery_init_field($stroopwafel['uid']);
$account = user_load(array(
'init' => $init,
));
if (!$account) {
$message = t('Account not found on %slave.', array(
'%slave' => variable_get('site_name', ''),
));
}
else {
drupal_set_header('X-Drupal-bakery-UID: ' . $account->uid);
$status = user_save($account, bakery_prepare_fields($stroopwafel, $account));
if ($status === FALSE) {
watchdog('bakery', 'User update from name %name_old to %name_new, mail %mail_old to %mail_new failed.', array(
'%name_old' => $account->name,
'%name_new' => $stroopwafel['name'],
'%mail_old' => $account->mail,
'%mail_new' => $stroopwafel['mail'],
), WATCHDOG_ERROR);
$message = t('There was a problem updating your account on %slave. Please contact the administrator.', array(
'%slave' => variable_get('site_name', ''),
));
header('HTTP/1.1 409 Conflict');
}
else {
watchdog('bakery', 'user updated name %name_old to %name_new, mail %mail_old to %mail_new.', array(
'%name_old' => $account->name,
'%name_new' => $stroopwafel['name'],
'%mail_old' => $account->mail,
'%mail_new' => $stroopwafel['mail'],
));
$message = t('Successfully updated account on %slave.', array(
'%slave' => variable_get('site_name', ''),
));
module_invoke_all('bakery_receive', $account, $stroopwafel);
}
}
module_invoke_all('exit');
print $message;
exit;
}
function bakery_prepare_fields($cookie, $account) {
$fields = array();
$profile_fields = bakery_get_profile_fields();
foreach (array_keys(array_filter(variable_get('bakery_supported_fields', array(
'mail' => 'mail',
'name' => 'name',
)))) as $type) {
if (isset($cookie[$type])) {
if (array_key_exists($type, $profile_fields)) {
db_query("DELETE FROM {profile_values} WHERE fid = %d AND uid = %d", $profile_fields[$type], $account->uid);
db_query("INSERT INTO {profile_values} (fid, uid, value) VALUES (%d, %d, '%s')", $profile_fields[$type], $account->uid, $cookie[$type]);
}
else {
$fields[$type] = $cookie[$type];
}
}
else {
$fields[$type] = $account->{$type};
}
}
return $fields;
}
function bakery_get_profile_fields() {
$return = array();
if (module_exists('profile')) {
$results = db_query("SELECT fid, name FROM {profile_fields}");
while ($result = db_fetch_object($results)) {
$return[$result->name] = $result->fid;
}
}
return $return;
}
function bakery_taste_thinmint_cookie() {
$type = 'thinmint';
if (empty($_POST[$type])) {
return FALSE;
}
if (($cookie = bakery_validate_data($_POST[$type], $type)) === FALSE) {
return FALSE;
}
$_SESSION['bakery']['name'] = $cookie['name'];
$_SESSION['bakery']['slave'] = $cookie['slave'];
$_SESSION['bakery']['uid'] = $cookie['uid'];
return TRUE;
}
function bakery_eat_thinmint_cookie() {
$name = $_SESSION['bakery']['name'];
unset($_SESSION['bakery']['name']);
$slave = $_SESSION['bakery']['slave'];
unset($_SESSION['bakery']['slave']);
$uid = $_SESSION['bakery']['uid'];
unset($_SESSION['bakery']['uid']);
$account = user_load(array(
'name' => $name,
));
if ($account) {
db_query("UPDATE {users} SET login = %d WHERE uid = %d", $_SERVER['REQUEST_TIME'], $account->uid);
_bakery_save_slave_uid($account, $slave, $uid);
}
}
function bakery_request_account($name, $or_email = FALSE) {
global $base_url;
$existing_account = user_load(array(
'name' => $name,
));
if (!$existing_account && $or_email) {
$existing_account = user_load(array(
'mail' => $name,
));
}
if ($existing_account) {
return FALSE;
}
$master = variable_get('bakery_master', 'http://drupal.org/');
$key = variable_get('bakery_key', '');
$new_account = array(
'name' => $name,
'pass' => user_password(),
'status' => 1,
'init' => 'bakery_temp/' . mt_rand(),
);
$account = user_save(NULL, $new_account);
if (!$account) {
watchdog('bakery', 'Unable to create stub account for @name', array(
'@name' => $name,
), WATCHDOG_ERROR);
return FALSE;
}
$stub_uid = $account->uid;
$type = 'gingerbread';
$payload = array();
$payload['name'] = $name;
$payload['or_email'] = $or_email;
$payload['slave'] = rtrim($base_url, '/') . '/';
$payload['uid'] = $account->uid;
$payload['timestamp'] = $_SERVER['REQUEST_TIME'];
$payload['type'] = $type;
$data = bakery_bake_data($payload);
$payload = drupal_query_string_encode(array(
$type => $data,
));
$result = drupal_http_request($master . 'bakery/create', array(
'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8',
), 'POST', $payload);
if ($result->code != 200) {
$message = $result->data;
watchdog('bakery', 'Received response !code from master with message @message', array(
'!code' => $result->code,
'@message' => $message,
), WATCHDOG_ERROR);
user_delete(array(), $stub_uid);
return FALSE;
}
if (($cookie = bakery_validate_data($result->data)) === FALSE) {
watchdog('bakery', 'Invalid response from master when attempting to create local account for @name', array(
'@name' => $name,
), WATCHDOG_ERROR);
user_delete(array(), $stub_uid);
return FALSE;
}
$account = user_save($account, array_merge(bakery_prepare_fields($cookie, $account), array(
'pass' => user_password(),
'init' => _bakery_init_field($cookie['uid']),
)));
if ($account) {
watchdog('bakery', 'Created account for @name', array(
'@name' => $name,
));
module_invoke_all('bakery_receive', $account, $cookie);
return $account->uid;
}
watchdog('bakery', 'Unable to create account for @name', array(
'@name' => $name,
), WATCHDOG_ERROR);
user_delete(array(), $stub_uid);
return FALSE;
}
function bakery_taste_gingerbread_cookie() {
$type = 'gingerbread';
if (empty($_POST[$type])) {
return FALSE;
}
if (($cookie = bakery_validate_data($_POST[$type], $type)) === FALSE) {
return FALSE;
}
$_SESSION['bakery']['name'] = $cookie['name'];
$_SESSION['bakery']['or_email'] = $cookie['or_email'];
$_SESSION['bakery']['slave'] = $cookie['slave'];
$_SESSION['bakery']['uid'] = $cookie['uid'];
return TRUE;
}
function bakery_eat_gingerbread_cookie() {
$name = $_SESSION['bakery']['name'];
unset($_SESSION['bakery']['name']);
$or_email = $_SESSION['bakery']['or_email'];
unset($_SESSION['bakery']['or_email']);
$slave = $_SESSION['bakery']['slave'];
unset($_SESSION['bakery']['slave']);
$slave_uid = $_SESSION['bakery']['uid'];
unset($_SESSION['bakery']['uid']);
$key = variable_get('bakery_key', '');
$account = user_load(array(
'name' => $name,
));
if (!$account && $or_email) {
$account = user_load(array(
'mail' => $name,
));
}
if ($account) {
_bakery_save_slave_uid($account, $slave, $slave_uid);
$payload = array();
$payload['name'] = $account->name;
$payload['mail'] = $account->mail;
$payload['uid'] = $account->uid;
foreach (variable_get('bakery_supported_fields', array(
'mail' => 'mail',
'name' => 'name',
)) as $type => $enabled) {
if ($enabled && $account->{$type}) {
$payload[$type] = $account->{$type};
}
}
$payload['data'] = module_invoke_all('bakery_transmit', NULL, $account);
$payload['timestamp'] = $_SERVER['REQUEST_TIME'];
$message = bakery_bake_data($payload);
}
else {
$message = t('No account found');
header('HTTP/1.1 409 Conflict');
}
module_invoke_all('exit');
print $message;
exit;
}
function _bakery_eat_cookie($type = 'CHOCOLATECHIP') {
$cookie_secure = ini_get('session.cookie_secure');
$type = _bakery_cookie_name($type);
setcookie($type, '', $_SERVER['REQUEST_TIME'] - 3600, '/', '', empty($cookie_secure) ? FALSE : TRUE, TRUE);
setcookie($type, '', $_SERVER['REQUEST_TIME'] - 3600, '/', variable_get('bakery_domain', ''), empty($cookie_secure) ? FALSE : TRUE, TRUE);
}
function _bakery_init_field($uid) {
$url = variable_get('bakery_master', 'http://drupal.org/');
$scheme = parse_url($url, PHP_URL_SCHEME);
return str_replace($scheme . '://', '', $url) . 'user/' . $uid . '/edit';
}
function _bakery_init_field_url($init) {
$scheme = parse_url(variable_get('bakery_master', 'http://drupal.org/'), PHP_URL_SCHEME);
return $scheme . '://' . $init;
}
function bakery_encrypt($text) {
$key = variable_get('bakery_key', '');
$td = mcrypt_module_open('rijndael-128', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $text);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $data;
}
function bakery_decrypt($text) {
$key = variable_get('bakery_key', '');
$td = mcrypt_module_open('rijndael-128', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$data = mdecrypt_generic($td, $text);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $data;
}
function bakery_user_external_login($account, $edit = array()) {
$form = drupal_get_form('user_login');
$state['values'] = $edit;
if (empty($state['values']['name'])) {
$state['values']['name'] = $account->name;
}
user_login_name_validate($form, $state, (array) $account);
if (form_get_errors()) {
return FALSE;
}
global $user;
$user = $account;
bakery_user_authenticate_finalize($state['values']);
return TRUE;
}
function bakery_user_authenticate_finalize(&$edit) {
global $user;
watchdog('user', 'Session opened for %name.', array(
'%name' => $user->name,
));
$user->login = time();
db_query("UPDATE {users} SET login = %d WHERE uid = %d", $user->login, $user->uid);
sess_regenerate();
user_module_invoke('login', $edit, $user);
}
function bakery_user_logout() {
global $user;
watchdog('user', 'Session closed for %name.', array(
'%name' => $user->name,
));
session_destroy();
$edit = array();
user_module_invoke('logout', $edit, $user);
$user = drupal_anonymous_user();
$get = $_GET;
$destination = !empty($get['q']) ? $get['q'] : '';
unset($get['q']);
$get['no_cache'] = time();
$url = url($destination, array(
'query' => $get,
'absolute' => TRUE,
'alias' => TRUE,
));
$url = str_replace(array(
"\n",
"\r",
), '', $url);
header('Location: ' . $url, TRUE, 307);
exit;
}
function bakery_uncrumble_access() {
global $user;
$access = FALSE;
if (!$user->uid) {
if (isset($_SESSION['BAKERY_CRUMBLED']) && $_SESSION['BAKERY_CRUMBLED']) {
$access = TRUE;
}
}
return $access;
}
function bakery_uncrumble(&$form_state) {
$site_name = variable_get('site_name', 'Drupal');
$cookie = _bakery_validate_cookie();
$samemail = db_fetch_object(db_query("SELECT uid, name, mail FROM {users} WHERE uid != 0 AND mail != '' AND LOWER(mail) = LOWER('%s')", $cookie['mail']));
$samename = db_fetch_object(db_query("SELECT uid, name, mail FROM {users} WHERE uid != 0 AND LOWER(name) = LOWER('%s')", $cookie['name']));
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#value' => $cookie['name'],
'#disabled' => TRUE,
'#required' => TRUE,
);
$form['mail'] = array(
'#type' => 'item',
'#title' => t('Email address'),
'#value' => $cookie['mail'],
'#required' => TRUE,
);
$form['pass'] = array(
'#type' => 'password',
'#title' => t('Password'),
'#description' => t('Enter the password that accompanies your username.'),
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Repair account'),
'#weight' => 2,
);
$help = '';
if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE init = '%s'", $cookie['init'])) > 1) {
drupal_set_message(t('Multiple accounts are associated with your master account. This must be fixed manually. <a href="@contact">Please contact the site administrator.</a>', array(
'%email' => $cookie['mail'],
'@contact' => variable_get('bakery_master', 'http://drupal.org/') . 'contact',
)));
$form['pass']['#disabled'] = TRUE;
$form['submit']['#disabled'] = TRUE;
}
else {
if ($samename && $samemail && $samename->uid != $samemail->uid) {
drupal_set_message(t('Both an account with matching name and an account with matching email address exist, but they are different accounts. This must be fixed manually. <a href="@contact">Please contact the site administrator.</a>', array(
'%email' => $cookie['mail'],
'@contact' => variable_get('bakery_master', 'http://drupal.org/') . 'contact',
)));
$form['pass']['#disabled'] = TRUE;
$form['submit']['#disabled'] = TRUE;
}
else {
if ($samename) {
$help = t("An account with a matching username was found. Repairing it will reset the email address to match your master account. If this is the correct account, please enter your %site password.", array(
'%site' => $site_name,
));
$form['mail']['#value'] = t('<em>*hidden*</em>');
$form['mail']['#description'] = t('Will change to %new.', array(
'%new' => $cookie['mail'],
));
}
else {
if ($samemail) {
$help = t("An account with a matching email address was found. Repairing it will reset the username to match your master account. If this is the correct account, please enter your %site password.", array(
'%site' => $site_name,
));
$form['name']['#value'] = $samemail->name;
$form['name']['#description'] = t('Will change to %new.', array(
'%new' => $cookie['name'],
));
}
}
}
}
$form['help'] = array(
'#type' => 'markup',
'#weight' => -10,
'#value' => $help,
);
return $form;
}
function bakery_uncrumble_validate($form, &$form_state) {
$account = user_load(array(
'name' => $form_state['values']['name'],
'pass' => $form_state['values']['pass'],
));
if (!($account && $account->uid)) {
watchdog('bakery', 'Login attempt failed for %user while running uncrumble.', array(
'%user' => $form_state['values']['name'],
));
form_set_error('pass', t('Sorry, unrecognized password. If you have forgotten your %site password, please <a href="@contact">contact the site administrator.</a>', array(
'%site' => variable_get('site_name', 'Drupal'),
'@contact' => variable_get('bakery_master', 'http://drupal.org/') . 'contact',
)), 'error');
}
else {
$form_state['bakery_uncrumble_account'] = $account;
}
}
function bakery_uncrumble_submit($form, &$form_state) {
$account = $form_state['bakery_uncrumble_account'];
unset($form_state['bakery_uncrumble_account']);
$cookie = _bakery_validate_cookie();
db_query("UPDATE {users} set init = '%s' WHERE uid = %d", $account->uid, $cookie['init']);
watchdog('bakery', 'uncrumble changed init field for uid %uid from %oldinit to %newinit', array(
'%oldinit' => $account->init,
'%newinit' => $cookie['init'],
'%uid' => $account->uid,
));
user_save($account, array(
'name' => $cookie['name'],
'mail' => $cookie['mail'],
));
watchdog('bakery', 'uncrumble updated name %name_old to %name_new, mail %mail_old to %mail_new on uid %uid.', array(
'%name_old' => $account->name,
'%name_new' => $cookie['name'],
'%mail_old' => $account->mail,
'%mail_new' => $cookie['mail'],
'%uid' => $account->uid,
));
drupal_set_message(t('Your account has been repaired.'));
$form_state['redirect'] = 'user';
}
function _bakery_save_slave_uid($account, $slave, $slave_uid) {
if (variable_get('bakery_is_master', 0) && !empty($slave_uid) && in_array($slave, variable_get('bakery_slaves', array())) && !db_result(db_query_range("SELECT 1 FROM {bakery_user} WHERE uid = %d AND slave = '%s'", $account->uid, $slave, 0, 1))) {
$row = array(
'uid' => $account->uid,
'slave' => $slave,
'slave_uid' => $slave_uid,
);
drupal_write_record('bakery_user', $row);
}
}
function bakery_pull_form() {
$form = array();
$form['or_email'] = array(
'#type' => 'radios',
'#options' => array(
0 => t('Username'),
1 => t('Username or email'),
),
'#default_value' => 0,
);
$form['name'] = array(
'#type' => 'textfield',
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Request account'),
);
return $form;
}
function bakery_pull_form_validate($form, &$form_state) {
$existing_account = user_load(array(
'name' => $form_state['values']['name'],
));
if (!$existing_account && $form_state['values']['or_email']) {
$existing_account = user_load(array(
'mail' => $form_state['values']['name'],
));
}
if ($existing_account) {
form_set_error('name', t('Account !link exists.', array(
'!link' => theme('username', $existing_account),
)));
}
}
function bakery_pull_form_submit($form, &$form_state) {
$result = bakery_request_account($form_state['values']['name'], $form_state['values']['or_email']);
if ($result === FALSE) {
drupal_set_message(t("Pulling account %name failed: maybe there is a typo or they don't exist on the master site.", array(
'%name' => $form_state['values']['name'],
)), 'error');
}
else {
$form_state['redirect'] = 'user/' . $result;
}
}