Skip to content

Commit 64b41dd

Browse files
committed
Merge branch 'development' into release
2 parents ebd6e4d + 1036498 commit 64b41dd

File tree

294 files changed

+6050
-3366
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

294 files changed

+6050
-3366
lines changed

.github/translators.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,11 @@ DerLinkman (derlinkman) :: German; German Informal
280280
TurnArabic :: Arabic
281281
Martin Sebek (sebekmartin) :: Czech
282282
Kuchinashi Hoshikawa (kuchinashi) :: Chinese Simplified
283+
digilady :: Greek
284+
Linus (LinusOP) :: Swedish
285+
Felipe Cardoso (felipecardosoruff) :: Portuguese, Brazilian
286+
RandomUser0815 :: German
287+
Ismael Mesquita (mesquitoliveira) :: Portuguese, Brazilian
288+
구인회 (laskdjlaskdj12) :: Korean
289+
LiZerui (CNLiZerui) :: Chinese Traditional
290+
Fabrice Boyer (FabriceBoyer) :: French

LICENSE

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2015-present, Dan Brown and the BookStack Project contributors
4-
https://github.com/BookStackApp/BookStack/graphs/contributors
3+
Copyright (c) 2015-2022, Dan Brown and the BookStack Project contributors.
54

65
Permission is hereby granted, free of charge, to any person obtaining a copy
76
of this software and associated documentation files (the "Software"), to deal

app/Actions/TagRepo.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,29 +57,29 @@ public function queryWithTotals(string $searchTerm, string $nameFilter): Builder
5757
* Get tag name suggestions from scanning existing tag names.
5858
* If no search term is given the 50 most popular tag names are provided.
5959
*/
60-
public function getNameSuggestions(?string $searchTerm): Collection
60+
public function getNameSuggestions(string $searchTerm): Collection
6161
{
6262
$query = Tag::query()
6363
->select('*', DB::raw('count(*) as count'))
6464
->groupBy('name');
6565

6666
if ($searchTerm) {
67-
$query = $query->where('name', 'LIKE', $searchTerm . '%')->orderBy('name', 'desc');
67+
$query = $query->where('name', 'LIKE', $searchTerm . '%')->orderBy('name', 'asc');
6868
} else {
6969
$query = $query->orderBy('count', 'desc')->take(50);
7070
}
7171

7272
$query = $this->permissions->restrictEntityRelationQuery($query, 'tags', 'entity_id', 'entity_type');
7373

74-
return $query->get(['name'])->pluck('name');
74+
return $query->pluck('name');
7575
}
7676

7777
/**
7878
* Get tag value suggestions from scanning existing tag values.
7979
* If no search is given the 50 most popular values are provided.
8080
* Passing a tagName will only find values for a tags with a particular name.
8181
*/
82-
public function getValueSuggestions(?string $searchTerm, ?string $tagName): Collection
82+
public function getValueSuggestions(string $searchTerm, string $tagName): Collection
8383
{
8484
$query = Tag::query()
8585
->select('*', DB::raw('count(*) as count'))
@@ -97,7 +97,7 @@ public function getValueSuggestions(?string $searchTerm, ?string $tagName): Coll
9797

9898
$query = $this->permissions->restrictEntityRelationQuery($query, 'tags', 'entity_id', 'entity_type');
9999

100-
return $query->get(['value'])->pluck('value');
100+
return $query->pluck('value');
101101
}
102102

103103
/**

app/Api/ApiEntityListFormatter.php

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
namespace BookStack\Api;
4+
5+
use BookStack\Entities\Models\Entity;
6+
7+
class ApiEntityListFormatter
8+
{
9+
/**
10+
* The list to be formatted.
11+
* @var Entity[]
12+
*/
13+
protected $list = [];
14+
15+
/**
16+
* The fields to show in the formatted data.
17+
* Can be a plain string array item for a direct model field (If existing on model).
18+
* If the key is a string, with a callable value, the return value of the callable
19+
* will be used for the resultant value. A null return value will omit the property.
20+
* @var array<string|int, string|callable>
21+
*/
22+
protected $fields = [
23+
'id', 'name', 'slug', 'book_id', 'chapter_id',
24+
'draft', 'template', 'created_at', 'updated_at',
25+
];
26+
27+
public function __construct(array $list)
28+
{
29+
$this->list = $list;
30+
31+
// Default dynamic fields
32+
$this->withField('url', fn(Entity $entity) => $entity->getUrl());
33+
}
34+
35+
/**
36+
* Add a field to be used in the formatter, with the property using the given
37+
* name and value being the return type of the given callback.
38+
*/
39+
public function withField(string $property, callable $callback): self
40+
{
41+
$this->fields[$property] = $callback;
42+
return $this;
43+
}
44+
45+
/**
46+
* Show the 'type' property in the response reflecting the entity type.
47+
* EG: page, chapter, bookshelf, book
48+
* To be included in results with non-pre-determined types.
49+
*/
50+
public function withType(): self
51+
{
52+
$this->withField('type', fn(Entity $entity) => $entity->getType());
53+
return $this;
54+
}
55+
56+
/**
57+
* Include tags in the formatted data.
58+
*/
59+
public function withTags(): self
60+
{
61+
$this->withField('tags', fn(Entity $entity) => $entity->tags);
62+
return $this;
63+
}
64+
65+
/**
66+
* Format the data and return an array of formatted content.
67+
* @return array[]
68+
*/
69+
public function format(): array
70+
{
71+
$results = [];
72+
73+
foreach ($this->list as $item) {
74+
$results[] = $this->formatSingle($item);
75+
}
76+
77+
return $results;
78+
}
79+
80+
/**
81+
* Format a single entity item to a plain array.
82+
*/
83+
protected function formatSingle(Entity $entity): array
84+
{
85+
$result = [];
86+
$values = (clone $entity)->toArray();
87+
88+
foreach ($this->fields as $field => $callback) {
89+
if (is_string($callback)) {
90+
$field = $callback;
91+
if (!isset($values[$field])) {
92+
continue;
93+
}
94+
$value = $values[$field];
95+
} else {
96+
$value = $callback($entity);
97+
if (is_null($value)) {
98+
continue;
99+
}
100+
}
101+
102+
$result[$field] = $value;
103+
}
104+
105+
return $result;
106+
}
107+
}

