1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-08-07 23:03:00 +03:00

Guest control: Cleaned methods involved in fetching/handling

- Moves guest user caching from User class to app container for
  simplicity.
- Updates test to use simpler $this->users->guest() method for
  consistency.
- Streamlined helpers to avoid function overlap for simplicity.
- Extracted user profile dropdown while doing changes.
This commit is contained in:
Dan Brown
2023-09-16 13:18:35 +01:00
parent 9ac932fc28
commit b90033a730
30 changed files with 148 additions and 166 deletions

View File

@@ -41,7 +41,7 @@ class View extends Model
public static function incrementFor(Viewable $viewable): int
{
$user = user();
if (is_null($user) || $user->isDefault()) {
if (is_null($user) || $user->isGuest()) {
return 0;
}

View File

@@ -22,7 +22,7 @@ class UserEntityWatchOptions
public function canWatch(): bool
{
return $this->user->can('receive-notifications') && !$this->user->isDefault();
return $this->user->can('receive-notifications') && !$this->user->isGuest();
}
public function getWatchLevel(): string

View File

@@ -9,6 +9,7 @@ use BookStack\Access\LdapService;
use BookStack\Access\LoginService;
use BookStack\Access\RegistrationService;
use BookStack\Api\ApiTokenGuard;
use BookStack\Users\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
use Illuminate\Validation\Rules\Password;
@@ -65,5 +66,11 @@ class AuthServiceProvider extends ServiceProvider
Auth::provider('external-users', function ($app, array $config) {
return new ExternalBaseUserProvider($config['model']);
});
// Bind and provide the default system user as a singleton to the app instance when needed.
// This effectively "caches" fetching the user at an app-instance level.
$this->app->singleton('users.default', function () {
return User::query()->where('system_name', '=', 'public')->first();
});
}
}

View File

@@ -35,23 +35,7 @@ function versioned_asset(string $file = ''): string
*/
function user(): User
{
return auth()->user() ?: User::getDefault();
}
/**
* Check if current user is a signed in user.
*/
function signedInUser(): bool
{
return auth()->user() && !auth()->user()->isDefault();
}
/**
* Check if the current user has general access.
*/
function hasAppAccess(): bool
{
return !auth()->guest() || setting('app-public');
return auth()->user() ?: User::getGuest();
}
/**
@@ -61,7 +45,7 @@ function hasAppAccess(): bool
function userCan(string $permission, Model $ownable = null): bool
{
if ($ownable === null) {
return user() && user()->can($permission);
return user()->can($permission);
}
// Check permission on ownable item

View File

@@ -10,7 +10,7 @@ class RecentlyViewed extends EntityQuery
public function run(int $count, int $page): Collection
{
$user = user();
if ($user === null || $user->isDefault()) {
if ($user === null || $user->isGuest()) {
return collect();
}

View File

@@ -10,7 +10,7 @@ class TopFavourites extends EntityQuery
public function run(int $count, int $skip = 0)
{
$user = user();
if ($user->isDefault()) {
if ($user->isGuest()) {
return collect();
}

View File

@@ -71,7 +71,7 @@ abstract class Controller extends BaseController
*/
protected function preventGuestAccess(): void
{
if (!signedInUser()) {
if (user()->isGuest()) {
$this->showPermissionError();
}
}

View File

@@ -31,7 +31,7 @@ class ApiAuthenticate
{
// Return if the user is already found to be signed in via session-based auth.
// This is to make it easy to browser the API via browser after just logging into the system.
if (signedInUser() || session()->isStarted()) {
if (!user()->isGuest() || session()->isStarted()) {
if (!$this->sessionUserHasApiAccess()) {
throw new ApiAuthException(trans('errors.api_user_no_api_permission'), 403);
}
@@ -53,6 +53,6 @@ class ApiAuthenticate
{
$hasApiPermission = user()->can('access-api');
return $hasApiPermission && hasAppAccess();
return $hasApiPermission && user()->hasAppAccess();
}
}

View File

@@ -12,7 +12,7 @@ class Authenticate
*/
public function handle(Request $request, Closure $next)
{
if (!hasAppAccess()) {
if (!user()->hasAppAccess()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
}

View File

@@ -20,7 +20,7 @@ class PreventAuthenticatedResponseCaching
/** @var Response $response */
$response = $next($request);
if (signedInUser()) {
if (!user()->isGuest()) {
$response->headers->set('Cache-Control', 'max-age=0, no-store, private');
$response->headers->set('Pragma', 'no-cache');
$response->headers->set('Expires', 'Sun, 12 Jul 2015 19:01:00 GMT');

View File

@@ -34,7 +34,7 @@ class SettingController extends Controller
return view('settings.' . $category, [
'category' => $category,
'version' => $version,
'guestUser' => User::getDefault(),
'guestUser' => User::getGuest(),
]);
}

View File

@@ -47,7 +47,7 @@ class SettingService
$default = config('setting-defaults.user.' . $key, false);
}
if ($user->isDefault()) {
if ($user->isGuest()) {
return $this->getFromSession($key, $default);
}
@@ -206,7 +206,7 @@ class SettingService
*/
public function putUser(User $user, string $key, string $value): bool
{
if ($user->isDefault()) {
if ($user->isGuest()) {
session()->put($key, $value);
return true;

View File

@@ -75,7 +75,7 @@ class LanguageManager
return $default;
}
if ($user->isDefault() && config('app.auto_detect_locale')) {
if ($user->isGuest() && config('app.auto_detect_locale')) {
return $this->autoDetectLocale($request, $default);
}

View File

@@ -14,7 +14,7 @@ class UserSearchController extends Controller
*/
public function forSelect(Request $request)
{
$hasPermission = signedInUser() && (
$hasPermission = !user()->isGuest() && (
userCan('users-manage')
|| userCan('restrictions-manage-own')
|| userCan('restrictions-manage-all')

View File

@@ -88,38 +88,31 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/
protected string $avatarUrl = '';
/**
* This holds the default user when loaded.
*/
protected static ?User $defaultUser = null;
/**
* Returns the default public user.
* Fetches from the container as a singleton to effectively cache at an app level.
*/
public static function getDefault(): self
public static function getGuest(): self
{
if (!is_null(static::$defaultUser)) {
return static::$defaultUser;
}
static::$defaultUser = static::query()->where('system_name', '=', 'public')->first();
return static::$defaultUser;
}
public static function clearDefault(): void
{
static::$defaultUser = null;
return app()->make('users.default');
}
/**
* Check if the user is the default public user.
*/
public function isDefault(): bool
public function isGuest(): bool
{
return $this->system_name === 'public';
}
/**
* Check if the user has general access to the application.
*/
public function hasAppAccess(): bool
{
return !$this->isGuest() || setting('app-public');
}
/**
* The roles that belong to the user.
*