summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Api/Middleware/AuthenticationMiddleware.php1
-rw-r--r--app/Auth/ApiAccessTokenAuth.php119
-rw-r--r--app/Auth/DatabaseAuth.php2
-rw-r--r--app/Auth/LdapAuth.php2
-rw-r--r--app/Auth/RememberMeAuth.php4
-rw-r--r--app/Auth/ReverseProxyAuth.php2
-rw-r--r--app/Auth/TotpAuth.php2
-rw-r--r--app/Controller/UserApiAccessController.php50
-rw-r--r--app/Core/Session/SessionStorage.php1
-rw-r--r--app/Locale/bs_BA/translations.php9
-rw-r--r--app/Locale/cs_CZ/translations.php9
-rw-r--r--app/Locale/da_DK/translations.php9
-rw-r--r--app/Locale/de_DE/translations.php9
-rw-r--r--app/Locale/el_GR/translations.php9
-rw-r--r--app/Locale/es_ES/translations.php9
-rw-r--r--app/Locale/fi_FI/translations.php9
-rw-r--r--app/Locale/fr_FR/translations.php9
-rw-r--r--app/Locale/hu_HU/translations.php9
-rw-r--r--app/Locale/id_ID/translations.php9
-rw-r--r--app/Locale/it_IT/translations.php9
-rw-r--r--app/Locale/ja_JP/translations.php9
-rw-r--r--app/Locale/ko_KR/translations.php9
-rw-r--r--app/Locale/my_MY/translations.php9
-rw-r--r--app/Locale/nb_NO/translations.php9
-rw-r--r--app/Locale/nl_NL/translations.php9
-rw-r--r--app/Locale/pl_PL/translations.php9
-rw-r--r--app/Locale/pt_BR/translations.php9
-rw-r--r--app/Locale/pt_PT/translations.php9
-rw-r--r--app/Locale/ru_RU/translations.php9
-rw-r--r--app/Locale/sr_Latn_RS/translations.php9
-rw-r--r--app/Locale/sv_SE/translations.php9
-rw-r--r--app/Locale/th_TH/translations.php9
-rw-r--r--app/Locale/tr_TR/translations.php9
-rw-r--r--app/Locale/zh_CN/translations.php9
-rw-r--r--app/Schema/Mysql.php7
-rw-r--r--app/Schema/Postgres.php7
-rw-r--r--app/Schema/Sql/mysql.sql5
-rw-r--r--app/Schema/Sql/postgres.sql9
-rw-r--r--app/Schema/Sqlite.php7
-rw-r--r--app/ServiceProvider/AuthenticationProvider.php3
-rw-r--r--app/ServiceProvider/RouteProvider.php1
-rw-r--r--app/Template/user_api_access/show.php17
-rw-r--r--app/Template/user_view/sidebar.php5
43 files changed, 454 insertions, 15 deletions
diff --git a/app/Api/Middleware/AuthenticationMiddleware.php b/app/Api/Middleware/AuthenticationMiddleware.php
index 8e309593..c4fa874a 100644
--- a/app/Api/Middleware/AuthenticationMiddleware.php
+++ b/app/Api/Middleware/AuthenticationMiddleware.php
@@ -28,6 +28,7 @@ class AuthenticationMiddleware extends Base implements MiddlewareInterface
public function execute($username, $password, $procedureName)
{
$this->dispatcher->dispatch('app.bootstrap');
+ $this->sessionStorage->scope = 'API';
if ($this->isUserAuthenticated($username, $password)) {
$this->userSession->initialize($this->userModel->getByUsername($username));
diff --git a/app/Auth/ApiAccessTokenAuth.php b/app/Auth/ApiAccessTokenAuth.php
new file mode 100644
index 00000000..12ab21a7
--- /dev/null
+++ b/app/Auth/ApiAccessTokenAuth.php
@@ -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;
+ }
+}
diff --git a/app/Auth/DatabaseAuth.php b/app/Auth/DatabaseAuth.php
index ecb42c17..84a1e019 100644
--- a/app/Auth/DatabaseAuth.php
+++ b/app/Auth/DatabaseAuth.php
@@ -11,7 +11,7 @@ use Kanboard\User\DatabaseUserProvider;
/**
* Database Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class DatabaseAuth extends Base implements PasswordAuthenticationProviderInterface, SessionCheckProviderInterface
diff --git a/app/Auth/LdapAuth.php b/app/Auth/LdapAuth.php
index a8dcfcb6..05ffbebf 100644
--- a/app/Auth/LdapAuth.php
+++ b/app/Auth/LdapAuth.php
@@ -12,7 +12,7 @@ use Kanboard\Core\Security\PasswordAuthenticationProviderInterface;
/**
* LDAP Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class LdapAuth extends Base implements PasswordAuthenticationProviderInterface
diff --git a/app/Auth/RememberMeAuth.php b/app/Auth/RememberMeAuth.php
index 5d0a8b2e..e0f4ceb6 100644
--- a/app/Auth/RememberMeAuth.php
+++ b/app/Auth/RememberMeAuth.php
@@ -7,9 +7,9 @@ use Kanboard\Core\Security\PreAuthenticationProviderInterface;
use Kanboard\User\DatabaseUserProvider;
/**
- * Rember Me Cookie Authentication Provider
+ * RememberMe Cookie Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class RememberMeAuth extends Base implements PreAuthenticationProviderInterface
diff --git a/app/Auth/ReverseProxyAuth.php b/app/Auth/ReverseProxyAuth.php
index fdf936b1..02afc302 100644
--- a/app/Auth/ReverseProxyAuth.php
+++ b/app/Auth/ReverseProxyAuth.php
@@ -10,7 +10,7 @@ use Kanboard\User\ReverseProxyUserProvider;
/**
* Reverse-Proxy Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class ReverseProxyAuth extends Base implements PreAuthenticationProviderInterface, SessionCheckProviderInterface
diff --git a/app/Auth/TotpAuth.php b/app/Auth/TotpAuth.php
index 8e1ebe35..abfb2168 100644
--- a/app/Auth/TotpAuth.php
+++ b/app/Auth/TotpAuth.php
@@ -11,7 +11,7 @@ use Kanboard\Core\Security\PostAuthenticationProviderInterface;
/**
* TOTP Authentication Provider
*
- * @package auth
+ * @package Kanboard\Auth
* @author Frederic Guillot
*/
class TotpAuth extends Base implements PostAuthenticationProviderInterface
diff --git a/app/Controller/UserApiAccessController.php b/app/Controller/UserApiAccessController.php
new file mode 100644
index 00000000..e03514d5
--- /dev/null
+++ b/app/Controller/UserApiAccessController.php
@@ -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'])));
+ }
+} \ No newline at end of file
diff --git a/app/Core/Session/SessionStorage.php b/app/Core/Session/SessionStorage.php
index 9e93602c..e6478d8d 100644
--- a/app/Core/Session/SessionStorage.php
+++ b/app/Core/Session/SessionStorage.php
@@ -19,6 +19,7 @@ namespace Kanboard\Core\Session;
* @property bool $hasSubtaskInProgress
* @property bool $hasRememberMe
* @property bool $boardCollapsed
+ * @property string $scope
* @property bool $twoFactorBeforeCodeCalled
* @property string $twoFactorSecret
* @property string $oauthState
diff --git a/app/Locale/bs_BA/translations.php b/app/Locale/bs_BA/translations.php
index cb9ad9d5..e27a4501 100644
--- a/app/Locale/bs_BA/translations.php
+++ b/app/Locale/bs_BA/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/cs_CZ/translations.php b/app/Locale/cs_CZ/translations.php
index 8541f303..5091de00 100644
--- a/app/Locale/cs_CZ/translations.php
+++ b/app/Locale/cs_CZ/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index 78a6d35e..2ca864e5 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index 433b7a2f..950a3b77 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -1278,4 +1278,13 @@ return array(
'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',
'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' => '',
);
diff --git a/app/Locale/el_GR/translations.php b/app/Locale/el_GR/translations.php
index ad17b4ed..7b7d855e 100644
--- a/app/Locale/el_GR/translations.php
+++ b/app/Locale/el_GR/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index b3a68751..984d42db 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index 733625b6..41e51fa1 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index 59f4609e..daac98ed 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -1279,4 +1279,13 @@ return array(
'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',
'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',
);
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index b5a23428..784c27ba 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/id_ID/translations.php b/app/Locale/id_ID/translations.php
index e711a512..9398d51d 100644
--- a/app/Locale/id_ID/translations.php
+++ b/app/Locale/id_ID/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index 3e27120b..65defe86 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -1278,4 +1278,13 @@ return array(
'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',
'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' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index b9feed07..d0487fb7 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/ko_KR/translations.php b/app/Locale/ko_KR/translations.php
index 8c882b8a..a613b467 100644
--- a/app/Locale/ko_KR/translations.php
+++ b/app/Locale/ko_KR/translations.php
@@ -1278,4 +1278,13 @@ return array(
'Moving a task is not permitted' => '할일 이동이 거부되었습니다.',
'This value must be in the range %d to %d' => '값의 범위는 %d 부터 %d 까지 입니다.',
'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' => '',
);
diff --git a/app/Locale/my_MY/translations.php b/app/Locale/my_MY/translations.php
index 048d8b4b..be335dec 100644
--- a/app/Locale/my_MY/translations.php
+++ b/app/Locale/my_MY/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/nb_NO/translations.php b/app/Locale/nb_NO/translations.php
index 0d2a340d..6b49545c 100644
--- a/app/Locale/nb_NO/translations.php
+++ b/app/Locale/nb_NO/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php
index e1745c14..44434a4e 100644
--- a/app/Locale/nl_NL/translations.php
+++ b/app/Locale/nl_NL/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index 164abe0c..51c0fef8 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index 637de30e..c0fa2387 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -1278,4 +1278,13 @@ return array(
'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',
// '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' => '',
);
diff --git a/app/Locale/pt_PT/translations.php b/app/Locale/pt_PT/translations.php
index 3b8975d9..47763d30 100644
--- a/app/Locale/pt_PT/translations.php
+++ b/app/Locale/pt_PT/translations.php
@@ -1278,4 +1278,13 @@ return array(
'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',
'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' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index 1e5c02c2..4d821f6a 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -1278,4 +1278,13 @@ return array(
'Moving a task is not permitted' => 'Перемещение задачи не разрешено',
'This value must be in the range %d to %d' => 'Значение должно находиться в диапазоне от %d до %d',
// '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' => '',
);
diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php
index 2f061260..470e3390 100644
--- a/app/Locale/sr_Latn_RS/translations.php
+++ b/app/Locale/sr_Latn_RS/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index f32728e7..2ec4fa82 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index 4025714a..5e0912fc 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -1278,4 +1278,13 @@ return array(
// 'Moving a task is not permitted' => '',
// 'This value must be in the range %d to %d' => '',
// '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' => '',
);
diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php
index 24399891..1a648bbf 100644
--- a/app/Locale/tr_TR/translations.php
+++ b/app/Locale/tr_TR/translations.php
@@ -1278,4 +1278,13 @@ return array(
'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"',
'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' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index e27a8a56..c87adbec 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -1278,4 +1278,13 @@ return array(
'Moving a task is not permitted' => '禁止移动任务',
'This value must be in the range %d to %d' => '输入值必须在%d到%d之间',
'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' => '',
);
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index 17285b12..fac8688a 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -6,7 +6,12 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
-const VERSION = 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)
{
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index 082c31eb..32a7a744 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -6,7 +6,12 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
-const VERSION = 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)
{
diff --git a/app/Schema/Sql/mysql.sql b/app/Schema/Sql/mysql.sql
index b39330e2..0ee88d88 100644
--- a/app/Schema/Sql/mysql.sql
+++ b/app/Schema/Sql/mysql.sql
@@ -715,6 +715,7 @@ CREATE TABLE `users` (
`role` varchar(25) NOT NULL DEFAULT 'app-user',
`is_active` tinyint(1) DEFAULT '1',
`avatar_path` varchar(255) DEFAULT NULL,
+ `api_access_token` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_username_idx` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -738,7 +739,7 @@ CREATE TABLE `users` (
LOCK TABLES `settings` WRITE;
/*!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 */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@@ -767,4 +768,4 @@ UNLOCK TABLES;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!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');
diff --git a/app/Schema/Sql/postgres.sql b/app/Schema/Sql/postgres.sql
index 024c5cda..7a93b9f1 100644
--- a/app/Schema/Sql/postgres.sql
+++ b/app/Schema/Sql/postgres.sql
@@ -1245,7 +1245,8 @@ CREATE TABLE "users" (
"gitlab_id" integer,
"role" character varying(25) DEFAULT 'app-user'::character varying NOT NULL,
"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_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 ('webhook_token', 'c12181512f9cfd66a6b2af4edf199390b922bbb8a259dc5397c2329ed47c', 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 ('webhook_token', '8687190194e06d34c2cd84a57b36f67696c971c2f8e453f96e59eccb8e73', 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_timezone', 'UTC', 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
--
-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');
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index edf6ce63..11dcd537 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -6,7 +6,12 @@ use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
use PDO;
-const VERSION = 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)
{
diff --git a/app/ServiceProvider/AuthenticationProvider.php b/app/ServiceProvider/AuthenticationProvider.php
index adff1e63..c2dad0e6 100644
--- a/app/ServiceProvider/AuthenticationProvider.php
+++ b/app/ServiceProvider/AuthenticationProvider.php
@@ -2,6 +2,7 @@
namespace Kanboard\ServiceProvider;
+use Kanboard\Auth\ApiAccessTokenAuth;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Kanboard\Core\Security\AuthenticationManager;
@@ -44,6 +45,8 @@ class AuthenticationProvider implements ServiceProviderInterface
$container['authenticationManager']->register(new LdapAuth($container));
}
+ $container['authenticationManager']->register(new ApiAccessTokenAuth($container));
+
$container['projectAccessMap'] = $this->getProjectAccessMap();
$container['applicationAccessMap'] = $this->getApplicationAccessMap();
$container['apiAccessMap'] = $this->getApiAccessMap();
diff --git a/app/ServiceProvider/RouteProvider.php b/app/ServiceProvider/RouteProvider.php
index 0d1a7931..52687647 100644
--- a/app/ServiceProvider/RouteProvider.php
+++ b/app/ServiceProvider/RouteProvider.php
@@ -158,6 +158,7 @@ class RouteProvider implements ServiceProviderInterface
$container['route']->addRoute('user/:user_id/authentication', 'UserCredentialController', 'changeAuthentication');
$container['route']->addRoute('user/:user_id/2fa', 'TwoFactorController', 'index');
$container['route']->addRoute('user/:user_id/avatar', 'AvatarFileController', 'show');
+ $container['route']->addRoute('user/:user_id/api', 'UserApiAccessController', 'show');
// Groups
$container['route']->addRoute('groups', 'GroupListController', 'index');
diff --git a/app/Template/user_api_access/show.php b/app/Template/user_api_access/show.php
new file mode 100644
index 00000000..3d58e0d5
--- /dev/null
+++ b/app/Template/user_api_access/show.php
@@ -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') ?>
diff --git a/app/Template/user_view/sidebar.php b/app/Template/user_view/sidebar.php
index a80daefa..ef494e42 100644
--- a/app/Template/user_view/sidebar.php
+++ b/app/Template/user_view/sidebar.php
@@ -90,6 +90,11 @@
<?= $this->url->link(t('Integrations'), 'UserViewController', 'integrations', array('user_id' => $user['id'])) ?>
</li>
<?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 if ($this->user->hasAccess('UserCredentialController', 'changeAuthentication')): ?>