Add user backend provider system

This commit is contained in:
Frederic Guillot
2017-11-09 15:09:54 -08:00
parent 95b2a36886
commit 44aa24bab1
23 changed files with 273 additions and 50 deletions

View File

@@ -69,6 +69,10 @@ class ProjectPermissionController extends BaseController
$project = $this->getProject(); $project = $this->getProject();
$values = $this->request->getValues(); $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'])) { if (empty($values['user_id'])) {
$this->flash->failure(t('User not found.')); $this->flash->failure(t('User not found.'));
} elseif ($this->projectUserRoleModel->addUser($values['project_id'], $values['user_id'], $values['role'])) { } elseif ($this->projectUserRoleModel->addUser($values['project_id'], $values['user_id'], $values['role'])) {

View File

@@ -2,9 +2,6 @@
namespace Kanboard\Controller; namespace Kanboard\Controller;
use Kanboard\Filter\UserNameFilter;
use Kanboard\Model\UserModel;
/** /**
* User Ajax Controller * User Ajax Controller
* *
@@ -21,13 +18,8 @@ class UserAjaxController extends BaseController
public function autocomplete() public function autocomplete()
{ {
$search = $this->request->getStringParam('term'); $search = $this->request->getStringParam('term');
$filter = $this->userQuery->withFilter(new UserNameFilter($search)); $users = $this->userManager->find($search);
$filter->getQuery() $this->response->json($this->userAutoCompleteFormatter->withUsers($users)->format());
->eq(UserModel::TABLE.'.is_active', 1)
->asc(UserModel::TABLE.'.name')
->asc(UserModel::TABLE.'.username');
$this->response->json($filter->format($this->userAutoCompleteFormatter));
} }
/** /**

View File

@@ -7,7 +7,7 @@ use Pimple\Container;
/** /**
* Base Class * Base Class
* *
* @package core * @package Kanboard\Core
* @author Frederic Guillot * @author Frederic Guillot
* *
* @property \Kanboard\Analytic\TaskDistributionAnalytic $taskDistributionAnalytic * @property \Kanboard\Analytic\TaskDistributionAnalytic $taskDistributionAnalytic
@@ -22,6 +22,7 @@ use Pimple\Container;
* @property \Kanboard\Core\Cache\BaseCache $cacheDriver * @property \Kanboard\Core\Cache\BaseCache $cacheDriver
* @property \Kanboard\Core\Event\EventManager $eventManager * @property \Kanboard\Core\Event\EventManager $eventManager
* @property \Kanboard\Core\Group\GroupManager $groupManager * @property \Kanboard\Core\Group\GroupManager $groupManager
* @property \Kanboard\Core\User\UserManager $userManager
* @property \Kanboard\Core\Http\Client $httpClient * @property \Kanboard\Core\Http\Client $httpClient
* @property \Kanboard\Core\Http\OAuth2 $oauth * @property \Kanboard\Core\Http\OAuth2 $oauth
* @property \Kanboard\Core\Http\RememberMeCookie $rememberMeCookie * @property \Kanboard\Core\Http\RememberMeCookie $rememberMeCookie

View File

@@ -5,7 +5,7 @@ namespace Kanboard\Core\Group;
/** /**
* Group Backend Provider Interface * Group Backend Provider Interface
* *
* @package group * @package Kanboard\Core\Group
* @author Frederic Guillot * @author Frederic Guillot
*/ */
interface GroupBackendProviderInterface interface GroupBackendProviderInterface

View File

@@ -5,7 +5,7 @@ namespace Kanboard\Core\Group;
/** /**
* Group Manager * Group Manager
* *
* @package group * @package Kanboard\Core\Group
* @author Frederic Guillot * @author Frederic Guillot
*/ */
class GroupManager class GroupManager
@@ -13,10 +13,10 @@ class GroupManager
/** /**
* List of backend providers * List of backend providers
* *
* @access private * @access protected
* @var array * @var array
*/ */
private $providers = array(); protected $providers = array();
/** /**
* Register a new group backend provider * Register a new group backend provider
@@ -52,11 +52,11 @@ class GroupManager
/** /**
* Remove duplicated groups * Remove duplicated groups
* *
* @access private * @access protected
* @param array $groups * @param array $groups
* @return GroupProviderInterface[] * @return GroupProviderInterface[]
*/ */
private function removeDuplicates(array $groups) protected function removeDuplicates(array $groups)
{ {
$result = array(); $result = array();

View File

@@ -5,7 +5,7 @@ namespace Kanboard\Core\Group;
/** /**
* Group Provider Interface * Group Provider Interface
* *
* @package group * @package Kanboard\Core\Group
* @author Frederic Guillot * @author Frederic Guillot
*/ */
interface GroupProviderInterface interface GroupProviderInterface

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -4,12 +4,11 @@ namespace Kanboard\Formatter;
use Kanboard\Core\Filter\FormatterInterface; use Kanboard\Core\Filter\FormatterInterface;
use Kanboard\Core\Group\GroupProviderInterface; use Kanboard\Core\Group\GroupProviderInterface;
use PicoDb\Table;
/** /**
* Auto-complete formatter for groups * Auto-complete formatter for groups
* *
* @package formatter * @package Kanboard\Formatter
* @author Frederic Guillot * @author Frederic Guillot
*/ */
class GroupAutoCompleteFormatter extends BaseFormatter implements FormatterInterface class GroupAutoCompleteFormatter extends BaseFormatter implements FormatterInterface

View File

@@ -2,37 +2,59 @@
namespace Kanboard\Formatter; namespace Kanboard\Formatter;
use Kanboard\Model\UserModel; use Kanboard\Core\User\UserProviderInterface;
use Kanboard\Core\Filter\FormatterInterface; use Kanboard\Core\Filter\FormatterInterface;
/** /**
* Auto-complete formatter for user filter * Auto-complete formatter for users
* *
* @package formatter * @package Kanboard\Formatter
* @author Frederic Guillot * @author Frederic Guillot
*/ */
class UserAutoCompleteFormatter extends BaseFormatter implements FormatterInterface 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 * @access public
* @return array * @return array
*/ */
public function format() public function format()
{ {
$users = $this->query->columns(UserModel::TABLE.'.id', UserModel::TABLE.'.username', UserModel::TABLE.'.name')->findAll(); $result = array();
foreach ($users as &$user) { foreach ($this->users as $user) {
if (empty($user['name'])) { $result[] = array(
$user['value'] = $user['username'].' (#'.$user['id'].')'; 'id' => $user->getInternalId(),
$user['label'] = $user['username']; 'username' => $user->getUsername(),
} else { 'external_id' => $user->getExternalId(),
$user['value'] = $user['name'].' (#'.$user['id'].')'; 'external_id_column' => $user->getExternalIdColumn(),
$user['label'] = $user['name'].' ('.$user['username'].')'; 'value' => $user->getName() === '' ? $user->getUsername() : $user->getName(),
} 'label' => $user->getName() === '' ? $user->getUsername() : $user->getName().' ('.$user->getUsername().')',
);
} }
return $users; return $result;
} }
} }

View File

@@ -376,4 +376,20 @@ class UserModel extends Base
->eq('id', $user_id) ->eq('id', $user_id)
->save(array('token' => '')); ->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;
}
} }

