Google oauth login

Signed-off-by: snipe <snipe@snipe.net>
This commit is contained in:
snipe 2023-05-10 00:14:28 -07:00
parent a1ec8cf490
commit c52b48c383
9 changed files with 247 additions and 10 deletions

View file

@ -175,6 +175,15 @@ REQUIRE_SAML=false
API_THROTTLE_PER_MINUTE=120 API_THROTTLE_PER_MINUTE=120
CSV_ESCAPE_FORMULAS=true CSV_ESCAPE_FORMULAS=true
# --------------------------------------------
# OPTIONAL: GOOGLE LOGIN
# --------------------------------------------
ENABLE_GOOGLE_LOGIN=false
GOOGLE_CLIENT_ID=null
GOOGLE_CLIENT_SECRET=null
GOOGLE_REDIRECT_URL=null
# -------------------------------------------- # --------------------------------------------
# OPTIONAL: HASHING # OPTIONAL: HASHING
# -------------------------------------------- # --------------------------------------------

View file

@ -0,0 +1,57 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
use Laravel\Socialite\Two\InvalidStateException;
class GoogleAuthController extends Controller
{
public function redirectToGoogle()
{
return Socialite::driver('google')->redirect();
}
public function handleGoogleCallback()
{
try {
$socialUser = Socialite::driver('google')->user();
} catch (InvalidStateException $exception) {
return redirect()->route('login')
->withErrors(
[
'email' => [
__('Google Login failed, please try again.'),
],
]
);
}
$user = User::where('email', $socialUser->getEmail())->first();
if ($user) {
$user->update([
'avatar' => $socialUser->avatar,
]);
Auth::login($user, true);
return redirect()->route('setup.done');
}
return redirect()->route('login')
->withErrors(
[
'email' => [
trans('admin/users/message.user_not_found'),
],
]
);
}
}

View file

@ -46,6 +46,7 @@
"laravel/helpers": "^1.4", "laravel/helpers": "^1.4",
"laravel/passport": "^10.1", "laravel/passport": "^10.1",
"laravel/slack-notification-channel": "^2.3", "laravel/slack-notification-channel": "^2.3",
"laravel/socialite": "^5.6",
"laravel/tinker": "^2.6", "laravel/tinker": "^2.6",
"laravel/ui": "^3.3", "laravel/ui": "^3.3",
"laravelcollective/html": "^6.2", "laravelcollective/html": "^6.2",

149
composer.lock generated
View file

@ -4,7 +4,7 @@
"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": "c0444af6de1d16a70c7e5520db745170", "content-hash": "4c82b2e171fb02a3ef024906db5d74c9",
"packages": [ "packages": [
{ {
"name": "alek13/slack", "name": "alek13/slack",
@ -3605,6 +3605,75 @@
}, },
"time": "2022-01-12T18:07:54+00:00" "time": "2022-01-12T18:07:54+00:00"
}, },
{
"name": "laravel/socialite",
"version": "v5.6.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/socialite.git",
"reference": "a14a177f2cc71d8add71e2b19e00800e83bdda09"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/socialite/zipball/a14a177f2cc71d8add71e2b19e00800e83bdda09",
"reference": "a14a177f2cc71d8add71e2b19e00800e83bdda09",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/guzzle": "^6.0|^7.0",
"illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0",
"illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0",
"league/oauth1-client": "^1.10.1",
"php": "^7.2|^8.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^4.0|^5.0|^6.0|^7.0|^8.0",
"phpunit/phpunit": "^8.0|^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.x-dev"
},
"laravel": {
"providers": [
"Laravel\\Socialite\\SocialiteServiceProvider"
],
"aliases": {
"Socialite": "Laravel\\Socialite\\Facades\\Socialite"
}
}
},
"autoload": {
"psr-4": {
"Laravel\\Socialite\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.",
"homepage": "https://laravel.com",
"keywords": [
"laravel",
"oauth"
],
"support": {
"issues": "https://github.com/laravel/socialite/issues",
"source": "https://github.com/laravel/socialite"
},
"time": "2023-01-20T15:42:35+00:00"
},
{ {
"name": "laravel/tinker", "name": "laravel/tinker",
"version": "v2.7.2", "version": "v2.7.2",
@ -4534,6 +4603,82 @@
], ],
"time": "2022-04-17T13:12:02+00:00" "time": "2022-04-17T13:12:02+00:00"
}, },
{
"name": "league/oauth1-client",
"version": "v1.10.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/oauth1-client.git",
"reference": "d6365b901b5c287dd41f143033315e2f777e1167"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/d6365b901b5c287dd41f143033315e2f777e1167",
"reference": "d6365b901b5c287dd41f143033315e2f777e1167",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-openssl": "*",
"guzzlehttp/guzzle": "^6.0|^7.0",
"guzzlehttp/psr7": "^1.7|^2.0",
"php": ">=7.1||>=8.0"
},
"require-dev": {
"ext-simplexml": "*",
"friendsofphp/php-cs-fixer": "^2.17",
"mockery/mockery": "^1.3.3",
"phpstan/phpstan": "^0.12.42",
"phpunit/phpunit": "^7.5||9.5"
},
"suggest": {
"ext-simplexml": "For decoding XML-based responses."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev",
"dev-develop": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"League\\OAuth1\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ben Corlett",
"email": "bencorlett@me.com",
"homepage": "http://www.webcomm.com.au",
"role": "Developer"
}
],
"description": "OAuth 1.0 Client Library",
"keywords": [
"Authentication",
"SSO",
"authorization",
"bitbucket",
"identity",
"idp",
"oauth",
"oauth1",
"single sign on",
"trello",
"tumblr",
"twitter"
],
"support": {
"issues": "https://github.com/thephpleague/oauth1-client/issues",
"source": "https://github.com/thephpleague/oauth1-client/tree/v1.10.1"
},
"time": "2022-04-15T14:02:14+00:00"
},
{ {
"name": "league/oauth2-server", "name": "league/oauth2-server",
"version": "8.3.5", "version": "8.3.5",
@ -16425,5 +16570,5 @@
"ext-pdo": "*" "ext-pdo": "*"
}, },
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.3.0" "plugin-api-version": "2.0.0"
} }

