From 3fe802d93112d7d3642807c3a83ec474b4b5c404 Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Mon, 24 Aug 2015 16:32:44 +0100 Subject: [PATCH] Introduce 'login credentials' auth mechanism Stores user credentials in the database after user login, uses the new CredentialsManager class --- apps/files_external/appinfo/application.php | 1 + .../lib/auth/password/logincredentials.php | 92 +++++++++++++++++++ .../lib/auth/password/sessioncredentials.php | 3 +- .../files_external/lib/auth/publickey/rsa.php | 3 +- apps/files_external/lib/backend/smb.php | 4 +- apps/files_external/lib/backend/smb_oc.php | 3 +- .../lib/config/configadapter.php | 4 +- .../lib/storagemodifiertrait.php | 4 +- 8 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 apps/files_external/lib/auth/password/logincredentials.php diff --git a/apps/files_external/appinfo/application.php b/apps/files_external/appinfo/application.php index 0c8b90935d3..86c58a45d5c 100644 --- a/apps/files_external/appinfo/application.php +++ b/apps/files_external/appinfo/application.php @@ -103,6 +103,7 @@ class Application extends App { // AuthMechanism::SCHEME_PASSWORD mechanisms $container->query('OCA\Files_External\Lib\Auth\Password\Password'), $container->query('OCA\Files_External\Lib\Auth\Password\SessionCredentials'), + $container->query('OCA\Files_External\Lib\Auth\Password\LoginCredentials'), // AuthMechanism::SCHEME_OAUTH1 mechanisms $container->query('OCA\Files_External\Lib\Auth\OAuth1\OAuth1'), diff --git a/apps/files_external/lib/auth/password/logincredentials.php b/apps/files_external/lib/auth/password/logincredentials.php new file mode 100644 index 00000000000..99cac3f4202 --- /dev/null +++ b/apps/files_external/lib/auth/password/logincredentials.php @@ -0,0 +1,92 @@ + + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Files_External\Lib\Auth\Password; + +use \OCP\IL10N; +use \OCP\IUser; +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\ICredentialsManager; +use \OCP\Files\Storage; +use \OCA\Files_External\Lib\SessionStorageWrapper; +use \OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; + +/** + * Username and password from login credentials, saved in DB + */ +class LoginCredentials extends AuthMechanism { + + const CREDENTIALS_IDENTIFIER = 'password::logincredentials/credentials'; + + /** @var ISession */ + protected $session; + + /** @var ICredentialsManager */ + protected $credentialsManager; + + public function __construct(IL10N $l, ISession $session, ICredentialsManager $credentialsManager) { + $this->session = $session; + $this->credentialsManager = $credentialsManager; + + $this + ->setIdentifier('password::logincredentials') + ->setScheme(self::SCHEME_PASSWORD) + ->setText($l->t('Login credentials')) + ->addParameters([ + ]) + ; + + \OCP\Util::connectHook('OC_User', 'post_login', $this, 'authenticate'); + } + + /** + * Hook listener on post login + * + * @param array $params + */ + public function authenticate(array $params) { + $userId = $params['uid']; + $credentials = [ + 'user' => $this->session->get('loginname'), + 'password' => $params['password'] + ]; + $this->credentialsManager->store($userId, self::CREDENTIALS_IDENTIFIER, $credentials); + } + + public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) { + if (!isset($user)) { + throw new InsufficientDataForMeaningfulAnswerException('No login credentials saved'); + } + $uid = $user->getUID(); + $credentials = $this->credentialsManager->retrieve($uid, self::CREDENTIALS_IDENTIFIER); + + if (!isset($credentials)) { + throw new InsufficientDataForMeaningfulAnswerException('No login credentials saved'); + } + + $storage->setBackendOption('user', $credentials['user']); + $storage->setBackendOption('password', $credentials['password']); + } + +} diff --git a/apps/files_external/lib/auth/password/sessioncredentials.php b/apps/files_external/lib/auth/password/sessioncredentials.php index 4f7d24c2f60..3fb8b8526cc 100644 --- a/apps/files_external/lib/auth/password/sessioncredentials.php +++ b/apps/files_external/lib/auth/password/sessioncredentials.php @@ -21,6 +21,7 @@ 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; @@ -66,7 +67,7 @@ class SessionCredentials extends AuthMechanism { $this->session->set('password::sessioncredentials/credentials', $this->crypto->encrypt(json_encode($params))); } - public function manipulateStorageConfig(StorageConfig &$storage) { + public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) { $encrypted = $this->session->get('password::sessioncredentials/credentials'); if (!isset($encrypted)) { throw new InsufficientDataForMeaningfulAnswerException('No session credentials saved'); diff --git a/apps/files_external/lib/auth/publickey/rsa.php b/apps/files_external/lib/auth/publickey/rsa.php index 131b3f36526..9045f6818f9 100644 --- a/apps/files_external/lib/auth/publickey/rsa.php +++ b/apps/files_external/lib/auth/publickey/rsa.php @@ -26,6 +26,7 @@ use \OCA\Files_External\Lib\DefinitionParameter; use \OCA\Files_External\Lib\Auth\AuthMechanism; use \OCA\Files_External\Lib\StorageConfig; use \OCP\IConfig; +use OCP\IUser; use \phpseclib\Crypt\RSA as RSACrypt; /** @@ -55,7 +56,7 @@ class RSA extends AuthMechanism { ; } - public function manipulateStorageConfig(StorageConfig &$storage) { + public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) { $auth = new RSACrypt(); $auth->setPassword($this->config->getSystemValue('secret', '')); if (!$auth->loadKey($storage->getBackendOption('private_key'))) { diff --git a/apps/files_external/lib/backend/smb.php b/apps/files_external/lib/backend/smb.php index aaf7658751f..9b71636936a 100644 --- a/apps/files_external/lib/backend/smb.php +++ b/apps/files_external/lib/backend/smb.php @@ -30,6 +30,7 @@ use \OCA\Files_External\Lib\StorageConfig; use \OCA\Files_External\Lib\LegacyDependencyCheckPolyfill; use \OCA\Files_External\Lib\Auth\Password\Password; +use OCP\IUser; class SMB extends Backend { @@ -56,8 +57,9 @@ class SMB extends Backend { /** * @param StorageConfig $storage + * @param IUser $user */ - public function manipulateStorageConfig(StorageConfig &$storage) { + public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) { $user = $storage->getBackendOption('user'); if ($domain = $storage->getBackendOption('domain')) { $storage->setBackendOption('user', $domain.'\\'.$user); diff --git a/apps/files_external/lib/backend/smb_oc.php b/apps/files_external/lib/backend/smb_oc.php index 57fdfc30ff3..ba38754ce5a 100644 --- a/apps/files_external/lib/backend/smb_oc.php +++ b/apps/files_external/lib/backend/smb_oc.php @@ -30,6 +30,7 @@ use \OCA\Files_External\Lib\Auth\Password\SessionCredentials; use \OCA\Files_External\Lib\StorageConfig; use \OCA\Files_External\Lib\LegacyDependencyCheckPolyfill; use \OCA\Files_External\Lib\Backend\SMB; +use OCP\IUser; /** * Deprecated SMB_OC class - use SMB with the password::sessioncredentials auth mechanism @@ -59,7 +60,7 @@ class SMB_OC extends Backend { ; } - public function manipulateStorageConfig(StorageConfig &$storage) { + public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) { $username_as_share = ($storage->getBackendOption('username_as_share') === true); if ($username_as_share) { diff --git a/apps/files_external/lib/config/configadapter.php b/apps/files_external/lib/config/configadapter.php index 0cd1381c815..2bf39bcaa4f 100644 --- a/apps/files_external/lib/config/configadapter.php +++ b/apps/files_external/lib/config/configadapter.php @@ -85,8 +85,8 @@ class ConfigAdapter implements IMountProvider { $storage->setBackendOption('objectstore', new $objectClass($objectStore)); } - $storage->getAuthMechanism()->manipulateStorageConfig($storage); - $storage->getBackend()->manipulateStorageConfig($storage); + $storage->getAuthMechanism()->manipulateStorageConfig($storage, $user); + $storage->getBackend()->manipulateStorageConfig($storage, $user); } /** diff --git a/apps/files_external/lib/storagemodifiertrait.php b/apps/files_external/lib/storagemodifiertrait.php index ec2b0a14ab1..30c2108feec 100644 --- a/apps/files_external/lib/storagemodifiertrait.php +++ b/apps/files_external/lib/storagemodifiertrait.php @@ -21,6 +21,7 @@ namespace OCA\Files_External\Lib; +use \OCP\IUser; use \OCP\Files\Storage; use \OCA\Files_External\Lib\StorageConfig; use \OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; @@ -45,10 +46,11 @@ trait StorageModifierTrait { * Modify a StorageConfig parameters * * @param StorageConfig $storage + * @param IUser $user User the storage is being used as * @throws InsufficientDataForMeaningfulAnswerException * @throws StorageNotAvailableException */ - public function manipulateStorageConfig(StorageConfig &$storage) { + public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) { } /**