]> BookStack Code Mirror - bookstack/commitdiff
Guest control: Cleaned methods involved in fetching/handling
authorDan Brown <redacted>
Sat, 16 Sep 2023 12:18:35 +0000 (13:18 +0100)
committerDan Brown <redacted>
Sat, 16 Sep 2023 12:18:35 +0000 (13:18 +0100)
- 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.

30 files changed:
app/Activity/Models/View.php
app/Activity/Tools/UserEntityWatchOptions.php
app/App/Providers/AuthServiceProvider.php
app/App/helpers.php
app/Entities/Queries/RecentlyViewed.php
app/Entities/Queries/TopFavourites.php
app/Http/Controller.php
app/Http/Middleware/ApiAuthenticate.php
app/Http/Middleware/Authenticate.php
app/Http/Middleware/PreventAuthenticatedResponseCaching.php
app/Settings/SettingController.php
app/Settings/SettingService.php
app/Translation/LanguageManager.php
app/Users/Controllers/UserSearchController.php
app/Users/Models/User.php
resources/views/books/show.blade.php
resources/views/chapters/show.blade.php
resources/views/common/header-user-menu.blade.php [new file with mode: 0644]
resources/views/common/header.blade.php
resources/views/errors/404.blade.php
resources/views/pages/show.blade.php
resources/views/search/all.blade.php
resources/views/shelves/show.blade.php
resources/views/users/preferences/index.blade.php
tests/Entity/PageRevisionTest.php
tests/Helpers/UserRoleProvider.php
tests/PublicActionTest.php
tests/TestCase.php
tests/User/UserManagementTest.php
tests/User/UserSearchTest.php

index 512e0829596089434f0ad772d455fa04d2fdcfc4..b593a7d27be74209f746c32c335361f0ac538995 100644 (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;
         }
 
index 231204fdf67b1f9f54fcbb90636fbea5de15ff24..559d7903d6f510671ae01c74a61409b0de93c875 100644 (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
index dc482ce33062725ba05ca2e353273ec5851c9e4f..26d1803107d41466a6e7c80cec72c23325fce1c3 100644 (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();
+        });
     }
 }
index 00d3e9243d7288096d39f91af5200212bb532316..b59a63448340d716fd5a24e5b2328f2c2b7d273e 100644 (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
index ffa3468882631e10f86ebc90e42ba135cd6d330c..5895b97a2ae8ad608ec95a77f5929bb43d380388 100644 (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();
         }
 
index cbccf35b054eceedd863e3edde10647b7462e650..a2f8d9ea1d2cdd42a93bebecf073f381bb14b672 100644 (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();
         }
 
index 584cea3aa74cd8ccffa7d5e366376b19ff8718dd..6e81dfd65738942ee30cdb542fe9775360c6a8a1 100644 (file)
@@ -71,7 +71,7 @@ abstract class Controller extends BaseController
      */
     protected function preventGuestAccess(): void
     {
-        if (!signedInUser()) {
+        if (user()->isGuest()) {
             $this->showPermissionError();
         }
     }
index b348473cf4d3dc40c1e353f1fb31c3b90e3c00de..5f3ad3168a0bbd3bbd1209996f50067027ce630f 100644 (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();
     }
 }
index a320291122b6f632b0bc36a8e96d15e42472a5f8..6a5c6e3542e0ec80c6f7205b80a48fc12ef2aa50 100644 (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);
             }
index 60c9138110a1665947c56a5c06f5896b1c4fd273..0a90ddd9e0f95d10dfa5a4ac67191ec8fbe5a8a5 100644 (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');
index bd55222f2302ee6a820fff3f67c8ecb8a007c4ad..bdbc3c78a392dce4bc97b7ae419f586147205b66 100644 (file)
@@ -34,7 +34,7 @@ class SettingController extends Controller
         return view('settings.' . $category, [
             'category'  => $category,
             'version'   => $version,
-            'guestUser' => User::getDefault(),
+            'guestUser' => User::getGuest(),
         ]);
     }
 
