diff --git a/core/modules/user/src/Controller/UserController.php b/core/modules/user/src/Controller/UserController.php
index 779cf90..fbd3e1c 100644
--- a/core/modules/user/src/Controller/UserController.php
+++ b/core/modules/user/src/Controller/UserController.php
@@ -186,6 +186,8 @@ public function getResetPassForm(Request $request, $uid) {
/**
* Validates user, hash, and timestamp; logs the user in if correct.
*
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * The request.
* @param int $uid
* User ID of the user requesting reset.
* @param int $timestamp
@@ -201,7 +203,7 @@ public function getResetPassForm(Request $request, $uid) {
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
* If $uid is for a blocked user or invalid user ID.
*/
- public function resetPassLogin($uid, $timestamp, $hash) {
+ public function resetPassLogin(Request $request, $uid, $timestamp, $hash) {
// The current user is not logged in, so check the parameters.
$current = REQUEST_TIME;
/** @var \Drupal\user\UserInterface $user */
@@ -222,6 +224,20 @@ public function resetPassLogin($uid, $timestamp, $hash) {
return $this->redirect('user.pass');
}
elseif ($user->isAuthenticated() && ($timestamp >= $user->getLastLoginTime()) && ($timestamp <= $current) && Crypt::hashEquals($hash, user_pass_rehash($user, $timestamp))) {
+ $flood_config = $this->config('user.flood');
+ if ($flood_config->get('uid_only')) {
+ // Register flood events based on the uid only, so they apply for any
+ // IP address. This is the most secure option.
+ $identifier = $user->id();
+ }
+ else {
+ // The default identifier is a combination of uid and IP address. This
+ // is less secure but more resistant to denial-of-service attacks that
+ // could lock out all users with public user names.
+ $identifier = $user->id() . '-' . $request->getClientIP();
+ }
+ \Drupal::flood()->clear('user.failed_login_ip');
+ \Drupal::flood()->clear('user.failed_login_user', $identifier);
user_login_finalize($user);
$this->logger->notice('User %name used one-time login link at time %timestamp.', ['%name' => $user->getDisplayName(), '%timestamp' => $timestamp]);
drupal_set_message($this->t('You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.'));
diff --git a/core/modules/user/src/Tests/UserLoginTest.php b/core/modules/user/src/Tests/UserLoginTest.php
index af00c74..46a5c99 100644
--- a/core/modules/user/src/Tests/UserLoginTest.php
+++ b/core/modules/user/src/Tests/UserLoginTest.php
@@ -63,6 +63,11 @@ function testGlobalLoginFloodControl() {
// A login with the correct password should also result in a flood error
// message.
$this->assertFailedLogin($user1, 'ip');
+ $this->resetUserPassword($user1);
+ $this->drupalLogout();
+ // Try to login as user 1, it should be successful.
+ $this->drupalLogin($user1);
+ $this->assertNoRaw(t('Too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or request a new password.', array(':url' => \Drupal::url('user.pass'))));
}
/**
@@ -103,6 +108,11 @@ function testPerUserLoginFloodControl() {
// Try one more attempt for user 1, it should be rejected, even if the
// correct password has been used.
$this->assertFailedLogin($user1, 'user');
+ $this->resetUserPassword($user1);
+ $this->drupalLogout();
+ // Try to login as user 1, it should be successful.
+ $this->drupalLogin($user1);
+ $this->assertNoRaw(\Drupal::translation()->formatPlural($this->config('user.flood')->get('user_limit'), 'There has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or request a new password.', 'There have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', array(':url' => \Drupal::url('user.pass'))));
}
/**
@@ -175,4 +185,23 @@ function assertFailedLogin($account, $flood_trigger = NULL) {
}
}
+ /**
+ * Reset user password.
+ *
+ * @param object $user
+ * A user object.
+ */
+ public function resetUserPassword($user) {
+ $this->drupalGet('user/password');
+ $edit['name'] = $user->getUsername();
+ $this->drupalPostForm(NULL, $edit, t('Submit'));
+ $_emails = $this->drupalGetMails();
+ $email = end($_emails);
+ $urls = array();
+ preg_match('#.+user/reset/.+#', $email['body'], $urls);
+ $resetURL = $urls[0];
+ $this->drupalGet($resetURL);
+ $this->drupalPostForm(NULL, NULL, t('Log in'));
+ }
+
}
diff --git a/sites/default/default.services.yml b/sites/default/default.services.yml
index e1bbbc7..23f6483 100644
--- a/sites/default/default.services.yml
+++ b/sites/default/default.services.yml
@@ -153,22 +153,3 @@ parameters:
- sftp
- webcal
- rtsp
-
- # Configure Cross-Site HTTP requests (CORS).
- # Read https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
- # for more information about the topic in general.
- # Note: By default the configuration is disabled.
- cors.config:
- enabled: false
- # Specify allowed headers, like 'x-allowed-header'.
- allowedHeaders: []
- # Specify allowed request methods, specify ['*'] to allow all possible ones.
- allowedMethods: []
- # Configure requests allowed from specific origins.
- allowedOrigins: ['*']
- # Sets the Access-Control-Expose-Headers header.
- exposedHeaders: false
- # Sets the Access-Control-Max-Age header.
- maxAge: false
- # Sets the Access-Control-Allow-Credentials header.
- supportsCredentials: false
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 9ee7360..7f28c29 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -144,11 +144,6 @@
* @code
* 'prefix' => 'main_',
* @endcode
- *
- * Per-table prefixes are deprecated as of Drupal 8.2, and will be removed in
- * Drupal 9.0. After that, only a single prefix for all tables will be
- * supported.
- *
* To provide prefixes for specific tables, set 'prefix' as an array.
* The array's keys are the table names and the values are the prefixes.
* The 'default' element is mandatory and holds the prefix for any tables
@@ -330,6 +325,9 @@
*
* You can also define an array of host names that can be accessed directly,
* bypassing the proxy, in $settings['http_client_config']['proxy']['no'].
+ *
+ * If these settings are not configured, the system environment variables
+ * HTTP_PROXY, HTTPS_PROXY, and NO_PROXY on the web server will be used instead.
*/
# $settings['http_client_config']['proxy']['http'] = 'http://proxy_user:proxy_pass@example.com:8080';
# $settings['http_client_config']['proxy']['https'] = 'http://proxy_user:proxy_pass@example.com:8080';
@@ -422,20 +420,6 @@
*/
# $settings['omit_vary_cookie'] = TRUE;
-
-/**
- * Cache TTL for client error (4xx) responses.
- *
- * Items cached per-URL tend to result in a large number of cache items, and
- * this can be problematic on 404 pages which by their nature are unbounded. A
- * fixed TTL can be set for these items, defaulting to one hour, so that cache
- * backends which do not support LRU can purge older entries. To disable caching
- * of client error responses set the value to 0. Currently applies only to
- * page_cache module.
- */
-# $settings['cache_ttl_4xx'] = 3600;
-
-
/**
* Class Loader.
*
@@ -672,7 +656,7 @@
/**
* Load services definition file.
*/
-$settings['container_yamls'][] = $app_root . '/' . $site_path . '/services.yml';
+$settings['container_yamls'][] = __DIR__ . '/services.yml';
/**
* Override the default service container class.
@@ -684,15 +668,6 @@
# $settings['container_base_class'] = '\Drupal\Core\DependencyInjection\Container';
/**
- * Override the default yaml parser class.
- *
- * Provide a fully qualified class name here if you would like to provide an
- * alternate implementation YAML parser. The class must implement the
- * \Drupal\Component\Serialization\SerializationInterface interface.
- */
-# $settings['yaml_parser_class'] = NULL;
-
-/**
* Trusted host configuration.
*
* Drupal core can use the Symfony trusted host mechanism to prevent HTTP Host
@@ -730,21 +705,6 @@
*/
/**
- * The default list of directories that will be ignored by Drupal's file API.
- *
- * By default ignore node_modules and bower_components folders to avoid issues
- * with common frontend tools and recursive scanning of directories looking for
- * extensions.
- *
- * @see file_scan_directory()
- * @see \Drupal\Core\Extension\ExtensionDiscovery::scanDirectory()
- */
-$settings['file_scan_ignore_directories'] = [
- 'node_modules',
- 'bower_components',
-];
-
-/**
* Load local development override configuration, if available.
*
* Use settings.local.php to override variables on secondary (staging,
@@ -754,7 +714,6 @@
*
* Keep this code block at the end of this file to take full effect.
*/
-#
-# if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
-# include $app_root . '/' . $site_path . '/settings.local.php';
+# if (file_exists(__DIR__ . '/settings.local.php')) {
+# include __DIR__ . '/settings.local.php';
# }