mirror of
https://github.com/Bubka/2FAuth.git
synced 2024-11-25 09:44:04 +01:00
TOTP integration
This commit is contained in:
parent
482c01ca2c
commit
6a76a493a2
@ -3,7 +3,10 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\TwoFAccount;
|
use App\TwoFAccount;
|
||||||
|
use OTPHP\TOTP;
|
||||||
|
use OTPHP\Factory;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use ParagonIE\ConstantTime\Base32;
|
||||||
|
|
||||||
class TwoFAccountController extends Controller
|
class TwoFAccountController extends Controller
|
||||||
{
|
{
|
||||||
@ -47,6 +50,29 @@ public function show(TwoFAccount $twofaccount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a TOTP
|
||||||
|
*
|
||||||
|
* @param \App\TwoFAccount $twofaccount
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function generateTOTP(TwoFAccount $twofaccount)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$otp = Factory::loadFromProvisioningUri($twofaccount->secret);
|
||||||
|
} catch (InvalidArgumentException $exception) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Error generating TOTP',
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'totp' => $otp->now(),
|
||||||
|
], 200);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the specified resource in storage.
|
* Update the specified resource in storage.
|
||||||
*
|
*
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
"fideloper/proxy": "^4.0",
|
"fideloper/proxy": "^4.0",
|
||||||
"laravel/framework": "5.8.*",
|
"laravel/framework": "5.8.*",
|
||||||
"laravel/passport": "^7.2",
|
"laravel/passport": "^7.2",
|
||||||
"laravel/tinker": "^1.0"
|
"laravel/tinker": "^1.0",
|
||||||
|
"spomky-labs/otphp": "^10.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"beyondcode/laravel-dump-server": "^1.0",
|
"beyondcode/laravel-dump-server": "^1.0",
|
||||||
|
322
composer.lock
generated
322
composer.lock
generated
@ -4,8 +4,63 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "dea87dd5fa06feeb9038c216bb7cca08",
|
"content-hash": "e2586083343555a07abbaad764ae5305",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "beberlei/assert",
|
||||||
|
"version": "v3.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/beberlei/assert.git",
|
||||||
|
"reference": "fd82f4c8592c8128dd74481034c31da71ebafc56"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/beberlei/assert/zipball/fd82f4c8592c8128dd74481034c31da71ebafc56",
|
||||||
|
"reference": "fd82f4c8592c8128dd74481034c31da71ebafc56",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "*",
|
||||||
|
"phpstan/phpstan-shim": "*",
|
||||||
|
"phpunit/phpunit": "*"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Assert\\": "lib/Assert"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"lib/Assert/functions.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-2-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de",
|
||||||
|
"role": "Lead Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Richard Quadling",
|
||||||
|
"email": "rquadling@gmail.com",
|
||||||
|
"role": "Collaborator"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Thin assertion library for input validation in business models.",
|
||||||
|
"keywords": [
|
||||||
|
"assert",
|
||||||
|
"assertion",
|
||||||
|
"validation"
|
||||||
|
],
|
||||||
|
"time": "2018-12-24T15:25:25+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "defuse/php-encryption",
|
"name": "defuse/php-encryption",
|
||||||
"version": "v2.2.1",
|
"version": "v2.2.1",
|
||||||
@ -1550,6 +1605,68 @@
|
|||||||
],
|
],
|
||||||
"time": "2019-05-05T12:50:25+00:00"
|
"time": "2019-05-05T12:50:25+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "paragonie/constant_time_encoding",
|
||||||
|
"version": "v2.2.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/paragonie/constant_time_encoding.git",
|
||||||
|
"reference": "55af0dc01992b4d0da7f6372e2eac097bbbaffdb"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/55af0dc01992b4d0da7f6372e2eac097bbbaffdb",
|
||||||
|
"reference": "55af0dc01992b4d0da7f6372e2eac097bbbaffdb",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^6|^7",
|
||||||
|
"vimeo/psalm": "^1|^2"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"ParagonIE\\ConstantTime\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Paragon Initiative Enterprises",
|
||||||
|
"email": "security@paragonie.com",
|
||||||
|
"homepage": "https://paragonie.com",
|
||||||
|
"role": "Maintainer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Steve 'Sc00bz' Thomas",
|
||||||
|
"email": "steve@tobtu.com",
|
||||||
|
"homepage": "https://www.tobtu.com",
|
||||||
|
"role": "Original Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
|
||||||
|
"keywords": [
|
||||||
|
"base16",
|
||||||
|
"base32",
|
||||||
|
"base32_decode",
|
||||||
|
"base32_encode",
|
||||||
|
"base64",
|
||||||
|
"base64_decode",
|
||||||
|
"base64_encode",
|
||||||
|
"bin2hex",
|
||||||
|
"encoding",
|
||||||
|
"hex",
|
||||||
|
"hex2bin",
|
||||||
|
"rfc4648"
|
||||||
|
],
|
||||||
|
"time": "2019-01-03T20:26:31+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "paragonie/random_compat",
|
"name": "paragonie/random_compat",
|
||||||
"version": "v9.99.99",
|
"version": "v9.99.99",
|
||||||
@ -2179,6 +2296,77 @@
|
|||||||
],
|
],
|
||||||
"time": "2018-07-19T23:38:55+00:00"
|
"time": "2018-07-19T23:38:55+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "spomky-labs/otphp",
|
||||||
|
"version": "v10.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Spomky-Labs/otphp.git",
|
||||||
|
"reference": "3ff28fc30efdedacf1bc99e66232225a9354dbba"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/3ff28fc30efdedacf1bc99e66232225a9354dbba",
|
||||||
|
"reference": "3ff28fc30efdedacf1bc99e66232225a9354dbba",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"beberlei/assert": "^3.0",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"paragonie/constant_time_encoding": "^2.0",
|
||||||
|
"php": "^7.2|^8.0",
|
||||||
|
"thecodingmachine/safe": "^0.1.14"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"php-coveralls/php-coveralls": "^2.0",
|
||||||
|
"phpstan/phpstan": "^0.11",
|
||||||
|
"phpstan/phpstan-beberlei-assert": "^0.11.0",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^0.11",
|
||||||
|
"phpstan/phpstan-phpunit": "^0.11",
|
||||||
|
"phpstan/phpstan-strict-rules": "^0.11",
|
||||||
|
"phpunit/phpunit": "^8.0",
|
||||||
|
"thecodingmachine/phpstan-safe-rule": "^0.1.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"v10.0": "10.0.x-dev",
|
||||||
|
"v9.0": "9.0.x-dev",
|
||||||
|
"v8.3": "8.3.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"OTPHP\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Florent Morselli",
|
||||||
|
"homepage": "https://github.com/Spomky"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "All contributors",
|
||||||
|
"homepage": "https://github.com/Spomky-Labs/otphp/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator",
|
||||||
|
"homepage": "https://github.com/Spomky-Labs/otphp",
|
||||||
|
"keywords": [
|
||||||
|
"FreeOTP",
|
||||||
|
"RFC 4226",
|
||||||
|
"RFC 6238",
|
||||||
|
"google authenticator",
|
||||||
|
"hotp",
|
||||||
|
"otp",
|
||||||
|
"totp"
|
||||||
|
],
|
||||||
|
"time": "2019-05-07T21:08:23+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "swiftmailer/swiftmailer",
|
"name": "swiftmailer/swiftmailer",
|
||||||
"version": "v6.2.1",
|
"version": "v6.2.1",
|
||||||
@ -3383,6 +3571,138 @@
|
|||||||
],
|
],
|
||||||
"time": "2019-05-01T12:55:36+00:00"
|
"time": "2019-05-01T12:55:36+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "thecodingmachine/safe",
|
||||||
|
"version": "v0.1.15",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/thecodingmachine/safe.git",
|
||||||
|
"reference": "9a4dbc54e397e0bfb152f4b38f8a03040a1e9e3e"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/thecodingmachine/safe/zipball/9a4dbc54e397e0bfb152f4b38f8a03040a1e9e3e",
|
||||||
|
"reference": "9a4dbc54e397e0bfb152f4b38f8a03040a1e9e3e",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpstan/phpstan": "^0.10.3",
|
||||||
|
"squizlabs/php_codesniffer": "^3.2",
|
||||||
|
"thecodingmachine/phpstan-strict-rules": "^0.10.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "0.1-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Safe\\": [
|
||||||
|
"lib/",
|
||||||
|
"generated/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"generated/apache.php",
|
||||||
|
"generated/apc.php",
|
||||||
|
"generated/apcu.php",
|
||||||
|
"generated/array.php",
|
||||||
|
"generated/bzip2.php",
|
||||||
|
"generated/classobj.php",
|
||||||
|
"generated/com.php",
|
||||||
|
"generated/cubrid.php",
|
||||||
|
"generated/curl.php",
|
||||||
|
"generated/datetime.php",
|
||||||
|
"generated/dir.php",
|
||||||
|
"generated/eio.php",
|
||||||
|
"generated/errorfunc.php",
|
||||||
|
"generated/exec.php",
|
||||||
|
"generated/fileinfo.php",
|
||||||
|
"generated/filesystem.php",
|
||||||
|
"generated/filter.php",
|
||||||
|
"generated/fpm.php",
|
||||||
|
"generated/ftp.php",
|
||||||
|
"generated/funchand.php",
|
||||||
|
"generated/gmp.php",
|
||||||
|
"generated/gnupg.php",
|
||||||
|
"generated/hash.php",
|
||||||
|
"generated/ibase.php",
|
||||||
|
"generated/ibmDb2.php",
|
||||||
|
"generated/iconv.php",
|
||||||
|
"generated/image.php",
|
||||||
|
"generated/imap.php",
|
||||||
|
"generated/info.php",
|
||||||
|
"generated/ingres-ii.php",
|
||||||
|
"generated/inotify.php",
|
||||||
|
"generated/json.php",
|
||||||
|
"generated/ldap.php",
|
||||||
|
"generated/libevent.php",
|
||||||
|
"generated/libxml.php",
|
||||||
|
"generated/lzf.php",
|
||||||
|
"generated/mailparse.php",
|
||||||
|
"generated/mbstring.php",
|
||||||
|
"generated/misc.php",
|
||||||
|
"generated/msql.php",
|
||||||
|
"generated/mssql.php",
|
||||||
|
"generated/mysql.php",
|
||||||
|
"generated/mysqli.php",
|
||||||
|
"generated/mysqlndMs.php",
|
||||||
|
"generated/mysqlndQc.php",
|
||||||
|
"generated/network.php",
|
||||||
|
"generated/oci8.php",
|
||||||
|
"generated/opcache.php",
|
||||||
|
"generated/openssl.php",
|
||||||
|
"generated/outcontrol.php",
|
||||||
|
"generated/password.php",
|
||||||
|
"generated/pcntl.php",
|
||||||
|
"generated/pcre.php",
|
||||||
|
"generated/pdf.php",
|
||||||
|
"generated/pgsql.php",
|
||||||
|
"generated/posix.php",
|
||||||
|
"generated/ps.php",
|
||||||
|
"generated/pspell.php",
|
||||||
|
"generated/readline.php",
|
||||||
|
"generated/rrd.php",
|
||||||
|
"generated/sem.php",
|
||||||
|
"generated/session.php",
|
||||||
|
"generated/shmop.php",
|
||||||
|
"generated/simplexml.php",
|
||||||
|
"generated/sockets.php",
|
||||||
|
"generated/sodium.php",
|
||||||
|
"generated/solr.php",
|
||||||
|
"generated/spl.php",
|
||||||
|
"generated/sqlsrv.php",
|
||||||
|
"generated/ssdeep.php",
|
||||||
|
"generated/ssh2.php",
|
||||||
|
"generated/stats.php",
|
||||||
|
"generated/stream.php",
|
||||||
|
"generated/strings.php",
|
||||||
|
"generated/swoole.php",
|
||||||
|
"generated/uodbc.php",
|
||||||
|
"generated/uopz.php",
|
||||||
|
"generated/url.php",
|
||||||
|
"generated/var.php",
|
||||||
|
"generated/xdiff.php",
|
||||||
|
"generated/xml.php",
|
||||||
|
"generated/xmlrpc.php",
|
||||||
|
"generated/yaml.php",
|
||||||
|
"generated/yaz.php",
|
||||||
|
"generated/zip.php",
|
||||||
|
"generated/zlib.php",
|
||||||
|
"lib/special_cases.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"description": "PHP core functions that throw exceptions instead of returning FALSE on error",
|
||||||
|
"time": "2019-04-17T16:09:50+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "tijsverkoyen/css-to-inline-styles",
|
"name": "tijsverkoyen/css-to-inline-styles",
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
|
@ -17,7 +17,7 @@ public function run()
|
|||||||
|
|
||||||
TwoFAccount::create([
|
TwoFAccount::create([
|
||||||
'name' => $faker->unique()->domainName,
|
'name' => $faker->unique()->domainName,
|
||||||
'secret' => $faker->password,
|
'secret' => 'otpauth://totp/test@test.com?secret=A4GRFHVVRBGY7UIW&issuer=test',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$deletedResource = TwoFAccount::create([
|
$deletedResource = TwoFAccount::create([
|
||||||
|
@ -22,5 +22,6 @@
|
|||||||
|
|
||||||
Route::group(['middleware' => 'auth:api'], function(){
|
Route::group(['middleware' => 'auth:api'], function(){
|
||||||
Route::apiResource('twofaccounts', 'TwoFAccountController');
|
Route::apiResource('twofaccounts', 'TwoFAccountController');
|
||||||
|
Route::get('twofaccounts/{twofaccount}/totp', 'TwoFAccountController@generateTOTP')->name('twofaccounts.generateTOTP');
|
||||||
Route::delete('twofaccounts/force/{id}', 'TwoFAccountController@forceDestroy')->name('twofaccounts.forceDestroy');
|
Route::delete('twofaccounts/force/{id}', 'TwoFAccountController@forceDestroy')->name('twofaccounts.forceDestroy');
|
||||||
});
|
});
|
@ -36,8 +36,6 @@ public function setUp(): void
|
|||||||
*/
|
*/
|
||||||
public function testTwoFAccountCreation()
|
public function testTwoFAccountCreation()
|
||||||
{
|
{
|
||||||
//$this->withoutMiddleware();
|
|
||||||
|
|
||||||
$user = \App\User::find(1);
|
$user = \App\User::find(1);
|
||||||
|
|
||||||
$response = $this->actingAs($user, 'api')
|
$response = $this->actingAs($user, 'api')
|
||||||
@ -53,6 +51,29 @@ public function testTwoFAccountCreation()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test TOTP generation via API
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testTOTPgeneration()
|
||||||
|
{
|
||||||
|
$user = \App\User::find(1);
|
||||||
|
|
||||||
|
$twofaccount = TwoFAccount::create([
|
||||||
|
'name' => 'testTOTP',
|
||||||
|
'secret' => 'otpauth://totp/test@test.com?secret=A4GRFHVVRBGY7UIW&issuer=test'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->actingAs($user, 'api')
|
||||||
|
->json('POST', '/api/twofaccounts/' . $twofaccount->id . '/totp')
|
||||||
|
->assertStatus(200)
|
||||||
|
->assertJsonStructure([
|
||||||
|
'totp',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test TwoFAccount update via API
|
* test TwoFAccount update via API
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user