Add oauth support
- Support azure, bitbucket, github, gitlab, google providers - Add authentication page to settings Co-authored-by: Suraj Kumar <srjkmr1024@gmail.com> Co-authored-by: Michael Castanieto <mcastanieto@gmail.com> Co-authored-by: Mike Kim <m.kim4247@gmail.com>
This commit is contained in:
parent
46ed17c99e
commit
1f37318f79
35
app/Http/Controllers/OauthController.php
Normal file
35
app/Http/Controllers/OauthController.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class OauthController extends Controller {
|
||||||
|
public function redirect(string $provider)
|
||||||
|
{
|
||||||
|
$socialite_provider = get_socialite_provider($provider);
|
||||||
|
return $socialite_provider->redirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function callback(string $provider)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$oauthUser = get_socialite_provider($provider)->user();
|
||||||
|
$user = User::whereEmail($oauthUser->email)->first();
|
||||||
|
if (!$user) {
|
||||||
|
$user = User::create([
|
||||||
|
'name' => $oauthUser->name,
|
||||||
|
'email' => $oauthUser->email,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
Auth::login($user);
|
||||||
|
return redirect('/');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
ray($e->getMessage());
|
||||||
|
return redirect()->route('login')->withErrors([__('auth.failed.callback')]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
app/Livewire/Settings/Auth.php
Normal file
43
app/Livewire/Settings/Auth.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Settings;
|
||||||
|
|
||||||
|
use Livewire\Component;
|
||||||
|
use App\Models\OauthSetting;
|
||||||
|
|
||||||
|
class Auth extends Component {
|
||||||
|
public $oauth_settings_map;
|
||||||
|
|
||||||
|
protected function rules() {
|
||||||
|
return OauthSetting::all()->reduce(function($carry, $setting) {
|
||||||
|
$carry["oauth_settings_map.$setting->provider.enabled"] = 'required';
|
||||||
|
$carry["oauth_settings_map.$setting->provider.client_id"] = 'nullable';
|
||||||
|
$carry["oauth_settings_map.$setting->provider.client_secret"] = 'nullable';
|
||||||
|
$carry["oauth_settings_map.$setting->provider.redirect_uri"] = 'nullable';
|
||||||
|
$carry["oauth_settings_map.$setting->provider.tenant"] = 'nullable';
|
||||||
|
return $carry;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mount() {
|
||||||
|
$this->oauth_settings_map = OauthSetting::all()->reduce(function($carry, $setting) {
|
||||||
|
$carry[$setting->provider] = $setting;
|
||||||
|
return $carry;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updateOauthSettings() {
|
||||||
|
foreach (array_values($this->oauth_settings_map) as &$setting) {
|
||||||
|
$setting->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function instantSave() {
|
||||||
|
$this->updateOauthSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function submit() {
|
||||||
|
$this->updateOauthSettings();
|
||||||
|
$this->dispatch('success', 'Instance settings updated successfully!');
|
||||||
|
}
|
||||||
|
}
|
21
app/Models/OauthSetting.php
Normal file
21
app/Models/OauthSetting.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Facades\Crypt;
|
||||||
|
|
||||||
|
class OauthSetting extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected function clientSecret(): Attribute
|
||||||
|
{
|
||||||
|
return Attribute::make(
|
||||||
|
get: fn (string | null $value) => empty($value) ? null : Crypt::decryptString($value),
|
||||||
|
set: fn (string | null $value) => empty($value) ? null : Crypt::encryptString($value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,9 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
// Registered::class => [
|
// Registered::class => [
|
||||||
// SendEmailVerificationNotification::class,
|
// SendEmailVerificationNotification::class,
|
||||||
// ],
|
// ],
|
||||||
|
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
|
||||||
|
\SocialiteProviders\Azure\AzureExtendSocialite::class.'@handle',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
use App\Actions\Fortify\UpdateUserPassword;
|
use App\Actions\Fortify\UpdateUserPassword;
|
||||||
use App\Actions\Fortify\UpdateUserProfileInformation;
|
use App\Actions\Fortify\UpdateUserProfileInformation;
|
||||||
use App\Models\InstanceSettings;
|
use App\Models\InstanceSettings;
|
||||||
|
use App\Models\OauthSetting;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Cache\RateLimiting\Limit;
|
use Illuminate\Cache\RateLimiting\Limit;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@ -56,13 +57,15 @@ public function boot(): void
|
|||||||
|
|
||||||
Fortify::loginView(function () {
|
Fortify::loginView(function () {
|
||||||
$settings = InstanceSettings::get();
|
$settings = InstanceSettings::get();
|
||||||
|
$enabled_oauth_providers = OauthSetting::where('enabled', true)->get();
|
||||||
$users = User::count();
|
$users = User::count();
|
||||||
if ($users == 0) {
|
if ($users == 0) {
|
||||||
// If there are no users, redirect to registration
|
// If there are no users, redirect to registration
|
||||||
return redirect()->route('register');
|
return redirect()->route('register');
|
||||||
}
|
}
|
||||||
return view('auth.login', [
|
return view('auth.login', [
|
||||||
'is_registration_enabled' => $settings->is_registration_enabled
|
'is_registration_enabled' => $settings->is_registration_enabled,
|
||||||
|
'enabled_oauth_providers' => $enabled_oauth_providers,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
26
bootstrap/helpers/socialite.php
Normal file
26
bootstrap/helpers/socialite.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\OauthSetting;
|
||||||
|
use Laravel\Socialite\Facades\Socialite;
|
||||||
|
|
||||||
|
function get_socialite_provider(string $provider)
|
||||||
|
{
|
||||||
|
$oauth_setting = OauthSetting::firstWhere('provider', $provider);
|
||||||
|
$config = [
|
||||||
|
'client_id' => $oauth_setting->client_id,
|
||||||
|
'client_secret' => $oauth_setting->client_secret,
|
||||||
|
'redirect' => $oauth_setting->redirect_uri,
|
||||||
|
'tenant' => $oauth_setting->tenant,
|
||||||
|
];
|
||||||
|
$provider_class_map = [
|
||||||
|
'azure' => \SocialiteProviders\Azure\Provider::class,
|
||||||
|
'bitbucket' => \Laravel\Socialite\Two\BitbucketProvider::class,
|
||||||
|
'github' => \Laravel\Socialite\Two\GithubProvider::class,
|
||||||
|
'gitlab' => \Laravel\Socialite\Two\GitlabProvider::class,
|
||||||
|
'google' => \Laravel\Socialite\Two\GoogleProvider::class,
|
||||||
|
];
|
||||||
|
return Socialite::buildProvider(
|
||||||
|
$provider_class_map[$provider],
|
||||||
|
$config
|
||||||
|
);
|
||||||
|
}
|
@ -17,6 +17,7 @@
|
|||||||
"laravel/horizon": "^5.15",
|
"laravel/horizon": "^5.15",
|
||||||
"laravel/prompts": "^0.1.6",
|
"laravel/prompts": "^0.1.6",
|
||||||
"laravel/sanctum": "^v3.2.1",
|
"laravel/sanctum": "^v3.2.1",
|
||||||
|
"laravel/socialite": "^5.12",
|
||||||
"laravel/tinker": "^v2.8.1",
|
"laravel/tinker": "^v2.8.1",
|
||||||
"laravel/ui": "^4.2",
|
"laravel/ui": "^4.2",
|
||||||
"lcobucci/jwt": "^5.0.0",
|
"lcobucci/jwt": "^5.0.0",
|
||||||
@ -31,6 +32,7 @@
|
|||||||
"pusher/pusher-php-server": "^7.2",
|
"pusher/pusher-php-server": "^7.2",
|
||||||
"resend/resend-laravel": "^0.5.0",
|
"resend/resend-laravel": "^0.5.0",
|
||||||
"sentry/sentry-laravel": "^3.4",
|
"sentry/sentry-laravel": "^3.4",
|
||||||
|
"socialiteproviders/microsoft-azure": "^5.1",
|
||||||
"spatie/laravel-activitylog": "^4.7.3",
|
"spatie/laravel-activitylog": "^4.7.3",
|
||||||
"spatie/laravel-data": "^3.4.3",
|
"spatie/laravel-data": "^3.4.3",
|
||||||
"spatie/laravel-ray": "^1.32.4",
|
"spatie/laravel-ray": "^1.32.4",
|
||||||
|
273
composer.lock
generated
273
composer.lock
generated
@ -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": "19b19082b605e09867e6ae65fb8135f6",
|
"content-hash": "9bdaf702cdd870434444f8937a816fdb",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "amphp/amp",
|
"name": "amphp/amp",
|
||||||
@ -3370,6 +3370,76 @@
|
|||||||
},
|
},
|
||||||
"time": "2023-11-08T14:08:06+00:00"
|
"time": "2023-11-08T14:08:06+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "laravel/socialite",
|
||||||
|
"version": "v5.12.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/laravel/socialite.git",
|
||||||
|
"reference": "7dae1b072573809f32ab6dcf4aebb57c8b3e8acf"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/laravel/socialite/zipball/7dae1b072573809f32ab6dcf4aebb57c8b3e8acf",
|
||||||
|
"reference": "7dae1b072573809f32ab6dcf4aebb57c8b3e8acf",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": "*",
|
||||||
|
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||||
|
"illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||||
|
"illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||||
|
"illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.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|^9.0",
|
||||||
|
"phpstan/phpstan": "^1.10",
|
||||||
|
"phpunit/phpunit": "^8.0|^9.3|^10.4"
|
||||||
|
},
|
||||||
|
"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": "2024-02-16T08:58:20+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/tinker",
|
"name": "laravel/tinker",
|
||||||
"version": "v2.9.0",
|
"version": "v2.9.0",
|
||||||
@ -4090,6 +4160,82 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-01-28T23:22:08+00:00"
|
"time": "2024-01-28T23:22:08+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/uri",
|
"name": "league/uri",
|
||||||
"version": "7.4.0",
|
"version": "7.4.0",
|
||||||
@ -7696,6 +7842,131 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-10-12T14:38:46+00:00"
|
"time": "2023-10-12T14:38:46+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "socialiteproviders/manager",
|
||||||
|
"version": "v4.5.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/SocialiteProviders/Manager.git",
|
||||||
|
"reference": "a67f194f0f4c4c7616c549afc697b78df9658d44"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/a67f194f0f4c4c7616c549afc697b78df9658d44",
|
||||||
|
"reference": "a67f194f0f4c4c7616c549afc697b78df9658d44",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0",
|
||||||
|
"laravel/socialite": "^5.2",
|
||||||
|
"php": "^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"mockery/mockery": "^1.2",
|
||||||
|
"phpunit/phpunit": "^9.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"SocialiteProviders\\Manager\\ServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"SocialiteProviders\\Manager\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Andy Wendt",
|
||||||
|
"email": "andy@awendt.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Anton Komarev",
|
||||||
|
"email": "a.komarev@cybercog.su"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Miguel Piedrafita",
|
||||||
|
"email": "soy@miguelpiedrafita.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "atymic",
|
||||||
|
"email": "atymicq@gmail.com",
|
||||||
|
"homepage": "https://atymic.dev"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Easily add new or override built-in providers in Laravel Socialite.",
|
||||||
|
"homepage": "https://socialiteproviders.com",
|
||||||
|
"keywords": [
|
||||||
|
"laravel",
|
||||||
|
"manager",
|
||||||
|
"oauth",
|
||||||
|
"providers",
|
||||||
|
"socialite"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/socialiteproviders/manager/issues",
|
||||||
|
"source": "https://github.com/socialiteproviders/manager"
|
||||||
|
},
|
||||||
|
"time": "2024-02-17T08:58:03+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "socialiteproviders/microsoft-azure",
|
||||||
|
"version": "5.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/SocialiteProviders/Microsoft-Azure.git",
|
||||||
|
"reference": "7522b27cd8518706b50e03b40a396fb0a6891feb"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/SocialiteProviders/Microsoft-Azure/zipball/7522b27cd8518706b50e03b40a396fb0a6891feb",
|
||||||
|
"reference": "7522b27cd8518706b50e03b40a396fb0a6891feb",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-json": "*",
|
||||||
|
"php": "^7.2 || ^8.0",
|
||||||
|
"socialiteproviders/manager": "~4.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"SocialiteProviders\\Azure\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Chris Hemmings",
|
||||||
|
"email": "chris@hemmin.gs"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Microsoft Azure OAuth2 Provider for Laravel Socialite",
|
||||||
|
"keywords": [
|
||||||
|
"azure",
|
||||||
|
"laravel",
|
||||||
|
"microsoft",
|
||||||
|
"oauth",
|
||||||
|
"provider",
|
||||||
|
"socialite"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"docs": "https://socialiteproviders.com/microsoft-azure",
|
||||||
|
"issues": "https://github.com/socialiteproviders/providers/issues",
|
||||||
|
"source": "https://github.com/socialiteproviders/providers"
|
||||||
|
},
|
||||||
|
"time": "2022-03-15T21:17:43+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/backtrace",
|
"name": "spatie/backtrace",
|
||||||
"version": "1.5.3",
|
"version": "1.5.3",
|
||||||
|
@ -187,6 +187,7 @@
|
|||||||
/*
|
/*
|
||||||
* Package Service Providers...
|
* Package Service Providers...
|
||||||
*/
|
*/
|
||||||
|
\SocialiteProviders\Manager\ServiceProvider::class,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Application Service Providers...
|
* Application Service Providers...
|
||||||
|
@ -30,5 +30,4 @@
|
|||||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
28
database/migrations/2024_03_08_180457_nullable_password.php
Normal file
28
database/migrations/2024_03_08_180457_nullable_password.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->string('password')->nullable()->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->string('password')->nullable(false)->change();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('oauth_settings', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('provider')->unique();
|
||||||
|
$table->boolean('enabled')->default(false);
|
||||||
|
$table->string('client_id')->nullable();
|
||||||
|
$table->text('client_secret')->nullable();
|
||||||
|
$table->string('redirect_uri')->nullable();
|
||||||
|
$table->string('tenant')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('oauth_settings');
|
||||||
|
}
|
||||||
|
};
|
@ -32,6 +32,7 @@ public function run(): void
|
|||||||
StandalonePostgresqlSeeder::class,
|
StandalonePostgresqlSeeder::class,
|
||||||
ScheduledDatabaseBackupSeeder::class,
|
ScheduledDatabaseBackupSeeder::class,
|
||||||
ScheduledDatabaseBackupExecutionSeeder::class,
|
ScheduledDatabaseBackupExecutionSeeder::class,
|
||||||
|
OauthSettingSeeder::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
37
database/seeders/OauthSettingSeeder.php
Normal file
37
database/seeders/OauthSettingSeeder.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\OauthSetting;
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class OauthSettingSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
OauthSetting::firstOrCreate([
|
||||||
|
'id' => 0,
|
||||||
|
'provider' => 'azure',
|
||||||
|
]);
|
||||||
|
OauthSetting::firstOrCreate([
|
||||||
|
'id' => 1,
|
||||||
|
'provider' => 'bitbucket',
|
||||||
|
]);
|
||||||
|
OauthSetting::firstOrCreate([
|
||||||
|
'id' => 2,
|
||||||
|
'provider' => 'github',
|
||||||
|
]);
|
||||||
|
OauthSetting::firstOrCreate([
|
||||||
|
'id' => 3,
|
||||||
|
'provider' => 'gitlab',
|
||||||
|
]);
|
||||||
|
OauthSetting::firstOrCreate([
|
||||||
|
'id' => 4,
|
||||||
|
'provider' => 'google',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -198,5 +198,8 @@ public function run(): void
|
|||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
echo "Error: {$e->getMessage()}\n";
|
echo "Error: {$e->getMessage()}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$oauth_settings_seeder = new OauthSettingSeeder();
|
||||||
|
$oauth_settings_seeder->run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
{
|
{
|
||||||
"auth.login": "Login",
|
"auth.login": "Login",
|
||||||
|
"auth.login.azure": "Login with Microsoft",
|
||||||
|
"auth.login.bitbucket": "Login with Bitbucket",
|
||||||
|
"auth.login.github": "Login with GitHub",
|
||||||
|
"auth.login.gitlab": "Login with Gitlab",
|
||||||
|
"auth.login.google": "Login with Google",
|
||||||
"auth.already_registered": "Already registered?",
|
"auth.already_registered": "Already registered?",
|
||||||
"auth.confirm_password": "Confirm password",
|
"auth.confirm_password": "Confirm password",
|
||||||
"auth.forgot_password": "Forgot password",
|
"auth.forgot_password": "Forgot password",
|
||||||
@ -10,6 +15,7 @@
|
|||||||
"auth.registration_disabled": "Registration is disabled. Please contact the administrator.",
|
"auth.registration_disabled": "Registration is disabled. Please contact the administrator.",
|
||||||
"auth.reset_password": "Reset password",
|
"auth.reset_password": "Reset password",
|
||||||
"auth.failed": "These credentials do not match our records.",
|
"auth.failed": "These credentials do not match our records.",
|
||||||
|
"auth.failed.callback": "Failed to process callback from login provider.",
|
||||||
"auth.failed.password": "The provided password is incorrect.",
|
"auth.failed.password": "The provided password is incorrect.",
|
||||||
"auth.failed.email": "We can't find a user with that e-mail address.",
|
"auth.failed.email": "We can't find a user with that e-mail address.",
|
||||||
"auth.throttle": "Too many login attempts. Please try again in :seconds seconds.",
|
"auth.throttle": "Too many login attempts. Please try again in :seconds seconds.",
|
||||||
|
@ -175,3 +175,7 @@ input.input-sm {
|
|||||||
option{
|
option{
|
||||||
@apply text-white;
|
@apply text-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
@ -40,6 +40,11 @@ class="text-xs text-center text-white normal-case bg-transparent border-none rou
|
|||||||
</a>
|
</a>
|
||||||
@endenv
|
@endenv
|
||||||
<x-forms.button type="submit">{{ __('auth.login') }}</x-forms.button>
|
<x-forms.button type="submit">{{ __('auth.login') }}</x-forms.button>
|
||||||
|
@foreach ($enabled_oauth_providers as $provider_setting)
|
||||||
|
<x-forms.button type="button" onclick="document.location.href='/auth/{{$provider_setting->provider}}/redirect'">
|
||||||
|
{{ __("auth.login.$provider_setting->provider") }}
|
||||||
|
</x-forms.button>
|
||||||
|
@endforeach
|
||||||
@if (!$is_registration_enabled)
|
@if (!$is_registration_enabled)
|
||||||
<div class="text-center ">{{ __('auth.registration_disabled') }}</div>
|
<div class="text-center ">{{ __('auth.registration_disabled') }}</div>
|
||||||
@endif
|
@endif
|
||||||
|
30
resources/views/livewire/settings/auth.blade.php
Normal file
30
resources/views/livewire/settings/auth.blade.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<div>
|
||||||
|
<form wire:submit='submit' class="flex flex-col">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<h2>Authentication</h2>
|
||||||
|
<x-forms.button type="submit">
|
||||||
|
Save
|
||||||
|
</x-forms.button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col gap-2 pt-4">
|
||||||
|
@foreach ($oauth_settings_map as $oauth_setting)
|
||||||
|
<div class="p-4 border border-coolgray-500">
|
||||||
|
<h3>{{ucfirst($oauth_setting->provider)}} Oauth</h3>
|
||||||
|
<div class="w-32">
|
||||||
|
<x-forms.checkbox instantSave id="oauth_settings_map.{{$oauth_setting->provider}}.enabled" label="Enabled" />
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||||
|
<x-forms.input id="oauth_settings_map.{{$oauth_setting->provider}}.client_id" label="Client ID" />
|
||||||
|
<x-forms.input id="oauth_settings_map.{{$oauth_setting->provider}}.client_secret" type="password" label="Client Secret" />
|
||||||
|
<x-forms.input id="oauth_settings_map.{{$oauth_setting->provider}}.redirect_uri" label="Redirect URI" />
|
||||||
|
@if ($oauth_setting->provider == 'azure')
|
||||||
|
<x-forms.input id="oauth_settings_map.{{$oauth_setting->provider}}.tenant" label="Tenant" />
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
@ -9,6 +9,8 @@
|
|||||||
<a :class="activeTab === 'smtp' && 'text-white'"
|
<a :class="activeTab === 'smtp' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'smtp'; window.location.hash = 'smtp'" href="#">Transactional
|
@click.prevent="activeTab = 'smtp'; window.location.hash = 'smtp'" href="#">Transactional
|
||||||
Email</a>
|
Email</a>
|
||||||
|
<a :class="activeTab === 'auth' && 'text-white'"
|
||||||
|
@click.prevent="activeTab = 'auth'; window.location.hash = 'auth'" href="#">Authentication</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full pl-8">
|
<div class="w-full pl-8">
|
||||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||||
@ -20,6 +22,9 @@
|
|||||||
<div x-cloak x-show="activeTab === 'smtp'" class="h-full">
|
<div x-cloak x-show="activeTab === 'smtp'" class="h-full">
|
||||||
<livewire:settings.email :settings="$settings" />
|
<livewire:settings.email :settings="$settings" />
|
||||||
</div>
|
</div>
|
||||||
|
<div x-cloak x-show="activeTab === 'auth'" class="h-full">
|
||||||
|
<livewire:settings.auth />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Controllers\MagicController;
|
use App\Http\Controllers\MagicController;
|
||||||
|
use App\Http\Controllers\OauthController;
|
||||||
use App\Livewire\Admin\Index as AdminIndex;
|
use App\Livewire\Admin\Index as AdminIndex;
|
||||||
use App\Livewire\Dev\Compose as Compose;
|
use App\Livewire\Dev\Compose as Compose;
|
||||||
|
|
||||||
@ -93,6 +93,9 @@
|
|||||||
Route::get('/auth/link', [Controller::class, 'link'])->name('auth.link');
|
Route::get('/auth/link', [Controller::class, 'link'])->name('auth.link');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::get('/auth/{provider}/redirect', [OauthController::class, 'redirect'])->name('auth.redirect');
|
||||||
|
Route::get('/auth/{provider}/callback', [OauthController::class, 'callback'])->name('auth.callback');
|
||||||
|
|
||||||
Route::prefix('magic')->middleware(['auth'])->group(function () {
|
Route::prefix('magic')->middleware(['auth'])->group(function () {
|
||||||
Route::get('/servers', [MagicController::class, 'servers']);
|
Route::get('/servers', [MagicController::class, 'servers']);
|
||||||
Route::get('/destinations', [MagicController::class, 'destinations']);
|
Route::get('/destinations', [MagicController::class, 'destinations']);
|
||||||
|
Loading…
Reference in New Issue
Block a user