summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2017-01-30 19:30:04 -0600
committerGitHub <noreply@github.com>2017-01-30 19:30:04 -0600
commit5bad417e57231e129b7113ebb110b1f2b282f349 (patch)
tree77f5d78e2bd4cd4fe3a70e1659875cce4d832c56
parente50320dc71135bf546c757f7dea6e23f5f48a906 (diff)
parent3ee5c7ea4e508b4945646013f871ad532d09ddbd (diff)
downloadnextcloud-server-5bad417e57231e129b7113ebb110b1f2b282f349.tar.gz
nextcloud-server-5bad417e57231e129b7113ebb110b1f2b282f349.zip
Merge pull request #2044 from nextcloud/login-credential-store
Login credential store
-rw-r--r--apps/encryption/appinfo/info.xml3
-rw-r--r--apps/files_external/appinfo/info.xml3
-rw-r--r--apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php60
-rw-r--r--apps/files_external/tests/Command/ListCommandTest.php15
-rw-r--r--core/Controller/LoginController.php1
-rw-r--r--core/templates/login.php2
-rw-r--r--lib/composer/composer/autoload_classmap.php5
-rw-r--r--lib/composer/composer/autoload_static.php5
-rw-r--r--lib/private/AppFramework/DependencyInjection/DIContainer.php4
-rw-r--r--lib/private/Authentication/LoginCredentials/Credentials.php72
-rw-r--r--lib/private/Authentication/LoginCredentials/Store.php120
-rw-r--r--lib/private/Server.php16
-rw-r--r--lib/private/legacy/util.php21
-rw-r--r--lib/public/Authentication/Exceptions/CredentialsUnavailableException.php34
-rw-r--r--lib/public/Authentication/LoginCredentials/ICredentials.php58
-rw-r--r--lib/public/Authentication/LoginCredentials/IStore.php44
-rw-r--r--tests/Core/Controller/LoginControllerTest.php3
-rw-r--r--tests/data/app/expected-info.json1
-rw-r--r--tests/data/app/invalid-info.xml1
-rw-r--r--tests/data/app/valid-info.xml1
-rw-r--r--tests/lib/Authentication/LoginCredentials/CredentialsTest.php66
-rw-r--r--tests/lib/Authentication/LoginCredentials/StoreTest.php182
22 files changed, 637 insertions, 80 deletions
diff --git a/apps/encryption/appinfo/info.xml b/apps/encryption/appinfo/info.xml
index 1e63ca5c471..307fef4ad8a 100644
--- a/apps/encryption/appinfo/info.xml
+++ b/apps/encryption/appinfo/info.xml
@@ -18,8 +18,7 @@
<user>user-encryption</user>
<admin>admin-encryption</admin>
</documentation>
- <rememberlogin>false</rememberlogin>
- <version>1.5.0</version>
+ <version>1.6.0</version>
<types>
<filesystem/>
</types>
diff --git a/apps/files_external/appinfo/info.xml b/apps/files_external/appinfo/info.xml
index 8482b8b25ed..3f6a48d2e22 100644
--- a/apps/files_external/appinfo/info.xml
+++ b/apps/files_external/appinfo/info.xml
@@ -12,8 +12,7 @@ External storage can be configured using the GUI or at the command line. This se
<documentation>
<admin>admin-external-storage</admin>
</documentation>
- <rememberlogin>false</rememberlogin>
- <version>1.2.0</version>
+ <version>1.3.0</version>
<types>
<filesystem/>
</types>
diff --git a/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php b/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php
index 2fa939764d7..30644206c26 100644
--- a/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php
+++ b/apps/files_external/lib/Lib/Auth/Password/SessionCredentials.php
@@ -1,4 +1,5 @@
<?php
+
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -23,61 +24,42 @@
namespace OCA\Files_External\Lib\Auth\Password;
-use \OCP\IUser;
-use \OCP\IL10N;
-use \OCA\Files_External\Lib\DefinitionParameter;
-use \OCA\Files_External\Lib\Auth\AuthMechanism;
-use \OCA\Files_External\Lib\StorageConfig;
-use \OCP\ISession;
-use \OCP\Security\ICrypto;
-use \OCP\Files\Storage;
-use \OCA\Files_External\Lib\SessionStorageWrapper;
-use \OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
+use OCA\Files_External\Lib\Auth\AuthMechanism;
+use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
+use OCA\Files_External\Lib\SessionStorageWrapper;
+use OCA\Files_External\Lib\StorageConfig;
+use OCP\Authentication\Exceptions\CredentialsUnavailableException;
+use OCP\Authentication\LoginCredentials\IStore as CredentialsStore;
+use OCP\Files\Storage;
+use OCP\IL10N;
+use OCP\IUser;
/**
* 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) {
- $this->session = $session;
- $this->crypto = $crypto;
+ public function __construct(IL10N $l, CredentialsStore $credentialsStore) {
+ $this->credentialsStore = $credentialsStore;
- $this
- ->setIdentifier('password::sessioncredentials')
+ $this->setIdentifier('password::sessioncredentials')
->setScheme(self::SCHEME_PASSWORD)
->setText($l->t('Log-in credentials, save in session'))
- ->addParameters([
- ])
- ;
-
- \OCP\Util::connectHook('OC_User', 'post_login', $this, 'authenticate');
- }
-
- /**
- * Hook listener on post login
- *
- * @param array $params
- */
- public function authenticate(array $params) {
- $this->session->set('password::sessioncredentials/credentials', $this->crypto->encrypt(json_encode($params)));
+ ->addParameters([]);
}
public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) {
- $encrypted = $this->session->get('password::sessioncredentials/credentials');
- if (!isset($encrypted)) {
+ try {
+ $credentials = $this->credentialsStore->getLoginCredentials();
+ } catch (CredentialsUnavailableException $e) {
throw new InsufficientDataForMeaningfulAnswerException('No session credentials saved');
}
- $credentials = json_decode($this->crypto->decrypt($encrypted), true);
- $storage->setBackendOption('user', $this->session->get('loginname'));
- $storage->setBackendOption('password', $credentials['password']);
+ $storage->setBackendOption('user', $credentials->getLoginName());
+ $storage->setBackendOption('password', $credentials->getPassword());
}
public function wrapStorage(Storage $storage) {
diff --git a/apps/files_external/tests/Command/ListCommandTest.php b/apps/files_external/tests/Command/ListCommandTest.php
index 5563b19c7a8..76a8f98f520 100644
--- a/apps/files_external/tests/Command/ListCommandTest.php
+++ b/apps/files_external/tests/Command/ListCommandTest.php
@@ -31,25 +31,27 @@ use OCA\Files_External\Lib\Backend\Local;
use OCA\Files_External\Lib\StorageConfig;
use OCA\Files_External\Service\GlobalStoragesService;
use OCA\Files_External\Service\UserStoragesService;
+use OCP\Authentication\LoginCredentials\IStore;
use OCP\IL10N;
use OCP\ISession;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Security\ICrypto;
+use PHPUnit_Framework_MockObject_MockObject;
use Symfony\Component\Console\Output\BufferedOutput;
class ListCommandTest extends CommandTest {
/**
- * @return \OCA\Files_External\Command\ListCommand|\PHPUnit_Framework_MockObject_MockObject
+ * @return ListCommand|PHPUnit_Framework_MockObject_MockObject
*/
private function getInstance() {
- /** @var \OCA\Files_External\Service\GlobalStoragesService|\PHPUnit_Framework_MockObject_MockObject $globalService */
+ /** @var GlobalStoragesService|PHPUnit_Framework_MockObject_MockObject $globalService */
$globalService = $this->createMock(GlobalStoragesService::class);
- /** @var \OCA\Files_External\Service\UserStoragesService|\PHPUnit_Framework_MockObject_MockObject $userService */
+ /** @var UserStoragesService|PHPUnit_Framework_MockObject_MockObject $userService */
$userService = $this->createMock(UserStoragesService::class);
- /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject $userManager */
+ /** @var IUserManager|PHPUnit_Framework_MockObject_MockObject $userManager */
$userManager = $this->createMock(IUserManager::class);
- /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject $userSession */
+ /** @var IUserSession|PHPUnit_Framework_MockObject_MockObject $userSession */
$userSession = $this->createMock(IUserSession::class);
return new ListCommand($globalService, $userService, $userSession, $userManager);
@@ -64,7 +66,8 @@ class ListCommandTest extends CommandTest {
$mount1->setAuthMechanism(new Password($l10n));
$mount1->setBackend(new Local($l10n, new NullMechanism($l10n)));
$mount2 = new StorageConfig();
- $mount2->setAuthMechanism(new SessionCredentials($l10n, $session, $crypto));
+ $credentialStore = $this->createMock(IStore::class);
+ $mount2->setAuthMechanism(new SessionCredentials($l10n, $credentialStore));
$mount2->setBackend(new Local($l10n, new NullMechanism($l10n)));
$input = $this->getInput($instance, [], [
'output' => 'json'
diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php
index 2509cdf0bde..52bd2213954 100644
--- a/core/Controller/LoginController.php
+++ b/core/Controller/LoginController.php
@@ -159,7 +159,6 @@ class LoginController extends Controller {
}
$parameters['alt_login'] = OC_App::getAlternativeLogIns();
- $parameters['rememberLoginAllowed'] = OC_Util::rememberLoginAllowed();
$parameters['rememberLoginState'] = !empty($remember_login) ? $remember_login : 0;
if (!is_null($user) && $user !== '') {
diff --git a/core/templates/login.php b/core/templates/login.php
index c200dfe366b..221242c0dcb 100644
--- a/core/templates/login.php
+++ b/core/templates/login.php
@@ -68,7 +68,6 @@ script('core', [
<input type="submit" id="submit" class="login primary icon-confirm-white" title="" value="<?php p($l->t('Log in')); ?>" disabled="disabled" />
<div class="login-additional">
- <?php if ($_['rememberLoginAllowed'] === true) : ?>
<div class="remember-login-container">
<?php if ($_['rememberLoginState'] === 0) { ?>
<input type="checkbox" name="remember_login" value="1" id="remember_login" class="checkbox checkbox--white">
@@ -77,7 +76,6 @@ script('core', [
<?php } ?>
<label for="remember_login"><?php p($l->t('Stay logged in')); ?></label>
</div>
- <?php endif; ?>
</div>
<input type="hidden" name="timezone_offset" id="timezone_offset"/>
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 9c4a2f2728b..4a345ed7a6d 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -54,7 +54,10 @@ return array(
'OCP\\App\\AppPathNotFoundException' => $baseDir . '/lib/public/App/AppPathNotFoundException.php',
'OCP\\App\\IAppManager' => $baseDir . '/lib/public/App/IAppManager.php',
'OCP\\App\\ManagerEvent' => $baseDir . '/lib/public/App/ManagerEvent.php',
+ 'OCP\\Authentication\\Exceptions\\CredentialsUnavailableException' => $baseDir . '/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php',
'OCP\\Authentication\\IApacheBackend' => $baseDir . '/lib/public/Authentication/IApacheBackend.php',
+ 'OCP\\Authentication\\LoginCredentials\\ICredentials' => $baseDir . '/lib/public/Authentication/LoginCredentials/ICredentials.php',
+ 'OCP\\Authentication\\LoginCredentials\\IStore' => $baseDir . '/lib/public/Authentication/LoginCredentials/IStore.php',
'OCP\\Authentication\\TwoFactorAuth\\IProvider' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/IProvider.php',
'OCP\\Authentication\\TwoFactorAuth\\TwoFactorException' => $baseDir . '/lib/public/Authentication/TwoFactorAuth/TwoFactorException.php',
'OCP\\AutoloadNotAllowedException' => $baseDir . '/lib/public/AutoloadNotAllowedException.php',
@@ -324,6 +327,8 @@ return array(
'OC\\Authentication\\Exceptions\\PasswordlessTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/PasswordlessTokenException.php',
'OC\\Authentication\\Exceptions\\TwoFactorAuthRequiredException' => $baseDir . '/lib/private/Authentication/Exceptions/TwoFactorAuthRequiredException.php',
'OC\\Authentication\\Exceptions\\UserAlreadyLoggedInException' => $baseDir . '/lib/private/Authentication/Exceptions/UserAlreadyLoggedInException.php',
+ 'OC\\Authentication\\LoginCredentials\\Credentials' => $baseDir . '/lib/private/Authentication/LoginCredentials/Credentials.php',
+ 'OC\\Authentication\\LoginCredentials\\Store' => $baseDir . '/lib/private/Authentication/LoginCredentials/Store.php',
'OC\\Authentication\\Token\\DefaultToken' => $baseDir . '/lib/private/Authentication/Token/DefaultToken.php',
'OC\\Authentication\\Token\\DefaultTokenCleanupJob' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenCleanupJob.php',
'OC\\Authentication\\Token\\DefaultTokenMapper' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenMapper.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index de1047e9729..f8d360fec4b 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -84,7 +84,10 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\App\\AppPathNotFoundException' => __DIR__ . '/../../..' . '/lib/public/App/AppPathNotFoundException.php',
'OCP\\App\\IAppManager' => __DIR__ . '/../../..' . '/lib/public/App/IAppManager.php',
'OCP\\App\\ManagerEvent' => __DIR__ . '/../../..' . '/lib/public/App/ManagerEvent.php',
+ 'OCP\\Authentication\\Exceptions\\CredentialsUnavailableException' => __DIR__ . '/../../..' . '/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php',
'OCP\\Authentication\\IApacheBackend' => __DIR__ . '/../../..' . '/lib/public/Authentication/IApacheBackend.php',
+ 'OCP\\Authentication\\LoginCredentials\\ICredentials' => __DIR__ . '/../../..' . '/lib/public/Authentication/LoginCredentials/ICredentials.php',
+ 'OCP\\Authentication\\LoginCredentials\\IStore' => __DIR__ . '/../../..' . '/lib/public/Authentication/LoginCredentials/IStore.php',
'OCP\\Authentication\\TwoFactorAuth\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/IProvider.php',
'OCP\\Authentication\\TwoFactorAuth\\TwoFactorException' => __DIR__ . '/../../..' . '/lib/public/Authentication/TwoFactorAuth/TwoFactorException.php',
'OCP\\AutoloadNotAllowedException' => __DIR__ . '/../../..' . '/lib/public/AutoloadNotAllowedException.php',
@@ -354,6 +357,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Authentication\\Exceptions\\PasswordlessTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/PasswordlessTokenException.php',
'OC\\Authentication\\Exceptions\\TwoFactorAuthRequiredException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/TwoFactorAuthRequiredException.php',
'OC\\Authentication\\Exceptions\\UserAlreadyLoggedInException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/UserAlreadyLoggedInException.php',
+ 'OC\\Authentication\\LoginCredentials\\Credentials' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Credentials.php',
+ 'OC\\Authentication\\LoginCredentials\\Store' => __DIR__ . '/../../..' . '/lib/private/Authentication/LoginCredentials/Store.php',
'OC\\Authentication\\Token\\DefaultToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultToken.php',
'OC\\Authentication\\Token\\DefaultTokenCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenCleanupJob.php',
'OC\\Authentication\\Token\\DefaultTokenMapper' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenMapper.php',
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php
index 57499f3ffe8..0879b3e9330 100644
--- a/lib/private/AppFramework/DependencyInjection/DIContainer.php
+++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php
@@ -93,6 +93,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return new Output($this->getServer()->getWebRoot());
});
+ $this->registerService(\OCP\Authentication\LoginCredentials\IStore::class, function() {
+ return $this->getServer()->query(\OCP\Authentication\LoginCredentials\IStore::class);
+ });
+
$this->registerService('OCP\\IAvatarManager', function($c) {
return $this->getServer()->getAvatarManager();
});
diff --git a/lib/private/Authentication/LoginCredentials/Credentials.php b/lib/private/Authentication/LoginCredentials/Credentials.php
new file mode 100644
index 00000000000..9314b7489db
--- /dev/null
+++ b/lib/private/Authentication/LoginCredentials/Credentials.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @copyright 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Authentication\LoginCredentials;
+
+use OCP\Authentication\LoginCredentials\ICredentials;
+
+class Credentials implements ICredentials {
+
+ /** @var string */
+ private $uid;
+
+ /** @var string */
+ private $loginName;
+
+ /** @var string */
+ private $password;
+
+ /**
+ * @param string $uid
+ * @param string $loginName
+ * @param string $password
+ */
+ public function __construct($uid, $loginName, $password) {
+ $this->uid = $uid;
+ $this->loginName = $loginName;
+ $this->password = $password;
+ }
+
+ /**
+ * @return string
+ */
+ public function getUID() {
+ return $this->uid;
+ }
+
+ /**
+ * @return string
+ */
+ public function getLoginName() {
+ return $this->loginName;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPassword() {
+ return $this->password;
+ }
+
+}
diff --git a/lib/private/Authentication/LoginCredentials/Store.php b/lib/private/Authentication/LoginCredentials/Store.php
new file mode 100644
index 00000000000..e44c88c7aea
--- /dev/null
+++ b/lib/private/Authentication/LoginCredentials/Store.php
@@ -0,0 +1,120 @@
+<?php
+
+/**
+ * @copyright 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Authentication\LoginCredentials;
+
+use OC\Authentication\Exceptions\InvalidTokenException;
+use OC\Authentication\Exceptions\PasswordlessTokenException;
+use OC\Authentication\Token\IProvider;
+use OCP\Authentication\Exceptions\CredentialsUnavailableException;
+use OCP\Authentication\LoginCredentials\ICredentials;
+use OCP\Authentication\LoginCredentials\IStore;
+use OCP\ILogger;
+use OCP\ISession;
+use OCP\Session\Exceptions\SessionNotAvailableException;
+use OCP\Util;
+
+class Store implements IStore {
+
+ /** @var ISession */
+ private $session;
+
+ /** @var ILogger */
+ private $logger;
+
+ /** @var IProvider|null */
+ private $tokenProvider;
+
+ /**
+ * @param ISession $session
+ * @param ILogger $logger
+ * @param IProvider $tokenProvider
+ */
+ public function __construct(ISession $session, ILogger $logger, IProvider $tokenProvider = null) {
+ $this->session = $session;
+ $this->logger = $logger;
+ $this->tokenProvider = $tokenProvider;
+
+ 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));
+ }
+
+ /**
+ * Replace the session implementation
+ *
+ * @param ISession $session
+ */
+ public function setSession(ISession $session) {
+ $this->session = $session;
+ }
+
+ /**
+ * @since 12
+ *
+ * @return ICredentials the login credentials of the current user
+ * @throws CredentialsUnavailableException
+ */
+ public function getLoginCredentials() {
+ if (is_null($this->tokenProvider)) {
+ throw new CredentialsUnavailableException();
+ }
+
+ $trySession = false;
+ try {
+ $sessionId = $this->session->getId();
+ $token = $this->tokenProvider->getToken($sessionId);
+
+ $uid = $token->getUID();
+ $user = $token->getLoginName();
+ $password = $this->tokenProvider->getPassword($token, $sessionId);
+
+ return new Credentials($uid, $user, $password);
+ } catch (SessionNotAvailableException $ex) {
+ $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();
+ }
+
+}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index bd8818e9460..3c716ae6ce6 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -46,6 +46,7 @@ use OC\App\AppStore\Fetcher\AppFetcher;
use OC\App\AppStore\Fetcher\CategoryFetcher;
use OC\AppFramework\Http\Request;
use OC\AppFramework\Utility\TimeFactory;
+use OC\Authentication\LoginCredentials\Store;
use OC\Command\AsyncBus;
use OC\Diagnostics\EventLogger;
use OC\Diagnostics\NullEventLogger;
@@ -89,6 +90,7 @@ use OC\Security\TrustedDomainHelper;
use OC\Session\CryptoWrapper;
use OC\Tagging\TagMapper;
use OCA\Theming\ThemingDefaults;
+use OCP\Authentication\LoginCredentials\IStore;
use OCP\IL10N;
use OCP\IServerContainer;
use OCP\RichObjectStrings\IValidator;
@@ -246,6 +248,17 @@ class Server extends ServerContainer implements IServerContainer {
});
return $groupManager;
});
+ $this->registerService(Store::class, function(Server $c) {
+ $session = $c->getSession();
+ if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
+ $tokenProvider = $c->query('OC\Authentication\Token\IProvider');
+ } else {
+ $tokenProvider = null;
+ }
+ $logger = $c->getLogger();
+ return new Store($session, $logger, $tokenProvider);
+ });
+ $this->registerAlias(IStore::class, Store::class);
$this->registerService('OC\Authentication\Token\DefaultTokenMapper', function (Server $c) {
$dbConnection = $c->getDatabaseConnection();
return new Authentication\Token\DefaultTokenMapper($dbConnection);
@@ -1000,7 +1013,8 @@ class Server extends ServerContainer implements IServerContainer {
*/
public function setSession(\OCP\ISession $session) {
$this->query(SessionStorage::class)->setSession($session);
- return $this->query('UserSession')->setSession($session);
+ $this->query('UserSession')->setSession($session);
+ $this->query(Store::class)->setSession($session);
}
/**
diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php
index d97ba37c4c0..5ef1130d361 100644
--- a/lib/private/legacy/util.php
+++ b/lib/private/legacy/util.php
@@ -1002,27 +1002,6 @@ class OC_Util {
}
/**
- * Check if it is allowed to remember login.
- *
- * @note Every app can set 'rememberlogin' to 'false' to disable the remember login feature
- *
- * @return bool
- */
- public static function rememberLoginAllowed() {
-
- $apps = OC_App::getEnabledApps();
-
- foreach ($apps as $app) {
- $appInfo = OC_App::getAppInfo($app);
- if (isset($appInfo['rememberlogin']) && $appInfo['rememberlogin'] === 'false') {
- return false;
- }
-
- }
- return true;
- }
-
- /**
* Check if the user is a subadmin, redirects to home if not
*
* @return null|boolean $groups where the current user is subadmin
diff --git a/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php b/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php
new file mode 100644
index 00000000000..9f9e38103f7
--- /dev/null
+++ b/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @copyright 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCP\Authentication\Exceptions;
+
+use Exception;
+
+/**
+ * @since 12
+ */
+class CredentialsUnavailableException extends Exception {
+
+}
diff --git a/lib/public/Authentication/LoginCredentials/ICredentials.php b/lib/public/Authentication/LoginCredentials/ICredentials.php
new file mode 100644
index 00000000000..c5ef9574398
--- /dev/null
+++ b/lib/public/Authentication/LoginCredentials/ICredentials.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @copyright 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCP\Authentication\LoginCredentials;
+
+/**
+ * @since 12
+ */
+interface ICredentials {
+
+ /**
+ * Get the user UID
+ *
+ * @since 12
+ *
+ * @return string
+ */
+ public function getUID();
+
+ /**
+ * Get the login name the users used to login
+ *
+ * @since 12
+ *
+ * @return string
+ */
+ public function getLoginName();
+
+ /**
+ * Get the password
+ *
+ * @since 12
+ *
+ * @return string
+ */
+ public function getPassword();
+}
diff --git a/lib/public/Authentication/LoginCredentials/IStore.php b/lib/public/Authentication/LoginCredentials/IStore.php
new file mode 100644
index 00000000000..4787b16d982
--- /dev/null
+++ b/lib/public/Authentication/LoginCredentials/IStore.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @copyright 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCP\Authentication\LoginCredentials;
+
+use OCP\Authentication\Exceptions\CredentialsUnavailableException;
+
+/**
+ * @since 12
+ */
+interface IStore {
+
+ /**
+ * Get login credentials of the currently logged in user
+ *
+ * @since 12
+ *
+ * @throws CredentialsUnavailableException
+ * @return ICredentials the login credentials of the current user
+ */
+ public function getLoginCredentials();
+
+}
diff --git a/tests/Core/Controller/LoginControllerTest.php b/tests/Core/Controller/LoginControllerTest.php
index 600179a1dc5..a1a4452abf8 100644
--- a/tests/Core/Controller/LoginControllerTest.php
+++ b/tests/Core/Controller/LoginControllerTest.php
@@ -179,7 +179,6 @@ class LoginControllerTest extends TestCase {
'user_autofocus' => true,
'canResetPassword' => true,
'alt_login' => [],
- 'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(),
'rememberLoginState' => 0,
'resetPasswordLink' => null,
],
@@ -238,7 +237,6 @@ class LoginControllerTest extends TestCase {
'user_autofocus' => false,
'canResetPassword' => $expectedResult,
'alt_login' => [],
- 'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(),
'rememberLoginState' => 0,
'resetPasswordLink' => false,
],
@@ -277,7 +275,6 @@ class LoginControllerTest extends TestCase {
'user_autofocus' => false,
'canResetPassword' => false,
'alt_login' => [],
- 'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(),
'rememberLoginState' => 0,
'resetPasswordLink' => false,
],
diff --git a/tests/data/app/expected-info.json b/tests/data/app/expected-info.json
index 646f22bea85..0666b902f2c 100644
--- a/tests/data/app/expected-info.json
+++ b/tests/data/app/expected-info.json
@@ -13,7 +13,6 @@
"user": "user-encryption",
"admin": "admin-encryption"
},
- "rememberlogin": "false",
"types": ["filesystem"],
"ocsid": "166047",
"dependencies": {
diff --git a/tests/data/app/invalid-info.xml b/tests/data/app/invalid-info.xml
index 3947f5420c2..0ddb13b89c0 100644
--- a/tests/data/app/invalid-info.xml
+++ b/tests/data/app/invalid-info.xml
@@ -14,7 +14,6 @@
<user>user-encryption</user>
<admin>admin-encryption</admin>
</documentation>
- <rememberlogin>false</rememberlogin>
<types>
<filesystem/>
</types>
diff --git a/tests/data/app/valid-info.xml b/tests/data/app/valid-info.xml
index 4b22d55d7bc..4788d046c13 100644
--- a/tests/data/app/valid-info.xml
+++ b/tests/data/app/valid-info.xml
@@ -14,7 +14,6 @@
<user>user-encryption</user>
<admin>admin-encryption</admin>
</documentation>
- <rememberlogin>false</rememberlogin>
<types>
<filesystem/>
</types>
diff --git a/tests/lib/Authentication/LoginCredentials/CredentialsTest.php b/tests/lib/Authentication/LoginCredentials/CredentialsTest.php
new file mode 100644
index 00000000000..308ccafb151
--- /dev/null
+++ b/tests/lib/Authentication/LoginCredentials/CredentialsTest.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @copyright 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Test\Authentication\LoginCredentials;
+
+use OC\Authentication\LoginCredentials\Credentials;
+use Test\TestCase;
+
+class CredentialsTest extends TestCase {
+
+ /** @var string */
+ private $uid;
+
+ /** @var string */
+ private $user;
+
+ /** @var string */
+ private $password;
+
+ /** @var Credentials */
+ private $credentials;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->uid = 'user123';
+ $this->user = 'User123';
+ $this->password = '123456';
+
+ $this->credentials = new Credentials($this->uid, $this->user, $this->password);
+ }
+
+ public function testGetUID() {
+ $this->assertEquals($this->uid, $this->credentials->getUID());
+ }
+
+ public function testGetUserName() {
+ $this->assertEquals($this->user, $this->credentials->getLoginName());
+ }
+
+ public function testGetPassword() {
+ $this->assertEquals($this->password, $this->credentials->getPassword());
+ }
+
+}
diff --git a/tests/lib/Authentication/LoginCredentials/StoreTest.php b/tests/lib/Authentication/LoginCredentials/StoreTest.php
new file mode 100644
index 00000000000..9a719339b43
--- /dev/null
+++ b/tests/lib/Authentication/LoginCredentials/StoreTest.php
@@ -0,0 +1,182 @@
+<?php
+
+/**
+ * @copyright 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2016 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Test\Authentication\LoginCredentials;
+
+use OC\Authentication\Exceptions\InvalidTokenException;
+use OC\Authentication\Exceptions\PasswordlessTokenException;
+use OC\Authentication\LoginCredentials\Credentials;
+use OC\Authentication\LoginCredentials\Store;
+use OC\Authentication\Token\IProvider;
+use OC\Authentication\Token\IToken;
+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 {
+
+ /** @var ISession|PHPUnit_Framework_MockObject_MockObject */
+ private $session;
+
+ /** @var IProvider|PHPUnit_Framework_MockObject_MockObject */
+ private $tokenProvider;
+
+ /** @var ILogger|PHPUnit_Framework_MockObject_MockObject */
+ private $logger;
+
+ /** @var Store */
+ private $store;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->session = $this->createMock(ISession::class);
+ $this->tokenProvider = $this->createMock(IProvider::class);
+ $this->logger = $this->createMock(ILogger::class);
+
+ $this->store = new Store($this->session, $this->logger, $this->tokenProvider);
+ }
+
+ 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 testGetLoginCredentialsNoTokenProvider() {
+ $this->store = new Store($this->session, $this->logger, null);
+
+ $this->expectException(CredentialsUnavailableException::class);
+
+ $this->store->getLoginCredentials();
+ }
+
+ public function testGetLoginCredentials() {
+ $uid = 'uid';
+ $user = 'user123';
+ $password = 'passme';
+ $token = $this->createMock(IToken::class);
+ $this->session->expects($this->once())
+ ->method('getId')
+ ->willReturn('sess2233');
+ $this->tokenProvider->expects($this->once())
+ ->method('getToken')
+ ->with('sess2233')
+ ->willReturn($token);
+ $token->expects($this->once())
+ ->method('getUID')
+ ->willReturn($uid);
+ $token->expects($this->once())
+ ->method('getLoginName')
+ ->willReturn($user);
+ $this->tokenProvider->expects($this->once())
+ ->method('getPassword')
+ ->with($token, 'sess2233')
+ ->willReturn($password);
+ $expected = new Credentials($uid, $user, $password);
+
+ $creds = $this->store->getLoginCredentials();
+
+ $this->assertEquals($expected, $creds);
+ }
+
+ public function testGetLoginCredentialsSessionNotAvailable() {
+ $this->session->expects($this->once())
+ ->method('getId')
+ ->will($this->throwException(new SessionNotAvailableException()));
+ $this->expectException(CredentialsUnavailableException::class);
+
+ $this->store->getLoginCredentials();
+ }
+
+ public function testGetLoginCredentialsInvalidToken() {
+ $this->session->expects($this->once())
+ ->method('getId')
+ ->willReturn('sess2233');
+ $this->tokenProvider->expects($this->once())
+ ->method('getToken')
+ ->with('sess2233')
+ ->will($this->throwException(new InvalidTokenException()));
+ $this->expectException(CredentialsUnavailableException::class);
+
+ $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')
+ ->willReturn('sess2233');
+ $this->tokenProvider->expects($this->once())
+ ->method('getToken')
+ ->with('sess2233')
+ ->will($this->throwException(new PasswordlessTokenException()));
+ $this->expectException(CredentialsUnavailableException::class);
+
+ $this->store->getLoginCredentials();
+ }
+
+}