fix(auth): reject OAuth logins without valid provider IDs
Add validation for missing, blank, and non-scalar provider user IDs and cover the rejection cases with feature tests.
This commit is contained in:
parent
f9f26c547c
commit
d29139f4a3
2 changed files with 35 additions and 1 deletions
|
|
@ -36,7 +36,11 @@ public function login(string $provider, object $oauthUser, OauthSetting $oauthSe
|
|||
private function resolveOauthUser(object $oauthUser, OauthSetting $oauthSetting, string $email): User
|
||||
{
|
||||
$provider = $oauthSetting->provider;
|
||||
$providerUserId = (string) $oauthUser->id;
|
||||
$providerUserId = $oauthUser->id ?? null;
|
||||
if (! is_scalar($providerUserId) || trim((string) $providerUserId) === '') {
|
||||
throw new HttpException(403, 'OAuth provider did not return a valid user ID');
|
||||
}
|
||||
$providerUserId = (string) $providerUserId;
|
||||
$rawClaims = is_array($oauthUser->user ?? null) ? $oauthUser->user : [];
|
||||
|
||||
return DB::transaction(function () use ($oauthUser, $oauthSetting, $email, $provider, $providerUserId, $rawClaims) {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@
|
|||
use App\Models\OauthIdentity;
|
||||
use App\Models\OauthSetting;
|
||||
use App\Models\User;
|
||||
use App\Services\Auth\OauthLoginService;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Once;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
|
|
@ -121,3 +123,31 @@
|
|||
'malformed email' => ['not-an-email'],
|
||||
'missing domain' => ['user@'],
|
||||
]);
|
||||
|
||||
it('rejects oauth logins when the provider does not return a valid user id', function (mixed $invalidId) {
|
||||
$oauthUser = (object) [
|
||||
'email' => 'user@example.edu',
|
||||
'name' => 'Example User',
|
||||
];
|
||||
|
||||
if ($invalidId !== 'missing') {
|
||||
$oauthUser->id = $invalidId;
|
||||
}
|
||||
|
||||
try {
|
||||
app(OauthLoginService::class)->login('google', $oauthUser, OauthSetting::where('provider', 'google')->firstOrFail());
|
||||
} catch (HttpException $exception) {
|
||||
expect($exception->getStatusCode())->toBe(403)
|
||||
->and(OauthIdentity::count())->toBe(0)
|
||||
->and(User::count())->toBe(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->fail('Expected an invalid OAuth provider user ID to be rejected.');
|
||||
})->with([
|
||||
'null id' => [null],
|
||||
'missing id' => ['missing'],
|
||||
'blank id' => [' '],
|
||||
'non-scalar id' => [[]],
|
||||
]);
|
||||
|
|
|
|||
Loading…
Reference in a new issue