Compare commits
No commits in common. "6840624be2ed8850b4a34b611965e617b1496361" and "e24e019609bcae6c43ab828bfce0cf04ab8c0dc7" have entirely different histories.
6840624be2
...
e24e019609
@ -22,7 +22,6 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1",
|
"php": "^8.1",
|
||||||
"filament/filament": "^3.0",
|
"filament/filament": "^3.0",
|
||||||
"league/oauth2-client": "*",
|
|
||||||
"spatie/laravel-package-tools": "^1.15.0"
|
"spatie/laravel-package-tools": "^1.15.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// config for AlexanderGabriel/FilamentOauth2
|
|
||||||
|
|
||||||
return [
|
|
||||||
|
|
||||||
'clientId' => env("OAUTH2_CLIENT_ID"),
|
|
||||||
'clientSecret' => env("OAUTH2_CLIENT_SECRET"),
|
|
||||||
'baseUrl' => env("OAUTH2_BASE_URL"), // https://DOMAIN/realms/REALM/protocol/openid-connect
|
|
||||||
'urlAuthorize' => env("OAUTH2_URL_AUTHORIZE", env("OAUTH2_BASE_URL")."/auth"),
|
|
||||||
'urlAccessToken' => env("OAUTH2_URL_ACCESS_TOKEN", env("OAUTH2_BASE_URL")."/token"),
|
|
||||||
'urlResourceOwnerDetails' => env("OAUTH2_URL_RSOURCE_OWNER_DETAILS", env("OAUTH2_BASE_URL")."/userinfo"),
|
|
||||||
'scopes' => env("OAUTH2_SCOPES", "profile email openid"),
|
|
||||||
'updateRoles' => env("OAUTH2_UPDATE_ROLES", false)
|
|
||||||
|
|
||||||
];
|
|
||||||
6
config/oauth2.php
Normal file
6
config/oauth2.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// config for AlexanderGabriel/FilamentOauth2
|
||||||
|
return [
|
||||||
|
|
||||||
|
];
|
||||||
19
database/migrations/create_oauth2_table.php.stub
Normal file
19
database/migrations/create_oauth2_table.php.stub
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('filament_oauth2_table', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
// add fields
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// https://github.com/filamentphp/actions/blob/4.x/routes/web.php
|
|
||||||
|
|
||||||
use AlexanderGabriel\FilamentOauth2\Http\Controllers\Oauth2Controller;
|
|
||||||
use Filament\Facades\Filament;
|
|
||||||
use Illuminate\Support\Facades\Route;
|
|
||||||
|
|
||||||
$panel = Filament::getCurrentPanel();
|
|
||||||
|
|
||||||
Route::prefix($panel->getPath())
|
|
||||||
->middleware($panel->getMiddleware())
|
|
||||||
->group(function () {
|
|
||||||
Route::get('login', [Oauth2Controller::class, 'redirectToOauth2Server'])->name('redirectToOauth2Server');
|
|
||||||
Route::name('filament-oauth2.')
|
|
||||||
->prefix('filament-oauth2')
|
|
||||||
->group(function () {
|
|
||||||
Route::get('redirectToOauth2Server', [Oauth2Controller::class, 'redirectToOauth2Server'])
|
|
||||||
->name('redirectToOauth2Server');
|
|
||||||
Route::get('handleCallback', [Oauth2Controller::class, 'handleCallback'])
|
|
||||||
->name('handleCallback');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
@ -2,12 +2,4 @@
|
|||||||
|
|
||||||
namespace AlexanderGabriel\FilamentOauth2;
|
namespace AlexanderGabriel\FilamentOauth2;
|
||||||
|
|
||||||
use AlexanderGabriel\FilamentOauth2\Http\Controllers\Oauth2Controller;
|
class FilamentOauth2 {}
|
||||||
|
|
||||||
class FilamentOauth2 {
|
|
||||||
|
|
||||||
public static function getLoginRouteAction(): array
|
|
||||||
{
|
|
||||||
return [Oauth2Controller::class, 'redirectToOauth2Server'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace AlexanderGabriel\FilamentOauth2;
|
namespace AlexanderGabriel\FilamentOauth2;
|
||||||
|
|
||||||
use AlexanderGabriel\FilamentOauth2\Facades\FilamentOauth2;
|
|
||||||
use Filament\Contracts\Plugin;
|
use Filament\Contracts\Plugin;
|
||||||
use Filament\Panel;
|
use Filament\Panel;
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ class FilamentOauth2Plugin implements Plugin
|
|||||||
|
|
||||||
public function register(Panel $panel): void
|
public function register(Panel $panel): void
|
||||||
{
|
{
|
||||||
$panel->login(FilamentOauth2::getLoginRouteAction());
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
public function boot(Panel $panel): void
|
public function boot(Panel $panel): void
|
||||||
|
|||||||
@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
namespace AlexanderGabriel\FilamentOauth2;
|
namespace AlexanderGabriel\FilamentOauth2;
|
||||||
|
|
||||||
|
use Filament\Support\Assets\AlpineComponent;
|
||||||
|
use Filament\Support\Assets\Asset;
|
||||||
|
use Filament\Support\Assets\Css;
|
||||||
|
use Filament\Support\Assets\Js;
|
||||||
|
use Filament\Support\Facades\FilamentAsset;
|
||||||
|
use Filament\Support\Facades\FilamentIcon;
|
||||||
use Illuminate\Filesystem\Filesystem;
|
use Illuminate\Filesystem\Filesystem;
|
||||||
use Livewire\Features\SupportTesting\Testable;
|
use Livewire\Features\SupportTesting\Testable;
|
||||||
use Spatie\LaravelPackageTools\Commands\InstallCommand;
|
use Spatie\LaravelPackageTools\Commands\InstallCommand;
|
||||||
@ -28,9 +34,10 @@ class FilamentOauth2ServiceProvider extends PackageServiceProvider
|
|||||||
->hasInstallCommand(function (InstallCommand $command) {
|
->hasInstallCommand(function (InstallCommand $command) {
|
||||||
$command
|
$command
|
||||||
->publishConfigFile()
|
->publishConfigFile()
|
||||||
|
->publishMigrations()
|
||||||
|
->askToRunMigrations()
|
||||||
->askToStarRepoOnGitHub('alexandergabriel/filament-oauth2');
|
->askToStarRepoOnGitHub('alexandergabriel/filament-oauth2');
|
||||||
})
|
});
|
||||||
->hasRoutes('web');
|
|
||||||
|
|
||||||
$configFileName = $package->shortName();
|
$configFileName = $package->shortName();
|
||||||
|
|
||||||
@ -38,6 +45,10 @@ class FilamentOauth2ServiceProvider extends PackageServiceProvider
|
|||||||
$package->hasConfigFile();
|
$package->hasConfigFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file_exists($package->basePath('/../database/migrations'))) {
|
||||||
|
$package->hasMigrations($this->getMigrations());
|
||||||
|
}
|
||||||
|
|
||||||
if (file_exists($package->basePath('/../resources/lang'))) {
|
if (file_exists($package->basePath('/../resources/lang'))) {
|
||||||
$package->hasTranslations();
|
$package->hasTranslations();
|
||||||
}
|
}
|
||||||
@ -51,6 +62,20 @@ class FilamentOauth2ServiceProvider extends PackageServiceProvider
|
|||||||
|
|
||||||
public function packageBooted(): void
|
public function packageBooted(): void
|
||||||
{
|
{
|
||||||
|
// Asset Registration
|
||||||
|
FilamentAsset::register(
|
||||||
|
$this->getAssets(),
|
||||||
|
$this->getAssetPackageName()
|
||||||
|
);
|
||||||
|
|
||||||
|
FilamentAsset::registerScriptData(
|
||||||
|
$this->getScriptData(),
|
||||||
|
$this->getAssetPackageName()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Icon Registration
|
||||||
|
FilamentIcon::register($this->getIcons());
|
||||||
|
|
||||||
// Handle Stubs
|
// Handle Stubs
|
||||||
if (app()->runningInConsole()) {
|
if (app()->runningInConsole()) {
|
||||||
foreach (app(Filesystem::class)->files(__DIR__ . '/../stubs/') as $file) {
|
foreach (app(Filesystem::class)->files(__DIR__ . '/../stubs/') as $file) {
|
||||||
@ -64,6 +89,23 @@ class FilamentOauth2ServiceProvider extends PackageServiceProvider
|
|||||||
Testable::mixin(new TestsFilamentOauth2);
|
Testable::mixin(new TestsFilamentOauth2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getAssetPackageName(): ?string
|
||||||
|
{
|
||||||
|
return 'alexandergabriel/filament-oauth2';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<Asset>
|
||||||
|
*/
|
||||||
|
protected function getAssets(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// AlpineComponent::make('filament-oauth2', __DIR__ . '/../resources/dist/components/filament-oauth2.js'),
|
||||||
|
Css::make('filament-oauth2-styles', __DIR__ . '/../resources/dist/filament-oauth2.css'),
|
||||||
|
Js::make('filament-oauth2-scripts', __DIR__ . '/../resources/dist/filament-oauth2.js'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<class-string>
|
* @return array<class-string>
|
||||||
*/
|
*/
|
||||||
@ -74,6 +116,14 @@ class FilamentOauth2ServiceProvider extends PackageServiceProvider
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
protected function getIcons(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string>
|
* @return array<string>
|
||||||
*/
|
*/
|
||||||
@ -82,4 +132,21 @@ class FilamentOauth2ServiceProvider extends PackageServiceProvider
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
protected function getScriptData(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
protected function getMigrations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'create_filament-oauth2_table',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,136 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace AlexanderGabriel\FilamentOauth2\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Role;
|
|
||||||
use App\Models\User;
|
|
||||||
use Dotenv\Exception\ValidationException;
|
|
||||||
use Exception;
|
|
||||||
use Filament\Facades\Filament;
|
|
||||||
use Filament\Http\Responses\Auth\LoginResponse;
|
|
||||||
use Filament\Models\Contracts\FilamentUser;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
|
|
||||||
use League\OAuth2\Client\Provider\GenericProvider;
|
|
||||||
use League\OAuth2\Client\Token\AccessToken;
|
|
||||||
|
|
||||||
class Oauth2Controller extends Controller
|
|
||||||
{
|
|
||||||
private GenericProvider $oauth2Provider;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
// https://oauth2-client.thephpleague.com/usage/
|
|
||||||
$this->oauth2Provider = new GenericProvider([
|
|
||||||
'clientId' => config('filament-oauth2.clientId'), // The client ID assigned to you by the provider
|
|
||||||
'clientSecret' => config('filament-oauth2.clientSecret'), // The client password assigned to you by the provider
|
|
||||||
'redirectUri' => route('filament-oauth2.handleCallback'),
|
|
||||||
'urlAuthorize' => config('filament-oauth2.urlAuthorize'),
|
|
||||||
'urlAccessToken' => config('filament-oauth2.urlAccessToken'),
|
|
||||||
'urlResourceOwnerDetails' => config('filament-oauth2.urlResourceOwnerDetails'),
|
|
||||||
'scopes' => config('filament-oauth2.scopes'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function redirectToOauth2Server()
|
|
||||||
{
|
|
||||||
return redirect($this->oauth2Provider->getAuthorizationUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handleCallback(Request $request)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$accessToken = $this->oauth2Provider->getAccessToken('authorization_code', ['code' => $request->input('code')]);
|
|
||||||
$oauth2User = $this->oauth2Provider->getResourceOwner($accessToken)->toArray();
|
|
||||||
|
|
||||||
$user = User::firstOrCreate([
|
|
||||||
'email' => $oauth2User['email'],
|
|
||||||
],[
|
|
||||||
'name' => $oauth2User['name'],
|
|
||||||
'password' => 'nonsense'
|
|
||||||
]);
|
|
||||||
if($user->name != $oauth2User['name'])
|
|
||||||
{
|
|
||||||
$user->name = $oauth2User['name'];
|
|
||||||
$user->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
Filament::auth()->loginUsingId($user->id, false);
|
|
||||||
|
|
||||||
if (
|
|
||||||
($user instanceof FilamentUser) &&
|
|
||||||
(! $user->canAccessPanel(Filament::getCurrentPanel()))
|
|
||||||
) {
|
|
||||||
Filament::auth()->logout();
|
|
||||||
|
|
||||||
$this->throwFailureValidationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
session()->regenerate();
|
|
||||||
|
|
||||||
//Should i update Roles and are there roles?
|
|
||||||
$hasRoles = false;
|
|
||||||
try {
|
|
||||||
$roles = $user->roles();
|
|
||||||
if($roles) $hasRoles = true;
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
//keine Rollen... Nichts tun...
|
|
||||||
}
|
|
||||||
if($hasRoles && config('filament-oauth2.updateRoles') != false) {
|
|
||||||
//Are there roles in the Token?
|
|
||||||
$accessToken = explode(".", $accessToken);
|
|
||||||
if(isset($accessToken[1])) {
|
|
||||||
$accessToken = json_decode(base64_decode($accessToken[1]));
|
|
||||||
$clientId = config('filament-oauth2.clientId');
|
|
||||||
if(isset($accessToken->resource_access) && isset($accessToken->resource_access->$clientId)) {
|
|
||||||
// Roles are defined. Maybe empty to remove all Roles from user
|
|
||||||
// TODO: test
|
|
||||||
if(!isset($accessToken->resource_access->$clientId->roles)) $roles = [];
|
|
||||||
else $roles = $accessToken->resource_access->$clientId->roles;
|
|
||||||
|
|
||||||
$userRoles = $user->roles();
|
|
||||||
|
|
||||||
//disconnect roles
|
|
||||||
foreach ($userRoles as $userRole) {
|
|
||||||
if(!in_array($userRole, $roles)) {
|
|
||||||
$user->roles()->detach($userRole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect or create roles
|
|
||||||
foreach($roles as $role) {
|
|
||||||
$existingRole = Role::first('name', '=', $role);
|
|
||||||
if($existingRole) {
|
|
||||||
$user->roles()->attach($existingRole->id);
|
|
||||||
} else {
|
|
||||||
$newRole = Role::create(['name' => $role]);
|
|
||||||
$newRole->save();
|
|
||||||
$user->roles()->attach($newRole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return app(LoginResponse::class);
|
|
||||||
|
|
||||||
} catch (IdentityProviderException $e) {
|
|
||||||
dd($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function throwFailureValidationException(): never
|
|
||||||
{
|
|
||||||
throw ValidationException::withMessages([
|
|
||||||
'data.email' => __('filament-panels::pages/auth/login.messages.failed'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Logout
|
|
||||||
// filament-oauth2-demo/vendor/filament/filament/src/Http/Controllers/Auth/LogoutController.php
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user