use login hook credentials as fallback
If no session token is available, we can use the credentials provided by the login hook. Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
parent
e4abb9cb6e
commit
6f74ecd94a
|
@ -32,27 +32,17 @@ use OCP\Authentication\Exceptions\CredentialsUnavailableException;
|
|||
use OCP\Authentication\LoginCredentials\IStore as CredentialsStore;
|
||||
use OCP\Files\Storage;
|
||||
use OCP\IL10N;
|
||||
use OCP\ISession;
|
||||
use OCP\IUser;
|
||||
use OCP\Security\ICrypto;
|
||||
|
||||
/**
|
||||
* Username and password from login credentials, saved in session
|
||||
*/
|
||||
class SessionCredentials extends AuthMechanism {
|
||||
|
||||
/** @var ISession */
|
||||
protected $session;
|
||||
|
||||
/** @var ICrypto */
|
||||
protected $crypto;
|
||||
|
||||
/** @var CredentialsStore */
|
||||
private $credentialsStore;
|
||||
|
||||
public function __construct(IL10N $l, ISession $session, ICrypto $crypto, CredentialsStore $credentialsStore) {
|
||||
$this->session = $session;
|
||||
$this->crypto = $crypto;
|
||||
public function __construct(IL10N $l, CredentialsStore $credentialsStore) {
|
||||
$this->credentialsStore = $credentialsStore;
|
||||
|
||||
$this->setIdentifier('password::sessioncredentials')
|
||||
|
|
|
@ -33,6 +33,7 @@ use OCP\Authentication\LoginCredentials\IStore;
|
|||
use OCP\ILogger;
|
||||
use OCP\ISession;
|
||||
use OCP\Session\Exceptions\SessionNotAvailableException;
|
||||
use OCP\Util;
|
||||
|
||||
class Store implements IStore {
|
||||
|
||||
|
@ -54,6 +55,17 @@ class Store implements IStore {
|
|||
$this->session = $session;
|
||||
$this->tokenProvider = $tokenProvider;
|
||||
$this->logger = $logger;
|
||||
|
||||
Util::connectHook('OC_User', 'post_login', $this, 'authenticate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook listener on post login
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
public function authenticate(array $params) {
|
||||
$this->session->set('login_credentials', json_encode($params));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,6 +84,7 @@ class Store implements IStore {
|
|||
* @throws CredentialsUnavailableException
|
||||
*/
|
||||
public function getLoginCredentials() {
|
||||
$trySession = false;
|
||||
try {
|
||||
$sessionId = $this->session->getId();
|
||||
$token = $this->tokenProvider->getToken($sessionId);
|
||||
|
@ -85,9 +98,17 @@ class Store implements IStore {
|
|||
$this->logger->debug('could not get login credentials because session is unavailable', ['app' => 'core']);
|
||||
} catch (InvalidTokenException $ex) {
|
||||
$this->logger->debug('could not get login credentials because the token is invalid', ['app' => 'core']);
|
||||
$trySession = true;
|
||||
} catch (PasswordlessTokenException $ex) {
|
||||
$this->logger->debug('could not get login credentials because the token has no password', ['app' => 'core']);
|
||||
$trySession = true;
|
||||
}
|
||||
|
||||
if ($trySession && $this->session->exists('login_credentials')) {
|
||||
$creds = json_decode($this->session->get('login_credentials'));
|
||||
return new Credentials($creds->uid, $creds->uid, $creds->password);
|
||||
}
|
||||
|
||||
// If we reach this line, an exception was thrown.
|
||||
throw new CredentialsUnavailableException();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ use OCP\Authentication\Exceptions\CredentialsUnavailableException;
|
|||
use OCP\ILogger;
|
||||
use OCP\ISession;
|
||||
use OCP\Session\Exceptions\SessionNotAvailableException;
|
||||
use PHPUnit_Framework_MockObject_MockObject;
|
||||
use Test\TestCase;
|
||||
|
||||
class StoreTest extends TestCase {
|
||||
|
@ -60,6 +61,26 @@ class StoreTest extends TestCase {
|
|||
$this->store = new Store($this->session, $this->tokenProvider, $this->logger);
|
||||
}
|
||||
|
||||
public function testAuthenticate() {
|
||||
$params = [
|
||||
'run' => true,
|
||||
'uid' => 'user123',
|
||||
'password' => 123456,
|
||||
];
|
||||
|
||||
$this->session->expects($this->once())
|
||||
->method('set')
|
||||
->with($this->equalTo('login_credentials'), $this->equalTo(json_encode($params)));
|
||||
|
||||
$this->store->authenticate($params);
|
||||
}
|
||||
|
||||
public function testSetSession() {
|
||||
$session = $this->createMock(ISession::class);
|
||||
|
||||
$this->store->setSession($session);
|
||||
}
|
||||
|
||||
public function testGetLoginCredentials() {
|
||||
$uid = 'uid';
|
||||
$user = 'user123';
|
||||
|
@ -67,21 +88,21 @@ class StoreTest extends TestCase {
|
|||
$token = $this->createMock(IToken::class);
|
||||
$this->session->expects($this->once())
|
||||
->method('getId')
|
||||
->will($this->returnValue('sess2233'));
|
||||
->willReturn('sess2233');
|
||||
$this->tokenProvider->expects($this->once())
|
||||
->method('getToken')
|
||||
->with('sess2233')
|
||||
->will($this->returnValue($token));
|
||||
->willReturn($token);
|
||||
$token->expects($this->once())
|
||||
->method('getUID')
|
||||
->will($this->returnValue($uid));
|
||||
->willReturn($uid);
|
||||
$token->expects($this->once())
|
||||
->method('getLoginName')
|
||||
->will($this->returnValue($user));
|
||||
->willReturn($user);
|
||||
$this->tokenProvider->expects($this->once())
|
||||
->method('getPassword')
|
||||
->with($token, 'sess2233')
|
||||
->will($this->returnValue($password));
|
||||
->willReturn($password);
|
||||
$expected = new Credentials($uid, $user, $password);
|
||||
|
||||
$creds = $this->store->getLoginCredentials();
|
||||
|
@ -101,7 +122,7 @@ class StoreTest extends TestCase {
|
|||
public function testGetLoginCredentialsInvalidToken() {
|
||||
$this->session->expects($this->once())
|
||||
->method('getId')
|
||||
->will($this->returnValue('sess2233'));
|
||||
->willReturn('sess2233');
|
||||
$this->tokenProvider->expects($this->once())
|
||||
->method('getToken')
|
||||
->with('sess2233')
|
||||
|
@ -111,10 +132,36 @@ class StoreTest extends TestCase {
|
|||
$this->store->getLoginCredentials();
|
||||
}
|
||||
|
||||
public function testGetLoginCredentialsInvalidTokenLoginCredentials() {
|
||||
$uid = 'user987';
|
||||
$password = '7389374';
|
||||
|
||||
$this->session->expects($this->once())
|
||||
->method('getId')
|
||||
->willReturn('sess2233');
|
||||
$this->tokenProvider->expects($this->once())
|
||||
->method('getToken')
|
||||
->with('sess2233')
|
||||
->will($this->throwException(new InvalidTokenException()));
|
||||
$this->session->expects($this->once())
|
||||
->method('exists')
|
||||
->with($this->equalTo('login_credentials'))
|
||||
->willReturn(true);
|
||||
$this->session->expects($this->once())
|
||||
->method('get')
|
||||
->with($this->equalTo('login_credentials'))
|
||||
->willReturn('{"run":true,"uid":"user987","password":"7389374"}');
|
||||
$expected = new Credentials('user987', 'user987', '7389374');
|
||||
|
||||
$actual = $this->store->getLoginCredentials();
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
public function testGetLoginCredentialsPasswordlessToken() {
|
||||
$this->session->expects($this->once())
|
||||
->method('getId')
|
||||
->will($this->returnValue('sess2233'));
|
||||
->willReturn('sess2233');
|
||||
$this->tokenProvider->expects($this->once())
|
||||
->method('getToken')
|
||||
->with('sess2233')
|
||||
|
|
Loading…
Reference in New Issue