mirror of
https://github.com/bs-community/blessing-skin-server.git
synced 2025-01-08 12:07:42 +08:00
feat: OAuth scope (#287)
Co-authored-by: Pig Fang <g-plane@hotmail.com>
This commit is contained in:
parent
5fb4240a47
commit
387fe81a60
@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Passport\Exceptions\MissingScopeException;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
@ -30,6 +31,8 @@ class Handler extends ExceptionHandler
|
||||
if (Str::endsWith($model, 'Texture')) {
|
||||
$exception = new ModelNotFoundException(trans('skinlib.non-existent'));
|
||||
}
|
||||
} elseif ($exception instanceof MissingScopeException) {
|
||||
return json($exception->getMessage(), 403);
|
||||
}
|
||||
|
||||
return parent::render($request, $exception);
|
||||
|
@ -65,5 +65,7 @@ class Kernel extends HttpKernel
|
||||
'setup' => \App\Http\Middleware\CheckInstallation::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \App\Http\Middleware\CheckUserVerified::class,
|
||||
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
|
||||
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
|
||||
];
|
||||
}
|
||||
|
19
app/Models/Scope.php
Normal file
19
app/Models/Scope.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string $description
|
||||
*/
|
||||
class Scope extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'name', 'description',
|
||||
];
|
||||
}
|
54
app/Providers/AuthServiceProvider.php
Normal file
54
app/Providers/AuthServiceProvider.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Scope;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Laravel\Passport\Passport;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The policy mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $policies = [
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
Passport::routes();
|
||||
|
||||
$defaultScopes = [
|
||||
'User.Read' => 'auth.oauth.scope.user.read',
|
||||
'Notification.Read' => 'auth.oauth.scope.notification.read',
|
||||
'Notification.ReadWrite' => 'auth.oauth.scope.notification.readwrite',
|
||||
'Player.Read' => 'auth.oauth.scope.player.read',
|
||||
'Player.ReadWrite' => 'auth.oauth.scope.player.readwrite',
|
||||
'Closet.Read' => 'auth.oauth.scope.closet.read',
|
||||
'Closet.ReadWrtie' => 'auth.oauth.scope.closet.readwrite',
|
||||
'UsersManagement.Read' => 'auth.oauth.scope.users-management.read',
|
||||
'UsersManagement.ReadWrite' => 'auth.oauth.scope.users-management.readwrite',
|
||||
'PlayersManagement.Read' => 'auth.oauth.scope.players-management.read',
|
||||
'PlayersManagement.ReadWrite' => 'auth.oauth.scope.players-management.readwrite',
|
||||
'ClosetManagement.Read' => 'auth.oauth.scope.closet-management.read',
|
||||
'ClosetManagement.ReadWrite' => 'auth.oauth.scope.closet-management.readwrite',
|
||||
'ReportsManagement.Read' => 'auth.oauth.scope.reports-management.read',
|
||||
'ReportsManagement.ReadWrite' => 'auth.oauth.scope.reports-management.readwrite',
|
||||
];
|
||||
|
||||
$scopes = Scope::all()->pluck('description', 'name')->all();
|
||||
|
||||
Passport::tokensCan(array_merge($defaultScopes, $scopes));
|
||||
|
||||
Passport::setDefaultScope(['User.Read']);
|
||||
}
|
||||
}
|
34
database/migrations/2021_04_14_181300_create_scope_table.php
Normal file
34
database/migrations/2021_04_14_181300_create_scope_table.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateScopeTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
if (!Schema::hasTable('scopes')) {
|
||||
Schema::create('scopes', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name')->unique();
|
||||
$table->string('description');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('scopes');
|
||||
}
|
||||
}
|
@ -64,6 +64,31 @@ oauth:
|
||||
title: Authorization
|
||||
introduction: A 3rd-party application ":name" is requesting permission to access your account.
|
||||
button: Authorize
|
||||
permissions: Permissions
|
||||
scope:
|
||||
user:
|
||||
read: Sign you in and read your profile
|
||||
notification:
|
||||
read: Allows the app to read your notifications.
|
||||
readwrite: Allows the app to send notifications.
|
||||
player:
|
||||
read: Allows the app to read your players.
|
||||
readwrite: Allows the app to create, read, update and delete your players.
|
||||
closet:
|
||||
read: Allows the app to read your closet items.
|
||||
readwrite: Allows the app to create, read, update and delete your closet items.
|
||||
users-management:
|
||||
read: Allows the app to read site's users.
|
||||
readwrite: Allows the app to create, read, update and delete site's users.
|
||||
players-management:
|
||||
read: Allows the app to read site's players.
|
||||
readwrite: Allows the app to create, read, update and delete site's players.
|
||||
closet-management:
|
||||
read: Allows the app to read user's of your site closet items.
|
||||
readwrite: Allows the app to create, read, update and delete user's closet items.
|
||||
reports-management:
|
||||
read: Allows the app to read user's reports.
|
||||
readwrite: Allows the app to read and review user's reports.
|
||||
|
||||
email: Email
|
||||
register-link: Register a new account
|
||||
|
12
resources/views/vendor/passport/authorize.twig
vendored
12
resources/views/vendor/passport/authorize.twig
vendored
@ -8,6 +8,18 @@
|
||||
<p class="login-box-msg">
|
||||
{{ trans('auth.oauth.authorization.introduction', {name: client.name}) }}
|
||||
</p>
|
||||
{% if scopes %}
|
||||
<div class="scopes">
|
||||
<p>
|
||||
<strong>{{ trans('auth.oauth.authorization.permission') }}</strong>
|
||||
</p>
|
||||
<ul>
|
||||
{% for scope in scopes %}
|
||||
<li>{{ trans(scope.description) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-flex justify-content-between">
|
||||
<form method="post" action="{{ route('passport.authorizations.approve', {}, false) }}">
|
||||
{{ csrf_field() }}
|
||||
|
@ -3,34 +3,42 @@
|
||||
Route::any('', 'HomeController@apiRoot');
|
||||
|
||||
Route::prefix('user')->middleware('auth:oauth')->group(function () {
|
||||
Route::get('', 'UserController@user');
|
||||
Route::get('', 'UserController@user')->middleware(['scope:User.Read']);
|
||||
|
||||
Route::get('notifications', 'NotificationsController@all');
|
||||
Route::post('notifications/{id}', 'NotificationsController@read');
|
||||
Route::middleware(['scope:Notification.Read'])->group(function () {
|
||||
Route::get('notifications', 'NotificationsController@all');
|
||||
Route::post('notifications/{id}', 'NotificationsController@read');
|
||||
});
|
||||
});
|
||||
|
||||
Route::prefix('players')->middleware('auth:oauth')->group(function () {
|
||||
Route::get('', 'PlayerController@list');
|
||||
Route::post('', 'PlayerController@add');
|
||||
Route::delete('{player}', 'PlayerController@delete');
|
||||
Route::put('{player}/name', 'PlayerController@rename');
|
||||
Route::put('{player}/textures', 'PlayerController@setTexture');
|
||||
Route::delete('{player}/textures', 'PlayerController@clearTexture');
|
||||
Route::get('', 'PlayerController@list')->middleware(['scope:Player.Read,Player.ReadWrite']);
|
||||
|
||||
Route::middleware(['scope:Player.ReadWrite'])->group(function () {
|
||||
Route::post('', 'PlayerController@add');
|
||||
Route::delete('{player}', 'PlayerController@delete');
|
||||
Route::put('{player}/name', 'PlayerController@rename');
|
||||
Route::put('{player}/textures', 'PlayerController@setTexture');
|
||||
Route::delete('{player}/textures', 'PlayerController@clearTexture');
|
||||
});
|
||||
});
|
||||
|
||||
Route::prefix('closet')->middleware('auth:oauth')->group(function () {
|
||||
Route::get('', 'ClosetController@getClosetData');
|
||||
Route::post('', 'ClosetController@add');
|
||||
Route::put('{tid}', 'ClosetController@rename');
|
||||
Route::delete('{tid}', 'ClosetController@remove');
|
||||
Route::get('', 'ClosetController@getClosetData')->middleware(['scope:Closet.Read,Closet.ReadWrite']);
|
||||
|
||||
Route::middleware(['scope:Closet.ReadWrite'])->group(function () {
|
||||
Route::post('', 'ClosetController@add');
|
||||
Route::put('{tid}', 'ClosetController@rename');
|
||||
Route::delete('{tid}', 'ClosetController@remove');
|
||||
});
|
||||
});
|
||||
|
||||
Route::prefix('admin')
|
||||
->middleware(['auth:oauth', 'role:admin'])
|
||||
->group(function () {
|
||||
Route::prefix('users')->group(function () {
|
||||
Route::get('', 'UsersManagementController@list')->name('list');
|
||||
Route::prefix('{user}')->group(function () {
|
||||
Route::get('', 'UsersManagementController@list')->name('list')->middleware(['scope:UsersManagement.Read,UsersManagement.ReadWrite']);
|
||||
Route::prefix('{user}')->middleware(['scope:UsersManagement.ReadWrite'])->group(function () {
|
||||
Route::put('email', 'UsersManagementController@email')->name('email');
|
||||
Route::put('verification', 'UsersManagementController@verification')->name('verification');
|
||||
Route::put('nickname', 'UsersManagementController@nickname')->name('nickname');
|
||||
@ -42,23 +50,28 @@ Route::prefix('admin')
|
||||
});
|
||||
|
||||
Route::prefix('players')->group(function () {
|
||||
Route::get('', 'PlayersManagementController@list');
|
||||
Route::put('{player}/name', 'PlayersManagementController@name');
|
||||
Route::put('{player}/owner', 'PlayersManagementController@owner');
|
||||
Route::put('{player}/textures', 'PlayersManagementController@texture');
|
||||
Route::delete('{player}', 'PlayersManagementController@delete');
|
||||
Route::get('', 'PlayersManagementController@list')->middleware(['scope:PlayersManagement.Read,PlayersManagement.ReadWrite']);
|
||||
|
||||
Route::middleware(['scope:PlayersManagement.ReadWrite'])->group(function () {
|
||||
Route::put('{player}/name', 'PlayersManagementController@name');
|
||||
Route::put('{player}/owner', 'PlayersManagementController@owner');
|
||||
Route::put('{player}/textures', 'PlayersManagementController@texture');
|
||||
Route::delete('{player}', 'PlayersManagementController@delete');
|
||||
});
|
||||
});
|
||||
|
||||
Route::prefix('closet')->group(function () {
|
||||
Route::get('{user}', 'ClosetManagementController@list');
|
||||
Route::post('{user}', 'ClosetManagementController@add');
|
||||
Route::delete('{user}', 'ClosetManagementController@remove');
|
||||
Route::get('{user}', 'ClosetManagementController@list')->middleware(['scope:ClosetManagement.Read,ClosetManagement.ReadWrite']);
|
||||
Route::middleware(['scope:ClosetManagement.ReadWrite'])->group(function () {
|
||||
Route::post('{user}', 'ClosetManagementController@add');
|
||||
Route::delete('{user}', 'ClosetManagementController@remove');
|
||||
});
|
||||
});
|
||||
|
||||
Route::prefix('reports')->group(function () {
|
||||
Route::get('', 'ReportController@manage');
|
||||
Route::put('{report}', 'ReportController@review');
|
||||
Route::get('', 'ReportController@manage')->middleware(['scope:ReportsManagement.Read,ReportsManagement.ReadWrite']);
|
||||
Route::put('{report}', 'ReportController@review')->middleware(['scope:ReportsManagement.ReadWrite']);
|
||||
});
|
||||
|
||||
Route::post('notifications', 'NotificationsController@send');
|
||||
Route::post('notifications', 'NotificationsController@send')->middleware(['scope:Notification.ReadWrite']);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user