Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[13.x] Deprecate JSON API #1778

Merged
merged 18 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ Passport's `oauth_personal_access_clients` table has been redundant and unnecess

In addition, the `passport.personal_access_client` configuration value, `Laravel\Passport\PersonalAccessClient` model, `Passport::$personalAccessClientModel` property, `Passport::usePersonalAccessClientModel()`, `Passport::personalAccessClientModel()`, and `Passport::personalAccessClient()` methods have been removed.

### JSON API Deprecation

PR: https://github.com/laravel/passport/pull/1778

The JSON API provided by Passport has been deprecated. If you need to continue using the deprecated JSON API, you can do so by setting `Passport::$registersJsonApiRoutes` to `true` within the `boot` method of your application’s `App\Providers\AppServiceProvider` class. Alternatively, you may also copy the relevant routes and controllers into your application as needed:

public function boot(): void
{
Passport::$registersJsonApiRoutes = true;
}

## Upgrading To 12.0 From 11.x

### Migration Changes
Expand Down
101 changes: 52 additions & 49 deletions routes/web.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Illuminate\Support\Facades\Route;
use Laravel\Passport\Passport;

Route::post('/token', [
'uses' => 'AccessTokenController@issueToken',
Expand Down Expand Up @@ -32,53 +33,55 @@
'as' => 'authorizations.deny',
]);

Route::get('/tokens', [
'uses' => 'AuthorizedAccessTokenController@forUser',
'as' => 'tokens.index',
]);

Route::delete('/tokens/{token_id}', [
'uses' => 'AuthorizedAccessTokenController@destroy',
'as' => 'tokens.destroy',
]);

Route::get('/clients', [
'uses' => 'ClientController@forUser',
'as' => 'clients.index',
]);

Route::post('/clients', [
'uses' => 'ClientController@store',
'as' => 'clients.store',
]);

Route::put('/clients/{client_id}', [
'uses' => 'ClientController@update',
'as' => 'clients.update',
]);

Route::delete('/clients/{client_id}', [
'uses' => 'ClientController@destroy',
'as' => 'clients.destroy',
]);

Route::get('/scopes', [
'uses' => 'ScopeController@all',
'as' => 'scopes.index',
]);

Route::get('/personal-access-tokens', [
'uses' => 'PersonalAccessTokenController@forUser',
'as' => 'personal.tokens.index',
]);

Route::post('/personal-access-tokens', [
'uses' => 'PersonalAccessTokenController@store',
'as' => 'personal.tokens.store',
]);

Route::delete('/personal-access-tokens/{token_id}', [
'uses' => 'PersonalAccessTokenController@destroy',
'as' => 'personal.tokens.destroy',
]);
if (Passport::$registersJsonApiRoutes) {
Route::get('/tokens', [
'uses' => 'AuthorizedAccessTokenController@forUser',
'as' => 'tokens.index',
]);

Route::delete('/tokens/{token_id}', [
'uses' => 'AuthorizedAccessTokenController@destroy',
'as' => 'tokens.destroy',
]);

Route::get('/clients', [
'uses' => 'ClientController@forUser',
'as' => 'clients.index',
]);

Route::post('/clients', [
'uses' => 'ClientController@store',
'as' => 'clients.store',
]);

Route::put('/clients/{client_id}', [
'uses' => 'ClientController@update',
'as' => 'clients.update',
]);

Route::delete('/clients/{client_id}', [
'uses' => 'ClientController@destroy',
'as' => 'clients.destroy',
]);

Route::get('/scopes', [
'uses' => 'ScopeController@all',
'as' => 'scopes.index',
]);

Route::get('/personal-access-tokens', [
'uses' => 'PersonalAccessTokenController@forUser',
'as' => 'personal.tokens.index',
]);

Route::post('/personal-access-tokens', [
'uses' => 'PersonalAccessTokenController@store',
'as' => 'personal.tokens.store',
]);

Route::delete('/personal-access-tokens/{token_id}', [
'uses' => 'PersonalAccessTokenController@destroy',
'as' => 'personal.tokens.destroy',
]);
}
});
66 changes: 20 additions & 46 deletions src/ClientRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Str;
use RuntimeException;

Expand All @@ -30,44 +31,26 @@ public function findActive(string|int $id): ?Client
/**
* Get a client instance for the given ID and user ID.
*
* @param int|string $clientId
* @param mixed $userId
* @return \Laravel\Passport\Client|null
* @deprecated Use $user->clients()->find()
*
* @param \Laravel\Passport\HasApiTokens $user
*/
public function findForUser($clientId, $userId)
public function findForUser(string|int $clientId, Authenticatable $user): ?Client
{
$client = Passport::client();

return $client
->where($client->getKeyName(), $clientId)
->where('user_id', $userId)
->first();
return $user->clients()->where('revoked', false)->find($clientId);
}

