usercp token management

This commit is contained in:
xiaomlove
2025-03-29 14:32:31 +07:00
parent 4b2f933806
commit edc9e56d7d
21 changed files with 218 additions and 122 deletions

View File

@@ -2,7 +2,7 @@
namespace App\Auth;
use App\Enums\PermissionEnum;
use App\Enums\Permission\PermissionEnum;
class Permission
{

View File

@@ -2,59 +2,8 @@
namespace App\Console\Commands;
use App\Enums\PermissionEnum;
use App\Events\TorrentUpdated;
use App\Filament\Resources\System\AgentAllowResource;
use App\Http\Resources\TagResource;
use App\Models\AgentAllow;
use App\Models\Attendance;
use App\Models\Category;
use App\Models\Exam;
use App\Models\ExamProgress;
use App\Models\ExamUser;
use App\Models\HitAndRun;
use App\Models\Invite;
use App\Models\LoginLog;
use App\Models\Medal;
use App\Models\Peer;
use App\Models\Post;
use App\Models\SearchBox;
use App\Models\Setting;
use App\Models\Snatch;
use App\Models\Tag;
use App\Models\Torrent;
use App\Models\TorrentOperationLog;
use App\Models\User;
use App\Models\UserBanLog;
use App\Repositories\AgentAllowRepository;
use App\Repositories\AttendanceRepository;
use App\Repositories\CleanupRepository;
use App\Repositories\ExamRepository;
use App\Repositories\HitAndRunRepository;
use App\Repositories\MeiliSearchRepository;
use App\Repositories\PluginRepository;
use App\Repositories\SearchBoxRepository;
use App\Repositories\SearchRepository;
use App\Repositories\TagRepository;
use App\Repositories\ToolRepository;
use App\Repositories\TorrentRepository;
use App\Repositories\UserRepository;
use Carbon\Carbon;
use Filament\Notifications\Notification;
use GeoIp2\Database\Reader;
use GuzzleHttp\Client;
use App\Models\PersonalAccessToken;
use Illuminate\Console\Command;
use Illuminate\Encryption\Encrypter;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Imdb\Cache;
use League\Flysystem\StorageAttributes;
use Nexus\Database\NexusDB;
use Nexus\Imdb\Imdb;
use NexusPlugin\Menu\Filament\MenuItemResource\Pages\ManageMenuItems;
use NexusPlugin\Menu\MenuRepository;
use NexusPlugin\Menu\Models\MenuItem;
@@ -66,9 +15,6 @@ use NexusPlugin\StickyPromotion\Models\StickyPromotionParticipator;
use NexusPlugin\Tracker\TrackerRepository;
use NexusPlugin\Work\Models\RoleWork;
use NexusPlugin\Work\WorkRepository;
use PhpIP\IP;
use PhpIP\IPBlock;
use Rhilip\Bencode\Bencode;
class Test extends Command
{
@@ -103,9 +49,9 @@ class Test extends Command
*/
public function handle()
{
$r = microtime();
$r = PersonalAccessToken::query()->find(11);
// $r = SearchBox::query()->find(4)->ss()->orWhere("mode", 0)->get();
dd($r);
dd($r->abilitiesText);
}
}

View File

@@ -1,8 +1,11 @@
<?php
namespace App\Enums;
namespace App\Enums\Permission;
enum PermissionEnum: string {
case UPLOAD_TO_SPECIAL_SECTION = 'uploadspecial';
case BE_ANONYMOUS = 'beanonymous';
case TORRENT_LIST = 'torrent:list';
case UPLOAD = 'upload';
}

View File

@@ -126,45 +126,7 @@ class AuthenticateController extends Controller
}
}
public function addToken(Request $request)
{
try {
$request->validate([
'name' => 'required|string',
]);
$user = Auth::user();
$count = $user->tokens()->count();
if ($count >= 5) {
throw new NexusException("Token limit exceeded");
}
$newAccessToken = $user->createToken($request->name);
PersonalAccessTokenPlain::query()->create([
'access_token_id' => $newAccessToken->accessToken->getKey(),
'plain_text_token' => $newAccessToken->plainTextToken,
]);
return $this->success(true);
} catch (\Exception $exception) {
return $this->fail(false, $exception->getMessage());
}
}
public function delToken(Request $request)
{
try {
$request->validate([
'id' => 'required|integer',
]);
$user = Auth::user();
$token = $user->tokens()->where("id", $request->id)->first();
if ($token) {
PersonalAccessTokenPlain::query()->where("access_token_id", $token->id)->delete();
$token->delete();
}
return $this->success(true);
} catch (\Exception $exception) {
return $this->fail(false, $exception->getMessage());
}
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace App\Http\Controllers;
use App\Exceptions\NexusException;
use App\Models\PersonalAccessTokenPlain;
use App\Repositories\TokenRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class TokenController extends Controller
{
private $repository;
public function __construct(TokenRepository $repository)
{
$this->repository = $repository;
}
public function addToken(Request $request)
{
try {
$request->validate([
'name' => 'required|string',
'permissions' => 'required|array|min:1',
]);
$user = Auth::user();
$count = $user->tokens()->count();
if ($count >= 5) {
throw new NexusException("Token limit exceeded");
}
$newAccessToken = $user->createToken($request->name, $request->permissions);
PersonalAccessTokenPlain::query()->create([
'access_token_id' => $newAccessToken->accessToken->getKey(),
'plain_text_token' => $newAccessToken->plainTextToken,
]);
return $this->success(true);
} catch (\Exception $exception) {
return $this->fail(false, $exception->getMessage());
}
}
public function delToken(Request $request)
{
try {
$request->validate([
'id' => 'required|integer',
]);
$user = Auth::user();
$token = $user->tokens()->where("id", $request->id)->first();
if ($token) {
PersonalAccessTokenPlain::query()->where("access_token_id", $token->id)->delete();
$token->delete();
}
return $this->success(true);
} catch (\Exception $exception) {
return $this->fail(false, $exception->getMessage());
}
}
public function getPlainText(Request $request)
{
try {
$request->validate([
'id' => 'required|integer',
]);
$user = Auth::user();
$token = $user->tokens()->where("id", $request->id)->first();
if (!$token) {
throw new NexusException("Token not found");
}
$plainRecord = PersonalAccessTokenPlain::query()->where("access_token_id", $token->id)->first();
if (!$plainRecord) {
throw new NexusException("Plain record not found");
}
return $this->success($plainRecord->plain_text_token);
} catch (\Exception $exception) {
return $this->fail(false, $exception->getMessage());
}
}
}

View File

@@ -26,4 +26,10 @@ class UploadController extends Controller
return $this->success($resource);
}
public function upload(Request $request)
{
$user = $request->user();
return $this->success("OK");
}
}

