]> BookStack Code Mirror - bookstack/commitdiff
Maintenance: Finished changes to meet phpstan level 3
authorDan Brown <redacted>
Wed, 3 Sep 2025 14:18:49 +0000 (15:18 +0100)
committerDan Brown <redacted>
Wed, 3 Sep 2025 14:18:49 +0000 (15:18 +0100)
app/Access/Guards/AsyncExternalBaseSessionGuard.php
app/Access/Guards/LdapSessionGuard.php
app/Access/LoginService.php
app/Entities/Queries/BookQueries.php
app/Entities/Queries/BookshelfQueries.php
app/Entities/Queries/ChapterQueries.php
app/Entities/Queries/PageQueries.php
app/Entities/Queries/ProvidesEntityQueries.php
app/Entities/Tools/PageIncludeParser.php
app/Exceptions/Handler.php
app/Permissions/EntityPermissionEvaluator.php

index ab982a6b0886487773e56b232c4aef8e4a8ccf19..b66fbe95e0977626f0ef4299c2d2c2c2730edfd7 100644 (file)
@@ -3,23 +3,18 @@
 namespace BookStack\Access\Guards;
 
 /**
- * Saml2 Session Guard.
+ * External Auth Session Guard.
  *
- * The saml2 login process is async in nature meaning it does not fit very well
- * into the default laravel 'Guard' auth flow. Instead most of the logic is done
- * via the Saml2 controller & Saml2Service. This class provides a safer, thin
- * version of SessionGuard.
+ * The login process for external auth (SAML2/OIDC) is async in nature, meaning it does not fit very well
+ * into the default laravel 'Guard' auth flow. Instead, most of the logic is done via the relevant
+ * controller and services. This class provides a safer, thin version of SessionGuard.
  */
 class AsyncExternalBaseSessionGuard extends ExternalBaseSessionGuard
 {
     /**
      * Validate a user's credentials.
-     *
-     * @param array $credentials
-     *
-     * @return bool
      */
-    public function validate(array $credentials = [])
+    public function validate(array $credentials = []): bool
     {
         return false;
     }
@@ -27,12 +22,9 @@ class AsyncExternalBaseSessionGuard extends ExternalBaseSessionGuard
     /**
      * Attempt to authenticate a user using the given credentials.
      *
-     * @param array $credentials
      * @param bool  $remember
-     *
-     * @return bool
      */
-    public function attempt(array $credentials = [], $remember = false)
+    public function attempt(array $credentials = [], $remember = false): bool
     {
         return false;
     }
index bd020f70b9555e107ca4c5fa8ac7322b043b8850..9455d530dfe6fab4c76c0920142a9b1f91398925 100644 (file)
@@ -35,13 +35,9 @@ class LdapSessionGuard extends ExternalBaseSessionGuard
     /**
      * Validate a user's credentials.
      *
-     * @param array $credentials
-     *
      * @throws LdapException
-     *
-     * @return bool
      */
-    public function validate(array $credentials = [])
+    public function validate(array $credentials = []): bool
     {
         $userDetails = $this->ldapService->getUserDetails($credentials['username']);
 
index 6607969afae76c7214922d2cf1f29c58cc07142e..76ae1938da0128c6283c310d9e324e4b1041e68d 100644 (file)
@@ -95,7 +95,7 @@ class LoginService
     {
         $value = session()->get(self::LAST_LOGIN_ATTEMPTED_SESSION_KEY);
         if (!$value) {
-            return ['user_id' => null, 'method' => null];
+            return ['user_id' => null, 'method' => null, 'remember' => false];
         }
 
         [$id, $method, $remember, $time] = explode(':', $value);
@@ -103,18 +103,18 @@ class LoginService
         if ($time < $hourAgo) {
             $this->clearLastLoginAttempted();
 
-            return ['user_id' => null, 'method' => null];
+            return ['user_id' => null, 'method' => null, 'remember' => false];
         }
 
         return ['user_id' => $id, 'method' => $method, 'remember' => boolval($remember)];
     }
 
     /**
-     * Set the last login attempted user.
+     * Set the last login-attempted user.
      * Must be only used when credentials are correct and a login could be
-     * achieved but a secondary factor has stopped the login.
+     * achieved, but a secondary factor has stopped the login.
      */
-    protected function setLastLoginAttemptedForUser(User $user, string $method, bool $remember)
+    protected function setLastLoginAttemptedForUser(User $user, string $method, bool $remember): void
     {
         session()->put(
             self::LAST_LOGIN_ATTEMPTED_SESSION_KEY,
index 5ff22252c14b20ae82accf39ac6cfc44dc442011..2492f81318ad7bd741e725718318d84eb90a4cbc 100644 (file)
@@ -6,6 +6,9 @@ use BookStack\Entities\Models\Book;
 use BookStack\Exceptions\NotFoundException;
 use Illuminate\Database\Eloquent\Builder;
 
+/**
+ * @implements ProvidesEntityQueries<Book>
+ */
 class BookQueries implements ProvidesEntityQueries
 {
     protected static array $listAttributes = [
index 874bc7f2f5896023bade18532652cb9b86963294..842011a878113b76716d61f50de24d582679fb84 100644 (file)
@@ -6,6 +6,9 @@ use BookStack\Entities\Models\Bookshelf;
 use BookStack\Exceptions\NotFoundException;
 use Illuminate\Database\Eloquent\Builder;
 
+/**
+ * @implements ProvidesEntityQueries<Bookshelf>
+ */
 class BookshelfQueries implements ProvidesEntityQueries
 {
     protected static array $listAttributes = [
index 53c5bc9d8423a7fe380d7eb67bd2cd9ab27ab040..9bf0ff65bfdd38283f7e554536c68b41d5b47f50 100644 (file)
@@ -6,6 +6,9 @@ use BookStack\Entities\Models\Chapter;
 use BookStack\Exceptions\NotFoundException;
 use Illuminate\Database\Eloquent\Builder;
 
+/**
+ * @implements ProvidesEntityQueries<Chapter>
+ */
 class ChapterQueries implements ProvidesEntityQueries
 {
     protected static array $listAttributes = [
index f821ee86a5889e0bcc1d59fc825ff7b4be73becf..ee7b201bc1af6beb04a483487be2b1ae821c402d 100644 (file)
@@ -6,6 +6,9 @@ use BookStack\Entities\Models\Page;
 use BookStack\Exceptions\NotFoundException;
 use Illuminate\Database\Eloquent\Builder;
 
+/**
+ * @implements ProvidesEntityQueries<Page>
+ */
 class PageQueries implements ProvidesEntityQueries
 {
     protected static array $contentAttributes = [
@@ -18,6 +21,9 @@ class PageQueries implements ProvidesEntityQueries
         'template', 'text', 'created_at', 'updated_at', 'priority', 'owned_by',
     ];
 
+    /**
+     * @return Builder<Page>
+     */
     public function start(): Builder
     {
         return Page::query();
index 1f8a71ae2308ff8b4cb3f4271d254d8864c55445..79fc64b3ab8dfeb9c4188bf5d89c3df778d8a84e 100644 (file)
@@ -7,17 +7,20 @@ use Illuminate\Database\Eloquent\Builder;
 
 /**
  * Interface for our classes which provide common queries for our
- * entity objects. Ideally all queries for entities should run through
+ * entity objects. Ideally, all queries for entities should run through
  * these classes.
  * Any added methods should return a builder instances to allow extension
  * via building on the query, unless the method starts with 'find'
  * in which case an entity object should be returned.
  * (nullable unless it's a *OrFail method).
+ *
+ * @template TModel of Entity
  */
 interface ProvidesEntityQueries
 {
     /**
      * Start a new query for this entity type.
+     * @return Builder<TModel>
      */
     public function start(): Builder;
 
@@ -29,7 +32,7 @@ interface ProvidesEntityQueries
     /**
      * Start a query for items that are visible, with selection
      * configured for list display of this item.
-     * @return Builder<Entity>
+     * @return Builder<TModel>
      */
     public function visibleForList(): Builder;
 }
index 329a7633f7a28d0b36af0ca55229c1c4851037d3..af7ed4fc6a1b6bf12ff51898414a4e2c0ebfe884 100644 (file)
@@ -13,8 +13,8 @@ class PageIncludeParser
     protected static string $includeTagRegex = "/{{@\s?([0-9].*?)}}/";
 
     /**
-     * Elements to clean up and remove if left empty after a parsing operation.
-     * @var DOMElement[]
+     * Nodes to clean up and remove if left empty after a parsing operation.
+     * @var DOMNode[]
      */
     protected array $toCleanup = [];
 
@@ -206,7 +206,7 @@ class PageIncludeParser
     }
 
     /**
-     * Cleanup after a parse operation.
+     * Clean up after a parse operation.
      * Removes stranded elements we may have left during the parse.
      */
     protected function cleanup(): void
index b8c3fa192a62ce9d3752d3fc01370e57a6750834..08d326ad81c591430bd0254329929ae8687d1d1f 100644 (file)
@@ -2,7 +2,6 @@
 
 namespace BookStack\Exceptions;
 
-use Exception;
 use Illuminate\Auth\AuthenticationException;
 use Illuminate\Database\Eloquent\ModelNotFoundException;
 use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
@@ -12,6 +11,7 @@ use Illuminate\Http\Request;
 use Illuminate\Http\Response;
 use Illuminate\Validation\ValidationException;
 use Symfony\Component\ErrorHandler\Error\FatalError;
+use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
 use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
 use Throwable;
 
@@ -20,7 +20,7 @@ class Handler extends ExceptionHandler
     /**
      * A list of the exception types that are not reported.
      *
-     * @var array<int, class-string<\Throwable>>
+     * @var array<int, class-string<Throwable>>
      */
     protected $dontReport = [
         NotFoundException::class,
@@ -50,11 +50,11 @@ class Handler extends ExceptionHandler
     /**
      * Report or log an exception.
      *
-     * @param \Throwable $exception
-     *
-     * @throws \Throwable
+     * @param Throwable $exception
      *
      * @return void
+     *@throws Throwable
+     *
      */
     public function report(Throwable $exception)
     {
@@ -64,12 +64,9 @@ class Handler extends ExceptionHandler
     /**
      * Render an exception into an HTTP response.
      *
-     * @param \Illuminate\Http\Request $request
-     * @param Exception                $e
-     *
-     * @return \Illuminate\Http\Response
+     * @param Request $request
      */
-    public function render($request, Throwable $e)
+    public function render($request, Throwable $e): SymfonyResponse
     {
         if ($e instanceof FatalError && str_contains($e->getMessage(), 'bytes exhausted (tried to allocate') && $this->onOutOfMemory) {
             $response = call_user_func($this->onOutOfMemory);
@@ -152,12 +149,9 @@ class Handler extends ExceptionHandler
     /**
      * Convert an authentication exception into an unauthenticated response.
      *
-     * @param \Illuminate\Http\Request                 $request
-     * @param \Illuminate\Auth\AuthenticationException $exception
-     *
-     * @return \Illuminate\Http\Response
+     * @param Request $request
      */
-    protected function unauthenticated($request, AuthenticationException $exception)
+    protected function unauthenticated($request, AuthenticationException $exception): SymfonyResponse
     {
         if ($request->expectsJson()) {
             return response()->json(['error' => 'Unauthenticated.'], 401);
@@ -169,12 +163,9 @@ class Handler extends ExceptionHandler
     /**
      * Convert a validation exception into a JSON response.
      *
-     * @param \Illuminate\Http\Request                   $request
-     * @param \Illuminate\Validation\ValidationException $exception
-     *
-     * @return \Illuminate\Http\JsonResponse
+     * @param Request $request
      */
-    protected function invalidJson($request, ValidationException $exception)
+    protected function invalidJson($request, ValidationException $exception): JsonResponse
     {
         return response()->json($exception->errors(), $exception->status);
     }
index 98ec0330649f5374d0add8cd718b1e5290342cf6..30c97b700c6065fdb82248f0db58f757189a2810 100644 (file)
@@ -30,7 +30,7 @@ class EntityPermissionEvaluator
     }
 
     /**
-     * @param array<string, array<string, int>> $permitsByType
+     * @param array<string, array<int, string>> $permitsByType
      */
     protected function evaluatePermitsByType(array $permitsByType): ?int
     {
@@ -50,7 +50,7 @@ class EntityPermissionEvaluator
     /**
      * @param string[] $typeIdChain
      * @param array<string, EntityPermission[]> $permissionMapByTypeId
-     * @return array<string, array<string, int>>
+     * @return array<string, array<int, string>>
      */
     protected function collapseAndCategorisePermissions(array $typeIdChain, array $permissionMapByTypeId): array
     {