index 1c5cbdf5af37e12df8c77b9908b76126e90467b4..31debdaea85066835fa21e1f231e54b539c5c444 100644 (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;
index ec116fd70a4b620b46d081baf143f027dc27dcbb..f3432d0387a8b82b8b0a8b7b6cd4238fad2d3e6a 100644 (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);
         }
 
index 1c7786f58961f78a5b9dd2133d4783e700491135..b6f37bce08b1f3daea32e13a3ba45b634a50f34f 100644 (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')
index 2479521a2e91d86f046490ef346a488534001c7f..1eeacfe2e18553931dd397cb1ef0c454f870bf80 100644 (file)
@@ -88,36 +88,29 @@ 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;
+        return app()->make('users.default');
     }
 
-    public static function clearDefault(): void
+    /**
+     * Check if the user is the default public user.
+     */
+    public function isGuest(): bool
     {
-        static::$defaultUser = null;
+        return $this->system_name === 'public';
     }
 
     /**
-     * Check if the user is the default public user.
+     * Check if the user has general access to the application.
      */
-    public function isDefault(): bool
+    public function hasAppAccess(): bool
     {
-        return $this->system_name === 'public';
+        return !$this->isGuest() || setting('app-public');
     }
 
     /**
index e3aef845ce09a061c969c909fe9b9308090a60e0..9e7df4156d429c629edffc1837f2328da900c5ad 100644 (file)
             @if($watchOptions->canWatch() && !$watchOptions->isWatching())
                 @include('entities.watch-action', ['entity' => $book])
             @endif
-            @if(signedInUser())
+            @if(!user()->isGuest())
                 @include('entities.favourite-action', ['entity' => $book])
             @endif
             @if(userCan('content-export'))
index 3cb512ccc532ae565ccc392a0ab75e0f18a099d5..0e5224d54783294da51558a0e3d231bdcb8919d1 100644 (file)
             @if($watchOptions->canWatch() && !$watchOptions->isWatching())
                 @include('entities.watch-action', ['entity' => $chapter])
             @endif
-            @if(signedInUser())
+            @if(!user()->isGuest())
                 @include('entities.favourite-action', ['entity' => $chapter])
             @endif
             @if(userCan('content-export'))
diff --git a/resources/views/common/header-user-menu.blade.php b/resources/views/common/header-user-menu.blade.php
new file mode 100644 (file)
index 0000000..8ba750f
--- /dev/null
@@ -0,0 +1,47 @@
+<div class="dropdown-container" component="dropdown" option:dropdown:bubble-escapes="true">
+    <span class="user-name py-s hide-under-l" refs="dropdown@toggle"
+          aria-haspopup="true" aria-expanded="false" aria-label="{{ trans('common.profile_menu') }}" tabindex="0">
+        <img class="avatar" src="{{$user->getAvatar(30)}}" alt="{{ $user->name }}">
+        <span class="name">{{ $user->getShortName(9) }}</span> @icon('caret-down')
+    </span>
+    <ul refs="dropdown@menu" class="dropdown-menu" role="menu">
+        <li>
+            <a href="{{ url('/favourites') }}" data-shortcut="favourites_view" class="icon-item">
+                @icon('star')
+                <div>{{ trans('entities.my_favourites') }}</div>
+            </a>
+        </li>
+        <li>
+            <a href="{{ $user->getProfileUrl() }}" data-shortcut="profile_view" class="icon-item">
+                @icon('user')
+                <div>{{ trans('common.view_profile') }}</div>
+            </a>
+        </li>
+        <li>
+            <a href="{{ $user->getEditUrl() }}" class="icon-item">
+                @icon('edit')
+                <div>{{ trans('common.edit_profile') }}</div>
+            </a>
+        </li>
+        <li>
+            <form action="{{ url(config('auth.method') === 'saml2' ? '/saml2/logout' : '/logout') }}"
+                  method="post">
+                {{ csrf_field() }}
+                <button class="icon-item" data-shortcut="logout">
+                    @icon('logout')
+                    <div>{{ trans('auth.logout') }}</div>
+                </button>
+            </form>
+        </li>
+        <li><hr></li>
+        <li>
+            <a href="{{ url('/preferences') }}" class="icon-item">
+                @icon('user-preferences')
+                <div>{{ trans('preferences.preferences') }}</div>
+            </a>
+        </li>
+        <li>
+            @include('common.dark-mode-toggle', ['classes' => 'icon-item'])
+        </li>
+    </ul>
+</div>
\ No newline at end of file
index 97a411d84541684150f5b81bd4e6b6c8e9a8825f..86ad3563dd497f68f99a238c867c7d4aa8e980af 100644 (file)
@@ -18,7 +18,7 @@
         </div>
 
         <div class="flex-container-column items-center justify-center hide-under-l">
-            @if (hasAppAccess())
+            @if (user()->hasAppAccess())
             <form component="global-search" action="{{ url('/search') }}" method="GET" class="search-box" role="search" tabindex="0">
                 <button id="header-search-box-button"
                         refs="global-search@button"
 
         <nav refs="header-mobile-toggle@menu" class="header-links">
             <div class="links text-center">
-                @if (hasAppAccess())
+                @if (user()->hasAppAccess())
                     <a class="hide-over-l" href="{{ url('/search') }}">@icon('search'){{ trans('common.search') }}</a>
                     @if(userCanOnAny('view', \BookStack\Entities\Models\Bookshelf::class) || userCan('bookshelf-view-all') || userCan('bookshelf-view-own'))
                         <a href="{{ url('/shelves') }}" data-shortcut="shelves_view">@icon('bookshelf'){{ trans('entities.shelves') }}</a>
                     @endif
                     <a href="{{ url('/books') }}" data-shortcut="books_view">@icon('books'){{ trans('entities.books') }}</a>
-                    @if(signedInUser() && userCan('settings-manage'))
+                    @if(!user()->isGuest() && userCan('settings-manage'))
                         <a href="{{ url('/settings') }}" data-shortcut="settings_view">@icon('settings'){{ trans('settings.settings') }}</a>
                     @endif
-                    @if(signedInUser() && userCan('users-manage') && !userCan('settings-manage'))
+                    @if(!user()->isGuest() && userCan('users-manage') && !userCan('settings-manage'))
                         <a href="{{ url('/settings/users') }}" data-shortcut="settings_view">@icon('users'){{ trans('settings.users') }}</a>
                     @endif
                 @endif
 
-                @if(!signedInUser())
+                @if(user()->isGuest())
                     @if(setting('registration-enabled') && config('auth.method') === 'standard')
                         <a href="{{ url('/register') }}">@icon('new-user'){{ trans('auth.sign_up') }}</a>
                     @endif
                     <a href="{{ url('/login')  }}">@icon('login'){{ trans('auth.log_in') }}</a>
                 @endif
             </div>
-            @if(signedInUser())
-                <?php $currentUser = user(); ?>
-                <div class="dropdown-container" component="dropdown" option:dropdown:bubble-escapes="true">
-                        <span class="user-name py-s hide-under-l" refs="dropdown@toggle"
-                              aria-haspopup="true" aria-expanded="false" aria-label="{{ trans('common.profile_menu') }}" tabindex="0">
-                            <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}">
-                            <span class="name">{{ $currentUser->getShortName(9) }}</span> @icon('caret-down')
-                        </span>
-                    <ul refs="dropdown@menu" class="dropdown-menu" role="menu">
-                        <li>
-                            <a href="{{ url('/favourites') }}" data-shortcut="favourites_view" class="icon-item">
-                                @icon('star')
-                                <div>{{ trans('entities.my_favourites') }}</div>
-                            </a>
-                        </li>
-                        <li>
-                            <a href="{{ $currentUser->getProfileUrl() }}" data-shortcut="profile_view" class="icon-item">
-                                @icon('user')
-                                <div>{{ trans('common.view_profile') }}</div>
-                            </a>
-                        </li>
-                        <li>
-                            <a href="{{ $currentUser->getEditUrl() }}" class="icon-item">
-                                @icon('edit')
-                                <div>{{ trans('common.edit_profile') }}</div>
-                            </a>
-                        </li>
-                        <li>
-                            <form action="{{ url(config('auth.method') === 'saml2' ? '/saml2/logout' : '/logout') }}"
-                                  method="post">
-                                {{ csrf_field() }}
-                                <button class="icon-item" data-shortcut="logout">
-                                    @icon('logout')
-                                    <div>{{ trans('auth.logout') }}</div>
-                                </button>
-                            </form>
-                        </li>
-                        <li><hr></li>
-                        <li>
-                            <a href="{{ url('/preferences') }}" class="icon-item">
-                                @icon('user-preferences')
-                                <div>{{ trans('preferences.preferences') }}</div>
-                            </a>
-                        </li>
-                        <li>
-                            @include('common.dark-mode-toggle', ['classes' => 'icon-item'])
-                        </li>
-                    </ul>
-                </div>
+            @if(!user()->isGuest())
+                @include('common.header-user-menu', ['user' => user()])
             @endif
         </nav>
 
index a4e5a0dd4c115c30ed1a0df46062109061f9f97d..27d66b30bb9a7a71ad6ea34e235b1d17e1c75f2b 100644 (file)
@@ -1,55 +1,55 @@
 @extends('layouts.simple')
 
 @section('content')
-<div class="container mt-l">
+    <div class="container mt-l">
 
-    <div class="card mb-xl px-l pb-l pt-l">
-        <div class="grid half v-center">
-            <div>
-                @include('errors.parts.not-found-text', [
-                    'title' => $message ?? trans('errors.404_page_not_found'),
-                    'subtitle' => $subtitle ?? trans('errors.sorry_page_not_found'),
-                    'details' => $details ?? trans('errors.sorry_page_not_found_permission_warning'),
-                ])
-            </div>
-            <div class="text-right">
-                @if(!signedInUser())
-                    <a href="{{ url('/login') }}" class="button outline">{{ trans('auth.log_in') }}</a>
-                @endif
-                <a href="{{ url('/') }}" class="button outline">{{ trans('errors.return_home') }}</a>
+        <div class="card mb-xl px-l pb-l pt-l">
+            <div class="grid half v-center">
+                <div>
+                    @include('errors.parts.not-found-text', [
+                        'title' => $message ?? trans('errors.404_page_not_found'),
+                        'subtitle' => $subtitle ?? trans('errors.sorry_page_not_found'),
+                        'details' => $details ?? trans('errors.sorry_page_not_found_permission_warning'),
+                    ])
+                </div>
+                <div class="text-right">
+                    @if(user()->isGuest())
+                        <a href="{{ url('/login') }}" class="button outline">{{ trans('auth.log_in') }}</a>
+                    @endif
+                    <a href="{{ url('/') }}" class="button outline">{{ trans('errors.return_home') }}</a>
+                </div>
             </div>
-        </div>
 
-    </div>
+        </div>
 
-    @if (setting('app-public') || !user()->isDefault())
-        <div class="grid third gap-xxl">
-            <div>
-                <div class="card mb-xl">
-                    <h3 class="card-title">{{ trans('entities.pages_popular') }}</h3>
-                    <div class="px-m">
-                        @include('entities.list', ['entities' => (new \BookStack\Entities\Queries\Popular)->run(10, 0, ['page']), 'style' => 'compact'])
+        @if (setting('app-public') || !user()->isGuest())
+            <div class="grid third gap-xxl">
+                <div>
+                    <div class="card mb-xl">
+                        <h3 class="card-title">{{ trans('entities.pages_popular') }}</h3>
+                        <div class="px-m">
+                            @include('entities.list', ['entities' => (new \BookStack\Entities\Queries\Popular)->run(10, 0, ['page']), 'style' => 'compact'])
+                        </div>
                     </div>
                 </div>
-            </div>
-            <div>
-                <div class="card mb-xl">
-                    <h3 class="card-title">{{ trans('entities.books_popular') }}</h3>
-                    <div class="px-m">
-                        @include('entities.list', ['entities' => (new \BookStack\Entities\Queries\Popular)->run(10, 0, ['book']), 'style' => 'compact'])
+                <div>
+                    <div class="card mb-xl">
+                        <h3 class="card-title">{{ trans('entities.books_popular') }}</h3>
+                        <div class="px-m">
+                            @include('entities.list', ['entities' => (new \BookStack\Entities\Queries\Popular)->run(10, 0, ['book']), 'style' => 'compact'])
+                        </div>
                     </div>
                 </div>
-            </div>
-            <div>
-                <div class="card mb-xl">
-                    <h3 class="card-title">{{ trans('entities.chapters_popular') }}</h3>
-                    <div class="px-m">
-                        @include('entities.list', ['entities' => (new \BookStack\Entities\Queries\Popular)->run(10, 0, ['chapter']), 'style' => 'compact'])
+                <div>
+                    <div class="card mb-xl">
+                        <h3 class="card-title">{{ trans('entities.chapters_popular') }}</h3>
+                        <div class="px-m">
+                            @include('entities.list', ['entities' => (new \BookStack\Entities\Queries\Popular)->run(10, 0, ['chapter']), 'style' => 'compact'])
+                        </div>
                     </div>
                 </div>
             </div>
-        </div>
-    @endif
-</div>
+        @endif
+    </div>
 
 @stop
\ No newline at end of file
index 1cbb819804f27a09ee934a24ffb047ac3610d80f..5d70f7c28e984d3400872c7ae4566699444d8591 100644 (file)
             @if($watchOptions->canWatch() && !$watchOptions->isWatching())
                 @include('entities.watch-action', ['entity' => $page])
             @endif
-            @if(signedInUser())
+            @if(!user()->isGuest())
                 @include('entities.favourite-action', ['entity' => $page])
             @endif
             @if(userCan('content-export'))
index 96b14f6e534c6931d92e61698bf51e35e368541a..64325d4c1bf08cee9efac6da8329cc7b9633a3c0 100644 (file)
@@ -32,7 +32,7 @@
                         <h6>{{ trans('entities.search_tags') }}</h6>
                         @include('search.parts.term-list', ['type' => 'tags', 'currentList' => $options->tags])
 
-                        @if(signedInUser())
+                        @if(!user()->isGuest())
                             <h6>{{ trans('entities.search_options') }}</h6>
 
                             @component('search.parts.boolean-filter', ['filters' => $options->filters, 'name' => 'viewed_by_me', 'value' => null])
index 86dd6326d758b030af2143a99f203b4fd2086cbd..8694ce86da55b2a85b55ac03c5a8fe203fe92273 100644 (file)
                 </a>
             @endif
 
-            @if(signedInUser())
+            @if(!user()->isGuest())
                 <hr class="primary-background">
                 @include('entities.favourite-action', ['entity' => $shelf])
             @endif
index 712fdb288e183b91de30284b72f7a2069aa1a991..f8576ed9e4ba8a634734a165037bdb1a1e4afb2b 100644 (file)
@@ -13,7 +13,7 @@
             </div>
         </section>
 
-        @if(signedInUser() && userCan('receive-notifications'))
+        @if(!user()->isGuest() && userCan('receive-notifications'))
             <section class="card content-wrap auto-height items-center justify-space-between gap-m flex-container-row wrap">
                 <div class="flex min-width-m">
                     <h2 class="list-heading">{{ trans('preferences.notifications') }}</h2>
@@ -25,7 +25,7 @@
             </section>
         @endif
 
-        @if(signedInUser())
+        @if(!user()->isGuest())
             <section class="card content-wrap auto-height items-center justify-space-between gap-m flex-container-row wrap">
                 <div class="flex min-width-m">
                     <h2 class="list-heading">{{ trans('settings.users_edit_profile') }}</h2>
index 97d5a6664daef838a9095dbdbeeea242e86ea1a6..a272dc38bdbd911cf302679bc668dd0f091be3e7 100644 (file)
@@ -136,7 +136,7 @@ class PageRevisionTest extends TestCase
         $page = $this->entities->page();
         $this->createRevisions($page, 2);
 
-        $pageView = $this->get($page->getUrl());
+        $pageView = $this->asViewer()->get($page->getUrl());
         $pageView->assertSee('Revision #' . $page->revision_count);
     }
 
index 3b2da369de5235251e23574e0eb5bc80d07f2d90..fe19cad4aab97e587990bbc1b978a869944505d9 100644 (file)
@@ -55,7 +55,7 @@ class UserRoleProvider
      */
     public function guest(): User
     {
-        return User::getDefault();
+        return User::getGuest();
     }
 
     /**
index 1e4dcbfb7b80df50c843ed6ff1e0bd591b2aec63..875b279a81c381d2394da96d4b7892bc161ee9b6 100644 (file)
@@ -103,7 +103,7 @@ class PublicActionTest extends TestCase
         $resp = $this->post($chapter->getUrl('/create-guest-page'), ['name' => 'My guest page']);
         $resp->assertRedirect($chapter->book->getUrl('/page/my-guest-page/edit'));
 
-        $user = User::getDefault();
+        $user = $this->users->guest();
         $this->assertDatabaseHas('pages', [
             'name'       => 'My guest page',
             'chapter_id' => $chapter->id,
@@ -197,7 +197,7 @@ class PublicActionTest extends TestCase
     public function test_public_view_can_take_on_other_roles()
     {
         $this->setSettings(['app-public' => 'true']);
-        $newRole = $this->users->attachNewRole(User::getDefault(), []);
+        $newRole = $this->users->attachNewRole($this->users->guest(), []);
         $page = $this->entities->page();
         $this->permissions->disableEntityInheritedPermissions($page);
         $this->permissions->addEntityPermission($page, ['view', 'update'], $newRole);
index f8f59977a1e1ac6a282f91e0cca4399e0c47b853..c59f843e94bdd877c4e8601c6d214c1977405e40 100644 (file)
@@ -42,7 +42,6 @@ abstract class TestCase extends BaseTestCase
         $this->permissions = new PermissionsProvider($this->users);
         $this->files = new FileProvider();
 
-        User::clearDefault();
         parent::setUp();
 
         // We can uncomment the below to run tests with failings upon deprecations.
index df60bede6e1de83d83720ad5ed2608f7a524a9ce..a6d869b2fd135159fc09b6ced35115b7c0a5b321 100644 (file)
@@ -191,7 +191,7 @@ class UserManagementTest extends TestCase
 
     public function test_guest_profile_shows_limited_form()
     {
-        $guest = User::getDefault();
+        $guest = $this->users->guest();
         $resp = $this->asAdmin()->get('/settings/users/' . $guest->id);
         $resp->assertSee('Guest');
         $this->withHtml($resp)->assertElementNotExists('#password');
@@ -199,7 +199,7 @@ class UserManagementTest extends TestCase
 
     public function test_guest_profile_cannot_be_deleted()
     {
-        $guestUser = User::getDefault();
+        $guestUser = $this->users->guest();
         $resp = $this->asAdmin()->get('/settings/users/' . $guestUser->id . '/delete');
         $resp->assertSee('Delete User');
         $resp->assertSee('Guest');
index 1387311ce7576d131e6b648197deedf5d9d69612..76efbf4af9ba27d7405911373b0e4bd1a362a7e9 100644 (file)
@@ -57,8 +57,7 @@ class UserSearchTest extends TestCase
     public function test_select_requires_logged_in_user()
     {
         $this->setSettings(['app-public' => true]);
-        $defaultUser = User::getDefault();
-        $this->permissions->grantUserRolePermissions($defaultUser, ['users-manage']);
+        $this->permissions->grantUserRolePermissions($this->users->guest(), ['users-manage']);
 
         $resp = $this->get('/search/users/select?search=a');
         $this->assertPermissionError($resp);