summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2017-03-09 21:24:04 -0500
committerFrederic Guillot <fred@kanboard.net>2017-03-09 21:24:04 -0500
commit6d814566fba8ac45b5cba6993e7b98223b259256 (patch)
tree199e1c456d721c4ca95b95092fbf619497ef073e
parentcbb4d0061e698376d4fbd9a6df95ac14d0733aed (diff)
Render QR code for TwoFactor authentication without Google Chart API
-rw-r--r--ChangeLog5
-rw-r--r--app/Controller/TwoFactorController.php31
-rw-r--r--app/Core/Security/PostAuthenticationProviderInterface.php9
-rw-r--r--app/Template/twofactor/show.php7
-rw-r--r--composer.json3
-rw-r--r--composer.lock113
-rw-r--r--tests/units/Auth/TotpAuthTest.php5
7 files changed, 114 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index a8a69648..92846544 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,11 +7,16 @@ New features:
Improvements:
+* Render QR code for TwoFactor authentication without Google Chart API
* Add toggle button to show/hide subtasks in task list view
* Display tags in task list view
* Change users list layout
* Project priority is always rendered now
+Breaking Changes:
+
+* Remove method getQrCodeUrl() from PostAuthenticationProviderInterface
+
Version 1.0.40 (Feb 24 2017)
----------------------------
diff --git a/app/Controller/TwoFactorController.php b/app/Controller/TwoFactorController.php
index d02c8950..73060c44 100644
--- a/app/Controller/TwoFactorController.php
+++ b/app/Controller/TwoFactorController.php
@@ -3,6 +3,7 @@
namespace Kanboard\Controller;
use Kanboard\Core\Controller\AccessForbiddenException;
+use PHPQRCode;
/**
* Two Factor Auth controller
@@ -65,9 +66,8 @@ class TwoFactorController extends UserViewController
}
$this->response->html($this->helper->layout->user('twofactor/show', array(
- 'user' => $user,
- 'secret' => $this->sessionStorage->twoFactorSecret,
- 'qrcode_url' => $provider->getQrCodeUrl($label),
+ 'user' => $user,
+ 'secret' => $this->sessionStorage->twoFactorSecret,
'key_url' => $provider->getKeyUrl($label),
)));
}
@@ -192,11 +192,28 @@ class TwoFactorController extends UserViewController
'twofactor_secret' => '',
));
- return $this->response->redirect($this->helper->url->to('UserViewController', 'show', array('user_id' => $user['id'])));
+ $this->response->redirect($this->helper->url->to('UserViewController', 'show', array('user_id' => $user['id'])));
+ } else {
+ $this->response->html($this->helper->layout->user('twofactor/disable', array(
+ 'user' => $user,
+ )));
}
+ }
- return $this->response->html($this->helper->layout->user('twofactor/disable', array(
- 'user' => $user,
- )));
+ /**
+ * Render QR Code image
+ */
+ public function qrcode()
+ {
+ if (isset($this->sessionStorage->twoFactorSecret)) {
+ $user = $this->getUser();
+ $provider = $this->authenticationManager->getPostAuthenticationProvider();
+ $provider->setSecret($this->sessionStorage->twoFactorSecret);
+ $url = $provider->getKeyUrl($user['email'] ?: $user['username']);
+
+ if (! empty($url)) {
+ PHPQRCode\QRcode::png($url, false, 'L', 6, 0);
+ }
+ }
}
}
diff --git a/app/Core/Security/PostAuthenticationProviderInterface.php b/app/Core/Security/PostAuthenticationProviderInterface.php
index 3f628bb0..27b7b5cf 100644
--- a/app/Core/Security/PostAuthenticationProviderInterface.php
+++ b/app/Core/Security/PostAuthenticationProviderInterface.php
@@ -50,15 +50,6 @@ interface PostAuthenticationProviderInterface extends AuthenticationProviderInte
public function getSecret();
/**
- * Get QR code url (empty if no QR can be provided)
- *
- * @access public
- * @param string $label
- * @return string
- */
- public function getQrCodeUrl($label);
-
- /**
* Get key url (empty if no url can be provided)
*
* @access public
diff --git a/app/Template/twofactor/show.php b/app/Template/twofactor/show.php
index a5bdeccb..412077b9 100644
--- a/app/Template/twofactor/show.php
+++ b/app/Template/twofactor/show.php
@@ -2,17 +2,14 @@
<h2><?= t('Two factor authentication') ?></h2>
</div>
-<?php if (! empty($secret) || ! empty($qrcode_url) || ! empty($key_url)): ?>
+<?php if (! empty($secret) || ! empty($key_url)): ?>
<div class="panel">
<?php if (! empty($secret)): ?>
<p><?= t('Secret key: ') ?><strong><?= $this->text->e($secret) ?></strong></p>
<?php endif ?>
- <?php if (! empty($qrcode_url)): ?>
- <p><br><img src="<?= $qrcode_url ?>"/><br><br></p>
- <?php endif ?>
-
<?php if (! empty($key_url)): ?>
+ <br><img src="<?= $this->url->href('TwoFactorController', 'qrcode') ?>"><br>
<p><?= t('This QR code contains the key URI: ') ?><a href="<?= $this->text->e($key_url) ?>"><?= $this->text->e($key_url) ?></a></p>
<?php endif ?>
</div>
diff --git a/composer.json b/composer.json
index ca25d3a2..28db1676 100644
--- a/composer.json
+++ b/composer.json
@@ -38,7 +38,8 @@
"swiftmailer/swiftmailer" : "5.4.5",
"symfony/console" : "2.8.7",
"symfony/event-dispatcher" : "2.7.14",
- "gregwar/captcha": "1.1.1"
+ "gregwar/captcha": "1.1.1",
+ "aferrandini/phpqrcode": "1.0.1"
},
"autoload" : {
"classmap" : ["app/"],
diff --git a/composer.lock b/composer.lock
index a327c2aa..9aba396a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,10 +4,54 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "3d24ad1182c0460eda5791bd7fc68984",
- "content-hash": "67d44f262438806c115a362c9912b669",
+ "hash": "9da4e56dd10c23d4c3ea7e4949d18b24",
+ "content-hash": "6fded72f90b9a69e404ea9a2410339ad",
"packages": [
{
+ "name": "aferrandini/phpqrcode",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/aferrandini/PHPQRCode.git",
+ "reference": "3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/aferrandini/PHPQRCode/zipball/3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46",
+ "reference": "3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "PHPQRCode": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ariel Ferrandini",
+ "email": "arielferrandini@gmail.com",
+ "homepage": "http://www.ferrandini.com/",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHPQRCode porting and changed for PHP 5.3 compatibility",
+ "homepage": "https://github.com/aferrandini/PHPQRCode",
+ "keywords": [
+ "barcode",
+ "php",
+ "qrcode"
+ ],
+ "time": "2013-07-08 09:39:08"
+ },
+ {
"name": "christian-riesen/base32",
"version": "1.3.1",
"source": {
@@ -1072,27 +1116,27 @@
},
{
"name": "phpspec/prophecy",
- "version": "v1.6.2",
+ "version": "v1.7.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
+ "reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
- "reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
+ "reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
- "sebastian/comparator": "^1.1",
- "sebastian/recursion-context": "^1.0|^2.0"
+ "sebastian/comparator": "^1.1|^2.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
},
"require-dev": {
- "phpspec/phpspec": "^2.0",
+ "phpspec/phpspec": "^2.5|^3.2",
"phpunit/phpunit": "^4.8 || ^5.6.5"
},
"type": "library",
@@ -1131,7 +1175,7 @@
"spy",
"stub"
],
- "time": "2016-11-21 14:58:47"
+ "time": "2017-03-02 20:05:34"
},
{
"name": "phpunit/php-code-coverage",
@@ -1285,25 +1329,30 @@
},
{
"name": "phpunit/php-timer",
- "version": "1.0.8",
+ "version": "1.0.9",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
- "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": "^5.3.3 || ^7.0"
},
"require-dev": {
- "phpunit/phpunit": "~4|~5"
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
"autoload": {
"classmap": [
"src/"
@@ -1325,20 +1374,20 @@
"keywords": [
"timer"
],
- "time": "2016-05-12 18:03:57"
+ "time": "2017-02-26 11:10:40"
},
{
"name": "phpunit/php-token-stream",
- "version": "1.4.9",
+ "version": "1.4.11",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b"
+ "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b",
- "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
+ "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
"shasum": ""
},
"require": {
@@ -1374,7 +1423,7 @@
"keywords": [
"tokenizer"
],
- "time": "2016-11-15 14:06:22"
+ "time": "2017-02-27 10:12:30"
},
{
"name": "phpunit/phpunit",
@@ -1570,16 +1619,16 @@
},
{
"name": "sebastian/comparator",
- "version": "1.2.2",
+ "version": "1.2.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f"
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
- "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
"shasum": ""
},
"require": {
@@ -1630,7 +1679,7 @@
"compare",
"equality"
],
- "time": "2016-11-19 09:18:40"
+ "time": "2017-01-29 09:50:25"
},
{
"name": "sebastian/diff",
@@ -1854,16 +1903,16 @@
},
{
"name": "sebastian/recursion-context",
- "version": "1.0.2",
+ "version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
- "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
"shasum": ""
},
"require": {
@@ -1903,7 +1952,7 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2015-11-11 19:50:13"
+ "time": "2016-10-03 07:41:43"
},
{
"name": "sebastian/version",
diff --git a/tests/units/Auth/TotpAuthTest.php b/tests/units/Auth/TotpAuthTest.php
index 3a82c01c..d799259b 100644
--- a/tests/units/Auth/TotpAuthTest.php
+++ b/tests/units/Auth/TotpAuthTest.php
@@ -40,11 +40,6 @@ class TotpAuthTest extends Base
$this->assertEmpty($provider->getKeyUrl('me'));
$provider->setSecret('mySecret');
- $this->assertEquals(
- 'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=M|0&chl=otpauth%3A%2F%2Ftotp%2Fme%3Fsecret%3DmySecret%26issuer%3DKanboard',
- $provider->getQrCodeUrl('me')
- );
-
$this->assertEquals('otpauth://totp/me?secret=mySecret&issuer=Kanboard', $provider->getKeyUrl('me'));
}