Compare commits
14
Commits
4e774e4fe1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce72d28912 | ||
|
|
f3b226a0fd | ||
|
|
7bbf7f68e4 | ||
|
|
e663b03c0e | ||
|
|
4a718ce763 | ||
|
|
d8c8f2d1e0 | ||
|
|
883e637c46 | ||
|
|
4512da5140 | ||
|
|
1a19aee52d | ||
|
|
5e5bb62d75 | ||
|
|
cd80efe1e3 | ||
|
|
0df43fefcb | ||
|
|
ae6869781e | ||
|
|
c09da27dea |
No files matched your search
@@ -5,9 +5,31 @@
|
|||||||
[](https://github.com/alexandergabriel/filament-oauth2/actions?query=workflow%3A"Fix+PHP+code+styling"+branch%3Amain)
|
[](https://github.com/alexandergabriel/filament-oauth2/actions?query=workflow%3A"Fix+PHP+code+styling"+branch%3Amain)
|
||||||
[](https://packagist.org/packages/alexandergabriel/filament-oauth2)
|
[](https://packagist.org/packages/alexandergabriel/filament-oauth2)
|
||||||
|
|
||||||
|
> !!!
|
||||||
|
> This Plugin is still under development and only tested with Keycloak.
|
||||||
|
> This is my first FilamentPHP-Plugin.
|
||||||
|
> Did not write any tests, not published to packagist yet...
|
||||||
|
> Feedback welcome.
|
||||||
|
> !!!
|
||||||
|
|
||||||
|
To be able to install you have to add/change this to/in your composer.json:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://github.com/AlexanderGabriel/filament-oauth2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
This is where your description should go. Limit it to a paragraph or two. Consider adding a small example.
|
This Plugin enables OAuth2-Login for [FilamentPHP](https://filamentphp.com) Panels.
|
||||||
|
Login and logout is done by OAuth2-Server.
|
||||||
|
If the OAuth2-Server provides roles for your client, they will be mapped to the App\Models\Role-Model
|
||||||
|
Non-existing Roles will be created.
|
||||||
|
Users will be detached to roles not in the access token any more.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -17,39 +39,75 @@ You can install the package via composer:
|
|||||||
composer require alexandergabriel/filament-oauth2
|
composer require alexandergabriel/filament-oauth2
|
||||||
```
|
```
|
||||||
|
|
||||||
You can publish and run the migrations with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
php artisan vendor:publish --tag="filament-oauth2-migrations"
|
|
||||||
php artisan migrate
|
|
||||||
```
|
|
||||||
|
|
||||||
You can publish the config file with:
|
You can publish the config file with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
php artisan vendor:publish --tag="filament-oauth2-config"
|
php artisan vendor:publish --tag="filament-oauth2-config"
|
||||||
```
|
```
|
||||||
|
|
||||||
Optionally, you can publish the views using
|
|
||||||
|
|
||||||
```bash
|
|
||||||
php artisan vendor:publish --tag="filament-oauth2-views"
|
|
||||||
```
|
|
||||||
|
|
||||||
This is the contents of the published config file:
|
This is the contents of the published config file:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
return [
|
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_RESOURCE_OWNER_DETAILS", env("OAUTH2_BASE_URL")."/userinfo"),
|
||||||
|
'urlLogout' => env("OAUTH2_URL_LOGOUT", env("OAUTH2_BASE_URL")."/logout"),
|
||||||
|
'urlAfterlogout' => env("OAUTH2_URL_AFTER_LOGOUT", url('/')),
|
||||||
|
'scopes' => env("OAUTH2_SCOPES", "profile email openid"),
|
||||||
|
'updateRoles' => env("OAUTH2_UPDATE_ROLES", false)
|
||||||
];
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
Load Plugin in your PanelProvider under filament-oauth2-demo/app/Providers/Filament:
|
||||||
```php
|
```php
|
||||||
$filamentOauth2 = new AlexanderGabriel\FilamentOauth2();
|
class YOURPanelProvider extends PanelProvider
|
||||||
echo $filamentOauth2->echoPhrase('Hello, AlexanderGabriel!');
|
{
|
||||||
|
public function panel(Panel $panel): Panel
|
||||||
|
{
|
||||||
|
return $panel
|
||||||
|
->plugin(
|
||||||
|
new FilamentOauth2Plugin()
|
||||||
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### To configure, add some config to your .env:
|
||||||
|
|
||||||
|
- OAUTH2_CLIENT_ID*
|
||||||
|
- OAuth2 client id, mandatory
|
||||||
|
- OAUTH2_CLIENT_SECRET*
|
||||||
|
- OAuth2 client secret, mandatory
|
||||||
|
- OAUTH2_BASE_URL*
|
||||||
|
- Base url to OAuth2 authentication server
|
||||||
|
- must include realm: https://DOMAIN/realms/REALM/protocol/openid-connect
|
||||||
|
- OAUTH2_URL_AUTHORIZE
|
||||||
|
- authorization url
|
||||||
|
- defaults to OAUTH2_BASE_URL+/auth
|
||||||
|
- OAUTH2_URL_ACCESS_TOKEN
|
||||||
|
- token url
|
||||||
|
- defaults to OAUTH2_BASE_URL+/token
|
||||||
|
- OAUTH2_URL_RESOURCE_OWNER_DETAILS
|
||||||
|
- resource owner details url
|
||||||
|
- defaults to OAUTH2_BASE_URL+/userinfo
|
||||||
|
- todo: needed?
|
||||||
|
- OAUTH2_URL_LOGOUT
|
||||||
|
- logout url
|
||||||
|
- defaults to OAUTH2_BASE_URL+/logout
|
||||||
|
- OAUTH2_URL_AFTER_LOGOUT
|
||||||
|
- post_logout_redirect_uri
|
||||||
|
- defaults to base url of Laravel app (without panel)
|
||||||
|
- OAUTH2_SCOPES
|
||||||
|
- scopes
|
||||||
|
- defaults to "profile email openid"
|
||||||
|
- OAUTH2_UPDATE_ROLES
|
||||||
|
- look for roles in token and update/create and map them
|
||||||
|
- defaults to false
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -70,6 +128,7 @@ Please review [our security policy](../../security/policy) on how to report secu
|
|||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
|
- To all helping developing and keeping alive FilamentPHP, PHP, OAuth2 and the OpenSource Ecosystem!
|
||||||
- [Alexander Gabriel](https://github.com/AlexanderGabriel)
|
- [Alexander Gabriel](https://github.com/AlexanderGabriel)
|
||||||
- [All Contributors](../../contributors)
|
- [All Contributors](../../contributors)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# This is my package filament-oauth2
|
||||||
|
|
||||||
|
[](https://packagist.org/packages/alexandergabriel/filament-oauth2)
|
||||||
|
[](https://github.com/alexandergabriel/filament-oauth2/actions?query=workflow%3Arun-tests+branch%3Amain)
|
||||||
|
[](https://github.com/alexandergabriel/filament-oauth2/actions?query=workflow%3A"Fix+PHP+code+styling"+branch%3Amain)
|
||||||
|
[](https://packagist.org/packages/alexandergabriel/filament-oauth2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This is where your description should go. Limit it to a paragraph or two. Consider adding a small example.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
You can install the package via composer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require alexandergabriel/filament-oauth2
|
||||||
|
```
|
||||||
|
|
||||||
|
You can publish and run the migrations with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan vendor:publish --tag="filament-oauth2-migrations"
|
||||||
|
php artisan migrate
|
||||||
|
```
|
||||||
|
|
||||||
|
You can publish the config file with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan vendor:publish --tag="filament-oauth2-config"
|
||||||
|
```
|
||||||
|
|
||||||
|
Optionally, you can publish the views using
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan vendor:publish --tag="filament-oauth2-views"
|
||||||
|
```
|
||||||
|
|
||||||
|
This is the contents of the published config file:
|
||||||
|
|
||||||
|
```php
|
||||||
|
return [
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```php
|
||||||
|
$filamentOauth2 = new AlexanderGabriel\FilamentOauth2();
|
||||||
|
echo $filamentOauth2->echoPhrase('Hello, AlexanderGabriel!');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.
|
||||||
|
|
||||||
|
## Security Vulnerabilities
|
||||||
|
|
||||||
|
Please review [our security policy](../../security/policy) on how to report security vulnerabilities.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
- [Alexander Gabriel](https://github.com/AlexanderGabriel)
|
||||||
|
- [All Contributors](../../contributors)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "alexandergabriel/filament-oauth2",
|
"name": "alexandergabriel/filament-oauth2",
|
||||||
"description": "This is my package filament-oauth2",
|
"description": "Enable OAuth2 Authentication to FilamentPHP Panels",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"AlexanderGabriel",
|
"AlexanderGabriel",
|
||||||
"laravel",
|
"laravel",
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1",
|
"php": "^8.1",
|
||||||
"filament/filament": "^3.0",
|
"filament/filament": "^4.0",
|
||||||
"league/oauth2-client": "*",
|
"league/oauth2-client": "*",
|
||||||
"spatie/laravel-package-tools": "^1.15.0"
|
"spatie/laravel-package-tools": "^1.15.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
// config for AlexanderGabriel/FilamentOauth2
|
// config for AlexanderGabriel/FilamentOauth2
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
'clientId' => env("OAUTH2_CLIENT_ID"),
|
'clientId' => env("OAUTH2_CLIENT_ID"),
|
||||||
'clientSecret' => env("OAUTH2_CLIENT_SECRET"),
|
'clientSecret' => env("OAUTH2_CLIENT_SECRET"),
|
||||||
'baseUrl' => env("OAUTH2_BASE_URL"), // https://DOMAIN/realms/REALM/protocol/openid-connect
|
'baseUrl' => env("OAUTH2_BASE_URL"), // https://DOMAIN/realms/REALM/protocol/openid-connect
|
||||||
'urlAuthorize' => env("OAUTH2_URL_AUTHORIZE", env("OAUTH2_BASE_URL")."/auth"),
|
'urlAuthorize' => env("OAUTH2_URL_AUTHORIZE", env("OAUTH2_BASE_URL")."/auth"),
|
||||||
'urlAccessToken' => env("OAUTH2_URL_ACCESS_TOKEN", env("OAUTH2_BASE_URL")."/token"),
|
'urlAccessToken' => env("OAUTH2_URL_ACCESS_TOKEN", env("OAUTH2_BASE_URL")."/token"),
|
||||||
'urlResourceOwnerDetails' => env("OAUTH2_URL_RSOURCE_OWNER_DETAILS", env("OAUTH2_BASE_URL")."/userinfo"),
|
'urlResourceOwnerDetails' => env("OAUTH2_URL_RESOURCE_OWNER_DETAILS", env("OAUTH2_BASE_URL")."/userinfo"),
|
||||||
|
'urlLogout' => env("OAUTH2_URL_LOGOUT", env("OAUTH2_BASE_URL")."/logout"),
|
||||||
|
'urlAfterlogout' => env("OAUTH2_URL_AFTER_LOGOUT", url('/')),
|
||||||
'scopes' => env("OAUTH2_SCOPES", "profile email openid"),
|
'scopes' => env("OAUTH2_SCOPES", "profile email openid"),
|
||||||
'updateRoles' => env("OAUTH2_UPDATE_ROLES", false)
|
'updateRoles' => env("OAUTH2_UPDATE_ROLES", false)
|
||||||
|
|
||||||
];
|
];
|
||||||
+3
-4
@@ -6,7 +6,7 @@ use AlexanderGabriel\FilamentOauth2\Http\Controllers\Oauth2Controller;
|
|||||||
use Filament\Facades\Filament;
|
use Filament\Facades\Filament;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
$panel = Filament::getCurrentPanel();
|
$panel = Filament::getCurrentOrDefaultPanel();
|
||||||
|
|
||||||
Route::prefix($panel->getPath())
|
Route::prefix($panel->getPath())
|
||||||
->middleware($panel->getMiddleware())
|
->middleware($panel->getMiddleware())
|
||||||
@@ -15,12 +15,11 @@ Route::prefix($panel->getPath())
|
|||||||
Route::name('filament-oauth2.')
|
Route::name('filament-oauth2.')
|
||||||
->prefix('filament-oauth2')
|
->prefix('filament-oauth2')
|
||||||
->group(function () {
|
->group(function () {
|
||||||
|
Route::get('handleLogout', [Oauth2Controller::class, 'handleLogout'])->name('handleLogout');
|
||||||
Route::get('redirectToOauth2Server', [Oauth2Controller::class, 'redirectToOauth2Server'])
|
Route::get('redirectToOauth2Server', [Oauth2Controller::class, 'redirectToOauth2Server'])
|
||||||
->name('redirectToOauth2Server');
|
->name('redirectToOauth2Server');
|
||||||
Route::get('handleCallback', [Oauth2Controller::class, 'handleCallback'])
|
Route::get('handleCallback', [Oauth2Controller::class, 'handleCallback'])
|
||||||
->name('handleCallback');
|
->name('handleCallback');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -4,6 +4,7 @@ namespace AlexanderGabriel\FilamentOauth2;
|
|||||||
|
|
||||||
use AlexanderGabriel\FilamentOauth2\Facades\FilamentOauth2;
|
use AlexanderGabriel\FilamentOauth2\Facades\FilamentOauth2;
|
||||||
use Filament\Contracts\Plugin;
|
use Filament\Contracts\Plugin;
|
||||||
|
use Filament\Navigation\MenuItem;
|
||||||
use Filament\Panel;
|
use Filament\Panel;
|
||||||
|
|
||||||
class FilamentOauth2Plugin implements Plugin
|
class FilamentOauth2Plugin implements Plugin
|
||||||
@@ -15,7 +16,15 @@ class FilamentOauth2Plugin implements Plugin
|
|||||||
|
|
||||||
public function register(Panel $panel): void
|
public function register(Panel $panel): void
|
||||||
{
|
{
|
||||||
$panel->login(FilamentOauth2::getLoginRouteAction());
|
$panel
|
||||||
|
->login(FilamentOauth2::getLoginRouteAction())
|
||||||
|
->userMenuItems([
|
||||||
|
'logout' => MenuItem::make()->url(function () {
|
||||||
|
$panel = filament()->getCurrentPanel();
|
||||||
|
return '/'.$panel->getPath().'/'.$this->getId().'/handleLogout';
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function boot(Panel $panel): void
|
public function boot(Panel $panel): void
|
||||||
|
|||||||
@@ -51,15 +51,6 @@ class FilamentOauth2ServiceProvider extends PackageServiceProvider
|
|||||||
|
|
||||||
public function packageBooted(): void
|
public function packageBooted(): void
|
||||||
{
|
{
|
||||||
// Handle Stubs
|
|
||||||
if (app()->runningInConsole()) {
|
|
||||||
foreach (app(Filesystem::class)->files(__DIR__ . '/../stubs/') as $file) {
|
|
||||||
$this->publishes([
|
|
||||||
$file->getRealPath() => base_path("stubs/filament-oauth2/{$file->getFilename()}"),
|
|
||||||
], 'filament-oauth2-stubs');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Testing
|
// Testing
|
||||||
Testable::mixin(new TestsFilamentOauth2);
|
Testable::mixin(new TestsFilamentOauth2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,19 +5,22 @@ namespace AlexanderGabriel\FilamentOauth2\Http\Controllers;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Role;
|
use App\Models\Role;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Dotenv\Exception\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Filament\Auth\Http\Responses\LoginResponse;
|
||||||
use Filament\Facades\Filament;
|
use Filament\Facades\Filament;
|
||||||
use Filament\Http\Responses\Auth\LoginResponse;
|
|
||||||
use Filament\Models\Contracts\FilamentUser;
|
use Filament\Models\Contracts\FilamentUser;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
|
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
|
||||||
use League\OAuth2\Client\Provider\GenericProvider;
|
use League\OAuth2\Client\Provider\GenericProvider;
|
||||||
use League\OAuth2\Client\Token\AccessToken;
|
|
||||||
|
|
||||||
class Oauth2Controller extends Controller
|
class Oauth2Controller extends Controller
|
||||||
{
|
{
|
||||||
private GenericProvider $oauth2Provider;
|
private GenericProvider $oauth2Provider;
|
||||||
|
private Model $user;
|
||||||
|
private $accessToken;
|
||||||
|
private $oauth2User;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -41,79 +44,41 @@ class Oauth2Controller extends Controller
|
|||||||
public function handleCallback(Request $request)
|
public function handleCallback(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$accessToken = $this->oauth2Provider->getAccessToken('authorization_code', ['code' => $request->input('code')]);
|
$this->accessToken = $this->oauth2Provider->getAccessToken('authorization_code', ['code' => $request->input('code')]);
|
||||||
$oauth2User = $this->oauth2Provider->getResourceOwner($accessToken)->toArray();
|
$this->oauth2User = $this->oauth2Provider->getResourceOwner($this->accessToken)->toArray();
|
||||||
|
|
||||||
$user = User::firstOrCreate([
|
// Create the user if it does not exist
|
||||||
'email' => $oauth2User['email'],
|
$this->user = User::firstOrCreate([
|
||||||
|
'email' => $this->oauth2User['email'],
|
||||||
],[
|
],[
|
||||||
'name' => $oauth2User['name'],
|
'name' => $this->oauth2User['name'],
|
||||||
|
// Todo -> is there a better way?
|
||||||
'password' => 'nonsense'
|
'password' => 'nonsense'
|
||||||
]);
|
]);
|
||||||
if($user->name != $oauth2User['name'])
|
|
||||||
|
// Update user data if different from Oauth2-Server
|
||||||
|
if($this->user->name != $this->oauth2User['name'])
|
||||||
{
|
{
|
||||||
$user->name = $oauth2User['name'];
|
$this->user->name = $this->oauth2User['name'];
|
||||||
$user->save();
|
$this->user->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
Filament::auth()->loginUsingId($user->id, false);
|
// Login User by id
|
||||||
|
Filament::auth()->loginUsingId($this->user->id, false);
|
||||||
|
|
||||||
|
// Taken from original LoginClass...
|
||||||
if (
|
if (
|
||||||
($user instanceof FilamentUser) &&
|
($this->user instanceof FilamentUser) &&
|
||||||
(! $user->canAccessPanel(Filament::getCurrentPanel()))
|
(! $this->user->canAccessPanel(Filament::getCurrentPanel()))
|
||||||
) {
|
) {
|
||||||
Filament::auth()->logout();
|
Filament::auth()->logout();
|
||||||
|
|
||||||
$this->throwFailureValidationException();
|
$this->throwFailureValidationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
session()->regenerate();
|
session()->regenerate();
|
||||||
|
|
||||||
//Should i update Roles and are there roles?
|
// Handle Role Mapping
|
||||||
$hasRoles = false;
|
$this->handleRoleMapping();
|
||||||
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);
|
return app(LoginResponse::class);
|
||||||
|
|
||||||
@@ -122,6 +87,51 @@ class Oauth2Controller extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function handleRoleMapping(): void
|
||||||
|
{
|
||||||
|
if(config('filament-oauth2.updateRoles') != false) {
|
||||||
|
try {
|
||||||
|
$roles = $this->user->roles();
|
||||||
|
if($roles) {
|
||||||
|
// Are there roles in the Token?
|
||||||
|
$this->accessToken = explode(".", $this->accessToken);
|
||||||
|
if(isset($this->accessToken[1])) {
|
||||||
|
$this->accessToken = json_decode(base64_decode($this->accessToken[1]));
|
||||||
|
$clientId = config('filament-oauth2.clientId');
|
||||||
|
if(isset($this->accessToken->resource_access) && isset($this->accessToken->resource_access->$clientId)) {
|
||||||
|
// Roles are defined. Maybe empty to remove all Roles from user
|
||||||
|
// TODO: test this without roles
|
||||||
|
if(!isset($this->accessToken->resource_access->$clientId->roles)) $roles = [];
|
||||||
|
else $roles = $this->accessToken->resource_access->$clientId->roles;
|
||||||
|
$userRoles = $this->user->roles();
|
||||||
|
// Disconnect roles not in the access token any more
|
||||||
|
foreach ($userRoles as $userRole) {
|
||||||
|
if(!in_array($userRole, $roles)) {
|
||||||
|
$this->user->roles()->detach($userRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Connect or create roles
|
||||||
|
foreach($roles as $role) {
|
||||||
|
$existingRole = Role::first('name', '=', $role);
|
||||||
|
if($existingRole) {
|
||||||
|
$this->user->roles()->attach($existingRole->id);
|
||||||
|
} else {
|
||||||
|
$newRole = Role::create(['name' => $role]);
|
||||||
|
// needed?
|
||||||
|
$newRole->save();
|
||||||
|
$this->user->roles()->attach($newRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
// No Roles. Nothing to do
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function throwFailureValidationException(): never
|
protected function throwFailureValidationException(): never
|
||||||
{
|
{
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
@@ -129,8 +139,14 @@ class Oauth2Controller extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Logout
|
public function handleLogout(Request $request)
|
||||||
// filament-oauth2-demo/vendor/filament/filament/src/Http/Controllers/Auth/LogoutController.php
|
{
|
||||||
|
// https://openid.net/specs/openid-connect-rpinitiated-1_0.html
|
||||||
|
session()->invalidate();
|
||||||
|
session()->regenerateToken();
|
||||||
|
Filament::auth()->logout();
|
||||||
|
$logoutUrl = config('filament-oauth2.urlLogout').'?client_id=filamentphp';
|
||||||
|
if(config('filament-oauth2.urlAfterlogout') != url('/')) $logoutUrl .= '&post_logout_redirect_uri='.config('filament-oauth2.urlAfterlogout');
|
||||||
|
return redirect($logoutUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Whitespace-only changes.
Reference in new issue
Block a user