View source
<?php
function auto_login_url_menu() {
$items = array();
$items[variable_get('auto_login_url_short_url', 'autologinurl') . '/%/%'] = array(
'title' => 'Auto Login',
'page callback' => '_auto_login_url_page',
'page arguments' => array(
1,
2,
),
'access callback' => '_auto_login_url_access',
'access arguments' => array(
1,
2,
),
'type' => MENU_CALLBACK,
);
$items['admin/config/people/autologinurl'] = array(
'title' => 'Auto Login URL settings',
'description' => 'Settings page for Auto Login URL',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'_auto_login_url_settings',
),
'access arguments' => array(
'administer auto login url',
),
);
$items['admin/config/people/autologinurl/settings'] = array(
'title' => 'Auto Login URL settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
return $items;
}
function _auto_login_url_page($uid, $hash) {
if (!flood_is_allowed('failed_login_attempt_ip', variable_get('user_failed_login_ip_limit', 50), variable_get('user_failed_login_ip_window', 3600))) {
drupal_set_message(t('Sorry, too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later.'), 'error');
drupal_access_denied();
return;
}
$auto_login_url_secret = _auto_login_url_get_secret();
$password = db_query("SELECT pass FROM {users} WHERE uid = :uid", array(
':uid' => $uid,
))
->fetchField();
$key = drupal_get_hash_salt() . $auto_login_url_secret . $password;
$result = db_select('auto_login_url', 'a')
->fields('a', array(
'id',
'uid',
'destination',
))
->condition('hash', drupal_hmac_base64($hash, $key), '=')
->execute()
->fetchAssoc();
if ($result !== FALSE && count($result) > 0) {
$current_user = user_load($result['uid']);
$destination = urldecode($result['destination']);
if (strrpos($destination, '#') !== FALSE) {
$fragment = substr($destination, strrpos($destination, '#') + 1);
$url_array['fragment'] = $fragment;
$url_array['alias'] = TRUE;
$destination = substr($destination, 0, strrpos($destination, '#'));
}
if (strrpos($destination, '?') !== FALSE) {
$arguments = substr($destination, strrpos($destination, '?') + 1);
$arguments = explode('&', $arguments);
$arguments_array = array();
foreach ($arguments as $argument) {
$temp_array = explode('=', $argument);
$arguments_array[$temp_array[0]] = isset($temp_array[1]) ? $temp_array[1] : '';
}
$url_array['query'] = $arguments_array;
$destination = substr($destination, 0, strrpos($destination, '?'));
}
module_invoke_all('pre_auto_login_url', $current_user, $destination);
global $user;
$current_user->login = REQUEST_TIME;
db_update('users')
->fields(array(
'login' => $current_user->login,
))
->condition('uid', $current_user->uid)
->execute();
$user = $current_user;
drupal_session_regenerate();
user_login_finalize();
if (variable_get('auto_login_url_delete_on_use', FALSE)) {
db_delete('auto_login_url')
->condition('id', array(
$result['id'],
))
->execute();
}
$url_array = array();
module_invoke_all('post_auto_login_url', $current_user, $destination);
if (count($url_array)) {
drupal_goto($destination, $url_array);
}
else {
drupal_goto($destination);
}
}
else {
_auto_login_url_register_flood($hash);
return MENU_ACCESS_DENIED;
}
}
function _auto_login_url_access($uid, $hash) {
if (!empty($hash) && db_query("SELECT uid FROM {users} WHERE uid = :uid", array(
':uid' => $uid,
))
->fetchField()) {
return TRUE;
}
else {
_auto_login_url_register_flood($hash);
return FALSE;
}
}
function _auto_login_url_register_flood($hash) {
flood_register_event('failed_login_attempt_ip', variable_get('user_failed_login_ip_window', 3600));
watchdog('auto_login_url', 'Failed Auto Login URL from ip: @ip and hash: @hash', array(
'@ip' => ip_address(),
'@hash' => $hash,
));
}
function _auto_login_url_get_secret() {
$secret = variable_get('auto_login_url_secret', '');
if ($secret == '') {
$secret = drupal_random_key();
variable_set('auto_login_url_secret', $secret);
}
return $secret;
}
function _auto_login_url_settings() {
$form = array();
$form['auto_login_url_secret'] = array(
'#type' => 'textfield',
'#title' => t('Secret word'),
'#required' => TRUE,
'#default_value' => _auto_login_url_get_secret(),
'#description' => t('Secret word to create hashes that are stored in DB.
Every time this changes all previous URLs are invalidated.'),
);
$form['auto_login_url_expiration'] = array(
'#type' => 'textfield',
'#title' => t('Expiration'),
'#required' => TRUE,
'#default_value' => variable_get('auto_login_url_expiration', 2592000),
'#description' => t('Expiration of URLs in seconds.'),
'#element_validate' => array(
'element_validate_integer_positive',
),
);
$form['auto_login_url_short_url'] = array(
'#type' => 'textfield',
'#title' => t('Short URL'),
'#required' => TRUE,
'#default_value' => variable_get('auto_login_url_short_url', 'autologinurl'),
'#description' => t('Set URL prefix to use before random token.'),
);
$form['auto_login_url_token_length'] = array(
'#type' => 'textfield',
'#title' => t('Token length'),
'#required' => TRUE,
'#default_value' => variable_get('auto_login_url_token_length', 64),
'#description' => t('Length of generated URL token.
WARNING: Please understand the security implications of a short auto-login-url string before you change this value.
It has to be between 8 and 64 digits.'),
'#element_validate' => array(
'element_validate_integer_positive',
),
);
$form['auto_login_url_delete_on_use'] = array(
'#type' => 'checkbox',
'#title' => t('Delete on use'),
'#default_value' => variable_get('auto_login_url_delete_on_use', FALSE),
'#description' => t('Auto delete URLs after use.'),
);
$form = system_settings_form($form);
$form['#submit'][] = '_auto_login_url_settings_submit';
return $form;
}
function _auto_login_url_settings_validate($form, &$form_state) {
if ($form_state['values']['auto_login_url_token_length'] < 8 || $form_state['values']['auto_login_url_token_length'] > 64) {
form_set_error('auto_login_url_token_length', t('Token length has to be between 8 and 64 digits.'));
}
}
function _auto_login_url_settings_submit($form, &$form_state) {
menu_rebuild();
}
function auto_login_url_permission() {
return array(
'administer auto login url' => array(
'title' => t('Administer Auto Login URL settings'),
'description' => t('Perform administration tasks on Auto Login URL.'),
),
);
}
function auto_login_url_variable_info() {
$variables = array();
$variables['auto_login_url_secret'] = array(
'title' => t('Auto Login URL secret word'),
'default' => _auto_login_url_get_secret(),
'group' => 'auto_login_url',
'token' => FALSE,
);
$variables['auto_login_url_expiration'] = array(
'title' => t('Auto Login URL expiration'),
'default' => 2592000,
'group' => 'auto_login_url',
'token' => FALSE,
);
$variables['auto_login_url_short_url'] = array(
'title' => t('Short URL'),
'default' => 'autologinurl',
'group' => 'auto_login_url',
'token' => FALSE,
);
return $variables;
}
function auto_login_url_create($uid = NULL, $destination = '', $absolute = FALSE) {
if ($uid != NULL && is_numeric($uid) && $uid != 0) {
$auto_login_url_secret = _auto_login_url_get_secret();
$password = db_query("SELECT pass FROM {users} WHERE uid = :uid", array(
':uid' => $uid,
))
->fetchField();
$key = drupal_get_hash_salt() . $auto_login_url_secret . $password;
$hash_helper = 0;
do {
$data = $uid . microtime(TRUE) . $destination . $hash_helper;
$hash = drupal_hmac_base64($data, $key);
$hash = substr($hash, 0, variable_get('auto_login_url_token_length', 64));
$hash_db = drupal_hmac_base64($hash, $key);
$result = db_select('auto_login_url', 'alu')
->fields('alu', array(
'hash',
))
->condition('alu.hash', $hash_db)
->execute()
->rowCount();
$hash_helper++;
} while ($result != 0);
db_insert('auto_login_url')
->fields(array(
'uid',
'hash',
'destination',
'timestamp',
))
->values(array(
'uid' => $uid,
'hash' => $hash_db,
'destination' => $destination,
'timestamp' => time(),
))
->execute();
$absolute_path = '';
if ($absolute) {
global $base_url;
$absolute_path = $base_url . '/';
}
return $absolute_path . variable_get('auto_login_url_short_url', 'autologinurl') . '/' . $uid . '/' . $hash;
}
return '';
}
function auto_login_url_convert_text($uid, $text) {
global $base_root;
$pattern = '/' . str_replace('/', '\\/', $base_root) . '\\/[^\\s^"^\']*/';
$current_conversion = new AutoLoginUrlConvertTextClass($uid);
$text = preg_replace_callback($pattern, array(
&$current_conversion,
'replace',
), $text);
return $text;
}
class AutoLoginUrlConvertTextClass {
public function __construct($uid) {
$this->uid = $uid;
}
public function replace(array $matches) {
$pattern = '/(\\.jpg|\\.gif|\\.png)/';
preg_match($pattern, $matches[0], $new_matches);
if (count($new_matches) > 0) {
return $matches[0];
}
else {
return auto_login_url_create($this->uid, $matches[0], TRUE);
}
}
}
function auto_login_url_cron() {
db_delete('auto_login_url')
->condition('timestamp', time() - variable_get('auto_login_url_expiration', 2592000), '<=')
->execute();
}
function auto_login_url_token_info() {
$info = array();
$info['tokens']['user']['auto-login-url-token'] = array(
'name' => t('Auto Login URL'),
'description' => t('This an auto login token for the user.'),
);
$info['tokens']['user']['auto-login-url-account-edit-token'] = array(
'name' => t('Auto Login URL account edit'),
'description' => t('This an auto login for the user account page.'),
);
return $info;
}
function auto_login_url_tokens($type, $tokens, array $data = array(), array $options = array()) {
$replacements = array();
if ($type == 'user' && isset($data['user'])) {
$user = $data['user'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'auto-login-url-token':
$replacements[$original] = auto_login_url_create($user->uid, '<front>', TRUE);
break;
case 'auto-login-url-account-edit-token':
$replacements[$original] = auto_login_url_create($user->uid, 'user/' . $user->uid . '/edit', TRUE);
break;
}
}
}
return $replacements;
}