View File

@@ -25,7 +25,7 @@ class GroupProvider implements ServiceProviderInterface
*/ */
public function register(Container $container) public function register(Container $container)
{ {
$container['groupManager'] = new GroupManager; $container['groupManager'] = new GroupManager();
if (DB_GROUP_PROVIDER) { if (DB_GROUP_PROVIDER) {
$container['groupManager']->register(new DatabaseBackendGroupProvider($container)); $container['groupManager']->register(new DatabaseBackendGroupProvider($container));

View File

@@ -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;
}
}

View File

@@ -46,7 +46,7 @@
'placeholder="'.t('Enter group name...').'"', 'placeholder="'.t('Enter group name...').'"',
'title="'.t('Enter group name...').'"', 'title="'.t('Enter group name...').'"',
'data-dst-field="group_id"', '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').'"', 'data-search-url="'.$this->url->href('GroupAjaxController', 'autocomplete').'"',
), ),
'autocomplete') ?> 'autocomplete') ?>

View File

@@ -34,15 +34,19 @@
<?= $this->form->csrf() ?> <?= $this->form->csrf() ?>
<?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?> <?= $this->form->hidden('project_id', array('project_id' => $project['id'])) ?>
<?= $this->form->hidden('user_id', $values) ?> <?= $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->label(t('Name'), 'name') ?>
<?= $this->form->text('name', $values, $errors, array( <?= $this->form->text('name', $values, $errors, array(
'required', 'required',
'placeholder="'.t('Enter user name...').'"', 'placeholder="'.t('Enter user name...').'"',
'title="'.t('Enter user name...').'"', 'title="'.t('Enter user name...').'"',
'data-dst-field="user_id"', 'data-dst-field="user_id"',
'data-search-url="'.$this->url->href('UserAjaxController', 'autocomplete').'"', 'data-dst-extra-fields="external_id,external_id_column,username"',
), 'data-search-url="'.$this->url->href('UserAjaxController', 'autocomplete').'"',
),
'autocomplete') ?> 'autocomplete') ?>
<?= $this->form->select('role', $roles, $values, $errors) ?> <?= $this->form->select('role', $roles, $values, $errors) ?>

