diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/Controller/ProjectPermissionController.php | 4 | ||||
-rw-r--r-- | app/Controller/UserAjaxController.php | 12 | ||||
-rw-r--r-- | app/Core/Base.php | 3 | ||||
-rw-r--r-- | app/Core/Group/GroupBackendProviderInterface.php | 2 | ||||
-rw-r--r-- | app/Core/Group/GroupManager.php | 10 | ||||
-rw-r--r-- | app/Core/Group/GroupProviderInterface.php | 2 | ||||
-rw-r--r-- | app/Core/User/UserBackendProviderInterface.php | 21 | ||||
-rw-r--r-- | app/Core/User/UserManager.php | 71 | ||||
-rw-r--r-- | app/Formatter/GroupAutoCompleteFormatter.php | 3 | ||||
-rw-r--r-- | app/Formatter/UserAutoCompleteFormatter.php | 50 | ||||
-rw-r--r-- | app/Model/UserModel.php | 16 | ||||
-rw-r--r-- | app/ServiceProvider/GroupProvider.php | 2 | ||||
-rw-r--r-- | app/ServiceProvider/UserProvider.php | 35 | ||||
-rw-r--r-- | app/Template/project_permission/groups.php | 2 | ||||
-rw-r--r-- | app/Template/project_permission/users.php | 16 | ||||
-rw-r--r-- | app/User/DatabaseBackendUserProvider.php | 43 | ||||
-rw-r--r-- | app/User/DatabaseUserProvider.php | 8 | ||||
-rw-r--r-- | app/common.php | 1 | ||||
-rw-r--r-- | app/constants.php | 1 |
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); |