-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
2FA Two Authentication Factor #164 #724
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
7db3df7
[WIP] Add google2fa depend and views
asbiin b8f3803
[WIP] Add check for code when enabling 2FA, improve views
asbiin 280498a
Update composer
asbiin f5ef3f9
Add a Command to deactivate 2FA for a user
asbiin 9c956a5
Add a new conf in the .env file to enable/disable 2FA
asbiin 70cb16b
Use the login function from Authenticator
asbiin a6cbd94
Add some tests
asbiin b0ef8cc
Updating composer
asbiin df3b0a4
Merge branch 'master' into 164-2FA-two-factor-auth
asbiin a1c1468
Commit StyleCI analysis
asbiin e49f927
Add a Security item in the sidebar, and fix other stuffs (translation…
asbiin 63bc2f3
Update lang file (en) that was missed on the last commit
asbiin 6f44483
Add a comment to the env example file
asbiin 0d37211
Renaming controller, add good return message
asbiin c8c8266
StyleCI recommandations
asbiin db98f2c
Merge branch 'master' into 164-2FA-two-factor-auth
asbiin b81a417
Merge branch 'master' into 164-2FA-two-factor-auth
asbiin 6006cf6
Update messages
asbiin 663db7c
Use app laravel function
asbiin 42260cf
Change route for 2fa validation
asbiin 2c5b1db
Fix layout and some messages
asbiin a740b68
Merge branch 'master' into 164-2FA-two-factor-auth
asbiin b37c399
Merge branch 'master' into 164-2FA-two-factor-auth
asbiin 28380f2
Fix styleci
asbiin fbe4586
Merge branch '164-2FA-two-factor-auth' of github.com:asbiin/monica in…
asbiin efe87c5
Add texts to every lang files
asbiin 8d0e1bf
Fix stylceci
asbiin 151535b
Add some infos
asbiin a7c0cfa
Merge branch 'master' into 164-2FA-two-factor-auth
asbiin 0b0f393
Merge branch 'master' into 164-2FA-two-factor-auth
asbiin d2159bb
Merge branch 'master' into 164-2FA-two-factor-auth
asbiin 06612eb
Review AddGoogle2faSecretToUsers
asbiin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -98,3 +98,6 @@ AWS_SECRET= | |
| AWS_REGION=us-east-1 | ||
| AWS_BUCKET= | ||
| AWS_SERVER= | ||
|
|
||
| # Enable Two Factor Authentication | ||
| 2FA_ENABLED=false | ||
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -10,3 +10,5 @@ DB_TEST_PASSWORD= | |
| CACHE_DRIVER=array | ||
| SESSION_DRIVER=array | ||
| QUEUE_DRIVER=sync | ||
|
|
||
| 2FA_ENABLED=false | ||
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -11,3 +11,4 @@ monica.sublime-workspace | |
| /storage/oauth-private.key | ||
| /storage/oauth-public.key | ||
| .DS_Store | ||
| npm-debug.log.* | ||
This file contains hidden or 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
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -24,4 +24,4 @@ Scott Williams @scott-joe | |
| Craig Davison @davisonio <[email protected]> | ||
| Michael Heap @mheap <[email protected]> | ||
| Matthew Du Pont @mattdp <[email protected]> | ||
| Alexis Saettler @asbiin | ||
| Alexis Saettler @asbiin <[email protected]> | ||
This file contains hidden or 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,83 @@ | ||
| <?php | ||
|
|
||
| namespace App\Console\Commands; | ||
|
|
||
| use App\User; | ||
| use Illuminate\Console\Command; | ||
|
|
||
| class Deactivate2FA extends Command | ||
| { | ||
| /** | ||
| * The name and signature of the console command. | ||
| * | ||
| * @var string | ||
| */ | ||
| protected $signature = '2fa:deactivate {--email= : The email of the user to deactivate 2FA} {--force : run without asking for confirmation}'; | ||
|
|
||
| /** | ||
| * The console command description. | ||
| * | ||
| * @var string | ||
| */ | ||
| protected $description = 'Deactivate 2FA for this user'; | ||
|
|
||
| /** | ||
| * Create a new command instance. | ||
| * | ||
| * @return void | ||
| */ | ||
| public function __construct() | ||
| { | ||
| parent::__construct(); | ||
| } | ||
|
|
||
| /** | ||
| * Execute the console command. | ||
| * | ||
| * @return mixed | ||
| */ | ||
| public function handle() | ||
| { | ||
| // retrieve the email from the option | ||
| $email = $this->option('email'); | ||
|
|
||
| // if no email was passed to the option, prompt the user to enter the email | ||
| if (! $email) { | ||
| $email = $this->ask('what is the user\'s email?'); | ||
| } | ||
|
|
||
| // retrieve the user with the specified email | ||
| $user = User::where('email', $email)->first(); | ||
|
|
||
| if (! $user) { | ||
| // show an error and exist if the user does not exist | ||
| $this->error('No user with that email.'); | ||
|
|
||
| return; | ||
| } | ||
| if (is_null($user->google2fa_secret)) { | ||
| // show an error and exist if the user does not exist | ||
| $this->error('2FA is currently not activated for this user.'); | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| // Print a warning | ||
| $this->info('2FA will be deactivated for '.$user->email); | ||
| $this->info('This action can\'t be cancelled.'); | ||
|
|
||
| // ask for confirmation if not forced | ||
| if (! $this->option('force') && ! $this->confirm('Do you wish to continue?')) { | ||
| return; | ||
| } | ||
|
|
||
| // remove google2fa_secret key | ||
| $user->google2fa_secret = null; | ||
|
|
||
| // save the user | ||
| $user->save(); | ||
|
|
||
| // show the new secret key | ||
| $this->info('2FA has been deactivated for '.$user->email); | ||
| } | ||
| } |
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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,144 @@ | ||
| <?php | ||
|
|
||
| namespace App\Http\Controllers\Settings; | ||
|
|
||
| use Google2FA; | ||
| use Illuminate\Http\Request; | ||
| use App\Http\Controllers\Controller; | ||
| use Illuminate\Foundation\Auth\RedirectsUsers; | ||
| use PragmaRX\Google2FALaravel\Support\Authenticator; | ||
|
|
||
| class MultiFAController extends Controller | ||
| { | ||
| use RedirectsUsers; | ||
|
|
||
| protected $redirectTo = '/settings/security'; | ||
|
|
||
| /** | ||
| * Session var name to store secret code. | ||
| */ | ||
| private const SESSION_TFA_SECRET = '2FA_secret'; | ||
|
|
||
| /** | ||
| * Create a new authentication controller instance. | ||
| * | ||
| * @return void | ||
| */ | ||
| public function __construct() | ||
| { | ||
| $this->middleware('web'); | ||
| } | ||
|
|
||
| /** | ||
| * @param \Illuminate\Http\Request $request | ||
| * @return \Illuminate\Http\Response | ||
| */ | ||
| public function enableTwoFactor(Request $request) | ||
| { | ||
| //generate new secret | ||
| $secret = $this->generateSecret(); | ||
|
|
||
| $user = $request->user(); | ||
|
|
||
| //generate image for QR barcode | ||
| $imageDataUri = Google2FA::getQRCodeInline( | ||
| $request->getHttpHost(), | ||
| $user->email, | ||
| $secret, | ||
| 200 | ||
| ); | ||
|
|
||
| $request->session()->put(self::SESSION_TFA_SECRET, $secret); | ||
|
|
||
| return view('settings.security.2fa-enable', ['image' => $imageDataUri, 'secret' => $secret]); | ||
| } | ||
|
|
||
| /** | ||
| * @param \Illuminate\Http\Request $request | ||
| * @return \Illuminate\Http\Response | ||
| */ | ||
| public function validateTwoFactor(Request $request) | ||
| { | ||
| $this->validate($request, [ | ||
| 'one_time_password' => 'required', | ||
| ]); | ||
|
|
||
| //retrieve secret | ||
| $secret = $request->session()->pull(self::SESSION_TFA_SECRET); | ||
|
|
||
| $authenticator = app(Authenticator::class)->boot($request); | ||
|
|
||
| if ($authenticator->verifyGoogle2FA($secret, $request['one_time_password'])) { | ||
| //get user | ||
| $user = $request->user(); | ||
|
|
||
| //encrypt and then save secret | ||
| $user->google2fa_secret = $secret; | ||
| $user->save(); | ||
|
|
||
| $authenticator->login(); | ||
|
|
||
| return redirect($this->redirectPath()) | ||
| ->with('status', trans('settings.2fa_enable_success')); | ||
| } | ||
|
|
||
| $authenticator->logout(); | ||
|
|
||
| return redirect($this->redirectPath()) | ||
| ->withErrors(trans('settings.2fa_enable_error')); | ||
| } | ||
|
|
||
| /** | ||
| * @param \Illuminate\Http\Request $request | ||
| * @return \Illuminate\Http\Response | ||
| */ | ||
| public function disableTwoFactor(Request $request) | ||
| { | ||
| return view('settings.security.2fa-disable'); | ||
| } | ||
|
|
||
| /** | ||
| * @param \Illuminate\Http\Request $request | ||
| * @return \Illuminate\Http\Response | ||
| */ | ||
| public function deactivateTwoFactor(Request $request) | ||
| { | ||
| $this->validate($request, [ | ||
| 'one_time_password' => 'required', | ||
| ]); | ||
|
|
||
| $user = $request->user(); | ||
|
|
||
| //retrieve secret | ||
| $secret = $user->google2fa_secret; | ||
|
|
||
| $authenticator = app(Authenticator::class)->boot($request); | ||
|
|
||
| if ($authenticator->verifyGoogle2FA($secret, $request['one_time_password'])) { | ||
|
|
||
| //make secret column blank | ||
| $user->google2fa_secret = null; | ||
| $user->save(); | ||
|
|
||
| $authenticator->logout(); | ||
|
|
||
| return redirect($this->redirectPath()) | ||
| ->with('status', trans('settings.2fa_disable_success')); | ||
| } | ||
|
|
||
| return redirect($this->redirectPath()) | ||
| ->withErrors(trans('settings.2fa_disable_error')); | ||
| } | ||
|
|
||
| /** | ||
| * Generate a secret key in Base32 format. | ||
| * | ||
| * @return string | ||
| */ | ||
| private function generateSecret() | ||
| { | ||
| $google2fa = app('pragmarx.google2fa'); | ||
|
|
||
| return $google2fa->generateSecretKey(32); | ||
| } | ||
| } | ||
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it's an issue, but static analysis says that this is an instance method, called statically
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, we should use
app('pragmarx.google2fa')->getQRCodeInlineinstead.Thanks !
Do you want to open an issue ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or just add it to the (great) PR #878
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have added