Commit 9eed2da5 authored by drumm's avatar drumm

#29147 by naudefj, markus_petrux, and Moshe:

- Clean up API for authenticating users.
- Default distributed authentication server.
parent 70b78091
......@@ -126,7 +126,13 @@ function drupal_settings() {
'#description' => t('If enabled, your Drupal site will allow other sites to register with your site and send information to this site. This functionality can be used to maintain a list of related sites.')
);
$form['services']['drupal_authentication_service'] = array(
$form['distauth'] = array(
'#type' => 'fieldset',
'#title' => t('Distributed authentication'),
'#tree' => FALSE
);
$form['distauth']['drupal_authentication_service'] = array(
'#type' => 'radios',
'#title' => t('Authentication service'),
'#default_value' => variable_get('drupal_authentication_service', 0),
......@@ -134,6 +140,21 @@ function drupal_settings() {
'#description' => t('If enabled, your Drupal site will accept logins with the user names of other Drupal sites, and likewise provide authentication for users logging into other Drupal sites, based on their user accounts here.')
);
$form['distauth']['drupal_default_da_server'] = array(
'#type' => 'textfield',
'#title' => t('Default authentication server'),
'#default_value' => variable_get('drupal_default_da_server', ''),
'#description' => t('The URL of the default Drupal authentication server. Omit the %http prefix (e.g. drupal.org, www.example.com, etc.). If the authentication service has been enabled, users registered at the server specified here, will not need to append the server to their user name when logging into your site. This enables users to provide a briefer, more familiar username in the login form.', array('%http' => theme('placeholder', 'http')))
);
$form['distauth']['drupal_default_da_server_only'] = array(
'#type' => 'radios',
'#title' => t('Only allow authentication from default server'),
'#default_value' => variable_get('drupal_default_da_server_only', 0),
'#options' => $options,
'#description' => t('Only accept remote logins from the above specified default authentication server and not from any other server. Useful when an external system is the solitary authority on user accounts for this site. A common usage is to enable this setting and also enable an authentication module which talks to your company\'s directory server.')
);
return $form;
}
......@@ -312,14 +333,24 @@ function drupal_info($field = 0) {
/**
* Implementation of hook_auth().
*/
function drupal_auth($username, $password, $server) {
function drupal_auth($username, $password, $server = FALSE) {
if (variable_get('drupal_authentication_service', 0)) {
$result = xmlrpc("http://$server/xmlrpc.php", 'drupal.login', $username, $password);
if ($result === FALSE) {
drupal_set_message(t('Error %code : %message', array('%code' => theme('placeholder', xmlrpc_errno()), '%message' => theme('placeholder', xmlrpc_error_msg()))), 'error');
if (!$server) {
$server = variable_get('drupal_default_da_server', '');
}
else {
return $result;
else if (variable_get('drupal_default_da_server_only', 0)) {
if (variable_get('drupal_default_da_server', '') != $server) {
return;
}
}
if (!empty($server)) {
$result = xmlrpc("http://$server/xmlrpc.php", 'drupal.login', $username, $password);
if ($result === FALSE) {
drupal_set_message(t('Error %code : %message', array('%code' => theme('placeholder', xmlrpc_errno()), '%message' => theme('placeholder', xmlrpc_error_msg()))), 'error');
}
else {
return $result;
}
}
}
}
......
......@@ -126,7 +126,13 @@ function drupal_settings() {
'#description' => t('If enabled, your Drupal site will allow other sites to register with your site and send information to this site. This functionality can be used to maintain a list of related sites.')
);
$form['services']['drupal_authentication_service'] = array(
$form['distauth'] = array(
'#type' => 'fieldset',
'#title' => t('Distributed authentication'),
'#tree' => FALSE
);
$form['distauth']['drupal_authentication_service'] = array(
'#type' => 'radios',
'#title' => t('Authentication service'),
'#default_value' => variable_get('drupal_authentication_service', 0),
......@@ -134,6 +140,21 @@ function drupal_settings() {
'#description' => t('If enabled, your Drupal site will accept logins with the user names of other Drupal sites, and likewise provide authentication for users logging into other Drupal sites, based on their user accounts here.')
);
$form['distauth']['drupal_default_da_server'] = array(
'#type' => 'textfield',
'#title' => t('Default authentication server'),
'#default_value' => variable_get('drupal_default_da_server', ''),
'#description' => t('The URL of the default Drupal authentication server. Omit the %http prefix (e.g. drupal.org, www.example.com, etc.). If the authentication service has been enabled, users registered at the server specified here, will not need to append the server to their user name when logging into your site. This enables users to provide a briefer, more familiar username in the login form.', array('%http' => theme('placeholder', 'http')))
);
$form['distauth']['drupal_default_da_server_only'] = array(
'#type' => 'radios',
'#title' => t('Only allow authentication from default server'),
'#default_value' => variable_get('drupal_default_da_server_only', 0),
'#options' => $options,
'#description' => t('Only accept remote logins from the above specified default authentication server and not from any other server. Useful when an external system is the solitary authority on user accounts for this site. A common usage is to enable this setting and also enable an authentication module which talks to your company\'s directory server.')
);
return $form;
}
......@@ -312,14 +333,24 @@ function drupal_info($field = 0) {
/**
* Implementation of hook_auth().
*/
function drupal_auth($username, $password, $server) {
function drupal_auth($username, $password, $server = FALSE) {
if (variable_get('drupal_authentication_service', 0)) {
$result = xmlrpc("http://$server/xmlrpc.php", 'drupal.login', $username, $password);
if ($result === FALSE) {
drupal_set_message(t('Error %code : %message', array('%code' => theme('placeholder', xmlrpc_errno()), '%message' => theme('placeholder', xmlrpc_error_msg()))), 'error');
if (!$server) {
$server = variable_get('drupal_default_da_server', '');
}
else {
return $result;
else if (variable_get('drupal_default_da_server_only', 0)) {
if (variable_get('drupal_default_da_server', '') != $server) {
return;
}
}
if (!empty($server)) {
$result = xmlrpc("http://$server/xmlrpc.php", 'drupal.login', $username, $password);
if ($result === FALSE) {
drupal_set_message(t('Error %code : %message', array('%code' => theme('placeholder', xmlrpc_errno()), '%message' => theme('placeholder', xmlrpc_error_msg()))), 'error');
}
else {
return $result;
}
}
}
}
......
......@@ -156,9 +156,12 @@ function user_save($account, $array = array(), $category = 'account') {
user_module_invoke('after_update', $array, $user, $category);
}
else {
$array['created'] = time();
$array['uid'] = db_next_id('{users}_uid');
if (!isset($array['created'])) { // Allow 'created' to be set by hook_auth
$array['created'] = time();
}
// Note, we wait with saving the data column to prevent module-handled
// fields from being saved there. We cannot invoke hook_user('insert') here
// because we don't have a fully initialized user object yet.
......@@ -953,6 +956,7 @@ function user_authenticate($name, $pass) {
// Try to log in the user locally. Don't set $user unless successful.
if ($account = user_load(array('name' => $name, 'pass' => $pass, 'status' => 1))) {
$user = $account;
return $user;
}
// Strip name and server from ID:
......@@ -963,30 +967,30 @@ function user_authenticate($name, $pass) {
// When possible, determine corresponding external auth source. Invoke
// source, and log in user if successful:
if (!$user->uid && $server && $result = user_get_authmaps("$name@$server")) {
if ($server && ($result = user_get_authmaps("$name@$server"))) {
if (module_invoke(key($result), 'auth', $name, $pass, $server)) {
$user = user_external_load("$name@$server");
watchdog('user', t('External load by %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', key($result)))));
}
else {
$error = t('Invalid password for %s.', array('%s' => theme('placeholder', $name .'@'. $server)));
}
}
// Try each external authentication source in series. Register user if
// successful.
else if (!$user->uid && $server) {
foreach (module_list() as $module) {
if (module_hook($module, 'auth')) {
if (module_invoke($module, 'auth', $name, $pass, $server)) {
if (variable_get('user_register', 1) == 1) {
$account = user_load(array('name' => "$name@$server"));
if (!$account->uid) { // Register this new user.
$user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server"));
watchdog('user', t('New external user: %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', $module))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
break;
}
else {
foreach (module_implements('auth') as $module) {
if (module_invoke($module, 'auth', $name, $pass, $server)) {
if ($server) {
$name .= '@'. $server;
}
$user = user_load(array('name' => $name));
if (!$user->uid) { // Register this new user.
$userinfo = array('name' => $name, 'pass' => user_password(), 'init' => $name, 'status' => 1);
if ($server) {
$userinfo["authname_$module"] = $name;
}
$user = user_save('', $userinfo);
watchdog('user', t('New external user: %user using module %module.', array('%user' => theme('placeholder', $name), '%module' => theme('placeholder', $module))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
break;
}
}
}
......
......@@ -156,9 +156,12 @@ function user_save($account, $array = array(), $category = 'account') {
user_module_invoke('after_update', $array, $user, $category);
}
else {
$array['created'] = time();
$array['uid'] = db_next_id('{users}_uid');
if (!isset($array['created'])) { // Allow 'created' to be set by hook_auth
$array['created'] = time();
}
// Note, we wait with saving the data column to prevent module-handled
// fields from being saved there. We cannot invoke hook_user('insert') here
// because we don't have a fully initialized user object yet.
......@@ -953,6 +956,7 @@ function user_authenticate($name, $pass) {
// Try to log in the user locally. Don't set $user unless successful.
if ($account = user_load(array('name' => $name, 'pass' => $pass, 'status' => 1))) {
$user = $account;
return $user;
}
// Strip name and server from ID:
......@@ -963,30 +967,30 @@ function user_authenticate($name, $pass) {
// When possible, determine corresponding external auth source. Invoke
// source, and log in user if successful:
if (!$user->uid && $server && $result = user_get_authmaps("$name@$server")) {
if ($server && ($result = user_get_authmaps("$name@$server"))) {
if (module_invoke(key($result), 'auth', $name, $pass, $server)) {
$user = user_external_load("$name@$server");
watchdog('user', t('External load by %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', key($result)))));
}
else {
$error = t('Invalid password for %s.', array('%s' => theme('placeholder', $name .'@'. $server)));
}
}
// Try each external authentication source in series. Register user if
// successful.
else if (!$user->uid && $server) {
foreach (module_list() as $module) {
if (module_hook($module, 'auth')) {
if (module_invoke($module, 'auth', $name, $pass, $server)) {
if (variable_get('user_register', 1) == 1) {
$account = user_load(array('name' => "$name@$server"));
if (!$account->uid) { // Register this new user.
$user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server"));
watchdog('user', t('New external user: %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', $module))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
break;
}
else {
foreach (module_implements('auth') as $module) {
if (module_invoke($module, 'auth', $name, $pass, $server)) {
if ($server) {
$name .= '@'. $server;
}
$user = user_load(array('name' => $name));
if (!$user->uid) { // Register this new user.
$userinfo = array('name' => $name, 'pass' => user_password(), 'init' => $name, 'status' => 1);
if ($server) {
$userinfo["authname_$module"] = $name;
}
$user = user_save('', $userinfo);
watchdog('user', t('New external user: %user using module %module.', array('%user' => theme('placeholder', $name), '%module' => theme('placeholder', $module))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
break;
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment