mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
fix: make Lastfm work with Sanctum
This commit is contained in:
parent
e356e72814
commit
d5e2d3ec79
6 changed files with 43 additions and 17 deletions
|
@ -10,6 +10,7 @@ use App\Services\TokenManager;
|
|||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
/**
|
||||
* @group Last.fm integration
|
||||
|
@ -22,7 +23,7 @@ class LastfmController extends Controller
|
|||
/** @var User */
|
||||
private $currentUser;
|
||||
|
||||
public function __construct(LastfmService $lastfmService, TokenManager $tokenManager, Authenticatable $currentUser)
|
||||
public function __construct(LastfmService $lastfmService, TokenManager $tokenManager, ?Authenticatable $currentUser)
|
||||
{
|
||||
$this->lastfmService = $lastfmService;
|
||||
$this->tokenManager = $tokenManager;
|
||||
|
@ -45,7 +46,11 @@ class LastfmController extends Controller
|
|||
*/
|
||||
public function connect()
|
||||
{
|
||||
abort_unless($this->lastfmService->enabled(), 401, 'Koel is not configured to use with Last.fm yet.');
|
||||
abort_unless(
|
||||
$this->lastfmService->enabled(),
|
||||
Response::HTTP_NOT_IMPLEMENTED,
|
||||
'Koel is not configured to use with Last.fm yet.'
|
||||
);
|
||||
|
||||
$callbackUrl = urlencode(sprintf(
|
||||
'%s?api_token=%s',
|
||||
|
@ -63,9 +68,11 @@ class LastfmController extends Controller
|
|||
*/
|
||||
public function callback(LastfmCallbackRequest $request)
|
||||
{
|
||||
$sessionKey = $this->lastfmService->getSessionKey($request->token);
|
||||
$this->currentUser = $this->tokenManager->getUserFromPlainTextToken($request->api_token);
|
||||
abort_unless((bool) $this->currentUser, Response::HTTP_UNAUTHORIZED);
|
||||
|
||||
abort_unless($sessionKey, 500, 'Invalid token key.');
|
||||
$sessionKey = $this->lastfmService->getSessionKey($request->token);
|
||||
abort_unless($sessionKey, Response::HTTP_INTERNAL_SERVER_ERROR, 'Invalid token key.');
|
||||
|
||||
$this->currentUser->savePreference('lastfm_session_key', $sessionKey);
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
namespace App\Http\Requests\API;
|
||||
|
||||
/**
|
||||
* @property string $token
|
||||
* @property string $token Lastfm's access token
|
||||
* @property string $api_token Koel's current user's token
|
||||
*/
|
||||
class LastfmCallbackRequest extends Request
|
||||
{
|
||||
|
@ -11,6 +12,7 @@ class LastfmCallbackRequest extends Request
|
|||
{
|
||||
return [
|
||||
'token' => 'required',
|
||||
'api_token' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Services;
|
|||
|
||||
use App\Models\User;
|
||||
use Laravel\Sanctum\NewAccessToken;
|
||||
use Laravel\Sanctum\PersonalAccessToken;
|
||||
|
||||
class TokenManager
|
||||
{
|
||||
|
@ -16,4 +17,11 @@ class TokenManager
|
|||
{
|
||||
$user->tokens()->delete();
|
||||
}
|
||||
|
||||
public function getUserFromPlainTextToken(string $plainTextToken): ?User
|
||||
{
|
||||
$token = PersonalAccessToken::findToken($plainTextToken);
|
||||
|
||||
return $token ? $token->tokenable : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,9 +57,7 @@ Route::group(['namespace' => 'API'], function () {
|
|||
Route::put('me', 'ProfileController@update');
|
||||
|
||||
// Last.fm-related routes
|
||||
Route::get('lastfm/connect', 'LastfmController@connect');
|
||||
Route::post('lastfm/session-key', 'LastfmController@setSessionKey');
|
||||
Route::get('lastfm/callback', 'LastfmController@callback')->name('lastfm.callback');
|
||||
Route::delete('lastfm/disconnect', 'LastfmController@disconnect')->name('lastfm.disconnect');
|
||||
|
||||
// YouTube-related routes
|
||||
|
|
|
@ -14,3 +14,9 @@ Route::get('/♫', function () {
|
|||
Route::get('/remote', function () {
|
||||
return view('remote');
|
||||
});
|
||||
|
||||
Route::get('/lastfm/connect', 'API\LastfmController@connect')
|
||||
->name('lastfm.connect');
|
||||
|
||||
Route::get('/lastfm/callback', 'API\LastfmController@callback')
|
||||
->name('lastfm.callback');
|
||||
|
|
|
@ -9,7 +9,6 @@ use GuzzleHttp\Client;
|
|||
use GuzzleHttp\Psr7\Response;
|
||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||
use Illuminate\Log\Logger;
|
||||
use Laravel\Sanctum\NewAccessToken;
|
||||
use Mockery;
|
||||
|
||||
class LastfmTest extends TestCase
|
||||
|
@ -27,12 +26,12 @@ class LastfmTest extends TestCase
|
|||
|
||||
public function testSetSessionKey(): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = factory(User::class)->create();
|
||||
$this->postAsUser('api/lastfm/session-key', ['key' => 'foo'], $user)
|
||||
->assertOk();
|
||||
|
||||
$user = User::find($user->id);
|
||||
self::assertEquals('foo', $user->lastfm_session_key);
|
||||
self::assertEquals('foo', $user->refresh()->lastfm_session_key);
|
||||
}
|
||||
|
||||
public function testConnectToLastfm(): void
|
||||
|
@ -41,27 +40,33 @@ class LastfmTest extends TestCase
|
|||
$user = factory(User::class)->create();
|
||||
$token = $user->createToken('Koel')->plainTextToken;
|
||||
|
||||
$this->getAsUser('api/lastfm/connect?api_token='.$token, $user)
|
||||
$this->get('lastfm/connect?api_token='.$token)
|
||||
->assertRedirect(
|
||||
'https://www.last.fm/api/auth/?api_key=foo&cb=http%3A%2F%2Flocalhost%2Fapi%2Flastfm%2Fcallback%3Fapi_token%3D'
|
||||
'https://www.last.fm/api/auth/?api_key=foo&cb=http%3A%2F%2Flocalhost%2Flastfm%2Fcallback%3Fapi_token%3D'
|
||||
.urlencode($token)
|
||||
);
|
||||
}
|
||||
|
||||
public function testRetrieveAndStoreSessionKey(): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = factory(User::class)->create();
|
||||
|
||||
$lastfm = static::mockIocDependency(LastfmService::class);
|
||||
$lastfm->shouldReceive('getSessionKey')
|
||||
->once()
|
||||
->with('foo')
|
||||
->andReturn('bar');
|
||||
|
||||
/** @var User $user */
|
||||
$user = factory(User::class)->create();
|
||||
$this->getAsUser('api/lastfm/callback?token=foo', $user);
|
||||
$user->refresh();
|
||||
$tokenManager = static::mockIocDependency(TokenManager::class);
|
||||
$tokenManager->shouldReceive('getUserFromPlainTextToken')
|
||||
->once()
|
||||
->with('my-token')
|
||||
->andReturn($user);
|
||||
|
||||
self::assertEquals('bar', $user->lastfm_session_key);
|
||||
$this->get('lastfm/callback?token=foo&api_token=my-token');
|
||||
|
||||
self::assertEquals('bar', $user->refresh()->lastfm_session_key);
|
||||
}
|
||||
|
||||
public function testDisconnectUser(): void
|
||||
|
|
Loading…
Reference in a new issue