diff --git a/core/modules/openid/openid.install b/core/modules/openid/openid.install index 01ddd47b23cbd1b6dd202852b5ff56e9d7aa8cb5..820a8e034b8e05ba5a596e1b7ea1c6bb51364f92 100644 --- a/core/modules/openid/openid.install +++ b/core/modules/openid/openid.install @@ -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". + */ diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module index ada493368c00f23b56f911fcea7068875a5d4d9f..0e8461ecb50abcbcd5755c7e117e0002de05f66c 100644 --- a/core/modules/openid/openid.module +++ b/core/modules/openid/openid.module @@ -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. diff --git a/core/modules/openid/openid.pages.inc b/core/modules/openid/openid.pages.inc index f54617c60524d89c0460fc53a88673bcddeb30ee..81a59056c7081d4d120aedcc05cdd42c6d6c87fd 100644 --- a/core/modules/openid/openid.pages.inc +++ b/core/modules/openid/openid.pages.inc @@ -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.')); diff --git a/core/modules/user/lib/Drupal/user/Tests/UserAuthmapAssignmentTest.php b/core/modules/user/lib/Drupal/user/Tests/UserAuthmapAssignmentTest.php deleted file mode 100644 index 92cc54c9d108a35db2def4442caa8603e0bbd8ae..0000000000000000000000000000000000000000 --- a/core/modules/user/lib/Drupal/user/Tests/UserAuthmapAssignmentTest.php +++ /dev/null @@ -1,69 +0,0 @@ - '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))); - } - } -} diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php index 2b532c90c79944e537f51ece85b67690c6620a7f..5d7b634a0f644495ac38ef78f43e5502f5b14437 100644 --- a/core/modules/user/lib/Drupal/user/UserStorageController.php +++ b/core/modules/user/lib/Drupal/user/UserStorageController.php @@ -175,9 +175,6 @@ protected function postDelete($entities) { 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)); } } diff --git a/core/modules/user/user.install b/core/modules/user/user.install index bb860024f720f1dd0591e8c9caeedb1e7f5e421a..9e09534b1e665893ca3084f130a9f70d03fd654b 100644 --- a/core/modules/user/user.install +++ b/core/modules/user/user.install @@ -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.', diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 7dabb6d093977898d38a0afe42a16b8a228fb807..285b9a770d50e8625bab93d656e12874a0cee324 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -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. * diff --git a/core/modules/user/user.views.inc b/core/modules/user/user.views.inc index 48b61389ef97b918524c40bed40be03e3fda6d4f..9264381130591a43848cb4af27cb8ae786212dfd 100644 --- a/core/modules/user/user.views.inc +++ b/core/modules/user/user.views.inc @@ -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; }