View source
<?php
function bakery_profile_menu() {
$items = array();
if (variable_get('bakery_is_master', 0)) {
$items['bakery/validate'] = array(
'title' => 'Validate',
'access callback' => 'bakery_profile_taste_thinmint_cookie',
'page callback' => 'bakery_profile_eat_thinmint_cookie',
'type' => MENU_CALLBACK,
);
$items['bakery/create'] = array(
'title' => 'Bakery create',
'access callback' => 'bakery_profile_taste_gingerbread_cookie',
'page callback' => 'bakery_profile_eat_gingerbread_cookie',
'type' => MENU_CALLBACK,
);
}
else {
$items['bakery/update'] = array(
'title' => 'Update',
'access callback' => 'bakery_profile_taste_stroopwafel_cookie',
'page callback' => 'bakery_profile_eat_stroopwafel_cookie',
'type' => MENU_CALLBACK,
);
$items['admin/config/people/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_profile_pull_form',
),
'type' => MENU_NORMAL_ITEM,
);
}
return $items;
}
function bakery_profile_user_update(&$edit, $account, $category) {
global $user;
if (variable_get('bakery_is_master', 0) && isset($_SESSION['bakery'])) {
$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_http_build_query(array(
$type => $data,
));
unset($_SESSION['bakery']);
$slaves = variable_get('bakery_slaves', array());
foreach ($slaves as $slave) {
$options = array(
'headers' => array(
'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8',
),
'method' => 'POST',
'data' => $payload,
);
$result = drupal_http_request($slave . 'bakery/update', $options);
if ($result->code != 200) {
drupal_set_message(t('Error %error for site at %url', array(
'%error' => $result->code . ' ' . $result->error,
'%url' => $slave,
)));
}
else {
drupal_set_message($result->data);
}
}
}
}
function bakery_profile_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_by_name($name);
if (!$account && $or_email) {
$account = user_load_by_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_profile_eat_stroopwafel_cookie() {
$stroopwafel = $_SESSION['bakery'];
unset($_SESSION['bakery']);
$init = _bakery_init_field($stroopwafel['uid']);
$account = user_load_multiple(array(), array(
'init' => $init,
));
if (empty($account)) {
$message = t('Account not found on %slave.', array(
'%slave' => variable_get('site_name', ''),
));
}
else {
$account = reset($account);
drupal_add_http_header('X-Drupal-bakery-UID', $account->uid);
$fields = array();
foreach (variable_get('bakery_supported_fields', array(
'mail' => 'mail',
'name' => 'name',
)) as $type => $value) {
if ($value) {
if (isset($stroopwafel[$type])) {
$fields[$type] = $stroopwafel[$type];
}
else {
$fields[$type] = $account->{$type};
}
}
}
$status = user_save($account, $fields);
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_profile_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_profile_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_by_name($name);
if ($account) {
db_query("UPDATE {users} SET login = :login WHERE uid = :uid", array(
':login' => $_SERVER['REQUEST_TIME'],
':uid' => $account->uid,
));
_bakery_save_slave_uid($account, $slave, $uid);
}
}
function bakery_profile_user_presave(&$edit, $account, $category) {
if (variable_get('bakery_is_master', 0)) {
$_SESSION['bakery']['data'] = module_invoke_all('bakery_transmit', $edit, $account, $category);
foreach (variable_get('bakery_supported_fields', array(
'mail' => 'mail',
'name' => 'name',
)) as $type => $enabled) {
if ($enabled && isset($edit[$type]) && isset($account->{$type}) && $account->{$type} != $edit[$type]) {
$_SESSION['bakery'][$type] = $edit[$type];
}
}
}
}
function bakery_profile_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_profile_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_profile_request_account($name, $or_email = FALSE) {
global $base_url;
$existing_account = user_load_by_name($name);
if (!$existing_account && $or_email) {
$account = user_load_by_mail($name);
}
if ($existing_account) {
return FALSE;
}
$master = variable_get('bakery_master', 'https://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_http_build_query(array(
$type => $data,
));
$http_options = array(
'method' => 'POST',
'data' => $payload,
'headers' => array(
'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8',
),
);
$result = drupal_http_request($master . 'bakery/create', $http_options);
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($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($stub_uid);
return FALSE;
}
$new_account = array(
'name' => $cookie['name'],
'pass' => user_password(),
'mail' => $cookie['mail'],
'init' => _bakery_init_field($cookie['uid']),
);
foreach (variable_get('bakery_supported_fields', array(
'mail' => 'mail',
'name' => 'name',
)) as $type => $enabled) {
if ($enabled && isset($cookie[$type])) {
$new_account[$type] = $cookie[$type];
}
}
$account = user_save($account, $new_account);
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($stub_uid);
return FALSE;
}
function bakery_profile_pull_form($form, &$form_state) {
$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_profile_pull_form_validate($form, &$form_state) {
$existing_account = user_load_by_name($form_state['values']['name']);
if (!$existing_account && $form_state['values']['or_email']) {
$existing_account = user_load_by_mail($form_state['values']['name']);
}
if ($existing_account) {
form_set_error('name', t('Account !link exists.', array(
'!link' => theme('username', array(
'account' => $existing_account,
)),
)));
}
}
function bakery_profile_pull_form_submit($form, &$form_state) {
$result = bakery_profile_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;
}
}