Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>tags/v13.0.0beta4
@@ -1647,7 +1647,8 @@ OC.PasswordConfirmation = { | |||
requiresPasswordConfirmation: function() { | |||
var timeSinceLogin = moment.now() - (nc_lastLogin * 1000); | |||
return timeSinceLogin > 30 * 60 * 1000; // 30 minutes | |||
// if timeSinceLogin > 30 minutes and user backend allows password confirmation | |||
return (backendAllowsPasswordConfirmation && timeSinceLogin > 30 * 60 * 1000); | |||
}, | |||
/** |
@@ -234,7 +234,8 @@ class DIContainer extends SimpleContainer implements IAppContainer { | |||
$server->getContentSecurityPolicyManager(), | |||
$server->getCsrfTokenManager(), | |||
$server->getContentSecurityPolicyNonceManager(), | |||
$server->getAppManager() | |||
$server->getAppManager(), | |||
$server->getUserSession() | |||
); | |||
}); |
@@ -55,6 +55,7 @@ use OCP\IURLGenerator; | |||
use OCP\IRequest; | |||
use OCP\ILogger; | |||
use OCP\AppFramework\Controller; | |||
use OCP\IUserSession; | |||
use OCP\Util; | |||
use OC\AppFramework\Middleware\Security\Exceptions\SecurityException; | |||
@@ -91,6 +92,8 @@ class SecurityMiddleware extends Middleware { | |||
private $cspNonceManager; | |||
/** @var IAppManager */ | |||
private $appManager; | |||
/** @var IUserSession */ | |||
private $userSession; | |||
/** | |||
* @param IRequest $request | |||
@@ -106,6 +109,7 @@ class SecurityMiddleware extends Middleware { | |||
* @param CSRFTokenManager $csrfTokenManager | |||
* @param ContentSecurityPolicyNonceManager $cspNonceManager | |||
* @param IAppManager $appManager | |||
* @param IUserSession $userSession | |||
*/ | |||
public function __construct(IRequest $request, | |||
ControllerMethodReflector $reflector, | |||
@@ -119,7 +123,9 @@ class SecurityMiddleware extends Middleware { | |||
ContentSecurityPolicyManager $contentSecurityPolicyManager, | |||
CsrfTokenManager $csrfTokenManager, | |||
ContentSecurityPolicyNonceManager $cspNonceManager, | |||
IAppManager $appManager) { | |||
IAppManager $appManager, | |||
IUserSession $userSession | |||
) { | |||
$this->navigationManager = $navigationManager; | |||
$this->request = $request; | |||
$this->reflector = $reflector; | |||
@@ -133,6 +139,7 @@ class SecurityMiddleware extends Middleware { | |||
$this->csrfTokenManager = $csrfTokenManager; | |||
$this->cspNonceManager = $cspNonceManager; | |||
$this->appManager = $appManager; | |||
$this->userSession = $userSession; | |||
} | |||
/** | |||
@@ -164,8 +171,15 @@ class SecurityMiddleware extends Middleware { | |||
} | |||
if ($this->reflector->hasAnnotation('PasswordConfirmationRequired')) { | |||
$user = $this->userSession->getUser(); | |||
$backendClassName = ''; | |||
if ($user !== null) { | |||
$backendClassName = $user->getBackendClassName(); | |||
} | |||
$lastConfirm = (int) $this->session->get('last-password-confirm'); | |||
if ($lastConfirm < (time() - (30 * 60 + 15))) { // allow 15 seconds delay | |||
// we can't check the password against a SAML backend, so skip password confirmation in this case | |||
if ($backendClassName !== 'user_saml' && $lastConfirm < (time() - (30 * 60 + 15))) { // allow 15 seconds delay | |||
throw new NotConfirmedException(); | |||
} | |||
} |
@@ -101,8 +101,10 @@ class JSConfigHelper { | |||
if ($this->currentUser !== null) { | |||
$uid = $this->currentUser->getUID(); | |||
$userBackend = $this->currentUser->getBackendClassName(); | |||
} else { | |||
$uid = null; | |||
$userBackend = ''; | |||
} | |||
// Get the config | |||
@@ -147,6 +149,7 @@ class JSConfigHelper { | |||
$array = [ | |||
"oc_debug" => $this->config->getSystemValue('debug', false) ? 'true' : 'false', | |||
"oc_isadmin" => $this->groupManager->isAdmin($uid) ? 'true' : 'false', | |||
"backendAllowsPasswordConfirmation" => $userBackend === 'user_saml'? 'false' : 'true', | |||
"oc_dataURL" => is_string($dataLocation) ? "\"".$dataLocation."\"" : 'false', | |||
"oc_webroot" => "\"".\OC::$WEBROOT."\"", | |||
"oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution |
@@ -50,6 +50,8 @@ use OCP\INavigationManager; | |||
use OCP\IRequest; | |||
use OCP\ISession; | |||
use OCP\IURLGenerator; | |||
use OCP\IUser; | |||
use OCP\IUserSession; | |||
use OCP\Security\ISecureRandom; | |||
class SecurityMiddlewareTest extends \Test\TestCase { | |||
@@ -82,6 +84,8 @@ class SecurityMiddlewareTest extends \Test\TestCase { | |||
private $cspNonceManager; | |||
/** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $appManager; | |||
/** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $userSession; | |||
protected function setUp() { | |||
parent::setUp(); | |||
@@ -100,6 +104,10 @@ class SecurityMiddlewareTest extends \Test\TestCase { | |||
$this->appManager->expects($this->any()) | |||
->method('isEnabledForUser') | |||
->willReturn(true); | |||
$this->userSession = $this->createMock(IUserSession::class); | |||
$user = $this->createMock(IUser::class); | |||
$user->expects($this->any())->method('getBackendClassName')->willReturn('user_ldap'); | |||
$this->userSession->expects($this->any())->method('getUser')->willReturn($user); | |||
$this->middleware = $this->getMiddleware(true, true); | |||
$this->secException = new SecurityException('hey', false); | |||
$this->secAjaxException = new SecurityException('hey', true); | |||
@@ -124,7 +132,8 @@ class SecurityMiddlewareTest extends \Test\TestCase { | |||
$this->contentSecurityPolicyManager, | |||
$this->csrfTokenManager, | |||
$this->cspNonceManager, | |||
$this->appManager | |||
$this->appManager, | |||
$this->userSession | |||
); | |||
} | |||