Add personal API access token
This commit is contained in:
parent
23d862aef8
commit
b8f7532e5c
|
|
@ -3,6 +3,7 @@ Version 1.0.35
|
||||||
|
|
||||||
New features:
|
New features:
|
||||||
|
|
||||||
|
* Add personal API access token for users
|
||||||
* Rewrite of Markdown editor (remove CodeMirror)
|
* Rewrite of Markdown editor (remove CodeMirror)
|
||||||
* Suggest menu for task ID and user mentions in Markdown editor
|
* Suggest menu for task ID and user mentions in Markdown editor
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ class AuthenticationMiddleware extends Base implements MiddlewareInterface
|
||||||
public function execute($username, $password, $procedureName)
|
public function execute($username, $password, $procedureName)
|
||||||
{
|
{
|
||||||
$this->dispatcher->dispatch('app.bootstrap');
|
$this->dispatcher->dispatch('app.bootstrap');
|
||||||
|
$this->sessionStorage->scope = 'API';
|
||||||
|
|
||||||
if ($this->isUserAuthenticated($username, $password)) {
|
if ($this->isUserAuthenticated($username, $password)) {
|
||||||
$this->userSession->initialize($this->userModel->getByUsername($username));
|
$this->userSession->initialize($this->userModel->getByUsername($username));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Auth;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
|
||||||
|
use Kanboard\Model\UserModel;
|
||||||
|
use Kanboard\User\DatabaseUserProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API Access Token Authentication Provider
|
||||||
|
*
|
||||||
|
* @package Kanboard\Auth
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ApiAccessTokenAuth extends Base implements PasswordAuthenticationProviderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* User properties
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $userInfo = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $username = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $password = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get authentication provider name
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'API Access Token';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate the user
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function authenticate()
|
||||||
|
{
|
||||||
|
if (! isset($this->sessionStorage->scope) || $this->sessionStorage->scope !== 'API') {
|
||||||
|
$this->logger->debug(__METHOD__.': Authentication provider skipped because invalid scope');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $this->db
|
||||||
|
->table(UserModel::TABLE)
|
||||||
|
->columns('id', 'password')
|
||||||
|
->eq('username', $this->username)
|
||||||
|
->eq('api_access_token', $this->password)
|
||||||
|
->notNull('api_access_token')
|
||||||
|
->eq('is_active', 1)
|
||||||
|
->findOne();
|
||||||
|
|
||||||
|
if (! empty($user)) {
|
||||||
|
$this->userInfo = $user;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user object
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return \Kanboard\User\DatabaseUserProvider
|
||||||
|
*/
|
||||||
|
public function getUser()
|
||||||
|
{
|
||||||
|
if (empty($this->userInfo)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DatabaseUserProvider($this->userInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set username
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $username
|
||||||
|
*/
|
||||||
|
public function setUsername($username)
|
||||||
|
{
|
||||||
|
$this->username = $username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set password
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $password
|
||||||
|
*/
|
||||||
|
public function setPassword($password)
|
||||||
|
{
|
||||||
|
$this->password = $password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ use Kanboard\User\DatabaseUserProvider;
|
||||||
/**
|
/**
|
||||||
* Database Authentication Provider
|
* Database Authentication Provider
|
||||||
*
|
*
|
||||||
* @package auth
|
* @package Kanboard\Auth
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class DatabaseAuth extends Base implements PasswordAuthenticationProviderInterface, SessionCheckProviderInterface
|
class DatabaseAuth extends Base implements PasswordAuthenticationProviderInterface, SessionCheckProviderInterface
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
|
||||||
/**
|
/**
|
||||||
* LDAP Authentication Provider
|
* LDAP Authentication Provider
|
||||||
*
|
*
|
||||||
* @package auth
|
* @package Kanboard\Auth
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class LdapAuth extends Base implements PasswordAuthenticationProviderInterface
|
class LdapAuth extends Base implements PasswordAuthenticationProviderInterface
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ use Kanboard\Core\Security\PreAuthenticationProviderInterface;
|
||||||
use Kanboard\User\DatabaseUserProvider;
|
use Kanboard\User\DatabaseUserProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rember Me Cookie Authentication Provider
|
* RememberMe Cookie Authentication Provider
|
||||||
*
|
*
|
||||||
* @package auth
|
* @package Kanboard\Auth
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class RememberMeAuth extends Base implements PreAuthenticationProviderInterface
|
class RememberMeAuth extends Base implements PreAuthenticationProviderInterface
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use Kanboard\User\ReverseProxyUserProvider;
|
||||||
/**
|
/**
|
||||||
* Reverse-Proxy Authentication Provider
|
* Reverse-Proxy Authentication Provider
|
||||||
*
|
*
|
||||||
* @package auth
|
* @package Kanboard\Auth
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class ReverseProxyAuth extends Base implements PreAuthenticationProviderInterface, SessionCheckProviderInterface
|
class ReverseProxyAuth extends Base implements PreAuthenticationProviderInterface, SessionCheckProviderInterface
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use Kanboard\Core\Security\PostAuthenticationProviderInterface;
|
||||||
/**
|
/**
|
||||||
* TOTP Authentication Provider
|
* TOTP Authentication Provider
|
||||||
*
|
*
|
||||||
* @package auth
|
* @package Kanboard\Auth
|
||||||
* @author Frederic Guillot
|
* @author Frederic Guillot
|
||||||
*/
|
*/
|
||||||
class TotpAuth extends Base implements PostAuthenticationProviderInterface
|
class TotpAuth extends Base implements PostAuthenticationProviderInterface
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
|
use Kanboard\Core\Security\Token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UserApiAccessController
|
||||||
|
*
|
||||||
|
* @package Kanboard\Controller
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class UserApiAccessController extends BaseController
|
||||||
|
{
|
||||||
|
public function show()
|
||||||
|
{
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
return $this->response->html($this->helper->layout->user('user_api_access/show', array(
|
||||||
|
'user' => $user,
|
||||||
|
'title' => t('API User Access'),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generate()
|
||||||
|
{
|
||||||
|
$user = $this->getUser();
|
||||||
|
$this->checkCSRFParam();
|
||||||
|
|
||||||
|
$this->userModel->update(array(
|
||||||
|
'id' => $user['id'],
|
||||||
|
'api_access_token' => Token::getToken(),
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->response->redirect($this->helper->url->to('UserApiAccessController', 'show', array('user_id' => $user['id'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
$user = $this->getUser();
|
||||||
|
$this->checkCSRFParam();
|
||||||
|
|
||||||
|
$this->userModel->update(array(
|
||||||
|
'id' => $user['id'],
|
||||||
|
'api_access_token' => null,
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->response->redirect($this->helper->url->to('UserApiAccessController', 'show', array('user_id' => $user['id'])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ namespace Kanboard\Core\Session;
|
||||||
* @property bool $hasSubtaskInProgress
|
* @property bool $hasSubtaskInProgress
|
||||||
* @property bool $hasRememberMe
|
* @property bool $hasRememberMe
|
||||||
* @property bool $boardCollapsed
|
* @property bool $boardCollapsed
|
||||||
|
* @property string $scope
|
||||||
* @property bool $twoFactorBeforeCodeCalled
|
* @property bool $twoFactorBeforeCodeCalled
|
||||||
* @property string $twoFactorSecret
|
* @property string $twoFactorSecret
|
||||||
* @property string $oauthState
|
* @property string $oauthState
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
'Moving a task is not permitted' => 'Verschieben einer Aufgabe ist nicht erlaubt',
|
'Moving a task is not permitted' => 'Verschieben einer Aufgabe ist nicht erlaubt',
|
||||||
'This value must be in the range %d to %d' => 'Dieser Wert muss im Bereich %d bis %d sein',
|
'This value must be in the range %d to %d' => 'Dieser Wert muss im Bereich %d bis %d sein',
|
||||||
'You are not allowed to move this task.' => 'Sie haben nicht die Berechtigung, diese Aufgabe zu verschieben.',
|
'You are not allowed to move this task.' => 'Sie haben nicht die Berechtigung, diese Aufgabe zu verschieben.',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1279,4 +1279,13 @@ return array(
|
||||||
'Moving a task is not permitted' => 'Déplaçer une tâche n\'est pas autorisé',
|
'Moving a task is not permitted' => 'Déplaçer une tâche n\'est pas autorisé',
|
||||||
'This value must be in the range %d to %d' => 'Cette valeur doit être définie entre %d et %d',
|
'This value must be in the range %d to %d' => 'Cette valeur doit être définie entre %d et %d',
|
||||||
'You are not allowed to move this task.' => 'Vous n\'êtes pas autorisé à déplacer cette tâche.',
|
'You are not allowed to move this task.' => 'Vous n\'êtes pas autorisé à déplacer cette tâche.',
|
||||||
|
'API User Access' => 'Accès utilisateur de l\'API',
|
||||||
|
'Preview' => 'Aperçu',
|
||||||
|
'Write' => 'Écrire',
|
||||||
|
'Write your text in Markdown' => 'Écrivez votre texte en Markdown',
|
||||||
|
'New External Task: %s' => 'Nouvelle tâche externe : %s',
|
||||||
|
'No personal API access token registered.' => 'Aucun jeton d\'accès personnel à l\'API enregistré.',
|
||||||
|
'Your personal API access token is "%s"' => 'Votre jeton d\'accès personnel à l\'API est « %s »',
|
||||||
|
'Remove your token' => 'Supprimer votre jeton',
|
||||||
|
'Generate a new token' => 'Générer un nouveau jeton',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
'Moving a task is not permitted' => 'Spostare task non è permesso',
|
'Moving a task is not permitted' => 'Spostare task non è permesso',
|
||||||
'This value must be in the range %d to %d' => 'Questo valore deve essere compreso tra %d e %d',
|
'This value must be in the range %d to %d' => 'Questo valore deve essere compreso tra %d e %d',
|
||||||
'You are not allowed to move this task.' => 'Non ti è permesso spostare questo task.',
|
'You are not allowed to move this task.' => 'Non ti è permesso spostare questo task.',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
'Moving a task is not permitted' => '할일 이동이 거부되었습니다.',
|
'Moving a task is not permitted' => '할일 이동이 거부되었습니다.',
|
||||||
'This value must be in the range %d to %d' => '값의 범위는 %d 부터 %d 까지 입니다.',
|
'This value must be in the range %d to %d' => '값의 범위는 %d 부터 %d 까지 입니다.',
|
||||||
'You are not allowed to move this task.' => '당신은 할일 이동이 거부되었습니다.',
|
'You are not allowed to move this task.' => '당신은 할일 이동이 거부되었습니다.',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
'Moving a task is not permitted' => 'Mover uma tarefa não é permitido',
|
'Moving a task is not permitted' => 'Mover uma tarefa não é permitido',
|
||||||
'This value must be in the range %d to %d' => 'Este valor precisa estar no intervalo %d até %d',
|
'This value must be in the range %d to %d' => 'Este valor precisa estar no intervalo %d até %d',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
'Moving a task is not permitted' => 'Não é permitido mover uma tarefa',
|
'Moving a task is not permitted' => 'Não é permitido mover uma tarefa',
|
||||||
'This value must be in the range %d to %d' => 'Este valor deve estar entre %d e %d',
|
'This value must be in the range %d to %d' => 'Este valor deve estar entre %d e %d',
|
||||||
'You are not allowed to move this task.' => 'Não lhe é permitido mover esta tarefa.',
|
'You are not allowed to move this task.' => 'Não lhe é permitido mover esta tarefa.',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
'Moving a task is not permitted' => 'Перемещение задачи не разрешено',
|
'Moving a task is not permitted' => 'Перемещение задачи не разрешено',
|
||||||
'This value must be in the range %d to %d' => 'Значение должно находиться в диапазоне от %d до %d',
|
'This value must be in the range %d to %d' => 'Значение должно находиться в диапазоне от %d до %d',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
// 'Moving a task is not permitted' => '',
|
// 'Moving a task is not permitted' => '',
|
||||||
// 'This value must be in the range %d to %d' => '',
|
// 'This value must be in the range %d to %d' => '',
|
||||||
// 'You are not allowed to move this task.' => '',
|
// 'You are not allowed to move this task.' => '',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
'Moving a task is not permitted' => 'Görev taşımaya izin verilmemiş',
|
'Moving a task is not permitted' => 'Görev taşımaya izin verilmemiş',
|
||||||
'This value must be in the range %d to %d' => 'Bu değer şu aralıkta olmalı: "%d" "%d"',
|
'This value must be in the range %d to %d' => 'Bu değer şu aralıkta olmalı: "%d" "%d"',
|
||||||
'You are not allowed to move this task.' => 'Bu görevi taşımaya izniniz yok.',
|
'You are not allowed to move this task.' => 'Bu görevi taşımaya izniniz yok.',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1278,4 +1278,13 @@ return array(
|
||||||
'Moving a task is not permitted' => '禁止移动任务',
|
'Moving a task is not permitted' => '禁止移动任务',
|
||||||
'This value must be in the range %d to %d' => '输入值必须在%d到%d之间',
|
'This value must be in the range %d to %d' => '输入值必须在%d到%d之间',
|
||||||
'You are not allowed to move this task.' => '你不能移动此任务',
|
'You are not allowed to move this task.' => '你不能移动此任务',
|
||||||
|
// 'API User Access' => '',
|
||||||
|
// 'Preview' => '',
|
||||||
|
// 'Write' => '',
|
||||||
|
// 'Write your text in Markdown' => '',
|
||||||
|
// 'New External Task: %s' => '',
|
||||||
|
// 'No personal API access token registered.' => '',
|
||||||
|
// 'Your personal API access token is "%s"' => '',
|
||||||
|
// 'Remove your token' => '',
|
||||||
|
// 'Generate a new token' => '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,12 @@ use PDO;
|
||||||
use Kanboard\Core\Security\Token;
|
use Kanboard\Core\Security\Token;
|
||||||
use Kanboard\Core\Security\Role;
|
use Kanboard\Core\Security\Role;
|
||||||
|
|
||||||
const VERSION = 117;
|
const VERSION = 118;
|
||||||
|
|
||||||
|
function version_118(PDO $pdo)
|
||||||
|
{
|
||||||
|
$pdo->exec('ALTER TABLE `users` ADD COLUMN `api_access_token` VARCHAR(255) DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
function version_117(PDO $pdo)
|
function version_117(PDO $pdo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,12 @@ use PDO;
|
||||||
use Kanboard\Core\Security\Token;
|
use Kanboard\Core\Security\Token;
|
||||||
use Kanboard\Core\Security\Role;
|
use Kanboard\Core\Security\Role;
|
||||||
|
|
||||||
const VERSION = 96;
|
const VERSION = 97;
|
||||||
|
|
||||||
|
function version_97(PDO $pdo)
|
||||||
|
{
|
||||||
|
$pdo->exec('ALTER TABLE "users" ADD COLUMN api_access_token VARCHAR(255) DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
function version_96(PDO $pdo)
|
function version_96(PDO $pdo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -715,6 +715,7 @@ CREATE TABLE `users` (
|
||||||
`role` varchar(25) NOT NULL DEFAULT 'app-user',
|
`role` varchar(25) NOT NULL DEFAULT 'app-user',
|
||||||
`is_active` tinyint(1) DEFAULT '1',
|
`is_active` tinyint(1) DEFAULT '1',
|
||||||
`avatar_path` varchar(255) DEFAULT NULL,
|
`avatar_path` varchar(255) DEFAULT NULL,
|
||||||
|
`api_access_token` varchar(255) DEFAULT NULL,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
UNIQUE KEY `users_username_idx` (`username`)
|
UNIQUE KEY `users_username_idx` (`username`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
@ -738,7 +739,7 @@ CREATE TABLE `users` (
|
||||||
|
|
||||||
LOCK TABLES `settings` WRITE;
|
LOCK TABLES `settings` WRITE;
|
||||||
/*!40000 ALTER TABLE `settings` DISABLE KEYS */;
|
/*!40000 ALTER TABLE `settings` DISABLE KEYS */;
|
||||||
INSERT INTO `settings` VALUES ('api_token','f9ae1d30899c88091642f4e996ff97b1e5db516b5edd256793246b18b637',0,0),('application_currency','USD',0,0),('application_datetime_format','m/d/Y H:i',1,1480728474),('application_date_format','m/d/Y',1,1480728474),('application_language','fr_FR',1,1480728474),('application_stylesheet','',1,1480728474),('application_timezone','UTC',1,1480728474),('application_time_format','H:i',1,1480728474),('application_url','',1,1480728474),('board_columns','',0,0),('board_highlight_period','172800',0,0),('board_private_refresh_interval','10',0,0),('board_public_refresh_interval','60',0,0),('calendar_project_tasks','date_started',0,0),('calendar_user_subtasks_time_tracking','0',0,0),('calendar_user_tasks','date_started',0,0),('cfd_include_closed_tasks','1',0,0),('default_color','yellow',0,0),('integration_gravatar','0',0,0),('password_reset','checked',1,1480728474),('project_categories','',0,0),('subtask_restriction','0',0,0),('subtask_time_tracking','1',0,0),('webhook_token','382dae506e2bd5a4e45709c275827b0bbc7bee9f683b2320c78299deb36e',0,0),('webhook_url','',0,0);
|
INSERT INTO `settings` VALUES ('api_token','f149956cb60c88d01123a28964fc035b1ce4513be454f2a85fe6b4ca3758',0,0),('application_currency','USD',0,0),('application_date_format','m/d/Y',0,0),('application_language','en_US',0,0),('application_stylesheet','',0,0),('application_timezone','UTC',0,0),('application_url','',0,0),('board_columns','',0,0),('board_highlight_period','172800',0,0),('board_private_refresh_interval','10',0,0),('board_public_refresh_interval','60',0,0),('calendar_project_tasks','date_started',0,0),('calendar_user_subtasks_time_tracking','0',0,0),('calendar_user_tasks','date_started',0,0),('cfd_include_closed_tasks','1',0,0),('default_color','yellow',0,0),('integration_gravatar','0',0,0),('password_reset','1',0,0),('project_categories','',0,0),('subtask_restriction','0',0,0),('subtask_time_tracking','1',0,0),('webhook_token','47d1d896b6612234c7543eb3f3a09a0a669f77a079d13ad3d810ccb79896',0,0),('webhook_url','',0,0);
|
||||||
/*!40000 ALTER TABLE `settings` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `settings` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||||
|
|
@ -767,4 +768,4 @@ UNLOCK TABLES;
|
||||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$ZYX2JNGPsH/SMc3UBk0rYu2LYCLYRVEqokhOjIULKXs6RjvaV2RBu', 'app-admin');INSERT INTO schema_version VALUES ('117');
|
INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$R1zYk04d96KcHRpd9.r5I.5I6mgKIgUdsaISZYmaDLPIJCUO0FFJG', 'app-admin');INSERT INTO schema_version VALUES ('118');
|
||||||
|
|
|
||||||
|
|
@ -1245,7 +1245,8 @@ CREATE TABLE "users" (
|
||||||
"gitlab_id" integer,
|
"gitlab_id" integer,
|
||||||
"role" character varying(25) DEFAULT 'app-user'::character varying NOT NULL,
|
"role" character varying(25) DEFAULT 'app-user'::character varying NOT NULL,
|
||||||
"is_active" boolean DEFAULT true,
|
"is_active" boolean DEFAULT true,
|
||||||
"avatar_path" character varying(255)
|
"avatar_path" character varying(255),
|
||||||
|
"api_access_token" character varying(255) DEFAULT NULL::character varying
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2544,8 +2545,8 @@ INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_high
|
||||||
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_public_refresh_interval', '60', 0, 0);
|
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_public_refresh_interval', '60', 0, 0);
|
||||||
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_private_refresh_interval', '10', 0, 0);
|
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_private_refresh_interval', '10', 0, 0);
|
||||||
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_columns', '', 0, 0);
|
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('board_columns', '', 0, 0);
|
||||||
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('webhook_token', 'c12181512f9cfd66a6b2af4edf199390b922bbb8a259dc5397c2329ed47c', 0, 0);
|
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('webhook_token', '8687190194e06d34c2cd84a57b36f67696c971c2f8e453f96e59eccb8e73', 0, 0);
|
||||||
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('api_token', '4e05046a5cb5b907da712ab02af98e9752da48bfacc0a625c4c08493bc8f', 0, 0);
|
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('api_token', '8381164131e3995ca17c754a5b0cf7039d66b9f389b80250978de9fcf2f5', 0, 0);
|
||||||
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_language', 'en_US', 0, 0);
|
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_language', 'en_US', 0, 0);
|
||||||
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_timezone', 'UTC', 0, 0);
|
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_timezone', 'UTC', 0, 0);
|
||||||
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_url', '', 0, 0);
|
INSERT INTO settings (option, value, changed_by, changed_on) VALUES ('application_url', '', 0, 0);
|
||||||
|
|
@ -2615,4 +2616,4 @@ SELECT pg_catalog.setval('links_id_seq', 11, true);
|
||||||
-- PostgreSQL database dump complete
|
-- PostgreSQL database dump complete
|
||||||
--
|
--
|
||||||
|
|
||||||
INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$ZYX2JNGPsH/SMc3UBk0rYu2LYCLYRVEqokhOjIULKXs6RjvaV2RBu', 'app-admin');INSERT INTO schema_version VALUES ('96');
|
INSERT INTO users (username, password, role) VALUES ('admin', '$2y$10$R1zYk04d96KcHRpd9.r5I.5I6mgKIgUdsaISZYmaDLPIJCUO0FFJG', 'app-admin');INSERT INTO schema_version VALUES ('97');
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,12 @@ use Kanboard\Core\Security\Token;
|
||||||
use Kanboard\Core\Security\Role;
|
use Kanboard\Core\Security\Role;
|
||||||
use PDO;
|
use PDO;
|
||||||
|
|
||||||
const VERSION = 107;
|
const VERSION = 108;
|
||||||
|
|
||||||
|
function version_108(PDO $pdo)
|
||||||
|
{
|
||||||
|
$pdo->exec('ALTER TABLE users ADD COLUMN api_access_token VARCHAR(255) DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
function version_107(PDO $pdo)
|
function version_107(PDO $pdo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Kanboard\ServiceProvider;
|
namespace Kanboard\ServiceProvider;
|
||||||
|
|
||||||
|
use Kanboard\Auth\ApiAccessTokenAuth;
|
||||||
use Pimple\Container;
|
use Pimple\Container;
|
||||||
use Pimple\ServiceProviderInterface;
|
use Pimple\ServiceProviderInterface;
|
||||||
use Kanboard\Core\Security\AuthenticationManager;
|
use Kanboard\Core\Security\AuthenticationManager;
|
||||||
|
|
@ -44,6 +45,8 @@ class AuthenticationProvider implements ServiceProviderInterface
|
||||||
$container['authenticationManager']->register(new LdapAuth($container));
|
$container['authenticationManager']->register(new LdapAuth($container));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$container['authenticationManager']->register(new ApiAccessTokenAuth($container));
|
||||||
|
|
||||||
$container['projectAccessMap'] = $this->getProjectAccessMap();
|
$container['projectAccessMap'] = $this->getProjectAccessMap();
|
||||||
$container['applicationAccessMap'] = $this->getApplicationAccessMap();
|
$container['applicationAccessMap'] = $this->getApplicationAccessMap();
|
||||||
$container['apiAccessMap'] = $this->getApiAccessMap();
|
$container['apiAccessMap'] = $this->getApiAccessMap();
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ class RouteProvider implements ServiceProviderInterface
|
||||||
$container['route']->addRoute('user/:user_id/authentication', 'UserCredentialController', 'changeAuthentication');
|
$container['route']->addRoute('user/:user_id/authentication', 'UserCredentialController', 'changeAuthentication');
|
||||||
$container['route']->addRoute('user/:user_id/2fa', 'TwoFactorController', 'index');
|
$container['route']->addRoute('user/:user_id/2fa', 'TwoFactorController', 'index');
|
||||||
$container['route']->addRoute('user/:user_id/avatar', 'AvatarFileController', 'show');
|
$container['route']->addRoute('user/:user_id/avatar', 'AvatarFileController', 'show');
|
||||||
|
$container['route']->addRoute('user/:user_id/api', 'UserApiAccessController', 'show');
|
||||||
|
|
||||||
// Groups
|
// Groups
|
||||||
$container['route']->addRoute('groups', 'GroupListController', 'index');
|
$container['route']->addRoute('groups', 'GroupListController', 'index');
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<div class="page-header">
|
||||||
|
<h2><?= t('API User Access') ?></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="alert">
|
||||||
|
<?php if (empty($user['api_access_token'])): ?>
|
||||||
|
<?= t('No personal API access token registered.') ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<?= t('Your personal API access token is "%s"', $user['api_access_token']) ?>
|
||||||
|
<?php endif ?>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<?php if (! empty($user['api_access_token'])): ?>
|
||||||
|
<?= $this->url->link(t('Remove your token'), 'UserApiAccessController', 'remove', array('user_id' => $user['id']), true, 'btn btn-red') ?>
|
||||||
|
<?php endif ?>
|
||||||
|
|
||||||
|
<?= $this->url->link(t('Generate a new token'), 'UserApiAccessController', 'generate', array('user_id' => $user['id']), true, 'btn btn-blue') ?>
|
||||||
|
|
@ -90,6 +90,11 @@
|
||||||
<?= $this->url->link(t('Integrations'), 'UserViewController', 'integrations', array('user_id' => $user['id'])) ?>
|
<?= $this->url->link(t('Integrations'), 'UserViewController', 'integrations', array('user_id' => $user['id'])) ?>
|
||||||
</li>
|
</li>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
<?php if ($this->user->hasAccess('UserApiAccessController', 'show')): ?>
|
||||||
|
<li <?= $this->app->checkMenuSelection('UserApiAccessController', 'show') ?>>
|
||||||
|
<?= $this->url->link(t('API'), 'UserApiAccessController', 'show', array('user_id' => $user['id'])) ?>
|
||||||
|
</li>
|
||||||
|
<?php endif ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
||||||
<?php if ($this->user->hasAccess('UserCredentialController', 'changeAuthentication')): ?>
|
<?php if ($this->user->hasAccess('UserCredentialController', 'changeAuthentication')): ?>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Kanboard\Auth\ApiAccessTokenAuth;
|
||||||
|
use Kanboard\Model\UserModel;
|
||||||
|
|
||||||
|
require_once __DIR__.'/../Base.php';
|
||||||
|
|
||||||
|
class ApiAccessTokenAuthTest extends Base
|
||||||
|
{
|
||||||
|
public function testGetName()
|
||||||
|
{
|
||||||
|
$provider = new ApiAccessTokenAuth($this->container);
|
||||||
|
$this->assertEquals('API Access Token', $provider->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAuthenticateWithoutToken()
|
||||||
|
{
|
||||||
|
$provider = new ApiAccessTokenAuth($this->container);
|
||||||
|
|
||||||
|
$provider->setUsername('admin');
|
||||||
|
$provider->setPassword('admin');
|
||||||
|
$this->assertFalse($provider->authenticate());
|
||||||
|
$this->assertNull($provider->getUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAuthenticateWithEmptyPassword()
|
||||||
|
{
|
||||||
|
$provider = new ApiAccessTokenAuth($this->container);
|
||||||
|
|
||||||
|
$provider->setUsername('admin');
|
||||||
|
$provider->setPassword('');
|
||||||
|
$this->assertFalse($provider->authenticate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAuthenticateWithTokenAndNoScope()
|
||||||
|
{
|
||||||
|
$provider = new ApiAccessTokenAuth($this->container);
|
||||||
|
$userModel = new UserModel($this->container);
|
||||||
|
|
||||||
|
$userModel->update(array(
|
||||||
|
'id' => 1,
|
||||||
|
'api_access_token' => 'test',
|
||||||
|
));
|
||||||
|
|
||||||
|
$provider->setUsername('admin');
|
||||||
|
$provider->setPassword('test');
|
||||||
|
$this->assertFalse($provider->authenticate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAuthenticateWithToken()
|
||||||
|
{
|
||||||
|
$this->container['sessionStorage']->scope = 'API';
|
||||||
|
|
||||||
|
$provider = new ApiAccessTokenAuth($this->container);
|
||||||
|
$userModel = new UserModel($this->container);
|
||||||
|
|
||||||
|
$userModel->update(array(
|
||||||
|
'id' => 1,
|
||||||
|
'api_access_token' => 'test',
|
||||||
|
));
|
||||||
|
|
||||||
|
$provider->setUsername('admin');
|
||||||
|
$provider->setPassword('test');
|
||||||
|
$this->assertTrue($provider->authenticate());
|
||||||
|
$this->assertInstanceOf('Kanboard\User\DatabaseUserProvider', $provider->getUser());
|
||||||
|
|
||||||
|
$provider->setUsername('admin');
|
||||||
|
$provider->setPassword('something else');
|
||||||
|
$this->assertFalse($provider->authenticate());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue