From 59aefe53713b5f999961db035dd9ea19a22dd768 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 10 Mar 2020 19:09:22 +0000 Subject: [PATCH] Updated social auth to take name from email if empty - Added tests to cover. Fixes #1853 --- .../Controllers/Auth/SocialController.php | 5 ++ tests/Auth/SocialAuthTest.php | 75 +++++++++++++------ 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/app/Http/Controllers/Auth/SocialController.php b/app/Http/Controllers/Auth/SocialController.php index ae7a1bc06..0c53c9233 100644 --- a/app/Http/Controllers/Auth/SocialController.php +++ b/app/Http/Controllers/Auth/SocialController.php @@ -123,6 +123,11 @@ class SocialController extends Controller 'password' => Str::random(32) ]; + // Take name from email address if empty + if (!$userData['name']) { + $userData['name'] = explode('@', $userData['email'])[0]; + } + $user = $this->registrationService->registerUser($userData, $socialAccount, $emailVerified); auth()->login($user); diff --git a/tests/Auth/SocialAuthTest.php b/tests/Auth/SocialAuthTest.php index 526c0e199..1a7a3fccc 100644 --- a/tests/Auth/SocialAuthTest.php +++ b/tests/Auth/SocialAuthTest.php @@ -1,20 +1,25 @@ make(); + $user = factory(User::class)->make(); $this->setSettings(['registration-enabled' => 'true']); config(['GOOGLE_APP_ID' => 'abc123', 'GOOGLE_APP_SECRET' => '123abc', 'APP_URL' => 'http://localhost']); - $mockSocialite = \Mockery::mock('Laravel\Socialite\Contracts\Factory'); - $this->app['Laravel\Socialite\Contracts\Factory'] = $mockSocialite; - $mockSocialDriver = \Mockery::mock('Laravel\Socialite\Contracts\Provider'); - $mockSocialUser = \Mockery::mock('\Laravel\Socialite\Contracts\User'); + $mockSocialite = Mockery::mock(Factory::class); + $this->app[Factory::class] = $mockSocialite; + $mockSocialDriver = Mockery::mock(Provider::class); + $mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class); $mockSocialite->shouldReceive('driver')->twice()->with('google')->andReturn($mockSocialDriver); $mockSocialDriver->shouldReceive('redirect')->once()->andReturn(redirect('/')); @@ -40,10 +45,10 @@ class SocialAuthTest extends TestCase 'APP_URL' => 'http://localhost' ]); - $mockSocialite = \Mockery::mock('Laravel\Socialite\Contracts\Factory'); - $this->app['Laravel\Socialite\Contracts\Factory'] = $mockSocialite; - $mockSocialDriver = \Mockery::mock('Laravel\Socialite\Contracts\Provider'); - $mockSocialUser = \Mockery::mock('\Laravel\Socialite\Contracts\User'); + $mockSocialite = Mockery::mock(Factory::class); + $this->app[Factory::class] = $mockSocialite; + $mockSocialDriver = Mockery::mock(Provider::class); + $mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class); $mockSocialUser->shouldReceive('getId')->twice()->andReturn('logintest123'); @@ -70,7 +75,7 @@ class SocialAuthTest extends TestCase // Test social callback with matching social account - \DB::table('social_accounts')->insert([ + DB::table('social_accounts')->insert([ 'user_id' => $this->getAdmin()->id, 'driver' => 'github', 'driver_id' => 'logintest123' @@ -86,11 +91,11 @@ class SocialAuthTest extends TestCase 'APP_URL' => 'http://localhost' ]); - $user = factory(\BookStack\Auth\User::class)->make(); - $mockSocialite = \Mockery::mock('Laravel\Socialite\Contracts\Factory'); - $this->app['Laravel\Socialite\Contracts\Factory'] = $mockSocialite; - $mockSocialDriver = \Mockery::mock('Laravel\Socialite\Contracts\Provider'); - $mockSocialUser = \Mockery::mock('\Laravel\Socialite\Contracts\User'); + $user = factory(User::class)->make(); + $mockSocialite = Mockery::mock(Factory::class); + $this->app[Factory::class] = $mockSocialite; + $mockSocialDriver = Mockery::mock(Provider::class); + $mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class); $mockSocialUser->shouldReceive('getId')->times(4)->andReturn(1); $mockSocialUser->shouldReceive('getEmail')->times(2)->andReturn($user->email); @@ -125,11 +130,11 @@ class SocialAuthTest extends TestCase 'APP_URL' => 'http://localhost', 'services.google.auto_register' => true, 'services.google.auto_confirm' => true ]); - $user = factory(\BookStack\Auth\User::class)->make(); - $mockSocialite = \Mockery::mock('Laravel\Socialite\Contracts\Factory'); - $this->app['Laravel\Socialite\Contracts\Factory'] = $mockSocialite; - $mockSocialDriver = \Mockery::mock('Laravel\Socialite\Contracts\Provider'); - $mockSocialUser = \Mockery::mock('\Laravel\Socialite\Contracts\User'); + $user = factory(User::class)->make(); + $mockSocialite = Mockery::mock(Factory::class); + $this->app[Factory::class] = $mockSocialite; + $mockSocialDriver = Mockery::mock(Provider::class); + $mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class); $mockSocialUser->shouldReceive('getId')->times(3)->andReturn(1); $mockSocialUser->shouldReceive('getEmail')->times(2)->andReturn($user->email); @@ -156,4 +161,32 @@ class SocialAuthTest extends TestCase $this->assertStringContainsString('prompt=select_account', $resp->headers->get('Location')); } + public function test_social_registration_with_no_name_uses_email_as_name() + { + $user = factory(User::class)->make(['email' => 'nonameuser@example.com']); + + $this->setSettings(['registration-enabled' => 'true']); + config(['GITHUB_APP_ID' => 'abc123', 'GITHUB_APP_SECRET' => '123abc', 'APP_URL' => 'http://localhost']); + + $mockSocialite = Mockery::mock(Factory::class); + $this->app[Factory::class] = $mockSocialite; + $mockSocialDriver = Mockery::mock(Provider::class); + $mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class); + + $mockSocialite->shouldReceive('driver')->twice()->with('github')->andReturn($mockSocialDriver); + $mockSocialDriver->shouldReceive('redirect')->once()->andReturn(redirect('/')); + $mockSocialDriver->shouldReceive('user')->once()->andReturn($mockSocialUser); + + $mockSocialUser->shouldReceive('getId')->twice()->andReturn(1); + $mockSocialUser->shouldReceive('getEmail')->twice()->andReturn($user->email); + $mockSocialUser->shouldReceive('getName')->once()->andReturn(''); + $mockSocialUser->shouldReceive('getAvatar')->once()->andReturn('avatar_placeholder'); + + $this->get('/register/service/github'); + $this->get('/login/service/github/callback'); + $this->assertDatabaseHas('users', ['name' => 'nonameuser', 'email' => $user->email]); + $user = $user->whereEmail($user->email)->first(); + $this->assertDatabaseHas('social_accounts', ['user_id' => $user->id]); + } + }