Родитель
f17c4dbc97
Коммит
2af718fd54
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"require": {
|
||||
"christian-riesen/otp": "1.*"
|
||||
"christian-riesen/otp": "1.*",
|
||||
"endroid/qrcode": "^1.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "67d801295df32f7541a878252e8a72d7",
|
||||
"content-hash": "3ecd28d69556d0f4621b7b7bb4f96bb6",
|
||||
"hash": "544fb333da3676eccc95c69b5417a2cf",
|
||||
"content-hash": "0b92e480772ba07f8827be4e0efd1c94",
|
||||
"packages": [
|
||||
{
|
||||
"name": "christian-riesen/base32",
|
||||
|
@ -111,6 +111,111 @@
|
|||
"totp"
|
||||
],
|
||||
"time": "2015-10-08 08:17:59"
|
||||
},
|
||||
{
|
||||
"name": "endroid/qrcode",
|
||||
"version": "1.7.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/endroid/QrCode.git",
|
||||
"reference": "4638f11b6944cccce997db7fa7508b5a7ad1a61b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/endroid/QrCode/zipball/4638f11b6944cccce997db7fa7508b5a7ad1a61b",
|
||||
"reference": "4638f11b6944cccce997db7fa7508b5a7ad1a61b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"php": ">=5.3.0",
|
||||
"symfony/options-resolver": "^2.3|^3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Endroid\\QrCode\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jeroen van den Enden",
|
||||
"email": "info@endroid.nl",
|
||||
"homepage": "http://endroid.nl/"
|
||||
}
|
||||
],
|
||||
"description": "Endroid QR Code",
|
||||
"homepage": "https://github.com/endroid/QrCode",
|
||||
"keywords": [
|
||||
"code",
|
||||
"endroid",
|
||||
"qr",
|
||||
"qrcode"
|
||||
],
|
||||
"time": "2016-05-31 12:48:19"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "30605874d99af0cde6c41fd39e18546330c38100"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/30605874d99af0cde6c41fd39e18546330c38100",
|
||||
"reference": "30605874d99af0cde6c41fd39e18546330c38100",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\OptionsResolver\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony OptionsResolver Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"config",
|
||||
"configuration",
|
||||
"options"
|
||||
],
|
||||
"time": "2016-05-12 15:59:27"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
|
|
@ -7,14 +7,17 @@
|
|||
OC.Settings.TwoFactorTotp = OC.Settings.TwoFactorTotp || {};
|
||||
|
||||
var TEMPLATE = '<div>'
|
||||
+ '<input type="checkbox" class="checkbox" id="totp-enabled">'
|
||||
+ '<label for="totp-enabled">Enable TOTP</label>'
|
||||
+ ' <input type="checkbox" class="checkbox" id="totp-enabled">'
|
||||
+ ' <label for="totp-enabled">' + t('twofactor_totp', 'Enable TOTP') + '</label>'
|
||||
+ '</div>'
|
||||
+ '{{#if qr}}'
|
||||
+ '{{#if secret}}'
|
||||
+ '<div>'
|
||||
+ ' <span>' + t('twofactor_totp', 'This is your new TOTP secret:') + ' {{secret}}</span>'
|
||||
+ '</div>'
|
||||
+ '<div>'
|
||||
+ '<a href="{{qr}}" target="_blank">Scan QR code with your TOTP app</a><br>'
|
||||
+ '<img src="{{qr}}>'
|
||||
+ '</div>'
|
||||
+ ' <span>' + t('twofactor_totp', 'Scan this QR code with your TOTP app') + '<span><br>'
|
||||
+ ' <img src="{{qr}}">'
|
||||
+ ' </div>'
|
||||
+ '{{/if}}';
|
||||
|
||||
var View = Backbone.View.extend({
|
||||
|
@ -68,7 +71,7 @@
|
|||
var _this = this;
|
||||
$.when(updating).done(function(data) {
|
||||
_this._enabled = data.enabled;
|
||||
_this._showQr(data.qr);
|
||||
_this._showQr(data);
|
||||
_this.$('#totp-enabled').attr('checked', data.enabled);
|
||||
});
|
||||
$.when(updating).always(function () {
|
||||
|
@ -77,9 +80,10 @@
|
|||
this._enabled = enabled;
|
||||
}
|
||||
},
|
||||
_showQr: function(qr) {
|
||||
_showQr: function(data) {
|
||||
this.render({
|
||||
qr: qr
|
||||
secret: data.secret,
|
||||
qr: data.qr
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
namespace OCA\TwoFactor_Totp\Controller;
|
||||
|
||||
use Endroid\QrCode\QrCode;
|
||||
use OCA\TwoFactor_Totp\Service\ITotp;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
|
@ -29,55 +30,61 @@ use OCP\IUserSession;
|
|||
|
||||
class SettingsController extends Controller {
|
||||
|
||||
/** @var ITotp */
|
||||
private $totp;
|
||||
/** @var ITotp */
|
||||
private $totp;
|
||||
|
||||
/** @var IUserSession */
|
||||
private $userSession;
|
||||
/** @var IUserSession */
|
||||
private $userSession;
|
||||
|
||||
/**
|
||||
* @param string $appName
|
||||
* @param IRequest $request
|
||||
* @param IUserSession $userSession
|
||||
* @param ITotp $totp
|
||||
*/
|
||||
public function __construct($appName, IRequest $request, IUserSession $userSession, ITotp $totp) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->userSession = $userSession;
|
||||
$this->totp = $totp;
|
||||
}
|
||||
/**
|
||||
* @param string $appName
|
||||
* @param IRequest $request
|
||||
* @param IUserSession $userSession
|
||||
* @param ITotp $totp
|
||||
*/
|
||||
public function __construct($appName, IRequest $request, IUserSession $userSession, ITotp $totp) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->userSession = $userSession;
|
||||
$this->totp = $totp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @return JSONResponse
|
||||
*/
|
||||
public function state() {
|
||||
$user = $this->userSession->getUser();
|
||||
return [
|
||||
'enabled' => $this->totp->hasSecret($user),
|
||||
];
|
||||
}
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @return JSONResponse
|
||||
*/
|
||||
public function state() {
|
||||
$user = $this->userSession->getUser();
|
||||
return [
|
||||
'enabled' => $this->totp->hasSecret($user),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @param bool $state
|
||||
* @return JSONResponse
|
||||
*/
|
||||
public function enable($state) {
|
||||
$user = $this->userSession->getUser();
|
||||
if ($state) {
|
||||
$qr = $this->totp->createSecret($user);
|
||||
return [
|
||||
'enabled' => true,
|
||||
'qr' => $qr,
|
||||
];
|
||||
}
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @param bool $state
|
||||
* @return JSONResponse
|
||||
*/
|
||||
public function enable($state) {
|
||||
$user = $this->userSession->getUser();
|
||||
if ($state) {
|
||||
$secret = $this->totp->createSecret($user);
|
||||
|
||||
$this->totp->deleteSecret($user);
|
||||
return [
|
||||
'enabled' => false,
|
||||
'qr' => null,
|
||||
];
|
||||
}
|
||||
$qrCode = new QrCode();
|
||||
$qr = $qrCode->setText("otpauth://totp/ownCloud%20TOTP?secret=$secret")
|
||||
->setSize(150)
|
||||
->getDataUri();
|
||||
return [
|
||||
'enabled' => true,
|
||||
'secret' => $secret,
|
||||
'qr' => $qr,
|
||||
];
|
||||
}
|
||||
|
||||
$this->totp->deleteSecret($user);
|
||||
return [
|
||||
'enabled' => false,
|
||||
'qr' => null,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ interface ITotp {
|
|||
|
||||
/**
|
||||
* @param IUser $user
|
||||
* @return string the newly created secret
|
||||
* @throws TotpSecretAlreadySet
|
||||
*/
|
||||
public function createSecret(IUser $user);
|
||||
|
|
|
@ -67,7 +67,7 @@ class Totp implements ITotp {
|
|||
|
||||
$this->secretMapper->insert($dbSecret);
|
||||
|
||||
return GoogleAuthenticator::getQrCodeUrl('totp', 'ownCloud TOTP', $secret);
|
||||
return $secret;
|
||||
}
|
||||
|
||||
public function deleteSecret(IUser $user) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче