From 4c0a408152ad0a9247e4c2dad4919c67a2cf15ee Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Fri, 5 Sep 2014 13:50:51 +0200 Subject: [PATCH] Added account removal --- data/config.ini | 8 ++--- public_html/js/Presenters/UserPresenter.js | 41 +++++++++++++++++++--- public_html/templates/account-removal.tpl | 21 +++++++++++ public_html/templates/user-list.tpl | 2 +- public_html/templates/user.tpl | 7 ++-- src/Controllers/UserController.php | 26 ++++++++------ src/Dao/UserDao.php | 7 ++++ src/Privilege.php | 2 ++ src/Services/UserService.php | 6 ++++ 9 files changed, 98 insertions(+), 22 deletions(-) create mode 100644 public_html/templates/account-removal.tpl diff --git a/data/config.ini b/data/config.ini index 7aafbecd..56393c8e 100644 --- a/data/config.ini +++ b/data/config.ini @@ -9,10 +9,10 @@ minPasswordLength = 5 [security.privileges] anonymous = register, viewUser -regularUser = listUsers, viewUser -powerUser = listUsers, viewUser -moderator = listUsers, viewUser -administrator = listUsers, viewUser +regularUser = listUsers, viewUser, deleteOwnAccount +powerUser = listUsers, viewUser, deleteOwnAccount +moderator = listUsers, viewUser, deleteOwnAccount +administrator = listUsers, viewUser, deleteOwnAccount, deleteUsers [users] minUserNameLength = 1 diff --git a/public_html/js/Presenters/UserPresenter.js b/public_html/js/Presenters/UserPresenter.js index 8f7e7cae..987468a4 100644 --- a/public_html/js/Presenters/UserPresenter.js +++ b/public_html/js/Presenters/UserPresenter.js @@ -14,6 +14,7 @@ App.Presenters.UserPresenter = function( var $messages = $el; var template; var accountSettingsTemplate; + var accountRemovalTemplate; var browsingSettingsTemplate; var user; var userName; @@ -25,11 +26,18 @@ App.Presenters.UserPresenter = function( promise.waitAll( util.promiseTemplate('user'), util.promiseTemplate('account-settings'), + util.promiseTemplate('account-removal'), util.promiseTemplate('browsing-settings'), api.get('/users/' + userName)) - .then(function(userHtml, accountSettingsHtml, browsingSettingsHtml, response) { + .then(function( + userHtml, + accountSettingsHtml, + accountRemovalHtml, + browsingSettingsHtml, + response) { template = _.template(userHtml); accountSettingsTemplate = _.template(accountSettingsHtml); + accountRemovalTemplate = _.template(accountRemovalHtml); browsingSettingsTemplate = _.template(browsingSettingsHtml); user = response.json; @@ -41,12 +49,37 @@ App.Presenters.UserPresenter = function( } function render() { - $el.html(template({user: user})); - $el.find('.browsing-settings').html(browsingSettingsTemplate({user: user})); - $el.find('.account-settings').html(accountSettingsTemplate({user: user})); + var context = { + user: user, + canDeleteAccount: auth.hasPrivilege('deleteAccounts') || + (auth.hasPrivilege('deleteOwnAccount') && auth.getCurrentUser().name == userName), + }; + $el.html(template(context)); + $el.find('.browsing-settings').html(browsingSettingsTemplate(context)); + $el.find('.account-settings').html(accountSettingsTemplate(context)); + $el.find('.account-removal').html(accountRemovalTemplate(context)); + $el.find('.account-removal form').submit(accountRemovalFormSubmitted); $messages = $el.find('.messages'); }; + function accountRemovalFormSubmitted(e) { + e.preventDefault(); + $messages = $el.find('.account-removal .messages'); + messagePresenter.hideMessages($messages); + if (!$el.find('.account-removal input[name=confirmation]:visible').prop('checked')) { + messagePresenter.showError($messages, 'Must confirm to proceed.'); + return; + } + api.delete('/users/' + user.name) + .then(function() { + auth.logout(); + var $messageDiv = messagePresenter.showInfo($messages, 'Account deleted. Back to main page'); + $messageDiv.find('a').click(mainPageLinkClicked); + }).fail(function(response) { + messagePresenter.showError($messages, response.json && response.json.error || response); + }); + } + return { init: init, render: render diff --git a/public_html/templates/account-removal.tpl b/public_html/templates/account-removal.tpl new file mode 100644 index 00000000..7792b45a --- /dev/null +++ b/public_html/templates/account-removal.tpl @@ -0,0 +1,21 @@ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+
+
diff --git a/public_html/templates/user-list.tpl b/public_html/templates/user-list.tpl index f009f657..f7b5e217 100644 --- a/public_html/templates/user-list.tpl +++ b/public_html/templates/user-list.tpl @@ -16,7 +16,7 @@ <% _.each(userList, function(user) { %>
- User name: <%= user.name %> + User name: <%= user.name %>
<% }); %> diff --git a/public_html/templates/user.tpl b/public_html/templates/user.tpl index 9b4e18fa..3d3905e1 100644 --- a/public_html/templates/user.tpl +++ b/public_html/templates/user.tpl @@ -3,11 +3,14 @@ <%= user.name %>

Browsing settings

-

Account settings

-
+ <% if (canDeleteAccount) { %> +

Account removal

+
+ <% } %> + diff --git a/src/Controllers/UserController.php b/src/Controllers/UserController.php index 3497c8c1..7f39ff5f 100644 --- a/src/Controllers/UserController.php +++ b/src/Controllers/UserController.php @@ -26,6 +26,16 @@ final class UserController extends AbstractController $router->delete('/api/users/:name', [$this, 'delete']); } + public function getByName($name) + { + $this->authService->assertPrivilege(\Szurubooru\Privilege::PRIVILEGE_VIEW_USER); + + $user = $this->userService->getByName($name); + if (!$user) + throw new \DomainException('User with name "' . $name . '" was not found.'); + return new \Szurubooru\ViewProxies\User($user); + } + public function getFiltered() { $this->authService->assertPrivilege(\Szurubooru\Privilege::PRIVILEGE_LIST_USERS); @@ -43,16 +53,6 @@ final class UserController extends AbstractController 'totalRecords' => $searchResult->totalRecords]; } - public function getByName($name) - { - $this->authService->assertPrivilege(\Szurubooru\Privilege::PRIVILEGE_VIEW_USER); - - $user = $this->userService->getByName($name); - if (!$user) - throw new \DomainException('User with name "' . $name . '" was not found.'); - return new \Szurubooru\ViewProxies\User($user); - } - public function register() { $this->authService->assertPrivilege(\Szurubooru\Privilege::PRIVILEGE_REGISTER); @@ -73,6 +73,10 @@ final class UserController extends AbstractController public function delete($name) { - throw new \BadMethodCallException('Not implemented'); + if ($name == $this->authService->getLoggedInUser()->name) + $this->authService->assertPrivilege(\Szurubooru\Privilege::PRIVILEGE_DELETE_OWN_ACCOUNT); + else + $this->authService->assertPrivilege(\Szurubooru\Privilege::PRIVILEGE_DELETE_ACCOUNTS); + return $this->userService->deleteByName($name); } } diff --git a/src/Dao/UserDao.php b/src/Dao/UserDao.php index 0276ca87..f2c8b5fa 100644 --- a/src/Dao/UserDao.php +++ b/src/Dao/UserDao.php @@ -19,4 +19,11 @@ class UserDao extends AbstractDao implements ICrudDao { return (bool) $this->collection->findOne(); } + + public function deleteByName($userName) + { + $this->collection->remove(['name' => $userName]); + $tokens = $this->db->selectCollection('tokens'); + $tokens->remove(['additionalData' => $userName]); + } } diff --git a/src/Privilege.php b/src/Privilege.php index 6649fc7f..c3f7b60f 100644 --- a/src/Privilege.php +++ b/src/Privilege.php @@ -5,5 +5,7 @@ class Privilege { const PRIVILEGE_LIST_USERS = 'listUsers'; const PRIVILEGE_VIEW_USER = 'viewUser'; + const PRIVILEGE_DELETE_ACCOUNTS = 'deleteAccounts'; + const PRIVILEGE_DELETE_OWN_ACCOUNT = 'deleteOwnAccount'; const PRIVILEGE_REGISTER = 'register'; } diff --git a/src/Services/UserService.php b/src/Services/UserService.php index bffdc1e3..e1777530 100644 --- a/src/Services/UserService.php +++ b/src/Services/UserService.php @@ -65,4 +65,10 @@ class UserService return $this->userDao->save($user); } + + public function deleteByName($name) + { + $this->userDao->deleteByName($name); + return true; + } }