diff --git a/app/Console/Commands/GeneratePersonalAccessToken.php b/app/Console/Commands/GeneratePersonalAccessToken.php new file mode 100644 index 0000000000..098d9678ad --- /dev/null +++ b/app/Console/Commands/GeneratePersonalAccessToken.php @@ -0,0 +1,97 @@ +validation = $validation; + $this->tokenRepository = $tokenRepository; + parent::__construct(); + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + + $accessTokenName = $this->option('name'); + if ($accessTokenName=='') { + $accessTokenName = 'CLI Auth Token'; + } + + if ($this->option('user_id')=='') { + return $this->error('ERROR: user_id cannot be blank.'); + } + + if ($user = User::find($this->option('user_id'))) { + + $createAccessToken = $user->createToken($accessTokenName)->accessToken; + + if ($this->option('key-only')) { + $this->info($createAccessToken); + + } else { + + $this->warn('Your API Token has been created. Be sure to copy this token now, as it will not be accessible again.'); + + if ($token = DB::table('oauth_access_tokens')->where('user_id', '=', $user->id)->where('name','=',$accessTokenName)->orderBy('created_at', 'desc')->first()) { + $this->info('API Token ID: '.$token->id); + } + + $this->info('API Token User: '.$user->present()->fullName.' ('.$user->username.')'); + $this->info('API Token Name: '.$accessTokenName); + $this->info('API Token: '.$createAccessToken); + } + } else { + return $this->error('ERROR: Invalid user. API key was not created.'); + } + + + + + } +} diff --git a/app/Http/Controllers/Api/ProfileController.php b/app/Http/Controllers/Api/ProfileController.php index 8a06a268dd..691efda981 100644 --- a/app/Http/Controllers/Api/ProfileController.php +++ b/app/Http/Controllers/Api/ProfileController.php @@ -5,10 +5,37 @@ namespace App\Http\Controllers\Api; use App\Helpers\Helper; use App\Http\Controllers\Controller; use App\Models\CheckoutRequest; -use Auth; +use Illuminate\Http\Response; +use Illuminate\Support\Facades\Auth; +use Illuminate\Http\Request; +use Laravel\Passport\TokenRepository; +use Illuminate\Contracts\Validation\Factory as ValidationFactory; +use Gate; +use DB; class ProfileController extends Controller { + + /** + * The token repository implementation. + * + * @var \Laravel\Passport\TokenRepository + */ + protected $tokenRepository; + + /** + * Create a controller instance. + * + * @param \Laravel\Passport\TokenRepository $tokenRepository + * @param \Illuminate\Contracts\Validation\Factory $validation + * @return void + */ + public function __construct(TokenRepository $tokenRepository, ValidationFactory $validation) + { + $this->validation = $validation; + $this->tokenRepository = $tokenRepository; + } + /** * Display a listing of requested assets. * @@ -42,4 +69,90 @@ class ProfileController extends Controller return $results; } + + + /** + * Delete an API token + * + * @author [A. Gianotto] [] + * @since [v6.0.5] + * + * @return \Illuminate\Http\Response + */ + public function createApiToken(Request $request) { + + if (!Gate::allows('self.api')) { + abort(403); + } + + $accessTokenName = $request->input('name', 'Auth Token'); + + if ($accessToken = Auth::user()->createToken($accessTokenName)->accessToken) { + + // Get the ID so we can return that with the payload + $token = DB::table('oauth_access_tokens')->where('user_id', '=', Auth::user()->id)->where('name','=',$accessTokenName)->orderBy('created_at', 'desc')->first(); + $accessTokenData['id'] = $token->id; + $accessTokenData['token'] = $accessToken; + $accessTokenData['name'] = $accessTokenName; + return response()->json(Helper::formatStandardApiResponse('success', $accessTokenData, 'Personal access token '.$accessTokenName.' created successfully')); + } + return response()->json(Helper::formatStandardApiResponse('error', null, 'Token could not be created.')); + + } + + + /** + * Delete an API token + * + * @author [A. Gianotto] [] + * @since [v6.0.5] + * + * @return \Illuminate\Http\Response + */ + public function deleteApiToken($tokenId) { + + if (!Gate::allows('self.api')) { + abort(403); + } + + $token = $this->tokenRepository->findForUser( + $tokenId, Auth::user()->getAuthIdentifier() + ); + + if (is_null($token)) { + return new Response('', 404); + } + + $token->revoke(); + + return new Response('', Response::HTTP_NO_CONTENT); + + } + + + /** + * Show user's API tokens + * + * @author [A. Gianotto] [] + * @since [v6.0.5] + * + * @return \Illuminate\Http\Response + */ + public function showApiTokens(Request $request) { + + if (!Gate::allows('self.api')) { + abort(403); + } + + $tokens = $this->tokenRepository->forUser(Auth::user()->getAuthIdentifier()); + $token_values = $tokens->load('client')->filter(function ($token) { + return $token->client->personal_access_client && ! $token->revoked; + })->values(); + + return response()->json(Helper::formatStandardApiResponse('success', $token_values, null)); + + } + + + } diff --git a/routes/api.php b/routes/api.php index 29af435687..0b16f84add 100644 --- a/routes/api.php +++ b/routes/api.php @@ -48,6 +48,27 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi ] )->name('api.assets.requestable'); + Route::post('personal-access-tokens', + [ + Api\ProfileController::class, + 'createApiToken' + ] + )->name('api.personal-access-token.create'); + + Route::get('personal-access-tokens', + [ + Api\ProfileController::class, + 'showApiTokens' + ] + )->name('api.personal-access-token.index'); + + Route::delete('personal-access-tokens/{tokenId}', + [ + Api\ProfileController::class, + 'deleteApiToken' + ] + )->name('api.personal-access-token.delete'); + }); // end account group