/**
* Get the client instances for the given user ID.
*
* @param mixed $userId
* @return \Illuminate\Database\Eloquent\Collection
*/
public function forUser($userId)
{
return Passport::client()
->where('user_id', $userId)
->orderBy('name', 'asc')->get();
}

/**
* Get the active client instances for the given user ID.
* @deprecated Use $user->clients()
*
* @param mixed $userId
* @return \Illuminate\Database\Eloquent\Collection
* @param \Laravel\Passport\HasApiTokens $user
* @return \Illuminate\Database\Eloquent\Collection<int, \Laravel\Passport\Client>
*/
public function activeForUser($userId)
public function forUser(Authenticatable $user): Collection
{
return $this->forUser($userId)->reject(function ($client) {
return $client->revoked;
})->values();
return $user->clients()->where('revoked', false)->orderBy('name')->get();
}

/*
Expand Down Expand Up @@ -188,6 +171,8 @@ public function createAuthorizationCodeGrantClient(
/**
* Update the given client.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param string[] $redirectUris
*/
public function update(Client $client, string $name, array $redirectUris): bool
Expand Down Expand Up @@ -215,27 +200,16 @@ public function regenerateSecret(Client $client): bool
}

/**
* Determine if the given client is revoked.
*
* @param int|string $id
* @return bool
*/
public function revoked($id)
{
$client = $this->find($id);

return is_null($client) || $client->revoked;
}

/**
* Delete the given client.
* Revoke the given client and its tokens.
*
* @param \Laravel\Passport\Client $client
* @return void
* @deprecated Will be removed in a future Laravel version.
*/
public function delete(Client $client)
public function delete(Client $client): void
{
$client->tokens()->update(['revoked' => true]);
$client->tokens()->with('refreshToken')->each(function (Token $token): void {
$token->refreshToken?->revoke();
$token->revoke();
});

$client->forceFill(['revoked' => true])->save();
}
Expand Down
55 changes: 16 additions & 39 deletions src/Http/Controllers/AuthorizedAccessTokenController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,52 @@

namespace Laravel\Passport\Http\Controllers;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Laravel\Passport\RefreshTokenRepository;
use Laravel\Passport\Token;
use Laravel\Passport\TokenRepository;

/**
* @deprecated Will be removed in a future Laravel version.
*/
class AuthorizedAccessTokenController
{
/**
* The token repository implementation.
*
* @var \Laravel\Passport\TokenRepository
*/
protected $tokenRepository;

/**
* The refresh token repository implementation.
*
* @var \Laravel\Passport\RefreshTokenRepository
*/
protected $refreshTokenRepository;

/**
* Create a new controller instance.
*
* @param \Laravel\Passport\TokenRepository $tokenRepository
* @param \Laravel\Passport\RefreshTokenRepository $refreshTokenRepository
* @return void
*/
public function __construct(TokenRepository $tokenRepository, RefreshTokenRepository $refreshTokenRepository)
{
$this->tokenRepository = $tokenRepository;
$this->refreshTokenRepository = $refreshTokenRepository;
public function __construct(
protected TokenRepository $tokenRepository
) {
}

/**
* Get all of the authorized tokens for the authenticated user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Database\Eloquent\Collection<int, \Laravel\Passport\Token>
*/
public function forUser(Request $request)
public function forUser(Request $request): Collection
{
$tokens = $this->tokenRepository->forUser($request->user()->getAuthIdentifier());

return $tokens->load('client')->filter(function ($token) {
return ! $token->client->firstParty() && ! $token->revoked;
})->values();
return $this->tokenRepository->forUser($request->user())
->reject(fn (Token $token): bool => $token->client->revoked || $token->client->firstParty())
->values();
}

/**
* Delete the given token.
*
* @param \Illuminate\Http\Request $request
* @param string $tokenId
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request, $tokenId)
public function destroy(Request $request, string $tokenId): Response
{
$token = $this->tokenRepository->findForUser(
$tokenId, $request->user()->getAuthIdentifier()
$tokenId, $request->user()
);

if (is_null($token)) {
return new Response('', 404);
}

$token->revoke();

$this->refreshTokenRepository->revokeRefreshTokensByAccessTokenId($tokenId);
$token->refreshToken?->revoke();

return new Response('', Response::HTTP_NO_CONTENT);
}
Expand Down
Loading