From 1e670b673f0a1a2f02566533b3676ae2097413bc Mon Sep 17 00:00:00 2001 From: Peter Deltchev Date: Fri, 30 Dec 2016 08:13:10 -0800 Subject: [PATCH] #25: Implemented a command to ensure all users have valid refresh tokens and email addresses. --- .../Commands/SyncPoniverseAccounts.php | 100 ++++++++++++++++++ app/Console/Kernel.php | 1 + app/Http/Middleware/AuthenticateOAuth.php | 2 +- app/Models/User.php | 16 ++- composer.lock | 8 +- tests/ApiAuthTest.php | 4 +- 6 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 app/Console/Commands/SyncPoniverseAccounts.php diff --git a/app/Console/Commands/SyncPoniverseAccounts.php b/app/Console/Commands/SyncPoniverseAccounts.php new file mode 100644 index 00000000..1d9edbd4 --- /dev/null +++ b/app/Console/Commands/SyncPoniverseAccounts.php @@ -0,0 +1,100 @@ +. + */ + +namespace Poniverse\Ponyfm\Console\Commands; + +use Illuminate\Console\Command; +use League\OAuth2\Client\Token\AccessToken; +use Poniverse\Lib\Client; +use Poniverse\Ponyfm\Models\User; + +class SyncPoniverseAccounts extends Command +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $signature = 'accounts:sync-with-poniverse'; + + /** + * @var Client + */ + protected $poniverse; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Ensures each Pony.fm account has a valid refresh token and email address from Poniverse on file.'; + + /** + * Create a new command instance. + */ + public function __construct() + { + parent::__construct(); + $this->poniverse = new Client( + config('poniverse.client_id'), config('poniverse.secret'), new \GuzzleHttp\Client()); + } + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $usersToUpdate = User::whereLinkedToPoniverse(); + + $progress = $this->output->createProgressBar($usersToUpdate->count()); + $progress->setFormat( +'%message% +%current%/%max% [%bar%] %percent:3s%% %elapsed:6s%'); + + $usersToUpdate + ->orderBy('id', 'ASC') + ->chunk(100, function($users) use ($progress) { + /** @var User $user */ + foreach ($users as $user) { + $progress->setMessage("Updating user ID {$user->id}..."); + $progress->advance(); + + $this->poniverse->poniverse()->meta() + ->syncAccount( + $user->getAccessToken()->getResourceOwnerId(), + function(AccessToken $accessTokenInfo) use ($user) { + $user->setAccessToken($accessTokenInfo); + }, + function(string $newEmailAddress) use ($user) { + $user->email = $newEmailAddress; + $user->save(); + }); + } + }); + + $progress->finish(); + $this->line(''); + $this->info('All done!'); + + return 0; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 11e080f7..1c84903f 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -44,6 +44,7 @@ class Kernel extends ConsoleKernel \Poniverse\Ponyfm\Console\Commands\RebuildFilesizes::class, \Poniverse\Ponyfm\Console\Commands\RebuildSearchIndex::class, \Poniverse\Ponyfm\Console\Commands\MergeAccounts::class, + \Poniverse\Ponyfm\Console\Commands\SyncPoniverseAccounts::class, \Poniverse\Ponyfm\Console\Commands\FixMLPMAImages::class, \Poniverse\Ponyfm\Console\Commands\VersionFiles::class ]; diff --git a/app/Http/Middleware/AuthenticateOAuth.php b/app/Http/Middleware/AuthenticateOAuth.php index 90e2a743..a891113c 100644 --- a/app/Http/Middleware/AuthenticateOAuth.php +++ b/app/Http/Middleware/AuthenticateOAuth.php @@ -69,7 +69,7 @@ class AuthenticateOAuth $accessToken = $this->determineAccessToken($request, false); // check that access token is valid at Poniverse.net - $accessTokenInfo = $this->poniverse->poniverse()->accessTokenInfo()->introspect($accessToken); + $accessTokenInfo = $this->poniverse->poniverse()->meta()->introspect($accessToken); if (!$accessTokenInfo->getIsActive()) { throw new AccessDeniedHttpException('This access token is expired or invalid!'); diff --git a/app/Models/User.php b/app/Models/User.php index 54e7ebd9..44e38980 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -98,6 +98,7 @@ use Venturecraft\Revisionable\RevisionableTrait; * @method static \Illuminate\Database\Query\Builder|\Poniverse\Ponyfm\Models\User withEmailSubscriptionFor($activityType) * @mixin \Eloquent * @method static \Illuminate\Database\Query\Builder|\Poniverse\Ponyfm\Models\User wherePoniverseId($poniverseId) + * @method static \Illuminate\Database\Query\Builder|\Poniverse\Ponyfm\Models\User whereLinkedToPoniverse() */ class User extends Model implements AuthenticatableContract, CanResetPasswordContract, \Illuminate\Contracts\Auth\Access\Authorizable, Searchable, Commentable { @@ -154,11 +155,22 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon */ public function scopeWherePoniverseId($query, int $poniverseId) { return $query - ->join('oauth2_tokens', 'users.id', '=', 'oauth2_tokens.user_id') - ->select('users.*', 'oauth2_tokens.external_user_id') + ->whereLinkedToPoniverse($query) ->where('oauth2_tokens.external_user_id', '=', $poniverseId); } + /** + * Filters the list of users to those who have a linked Poniverse account. + * + * @param $query + * @return mixed + */ + public function scopeWhereLinkedToPoniverse($query) { + return $query + ->join('oauth2_tokens', 'users.id', '=', 'oauth2_tokens.user_id') + ->select('users.*', 'oauth2_tokens.external_user_id'); + } + /** * Gets this user's OAuth access token record. * diff --git a/composer.lock b/composer.lock index 4e13e672..7c13e2d0 100644 --- a/composer.lock +++ b/composer.lock @@ -2597,12 +2597,12 @@ "source": { "type": "git", "url": "https://github.com/Poniverse/poniverse-php.git", - "reference": "851f9ea1495142dcbf0307d48131cedc70d4e44e" + "reference": "241c32e32076eaa4c0cf4d2a33cddcda006f2ba8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Poniverse/poniverse-php/zipball/851f9ea1495142dcbf0307d48131cedc70d4e44e", - "reference": "851f9ea1495142dcbf0307d48131cedc70d4e44e", + "url": "https://api.github.com/repos/Poniverse/poniverse-php/zipball/241c32e32076eaa4c0cf4d2a33cddcda006f2ba8", + "reference": "241c32e32076eaa4c0cf4d2a33cddcda006f2ba8", "shasum": "" }, "require": { @@ -2638,7 +2638,7 @@ "laravel", "laravel4" ], - "time": "2016-12-29 16:04:47" + "time": "2016-12-30 16:09:52" }, { "name": "predis/predis", diff --git a/tests/ApiAuthTest.php b/tests/ApiAuthTest.php index 52942d66..a4c4c4de 100644 --- a/tests/ApiAuthTest.php +++ b/tests/ApiAuthTest.php @@ -50,7 +50,7 @@ class ApiAuthTest extends TestCase ])); $poniverse->shouldReceive('setAccessToken'); - $accessTokenService = Mockery::mock('overload:Poniverse\Lib\Service\Poniverse\AccessTokenInfo'); + $accessTokenService = Mockery::mock('overload:Poniverse\Lib\Service\Poniverse\Meta'); $accessTokenService->shouldReceive('introspect') ->andReturn($accessTokenInfo); @@ -78,7 +78,7 @@ class ApiAuthTest extends TestCase ])); $poniverse->shouldReceive('setAccessToken'); - $accessTokenService = Mockery::mock('overload:Poniverse\Lib\Service\Poniverse\AccessTokenInfo'); + $accessTokenService = Mockery::mock('overload:Poniverse\Lib\Service\Poniverse\Meta'); $accessTokenService ->shouldReceive('introspect') ->andReturn($accessTokenInfo);