summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2017-11-09 15:09:54 -0800
committerFrederic Guillot <fred@kanboard.net>2017-11-09 15:09:54 -0800
commit44aa24bab16bdc2545b08594386adb24ead3aa9e (patch)
tree4ca2c4632d9657f8babfb7781b5aadc0d3e30238 /app
parent95b2a36886a763242e11b4b27998a0d5c51ca7f4 (diff)
Add user backend provider system
Diffstat (limited to 'app')
-rw-r--r--app/Controller/ProjectPermissionController.php4
-rw-r--r--app/Controller/UserAjaxController.php12
-rw-r--r--app/Core/Base.php3
-rw-r--r--app/Core/Group/GroupBackendProviderInterface.php2
-rw-r--r--app/Core/Group/GroupManager.php10
-rw-r--r--app/Core/Group/GroupProviderInterface.php2
-rw-r--r--app/Core/User/UserBackendProviderInterface.php21
-rw-r--r--app/Core/User/UserManager.php71
-rw-r--r--app/Formatter/GroupAutoCompleteFormatter.php3
-rw-r--r--app/Formatter/UserAutoCompleteFormatter.php50
-rw-r--r--app/Model/UserModel.php16
-rw-r--r--app/ServiceProvider/GroupProvider.php2
-rw-r--r--app/ServiceProvider/UserProvider.php35
-rw-r--r--app/Template/project_permission/groups.php2
-rw-r--r--app/Template/project_permission/users.php16
-rw-r--r--app/User/DatabaseBackendUserProvider.php43
-rw-r--r--app/User/DatabaseUserProvider.php8
-rw-r--r--app/common.php1
-rw-r--r--app/constants.php1
19 files changed, 256 insertions, 46 deletions
diff --git a/app/Controller/ProjectPermissionController.php b/app/Controller/ProjectPermissionController.php
index d043d3ec..3fb6c090 100644
--- a/app/Controller/ProjectPermissionController.php
+++ b/app/Controller/ProjectPermissionController.php
@@ -69,6 +69,10 @@ class ProjectPermissionController extends BaseController
$project = $this->getProject();
$values = $this->request->getValues();
+ if (empty($values['user_id']) && ! empty($values['external_id']) && ! empty($values['external_id_column'])) {
+ $values['user_id'] = $this->userModel->getOrCreateExternalUserId($values['username'], $values['name'], $values['external_id_column'], $values['external_id']);
+ }
+
if (empty($values['user_id'])) {
$this->flash->failure(t('User not found.'));
} elseif ($this->projectUserRoleModel->addUser($values['project_id'], $values['user_id'], $values['role'])) {
diff --git a/app/Controller/UserAjaxController.php b/app/Controller/UserAjaxController.php
index 37c09b8a..57596202 100644
--- a/app/Controller/UserAjaxController.php
+++ b/app/Controller/UserAjaxController.php
@@ -2,9 +2,6 @@
namespace Kanboard\Controller;
-use Kanboard\Filter\UserNameFilter;
-use Kanboard\Model\UserModel;
-
/**
* User Ajax Controller
*
@@ -21,13 +18,8 @@ class UserAjaxController extends BaseController
public function autocomplete()
{
$search = $this->request->getStringParam('term');
- $filter = $this->userQuery->withFilter(new UserNameFilter($search));
- $filter->getQuery()
- ->eq(UserModel::TABLE.'.is_active', 1)
- ->asc(UserModel::TABLE.'.name')
- ->asc(UserModel::TABLE.'.username');
-
- $this->response->json($filter->format($this->userAutoCompleteFormatter));
+ $users = $this->userManager->find($search);
+ $this->response->json($this->userAutoCompleteFormatter->withUsers($users)->format());
}
/**
diff --git a/app/Core/Base.php b/app/Core/Base.php
index 4e553746..3807f385 100644
--- a/app/Core/Base.php
+++ b/app/Core/Base.php
@@ -7,7 +7,7 @@ use Pimple\Container;
/**
* Base Class
*
- * @package core
+ * @package Kanboard\Core
* @author Frederic Guillot
*
* @property \Kanboard\Analytic\TaskDistributionAnalytic $taskDistributionAnalytic
@@ -22,6 +22,7 @@ use Pimple\Container;
* @property \Kanboard\Core\Cache\BaseCache $cacheDriver
* @property \Kanboard\Core\Event\EventManager $eventManager
* @property \Kanboard\Core\Group\GroupManager $groupManager
+ * @property \Kanboard\Core\User\UserManager $userManager
* @property \Kanboard\Core\Http\Client $httpClient
* @property \Kanboard\Core\Http\OAuth2 $oauth
* @property \Kanboard\Core\Http\RememberMeCookie $rememberMeCookie
diff --git a/app/Core/Group/GroupBackendProviderInterface.php b/app/Core/Group/GroupBackendProviderInterface.php
index 74c5cb03..0b6e2985 100644
--- a/app/Core/Group/GroupBackendProviderInterface.php
+++ b/app/Core/Group/GroupBackendProviderInterface.php
@@ -5,7 +5,7 @@ namespace Kanboard\Core\Group;
/**
* Group Backend Provider Interface
*
- * @package group
+ * @package Kanboard\Core\Group
* @author Frederic Guillot
*/
interface GroupBackendProviderInterface
diff --git a/app/Core/Group/GroupManager.php b/app/Core/Group/GroupManager.php
index 48b6c4f8..a0559139 100644
--- a/app/Core/Group/GroupManager.php
+++ b/app/Core/Group/GroupManager.php
@@ -5,7 +5,7 @@ namespace Kanboard\Core\Group;
/**
* Group Manager
*
- * @package group
+ * @package Kanboard\Core\Group
* @author Frederic Guillot
*/
class GroupManager
@@ -13,10 +13,10 @@ class GroupManager
/**
* List of backend providers
*
- * @access private
+ * @access protected
* @var array
*/
- private $providers = array();
+ protected $providers = array();
/**
* Register a new group backend provider
@@ -52,11 +52,11 @@ class GroupManager
/**
* Remove duplicated groups
*
- * @access private
+ * @access protected
* @param array $groups
* @return GroupProviderInterface[]
*/
- private function removeDuplicates(array $groups)
+ protected function removeDuplicates(array $groups)
{
$result = array();
diff --git a/app/Core/Group/GroupProviderInterface.php b/app/Core/Group/GroupProviderInterface.php
index 4c7c16ec..f312f89b 100644
--- a/app/Core/Group/GroupProviderInterface.php
+++ b/app/Core/Group/GroupProviderInterface.php
@@ -5,7 +5,7 @@ namespace Kanboard\Core\Group;
/**
* Group Provider Interface
*
- * @package group
+ * @package Kanboard\Core\Group
* @author Frederic Guillot
*/
interface GroupProviderInterface
diff --git a/app/Core/User/UserBackendProviderInterface.php b/app/Core/User/UserBackendProviderInterface.php
new file mode 100644
index 00000000..5f8cab47
--- /dev/null
+++ b/app/Core/User/UserBackendProviderInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Kanboard\Core\User;
+
+/**
+ * User Backend Provider Interface
+ *
+ * @package Kanboard\Core\User
+ * @author Frederic Guillot
+ */
+interface UserBackendProviderInterface
+{
+ /**
+ * Find a user from a search query
+ *
+ * @access public
+ * @param string $input
+ * @return UserProviderInterface[]
+ */
+ public function find($input);
+}
diff --git a/app/Core/User/UserManager.php b/app/Core/User/UserManager.php
new file mode 100644
index 00000000..e1692480
--- /dev/null
+++ b/app/Core/User/UserManager.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Kanboard\Core\User;
+
+/**
+ * User Manager
+ *
+ * @package Kanboard\Core\User
+ * @author Frederic Guillot
+ */
+class UserManager
+{
+ /**
+ * List of backend providers
+ *
+ * @access protected
+ * @var array
+ */
+ protected $providers = array();
+
+ /**
+ * Register a new group backend provider
+ *
+ * @access public
+ * @param UserBackendProviderInterface $provider
+ * @return $this
+ */
+ public function register(UserBackendProviderInterface $provider)
+ {
+ $this->providers[] = $provider;
+ return $this;
+ }
+
+ /**
+ * Find a group from a search query
+ *
+ * @access public
+ * @param string $input
+ * @return UserProviderInterface[]
+ */
+ public function find($input)
+ {
+ $groups = array();
+
+ foreach ($this->providers as $provider) {
+ $groups = array_merge($groups, $provider->find($input));
+ }
+
+ return $this->removeDuplicates($groups);
+ }
+
+ /**
+ * Remove duplicated users
+ *
+ * @access protected
+ * @param array $users
+ * @return UserProviderInterface[]
+ */
+ protected function removeDuplicates(array $users)
+ {
+ $result = array();
+
+ foreach ($users as $user) {
+ if (! isset($result[$user->getUsername()])) {
+ $result[$user->getUsername()] = $user;
+ }
+ }
+
+ return array_values($result);
+ }
+}
diff --git a/app/Formatter/GroupAutoCompleteFormatter.php b/app/Formatter/GroupAutoCompleteFormatter.php
index d811de7f..9d740b7f 100644
--- a/app/Formatter/GroupAutoCompleteFormatter.php
+++ b/app/Formatter/GroupAutoCompleteFormatter.php
@@ -4,12 +4,11 @@ namespace Kanboard\Formatter;
use Kanboard\Core\Filter\FormatterInterface;
use Kanboard\Core\Group\GroupProviderInterface;
-use PicoDb\Table;
/**
* Auto-complete formatter for groups
*
- * @package formatter
+ * @package Kanboard\Formatter
* @author Frederic Guillot
*/
class GroupAutoCompleteFormatter extends BaseFormatter implements FormatterInterface
diff --git a/app/Formatter/UserAutoCompleteFormatter.php b/app/Formatter/UserAutoCompleteFormatter.php
index c81af00a..aa02cd22 100644
--- a/app/Formatter/UserAutoCompleteFormatter.php
+++ b/app/Formatter/UserAutoCompleteFormatter.php
@@ -2,37 +2,59 @@
namespace Kanboard\Formatter;
-use Kanboard\Model\UserModel;
+use Kanboard\Core\User\UserProviderInterface;
use Kanboard\Core\Filter\FormatterInterface;
/**
- * Auto-complete formatter for user filter
+ * Auto-complete formatter for users
*
- * @package formatter
+ * @package Kanboard\Formatter
* @author Frederic Guillot
*/
class UserAutoCompleteFormatter extends BaseFormatter implements FormatterInterface
{
/**
- * Format the tasks for the ajax auto-completion
+ * Users found
+ *
+ * @access protected
+ * @var UserProviderInterface[]
+ */
+ protected $users;
+
+ /**
+ * Set users
+ *
+ * @access public
+ * @param UserProviderInterface[] $users
+ * @return $this
+ */
+ public function withUsers(array $users)
+ {
+ $this->users = $users;
+ return $this;
+ }
+
+ /**
+ * Format the users for the ajax auto-completion
*
* @access public
* @return array
*/
public function format()
{
- $users = $this->query->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name')->findAll();
+ $result = array();
- foreach ($users as &$user) {
- if (empty($user['name'])) {
- $user['value'] = $user['username'].' (#'.$user['id'].')';
- $user['label'] = $user['username'];
- } else {
- $user['value'] = $user['name'].' (#'.$user['id'].')';
- $user['label'] = $user['name'].' ('.$user['username'].')';
- }
+ foreach ($this->users as $user) {
+ $result[] = array(
+ 'id' => $user->getInternalId(),
+ 'username' => $user->getUsername(),
+ 'external_id' => $user->getExternalId(),
+ 'external_id_column' => $user->getExternalIdColumn(),
+ 'value' => $user->getName() === '' ? $user->getUsername() : $user->getName(),
+ 'label' => $user->getName() === '' ? $user->getUsername() : $user->getName().' ('.$user->getUsername().')',
+ );
}
- return $users;
+ return $result;
}
}
diff --git a/app/Model/UserModel.php b/app/Model/UserModel.php
index 56b1a960..af49ce7d 100644
--- a/app/Model/UserModel.php
+++ b/app/Model/UserModel.php
@@ -376,4 +376,20 @@ class UserModel extends Base
->eq('id', $user_id)
->save(array('token' => ''));
}
+
+ public function getOrCreateExternalUserId($username, $name, $externalIdColumn, $externalId)
+ {
+ $userId = $this->db->table(self::TABLE)->eq($externalIdColumn, $externalId)->findOneColumn('id');
+
+ if (empty($userId)) {
+ $userId = $this->create(array(
+ 'username' => $username,
+ 'name' => $name,
+ 'is_ldap_user' => 1,
+ $externalIdColumn => $externalId,
+ ));
+ }
+
+ return $userId;
+ }
}
diff --git a/app/ServiceProvider/GroupProvider.php b/app/ServiceProvider/GroupProvider.php
index 08548c73..86f5d112 100644
--- a/app/ServiceProvider/GroupProvider.php
+++ b/app/ServiceProvider/GroupProvider.php
@@ -25,7 +25,7 @@ class GroupProvider implements ServiceProviderInterface
*/
public function register(Container $container)
{
- $container['groupManager'] = new GroupManager;
+ $container['groupManager'] = new GroupManager();
if (DB_GROUP_PROVIDER) {
$container['groupManager']->register(new DatabaseBackendGroupProvider($container));
diff --git a/app/ServiceProvider/UserProvider.php b/app/ServiceProvider/UserProvider.php
new file mode 100644
index 00000000..c80a2aeb
--- /dev/null
+++ b/app/ServiceProvider/UserProvider.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Kanboard\ServiceProvider;
+
+use Kanboard\Core\User\UserManager;
+use Kanboard\User\DatabaseBackendUserProvider;
+use Pimple\Container;
+use Pimple\ServiceProviderInterface;
+
+/**
+ * User Provider
+ *
+ * @package Kanboard\ServiceProvider
+ * @author Frederic Guillot
+ */
+class UserProvider implements ServiceProviderInterface
+{
+ /**
+ * Register providers
+ *
+ * @access public
+ * @param \Pimple\Container $container
+ * @return \Pimple\Container
+ */
+ public function register(Container $container)
+ {
+ $container['userManager'] = new UserManager();
+
+ if (DB_USER_PROVIDER) {
+ $container['userManager']->register(new DatabaseBackendUserProvider($container));
+ }
+
+ return $container;
+ }
+}
diff --git a/app/Template/project_permission/groups.php b/app/Template/project_permission/groups.php
index c9914344..c241302b 100644
--- a/app/Template/project_permission/groups.php
+++ b/app/Template/project_permission/groups.php
@@ -46,7 +46,7 @@
'placeholder="'.t('Enter group name...').'"',
'title="'.t('Enter group name...').'"',
'data-dst-field="group_id"',
- 'data-dst-extra-field="external_id"',
+ 'data-dst-extra-fields="external_id"',
'data-search-url="'.$this->url->href('GroupAjaxController', 'autocomplete').'"',
),
'autocomplete') ?>
diff --git a/app/Template/project_permission/users.php b/app/Template/project_permission/users.php
index bc92d060..1180fe1c 100644
--- a/app/Template/project_permission/users.php
+++ b/app/Template/project_permission/users.php
@@ -34,15 +34,19 @@
<?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
<?= $this->form->hidden('user_id', $values) ?>
+ <?= $this->form->hidden('username', $values) ?>
+ <?= $this->form->hidden('external_id', $values) ?>
+ <?= $this->form->hidden('external_id_column', $values) ?>
<?= $this->form->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array(
- 'required',
- 'placeholder="'.t('Enter user name...').'"',
- 'title="'.t('Enter user name...').'"',
- 'data-dst-field="user_id"',
- 'data-search-url="'.$this->url->href('UserAjaxController', 'autocomplete').'"',
- ),
+ 'required',
+ 'placeholder="'.t('Enter user name...').'"',
+ 'title="'.t('Enter user name...').'"',
+ 'data-dst-field="user_id"',
+ 'data-dst-extra-fields="external_id,external_id_column,username"',
+ 'data-search-url="'.$this->url->href('UserAjaxController', 'autocomplete').'"',
+ ),
'autocomplete') ?>
<?= $this->form->select('role', $roles, $values, $errors) ?>
diff --git a/app/User/DatabaseBackendUserProvider.php b/app/User/DatabaseBackendUserProvider.php
new file mode 100644
index 00000000..835d90be
--- /dev/null
+++ b/app/User/DatabaseBackendUserProvider.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Kanboard\User;
+
+use Kanboard\Core\Base;
+use Kanboard\Core\User\UserBackendProviderInterface;
+use Kanboard\Filter\UserNameFilter;
+use Kanboard\Model\UserModel;
+
+/**
+ * Database Backend User Provider
+ *
+ * @package Kanboard\User
+ * @author Frederic Guillot
+ */
+class DatabaseBackendUserProvider extends Base implements UserBackendProviderInterface
+{
+ /**
+ * Find a group from a search query
+ *
+ * @access public
+ * @param string $input
+ * @return DatabaseUserProvider[]
+ */
+ public function find($input)
+ {
+ $result = array();
+
+ $users = $this->userQuery->withFilter(new UserNameFilter($input))
+ ->getQuery()
+ ->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name')
+ ->eq(UserModel::TABLE.'.is_active', 1)
+ ->asc(UserModel::TABLE.'.name')
+ ->asc(UserModel::TABLE.'.username')
+ ->findAll();
+
+ foreach ($users as $user) {
+ $result[] = new DatabaseUserProvider($user);
+ }
+
+ return $result;
+ }
+}
diff --git a/app/User/DatabaseUserProvider.php b/app/User/DatabaseUserProvider.php
index fc626610..3b26aedb 100644
--- a/app/User/DatabaseUserProvider.php
+++ b/app/User/DatabaseUserProvider.php
@@ -83,7 +83,7 @@ class DatabaseUserProvider implements UserProviderInterface
*/
public function getRole()
{
- return '';
+ return empty($this->user['role']) ? '' : $this->user['role'];
}
/**
@@ -94,7 +94,7 @@ class DatabaseUserProvider implements UserProviderInterface
*/
public function getUsername()
{
- return '';
+ return empty($this->user['username']) ? '' : $this->user['username'];
}
/**
@@ -105,7 +105,7 @@ class DatabaseUserProvider implements UserProviderInterface
*/
public function getName()
{
- return '';
+ return empty($this->user['name']) ? '' : $this->user['name'];
}
/**
@@ -116,7 +116,7 @@ class DatabaseUserProvider implements UserProviderInterface
*/
public function getEmail()
{
- return '';
+ return empty($this->user['email']) ? '' : $this->user['email'];
}
/**
diff --git a/app/common.php b/app/common.php
index 69c56953..a1d42c33 100644
--- a/app/common.php
+++ b/app/common.php
@@ -42,6 +42,7 @@ $container->register(new Kanboard\ServiceProvider\NotificationProvider());
$container->register(new Kanboard\ServiceProvider\ClassProvider());
$container->register(new Kanboard\ServiceProvider\EventDispatcherProvider());
$container->register(new Kanboard\ServiceProvider\GroupProvider());
+$container->register(new Kanboard\ServiceProvider\UserProvider());
$container->register(new Kanboard\ServiceProvider\RouteProvider());
$container->register(new Kanboard\ServiceProvider\ActionProvider());
$container->register(new Kanboard\ServiceProvider\ExternalLinkProvider());
diff --git a/app/constants.php b/app/constants.php
index 2266014d..6b260a4a 100644
--- a/app/constants.php
+++ b/app/constants.php
@@ -56,6 +56,7 @@ defined('DB_SSL_CA') or define('DB_SSL_CA', null);
// Database backend group provider
defined('DB_GROUP_PROVIDER') or define('DB_GROUP_PROVIDER', true);
+defined('DB_USER_PROVIDER') or define('DB_USER_PROVIDER', true);
// LDAP configuration
defined('LDAP_AUTH') or define('LDAP_AUTH', false);