View File

@@ -78,4 +78,9 @@ class Kernel extends HttpKernel
'locale' => \App\Http\Middleware\Locale::class,
'user' => \App\Http\Middleware\User::class,
];
protected $middlewareAliases = [
'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class,
'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class,
];
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken;
class PersonalAccessToken extends SanctumPersonalAccessToken
{
public function getAbilitiesTextAttribute(): string
{
if (in_array('*', $this->abilities)) {
return 'ALL';
}
$result = [];
foreach ($this->abilities as $ability) {
if ($ability != '*') {
$result[] = nexus_trans("permission.{$ability}.text");
}
}
return implode(', ', $result);
}
}

View File

@@ -13,6 +13,7 @@ use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use Illuminate\Http\Resources\Json\JsonResource;
use Laravel\Passport\Passport;
use Nexus\Database\NexusDB;
use Nexus\Nexus;
use Filament\Facades\Filament;
@@ -37,6 +38,7 @@ class AppServiceProvider extends ServiceProvider
{
global $plugin;
$plugin->start();
NexusDB::customModel();
DB::connection(config('database.default'))->enableQueryLog();
$forceScheme = strtolower(env('FORCE_SCHEME'));
if (env('APP_ENV') == "production" && in_array($forceScheme, ['https', 'http'])) {

View File

@@ -9,7 +9,6 @@ use App\Models\Category;
use App\Models\Codec;
use App\Models\Icon;
use App\Models\Media;
use App\Models\OauthClient;
use App\Models\Plugin;
use App\Models\Processing;
use App\Models\SearchBox;
@@ -22,7 +21,6 @@ use App\Policies\CodecPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Laravel\Passport\Passport;
class AuthServiceProvider extends ServiceProvider
{
@@ -55,11 +53,6 @@ class AuthServiceProvider extends ServiceProvider
*/
public function boot()
{
// $this->registerPolicies();
if (class_exists(Passport::class)) {
Passport::useClientModel(OauthClient::class);
}
Auth::viaRequest('nexus-cookie', function (Request $request) {
return $this->getUserByCookie($request->cookie());
});

View File

@@ -39,7 +39,7 @@ class RouteServiceProvider extends ServiceProvider
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
Route::prefix('api/v1')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Repositories;
use App\Enums\Permission\PermissionEnum;
class TokenRepository extends BaseRepository
{
private static array $userTokenPermissions = [
PermissionEnum::TORRENT_LIST,
PermissionEnum::UPLOAD,
];
public function listUserTokenPermissions(): array
{
$result = [];
foreach (self::$userTokenPermissions as $permission) {
$result[$permission->value] = nexus_trans("permission.{$permission->value}.text");
}
return $result;
}
}