fix: normalize oauth emails before matching users (#9488)
This commit is contained in:
commit
f2ac6da98e
2 changed files with 86 additions and 2 deletions
|
|
@ -19,7 +19,12 @@ public function callback(string $provider)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$oauthUser = get_socialite_provider($provider)->user();
|
$oauthUser = get_socialite_provider($provider)->user();
|
||||||
$user = User::whereEmail($oauthUser->email)->first();
|
$email = trim((string) $oauthUser->email);
|
||||||
|
if ($email === '') {
|
||||||
|
abort(403, 'OAuth provider did not return an email address');
|
||||||
|
}
|
||||||
|
$email = strtolower($email);
|
||||||
|
$user = User::whereEmail($email)->first();
|
||||||
if (! $user) {
|
if (! $user) {
|
||||||
$settings = instanceSettings();
|
$settings = instanceSettings();
|
||||||
if (! $settings->is_registration_enabled) {
|
if (! $settings->is_registration_enabled) {
|
||||||
|
|
@ -28,7 +33,7 @@ public function callback(string $provider)
|
||||||
|
|
||||||
$user = User::create([
|
$user = User::create([
|
||||||
'name' => $oauthUser->name,
|
'name' => $oauthUser->name,
|
||||||
'email' => $oauthUser->email,
|
'email' => $email,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
Auth::login($user);
|
Auth::login($user);
|
||||||
|
|
|
||||||
79
tests/Feature/OauthControllerTest.php
Normal file
79
tests/Feature/OauthControllerTest.php
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\InstanceSettings;
|
||||||
|
use App\Models\OauthSetting;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Laravel\Socialite\Facades\Socialite;
|
||||||
|
|
||||||
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
InstanceSettings::create([
|
||||||
|
'id' => 0,
|
||||||
|
'is_registration_enabled' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
OauthSetting::create([
|
||||||
|
'provider' => 'google',
|
||||||
|
'client_id' => 'client-id',
|
||||||
|
'client_secret' => 'client-secret',
|
||||||
|
'redirect_uri' => 'https://coolify.example.com/auth/google/callback',
|
||||||
|
'tenant' => 'example.com',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('logs in an existing user when the oauth provider returns a mixed-case email', function () {
|
||||||
|
config()->set('app.maintenance.driver', 'file');
|
||||||
|
|
||||||
|
$user = User::factory()->create([
|
||||||
|
'email' => 'username@example.edu',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$provider = \Mockery::mock();
|
||||||
|
$provider->shouldReceive('setConfig')->once()->andReturnSelf();
|
||||||
|
$provider->shouldReceive('with')->once()->with(['hd' => 'example.com'])->andReturnSelf();
|
||||||
|
$provider->shouldReceive('user')->once()->andReturn((object) [
|
||||||
|
'email' => 'UserName@example.edu',
|
||||||
|
'name' => 'Example User',
|
||||||
|
'id' => 'google-user-id',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Socialite::shouldReceive('driver')->once()->with('google')->andReturn($provider);
|
||||||
|
|
||||||
|
$response = $this->get(route('auth.callback', 'google'));
|
||||||
|
|
||||||
|
$response->assertRedirect('/');
|
||||||
|
$this->assertAuthenticatedAs($user);
|
||||||
|
expect(User::count())->toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects oauth logins when the provider does not return an email address', function (?string $providerEmail) {
|
||||||
|
config()->set('app.maintenance.driver', 'file');
|
||||||
|
InstanceSettings::firstOrCreate([
|
||||||
|
'id' => 0,
|
||||||
|
], [
|
||||||
|
'is_registration_enabled' => false,
|
||||||
|
])->update([
|
||||||
|
'is_registration_enabled' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$provider = \Mockery::mock();
|
||||||
|
$provider->shouldReceive('setConfig')->once()->andReturnSelf();
|
||||||
|
$provider->shouldReceive('with')->once()->with(['hd' => 'example.com'])->andReturnSelf();
|
||||||
|
$provider->shouldReceive('user')->once()->andReturn((object) [
|
||||||
|
'email' => $providerEmail,
|
||||||
|
'name' => 'Example User',
|
||||||
|
'id' => 'google-user-id',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Socialite::shouldReceive('driver')->once()->with('google')->andReturn($provider);
|
||||||
|
|
||||||
|
$response = $this->from('/login')->get(route('auth.callback', 'google'));
|
||||||
|
|
||||||
|
$response->assertRedirect('/login');
|
||||||
|
expect(User::count())->toBe(0);
|
||||||
|
})->with([
|
||||||
|
'null email' => [null],
|
||||||
|
'blank email' => [' '],
|
||||||
|
]);
|
||||||
Loading…
Reference in a new issue