From 6161eaef9e107ddbfc104753eb5d48434de3b824 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sat, 13 Feb 2016 15:38:35 -0500 Subject: Enable/Disable users --- ChangeLog | 1 + app/Api/User.php | 15 ++++ app/Auth/DatabaseAuth.php | 3 +- app/Controller/Projectuser.php | 6 +- app/Controller/User.php | 29 +------ app/Controller/UserStatus.php | 111 +++++++++++++++++++++++++ app/Core/User/UserProfile.php | 2 +- app/Model/ProjectGroupRole.php | 1 + app/Model/ProjectPermission.php | 3 +- app/Model/ProjectUserRole.php | 5 +- app/Model/User.php | 40 ++++++++- app/Schema/Mysql.php | 7 +- app/Schema/Postgres.php | 7 +- app/Schema/Sqlite.php | 7 +- app/ServiceProvider/AuthenticationProvider.php | 3 +- app/ServiceProvider/RouteProvider.php | 1 - app/Template/user/dropdown.php | 27 ++++++ app/Template/user/index.php | 33 ++++---- app/Template/user/remove.php | 13 --- app/Template/user/show.php | 1 + app/Template/user/sidebar.php | 6 -- app/Template/user_status/disable.php | 13 +++ app/Template/user_status/enable.php | 13 +++ app/Template/user_status/remove.php | 13 +++ doc/api-user-procedures.markdown | 93 +++++++++++++++++++++ tests/integration/Base.php | 2 +- tests/integration/UserTest.php | 18 ++++ tests/units/Auth/DatabaseAuthTest.php | 12 ++- tests/units/Model/ProjectGroupRoleTest.php | 38 +++++++++ tests/units/Model/ProjectPermissionTest.php | 22 +++++ tests/units/Model/ProjectUserRoleTest.php | 61 ++++++++++++++ tests/units/Model/UserTest.php | 27 +++++- 32 files changed, 551 insertions(+), 82 deletions(-) create mode 100644 app/Controller/UserStatus.php create mode 100644 app/Template/user/dropdown.php delete mode 100644 app/Template/user/remove.php create mode 100644 app/Template/user_status/disable.php create mode 100644 app/Template/user_status/enable.php create mode 100644 app/Template/user_status/remove.php create mode 100644 tests/integration/UserTest.php diff --git a/ChangeLog b/ChangeLog index 4f8f3211..830eff80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ Version 1.0.26 (unreleased) New features: +* Enable/Disable users * Add setting option to disable private projects * Add new config option to disable logout diff --git a/app/Api/User.php b/app/Api/User.php index 9f26615d..48337ac6 100644 --- a/app/Api/User.php +++ b/app/Api/User.php @@ -36,6 +36,21 @@ class User extends \Kanboard\Core\Base return $this->user->remove($user_id); } + public function disableUser($user_id) + { + return $this->user->disable($user_id); + } + + public function enableUser($user_id) + { + return $this->user->enable($user_id); + } + + public function isActiveUser($user_id) + { + return $this->user->isActive($user_id); + } + public function createUser($username, $password, $name = '', $email = '', $role = Role::APP_USER) { $values = array( diff --git a/app/Auth/DatabaseAuth.php b/app/Auth/DatabaseAuth.php index 5a8ee64d..c13af687 100644 --- a/app/Auth/DatabaseAuth.php +++ b/app/Auth/DatabaseAuth.php @@ -65,6 +65,7 @@ class DatabaseAuth extends Base implements PasswordAuthenticationProviderInterfa ->eq('username', $this->username) ->eq('disable_login_form', 0) ->eq('is_ldap_user', 0) + ->eq('is_active', 1) ->findOne(); if (! empty($user) && password_verify($this->password, $user['password'])) { @@ -83,7 +84,7 @@ class DatabaseAuth extends Base implements PasswordAuthenticationProviderInterfa */ public function isValidSession() { - return $this->user->exists($this->userSession->getId()); + return $this->user->isActive($this->userSession->getId()); } /** diff --git a/app/Controller/Projectuser.php b/app/Controller/Projectuser.php index 9cd21021..a6d4fe4e 100644 --- a/app/Controller/Projectuser.php +++ b/app/Controller/Projectuser.php @@ -24,7 +24,7 @@ class Projectuser extends Base $project_ids = $this->projectPermission->getActiveProjectIds($this->userSession->getId()); } - return array($user_id, $project_ids, $this->user->getList(true)); + return array($user_id, $project_ids, $this->user->getActiveUsersList(true)); } private function role($role, $action, $title, $title_user) @@ -33,7 +33,7 @@ class Projectuser extends Base $query = $this->projectPermission->getQueryByRole($project_ids, $role)->callback(array($this->project, 'applyColumnStats')); - if ($user_id !== UserModel::EVERYBODY_ID) { + if ($user_id !== UserModel::EVERYBODY_ID && isset($users[$user_id])) { $query->eq(UserModel::TABLE.'.id', $user_id); $title = t($title_user, $users[$user_id]); } @@ -59,7 +59,7 @@ class Projectuser extends Base $query = $this->taskFinder->getProjectUserOverviewQuery($project_ids, $is_active); - if ($user_id !== UserModel::EVERYBODY_ID) { + if ($user_id !== UserModel::EVERYBODY_ID && isset($users[$user_id])) { $query->eq(TaskModel::TABLE.'.owner_id', $user_id); $title = t($title_user, $users[$user_id]); } diff --git a/app/Controller/User.php b/app/Controller/User.php index 881266d4..f7d7d2e0 100644 --- a/app/Controller/User.php +++ b/app/Controller/User.php @@ -32,7 +32,8 @@ class User extends Base $this->helper->layout->app('user/index', array( 'title' => t('Users').' ('.$paginator->getTotal().')', 'paginator' => $paginator, - ))); + ) + )); } /** @@ -404,30 +405,4 @@ class User extends Base 'user' => $user, ))); } - - /** - * Remove a user - * - * @access public - */ - public function remove() - { - $user = $this->getUser(); - - if ($this->request->getStringParam('confirmation') === 'yes') { - $this->checkCSRFParam(); - - if ($this->user->remove($user['id'])) { - $this->flash->success(t('User removed successfully.')); - } else { - $this->flash->failure(t('Unable to remove this user.')); - } - - $this->response->redirect($this->helper->url->to('user', 'index')); - } - - $this->response->html($this->helper->layout->user('user/remove', array( - 'user' => $user, - ))); - } } diff --git a/app/Controller/UserStatus.php b/app/Controller/UserStatus.php new file mode 100644 index 00000000..b8ee5c91 --- /dev/null +++ b/app/Controller/UserStatus.php @@ -0,0 +1,111 @@ +getUser(); + + $this->response->html($this->helper->layout->user('user_status/remove', array( + 'user' => $user, + ))); + } + + /** + * Remove a user + * + * @access public + */ + public function remove() + { + $user = $this->getUser(); + $this->checkCSRFParam(); + + if ($this->user->remove($user['id'])) { + $this->flash->success(t('User removed successfully.')); + } else { + $this->flash->failure(t('Unable to remove this user.')); + } + + $this->response->redirect($this->helper->url->to('user', 'index')); + } + + /** + * Confirm enable a user + * + * @access public + */ + public function confirmEnable() + { + $user = $this->getUser(); + + $this->response->html($this->helper->layout->user('user_status/enable', array( + 'user' => $user, + ))); + } + + /** + * Enable a user + * + * @access public + */ + public function enable() + { + $user = $this->getUser(); + $this->checkCSRFParam(); + + if ($this->user->enable($user['id'])) { + $this->flash->success(t('User activated successfully.')); + } else { + $this->flash->failure(t('Unable to enable this user.')); + } + + $this->response->redirect($this->helper->url->to('user', 'index')); + } + + /** + * Confirm disable a user + * + * @access public + */ + public function confirmDisable() + { + $user = $this->getUser(); + + $this->response->html($this->helper->layout->user('user_status/disable', array( + 'user' => $user, + ))); + } + + /** + * Disable a user + * + * @access public + */ + public function disable() + { + $user = $this->getUser(); + $this->checkCSRFParam(); + + if ($this->user->disable($user['id'])) { + $this->flash->success(t('User disabled successfully.')); + } else { + $this->flash->failure(t('Unable to disable this user.')); + } + + $this->response->redirect($this->helper->url->to('user', 'index')); + } +} diff --git a/app/Core/User/UserProfile.php b/app/Core/User/UserProfile.php index ccbc7f06..ef325801 100644 --- a/app/Core/User/UserProfile.php +++ b/app/Core/User/UserProfile.php @@ -52,7 +52,7 @@ class UserProfile extends Base $this->groupSync->synchronize($profile['id'], $user->getExternalGroupIds()); } - if (! empty($profile)) { + if (! empty($profile) && $profile['is_active'] == 1) { $this->userSession->initialize($profile); return true; } diff --git a/app/Model/ProjectGroupRole.php b/app/Model/ProjectGroupRole.php index 591b28c6..750ba7fb 100644 --- a/app/Model/ProjectGroupRole.php +++ b/app/Model/ProjectGroupRole.php @@ -106,6 +106,7 @@ class ProjectGroupRole extends Base ->join(GroupMember::TABLE, 'user_id', 'id', User::TABLE) ->join(self::TABLE, 'group_id', 'group_id', GroupMember::TABLE) ->eq(self::TABLE.'.project_id', $project_id) + ->eq(User::TABLE.'.is_active', 1) ->in(self::TABLE.'.role', array(Role::PROJECT_MANAGER, Role::PROJECT_MEMBER)) ->asc(User::TABLE.'.username') ->findAll(); diff --git a/app/Model/ProjectPermission.php b/app/Model/ProjectPermission.php index cea62e13..db1573ae 100644 --- a/app/Model/ProjectPermission.php +++ b/app/Model/ProjectPermission.php @@ -107,7 +107,8 @@ class ProjectPermission extends Base */ public function isAssignable($project_id, $user_id) { - return in_array($this->projectUserRole->getUserRole($project_id, $user_id), array(Role::PROJECT_MEMBER, Role::PROJECT_MANAGER)); + return $this->user->isActive($user_id) && + in_array($this->projectUserRole->getUserRole($project_id, $user_id), array(Role::PROJECT_MEMBER, Role::PROJECT_MANAGER)); } /** diff --git a/app/Model/ProjectUserRole.php b/app/Model/ProjectUserRole.php index 8149a253..56da679c 100644 --- a/app/Model/ProjectUserRole.php +++ b/app/Model/ProjectUserRole.php @@ -152,13 +152,14 @@ class ProjectUserRole extends Base public function getAssignableUsers($project_id) { if ($this->projectPermission->isEverybodyAllowed($project_id)) { - return $this->user->getList(); + return $this->user->getActiveUsersList(); } $userMembers = $this->db->table(self::TABLE) ->columns(User::TABLE.'.id', User::TABLE.'.username', User::TABLE.'.name') ->join(User::TABLE, 'id', 'user_id') - ->eq('project_id', $project_id) + ->eq(User::TABLE.'.is_active', 1) + ->eq(self::TABLE.'.project_id', $project_id) ->in(self::TABLE.'.role', array(Role::PROJECT_MANAGER, Role::PROJECT_MEMBER)) ->findAll(); diff --git a/app/Model/User.php b/app/Model/User.php index dd622207..e2494c4c 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -40,6 +40,18 @@ class User extends Base return $this->db->table(self::TABLE)->eq('id', $user_id)->exists(); } + /** + * Return true if the user is active + * + * @access public + * @param integer $user_id User id + * @return boolean + */ + public function isActive($user_id) + { + return $this->db->table(self::TABLE)->eq('id', $user_id)->eq('is_active', 1)->exists(); + } + /** * Get query to fetch all users * @@ -193,9 +205,9 @@ class User extends Base * @param boolean $prepend Prepend "All users" * @return array */ - public function getList($prepend = false) + public function getActiveUsersList($prepend = false) { - $users = $this->db->table(self::TABLE)->columns('id', 'username', 'name')->findAll(); + $users = $this->db->table(self::TABLE)->eq('is_active', 1)->columns('id', 'username', 'name')->findAll(); $listing = $this->prepareList($users); if ($prepend) { @@ -280,6 +292,30 @@ class User extends Base return $result; } + /** + * Disable a specific user + * + * @access public + * @param integer $user_id + * @return boolean + */ + public function disable($user_id) + { + return $this->db->table(self::TABLE)->eq('id', $user_id)->update(array('is_active' => 0)); + } + + /** + * Enable a specific user + * + * @access public + * @param integer $user_id + * @return boolean + */ + public function enable($user_id) + { + return $this->db->table(self::TABLE)->eq('id', $user_id)->update(array('is_active' => 1)); + } + /** * Remove a specific user * diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php index 036958b6..1cebbd22 100644 --- a/app/Schema/Mysql.php +++ b/app/Schema/Mysql.php @@ -6,7 +6,12 @@ use PDO; use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Role; -const VERSION = 104; +const VERSION = 105; + +function version_105(PDO $pdo) +{ + $pdo->exec("ALTER TABLE users ADD COLUMN is_active TINYINT(1) DEFAULT 1"); +} function version_104(PDO $pdo) { diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php index 363b633b..b0b89a7c 100644 --- a/app/Schema/Postgres.php +++ b/app/Schema/Postgres.php @@ -6,7 +6,12 @@ use PDO; use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Role; -const VERSION = 84; +const VERSION = 85; + +function version_85(PDO $pdo) +{ + $pdo->exec("ALTER TABLE users ADD COLUMN is_active BOOLEAN DEFAULT '1'"); +} function version_84(PDO $pdo) { diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php index bc701341..aa10e58b 100644 --- a/app/Schema/Sqlite.php +++ b/app/Schema/Sqlite.php @@ -6,7 +6,12 @@ use Kanboard\Core\Security\Token; use Kanboard\Core\Security\Role; use PDO; -const VERSION = 96; +const VERSION = 97; + +function version_97(PDO $pdo) +{ + $pdo->exec("ALTER TABLE users ADD COLUMN is_active INTEGER DEFAULT 1"); +} function version_96(PDO $pdo) { diff --git a/app/ServiceProvider/AuthenticationProvider.php b/app/ServiceProvider/AuthenticationProvider.php index 9b5cdbe9..c2f7a5c4 100644 --- a/app/ServiceProvider/AuthenticationProvider.php +++ b/app/ServiceProvider/AuthenticationProvider.php @@ -134,7 +134,8 @@ class AuthenticationProvider implements ServiceProviderInterface $acl->add('Projectuser', '*', Role::APP_MANAGER); $acl->add('Twofactor', 'disable', Role::APP_ADMIN); $acl->add('UserImport', '*', Role::APP_ADMIN); - $acl->add('User', array('index', 'create', 'save', 'authentication', 'remove'), Role::APP_ADMIN); + $acl->add('User', array('index', 'create', 'save', 'authentication'), Role::APP_ADMIN); + $acl->add('UserStatus', '*', Role::APP_ADMIN); return $acl; } diff --git a/app/ServiceProvider/RouteProvider.php b/app/ServiceProvider/RouteProvider.php index 683ea1c1..5003eb88 100644 --- a/app/ServiceProvider/RouteProvider.php +++ b/app/ServiceProvider/RouteProvider.php @@ -157,7 +157,6 @@ class RouteProvider implements ServiceProviderInterface $container['route']->addRoute('user/:user_id/accounts', 'user', 'external'); $container['route']->addRoute('user/:user_id/integrations', 'user', 'integrations'); $container['route']->addRoute('user/:user_id/authentication', 'user', 'authentication'); - $container['route']->addRoute('user/:user_id/remove', 'user', 'remove'); $container['route']->addRoute('user/:user_id/2fa', 'twofactor', 'index'); // Groups diff --git a/app/Template/user/dropdown.php b/app/Template/user/dropdown.php new file mode 100644 index 00000000..b74ed6e0 --- /dev/null +++ b/app/Template/user/dropdown.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/app/Template/user/index.php b/app/Template/user/index.php index cb7416d6..494c1465 100644 --- a/app/Template/user/index.php +++ b/app/Template/user/index.php @@ -12,23 +12,21 @@ isEmpty()): ?>

- +
- - - - - - - - + + + + + + + + getCollection() as $user): ?> - + diff --git a/app/Template/user/remove.php b/app/Template/user/remove.php deleted file mode 100644 index 810a3a3f..00000000 --- a/app/Template/user/remove.php +++ /dev/null @@ -1,13 +0,0 @@ - - -
-

- -
- url->link(t('Yes'), 'user', 'remove', array('user_id' => $user['id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?> - - url->link(t('cancel'), 'user', 'show', array('user_id' => $user['id'])) ?> -
-
\ No newline at end of file diff --git a/app/Template/user/show.php b/app/Template/user/show.php index 89c6b36b..9da56666 100644 --- a/app/Template/user/show.php +++ b/app/Template/user/show.php @@ -5,6 +5,7 @@
  • e($user['username']) ?>
  • e($user['name']) ?: t('None') ?>
  • e($user['email']) ?: t('None') ?>
  • +
  • \ No newline at end of file diff --git a/app/Template/user_status/disable.php b/app/Template/user_status/disable.php new file mode 100644 index 00000000..90d8c757 --- /dev/null +++ b/app/Template/user_status/disable.php @@ -0,0 +1,13 @@ + + +
    +

    + +
    + url->link(t('Yes'), 'UserStatus', 'disable', array('user_id' => $user['id']), true, 'btn btn-red') ?> + + url->link(t('cancel'), 'user', 'index', array(), false, 'close-popover') ?> +
    +
    diff --git a/app/Template/user_status/enable.php b/app/Template/user_status/enable.php new file mode 100644 index 00000000..cd3d4947 --- /dev/null +++ b/app/Template/user_status/enable.php @@ -0,0 +1,13 @@ + + +
    +

    + +
    + url->link(t('Yes'), 'UserStatus', 'enable', array('user_id' => $user['id']), true, 'btn btn-red') ?> + + url->link(t('cancel'), 'user', 'index', array(), false, 'close-popover') ?> +
    +
    diff --git a/app/Template/user_status/remove.php b/app/Template/user_status/remove.php new file mode 100644 index 00000000..cd5c09a6 --- /dev/null +++ b/app/Template/user_status/remove.php @@ -0,0 +1,13 @@ + + +
    +

    + +
    + url->link(t('Yes'), 'UserStatus', 'remove', array('user_id' => $user['id']), true, 'btn btn-red') ?> + + url->link(t('cancel'), 'user', 'index', array(), false, 'close-popover') ?> +
    +
    diff --git a/doc/api-user-procedures.markdown b/doc/api-user-procedures.markdown index 9b43e1e1..6c09355d 100644 --- a/doc/api-user-procedures.markdown +++ b/doc/api-user-procedures.markdown @@ -262,3 +262,96 @@ Response example: "result": true } ``` + +## disableUser + +- Purpose: **Disable a user** +- Parameters: + - **user_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "disableUser", + "id": 2094191872, + "params": { + "user_id": 1 + } +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 2094191872, + "result": true +} +``` + +## enableUser + +- Purpose: **Enable a user** +- Parameters: + - **user_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "enableUser", + "id": 2094191872, + "params": { + "user_id": 1 + } +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 2094191872, + "result": true +} +``` + +## isActiveUser + +- Purpose: **Check if a user is active** +- Parameters: + - **user_id** (integer, required) +- Result on success: **true** +- Result on failure: **false** + +Request example: + +```json +{ + "jsonrpc": "2.0", + "method": "isActiveUser", + "id": 2094191872, + "params": { + "user_id": 1 + } +} +``` + +Response example: + +```json +{ + "jsonrpc": "2.0", + "id": 2094191872, + "result": true +} +``` diff --git a/tests/integration/Base.php b/tests/integration/Base.php index 6facd9ce..983d0ed9 100644 --- a/tests/integration/Base.php +++ b/tests/integration/Base.php @@ -35,7 +35,7 @@ abstract class Base extends PHPUnit_Framework_TestCase { $this->app = new JsonRPC\Client(API_URL); $this->app->authentication('jsonrpc', API_KEY); - $this->app->debug = true; + // $this->app->debug = true; $this->admin = new JsonRPC\Client(API_URL); $this->admin->authentication('admin', 'admin'); diff --git a/tests/integration/UserTest.php b/tests/integration/UserTest.php new file mode 100644 index 00000000..10da051c --- /dev/null +++ b/tests/integration/UserTest.php @@ -0,0 +1,18 @@ +assertEquals(2, $this->app->createUser(array('username' => 'someone', 'password' => 'test123'))); + $this->assertTrue($this->app->isActiveUser(2)); + + $this->assertTrue($this->app->disableUser(2)); + $this->assertFalse($this->app->isActiveUser(2)); + + $this->assertTrue($this->app->enableUser(2)); + $this->assertTrue($this->app->isActiveUser(2)); + } +} diff --git a/tests/units/Auth/DatabaseAuthTest.php b/tests/units/Auth/DatabaseAuthTest.php index a13b7fee..ac099a7e 100644 --- a/tests/units/Auth/DatabaseAuthTest.php +++ b/tests/units/Auth/DatabaseAuthTest.php @@ -3,6 +3,7 @@ require_once __DIR__.'/../Base.php'; use Kanboard\Auth\DatabaseAuth; +use Kanboard\Model\User; class DatabaseAuthTest extends Base { @@ -40,12 +41,21 @@ class DatabaseAuthTest extends Base public function testIsvalidSession() { + $userModel = new User($this->container); $provider = new DatabaseAuth($this->container); + $this->assertFalse($provider->isValidSession()); - $this->container['sessionStorage']->user = array('id' => 1); + $this->assertEquals(2, $userModel->create(array('username' => 'foobar'))); + + $this->container['sessionStorage']->user = array('id' => 2); $this->assertTrue($provider->isValidSession()); + $this->container['sessionStorage']->user = array('id' => 3); + $this->assertFalse($provider->isValidSession()); + + $this->assertTrue($userModel->disable(2)); + $this->container['sessionStorage']->user = array('id' => 2); $this->assertFalse($provider->isValidSession()); } diff --git a/tests/units/Model/ProjectGroupRoleTest.php b/tests/units/Model/ProjectGroupRoleTest.php index 29a9536b..e38e812a 100644 --- a/tests/units/Model/ProjectGroupRoleTest.php +++ b/tests/units/Model/ProjectGroupRoleTest.php @@ -204,6 +204,44 @@ class ProjectGroupRoleTest extends Base $this->assertEquals('', $users[1]['name']); } + public function testGetAssignableUsersWithDisabledUsers() + { + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $groupModel = new Group($this->container); + $groupMemberModel = new GroupMember($this->container); + $groupRoleModel = new ProjectGroupRole($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'Project 1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'Project 2'))); + + $this->assertEquals(2, $userModel->create(array('username' => 'user 1', 'name' => 'User #1'))); + $this->assertEquals(3, $userModel->create(array('username' => 'user 2', 'is_active' => 0))); + $this->assertEquals(4, $userModel->create(array('username' => 'user 3'))); + + $this->assertEquals(1, $groupModel->create('Group A')); + $this->assertEquals(2, $groupModel->create('Group B')); + $this->assertEquals(3, $groupModel->create('Group C')); + + $this->assertTrue($groupMemberModel->addUser(1, 4)); + $this->assertTrue($groupMemberModel->addUser(2, 3)); + $this->assertTrue($groupMemberModel->addUser(3, 2)); + + $this->assertTrue($groupRoleModel->addGroup(1, 1, Role::PROJECT_VIEWER)); + $this->assertTrue($groupRoleModel->addGroup(1, 2, Role::PROJECT_MEMBER)); + $this->assertTrue($groupRoleModel->addGroup(1, 3, Role::PROJECT_MANAGER)); + + $users = $groupRoleModel->getAssignableUsers(2); + $this->assertCount(0, $users); + + $users = $groupRoleModel->getAssignableUsers(1); + $this->assertCount(1, $users); + + $this->assertEquals(2, $users[0]['id']); + $this->assertEquals('user 1', $users[0]['username']); + $this->assertEquals('User #1', $users[0]['name']); + } + public function testGetProjectsByUser() { $userModel = new User($this->container); diff --git a/tests/units/Model/ProjectPermissionTest.php b/tests/units/Model/ProjectPermissionTest.php index 035a1246..10fcdcc2 100644 --- a/tests/units/Model/ProjectPermissionTest.php +++ b/tests/units/Model/ProjectPermissionTest.php @@ -192,6 +192,28 @@ class ProjectPermissionTest extends Base $this->assertFalse($projectPermission->isAssignable(2, 5)); } + public function testIsAssignableWhenUserIsDisabled() + { + $userModel = new User($this->container); + $projectModel = new Project($this->container); + $groupModel = new Group($this->container); + $groupRoleModel = new ProjectGroupRole($this->container); + $groupMemberModel = new GroupMember($this->container); + $userRoleModel = new ProjectUserRole($this->container); + $projectPermission = new ProjectPermission($this->container); + + $this->assertEquals(2, $userModel->create(array('username' => 'user 1'))); + $this->assertEquals(3, $userModel->create(array('username' => 'user 2', 'is_active' => 0))); + + $this->assertEquals(1, $projectModel->create(array('name' => 'Project 1'))); + + $this->assertTrue($userRoleModel->addUser(1, 2, Role::PROJECT_MEMBER)); + $this->assertTrue($userRoleModel->addUser(1, 3, Role::PROJECT_MEMBER)); + + $this->assertTrue($projectPermission->isAssignable(1, 2)); + $this->assertFalse($projectPermission->isAssignable(1, 3)); + } + public function testIsMember() { $userModel = new User($this->container); diff --git a/tests/units/Model/ProjectUserRoleTest.php b/tests/units/Model/ProjectUserRoleTest.php index c6b4eb7c..06cd1b70 100644 --- a/tests/units/Model/ProjectUserRoleTest.php +++ b/tests/units/Model/ProjectUserRoleTest.php @@ -8,6 +8,7 @@ use Kanboard\Model\Group; use Kanboard\Model\GroupMember; use Kanboard\Model\ProjectGroupRole; use Kanboard\Model\ProjectUserRole; +use Kanboard\Model\ProjectPermission; use Kanboard\Core\Security\Role; class ProjectUserRoleTest extends Base @@ -100,6 +101,36 @@ class ProjectUserRoleTest extends Base $this->assertEquals('', $userRoleModel->getUserRole(1, 2)); } + public function testGetAssignableUsersWithDisabledUsers() + { + $projectModel = new Project($this->container); + $userModel = new User($this->container); + $userRoleModel = new ProjectUserRole($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'Test'))); + $this->assertEquals(2, $userModel->create(array('username' => 'user1', 'name' => 'User1'))); + $this->assertEquals(3, $userModel->create(array('username' => 'user2', 'name' => 'User2'))); + + $this->assertTrue($userRoleModel->addUser(1, 1, Role::PROJECT_MEMBER)); + $this->assertTrue($userRoleModel->addUser(1, 2, Role::PROJECT_MEMBER)); + $this->assertTrue($userRoleModel->addUser(1, 3, Role::PROJECT_MEMBER)); + + $users = $userRoleModel->getAssignableUsers(1); + $this->assertCount(3, $users); + + $this->assertEquals('admin', $users[1]); + $this->assertEquals('User1', $users[2]); + $this->assertEquals('User2', $users[3]); + + $this->assertTrue($userModel->disable(2)); + + $users = $userRoleModel->getAssignableUsers(1); + $this->assertCount(2, $users); + + $this->assertEquals('admin', $users[1]); + $this->assertEquals('User2', $users[3]); + } + public function testGetAssignableUsersWithoutGroups() { $projectModel = new Project($this->container); @@ -219,6 +250,36 @@ class ProjectUserRoleTest extends Base $this->assertEquals('User4', $users[5]); } + public function testGetAssignableUsersWithDisabledUsersAndEverybodyAllowed() + { + $projectModel = new Project($this->container); + $projectPermission = new ProjectPermission($this->container); + $userModel = new User($this->container); + $userRoleModel = new ProjectUserRole($this->container); + + $this->assertEquals(2, $userModel->create(array('username' => 'user1', 'name' => 'User1'))); + $this->assertEquals(3, $userModel->create(array('username' => 'user2', 'name' => 'User2'))); + + $this->assertEquals(1, $projectModel->create(array('name' => 'Project 1', 'is_everybody_allowed' => 1))); + + $this->assertTrue($projectPermission->isEverybodyAllowed(1)); + + $users = $userRoleModel->getAssignableUsers(1); + $this->assertCount(3, $users); + + $this->assertEquals('admin', $users[1]); + $this->assertEquals('User1', $users[2]); + $this->assertEquals('User2', $users[3]); + + $this->assertTrue($userModel->disable(2)); + + $users = $userRoleModel->getAssignableUsers(1); + $this->assertCount(2, $users); + + $this->assertEquals('admin', $users[1]); + $this->assertEquals('User2', $users[3]); + } + public function testGetProjectsByUser() { $userModel = new User($this->container); diff --git a/tests/units/Model/UserTest.php b/tests/units/Model/UserTest.php index 0987fa56..e411da0c 100644 --- a/tests/units/Model/UserTest.php +++ b/tests/units/Model/UserTest.php @@ -96,13 +96,14 @@ class UserTest extends Base $this->assertEquals('you', $users[2]['username']); } - public function testGetList() + public function testGetActiveUsersList() { $u = new User($this->container); $this->assertEquals(2, $u->create(array('username' => 'you'))); $this->assertEquals(3, $u->create(array('username' => 'me', 'name' => 'Me too'))); + $this->assertEquals(4, $u->create(array('username' => 'foobar', 'is_active' => 0))); - $users = $u->getList(); + $users = $u->getActiveUsersList(); $expected = array( 1 => 'admin', @@ -112,7 +113,7 @@ class UserTest extends Base $this->assertEquals($expected, $users); - $users = $u->getList(true); + $users = $u->getActiveUsersList(true); $expected = array( User::EVERYBODY_ID => 'Everybody', @@ -391,4 +392,24 @@ class UserTest extends Base $this->assertEquals('toto', $user['username']); $this->assertEmpty($user['token']); } + + public function testEnableDisable() + { + $userModel = new User($this->container); + $this->assertEquals(2, $userModel->create(array('username' => 'toto'))); + + $this->assertTrue($userModel->isActive(2)); + $user = $userModel->getById(2); + $this->assertEquals(1, $user['is_active']); + + $this->assertTrue($userModel->disable(2)); + $user = $userModel->getById(2); + $this->assertEquals(0, $user['is_active']); + $this->assertFalse($userModel->isActive(2)); + + $this->assertTrue($userModel->enable(2)); + $user = $userModel->getById(2); + $this->assertEquals(1, $user['is_active']); + $this->assertTrue($userModel->isActive(2)); + } } -- cgit v1.2.3
    order(t('Id'), 'id') ?>order(t('Username'), 'username') ?>order(t('Name'), 'name') ?>order(t('Email'), 'email') ?>order(t('Role'), 'role') ?>order(t('Two factor authentication'), 'twofactor_activated') ?>order(t('Notifications'), 'notifications_enabled') ?>order(t('Account type'), 'is_ldap_user') ?>order(t('Username'), 'username') ?>order(t('Name'), 'name') ?>order(t('Email'), 'email') ?>order(t('Role'), 'role') ?>order(t('Two Factor'), 'twofactor_activated') ?>order(t('Account type'), 'is_ldap_user') ?>order(t('Status'), 'is_active') ?>
    - url->link('#'.$user['id'], 'user', 'show', array('user_id' => $user['id'])) ?> - +   url->link($this->e($user['username']), 'user', 'show', array('user_id' => $user['id'])) ?> @@ -44,14 +42,17 @@ - - + + + + - + - + render('user/dropdown', array('user' => $user)) ?>