Skip to content

Commit 1ee8287

Browse files
committed
Merge branch 'v21.04.x' into release
2 parents 8eb98cd + c7322a7 commit 1ee8287

File tree

6 files changed

+101
-27
lines changed

6 files changed

+101
-27
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
}

app/Uploads/ImageService.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,13 @@ protected function saveImageDataInPublicSpace(Storage $storage, string $path, st
140140
{
141141
$storage->put($path, $data);
142142

143-
// Set visibility if using s3 without an endpoint set.
144-
// Done since this call can break s3-like services but desired for actual
145-
// AWS s3 usage. Attempting to set ACL during above put request requires
146-
// different permissions hence would technically be a breaking change.
143+
// Set visibility when a non-AWS-s3, s3-like storage option is in use.
144+
// Done since this call can break s3-like services but desired for other image stores.
145+
// Attempting to set ACL during above put request requires different permissions
146+
// hence would technically be a breaking change for actual s3 usage.
147147
$usingS3 = strtolower(config('filesystems.images')) === 's3';
148-
if ($usingS3 && is_null(config('filesystems.disks.s3.endpoint'))) {
148+
$usingS3Like = $usingS3 && !is_null(config('filesystems.disks.s3.endpoint'));
149+
if (!$usingS3Like) {
149150
$storage->setVisibility($path, 'public');
150151
}
151152
}

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

tests/Uploads/ImageTest.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class ImageTest extends TestCase
1414

1515
public function test_image_upload()
1616
{
17-
$page = Page::first();
17+
$page = Page::query()->first();
1818
$admin = $this->getAdmin();
1919
$this->actingAs($admin);
2020

@@ -38,7 +38,7 @@ public function test_image_upload()
3838

3939
public function test_image_display_thumbnail_generation_does_not_increase_image_size()
4040
{
41-
$page = Page::first();
41+
$page = Page::query()->first();
4242
$admin = $this->getAdmin();
4343
$this->actingAs($admin);
4444

@@ -108,7 +108,7 @@ public function test_gallery_get_list_format()
108108

109109
public function test_image_usage()
110110
{
111-
$page = Page::first();
111+
$page = Page::query()->first();
112112
$editor = $this->getEditor();
113113
$this->actingAs($editor);
114114

@@ -128,7 +128,7 @@ public function test_image_usage()
128128

129129
public function test_php_files_cannot_be_uploaded()
130130
{
131-
$page = Page::first();
131+
$page = Page::query()->first();
132132
$admin = $this->getAdmin();
133133
$this->actingAs($admin);
134134

@@ -150,7 +150,7 @@ public function test_php_files_cannot_be_uploaded()
150150

151151
public function test_php_like_files_cannot_be_uploaded()
152152
{
153-
$page = Page::first();
153+
$page = Page::query()->first();
154154
$admin = $this->getAdmin();
155155
$this->actingAs($admin);
156156

@@ -202,7 +202,7 @@ public function test_url_entities_removed_from_filenames()
202202
];
203203
foreach ($badNames as $name) {
204204
$galleryFile = $this->getTestImage($name);
205-
$page = Page::first();
205+
$page = Page::query()->first();
206206
$badPath = $this->getTestImagePath('gallery', $name);
207207
$this->deleteImage($badPath);
208208

@@ -227,7 +227,7 @@ public function test_secure_images_uploads_to_correct_place()
227227
config()->set('filesystems.images', 'local_secure');
228228
$this->asEditor();
229229
$galleryFile = $this->getTestImage('my-secure-test-upload.png');
230-
$page = Page::first();
230+
$page = Page::query()->first();
231231
$expectedPath = storage_path('uploads/images/gallery/' . Date('Y-m') . '/my-secure-test-upload.png');
232232

233233
$upload = $this->call('POST', '/images/gallery', ['uploaded_to' => $page->id], [], ['file' => $galleryFile], []);
@@ -245,7 +245,7 @@ public function test_secure_images_included_in_exports()
245245
config()->set('filesystems.images', 'local_secure');
246246
$this->asEditor();
247247
$galleryFile = $this->getTestImage('my-secure-test-upload.png');
248-
$page = Page::first();
248+
$page = Page::query()->first();
249249
$expectedPath = storage_path('uploads/images/gallery/' . Date('Y-m') . '/my-secure-test-upload.png');
250250

251251
$upload = $this->call('POST', '/images/gallery', ['uploaded_to' => $page->id], [], ['file' => $galleryFile], []);
@@ -282,7 +282,7 @@ public function test_system_images_remain_public()
282282

283283
public function test_image_delete()
284284
{
285-
$page = Page::first();
285+
$page = Page::query()->first();
286286
$this->asAdmin();
287287
$imageName = 'first-image.png';
288288
$relPath = $this->getTestImagePath('gallery', $imageName);
@@ -304,7 +304,7 @@ public function test_image_delete()
304304

305305
public function test_image_delete_does_not_delete_similar_images()
306306
{
307-
$page = Page::first();
307+
$page = Page::query()->first();
308308
$this->asAdmin();
309309
$imageName = 'first-image.png';
310310

@@ -383,7 +383,7 @@ public function test_user_images_deleted_on_user_deletion()
383383

384384
public function test_deleted_unused_images()
385385
{
386-
$page = Page::first();
386+
$page = Page::query()->first();
387387
$admin = $this->getAdmin();
388388
$this->actingAs($admin);
389389

0 commit comments

Comments
 (0)