Render QR code for TwoFactor authentication without Google Chart API

This commit is contained in:
Frederic Guillot 2017-03-09 21:24:04 -05:00
parent cbb4d0061e
commit 6d814566fb
7 changed files with 114 additions and 59 deletions

View File

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

View File

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

View File

@ -49,15 +49,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)
*

View File

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

View File

@ -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/"],

113
composer.lock generated
View File

@ -4,9 +4,53 @@
"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",
@ -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",

View File

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