From d5dd30c3a0bcd90da75a497a5e0eea775f1a2101 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 21 Jun 2016 14:58:35 +0200 Subject: [PATCH] Add "Login credentials" and "User Provided" This adds the "Login Credentials" and "User Provided" option to the external storage implementation, it is basically done by reverting 176fb191b7ec1c742b70295ca2a315d8cc1f1ea0 from https://github.com/owncloud/core/pull/22432. This was taken from owncloud/core which is AGPL licensed. --- .../lib/AppInfo/Application.php | 2 + .../Lib/Auth/Password/LoginCredentials.php | 92 +++++++++++++++++++ .../lib/Lib/Auth/Password/UserProvided.php | 88 ++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 apps/files_external/lib/Lib/Auth/Password/LoginCredentials.php create mode 100644 apps/files_external/lib/Lib/Auth/Password/UserProvided.php diff --git a/apps/files_external/lib/AppInfo/Application.php b/apps/files_external/lib/AppInfo/Application.php index ee773d03d8..cbbcbe9c31 100644 --- a/apps/files_external/lib/AppInfo/Application.php +++ b/apps/files_external/lib/AppInfo/Application.php @@ -112,6 +112,8 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide // 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'), + $container->query('OCA\Files_External\Lib\Auth\Password\UserProvided'), $container->query('OCA\Files_External\Lib\Auth\Password\GlobalAuth'), // AuthMechanism::SCHEME_OAUTH1 mechanisms diff --git a/apps/files_external/lib/Lib/Auth/Password/LoginCredentials.php b/apps/files_external/lib/Lib/Auth/Password/LoginCredentials.php new file mode 100644 index 0000000000..25bd66fb41 --- /dev/null +++ b/apps/files_external/lib/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('Log-in credentials, save in database')) + ->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/Lib/Auth/Password/UserProvided.php b/apps/files_external/lib/Lib/Auth/Password/UserProvided.php new file mode 100644 index 0000000000..2f27716318 --- /dev/null +++ b/apps/files_external/lib/Lib/Auth/Password/UserProvided.php @@ -0,0 +1,88 @@ + + * + * @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 OCA\Files_External\Lib\Auth\IUserProvided; +use OCA\Files_External\Lib\DefinitionParameter; +use OCA\Files_External\Service\BackendService; +use OCP\IL10N; +use OCP\IUser; +use OCA\Files_External\Lib\Auth\AuthMechanism; +use OCA\Files_External\Lib\StorageConfig; +use OCP\Security\ICredentialsManager; +use OCP\Files\Storage; +use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; + +/** + * User provided Username and Password + */ +class UserProvided extends AuthMechanism implements IUserProvided { + + const CREDENTIALS_IDENTIFIER_PREFIX = 'password::userprovided/'; + + /** @var ICredentialsManager */ + protected $credentialsManager; + + public function __construct(IL10N $l, ICredentialsManager $credentialsManager) { + $this->credentialsManager = $credentialsManager; + + $this + ->setIdentifier('password::userprovided') + ->setVisibility(BackendService::VISIBILITY_ADMIN) + ->setScheme(self::SCHEME_PASSWORD) + ->setText($l->t('User entered, store in database')) + ->addParameters([ + (new DefinitionParameter('user', $l->t('Username'))) + ->setFlag(DefinitionParameter::FLAG_USER_PROVIDED), + (new DefinitionParameter('password', $l->t('Password'))) + ->setType(DefinitionParameter::VALUE_PASSWORD) + ->setFlag(DefinitionParameter::FLAG_USER_PROVIDED), + ]); + } + + private function getCredentialsIdentifier($storageId) { + return self::CREDENTIALS_IDENTIFIER_PREFIX . $storageId; + } + + public function saveBackendOptions(IUser $user, $id, array $options) { + $this->credentialsManager->store($user->getUID(), $this->getCredentialsIdentifier($id), [ + 'user' => $options['user'], // explicitly copy the fields we want instead of just passing the entire $options array + 'password' => $options['password'] // this way we prevent users from being able to modify any other field + ]); + } + + public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) { + if (!isset($user)) { + throw new InsufficientDataForMeaningfulAnswerException('No credentials saved'); + } + $uid = $user->getUID(); + $credentials = $this->credentialsManager->retrieve($uid, $this->getCredentialsIdentifier($storage->getId())); + + if (!isset($credentials)) { + throw new InsufficientDataForMeaningfulAnswerException('No credentials saved'); + } + + $storage->setBackendOption('user', $credentials['user']); + $storage->setBackendOption('password', $credentials['password']); + } + +}