View File

@@ -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;
}
}

View File

@@ -83,7 +83,7 @@ class DatabaseUserProvider implements UserProviderInterface
*/ */
public function getRole() public function getRole()
{ {
return ''; return empty($this->user['role']) ? '' : $this->user['role'];
} }
/** /**
@@ -94,7 +94,7 @@ class DatabaseUserProvider implements UserProviderInterface
*/ */
public function getUsername() public function getUsername()
{ {
return ''; return empty($this->user['username']) ? '' : $this->user['username'];
} }
/** /**
@@ -105,7 +105,7 @@ class DatabaseUserProvider implements UserProviderInterface
*/ */
public function getName() public function getName()
{ {
return ''; return empty($this->user['name']) ? '' : $this->user['name'];
} }
/** /**
@@ -116,7 +116,7 @@ class DatabaseUserProvider implements UserProviderInterface
*/ */
public function getEmail() public function getEmail()
{ {
return ''; return empty($this->user['email']) ? '' : $this->user['email'];
} }
/** /**

View File

@@ -42,6 +42,7 @@ $container->register(new Kanboard\ServiceProvider\NotificationProvider());
$container->register(new Kanboard\ServiceProvider\ClassProvider()); $container->register(new Kanboard\ServiceProvider\ClassProvider());
$container->register(new Kanboard\ServiceProvider\EventDispatcherProvider()); $container->register(new Kanboard\ServiceProvider\EventDispatcherProvider());
$container->register(new Kanboard\ServiceProvider\GroupProvider()); $container->register(new Kanboard\ServiceProvider\GroupProvider());
$container->register(new Kanboard\ServiceProvider\UserProvider());
$container->register(new Kanboard\ServiceProvider\RouteProvider()); $container->register(new Kanboard\ServiceProvider\RouteProvider());
$container->register(new Kanboard\ServiceProvider\ActionProvider()); $container->register(new Kanboard\ServiceProvider\ActionProvider());
$container->register(new Kanboard\ServiceProvider\ExternalLinkProvider()); $container->register(new Kanboard\ServiceProvider\ExternalLinkProvider());

View File

@@ -56,6 +56,7 @@ defined('DB_SSL_CA') or define('DB_SSL_CA', null);
// Database backend group provider // Database backend group provider
defined('DB_GROUP_PROVIDER') or define('DB_GROUP_PROVIDER', true); defined('DB_GROUP_PROVIDER') or define('DB_GROUP_PROVIDER', true);
defined('DB_USER_PROVIDER') or define('DB_USER_PROVIDER', true);
// LDAP configuration // LDAP configuration
defined('LDAP_AUTH') or define('LDAP_AUTH', false); defined('LDAP_AUTH') or define('LDAP_AUTH', false);

File diff suppressed because one or more lines are too long

View File

@@ -79,7 +79,7 @@ Kanboard.App.prototype.autoComplete = function() {
$(".autocomplete").each(function() { $(".autocomplete").each(function() {
var input = $(this); var input = $(this);
var field = input.data("dst-field"); var field = input.data("dst-field");
var extraField = input.data("dst-extra-field"); var extraFields = input.data("dst-extra-fields");
if ($('#form-' + field).val() === '') { if ($('#form-' + field).val() === '') {
input.parent().find("button[type=submit]").attr('disabled','disabled'); input.parent().find("button[type=submit]").attr('disabled','disabled');
@@ -91,8 +91,13 @@ Kanboard.App.prototype.autoComplete = function() {
select: function(event, ui) { select: function(event, ui) {
$("input[name=" + field + "]").val(ui.item.id); $("input[name=" + field + "]").val(ui.item.id);
if (extraField) { if (extraFields) {
$("input[name=" + extraField + "]").val(ui.item[extraField]); var fields = extraFields.split(',');
for (var i = 0; i < fields.length; i++) {
var fieldName = fields[i].trim();
$("input[name=" + fieldName + "]").val(ui.item[fieldName]);
}
} }
input.parent().find("button[type=submit]").removeAttr('disabled'); input.parent().find("button[type=submit]").removeAttr('disabled');

View File

@@ -348,6 +348,8 @@ return array(
'Kanboard\\Core\\User\\Avatar\\AvatarManager' => $baseDir . '/app/Core/User/Avatar/AvatarManager.php', 'Kanboard\\Core\\User\\Avatar\\AvatarManager' => $baseDir . '/app/Core/User/Avatar/AvatarManager.php',
'Kanboard\\Core\\User\\Avatar\\AvatarProviderInterface' => $baseDir . '/app/Core/User/Avatar/AvatarProviderInterface.php', 'Kanboard\\Core\\User\\Avatar\\AvatarProviderInterface' => $baseDir . '/app/Core/User/Avatar/AvatarProviderInterface.php',
'Kanboard\\Core\\User\\GroupSync' => $baseDir . '/app/Core/User/GroupSync.php', 'Kanboard\\Core\\User\\GroupSync' => $baseDir . '/app/Core/User/GroupSync.php',
'Kanboard\\Core\\User\\UserBackendProviderInterface' => $baseDir . '/app/Core/User/UserBackendProviderInterface.php',
'Kanboard\\Core\\User\\UserManager' => $baseDir . '/app/Core/User/UserManager.php',
'Kanboard\\Core\\User\\UserProfile' => $baseDir . '/app/Core/User/UserProfile.php', 'Kanboard\\Core\\User\\UserProfile' => $baseDir . '/app/Core/User/UserProfile.php',
'Kanboard\\Core\\User\\UserProperty' => $baseDir . '/app/Core/User/UserProperty.php', 'Kanboard\\Core\\User\\UserProperty' => $baseDir . '/app/Core/User/UserProperty.php',
'Kanboard\\Core\\User\\UserProviderInterface' => $baseDir . '/app/Core/User/UserProviderInterface.php', 'Kanboard\\Core\\User\\UserProviderInterface' => $baseDir . '/app/Core/User/UserProviderInterface.php',
@@ -609,6 +611,7 @@ return array(
'Kanboard\\ServiceProvider\\QueueProvider' => $baseDir . '/app/ServiceProvider/QueueProvider.php', 'Kanboard\\ServiceProvider\\QueueProvider' => $baseDir . '/app/ServiceProvider/QueueProvider.php',
'Kanboard\\ServiceProvider\\RouteProvider' => $baseDir . '/app/ServiceProvider/RouteProvider.php', 'Kanboard\\ServiceProvider\\RouteProvider' => $baseDir . '/app/ServiceProvider/RouteProvider.php',
'Kanboard\\ServiceProvider\\SessionProvider' => $baseDir . '/app/ServiceProvider/SessionProvider.php', 'Kanboard\\ServiceProvider\\SessionProvider' => $baseDir . '/app/ServiceProvider/SessionProvider.php',
'Kanboard\\ServiceProvider\\UserProvider' => $baseDir . '/app/ServiceProvider/UserProvider.php',
'Kanboard\\Subscriber\\AuthSubscriber' => $baseDir . '/app/Subscriber/AuthSubscriber.php', 'Kanboard\\Subscriber\\AuthSubscriber' => $baseDir . '/app/Subscriber/AuthSubscriber.php',
'Kanboard\\Subscriber\\BaseSubscriber' => $baseDir . '/app/Subscriber/BaseSubscriber.php', 'Kanboard\\Subscriber\\BaseSubscriber' => $baseDir . '/app/Subscriber/BaseSubscriber.php',
'Kanboard\\Subscriber\\BootstrapSubscriber' => $baseDir . '/app/Subscriber/BootstrapSubscriber.php', 'Kanboard\\Subscriber\\BootstrapSubscriber' => $baseDir . '/app/Subscriber/BootstrapSubscriber.php',
@@ -620,6 +623,7 @@ return array(
'Kanboard\\Subscriber\\TransitionSubscriber' => $baseDir . '/app/Subscriber/TransitionSubscriber.php', 'Kanboard\\Subscriber\\TransitionSubscriber' => $baseDir . '/app/Subscriber/TransitionSubscriber.php',
'Kanboard\\User\\Avatar\\AvatarFileProvider' => $baseDir . '/app/User/Avatar/AvatarFileProvider.php', 'Kanboard\\User\\Avatar\\AvatarFileProvider' => $baseDir . '/app/User/Avatar/AvatarFileProvider.php',
'Kanboard\\User\\Avatar\\LetterAvatarProvider' => $baseDir . '/app/User/Avatar/LetterAvatarProvider.php', 'Kanboard\\User\\Avatar\\LetterAvatarProvider' => $baseDir . '/app/User/Avatar/LetterAvatarProvider.php',
'Kanboard\\User\\DatabaseBackendUserProvider' => $baseDir . '/app/User/DatabaseBackendUserProvider.php',
'Kanboard\\User\\DatabaseUserProvider' => $baseDir . '/app/User/DatabaseUserProvider.php', 'Kanboard\\User\\DatabaseUserProvider' => $baseDir . '/app/User/DatabaseUserProvider.php',
'Kanboard\\User\\LdapUserProvider' => $baseDir . '/app/User/LdapUserProvider.php', 'Kanboard\\User\\LdapUserProvider' => $baseDir . '/app/User/LdapUserProvider.php',
'Kanboard\\User\\OAuthUserProvider' => $baseDir . '/app/User/OAuthUserProvider.php', 'Kanboard\\User\\OAuthUserProvider' => $baseDir . '/app/User/OAuthUserProvider.php',

View File

@@ -484,6 +484,8 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
'Kanboard\\Core\\User\\Avatar\\AvatarManager' => __DIR__ . '/../..' . '/app/Core/User/Avatar/AvatarManager.php', 'Kanboard\\Core\\User\\Avatar\\AvatarManager' => __DIR__ . '/../..' . '/app/Core/User/Avatar/AvatarManager.php',
'Kanboard\\Core\\User\\Avatar\\AvatarProviderInterface' => __DIR__ . '/../..' . '/app/Core/User/Avatar/AvatarProviderInterface.php', 'Kanboard\\Core\\User\\Avatar\\AvatarProviderInterface' => __DIR__ . '/../..' . '/app/Core/User/Avatar/AvatarProviderInterface.php',
'Kanboard\\Core\\User\\GroupSync' => __DIR__ . '/../..' . '/app/Core/User/GroupSync.php', 'Kanboard\\Core\\User\\GroupSync' => __DIR__ . '/../..' . '/app/Core/User/GroupSync.php',
'Kanboard\\Core\\User\\UserBackendProviderInterface' => __DIR__ . '/../..' . '/app/Core/User/UserBackendProviderInterface.php',
'Kanboard\\Core\\User\\UserManager' => __DIR__ . '/../..' . '/app/Core/User/UserManager.php',
'Kanboard\\Core\\User\\UserProfile' => __DIR__ . '/../..' . '/app/Core/User/UserProfile.php', 'Kanboard\\Core\\User\\UserProfile' => __DIR__ . '/../..' . '/app/Core/User/UserProfile.php',
'Kanboard\\Core\\User\\UserProperty' => __DIR__ . '/../..' . '/app/Core/User/UserProperty.php', 'Kanboard\\Core\\User\\UserProperty' => __DIR__ . '/../..' . '/app/Core/User/UserProperty.php',
'Kanboard\\Core\\User\\UserProviderInterface' => __DIR__ . '/../..' . '/app/Core/User/UserProviderInterface.php', 'Kanboard\\Core\\User\\UserProviderInterface' => __DIR__ . '/../..' . '/app/Core/User/UserProviderInterface.php',
@@ -745,6 +747,7 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
'Kanboard\\ServiceProvider\\QueueProvider' => __DIR__ . '/../..' . '/app/ServiceProvider/QueueProvider.php', 'Kanboard\\ServiceProvider\\QueueProvider' => __DIR__ . '/../..' . '/app/ServiceProvider/QueueProvider.php',
'Kanboard\\ServiceProvider\\RouteProvider' => __DIR__ . '/../..' . '/app/ServiceProvider/RouteProvider.php', 'Kanboard\\ServiceProvider\\RouteProvider' => __DIR__ . '/../..' . '/app/ServiceProvider/RouteProvider.php',
'Kanboard\\ServiceProvider\\SessionProvider' => __DIR__ . '/../..' . '/app/ServiceProvider/SessionProvider.php', 'Kanboard\\ServiceProvider\\SessionProvider' => __DIR__ . '/../..' . '/app/ServiceProvider/SessionProvider.php',
'Kanboard\\ServiceProvider\\UserProvider' => __DIR__ . '/../..' . '/app/ServiceProvider/UserProvider.php',
'Kanboard\\Subscriber\\AuthSubscriber' => __DIR__ . '/../..' . '/app/Subscriber/AuthSubscriber.php', 'Kanboard\\Subscriber\\AuthSubscriber' => __DIR__ . '/../..' . '/app/Subscriber/AuthSubscriber.php',
'Kanboard\\Subscriber\\BaseSubscriber' => __DIR__ . '/../..' . '/app/Subscriber/BaseSubscriber.php', 'Kanboard\\Subscriber\\BaseSubscriber' => __DIR__ . '/../..' . '/app/Subscriber/BaseSubscriber.php',
'Kanboard\\Subscriber\\BootstrapSubscriber' => __DIR__ . '/../..' . '/app/Subscriber/BootstrapSubscriber.php', 'Kanboard\\Subscriber\\BootstrapSubscriber' => __DIR__ . '/../..' . '/app/Subscriber/BootstrapSubscriber.php',
@@ -756,6 +759,7 @@ class ComposerStaticInit6edea6294a88689e3f5c56484bb70c9b
'Kanboard\\Subscriber\\TransitionSubscriber' => __DIR__ . '/../..' . '/app/Subscriber/TransitionSubscriber.php', 'Kanboard\\Subscriber\\TransitionSubscriber' => __DIR__ . '/../..' . '/app/Subscriber/TransitionSubscriber.php',
'Kanboard\\User\\Avatar\\AvatarFileProvider' => __DIR__ . '/../..' . '/app/User/Avatar/AvatarFileProvider.php', 'Kanboard\\User\\Avatar\\AvatarFileProvider' => __DIR__ . '/../..' . '/app/User/Avatar/AvatarFileProvider.php',
'Kanboard\\User\\Avatar\\LetterAvatarProvider' => __DIR__ . '/../..' . '/app/User/Avatar/LetterAvatarProvider.php', 'Kanboard\\User\\Avatar\\LetterAvatarProvider' => __DIR__ . '/../..' . '/app/User/Avatar/LetterAvatarProvider.php',
'Kanboard\\User\\DatabaseBackendUserProvider' => __DIR__ . '/../..' . '/app/User/DatabaseBackendUserProvider.php',
'Kanboard\\User\\DatabaseUserProvider' => __DIR__ . '/../..' . '/app/User/DatabaseUserProvider.php', 'Kanboard\\User\\DatabaseUserProvider' => __DIR__ . '/../..' . '/app/User/DatabaseUserProvider.php',
'Kanboard\\User\\LdapUserProvider' => __DIR__ . '/../..' . '/app/User/LdapUserProvider.php', 'Kanboard\\User\\LdapUserProvider' => __DIR__ . '/../..' . '/app/User/LdapUserProvider.php',
'Kanboard\\User\\OAuthUserProvider' => __DIR__ . '/../..' . '/app/User/OAuthUserProvider.php', 'Kanboard\\User\\OAuthUserProvider' => __DIR__ . '/../..' . '/app/User/OAuthUserProvider.php',