From 40b99734d3413ecee7c7ae1d71868c801b7c4188 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Mon, 25 Apr 2016 14:56:11 +0200 Subject: [PATCH] introduce accounts table and keep it up-to-date with the data added to the personal settings Signed-off-by: Roeland Jago Douma --- db_structure.xml | 32 ++++ lib/private/Accounts/AccountManager.php | 116 ++++++++++++++ settings/Application.php | 135 +++++++++++++++- settings/Controller/UsersController.php | 26 +++- tests/lib/accounts/AccountsManagerTest.php | 173 +++++++++++++++++++++ 5 files changed, 479 insertions(+), 3 deletions(-) create mode 100644 lib/private/Accounts/AccountManager.php create mode 100644 tests/lib/accounts/AccountsManagerTest.php diff --git a/db_structure.xml b/db_structure.xml index c7e1e072a8e..545628a9233 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -2113,4 +2113,36 @@ + + + *dbprefix*accounts + + + + uid + text + + true + 64 + + + data + clob + + true + + + + uid_index + true + true + + uid + ascending + + + + +
+ diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php new file mode 100644 index 00000000000..3decac0153a --- /dev/null +++ b/lib/private/Accounts/AccountManager.php @@ -0,0 +1,116 @@ + + * + * @copyright Copyright (c) 2016, 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 OC\Accounts; + + +use OCP\IDBConnection; + +/** + * Class AccountManager + * + * Manage system accounts table + * + * @group DB + * @package OC\Accounts + */ +class AccountManager { + + /** @var IDBConnection database connection */ + private $connection; + + /** @var string table name */ + private $table = 'accounts'; + + /** + * AccountManager constructor. + * + * @param IDBConnection $connection + */ + public function __construct(IDBConnection $connection) { + $this->connection = $connection; + } + + public function updateUser($uid, $data) { + $userData = $this->getUser($uid); + if (empty($userData)) { + $this->insertNewUser($uid, $data); + } else { + $this->updateExistingUser($uid, $data); + } + } + + /** + * get stored data from a given user + * + * @param $uid + * @return array + */ + public function getUser($uid) { + $query = $this->connection->getQueryBuilder(); + $query->select('data')->from($this->table) + ->where($query->expr()->eq('uid', $query->createParameter('uid'))) + ->setParameter('uid', $uid); + $query->execute(); + $result = $query->execute()->fetchAll(); + + if (empty($result)) { + return []; + } + + return json_decode($result[0]['data'], true); + } + + /** + * add new user to accounts table + * + * @param string $uid + * @param array $data + */ + protected function insertNewUser($uid, $data) { + $jsonEncodedData = json_encode($data); + $query = $this->connection->getQueryBuilder(); + $query->insert($this->table) + ->values( + [ + 'uid' => $query->createNamedParameter($uid), + 'data' => $query->createNamedParameter($jsonEncodedData), + ] + ) + ->execute(); + } + + /** + * update existing user in accounts table + * + * @param string $uid + * @param array $data + */ + protected function updateExistingUser($uid, $data) { + $jsonEncodedData = json_encode($data); + $query = $this->connection->getQueryBuilder(); + $query->update($this->table) + ->set('data', $query->createNamedParameter($jsonEncodedData)) + ->where($query->expr()->eq('uid', $query->createNamedParameter($uid))) + ->execute(); + } +} diff --git a/settings/Application.php b/settings/Application.php index d907cd666fb..d0eab02cdd3 100644 --- a/settings/Application.php +++ b/settings/Application.php @@ -35,8 +35,21 @@ use OC\App\AppStore\Fetcher\CategoryFetcher; use OC\AppFramework\Utility\TimeFactory; use OC\Authentication\Token\IProvider; use OC\Server; +use OC\Files\View; +use OC\Server; +use OC\Settings\Controller\AppSettingsController; +use OC\Settings\Controller\AuthSettingsController; +use OC\Settings\Controller\CertificateController; +use OC\Settings\Controller\CheckSetupController; +use OC\Settings\Controller\EncryptionController; +use OC\Settings\Controller\GroupsController; +use OC\Settings\Controller\LogSettingsController; +use OC\Settings\Controller\MailSettingsController; +use OC\Settings\Controller\SecuritySettingsController; +use OC\Settings\Controller\UsersController; use OC\Settings\Middleware\SubadminMiddleware; use OCP\AppFramework\App; +use OCP\AppFramework\IAppContainer; use OCP\IContainer; use OCP\Settings\IManager; use OCP\Util; @@ -57,7 +70,127 @@ class Application extends App { // Register Middleware $container->registerAlias('SubadminMiddleware', SubadminMiddleware::class); - $container->registerMiddleWare('SubadminMiddleware'); + /** + * Controllers + */ + $container->registerService('MailSettingsController', function(IContainer $c) { + return new MailSettingsController( + $c->query('AppName'), + $c->query('Request'), + $c->query('L10N'), + $c->query('Config'), + $c->query('UserSession'), + $c->query('Defaults'), + $c->query('Mailer'), + $c->query('DefaultMailAddress') + ); + }); + $container->registerService('EncryptionController', function(IContainer $c) { + return new EncryptionController( + $c->query('AppName'), + $c->query('Request'), + $c->query('L10N'), + $c->query('Config'), + $c->query('DatabaseConnection'), + $c->query('UserManager'), + new View(), + $c->query('Logger') + ); + }); + $container->registerService('AppSettingsController', function(IContainer $c) { + return new AppSettingsController( + $c->query('AppName'), + $c->query('Request'), + $c->query('L10N'), + $c->query('Config'), + $c->query('ICacheFactory'), + $c->query('INavigationManager'), + $c->query('IAppManager'), + $c->query('OcsClient') + ); + }); + $container->registerService('AuthSettingsController', function(IContainer $c) { + return new AuthSettingsController( + $c->query('AppName'), + $c->query('Request'), + $c->query('ServerContainer')->query('OC\Authentication\Token\IProvider'), + $c->query('UserManager'), + $c->query('ServerContainer')->getSession(), + $c->query('ServerContainer')->getSecureRandom(), + $c->query('UserId') + ); + }); + $container->registerService('SecuritySettingsController', function(IContainer $c) { + return new SecuritySettingsController( + $c->query('AppName'), + $c->query('Request'), + $c->query('Config') + ); + }); + $container->registerService('AccountManager', function(IAppContainer $c) { + return new AccountManager($c->getServer()->getDatabaseConnection()); + }); + $container->registerService('CertificateController', function(IContainer $c) { + return new CertificateController( + $c->query('AppName'), + $c->query('Request'), + $c->query('CertificateManager'), + $c->query('SystemCertificateManager'), + $c->query('L10N'), + $c->query('IAppManager') + ); + }); + $container->registerService('GroupsController', function(IContainer $c) { + return new GroupsController( + $c->query('AppName'), + $c->query('Request'), + $c->query('GroupManager'), + $c->query('UserSession'), + $c->query('IsAdmin'), + $c->query('L10N') + ); + }); + $container->registerService('UsersController', function(IContainer $c) { + return new UsersController( + $c->query('AppName'), + $c->query('Request'), + $c->query('UserManager'), + $c->query('GroupManager'), + $c->query('UserSession'), + $c->query('Config'), + $c->query('IsAdmin'), + $c->query('L10N'), + $c->query('Logger'), + $c->query('Defaults'), + $c->query('Mailer'), + $c->query('DefaultMailAddress'), + $c->query('URLGenerator'), + $c->query('OCP\\App\\IAppManager'), + $c->query('OCP\\IAvatarManager'), + $c->query('AccountManager') + ); + }); + $container->registerService('LogSettingsController', function(IContainer $c) { + return new LogSettingsController( + $c->query('AppName'), + $c->query('Request'), + $c->query('Config'), + $c->query('L10N') + ); + }); + $container->registerService('CheckSetupController', function(IContainer $c) { + return new CheckSetupController( + $c->query('AppName'), + $c->query('Request'), + $c->query('Config'), + $c->query('ClientService'), + $c->query('URLGenerator'), + $c->query('Util'), + $c->query('L10N'), + $c->query('Checker') + ); + }); + /** * Core class wrappers diff --git a/settings/Controller/UsersController.php b/settings/Controller/UsersController.php index 7529cedd196..35344234330 100644 --- a/settings/Controller/UsersController.php +++ b/settings/Controller/UsersController.php @@ -30,6 +30,7 @@ namespace OC\Settings\Controller; +use OC\Accounts\AccountManager; use OC\AppFramework\Http; use OC\User\User; use OCP\App\IAppManager; @@ -80,6 +81,8 @@ class UsersController extends Controller { private $isRestoreEnabled = false; /** @var IAvatarManager */ private $avatarManager; + /** @var AccountManager */ + private $accountManager; /** * @param string $appName @@ -97,6 +100,7 @@ class UsersController extends Controller { * @param IURLGenerator $urlGenerator * @param IAppManager $appManager * @param IAvatarManager $avatarManager + * @param AccountManager $accountManager */ public function __construct($appName, IRequest $request, @@ -112,7 +116,9 @@ class UsersController extends Controller { $fromMailAddress, IURLGenerator $urlGenerator, IAppManager $appManager, - IAvatarManager $avatarManager) { + IAvatarManager $avatarManager, + AccountManager $accountManager +) { parent::__construct($appName, $request); $this->userManager = $userManager; $this->groupManager = $groupManager; @@ -126,6 +132,7 @@ class UsersController extends Controller { $this->fromMailAddress = $fromMailAddress; $this->urlGenerator = $urlGenerator; $this->avatarManager = $avatarManager; + $this->accountManager = $accountManager; // check for encryption state - TODO see formatUserForIndex $this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption'); @@ -519,7 +526,22 @@ class UsersController extends Controller { $email, $emailScope, $website, $websiteScope, $address, $addressScope) { - // TODO: implement + + if($userId === null) { + $userId = $this->userSession->getUser()->getUID(); + } + + $data = [ + 'avatar' => ['scope' => $avatarScope], + 'displayName' => ['value' => $displayname, 'scope' => $displaynameScope], + 'email' => ['value' => $email, 'scope' => $emailScope], + 'website' => ['value' => $website, 'scope' => $websiteScope], + 'address' => ['value' => $address, 'scope' => $addressScope], + 'phone' => ['value' => $phone, 'scope' => $phoneScope] + ]; + + $this->accountManager->updateUser($userId, $data); + return new DataResponse( array( 'status' => 'success', diff --git a/tests/lib/accounts/AccountsManagerTest.php b/tests/lib/accounts/AccountsManagerTest.php new file mode 100644 index 00000000000..1e9464bceb7 --- /dev/null +++ b/tests/lib/accounts/AccountsManagerTest.php @@ -0,0 +1,173 @@ + + * + * @copyright Copyright (c) 2016, 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 Test\Accounts; + + +use OC\Accounts\AccountManager; +use OC\Mail\Mailer; +use Test\TestCase; + +/** + * Class AccountsManagerTest + * + * @group DB + * @package Test\Accounts + */ +class AccountsManagerTest extends TestCase { + + /** @var \OCP\IDBConnection */ + private $connection; + + /** @var string accounts table name */ + private $table = 'accounts'; + + public function setUp() { + parent::setUp(); + $this->connection = \OC::$server->getDatabaseConnection(); + } + + public function tearDown() { + parent::tearDown(); + $query = $this->connection->getQueryBuilder(); + $query->delete($this->table)->execute(); + } + + /** + * get a instance of the accountManager + * + * @param array $mockedMethods list of methods which should be mocked + * @return \PHPUnit_Framework_MockObject_MockObject | AccountManager + */ + public function getInstance($mockedMethods = null) { + return $this->getMockBuilder('OC\Accounts\AccountManager') + ->setConstructorArgs([$this->connection]) + ->setMethods($mockedMethods) + ->getMock(); + + } + + /** + * @dataProvider dataTrueFalse + * + * @param bool $userAlreadyExists + */ + public function testUpdateUser($userAlreadyExists) { + $accountManager = $this->getInstance(['getUser', 'insertNewUser', 'updateExistingUser']); + + $accountManager->expects($this->once())->method('getUser')->willReturn($userAlreadyExists); + + if ($userAlreadyExists) { + $accountManager->expects($this->once())->method('updateExistingUser') + ->with('uid', 'data'); + $accountManager->expects($this->never())->method('insertNewUser'); + } else { + $accountManager->expects($this->once())->method('insertNewUser') + ->with('uid', 'data'); + $accountManager->expects($this->never())->method('updateExistingUser'); + } + + $accountManager->updateUser('uid', 'data'); + } + + public function dataTrueFalse() { + return [ + [true], + [false] + ]; + } + + + /** + * @dataProvider dataTestGetUser + * + * @param string $setUser + * @param array $setData + * @param string $askUser + * @param array $expectedData + */ + public function testGetUser($setUser, $setData, $askUser, $expectedData) { + $accountManager = $this->getInstance(); + $this->addDummyValuesToTable($setUser, $setData); + $this->assertEquals($expectedData, + $accountManager->getUser($askUser) + ); + } + + public function dataTestGetUser() { + return [ + ['user1', ['key' => 'value'], 'user1', ['key' => 'value']], + ['user1', ['key' => 'value'], 'user2', []], + ]; + } + + public function testUpdateExistingUser() { + $user = 'user1'; + $oldData = ['key' => 'value']; + $newData = ['newKey' => 'newValue']; + + $accountManager = $this->getInstance(); + $this->addDummyValuesToTable($user, $oldData); + $this->invokePrivate($accountManager, 'updateExistingUser', [$user, $newData]); + $newDataFromTable = $this->getDataFromTable($user); + $this->assertEquals($newData, $newDataFromTable); + } + + public function testInsertNewUser() { + $user = 'user1'; + $data = ['key' => 'value']; + + $accountManager = $this->getInstance(); + $this->assertNull($this->getDataFromTable($user)); + $this->invokePrivate($accountManager, 'insertNewUser', [$user, $data]); + + $dataFromDb = $this->getDataFromTable($user); + $this->assertEquals($data, $dataFromDb); + } + + private function addDummyValuesToTable($uid, $data) { + + $query = $this->connection->getQueryBuilder(); + $query->insert($this->table) + ->values( + [ + 'uid' => $query->createNamedParameter($uid), + 'data' => $query->createNamedParameter(json_encode($data)), + ] + ) + ->execute(); + } + + private function getDataFromTable($uid) { + $query = $this->connection->getQueryBuilder(); + $query->select('data')->from($this->table) + ->where($query->expr()->eq('uid', $query->createParameter('uid'))) + ->setParameter('uid', $uid); + $query->execute(); + $result = $query->execute()->fetchAll(); + + if (!empty($result)) { + return json_decode($result[0]['data'], true); + } + } + +} -- 2.39.5