From 432c57f8866c7d65ff359a972ae1c9275751135d Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Thu, 17 Apr 2025 18:59:03 +0700 Subject: [PATCH] separate route permission + token manage --- app/Auth/Permission.php | 15 ++++ app/Console/Commands/Test.php | 11 ++- app/Enums/Permission/PermissionEnum.php | 7 +- app/Enums/Permission/RoutePermissionEnum.php | 10 +++ app/Exceptions/Handler.php | 1 + .../Resources/User/HitAndRunResource.php | 4 +- app/Filament/Resources/User/TokenResource.php | 84 +++++++++++++++++++ .../User/TokenResource/Pages/ManageTokens.php | 20 +++++ app/Http/Resources/ExamResource.php | 4 +- app/Http/Resources/UserResource.php | 4 +- app/Models/PersonalAccessToken.php | 2 +- app/Policies/UserPolicy.php | 10 ++- app/Providers/Filament/AppPanelProvider.php | 3 +- app/Repositories/TokenRepository.php | 12 +-- app/Repositories/UserRepository.php | 5 +- include/globalfunctions.php | 2 +- resources/lang/en/admin.php | 1 + resources/lang/en/permission.php | 4 - resources/lang/en/token.php | 2 + resources/lang/zh_CN/admin.php | 1 + resources/lang/zh_CN/permission.php | 14 ---- resources/lang/zh_CN/route-permission.php | 20 +++++ resources/lang/zh_CN/token.php | 2 + resources/lang/zh_TW/admin.php | 1 + resources/lang/zh_TW/permission.php | 4 - resources/lang/zh_TW/token.php | 2 + routes/api.php | 12 +-- 27 files changed, 203 insertions(+), 54 deletions(-) create mode 100644 app/Enums/Permission/RoutePermissionEnum.php create mode 100644 app/Filament/Resources/User/TokenResource.php create mode 100644 app/Filament/Resources/User/TokenResource/Pages/ManageTokens.php create mode 100644 resources/lang/zh_CN/route-permission.php diff --git a/app/Auth/Permission.php b/app/Auth/Permission.php index 7fbd3e63..8ee87f22 100644 --- a/app/Auth/Permission.php +++ b/app/Auth/Permission.php @@ -64,4 +64,19 @@ class Permission { return user_can(PermissionEnum::TORRENT_SET_SPECIAL_TAG->value); } + + public static function canManageUserBasicInfo(): bool + { + return user_can(PermissionEnum::MANAGE_USER_BASIC_INFO->value); + } + + public static function canManageUserConfidentialInfo(): bool + { + return user_can(PermissionEnum::MANAGE_USER_CONFIDENTIAL_INFO->value); + } + + public static function canViewUserConfidentialInfo(): bool + { + return user_can(PermissionEnum::VIEW_USER_CONFIDENTIAL_INFO->value); + } } diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index e4601533..1aac2561 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -2,9 +2,11 @@ namespace App\Console\Commands; +use App\Models\ExamUser; use App\Models\PersonalAccessToken; use App\Models\Torrent; use App\Models\User; +use App\Repositories\ExamRepository; use App\Repositories\UploadRepository; use Illuminate\Console\Command; use NexusPlugin\Menu\Filament\MenuItemResource\Pages\ManageMenuItems; @@ -53,12 +55,9 @@ class Test extends Command */ public function handle() { - $a = ['acb' => 2]; - - if ($a = isset($a['ab'])) { - $this->info("isset ab = true"); - } - dd($a); + $rep = new ExamRepository(); + $result = $rep->getUserExamProgress(10041, ExamUser::STATUS_NORMAL); + dd($result); } } diff --git a/app/Enums/Permission/PermissionEnum.php b/app/Enums/Permission/PermissionEnum.php index f6689d96..342815fb 100644 --- a/app/Enums/Permission/PermissionEnum.php +++ b/app/Enums/Permission/PermissionEnum.php @@ -5,9 +5,6 @@ namespace App\Enums\Permission; enum PermissionEnum: string { case UPLOAD_TO_SPECIAL_SECTION = 'uploadspecial'; case BE_ANONYMOUS = 'beanonymous'; - - case TORRENT_LIST = 'torrent:list'; - case TORRENT_VIEW = 'torrent:view'; case TORRENT_VIEW_SPECIAL = 'view_special_torrent'; case TORRENT_SET_HR = 'torrent_hr'; case TORRENT_SET_PRICE = 'torrent-set-price'; @@ -16,6 +13,8 @@ enum PermissionEnum: string { case TORRENT_APPROVAL_ALLOW_AUTOMATIC = 'torrent-approval-allow-automatic'; case TORRENT_SET_SPECIAL_TAG = 'torrent-set-special-tag'; case UPLOAD = 'upload'; + case MANAGE_USER_BASIC_INFO = "prfmanage"; + case MANAGE_USER_CONFIDENTIAL_INFO = "cruprfmanage"; + case VIEW_USER_CONFIDENTIAL_INFO = "userprofile"; - case USER_VIEW = "user:view"; } diff --git a/app/Enums/Permission/RoutePermissionEnum.php b/app/Enums/Permission/RoutePermissionEnum.php new file mode 100644 index 00000000..c0b9f3e8 --- /dev/null +++ b/app/Enums/Permission/RoutePermissionEnum.php @@ -0,0 +1,10 @@ +getTraceAsString()), "error"); } diff --git a/app/Filament/Resources/User/HitAndRunResource.php b/app/Filament/Resources/User/HitAndRunResource.php index 88cd68a2..efc59b27 100644 --- a/app/Filament/Resources/User/HitAndRunResource.php +++ b/app/Filament/Resources/User/HitAndRunResource.php @@ -80,7 +80,7 @@ class HitAndRunResource extends Resource ->form([ Forms\Components\DatePicker::make('created_at_begin') ->maxDate(now()) - ->label(__('hr.created_at_begin')) + ->label(__('label.created_at_begin')) , ])->query(function (Builder $query, array $data) { return $query->when($data['created_at_begin'], fn (Builder $query, $value) => $query->where("created_at", '>=', $value)); @@ -90,7 +90,7 @@ class HitAndRunResource extends Resource ->form([ Forms\Components\DatePicker::make('created_at_end') ->maxDate(now()) - ->label(__('hr.created_at_end')) + ->label(__('label.created_at_end')) , ])->query(function (Builder $query, array $data) { return $query->when($data['created_at_end'], fn (Builder $query, $value) => $query->where("created_at", '<=', $value)); diff --git a/app/Filament/Resources/User/TokenResource.php b/app/Filament/Resources/User/TokenResource.php new file mode 100644 index 00000000..15c69e9f --- /dev/null +++ b/app/Filament/Resources/User/TokenResource.php @@ -0,0 +1,84 @@ +schema([ + // + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('id'), + Tables\Columns\TextColumn::make('name')->label(__('label.name')), + Tables\Columns\TextColumn::make('abilities') + ->label(__('token.permission')) + ->formatStateUsing(fn ($record): string => $record->abilitiesText) + , + Tables\Columns\TextColumn::make('token')->label(__('token.token')), + Tables\Columns\TextColumn::make('tokenable_id') + ->label(__('label.username')) + ->formatStateUsing(fn ($state) => username_for_admin($state)) + , + Tables\Columns\TextColumn::make('last_used_at')->label(__('token.last_used_at')), + Tables\Columns\TextColumn::make('expires_at')->label(__('label.expire_at')), + Tables\Columns\TextColumn::make('created_at')->label(__('label.created_at')), + ]) + ->filters([ + // + ]) + ->actions([ +// Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ManageTokens::route('/'), + ]; + } +} diff --git a/app/Filament/Resources/User/TokenResource/Pages/ManageTokens.php b/app/Filament/Resources/User/TokenResource/Pages/ManageTokens.php new file mode 100644 index 00000000..82b83dbb --- /dev/null +++ b/app/Filament/Resources/User/TokenResource/Pages/ManageTokens.php @@ -0,0 +1,20 @@ +filters; foreach (Exam::$filters as $key => $value) { - if (!isset($filters->$key)) { - $filters->$key = []; + if (!isset($filters[$key])) { + $filters[$key] = []; } } return $filters; diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php index d4f3b8a6..0b6d50e8 100644 --- a/app/Http/Resources/UserResource.php +++ b/app/Http/Resources/UserResource.php @@ -2,7 +2,9 @@ namespace App\Http\Resources; +use App\Auth\Permission; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\Gate; class UserResource extends JsonResource { @@ -18,7 +20,7 @@ class UserResource extends JsonResource $out = [ 'id' => $this->id, 'username' => $this->username, - 'email' => $this->email, + 'email' => $this->when(Gate::allows("viewEmail", $this->resource), $this->email), 'status' => $this->status, 'enabled' => $this->enabled, 'added' => format_datetime($this->added), diff --git a/app/Models/PersonalAccessToken.php b/app/Models/PersonalAccessToken.php index 7af01e1f..ef605944 100644 --- a/app/Models/PersonalAccessToken.php +++ b/app/Models/PersonalAccessToken.php @@ -13,7 +13,7 @@ class PersonalAccessToken extends SanctumPersonalAccessToken $result = []; foreach ($this->abilities as $ability) { if ($ability != '*') { - $result[] = nexus_trans("permission.{$ability}.text"); + $result[] = nexus_trans("route-permission.{$ability}.text"); } } return implode(', ', $result); diff --git a/app/Policies/UserPolicy.php b/app/Policies/UserPolicy.php index 05c02851..2c526a01 100644 --- a/app/Policies/UserPolicy.php +++ b/app/Policies/UserPolicy.php @@ -2,8 +2,10 @@ namespace App\Policies; +use App\Auth\Permission; use App\Models\User; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Auth\Access\Response; class UserPolicy extends BasePolicy { @@ -29,7 +31,13 @@ class UserPolicy extends BasePolicy */ public function view(User $user, User $model) { - return true; + return $model->privacy != "strong" || $user->id == $model->id|| Permission::canManageUserBasicInfo(); + } + + public function viewEmail(User $user, User $model) + { + do_log(sprintf("user: %s, model: %s", $user->id, $model->id)); + return $model->privacy == "low" || $user->id == $model->id || Permission::canViewUserConfidentialInfo(); } /** diff --git a/app/Providers/Filament/AppPanelProvider.php b/app/Providers/Filament/AppPanelProvider.php index 7fa926c4..f7d72fd2 100644 --- a/app/Providers/Filament/AppPanelProvider.php +++ b/app/Providers/Filament/AppPanelProvider.php @@ -73,7 +73,8 @@ class AppPanelProvider extends PanelProvider ]) ->authMiddleware([ \App\Http\Middleware\Filament::class, - ]); + ]) + ; } public function boot() diff --git a/app/Repositories/TokenRepository.php b/app/Repositories/TokenRepository.php index 6fbd41a8..8197b97d 100644 --- a/app/Repositories/TokenRepository.php +++ b/app/Repositories/TokenRepository.php @@ -1,22 +1,22 @@ value] = nexus_trans("permission.{$permission->value}.text"); + $result[$permission->value] = nexus_trans("route-permission.{$permission->value}.text"); } return $result; } diff --git a/app/Repositories/UserRepository.php b/app/Repositories/UserRepository.php index 0dad069b..b58430f2 100644 --- a/app/Repositories/UserRepository.php +++ b/app/Repositories/UserRepository.php @@ -26,6 +26,7 @@ use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Gate; use Illuminate\Support\Str; use Nexus\Database\NexusDB; @@ -69,7 +70,9 @@ class UserRepository extends BaseRepository ->allowIncludeCounts($allowIncludeCounts) ->allowIncludeFields($allowIncludeFields) ; - $user = $apiQueryBuilder->build()->findOrFail($id); + $query = $apiQueryBuilder->build(); + $user = $query->findOrFail($id); + Gate::authorize('view', $user); return $this->appendIncludeFields($apiQueryBuilder, $currentUser, $user); } diff --git a/include/globalfunctions.php b/include/globalfunctions.php index d6752daa..56a6172f 100644 --- a/include/globalfunctions.php +++ b/include/globalfunctions.php @@ -1382,7 +1382,7 @@ function send_admin_fail_notification(string $msg = ""): void { \Filament\Notifications\Notification::make()->danger()->title($msg ?: "Fail!")->send(); } -function ability(\App\Enums\Permission\PermissionEnum $permission): string { +function ability(\App\Enums\Permission\RoutePermissionEnum $permission): string { return sprintf("ability:%s", $permission->value); } diff --git a/resources/lang/en/admin.php b/resources/lang/en/admin.php index ab571e68..f471b6db 100644 --- a/resources/lang/en/admin.php +++ b/resources/lang/en/admin.php @@ -42,6 +42,7 @@ return [ 'oauth_access_token' => 'Access tokens', 'oauth_auth_code' => 'Auth codes', 'oauth_refresh_token' => 'Refresh tokens', + 'token' => 'Access tokens', ], 'resources' => [ 'agent_allow' => [ diff --git a/resources/lang/en/permission.php b/resources/lang/en/permission.php index 8a656c01..97566b71 100644 --- a/resources/lang/en/permission.php +++ b/resources/lang/en/permission.php @@ -217,8 +217,4 @@ return [ 'text' => 'Allow Userbar', 'desc' => ' Get his userba', ], - 'torrent:list' => [ - 'text' => 'Get torrent list', - 'desc' => 'Get torrent list', - ], ]; diff --git a/resources/lang/en/token.php b/resources/lang/en/token.php index e5d50c45..2a41a9ae 100644 --- a/resources/lang/en/token.php +++ b/resources/lang/en/token.php @@ -5,4 +5,6 @@ return array ( 'permission' => 'Permissions', 'maximum_allow_number_reached' => 'The number reaches the upper limit', 'create_success_tip' => 'The token was created successfully, this data is displayed only once, please save it properly

:token', + 'last_used_at' => 'Recent usage time', + 'token' => 'summary', ); diff --git a/resources/lang/zh_CN/admin.php b/resources/lang/zh_CN/admin.php index b08da80e..56212b13 100644 --- a/resources/lang/zh_CN/admin.php +++ b/resources/lang/zh_CN/admin.php @@ -40,6 +40,7 @@ return [ 'oauth_access_token' => '访问令牌', 'oauth_auth_code' => '授权码', 'oauth_refresh_token' => '刷新令牌', + 'token' => '访问令牌', ], 'resources' => [ 'agent_allow' => [ diff --git a/resources/lang/zh_CN/permission.php b/resources/lang/zh_CN/permission.php index 5a72e3ea..4b944869 100644 --- a/resources/lang/zh_CN/permission.php +++ b/resources/lang/zh_CN/permission.php @@ -217,18 +217,4 @@ return [ 'text' => '允许个性条', 'desc' => '允许用户使用个性条', ], - - //新加 - 'torrent:list' => [ - 'text' => '获取种子列表', - 'desc' => '获取种子列表', - ], - 'torrent:view' => [ - 'text' => '查看种子详情', - 'desc' => '查看种子详情', - ], - 'user:view' => [ - 'text' => '查看用户基本信息', - 'desc' => '查看用户基本信息', - ], ]; diff --git a/resources/lang/zh_CN/route-permission.php b/resources/lang/zh_CN/route-permission.php new file mode 100644 index 00000000..c4d00f99 --- /dev/null +++ b/resources/lang/zh_CN/route-permission.php @@ -0,0 +1,20 @@ + [ + 'text' => '发布种子', + 'desc' => '发布种子', + ], + 'torrent:list' => [ + 'text' => '获取种子列表', + 'desc' => '获取种子列表', + ], + 'torrent:view' => [ + 'text' => '查看种子详情', + 'desc' => '查看种子详情', + ], + 'user:view' => [ + 'text' => '查看用户基本信息', + 'desc' => '查看用户基本信息', + ], +]; diff --git a/resources/lang/zh_CN/token.php b/resources/lang/zh_CN/token.php index 9e126d8e..6c4f1f36 100644 --- a/resources/lang/zh_CN/token.php +++ b/resources/lang/zh_CN/token.php @@ -5,4 +5,6 @@ return [ "permission" => "权限", "maximum_allow_number_reached" => "数量达到上限", "create_success_tip" => "token 创建成功,此数据只展示一次,请妥善保存

:token", + "last_used_at" => "最近使用时间", + "token" => "摘要", ]; diff --git a/resources/lang/zh_TW/admin.php b/resources/lang/zh_TW/admin.php index 4c7f13f5..5011d74f 100644 --- a/resources/lang/zh_TW/admin.php +++ b/resources/lang/zh_TW/admin.php @@ -42,6 +42,7 @@ return [ 'oauth_access_token' => '訪問令牌', 'oauth_auth_code' => '授權碼', 'oauth_refresh_token' => '刷新令牌', + 'token' => '訪問令牌', ], 'resources' => [ 'agent_allow' => [ diff --git a/resources/lang/zh_TW/permission.php b/resources/lang/zh_TW/permission.php index f2767701..26057fe1 100644 --- a/resources/lang/zh_TW/permission.php +++ b/resources/lang/zh_TW/permission.php @@ -217,8 +217,4 @@ return [ 'text' => '允許個性條', 'desc' => '允許用戶使用個性條', ], - 'torrent:list' => [ - 'text' => '獲取種子列表', - 'desc' => '獲取種子列表', - ], ]; diff --git a/resources/lang/zh_TW/token.php b/resources/lang/zh_TW/token.php index ced6d4cd..4490e4bb 100644 --- a/resources/lang/zh_TW/token.php +++ b/resources/lang/zh_TW/token.php @@ -5,4 +5,6 @@ return array ( 'permission' => '權限', 'maximum_allow_number_reached' => '數量達到上限', 'create_success_tip' => 'token 創建成功,此數據只展示一次,請妥善保存

:token', + 'last_used_at' => '最近使用時間', + 'token' => '摘要', ); diff --git a/routes/api.php b/routes/api.php index 1e12f47a..d4fdf6f6 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,7 +2,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; -use App\Enums\Permission\PermissionEnum; +use App\Enums\Permission\RoutePermissionEnum; /* |-------------------------------------------------------------------------- @@ -48,12 +48,12 @@ Route::group(['middleware' => ['auth:sanctum']], function () { // Route::resource('forums', \App\Http\Controllers\ForumController::class); // Route::resource('topics', \App\Http\Controllers\TopicController::class); - Route::get('sections', [\App\Http\Controllers\UploadController::class, 'sections'])->middleware(ability(PermissionEnum::UPLOAD)); - Route::get('torrents/{section?}', [\App\Http\Controllers\TorrentController::class, 'index'])->middleware(ability(PermissionEnum::TORRENT_LIST)); - Route::post('upload', [\App\Http\Controllers\TorrentController::class, 'store'])->middleware(ability(PermissionEnum::UPLOAD)); - Route::get('detail/{id}', [\App\Http\Controllers\TorrentController::class, 'show'])->middleware(ability(PermissionEnum::TORRENT_VIEW)); + Route::get('sections', [\App\Http\Controllers\UploadController::class, 'sections'])->middleware(ability(RoutePermissionEnum::TORRENT_UPLOAD)); + Route::get('torrents/{section?}', [\App\Http\Controllers\TorrentController::class, 'index'])->middleware(ability(RoutePermissionEnum::TORRENT_LIST)); + Route::post('upload', [\App\Http\Controllers\TorrentController::class, 'store'])->middleware(ability(RoutePermissionEnum::TORRENT_UPLOAD)); + Route::get('detail/{id}', [\App\Http\Controllers\TorrentController::class, 'show'])->middleware(ability(RoutePermissionEnum::TORRENT_VIEW)); - Route::get('/profile/{id?}', [\App\Http\Controllers\UserController::class, 'show'])->middleware(ability(PermissionEnum::USER_VIEW)); + Route::get('/profile/{id?}', [\App\Http\Controllers\UserController::class, 'show'])->middleware(ability(RoutePermissionEnum::USER_VIEW)); });