View file

@ -217,6 +217,16 @@ return [
'require_saml' => env('REQUIRE_SAML', false), 'require_saml' => env('REQUIRE_SAML', false),
/*
|--------------------------------------------------------------------------
| Enable Google Login
|--------------------------------------------------------------------------
*/
'google_login' => env('ENABLE_GOOGLE_LOGIN', false),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Demo Mode Lockdown | Demo Mode Lockdown
@ -294,6 +304,7 @@ return [
Laravel\Tinker\TinkerServiceProvider::class, Laravel\Tinker\TinkerServiceProvider::class,
Unicodeveloper\DumbPassword\DumbPasswordServiceProvider::class, Unicodeveloper\DumbPassword\DumbPasswordServiceProvider::class,
Eduardokum\LaravelMailAutoEmbed\ServiceProvider::class, Eduardokum\LaravelMailAutoEmbed\ServiceProvider::class,
Laravel\Socialite\SocialiteServiceProvider::class,
/* /*
* Application Service Providers... * Application Service Providers...
@ -366,6 +377,7 @@ return [
'Image' => Intervention\Image\ImageServiceProvider::class, 'Image' => Intervention\Image\ImageServiceProvider::class,
'Carbon' => Carbon\Carbon::class, 'Carbon' => Carbon\Carbon::class,
'Helper' => App\Helpers\Helper::class, // makes it much easier to use 'Helper::blah' in blades (which is where we usually use this) 'Helper' => App\Helpers\Helper::class, // makes it much easier to use 'Helper::blah' in blades (which is where we usually use this)
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
], ],

View file

@ -51,6 +51,9 @@ return [
'google' => [ 'google' => [
'maps_api_key' => env('GOOGLE_MAPS_API'), 'maps_api_key' => env('GOOGLE_MAPS_API'),
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT_URL'),
], ],
]; ];

View file

@ -12,5 +12,7 @@ return [
'remember_me' => 'Remember Me', 'remember_me' => 'Remember Me',
'username_help_top' => 'Enter your <strong>username</strong> to be emailed a password reset link.', 'username_help_top' => 'Enter your <strong>username</strong> to be emailed a password reset link.',
'username_help_bottom' => 'Your username and email address <em>may</em> be the same, but may not be, depending on your configuration. If you cannot remember your username, contact your administrator. <br><br><strong>Usernames without an associated email address will not be emailed a password reset link.</strong> ', 'username_help_bottom' => 'Your username and email address <em>may</em> be the same, but may not be, depending on your configuration. If you cannot remember your username, contact your administrator. <br><br><strong>Usernames without an associated email address will not be emailed a password reset link.</strong> ',
]; 'google_login' => 'Login via Google',
];

View file

@ -64,7 +64,7 @@
</div> <!-- end row --> </div> <!-- end row -->
@if (!config('app.require_saml') && $snipeSettings->saml_enabled) @if (!config('app.require_saml') && $snipeSettings->saml_enabled)
<div class="row "> <div class="row">
<div class="text-right col-md-12"> <div class="text-right col-md-12">
<a href="{{ route('saml.login') }}">{{ trans('auth/general.saml_login') }}</a> <a href="{{ route('saml.login') }}">{{ trans('auth/general.saml_login') }}</a>
</div> </div>
@ -77,6 +77,14 @@
@else @else
<button class="btn btn-lg btn-primary btn-block">{{ trans('auth/general.login') }}</button> <button class="btn btn-lg btn-primary btn-block">{{ trans('auth/general.login') }}</button>
@endif @endif
@if ((config('app.google_login')) && (config('services.google.client_id')) && (config('services.google.client_secret')) && (config('services.google.redirect')))
<a class="btn btn-lg btn-primary btn-block" href="{{ route('google.redirect') }}">
<i class="fa-brands fa-google"></i>
{{ trans('auth/general.google_login') }}
</a>
@endif
</div> </div>
<div class="text-right col-md-12 col-sm-12 col-xs-12" style="padding-top: 10px;"> <div class="text-right col-md-12 col-sm-12 col-xs-12" style="padding-top: 10px;">
@if ($snipeSettings->custom_forgot_pass_url) @if ($snipeSettings->custom_forgot_pass_url)

View file

@ -453,8 +453,6 @@ Route::group(['middleware' => 'web'], function () {
[LoginController::class, 'postTwoFactorAuth'] [LoginController::class, 'postTwoFactorAuth']
); );
Route::post( Route::post(
'password/email', 'password/email',
[ForgotPasswordController::class, 'sendResetLinkEmail'] [ForgotPasswordController::class, 'sendResetLinkEmail']
@ -483,7 +481,9 @@ Route::group(['middleware' => 'web'], function () {
)->name('password.email')->middleware('throttle:forgotten_password'); )->name('password.email')->middleware('throttle:forgotten_password');
// Socialite Google login
Route::get('google', 'App\Http\Controllers\GoogleAuthController@redirectToGoogle')->name('google.redirect');
Route::get('google/callback', 'App\Http\Controllers\GoogleAuthController@handleGoogleCallback')->name('google.callback');
Route::get( Route::get(