Issue #817118 by Sylvain Lecoy, bfroehle, Stevel: remove {authmap} and migrate OpenID entries to their own table.
parent
551868bb74
commit
881b8a6a17
core/modules
|
@ -54,6 +54,41 @@ function openid_schema() {
|
|||
'primary key' => array('assoc_handle'),
|
||||
);
|
||||
|
||||
$schema['openid_identities'] = array(
|
||||
'description' => 'Stores OpenID authentication mapping.',
|
||||
'fields' => array(
|
||||
'aid' => array(
|
||||
'description' => 'Primary Key: Unique authmap ID.',
|
||||
'type' => 'serial',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'uid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => "User's {users}.uid.",
|
||||
),
|
||||
'identifier' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'Unique OpenID identifier.',
|
||||
),
|
||||
),
|
||||
'unique keys' => array(
|
||||
'identifier' => array('identifier'),
|
||||
),
|
||||
'primary key' => array('aid'),
|
||||
'foreign keys' => array(
|
||||
'user' => array(
|
||||
'table' => 'users',
|
||||
'columns' => array('uid' => 'uid'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$schema['openid_nonce'] = array(
|
||||
'description' => 'Stores received openid.response_nonce per OpenID endpoint URL to prevent replay attacks.',
|
||||
'fields' => array(
|
||||
|
@ -123,6 +158,11 @@ function openid_update_last_removed() {
|
|||
return 6000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup updates-7.x-to-8.x
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Moves xri_proxy_resolver settings from variable to config.
|
||||
*
|
||||
|
@ -133,3 +173,62 @@ function openid_update_8001() {
|
|||
'xri_proxy_resolver' => 'xri_proxy_resolver',
|
||||
));
|
||||
}
|
||||
/**
|
||||
* Move authentication mapping to an OpenID managed table.
|
||||
*/
|
||||
function openid_update_8002() {
|
||||
$schema['openid_identities'] = array(
|
||||
'description' => 'Stores OpenID authentication mapping.',
|
||||
'fields' => array(
|
||||
'aid' => array(
|
||||
'description' => 'Primary Key: Unique authmap ID.',
|
||||
'type' => 'serial',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'uid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => "User's {users}.uid.",
|
||||
),
|
||||
'identifier' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'Unique OpenID identifier.',
|
||||
),
|
||||
),
|
||||
'unique keys' => array(
|
||||
'identifier' => array('identifier'),
|
||||
),
|
||||
'primary key' => array('aid'),
|
||||
'foreign keys' => array(
|
||||
'user' => array(
|
||||
'table' => 'users',
|
||||
'columns' => array('uid' => 'uid'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
db_create_table('openid_identities', $schema['openid_identities']);
|
||||
|
||||
// Migrate entries from {authmap} to {openid_identities}.
|
||||
$query = db_select('authmap', 'a')
|
||||
->condition('module', 'openid');
|
||||
$query->addField('a', 'uid');
|
||||
$query->addField('a', 'authname', 'identifier');
|
||||
db_insert('openid_identities')
|
||||
->from($query)
|
||||
->execute();
|
||||
|
||||
// Remove old entries in {authmap}.
|
||||
db_delete('authmap')
|
||||
->condition('module', 'openid')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup updates-7.x-to-8.x".
|
||||
*/
|
||||
|
|
|
@ -87,6 +87,32 @@ function openid_help($path, $arg) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a user object by OpenID identifier.
|
||||
*
|
||||
* @param $identifier
|
||||
* The OpenID identifier.
|
||||
*
|
||||
* @return
|
||||
* A fully-loaded user object if the user is found or FALSE if not found.
|
||||
*/
|
||||
function openid_external_load($identifier) {
|
||||
$uid = db_query("SELECT uid FROM {openid_identities} WHERE identifier = :identifier", array(':identifier' => $identifier))->fetchField();
|
||||
if ($uid) {
|
||||
return user_load($uid);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_user_delete().
|
||||
*/
|
||||
function openid_user_delete($account) {
|
||||
db_delete('openid_identities')
|
||||
->condition('uid', $account->uid)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_user_insert().
|
||||
*/
|
||||
|
@ -96,7 +122,12 @@ function openid_user_insert($account) {
|
|||
if (config('user.settings')->get('verify_mail')) {
|
||||
drupal_set_message(t('Once you have verified your e-mail address, you may log in via OpenID.'));
|
||||
}
|
||||
user_set_authmaps($account, array('authname_openid' => $account->openid_claimed_id));
|
||||
db_insert('openid_identities')
|
||||
->fields(array(
|
||||
'uid' => $account->uid,
|
||||
'identifier' => $account->openid_claimed_id,
|
||||
))
|
||||
->execute();
|
||||
unset($_SESSION['openid']);
|
||||
unset($account->openid_claimed_id);
|
||||
}
|
||||
|
@ -720,7 +751,7 @@ function openid_association($op_endpoint) {
|
|||
function openid_authentication($response) {
|
||||
$identity = $response['openid.claimed_id'];
|
||||
|
||||
$account = user_external_load($identity);
|
||||
$account = openid_external_load($identity);
|
||||
if (isset($account->uid)) {
|
||||
if (!config('user.settings')->get('verify_mail') || $account->login) {
|
||||
// Check if user is blocked.
|
||||
|
|
|
@ -34,11 +34,10 @@ function openid_user_identities($account) {
|
|||
$response = openid_complete();
|
||||
if ($response['status'] == 'success') {
|
||||
$identity = $response['openid.claimed_id'];
|
||||
$query = db_insert('authmap')
|
||||
$query = db_insert('openid_identities')
|
||||
->fields(array(
|
||||
'uid' => $account->uid,
|
||||
'authname' => $identity,
|
||||
'module' => 'openid',
|
||||
'identifier' => $identity,
|
||||
))
|
||||
->execute();
|
||||
drupal_set_message(t('Successfully added %identity', array('%identity' => $identity)));
|
||||
|
@ -49,10 +48,10 @@ function openid_user_identities($account) {
|
|||
$header = array(t('OpenID'), t('Operations'));
|
||||
$rows = array();
|
||||
|
||||
$result = db_query("SELECT * FROM {authmap} WHERE module='openid' AND uid=:uid", array(':uid' => $account->uid));
|
||||
$result = db_query("SELECT * FROM {openid_identities} WHERE uid=:uid", array(':uid' => $account->uid));
|
||||
foreach ($result as $identity) {
|
||||
$row = array();
|
||||
$row[] = check_plain($identity->authname);
|
||||
$row[] = check_plain($identity->identifier);
|
||||
$links = array();
|
||||
$links['delete'] = array(
|
||||
'title' => t('Delete'),
|
||||
|
@ -96,7 +95,7 @@ function openid_user_add() {
|
|||
function openid_user_add_validate($form, &$form_state) {
|
||||
// Check for existing entries.
|
||||
$claimed_id = openid_normalize($form_state['values']['openid_identifier']);
|
||||
if (db_query("SELECT authname FROM {authmap} WHERE authname = :authname", (array(':authname' => $claimed_id)))->fetchField()) {
|
||||
if (db_query("SELECT identifier FROM {openid_identities} WHERE identifier = :identifier", array(':identifier' => $claimed_id))->fetchField()) {
|
||||
form_set_error('openid_identifier', t('That OpenID is already in use on this site.'));
|
||||
}
|
||||
}
|
||||
|
@ -110,19 +109,18 @@ function openid_user_add_submit($form, &$form_state) {
|
|||
* Menu callback; Delete the specified OpenID identity from the system.
|
||||
*/
|
||||
function openid_user_delete_form($form, $form_state, $account, $aid = 0) {
|
||||
$authname = db_query("SELECT authname FROM {authmap} WHERE uid = :uid AND aid = :aid AND module = 'openid'", array(
|
||||
$identifier = db_query("SELECT identifier FROM {openid_identities} WHERE uid = :uid AND aid = :aid", array(
|
||||
':uid' => $account->uid,
|
||||
':aid' => $aid,
|
||||
))
|
||||
->fetchField();
|
||||
return confirm_form(array(), t('Are you sure you want to delete the OpenID %authname for %user?', array('%authname' => $authname, '%user' => $account->name)), 'user/' . $account->uid . '/openid');
|
||||
return confirm_form(array(), t('Are you sure you want to delete the OpenID %identifier for %user?', array('%identifier' => $identifier, '%user' => $account->name)), 'user/' . $account->uid . '/openid');
|
||||
}
|
||||
|
||||
function openid_user_delete_form_submit($form, &$form_state) {
|
||||
$query = db_delete('authmap')
|
||||
$query = db_delete('openid_identities')
|
||||
->condition('uid', $form_state['build_info']['args'][0]->uid)
|
||||
->condition('aid', $form_state['build_info']['args'][1])
|
||||
->condition('module', 'openid')
|
||||
->execute();
|
||||
if ($query) {
|
||||
drupal_set_message(t('OpenID deleted.'));
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\user\Tests\UserAuthmapAssignmentTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\user\Tests;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Unit test for authmap assignment.
|
||||
*/
|
||||
class UserAuthmapAssignmentTest extends WebTestBase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Authmap assignment',
|
||||
'description' => 'Tests that users can be assigned and unassigned authmaps.',
|
||||
'group' => 'User'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test authmap assignment and retrieval.
|
||||
*/
|
||||
function testAuthmapAssignment() {
|
||||
$account = $this->drupalCreateUser();
|
||||
|
||||
// Assign authmaps to the user.
|
||||
$authmaps = array(
|
||||
'authname_poll' => 'external username one',
|
||||
'authname_book' => 'external username two',
|
||||
);
|
||||
user_set_authmaps($account, $authmaps);
|
||||
|
||||
// Test for expected authmaps.
|
||||
$expected_authmaps = array(
|
||||
'external username one' => array(
|
||||
'poll' => 'external username one',
|
||||
),
|
||||
'external username two' => array(
|
||||
'book' => 'external username two',
|
||||
),
|
||||
);
|
||||
foreach ($expected_authmaps as $authname => $expected_output) {
|
||||
$this->assertIdentical(user_get_authmaps($authname), $expected_output, format_string('Authmap for authname %authname was set correctly.', array('%authname' => $authname)));
|
||||
}
|
||||
|
||||
// Remove authmap for module poll, add authmap for module blog.
|
||||
$authmaps = array(
|
||||
'authname_poll' => NULL,
|
||||
'authname_blog' => 'external username three',
|
||||
);
|
||||
user_set_authmaps($account, $authmaps);
|
||||
|
||||
// Assert that external username one does not have authmaps.
|
||||
$remove_username = 'external username one';
|
||||
unset($expected_authmaps[$remove_username]);
|
||||
$this->assertFalse(user_get_authmaps($remove_username), format_string('Authmap for %authname was removed.', array('%authname' => $remove_username)));
|
||||
|
||||
// Assert that a new authmap was created for external username three, and
|
||||
// existing authmaps for external username two were unchanged.
|
||||
$expected_authmaps['external username three'] = array('blog' => 'external username three');
|
||||
foreach ($expected_authmaps as $authname => $expected_output) {
|
||||
$this->assertIdentical(user_get_authmaps($authname), $expected_output, format_string('Authmap for authname %authname was set correctly.', array('%authname' => $authname)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -175,9 +175,6 @@ class UserStorageController extends DatabaseStorageController {
|
|||
db_delete('users_roles')
|
||||
->condition('uid', array_keys($entities), 'IN')
|
||||
->execute();
|
||||
db_delete('authmap')
|
||||
->condition('uid', array_keys($entities), 'IN')
|
||||
->execute();
|
||||
drupal_container()->get('user.data')->delete(NULL, array_keys($entities));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ function user_schema() {
|
|||
);
|
||||
|
||||
$schema['authmap'] = array(
|
||||
'description' => 'Stores distributed authentication mapping.',
|
||||
'description' => 'Stores distributed authentication mapping. The authmap is deprecated since Drupal 8 and is kept only in a migration data process in mind. Modules that uses the authmap should move their data in custom tables as it will removed in Drupal 9.',
|
||||
'fields' => array(
|
||||
'aid' => array(
|
||||
'description' => 'Primary Key: Unique authmap ID.',
|
||||
|
|
|
@ -220,26 +220,6 @@ function user_field_extra_fields() {
|
|||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a user object based on an external authentication source.
|
||||
*
|
||||
* @param string $authname
|
||||
* The external authentication username.
|
||||
*
|
||||
* @return
|
||||
* A fully-loaded user object if the user is found or FALSE if not found.
|
||||
*/
|
||||
function user_external_load($authname) {
|
||||
$uid = db_query("SELECT uid FROM {authmap} WHERE authname = :authname", array(':authname' => $authname))->fetchField();
|
||||
|
||||
if ($uid) {
|
||||
return user_load($uid);
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads multiple users based on certain conditions.
|
||||
*
|
||||
|
@ -1412,52 +1392,6 @@ function user_page_title($account) {
|
|||
return is_object($account) ? user_format_name($account) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover which external authentication module(s) authenticated a username.
|
||||
*
|
||||
* @param $authname
|
||||
* A username used by an external authentication module.
|
||||
* @return
|
||||
* An associative array with module as key and username as value.
|
||||
*/
|
||||
function user_get_authmaps($authname = NULL) {
|
||||
$authmaps = db_query("SELECT module, authname FROM {authmap} WHERE authname = :authname", array(':authname' => $authname))->fetchAllKeyed();
|
||||
return count($authmaps) ? $authmaps : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save mappings of which external authentication module(s) authenticated
|
||||
* a user. Maps external usernames to user ids in the users table.
|
||||
*
|
||||
* @param $account
|
||||
* A user object.
|
||||
* @param $authmaps
|
||||
* An associative array with a compound key and the username as the value.
|
||||
* The key is made up of 'authname_' plus the name of the external authentication
|
||||
* module.
|
||||
* @see user_external_login_register()
|
||||
*/
|
||||
function user_set_authmaps($account, $authmaps) {
|
||||
foreach ($authmaps as $key => $value) {
|
||||
$module = explode('_', $key, 2);
|
||||
if ($value) {
|
||||
db_merge('authmap')
|
||||
->key(array(
|
||||
'uid' => $account->uid,
|
||||
'module' => $module[1],
|
||||
))
|
||||
->fields(array('authname' => $value))
|
||||
->execute();
|
||||
}
|
||||
else {
|
||||
db_delete('authmap')
|
||||
->condition('uid', $account->uid)
|
||||
->condition('module', $module[1])
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form builder; the main user login form.
|
||||
*
|
||||
|
@ -1696,36 +1630,6 @@ function user_user_logout($account) {
|
|||
drupal_static_reset('template_preprocess');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for authentication modules. Either logs in or registers
|
||||
* the current user, based on username. Either way, the global $user object is
|
||||
* populated and login tasks are performed.
|
||||
*/
|
||||
function user_external_login_register($name, $module) {
|
||||
$account = user_external_load($name);
|
||||
if (!$account) {
|
||||
// Register this new user.
|
||||
$account = entity_create('user', array(
|
||||
'name' => $name,
|
||||
'pass' => user_password(),
|
||||
'init' => $name,
|
||||
'status' => 1,
|
||||
'access' => REQUEST_TIME
|
||||
));
|
||||
$status = $account->save();
|
||||
// Terminate if an error occurred while saving the account.
|
||||
if ($status != SAVED_NEW) {
|
||||
drupal_set_message(t("Error saving user account."), 'error');
|
||||
return;
|
||||
}
|
||||
user_set_authmaps($account, array("authname_$module" => $name));
|
||||
}
|
||||
|
||||
// Log user in.
|
||||
$form_state['uid'] = $account->uid;
|
||||
user_login_form_submit(array(), $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique URL for a user to login and reset their password.
|
||||
*
|
||||
|
|
|
@ -390,59 +390,6 @@ function user_views_data() {
|
|||
),
|
||||
);
|
||||
|
||||
// authmap table
|
||||
|
||||
$data['authmap']['table']['group'] = t('User');
|
||||
$data['authmap']['table']['join'] = array(
|
||||
// Directly links to users table.
|
||||
'users' => array(
|
||||
'left_field' => 'uid',
|
||||
'field' => 'uid',
|
||||
),
|
||||
);
|
||||
|
||||
$data['authmap']['aid'] = array(
|
||||
'title' => t('Authmap ID'),
|
||||
'help' => t('The Authmap ID.'),
|
||||
'field' => array(
|
||||
'id' => 'numeric',
|
||||
),
|
||||
'filter' => array(
|
||||
'id' => 'numeric',
|
||||
'numeric' => TRUE,
|
||||
),
|
||||
'argument' => array(
|
||||
'id' => 'numeric',
|
||||
'numeric' => TRUE,
|
||||
),
|
||||
);
|
||||
$data['authmap']['authname'] = array(
|
||||
'title' => t('Authentication name'),
|
||||
'help' => t('The unique authentication name.'),
|
||||
'field' => array(
|
||||
'id' => 'standard',
|
||||
),
|
||||
'filter' => array(
|
||||
'id' => 'string',
|
||||
),
|
||||
'argument' => array(
|
||||
'id' => 'numeric',
|
||||
),
|
||||
);
|
||||
$data['authmap']['module'] = array(
|
||||
'title' => t('Authentication module'),
|
||||
'help' => t('The name of the module managing the authentication entry.'),
|
||||
'field' => array(
|
||||
'id' => 'standard',
|
||||
),
|
||||
'filter' => array(
|
||||
'id' => 'string',
|
||||
),
|
||||
'argument' => array(
|
||||
'id' => 'string',
|
||||
),
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue