Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
8bab6674
Commit
8bab6674
authored
Mar 10, 2014
by
alexpott
Browse files
Issue
#2206687
by damiankloip: Replace user_authenticate with a UserAuth service.
parent
8e47a4eb
Changes
8
Hide whitespace changes
Inline
Side-by-side
core/modules/basic_auth/basic_auth.services.yml
View file @
8bab6674
services
:
authentication.basic_auth
:
class
:
Drupal\basic_auth\Authentication\Provider\BasicAuth
arguments
:
[
'
@config.factory'
]
arguments
:
[
'
@config.factory'
,
'
@user.auth'
]
tags
:
-
{
name
:
authentication_provider
,
priority
:
100
}
core/modules/basic_auth/lib/Drupal/basic_auth/Authentication/Provider/BasicAuth.php
View file @
8bab6674
...
...
@@ -11,6 +11,7 @@
use
Drupal\Core\Authentication\AuthenticationProviderInterface
;
use
Drupal\Core\Config\Config
;
use
Drupal\Core\Config\ConfigFactoryInterface
;
use
Drupal\user\UserAuthInterface
;
use
Symfony\Component\HttpFoundation\Request
;
use
Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent
;
use
Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
;
...
...
@@ -28,14 +29,22 @@ class BasicAuth implements AuthenticationProviderInterface {
*/
protected
$configFactory
;
/**
* The user auth service.
*
* @var \Drupal\user\UserAuthInterface
*/
protected
$userAuth
;
/**
* Constructs a HTTP basic authentication provider object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
*/
public
function
__construct
(
ConfigFactoryInterface
$config_factory
)
{
public
function
__construct
(
ConfigFactoryInterface
$config_factory
,
UserAuthInterface
$user_auth
)
{
$this
->
configFactory
=
$config_factory
;
$this
->
userAuth
=
$user_auth
;
}
/**
...
...
@@ -53,7 +62,7 @@ public function applies(Request $request) {
public
function
authenticate
(
Request
$request
)
{
$username
=
$request
->
headers
->
get
(
'PHP_AUTH_USER'
);
$password
=
$request
->
headers
->
get
(
'PHP_AUTH_PW'
);
$uid
=
user_
authenticate
(
$username
,
$password
);
$uid
=
$this
->
userAuth
->
authenticate
(
$username
,
$password
);
if
(
$uid
)
{
return
user_load
(
$uid
);
}
...
...
core/modules/user/lib/Drupal/user/Form/UserLoginForm.php
View file @
8bab6674
...
...
@@ -9,6 +9,7 @@
use
Drupal\Core\Flood\FloodInterface
;
use
Drupal\Core\Form\FormBase
;
use
Drupal\user\UserAuthInterface
;
use
Drupal\user\UserStorageControllerInterface
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
...
...
@@ -31,6 +32,13 @@ class UserLoginForm extends FormBase {
*/
protected
$userStorage
;
/**
* The user authentication object.
*
* @var \Drupal\user\UserAuthInterface
*/
protected
$userAuth
;
/**
* Constructs a new UserLoginForm.
*
...
...
@@ -38,10 +46,13 @@ class UserLoginForm extends FormBase {
* The flood service.
* @param \Drupal\user\UserStorageControllerInterface $user_storage
* The user storage controller.
* @param \Drupal\user\UserAuthInterface $user_auth
* The user authentication object.
*/
public
function
__construct
(
FloodInterface
$flood
,
UserStorageControllerInterface
$user_storage
)
{
public
function
__construct
(
FloodInterface
$flood
,
UserStorageControllerInterface
$user_storage
,
UserAuthInterface
$user_auth
)
{
$this
->
flood
=
$flood
;
$this
->
userStorage
=
$user_storage
;
$this
->
userAuth
=
$user_auth
;
}
/**
...
...
@@ -50,7 +61,8 @@ public function __construct(FloodInterface $flood, UserStorageControllerInterfac
public
static
function
create
(
ContainerInterface
$container
)
{
return
new
static
(
$container
->
get
(
'flood'
),
$container
->
get
(
'entity.manager'
)
->
getStorageController
(
'user'
)
$container
->
get
(
'entity.manager'
)
->
getStorageController
(
'user'
),
$container
->
get
(
'user.auth'
)
);
}
...
...
@@ -165,7 +177,7 @@ public function validateAuthentication(array &$form, array &$form_state) {
}
// We are not limited by flood control, so try to authenticate.
// Set $form_state['uid'] as a flag for self::validateFinal().
$form_state
[
'uid'
]
=
user_
authenticate
(
$form_state
[
'values'
][
'name'
],
$password
);
$form_state
[
'uid'
]
=
$this
->
userAuth
->
authenticate
(
$form_state
[
'values'
][
'name'
],
$password
);
}
}
...
...
core/modules/user/lib/Drupal/user/UserAuth.php
0 → 100644
View file @
8bab6674
<?php
/**
* @file
* Contains \Drupal\user\UserAuth.
*/
namespace
Drupal\user
;
use
Drupal\Core\Entity\EntityManagerInterface
;
use
Drupal\Core\Entity\EntityStorageControllerInterface
;
use
Drupal\Core\Password\PasswordInterface
;
/**
* Validates user authentication credentials.
*/
class
UserAuth
implements
UserAuthInterface
{
/**
* The user storage.
*
* @var \Drupal\Core\Entity\EntityStorageControllerInterface
*/
protected
$storage
;
/**
* The password service.
*
* @var \Drupal\Core\Password\PasswordInterface
*/
protected
$passwordChecker
;
/**
* Constructs a UserAuth object.
*
* @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage
* The user storage.
* @param \Drupal\Core\Password\PasswordInterface $password_checker
* The password service.
*/
public
function
__construct
(
EntityManagerInterface
$entity_manager
,
PasswordInterface
$password_checker
)
{
$this
->
storage
=
$entity_manager
->
getStorageController
(
'user'
);
$this
->
passwordChecker
=
$password_checker
;
}
/**
* {@inheritdoc}
*/
public
function
authenticate
(
$username
,
$password
)
{
$uid
=
FALSE
;
if
(
!
empty
(
$username
)
&&
!
empty
(
$password
))
{
$account_search
=
$this
->
storage
->
loadByProperties
(
array
(
'name'
=>
$username
));
if
(
$account
=
reset
(
$account_search
))
{
if
(
$this
->
passwordChecker
->
check
(
$password
,
$account
))
{
// Successful authentication.
$uid
=
$account
->
id
();
// Update user to new password scheme if needed.
if
(
$this
->
passwordChecker
->
userNeedsNewHash
(
$account
))
{
$account
->
setPassword
(
$password
);
$account
->
save
();
}
}
}
}
return
$uid
;
}
}
core/modules/user/lib/Drupal/user/UserAuthInterface.php
0 → 100644
View file @
8bab6674
<?php
/**
* @file
* Contains \Drupal\user\UserAuthInterface.
*/
namespace
Drupal\user
;
/**
* An interface for validating user authentication credentials.
*/
interface
UserAuthInterface
{
/**
* Validates user authentication credentials.
*
* @param string $username
* The user name to authenticate.
* @param string $password
* A plain-text password, such as trimmed text from form values.
* @return int|bool
* The user's uid on success, or FALSE on failure to authenticate.
*/
public
function
authenticate
(
$username
,
$password
);
}
core/modules/user/tests/Drupal/user/Tests/UserAuthTest.php
0 → 100644
View file @
8bab6674
<?php
/**
* @file
* Contains \Drupal\user\Tests\UserAuthTest.
*/
namespace
Drupal\user\Tests
;
use
Drupal\Tests\UnitTestCase
;
use
Drupal\user\UserAuth
;
/**
* Tests the UserAuth class.
*
* @group Drupal
* @group User
*
* @coverDefaultClass \Drupal\user\UserAuth
*/
class
UserAuthTest
extends
UnitTestCase
{
/**
* The mock user storage controller.
*
* @var \Drupal\Core\Entity\EntityStorageControllerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected
$userStorage
;
/**
* The mocked password service.
*
* @var \Drupal\Core\Password\PasswordInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected
$passwordService
;
/**
* The mock user.
*
* @var \Drupal\user\Entity\User|\PHPUnit_Framework_MockObject_MockObject
*/
protected
$testUser
;
/**
* The user auth object under test.
*
* @var \Drupal\user\UserAuth
*/
protected
$userAuth
;
/**
* The test username.
*
* @var string
*/
protected
$username
=
'test_user'
;
/**
* The test password
*
* @var string
*/
protected
$password
=
'password'
;
/**
* {@inheritdoc}
*/
public
static
function
getInfo
()
{
return
array
(
'name'
=>
'User auth service'
,
'description'
=>
'Tests the user auth service'
,
'group'
=>
'User'
,
);
}
/**
* {@inheritdoc}
*/
public
function
setUp
()
{
$this
->
userStorage
=
$this
->
getMock
(
'Drupal\Core\Entity\EntityStorageControllerInterface'
);
$entity_manager
=
$this
->
getMock
(
'Drupal\Core\Entity\EntityManagerInterface'
);
// Getting the user storage controller should only happen once per test.
$entity_manager
->
expects
(
$this
->
once
())
->
method
(
'getStorageController'
)
->
with
(
'user'
)
->
will
(
$this
->
returnValue
(
$this
->
userStorage
));
$this
->
passwordService
=
$this
->
getMock
(
'Drupal\Core\Password\PasswordInterface'
);
$this
->
testUser
=
$this
->
getMockBuilder
(
'Drupal\user\Entity\User'
)
->
disableOriginalConstructor
()
->
setMethods
(
array
(
'id'
,
'setPassword'
,
'save'
))
->
getMock
();
$this
->
userAuth
=
new
UserAuth
(
$entity_manager
,
$this
->
passwordService
);
}
/**
* Tests failing authentication with missing credential parameters.
*
* @covers ::authenticate()
*
* @dataProvider providerTestAuthenticateWithMissingCredentials
*/
public
function
testAuthenticateWithMissingCredentials
(
$username
,
$password
)
{
$this
->
userStorage
->
expects
(
$this
->
never
())
->
method
(
'loadByProperties'
);
$this
->
assertFalse
(
$this
->
userAuth
->
authenticate
(
$username
,
$password
));
}
/**
* Data provider for testAuthenticateWithMissingCredentials().
*
* @return array
*/
public
function
providerTestAuthenticateWithMissingCredentials
()
{
return
array
(
array
(
NULL
,
NULL
),
array
(
NULL
,
''
),
array
(
''
,
NULL
),
array
(
''
,
''
),
);
}
/**
* Tests the authenticate method with no account returned.
*
* @covers ::authenticate()
*/
public
function
testAuthenticateWithNoAccountReturned
()
{
$this
->
userStorage
->
expects
(
$this
->
once
())
->
method
(
'loadByProperties'
)
->
with
(
array
(
'name'
=>
$this
->
username
))
->
will
(
$this
->
returnValue
(
array
()));
$this
->
assertFalse
(
$this
->
userAuth
->
authenticate
(
$this
->
username
,
$this
->
password
));
}
/**
* Tests the authenticate method with an incorrect password.
*
* @covers ::authenticate()
*/
public
function
testAuthenticateWithIncorrectPassword
()
{
$this
->
userStorage
->
expects
(
$this
->
once
())
->
method
(
'loadByProperties'
)
->
with
(
array
(
'name'
=>
$this
->
username
))
->
will
(
$this
->
returnValue
(
array
(
$this
->
testUser
)));
$this
->
passwordService
->
expects
(
$this
->
once
())
->
method
(
'check'
)
->
with
(
$this
->
password
,
$this
->
testUser
)
->
will
(
$this
->
returnValue
(
FALSE
));
$this
->
assertFalse
(
$this
->
userAuth
->
authenticate
(
$this
->
username
,
$this
->
password
));
}
/**
* Tests the authenticate method with a correct password.
*
* @covers ::authenticate()
*/
public
function
testAuthenticateWithCorrectPassword
()
{
$this
->
testUser
->
expects
(
$this
->
once
())
->
method
(
'id'
)
->
will
(
$this
->
returnValue
(
1
));
$this
->
userStorage
->
expects
(
$this
->
once
())
->
method
(
'loadByProperties'
)
->
with
(
array
(
'name'
=>
$this
->
username
))
->
will
(
$this
->
returnValue
(
array
(
$this
->
testUser
)));
$this
->
passwordService
->
expects
(
$this
->
once
())
->
method
(
'check'
)
->
with
(
$this
->
password
,
$this
->
testUser
)
->
will
(
$this
->
returnValue
(
TRUE
));
$this
->
assertsame
(
1
,
$this
->
userAuth
->
authenticate
(
$this
->
username
,
$this
->
password
));
}
/**
* Tests the authenticate method with a correct password and new password hash.
*
* @covers ::authenticate()
*/
public
function
testAuthenticateWithCorrectPasswordAndNewPasswordHash
()
{
$this
->
testUser
->
expects
(
$this
->
once
())
->
method
(
'id'
)
->
will
(
$this
->
returnValue
(
1
));
$this
->
testUser
->
expects
(
$this
->
once
())
->
method
(
'setPassword'
)
->
with
(
$this
->
password
);
$this
->
testUser
->
expects
(
$this
->
once
())
->
method
(
'save'
);
$this
->
userStorage
->
expects
(
$this
->
once
())
->
method
(
'loadByProperties'
)
->
with
(
array
(
'name'
=>
$this
->
username
))
->
will
(
$this
->
returnValue
(
array
(
$this
->
testUser
)));
$this
->
passwordService
->
expects
(
$this
->
once
())
->
method
(
'check'
)
->
with
(
$this
->
password
,
$this
->
testUser
)
->
will
(
$this
->
returnValue
(
TRUE
));
$this
->
passwordService
->
expects
(
$this
->
once
())
->
method
(
'userNeedsNewHash'
)
->
with
(
$this
->
testUser
)
->
will
(
$this
->
returnValue
(
TRUE
));
$this
->
assertsame
(
1
,
$this
->
userAuth
->
authenticate
(
$this
->
username
,
$this
->
password
));
}
}
core/modules/user/user.module
View file @
8bab6674
...
...
@@ -796,26 +796,12 @@ function user_admin_paths() {
* A plain-text password, such as trimmed text from form values.
* @return
* The user's uid on success, or FALSE on failure to authenticate.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
* Use \Drupal\user\UserAuth::authenticate() instead.
*/
function
user_authenticate
(
$name
,
$password
)
{
$uid
=
FALSE
;
if
(
!
empty
(
$name
)
&&
!
empty
(
$password
))
{
$account
=
user_load_by_name
(
$name
);
if
(
$account
)
{
$password_hasher
=
\
Drupal
::
service
(
'password'
);
if
(
$password_hasher
->
check
(
$password
,
$account
))
{
// Successful authentication.
$uid
=
$account
->
id
();
// Update user to new password scheme if needed.
if
(
$password_hasher
->
userNeedsNewHash
(
$account
))
{
$account
->
setPassword
(
$password
);
$account
->
save
();
}
}
}
}
return
$uid
;
return
\
Drupal
::
service
(
'user.auth'
)
->
authenticate
(
$name
,
$password
);
}
/**
...
...
core/modules/user/user.services.yml
View file @
8bab6674
...
...
@@ -33,3 +33,6 @@ services:
user.permissions_hash
:
class
:
Drupal\user\PermissionsHash
arguments
:
[
'
@private_key'
,
'
@cache.cache'
]
user.auth
:
class
:
Drupal\user\UserAuth
arguments
:
[
'
@entity.manager'
,
'
@password'
]
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment