-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 12e74ef
Showing
14 changed files
with
519 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/.idea | ||
/vendor | ||
/node_modules | ||
package-lock.json | ||
composer.phar | ||
composer.lock | ||
phpunit.xml | ||
.phpunit.result.cache | ||
.DS_Store | ||
Thumbs.db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"name": "lifeonscreen/nova-google2fa", | ||
"description": "This package provides Google2FA to Laravel Nova.", | ||
"keywords": [ | ||
"laravel", | ||
"nova" | ||
], | ||
"license": "MIT", | ||
"require": { | ||
"php": ">=7.1.0", | ||
"bacon/bacon-qr-code": "^2.0", | ||
"pragmarx/google2fa-laravel": "^0.2.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"Lifeonscreen\\Google2fa\\": "src/" | ||
} | ||
}, | ||
"extra": { | ||
"laravel": { | ||
"providers": [ | ||
"Lifeonscreen\\Google2fa\\ToolServiceProvider" | ||
] | ||
} | ||
}, | ||
"config": { | ||
"sort-packages": true | ||
}, | ||
"minimum-stability": "dev", | ||
"prefer-stable": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?php | ||
|
||
return [ | ||
'models' => [ | ||
'user' => 'App\User', | ||
], | ||
'tables' => [ | ||
'user' => 'users', | ||
], | ||
]; |
41 changes: 41 additions & 0 deletions
41
resources/database/2018_10_15_095425_create_user_2fa_table.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
|
||
use Illuminate\Support\Facades\Schema; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Database\Migrations\Migration; | ||
|
||
class CreateUser2faTable extends Migration | ||
{ | ||
/** | ||
* Run the migrations. | ||
* | ||
* @return void | ||
*/ | ||
public function up() | ||
{ | ||
Schema::create('user_2fa', function (Blueprint $table) { | ||
$table->increments('id'); | ||
$table->unsignedInteger('user_id'); | ||
$table->boolean('google2fa_enable')->default(false); | ||
$table->string('google2fa_secret')->nullable(); | ||
$table->timestamp('created_at') | ||
->default(DB::raw('CURRENT_TIMESTAMP')); | ||
$table->timestamp('updated_at') | ||
->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); | ||
|
||
$table->foreign('user_id') | ||
->references('id') | ||
->on(config('lifeonscreen2fa.tables.user')); | ||
}); | ||
} | ||
|
||
/** | ||
* Reverse the migrations. | ||
* | ||
* @return void | ||
*/ | ||
public function down() | ||
{ | ||
Schema::dropIfExists('user_2fa'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<!DOCTYPE html> | ||
<html lang="en" class="h-full font-sans"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||
<meta name="csrf-token" content="{{ csrf_token() }}"> | ||
|
||
<title>{{ Nova::name() }}</title> | ||
|
||
<!-- Styles --> | ||
<link rel="stylesheet" href="{{ mix('app.css', 'vendor/nova') }}"> | ||
|
||
<style> | ||
body { | ||
font-family: "Montserrat", sans-serif !important; | ||
} | ||
.btn, | ||
.form-input, | ||
.rounded-lg { | ||
border-radius: 0 !important; | ||
} | ||
</style> | ||
</head> | ||
<body class="bg-40 text-black h-full"> | ||
<div class="h-full"> | ||
<div class="px-view py-view mx-auto"> | ||
<div class="mx-auto py-8 max-w-sm text-center text-90"> | ||
@include('nova::partials.logo') | ||
</div> | ||
|
||
<form class="bg-white shadow rounded-lg p-8 max-w-xl mx-auto" method="POST" action="/los/2fa/authenticate"> | ||
<h2 class="p-2">Two Factor Authentication</h2> | ||
|
||
<p class="p-2">Two factor authentication (2FA) strengthens access security by requiring two methods (also | ||
referred to as factors) to | ||
verify your identity. | ||
Two factor authentication protects against phishing, social engineering and password brute force attacks | ||
and secures your logins from attackers | ||
exploiting weak or stolen credentials.</p> | ||
<p class="p-2"><strong>Enter the pin from Google Authenticator Enable 2FA</strong></p> | ||
|
||
<div class="text-center pt-3"> | ||
<div class="mb-6 w-1/2" style="display:inline-block"> | ||
@if (isset($error)) | ||
<p class="text-center font-semibold text-danger my-3"> | ||
{{ $error }} | ||
</p> | ||
@endif | ||
<label class="block font-bold mb-2" for="co">One Time Password</label> | ||
<input class="form-control form-input form-input-bordered w-full" id="secret" type="number" | ||
name="secret" value="" required="required" autofocus=""> | ||
|
||
</div> | ||
<button class="w-1/2 btn btn-default btn-primary hover:bg-primary-dark" type="submit"> | ||
Authenticate | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<!DOCTYPE html> | ||
<html lang="en" class="h-full font-sans"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||
<meta name="csrf-token" content="{{ csrf_token() }}"> | ||
|
||
<title>{{ Nova::name() }}</title> | ||
|
||
<!-- Styles --> | ||
<link rel="stylesheet" href="{{ mix('app.css', 'vendor/nova') }}"> | ||
|
||
<style> | ||
body { | ||
font-family: "Montserrat", sans-serif !important; | ||
} | ||
.btn, | ||
.form-input, | ||
.rounded-lg { | ||
border-radius: 0 !important; | ||
} | ||
</style> | ||
</head> | ||
<body class="bg-40 text-black h-full"> | ||
<div class="h-full"> | ||
<div class="px-view py-view mx-auto"> | ||
<div class="mx-auto py-8 max-w-sm text-center text-90"> | ||
@include('nova::partials.logo') | ||
</div> | ||
|
||
<form class="bg-white shadow rounded-lg p-8 max-w-xl mx-auto" method="POST" action="/los/2fa/confirm"> | ||
<h2 class="p-2">Two Factor Authentication</h2> | ||
|
||
<p class="p-2">Two factor authentication (2FA) strengthens access security by requiring two methods (also | ||
referred | ||
to as factors) to verify your identity. Two factor authentication protects against phishing, social | ||
engineering and password brute force attacks and secures your logins from attackers exploiting weak | ||
or stolen credentials.</p> | ||
<p class="p-2">To Enable Two Factor Authentication on your Account, you need to do following steps</p> | ||
<strong> | ||
<ol> | ||
<li>Verify the OTP from Google Authenticator Mobile App</li> | ||
</ol> | ||
</strong> | ||
<div class="text-center"> | ||
<img src="{{ $google2fa_url }}" alt=""> | ||
</div> | ||
|
||
<div class="text-center"> | ||
<div class="mb-6 w-1/2" style="display:inline-block"> | ||
@if (isset($error)) | ||
<p class="text-center font-semibold text-danger my-3"> | ||
{{ $error }} | ||
</p> | ||
@endif | ||
<label class="block font-bold mb-2" for="co">Secret</label> | ||
<input class="form-control form-input form-input-bordered w-full" id="secret" type="number" | ||
name="secret" value="" required="required" autofocus=""> | ||
</div> | ||
|
||
|
||
<button class="w-1/2 btn btn-default btn-primary hover:bg-primary-dark" type="submit"> | ||
Confirm | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
use Illuminate\Support\Facades\Route; | ||
|
||
/** | ||
* This route is called when user must first time confirm secret | ||
*/ | ||
Route::post('confirm', 'Lifeonscreen\Google2fa\Google2fa@confirm'); | ||
|
||
/** | ||
* This route is called to verify users secret | ||
*/ | ||
Route::post('authenticate', 'Lifeonscreen\Google2fa\Google2fa@authenticate'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
namespace Lifeonscreen\Google2fa; | ||
|
||
use App\Exceptions\ValidationException; | ||
use PragmaRX\Google2FALaravel\Support\Authenticator; | ||
|
||
/** | ||
* Class Google2FAAuthenticator | ||
* @package Lifeonscreen\Google2fa | ||
*/ | ||
class Google2FAAuthenticator extends Authenticator | ||
{ | ||
protected function canPassWithoutCheckingOTP() | ||
{ | ||
return | ||
!$this->isEnabled() || | ||
$this->noUserIsAuthenticated() || | ||
$this->twoFactorAuthStillValid(); | ||
} | ||
|
||
/** | ||
* @return mixed | ||
* @throws ValidationException | ||
*/ | ||
protected function getGoogle2FASecretKey() | ||
{ | ||
$secret = $this->getUser()->user2fa->{$this->config('otp_secret_column')}; | ||
if (is_null($secret) || empty($secret)) { | ||
throw new ValidationException('Secret key cannot be empty.'); | ||
} | ||
|
||
return $secret; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php | ||
|
||
namespace Lifeonscreen\Google2fa; | ||
|
||
use Laravel\Nova\Tool; | ||
use PragmaRX\Google2FA\Google2FA as G2fa; | ||
use Request; | ||
|
||
class Google2fa extends Tool | ||
{ | ||
/** | ||
* Perform any tasks that need to happen when the tool is booted. | ||
* | ||
* @return void | ||
*/ | ||
public function boot() | ||
{ | ||
} | ||
|
||
/** | ||
* Build the view that renders the navigation links for the tool. | ||
* | ||
* @return \Illuminate\View\View | ||
*/ | ||
public function renderNavigation() | ||
{ | ||
return view('google2fa::navigation'); | ||
} | ||
|
||
protected function is2FAValid() | ||
{ | ||
$secret = Request::get('secret'); | ||
|
||
$google2fa = new G2fa(); | ||
$google2fa->setAllowInsecureCallToGoogleApis(true); | ||
|
||
return $google2fa->verifyKey(auth()->user()->user2fa->google2fa_secret, $secret); | ||
} | ||
|
||
public function confirm() | ||
{ | ||
if ($this->is2FAValid()) { | ||
auth()->user()->user2fa->google2fa_enable = 1; | ||
auth()->user()->user2fa->save(); | ||
$authenticator = app(Google2FAAuthenticator::class); | ||
$authenticator->login(); | ||
|
||
return response()->redirectTo('/nova'); | ||
} | ||
|
||
$google2fa = new G2fa(); | ||
$secretKey = $google2fa->generateSecretKey(); | ||
$google2fa->setAllowInsecureCallToGoogleApis(true); | ||
|
||
$google2fa_url = $google2fa->getQRCodeGoogleUrl( | ||
config('app.name'), | ||
auth()->user()->email, | ||
$secretKey | ||
); | ||
|
||
$data['google2fa_url'] = $google2fa_url; | ||
$data['error'] = 'Secret is invalid.'; | ||
|
||
return view('google2fa::register', $data); | ||
|
||
} | ||
|
||
public function authenticate() | ||
{ | ||
if ($this->is2FAValid()) { | ||
$authenticator = app(Google2FAAuthenticator::class); | ||
$authenticator->login(); | ||
|
||
return response()->redirectTo('/nova'); | ||
} | ||
$data['error'] = 'One time password is invalid.'; | ||
|
||
return view('google2fa::authenticate', $data); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace Lifeonscreen\Google2fa\Http\Middleware; | ||
|
||
use Lifeonscreen\Google2fa\Google2fa; | ||
|
||
class Authorize | ||
{ | ||
/** | ||
* Handle the incoming request. | ||
* | ||
* @param \Illuminate\Http\Request $request | ||
* @param \Closure $next | ||
* @return \Illuminate\Http\Response | ||
*/ | ||
public function handle($request, $next) | ||
{ | ||
return resolve(Google2fa::class)->authorize($request) ? $next($request) : abort(403); | ||
} | ||
} |
Oops, something went wrong.