Skip to content

Instantly share code, notes, and snippets.

@noxify
Last active January 26, 2018 04:31
Show Gist options
  • Save noxify/90ffac363138e43bc330b74df6c9cfbc to your computer and use it in GitHub Desktop.
Save noxify/90ffac363138e43bc330b74df6c9cfbc to your computer and use it in GitHub Desktop.
<?php
/*
* NOTICE OF LICENSE
*
* Part of the Rinvex Fort Package.
*
* This source file is subject to The MIT License (MIT)
* that is bundled with this package in the LICENSE file.
*
* Package: Rinvex Fort Package
* License: The MIT License (MIT)
* Link: https://rinvex.com
*/
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Rinvex\Fort\Services\TwoFactorTotpProvider;
class WebsudoController extends AuthenticatedController
{
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function formPassword() {
return view('websudo.password');
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function formTwofactor() {
return view('websudo.twofactor');
}
/**
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
*/
public function processPassword( Request $request ) {
$session_name = session('rinvex.security.session_name');
$redirect_url = session('rinvex.security.intended');
if( Hash::check($request->input('password'), request()->user()->password) ) {
$this->setSession($session_name);
}
return intend([
'intended' => url($redirect_url)
]);
}
/**
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
*/
public function processTwofactor( Request $request ) {
$session_name = session('rinvex.security.session_name');
$redirect_url = session('rinvex.security.intended');
$guard = $this->getGuard();
$token = $request->get('token');
$user = $request->user($guard);
if( $this->isValidTwoFactorTotp($user, $token) ) {
$this->setSession($session_name);
}
return intend([
'intended' => url($redirect_url)
]);
}
/**
* @param $session_name
*/
protected function setSession($session_name) {
session()->put($session_name, time());
session()->forget('rinvex.security.intended');
session()->forget('rinvex.security.session_name');
}
/**
* @param $user
* @param $token
*
* @return bool
*/
protected function isValidTwoFactorTotp( $user, $token)
{
$totp = app(TwoFactorTotpProvider::class);
$secret = array_get($user->getTwoFactor(), 'totp.secret');
return !is_null($secret) && strlen($token) === 6 && $totp->verifyKey($secret, $token);
}
}
<?php
//...
protected $routeMiddleware = [
//....
'websudo' => \App\Http\Middleware\WebSudo::class
];
<?php
/*
* NOTICE OF LICENSE
*
* Part of the Rinvex Fort Package.
*
* This source file is subject to The MIT License (MIT)
* that is bundled with this package in the LICENSE file.
*
* Package: Rinvex Fort Package
* License: The MIT License (MIT)
* Link: https://rinvex.com
*/
namespace App\Http\Middleware;
use Closure;
class WebSudo
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next, $type='password', $session_name=null, $timeout=120, $renew=false)
{
if( is_null($session_name) || empty($session_name)) {
$session_name = config('rinvex.fort.websudo.prefix').$request->route()->getName();
} else {
$session_name = config('rinvex.fort.websudo.prefix').$session_name;
}
if( is_null( session( $session_name ) ) || time() - session( $session_name ) >= $timeout ) {
session()->forget( $session_name );
session()->put('rinvex.security.intended', $request->url());
session()->put('rinvex.security.session_name', $session_name);
return intend( [
'route' => 'rinvex.fort.websudo.'.$type
] );
}
if( $renew ) {
session()->put($session_name, time());
}
return $next($request);
}
}
<?php
//....
return [
'websudo' => [
'prefix' => 'rinvex.security.'
],
/*
|--------------------------------------------------------------------------
| Authentication and Authorization Models
|--------------------------------------------------------------------------
*/
//....
{{-- Master Layout --}}
@extends('frontend.common.layout')
{{-- Page Title --}}
@section('title')
{{ config('app.name') }} » Websudo
@stop
{{-- Main Content --}}
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<section class="panel panel-default">
<header class="panel-heading">Websudo</header>
<div class="panel-body">
{{ Form::open(['route' => 'rinvex.fort.websudo.password.post', 'class' => 'form-horizontal']) }}
@include('frontend.alerts.success')
@include('frontend.alerts.warning')
@include('frontend.alerts.error')
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
{{ Form::label('password', trans('rinvex/fort::forms.common.password'), ['class' => 'col-md-4 control-label']) }}
<div class="col-md-6">
{{ Form::password('password', ['class' => 'form-control', 'placeholder' => trans('rinvex/fort::forms.common.password'), 'required' => 'required']) }}
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12 text-center">
{{ Form::button('<i class="fa fa-sign-in"></i> Confirm', ['class' => 'btn btn-primary', 'type' => 'submit']) }}
{{ Html::link(route('rinvex.fort.frontend.passwordreset.request'), trans('rinvex/fort::forms.common.forgot_password'), ['class' => 'btn btn-link']) }}
</div>
</div>
{{ Form::close() }}
</div>
</section>
</div>
</div>
</div>
@endsection
{{-- Master Layout --}}
@extends('frontend.common.layout')
{{-- Page Title --}}
@section('title')
{{ config('app.name') }} » Websudo
@stop
{{-- Main Content --}}
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<section class="panel panel-default">
<header class="panel-heading">Websudo</header>
<div class="panel-body">
{{ Form::open(['route' => 'rinvex.fort.websudo.twofactor.post', 'class' => 'form-horizontal']) }}
@include('frontend.alerts.success')
@include('frontend.alerts.warning')
@include('frontend.alerts.error')
<div class="form-group{{ $errors->has('token') ? ' has-error' : '' }}">
{{ Form::label('token', trans('rinvex/fort::forms.common.authentication_code'), ['class' => 'col-md-4 control-label']) }}
<div class="col-md-6">
{{ Form::text('token', old('token'), ['class' => 'form-control', 'placeholder' => trans('rinvex/fort::forms.common.authentication_code'), 'required' => 'required', 'autofocus' => 'autofocus']) }}
@if ($errors->has('token'))
<span class="help-block">
<strong>{{ $errors->first('token') }}</strong>
</span>
@endif
</div>
</div>
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12 text-center">
{{ Form::button('<i class="fa fa-sign-in"></i> Confirm', ['class' => 'btn btn-primary', 'type' => 'submit']) }}
</div>
</div>
{{ Form::close() }}
</div>
</section>
</div>
</div>
</div>
@endsection
<?php
//...
Route::get('websudo/password')->name('rinvex.fort.websudo.password')->uses('WebsudoController@formPassword')->middleware(['web', 'auth']);
Route::post('websudo/password')->name('rinvex.fort.websudo.password.post')->uses('WebsudoController@processPassword')->middleware(['web', 'auth']);
Route::get('websudo/twofactor')->name('rinvex.fort.websudo.twofactor')->uses('WebsudoController@formTwofactor')->middleware(['web', 'auth']);
Route::post('websudo/twofactor')->name('rinvex.fort.websudo.twofactor.post')->uses('WebsudoController@processTwofactor')->middleware(['web', 'auth']);
//...
//use it inside a group with a generic session name which will be used for all child routes
Route::namespace('Backend')->name('rinvex.fort.backend.')->prefix('backend')->middleware(['web', 'websudo:password,backend.websudo,3600,true', 'can:access-dashboard'])->group(function () {
//...
});
//or use it for one resource
Route::namespace('Backend')->name('rinvex.fort.backend.')->prefix('backend')->middleware(['web', 'can:access-dashboard'])->group(function () {
Route::get('/')->name('dashboard.home')->uses('DashboardController@home')->middleware(['websudo:password,,3600,true']);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment