Skip to content

Commit e305ba1

Browse files
committed
Merge branch 'master' into attachment_drag_drop
2 parents 18f406d + b87e97f commit e305ba1

Some content is hidden

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

47 files changed

+940
-3801
lines changed

.env.example.complete

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,12 @@ API_DEFAULT_ITEM_COUNT=100
270270
API_MAX_ITEM_COUNT=500
271271

272272
# The number of API requests that can be made per minute by a single user.
273-
API_REQUESTS_PER_MIN=180
273+
API_REQUESTS_PER_MIN=180
274+
275+
# Enable the logging of failed email+password logins with the given message
276+
# The defaul log channel below uses the php 'error_log' function which commonly
277+
# results in messages being output to the webserver error logs.
278+
# The message can contain a %u parameter which will be replaced with the login
279+
# user identifier (Username or email).
280+
LOG_FAILED_LOGIN_MESSAGE=false
281+
LOG_FAILED_LOGIN_CHANNEL=errorlog_plain_webserver

app/Actions/ActivityService.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use BookStack\Auth\User;
55
use BookStack\Entities\Entity;
66
use Illuminate\Support\Collection;
7+
use Illuminate\Support\Facades\Log;
78

89
class ActivityService
910
{
@@ -49,7 +50,7 @@ public function addMessage(string $activityKey, string $message, ?int $bookId =
4950
protected function newActivityForUser(string $key, ?int $bookId = null): Activity
5051
{
5152
return $this->activity->newInstance()->forceFill([
52-
'key' => strtolower($key),
53+
'key' => strtolower($key),
5354
'user_id' => $this->user->id,
5455
'book_id' => $bookId ?? 0,
5556
]);
@@ -64,8 +65,8 @@ public function removeEntity(Entity $entity): Collection
6465
{
6566
$activities = $entity->activity()->get();
6667
$entity->activity()->update([
67-
'extra' => $entity->name,
68-
'entity_id' => 0,
68+
'extra' => $entity->name,
69+
'entity_id' => 0,
6970
'entity_type' => '',
7071
]);
7172
return $activities;
@@ -99,7 +100,7 @@ public function entityActivity(Entity $entity, int $count = 20, int $page = 1):
99100
$query = $this->activity->newQuery()->where('entity_type', '=', $entity->getMorphClass())
100101
->where('entity_id', '=', $entity->id);
101102
}
102-
103+
103104
$activity = $this->permissionService
104105
->filterRestrictedEntityRelations($query, 'activities', 'entity_id', 'entity_type')
105106
->orderBy('created_at', 'desc')
@@ -159,4 +160,20 @@ protected function setNotification(string $activityKey)
159160
session()->flash('success', $message);
160161
}
161162
}
163+
164+
/**
165+
* Log out a failed login attempt, Providing the given username
166+
* as part of the message if the '%u' string is used.
167+
*/
168+
public function logFailedLogin(string $username)
169+
{
170+
$message = config('logging.failed_login.message');
171+
if (!$message) {
172+
return;
173+
}
174+
175+
$message = str_replace("%u", $username, $message);
176+
$channel = config('logging.failed_login.channel');
177+
Log::channel($channel)->warning($message);
178+
}
162179
}

app/Auth/Access/ExternalAuthService.php

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
use BookStack\Auth\Role;
44
use BookStack\Auth\User;
55
use Illuminate\Database\Eloquent\Builder;
6+
use Illuminate\Support\Collection;
7+
use Illuminate\Support\Facades\DB;
68

79
class ExternalAuthService
810
{
@@ -39,22 +41,14 @@ protected function externalIdMatchesGroupNames(string $externalId, array $groupN
3941
/**
4042
* Match an array of group names to BookStack system roles.
4143
* Formats group names to be lower-case and hyphenated.
42-
* @param array $groupNames
43-
* @return \Illuminate\Support\Collection
4444
*/
45-
protected function matchGroupsToSystemsRoles(array $groupNames)
45+
protected function matchGroupsToSystemsRoles(array $groupNames): Collection
4646
{
4747
foreach ($groupNames as $i => $groupName) {
4848
$groupNames[$i] = str_replace(' ', '-', trim(strtolower($groupName)));
4949
}
5050

51-
$roles = Role::query()->where(function (Builder $query) use ($groupNames) {
52-
$query->whereIn('name', $groupNames);
53-
foreach ($groupNames as $groupName) {
54-
$query->orWhere('external_auth_id', 'LIKE', '%' . $groupName . '%');
55-
}
56-
})->get();
57-
51+
$roles = Role::query()->get(['id', 'external_auth_id', 'display_name']);
5852
$matchedRoles = $roles->filter(function (Role $role) use ($groupNames) {
5953
return $this->roleMatchesGroupNames($role, $groupNames);
6054
});

app/Auth/Access/RegistrationService.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,15 @@ public function registerUser(array $userData, ?SocialAccount $socialAccount = nu
7171
// Start email confirmation flow if required
7272
if ($this->emailConfirmationService->confirmationRequired() && !$emailConfirmed) {
7373
$newUser->save();
74-
$message = '';
7574

7675
try {
7776
$this->emailConfirmationService->sendConfirmation($newUser);
77+
session()->flash('sent-email-confirmation', true);
7878
} catch (Exception $e) {
7979
$message = trans('auth.email_confirm_send_error');
80+
throw new UserRegistrationException($message, '/register/confirm');
8081
}
8182

82-
throw new UserRegistrationException($message, '/register/confirm');
8383
}
8484

8585
return $newUser;

app/Auth/Access/Saml2Service.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ protected function getSamlResponseAttribute(array $samlAttributes, string $prope
311311

312312
/**
313313
* Get the user from the database for the specified details.
314-
* @throws SamlException
315314
* @throws UserRegistrationException
316315
*/
317316
protected function getOrRegisterUser(array $userDetails): ?User

app/Auth/Permissions/JointPermission.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@
33
use BookStack\Auth\Role;
44
use BookStack\Entities\Entity;
55
use BookStack\Model;
6+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
7+
use Illuminate\Database\Eloquent\Relations\MorphOne;
68

79
class JointPermission extends Model
810
{
11+
protected $primaryKey = null;
912
public $timestamps = false;
1013

1114
/**
1215
* Get the role that this points to.
13-
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
1416
*/
15-
public function role()
17+
public function role(): BelongsTo
1618
{
1719
return $this->belongsTo(Role::class);
1820
}
1921

2022
/**
2123
* Get the entity this points to.
22-
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
2324
*/
24-
public function entity()
25+
public function entity(): MorphOne
2526
{
2627
return $this->morphOne(Entity::class, 'entity');
2728
}

app/Auth/Permissions/PermissionsRepo.php

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<?php namespace BookStack\Auth\Permissions;
22

3-
use BookStack\Auth\Permissions;
43
use BookStack\Auth\Role;
54
use BookStack\Exceptions\PermissionsException;
5+
use Exception;
6+
use Illuminate\Database\Eloquent\Collection;
67
use Illuminate\Support\Str;
78

89
class PermissionsRepo
@@ -16,11 +17,8 @@ class PermissionsRepo
1617

1718
/**
1819
* PermissionsRepo constructor.
19-
* @param RolePermission $permission
20-
* @param Role $role
21-
* @param \BookStack\Auth\Permissions\PermissionService $permissionService
2220
*/
23-
public function __construct(RolePermission $permission, Role $role, Permissions\PermissionService $permissionService)
21+
public function __construct(RolePermission $permission, Role $role, PermissionService $permissionService)
2422
{
2523
$this->permission = $permission;
2624
$this->role = $role;
@@ -29,46 +27,34 @@ public function __construct(RolePermission $permission, Role $role, Permissions\
2927

3028
/**
3129
* Get all the user roles from the system.
32-
* @return \Illuminate\Database\Eloquent\Collection|static[]
3330
*/
34-
public function getAllRoles()
31+
public function getAllRoles(): Collection
3532
{
3633
return $this->role->all();
3734
}
3835

3936
/**
4037
* Get all the roles except for the provided one.
41-
* @param Role $role
42-
* @return mixed
4338
*/
44-
public function getAllRolesExcept(Role $role)
39+
public function getAllRolesExcept(Role $role): Collection
4540
{
4641
return $this->role->where('id', '!=', $role->id)->get();
4742
}
4843

4944
/**
5045
* Get a role via its ID.
51-
* @param $id
52-
* @return mixed
5346
*/
54-
public function getRoleById($id)
47+
public function getRoleById($id): Role
5548
{
56-
return $this->role->findOrFail($id);
49+
return $this->role->newQuery()->findOrFail($id);
5750
}
5851

5952
/**
6053
* Save a new role into the system.
61-
* @param array $roleData
62-
* @return Role
6354
*/
64-
public function saveNewRole($roleData)
55+
public function saveNewRole(array $roleData): Role
6556
{
6657
$role = $this->role->newInstance($roleData);
67-
$role->name = str_replace(' ', '-', strtolower($roleData['display_name']));
68-
// Prevent duplicate names
69-
while ($this->role->where('name', '=', $role->name)->count() > 0) {
70-
$role->name .= strtolower(Str::random(2));
71-
}
7258
$role->save();
7359

7460
$permissions = isset($roleData['permissions']) ? array_keys($roleData['permissions']) : [];
@@ -80,13 +66,11 @@ public function saveNewRole($roleData)
8066
/**
8167
* Updates an existing role.
8268
* Ensure Admin role always have core permissions.
83-
* @param $roleId
84-
* @param $roleData
85-
* @throws PermissionsException
8669
*/
87-
public function updateRole($roleId, $roleData)
70+
public function updateRole($roleId, array $roleData)
8871
{
89-
$role = $this->role->findOrFail($roleId);
72+
/** @var Role $role */
73+
$role = $this->role->newQuery()->findOrFail($roleId);
9074

9175
$permissions = isset($roleData['permissions']) ? array_keys($roleData['permissions']) : [];
9276
if ($role->system_name === 'admin') {
@@ -108,16 +92,19 @@ public function updateRole($roleId, $roleData)
10892

10993
/**
11094
* Assign an list of permission names to an role.
111-
* @param Role $role
112-
* @param array $permissionNameArray
11395
*/
114-
public function assignRolePermissions(Role $role, $permissionNameArray = [])
96+
public function assignRolePermissions(Role $role, array $permissionNameArray = [])
11597
{
11698
$permissions = [];
11799
$permissionNameArray = array_values($permissionNameArray);
118-
if ($permissionNameArray && count($permissionNameArray) > 0) {
119-
$permissions = $this->permission->whereIn('name', $permissionNameArray)->pluck('id')->toArray();
100+
101+
if ($permissionNameArray) {
102+
$permissions = $this->permission->newQuery()
103+
->whereIn('name', $permissionNameArray)
104+
->pluck('id')
105+
->toArray();
120106
}
107+
121108
$role->permissions()->sync($permissions);
122109
}
123110

@@ -126,13 +113,13 @@ public function assignRolePermissions(Role $role, $permissionNameArray = [])
126113
* Check it's not an admin role or set as default before deleting.
127114
* If an migration Role ID is specified the users assign to the current role
128115
* will be added to the role of the specified id.
129-
* @param $roleId
130-
* @param $migrateRoleId
131116
* @throws PermissionsException
117+
* @throws Exception
132118
*/
133119
public function deleteRole($roleId, $migrateRoleId)
134120
{
135-
$role = $this->role->findOrFail($roleId);
121+
/** @var Role $role */
122+
$role = $this->role->newQuery()->findOrFail($roleId);
136123

137124
// Prevent deleting admin role or default registration role.
138125
if ($role->system_name && in_array($role->system_name, $this->systemRoles)) {
@@ -142,9 +129,9 @@ public function deleteRole($roleId, $migrateRoleId)
142129
}
143130

144131
if ($migrateRoleId) {
145-
$newRole = $this->role->find($migrateRoleId);
132+
$newRole = $this->role->newQuery()->find($migrateRoleId);
146133
if ($newRole) {
147-
$users = $role->users->pluck('id')->toArray();
134+
$users = $role->users()->pluck('id')->toArray();
148135
$newRole->users()->sync($users);
149136
}
150137
}

app/Auth/Permissions/RolePermission.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
use BookStack\Auth\Role;
44
use BookStack\Model;
55

6+
/**
7+
* @property int $id
8+
*/
69
class RolePermission extends Model
710
{
811
/**

0 commit comments

Comments
 (0)