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

[5.x] OAuth: option not to create or update user during authentication #10853

Merged
merged 8 commits into from
Dec 16, 2024
6 changes: 5 additions & 1 deletion resources/views/auth/unauthorized.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
<div class="outside-shadow absolute inset-0"></div>
<div class="card auth-card">
<div class="mb-6">{{ __('Unauthorized') }}</div>
<a class="btn-primary" href="{{ cp_route('logout') }}?redirect={{ $redirect }}">{{ __('Log out') }}</a>
@auth
<a class="btn-primary" href="{{ cp_route('logout') }}?redirect={{ $redirect }}">{{ __('Log out') }}</a>
@else
<a class="btn-primary" href="{{ cp_route('login') }}">{{ __('Log in') }}</a>
@endauth
</div>
</div>

Expand Down
25 changes: 20 additions & 5 deletions src/Http/Controllers/OAuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,24 @@ public function handleProviderCallback(Request $request, string $provider)
return $this->redirectToProvider($request, $provider);
}

$user = $oauth->findOrCreateUser($providerUser);
if ($user = $oauth->findUser($providerUser)) {
if (config('statamic.oauth.merge_user_data', true)) {
$user = $oauth->mergeUser($user, $providerUser);
}
} elseif (config('statamic.oauth.create_user', true)) {
$user = $oauth->createUser($providerUser);
}

session()->put('oauth-provider', $provider);
if ($user) {
session()->put('oauth-provider', $provider);

Auth::guard($request->session()->get('statamic.oauth.guard'))
->login($user, config('statamic.oauth.remember_me', true));
Auth::guard($request->session()->get('statamic.oauth.guard'))
->login($user, config('statamic.oauth.remember_me', true));

return redirect()->to($this->successRedirectUrl());
return redirect()->to($this->successRedirectUrl());
} else {
return redirect()->to($this->unauthorizedRedirectUrl());
}
}

protected function successRedirectUrl()
Expand All @@ -60,4 +70,9 @@ protected function successRedirectUrl()

return Arr::get($query, 'redirect', $default);
}

protected function unauthorizedRedirectUrl()
{
return config('statamic.oauth.unauthorized_redirect', '/cp/auth/unauthorized');
}
}
18 changes: 16 additions & 2 deletions src/OAuth/Provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,29 @@ public function getUserId(string $id): ?string
}

public function findOrCreateUser($socialite): StatamicUser
{
if ($user = $this->findUser($socialite)) {
return $this->mergeUser($user, $socialite);
}

return $this->createUser($socialite);
}

/**
* Find a Statamic user by a Socialite user.
*
* @param SocialiteUser $socialite
*/
public function findUser($socialite): ?StatamicUser
{
if (
($user = User::findByOAuthId($this, $socialite->getId())) ||
($user = User::findByEmail($socialite->getEmail()))
) {
return $this->mergeUser($user, $socialite);
return $user;
}

return $this->createUser($socialite);
return null;
}

/**
Expand Down
50 changes: 49 additions & 1 deletion tests/OAuth/ProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,39 @@ public function it_creates_a_user()
}

#[Test]
public function it_finds_an_existing_user_by_email()
public function it_finds_an_existing_user_via_find_user_method()
{
$provider = $this->provider();

$savedUser = $this->user()->save();

$this->assertCount(1, UserFacade::all());
$this->assertEquals([$savedUser], UserFacade::all()->all());

$foundUser = $provider->findUser($this->socialite());

$this->assertCount(1, UserFacade::all());
$this->assertEquals([$savedUser], UserFacade::all()->all());
$this->assertEquals($savedUser, $foundUser);
}

#[Test]
public function it_does_not_find_or_create_a_user_via_find_user_method()
{
$this->assertCount(0, UserFacade::all());

$provider = $this->provider();
$foundUser = $provider->findUser($this->socialite());

$this->assertNull($foundUser);

$this->assertCount(0, UserFacade::all());
$user = UserFacade::all()->get(0);
$this->assertNull($user);
}

#[Test]
public function it_finds_an_existing_user_via_find_or_create_user_method()
{
$provider = $this->provider();

Expand All @@ -138,6 +170,22 @@ public function it_finds_an_existing_user_by_email()
$this->assertEquals($savedUser, $foundUser);
}

#[Test]
public function it_creates_a_user_via_find_or_create_user_method()
{
$this->assertCount(0, UserFacade::all());

$provider = $this->provider();
$provider->findOrCreateUser($this->socialite());

$this->assertCount(1, UserFacade::all());
$user = UserFacade::all()->get(0);
$this->assertNotNull($user);
$this->assertEquals('[email protected]', $user->email());
$this->assertEquals('Foo Bar', $user->name());
$this->assertEquals($user->id(), $provider->getUserId('foo-bar'));
}

#[Test]
public function it_gets_the_user_by_id_after_merging_data()
{
Expand Down
Loading