Skip to content

Commit c7322a7

Browse files
committed
Added theme add social driver redirect configuration callback
Allows someone using the theme system to configure the social driver before a redirect action occurs, by passing a callback as an additional param to the theme 'addSocialDriver' method.
1 parent 2c3523f commit c7322a7

File tree

4 files changed

+84
-11
lines changed

4 files changed

+84
-11
lines changed

app/Auth/Access/SocialAuthService.php

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,37 @@
1919

2020
class SocialAuthService
2121
{
22+
/**
23+
* The core socialite library used.
24+
* @var Socialite
25+
*/
2226
protected $socialite;
23-
protected $socialAccount;
2427

25-
protected $validSocialDrivers = ['google', 'github', 'facebook', 'slack', 'twitter', 'azure', 'okta', 'gitlab', 'twitch', 'discord'];
28+
/**
29+
* The default built-in social drivers we support.
30+
* @var string[]
31+
*/
32+
protected $validSocialDrivers = [
33+
'google',
34+
'github',
35+
'facebook',
36+
'slack',
37+
'twitter',
38+
'azure',
39+
'okta',
40+
'gitlab',
41+
'twitch',
42+
'discord'
43+
];
44+
45+
/**
46+
* Callbacks to run when configuring a social driver
47+
* for an initial redirect action.
48+
* Array is keyed by social driver name.
49+
* Callbacks are passed an instance of the driver.
50+
* @var array<string, callable>
51+
*/
52+
protected $configureForRedirectCallbacks = [];
2653

2754
/**
2855
* SocialAuthService constructor.
@@ -39,7 +66,7 @@ public function __construct(Socialite $socialite)
3966
public function startLogIn(string $socialDriver): RedirectResponse
4067
{
4168
$driver = $this->validateDriver($socialDriver);
42-
return $this->getSocialDriver($driver)->redirect();
69+
return $this->getDriverForRedirect($driver)->redirect();
4370
}
4471

4572
/**
@@ -49,7 +76,7 @@ public function startLogIn(string $socialDriver): RedirectResponse
4976
public function startRegister(string $socialDriver): RedirectResponse
5077
{
5178
$driver = $this->validateDriver($socialDriver);
52-
return $this->getSocialDriver($driver)->redirect();
79+
return $this->getDriverForRedirect($driver)->redirect();
5380
}
5481

5582
/**
@@ -227,7 +254,7 @@ public function detachSocialAccount(string $socialDriver): void
227254
/**
228255
* Provide redirect options per service for the Laravel Socialite driver
229256
*/
230-
public function getSocialDriver(string $driverName): Provider
257+
protected function getDriverForRedirect(string $driverName): Provider
231258
{
232259
$driver = $this->socialite->driver($driverName);
233260

@@ -238,6 +265,10 @@ public function getSocialDriver(string $driverName): Provider
238265
$driver->with(['resource' => 'https://graph.windows.net']);
239266
}
240267

268+
if (isset($this->configureForRedirectCallbacks[$driverName])) {
269+
$this->configureForRedirectCallbacks[$driverName]($driver);
270+
}
271+
241272
return $driver;
242273
}
243274

@@ -248,12 +279,19 @@ public function getSocialDriver(string $driverName): Provider
248279
* within the `Config/services.php` file.
249280
* Handler should be a Class@method handler to the SocialiteWasCalled event.
250281
*/
251-
public function addSocialDriver(string $driverName, array $config, string $socialiteHandler)
252-
{
282+
public function addSocialDriver(
283+
string $driverName,
284+
array $config,
285+
string $socialiteHandler,
286+
callable $configureForRedirect = null
287+
) {
253288
$this->validSocialDrivers[] = $driverName;
254289
config()->set('services.' . $driverName, $config);
255290
config()->set('services.' . $driverName . '.redirect', url('/login/service/' . $driverName . '/callback'));
256291
config()->set('services.' . $driverName . '.name', $config['name'] ?? $driverName);
257292
Event::listen(SocialiteWasCalled::class, $socialiteHandler);
293+
if (!is_null($configureForRedirect)) {
294+
$this->configureForRedirectCallbacks[$driverName] = $configureForRedirect;
295+
}
258296
}
259297
}

app/Theming/ThemeService.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ public function readThemeActions()
5353
/**
5454
* @see SocialAuthService::addSocialDriver
5555
*/
56-
public function addSocialDriver(string $driverName, array $config, string $socialiteHandler)
56+
public function addSocialDriver(string $driverName, array $config, string $socialiteHandler, callable $configureForRedirect = null)
5757
{
5858
$socialAuthService = app()->make(SocialAuthService::class);
59-
$socialAuthService->addSocialDriver($driverName, $config, $socialiteHandler);
59+
$socialAuthService->addSocialDriver($driverName, $config, $socialiteHandler, $configureForRedirect);
6060
}
6161
}

dev/docs/logical-theme-system.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,18 @@ Theme::listen(ThemeEvents::APP_BOOT, function($app) {
9595
'name' => 'Reddit',
9696
], '\SocialiteProviders\Reddit\RedditExtendSocialite@handle');
9797
});
98+
```
99+
100+
In some cases you may need to customize the driver before it performs a redirect.
101+
This can be done by providing a callback as a fourth parameter like so:
102+
103+
```php
104+
Theme::addSocialDriver('reddit', [
105+
'client_id' => 'abc123',
106+
'client_secret' => 'def456789',
107+
'name' => 'Reddit',
108+
], '\SocialiteProviders\Reddit\RedditExtendSocialite@handle', function($driver) {
109+
$driver->with(['prompt' => 'select_account']);
110+
$driver->scopes(['open_id']);
111+
});
98112
```

tests/ThemeTest.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?php namespace Tests;
22

3-
use BookStack\Auth\Access\SocialAuthService;
43
use BookStack\Auth\User;
54
use BookStack\Entities\Models\Page;
65
use BookStack\Entities\Tools\PageContent;
@@ -149,7 +148,7 @@ public function test_event_auth_register_standard()
149148
$this->setSettings(['registration-enabled' => 'true']);
150149

151150
$user = factory(User::class)->make();
152-
$this->post('/register', ['email' => $user->email, 'name' => $user->name, 'password' => 'password']);
151+
$this->post('/register', ['email' => $user->email, 'name' => $user->name, 'password' => 'password']);
153152

154153
$this->assertCount(2, $args);
155154
$this->assertEquals('standard', $args[0]);
@@ -184,6 +183,28 @@ public function test_add_social_driver_uses_name_in_config_if_given()
184183
$loginResp->assertSee('Super Cat Name');
185184
}
186185

186+
187+
public function test_add_social_driver_allows_a_configure_for_redirect_callback_to_be_passed()
188+
{
189+
Theme::addSocialDriver(
190+
'discord',
191+
[
192+
'client_id' => 'abc123',
193+
'client_secret' => 'def456',
194+
'name' => 'Super Cat Name',
195+
],
196+
'SocialiteProviders\Discord\DiscordExtendSocialite@handle',
197+
function ($driver) {
198+
$driver->with(['donkey' => 'donut']);
199+
}
200+
);
201+
202+
$loginResp = $this->get('/login/service/discord');
203+
$redirect = $loginResp->headers->get('location');
204+
$this->assertStringContainsString('donkey=donut', $redirect);
205+
}
206+
207+
187208
protected function usingThemeFolder(callable $callback)
188209
{
189210
// Create a folder and configure a theme

0 commit comments

Comments
 (0)