Skip to content

Commit 86a0e64

Browse files
ChristophWurstDeepDiver1975
authored andcommitted
Login hooks (#25260)
* fix login hooks * adjust user session tests * fix login return value of successful token logins * trigger preLogin hook earlier; extract method 'loginWithPassword' * call postLogin hook earlier; add PHPDoc
1 parent 332b38f commit 86a0e64

File tree

2 files changed

+65
-41
lines changed

2 files changed

+65
-41
lines changed

lib/private/User/Session.php

Lines changed: 61 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -280,46 +280,11 @@ public function getLoginName() {
280280
*/
281281
public function login($uid, $password) {
282282
$this->session->regenerateId();
283-
if ($this->validateToken($password, $uid)) {
284-
// When logging in with token, the password must be decrypted first before passing to login hook
285-
try {
286-
$token = $this->tokenProvider->getToken($password);
287-
try {
288-
$loginPassword = $this->tokenProvider->getPassword($token, $password);
289-
$this->manager->emit('\OC\User', 'preLogin', array($uid, $loginPassword));
290-
} catch (PasswordlessTokenException $ex) {
291-
$this->manager->emit('\OC\User', 'preLogin', array($uid, ''));
292-
}
293-
} catch (InvalidTokenException $ex) {
294-
// Invalid token, nothing to do
295-
}
296283

297-
$this->loginWithToken($password);
298-
$user = $this->getUser();
284+
if ($this->validateToken($password, $uid)) {
285+
return $this->loginWithToken($password);
299286
} else {
300-
$this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
301-
$user = $this->manager->checkPassword($uid, $password);
302-
}
303-
if ($user !== false) {
304-
if (!is_null($user)) {
305-
if ($user->isEnabled()) {
306-
$this->setUser($user);
307-
$this->setLoginName($uid);
308-
$this->manager->emit('\OC\User', 'postLogin', array($user, $password));
309-
if ($this->isLoggedIn()) {
310-
$this->prepareUserLogin();
311-
return true;
312-
} else {
313-
// injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
314-
$message = \OC::$server->getL10N('lib')->t('Login canceled by app');
315-
throw new LoginException($message);
316-
}
317-
} else {
318-
// injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
319-
$message = \OC::$server->getL10N('lib')->t('User disabled');
320-
throw new LoginException($message);
321-
}
322-
}
287+
return $this->loginWithPassword($uid, $password);
323288
}
324289
return false;
325290
}
@@ -449,6 +414,49 @@ public function tryBasicAuthLogin(IRequest $request) {
449414
return false;
450415
}
451416

417+
/**
418+
* Log an user in via login name and password
419+
*
420+
* @param string $uid
421+
* @param string $password
422+
* @return boolean
423+
* @throws LoginException if an app canceld the login process or the user is not enabled
424+
*/
425+
private function loginWithPassword($uid, $password) {
426+
$this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
427+
$user = $this->manager->checkPassword($uid, $password);
428+
if ($user === false) {
429+
// Password check failed
430+
return false;
431+
}
432+
433+
if ($user->isEnabled()) {
434+
$this->setUser($user);
435+
$this->setLoginName($uid);
436+
$this->manager->emit('\OC\User', 'postLogin', array($user, $password));
437+
if ($this->isLoggedIn()) {
438+
$this->prepareUserLogin();
439+
return true;
440+
} else {
441+
// injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
442+
$message = \OC::$server->getL10N('lib')->t('Login canceled by app');
443+
throw new LoginException($message);
444+
}
445+
} else {
446+
// injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
447+
$message = \OC::$server->getL10N('lib')->t('User disabled');
448+
throw new LoginException($message);
449+
}
450+
return false;
451+
}
452+
453+
/**
454+
* Log an user in with a given token (id)
455+
*
456+
* @param string $token
457+
* @return boolean
458+
* @throws LoginException if an app canceld the login process or the user is not enabled
459+
*/
452460
private function loginWithToken($token) {
453461
try {
454462
$dbToken = $this->tokenProvider->getToken($token);
@@ -457,12 +465,14 @@ private function loginWithToken($token) {
457465
}
458466
$uid = $dbToken->getUID();
459467

468+
// When logging in with token, the password must be decrypted first before passing to login hook
460469
$password = '';
461470
try {
462471
$password = $this->tokenProvider->getPassword($dbToken, $token);
463472
} catch (PasswordlessTokenException $ex) {
464473
// Ignore and use empty string instead
465474
}
475+
466476
$this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
467477

468478
$user = $this->manager->get($uid);
@@ -472,13 +482,24 @@ private function loginWithToken($token) {
472482
}
473483
if (!$user->isEnabled()) {
474484
// disabled users can not log in
475-
return false;
485+
// injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
486+
$message = \OC::$server->getL10N('lib')->t('User disabled');
487+
throw new LoginException($message);
476488
}
477489

478490
//login
479491
$this->setUser($user);
480-
492+
$this->setLoginName($dbToken->getLoginName());
481493
$this->manager->emit('\OC\User', 'postLogin', array($user, $password));
494+
495+
if ($this->isLoggedIn()) {
496+
$this->prepareUserLogin();
497+
} else {
498+
// injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
499+
$message = \OC::$server->getL10N('lib')->t('Login canceled by app');
500+
throw new LoginException($message);
501+
}
502+
482503
return true;
483504
}
484505

tests/lib/User/SessionTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,9 @@ public function testCreateSessionTokenWithNonExistentUser() {
729729
$this->assertFalse($userSession->createSessionToken($request, $uid, $loginName, $password));
730730
}
731731

732+
/**
733+
* @expectedException \OC\User\LoginException
734+
*/
732735
public function testTryTokenLoginWithDisabledUser() {
733736
$manager = $this->getMockBuilder('\OC\User\Manager')
734737
->disableOriginalConstructor()
@@ -761,7 +764,7 @@ public function testTryTokenLoginWithDisabledUser() {
761764
->method('isEnabled')
762765
->will($this->returnValue(false));
763766

764-
$this->assertFalse($userSession->tryTokenLogin($request));
767+
$userSession->tryTokenLogin($request);
765768
}
766769

767770
public function testValidateSessionDisabledUser() {

0 commit comments

Comments
 (0)