From efb6a6b457ac8e20bbbb39d8a730921850c2751a Mon Sep 17 00:00:00 2001 From: Dan Brown <ssddanbrown@googlemail.com> Date: Mon, 28 Jun 2021 22:02:45 +0100 Subject: [PATCH] Started barebones work of MFA system --- app/Http/Controllers/Auth/MfaController.php | 29 +++ composer.json | 2 + composer.lock | 221 +++++++++++++++++++- resources/views/mfa/setup.blade.php | 16 ++ routes/web.php | 2 + 5 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/Auth/MfaController.php create mode 100644 resources/views/mfa/setup.blade.php diff --git a/app/Http/Controllers/Auth/MfaController.php b/app/Http/Controllers/Auth/MfaController.php new file mode 100644 index 000000000..1d0dbd1a4 --- /dev/null +++ b/app/Http/Controllers/Auth/MfaController.php @@ -0,0 +1,29 @@ +<?php + +namespace BookStack\Http\Controllers\Auth; + +use BookStack\Http\Controllers\Controller; +use Illuminate\Http\Request; + +class MfaController extends Controller +{ + /** + * Show the view to setup MFA for the current user. + */ + public function setup() + { + // TODO - Redirect back to profile/edit if already setup? + // Show MFA setup route + return view('mfa.setup'); + } + + public function generateQr() + { + // https://github.com/antonioribeiro/google2fa#how-to-generate-and-use-two-factor-authentication + + // Generate secret key + // Store key in session? + // Get user to verify setup via responding once. + // If correct response, Save key against user + } +} diff --git a/composer.json b/composer.json index bbd689454..7362a085d 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "ext-json": "*", "ext-mbstring": "*", "ext-xml": "*", + "bacon/bacon-qr-code": "^2.0", "barryvdh/laravel-dompdf": "^0.9.0", "barryvdh/laravel-snappy": "^0.4.8", "doctrine/dbal": "^2.12.1", @@ -26,6 +27,7 @@ "league/html-to-markdown": "^5.0.0", "nunomaduro/collision": "^3.1", "onelogin/php-saml": "^4.0", + "pragmarx/google2fa": "^8.0", "predis/predis": "^1.1.6", "socialiteproviders/discord": "^4.1", "socialiteproviders/gitlab": "^4.1", diff --git a/composer.lock b/composer.lock index 0647038cc..07c27ea52 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d1109d0dc4a6ab525cdbf64ed21f6dd4", + "content-hash": "4d845f3c8b77c8d73bf92c9223ddd805", "packages": [ { "name": "aws/aws-sdk-php", @@ -96,6 +96,59 @@ }, "time": "2021-06-25T18:19:14+00:00" }, + { + "name": "bacon/bacon-qr-code", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "f73543ac4e1def05f1a70bcd1525c8a157a1ad09" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/f73543ac4e1def05f1a70bcd1525c8a157a1ad09", + "reference": "f73543ac4e1def05f1a70bcd1525c8a157a1ad09", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^1.4", + "phpunit/phpunit": "^7 | ^8 | ^9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.4" + }, + "time": "2021-06-18T13:26:35+00:00" + }, { "name": "barryvdh/laravel-dompdf", "version": "v0.9.0", @@ -227,6 +280,53 @@ }, "time": "2020-09-07T12:33:10+00:00" }, + { + "name": "dasprid/enum", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/5abf82f213618696dda8e3bf6f64dd042d8542b2", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^7 | ^8 | ^9", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.3" + }, + "time": "2020-10-02T16:03:48+00:00" + }, { "name": "doctrine/cache", "version": "2.0.3", @@ -2789,6 +2889,73 @@ }, "time": "2021-04-09T13:42:10+00:00" }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", + "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "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" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2020-12-06T15:14:20+00:00" + }, { "name": "paragonie/random_compat", "version": "v9.99.99", @@ -3095,6 +3262,58 @@ ], "time": "2020-07-20T17:29:33+00:00" }, + { + "name": "pragmarx/google2fa", + "version": "8.0.0", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa.git", + "reference": "26c4c5cf30a2844ba121760fd7301f8ad240100b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/26c4c5cf30a2844ba121760fd7301f8ad240100b", + "reference": "26c4c5cf30a2844ba121760fd7301f8ad240100b", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1.0|^2.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.18", + "phpunit/phpunit": "^7.5.15|^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PragmaRX\\Google2FA\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "A One Time Password Authentication package, compatible with Google Authenticator.", + "keywords": [ + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa/issues", + "source": "https://github.com/antonioribeiro/google2fa/tree/8.0.0" + }, + "time": "2020-04-05T10:47:18+00:00" + }, { "name": "predis/predis", "version": "v1.1.7", diff --git a/resources/views/mfa/setup.blade.php b/resources/views/mfa/setup.blade.php new file mode 100644 index 000000000..25eb5d925 --- /dev/null +++ b/resources/views/mfa/setup.blade.php @@ -0,0 +1,16 @@ +@extends('simple-layout') + +@section('body') + <div class="container small py-xl"> + + <div class="card content-wrap auto-height"> + <h1 class="list-heading">Setup Multi-Factor Authentication</h1> + <p> + Setup multi-factor authentication as an extra layer of security + for your user account. + To use multi-factor authentication you'll need a mobile application + that supports TOTP such as Google Authenticator, Authy or Microsoft Authenticator. + </p> + </div> + </div> +@stop diff --git a/routes/web.php b/routes/web.php index bc9705e10..7807d5477 100644 --- a/routes/web.php +++ b/routes/web.php @@ -223,6 +223,8 @@ Route::group(['middleware' => 'auth'], function () { Route::get('/roles/{id}', 'RoleController@edit'); Route::put('/roles/{id}', 'RoleController@update'); }); + + Route::get('/mfa/setup', 'Auth\MfaController@setup'); }); // Social auth routes