app/Api/ListingResponseBuilder.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace BookStack\Api;
44

5-
use BookStack\Model;
65
use Illuminate\Database\Eloquent\Builder;
76
use Illuminate\Database\Eloquent\Collection;
87
use Illuminate\Http\JsonResponse;

app/Auth/Access/LoginService.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use BookStack\Actions\ActivityType;
66
use BookStack\Auth\Access\Mfa\MfaSession;
77
use BookStack\Auth\User;
8+
use BookStack\Exceptions\LoginAttemptException;
89
use BookStack\Exceptions\StoppedAuthenticationException;
910
use BookStack\Facades\Activity;
1011
use BookStack\Facades\Theme;
@@ -149,6 +150,7 @@ public function awaitingEmailConfirmation(User $user): bool
149150
* May interrupt the flow if extra authentication requirements are imposed.
150151
*
151152
* @throws StoppedAuthenticationException
153+
* @throws LoginAttemptException
152154
*/
153155
public function attempt(array $credentials, string $method, bool $remember = false): bool
154156
{

app/Auth/Access/Saml2Service.php

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,11 @@
2020
*/
2121
class Saml2Service
2222
{
23-
protected $config;
24-
protected $registrationService;
25-
protected $loginService;
26-
protected $groupSyncService;
23+
protected array $config;
24+
protected RegistrationService $registrationService;
25+
protected LoginService $loginService;
26+
protected GroupSyncService $groupSyncService;
2727

28-
/**
29-
* Saml2Service constructor.
30-
*/
3128
public function __construct(
3229
RegistrationService $registrationService,
3330
LoginService $loginService,
@@ -169,7 +166,7 @@ protected function actionLogout()
169166
*/
170167
public function metadata(): string
171168
{
172-
$toolKit = $this->getToolkit();
169+
$toolKit = $this->getToolkit(true);
173170
$settings = $toolKit->getSettings();
174171
$metadata = $settings->getSPMetadata();
175172
$errors = $settings->validateMetadata($metadata);
@@ -190,7 +187,7 @@ public function metadata(): string
190187
* @throws Error
191188
* @throws Exception
192189
*/
193-
protected function getToolkit(): Auth
190+
protected function getToolkit(bool $spOnly = false): Auth
194191
{
195192
$settings = $this->config['onelogin'];
196193
$overrides = $this->config['onelogin_overrides'] ?? [];
@@ -200,14 +197,14 @@ protected function getToolkit(): Auth
200197
}
201198

202199
$metaDataSettings = [];
203-
if ($this->config['autoload_from_metadata']) {
200+
if (!$spOnly && $this->config['autoload_from_metadata']) {
204201
$metaDataSettings = IdPMetadataParser::parseRemoteXML($settings['idp']['entityId']);
205202
}
206203

207204
$spSettings = $this->loadOneloginServiceProviderDetails();
208205
$settings = array_replace_recursive($settings, $spSettings, $metaDataSettings, $overrides);
209206

210-
return new Auth($settings);
207+
return new Auth($settings, $spOnly);
211208
}
212209

213210
/**

app/Auth/Permissions/EntityPermission.php

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,41 @@
22

33
namespace BookStack\Auth\Permissions;
44

5+
use BookStack\Auth\Role;
56
use BookStack\Model;
7+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
8+
use Illuminate\Database\Eloquent\Relations\MorphTo;
69

10+
/**
11+
* @property int $id
12+
* @property int $role_id
13+
* @property int $entity_id
14+
* @property string $entity_type
15+
* @property boolean $view
16+
* @property boolean $create
17+
* @property boolean $update
18+
* @property boolean $delete
19+
*/
720
class EntityPermission extends Model
821
{
9-
protected $fillable = ['role_id', 'action'];
22+
public const PERMISSIONS = ['view', 'create', 'update', 'delete'];
23+
24+
protected $fillable = ['role_id', 'view', 'create', 'update', 'delete'];
1025
public $timestamps = false;
1126

1227
/**
13-
* Get all this restriction's attached entity.
14-
*
15-
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
28+
* Get this restriction's attached entity.
1629
*/
17-
public function restrictable()
30+
public function restrictable(): MorphTo
1831
{
1932
return $this->morphTo('restrictable');
2033
}
34+
35+
/**
36+
* Get the role assigned to this entity permission.
37+
*/
38+
public function role(): BelongsTo
39+
{
40+
return $this->belongsTo(Role::class);
41+
}
2142
}

0 commit comments

Comments
 (0)