From 12a9a45747f3ce3ff58464cd7ccb88f2c42438e8 Mon Sep 17 00:00:00 2001
From: benrubson <6764151+benrubson@users.noreply.github.com>
Date: Sun, 9 Feb 2020 10:01:33 +0100
Subject: [PATCH 1/4] Log failed accesses

---
 app/Http/Controllers/Auth/LoginController.php | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php
index ea584a3b6..75ade74e7 100644
--- a/app/Http/Controllers/Auth/LoginController.php
+++ b/app/Http/Controllers/Auth/LoginController.php
@@ -101,6 +101,9 @@ class LoginController extends Controller
             $this->hasTooManyLoginAttempts($request)) {
             $this->fireLockoutEvent($request);
 
+            // Also log some error message
+            $this->logFailedAccess($request);
+
             return $this->sendLockoutResponse($request);
         }
 
@@ -117,6 +120,9 @@ class LoginController extends Controller
         // user surpasses their maximum number of attempts they will get locked out.
         $this->incrementLoginAttempts($request);
 
+        // Also log some error message
+        $this->logFailedAccess($request);
+
         return $this->sendFailedLoginResponse($request);
     }
 
@@ -162,4 +168,16 @@ class LoginController extends Controller
         return redirect('/login');
     }
 
+    /**
+     * Log failed accesses, matching the default fail2ban nginx/apache auth rules.
+     */
+    protected function logFailedAccess(Request $request)
+    {
+        if (isset($_SERVER['SERVER_SOFTWARE']) && preg_match('/nginx/i', $_SERVER['SERVER_SOFTWARE'])) {
+             error_log('user "' . $request->get($this->username()) . '" was not found in "BookStack"', 4);
+         } else {
+             error_log('user "' . $request->get($this->username()) . '" authentication failure for "BookStack"', 4);
+         }
+    }
+
 }

From 58df3ad9566061186e62110e7c1e4a4140ed02c2 Mon Sep 17 00:00:00 2001
From: benrubson <6764151+benrubson@users.noreply.github.com>
Date: Sun, 3 May 2020 16:20:02 +0200
Subject: [PATCH 2/4] Log failed accesses option

---
 .env.example.complete                         |  8 ++++++-
 app/Http/Controllers/Auth/LoginController.php | 21 ++++++++++++-------
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/.env.example.complete b/.env.example.complete
index 04cd73b90..5b62b1a2a 100644
--- a/.env.example.complete
+++ b/.env.example.complete
@@ -266,4 +266,10 @@ API_DEFAULT_ITEM_COUNT=100
 API_MAX_ITEM_COUNT=500
 
 # The number of API requests that can be made per minute by a single user.
-API_REQUESTS_PER_MIN=180
\ No newline at end of file
+API_REQUESTS_PER_MIN=180
+
+# Failed access
+# message to log into webserver logs in case of failed access, for further processing by tools like Fail2Ban
+# Apache users should use : user "%u" authentication failure for "BookStack"
+# Nginx  users should use : user "%u" was not found in "BookStack"
+FAILED_ACCESS_MESSAGE=''
diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php
index 75ade74e7..c000af49e 100644
--- a/app/Http/Controllers/Auth/LoginController.php
+++ b/app/Http/Controllers/Auth/LoginController.php
@@ -169,15 +169,20 @@ class LoginController extends Controller
     }
 
     /**
-     * Log failed accesses, matching the default fail2ban nginx/apache auth rules.
-     */
-    protected function logFailedAccess(Request $request)
+     * Log failed accesses, for further processing by tools like Fail2Ban
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return void
+      */
+    protected function logFailedAccess($request)
     {
-        if (isset($_SERVER['SERVER_SOFTWARE']) && preg_match('/nginx/i', $_SERVER['SERVER_SOFTWARE'])) {
-             error_log('user "' . $request->get($this->username()) . '" was not found in "BookStack"', 4);
-         } else {
-             error_log('user "' . $request->get($this->username()) . '" authentication failure for "BookStack"', 4);
-         }
+        $log_msg = env('FAILED_ACCESS_MESSAGE', '');
+
+        if (!is_string($request->get($this->username())) || !is_string($log_msg) || strlen($log_msg)<1)
+            return;
+
+        $log_msg = str_replace("%u", $request->get($this->username()), $log_msg);
+        error_log($log_msg, 4);
     }
 
 }

From 8f1f73defa321f026d487b3e9344055746bc6f58 Mon Sep 17 00:00:00 2001
From: benrubson <6764151+benrubson@users.noreply.github.com>
Date: Sat, 23 May 2020 12:06:37 +0200
Subject: [PATCH 3/4] Properly use env/config functions

---
 app/Config/logging.php                        | 5 +++++
 app/Http/Controllers/Auth/LoginController.php | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/app/Config/logging.php b/app/Config/logging.php
index 0b55dc24d..406b9f2f9 100644
--- a/app/Config/logging.php
+++ b/app/Config/logging.php
@@ -79,4 +79,9 @@ return [
         ],
     ],
 
+    // Failed Access Message
+    // Defines the message to log into webserver logs in case of failed access,
+    // for further processing by tools like Fail2Ban.
+    'failed_access_message' => env('FAILED_ACCESS_MESSAGE', ''),
+
 ];
diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php
index c000af49e..cf9e44e43 100644
--- a/app/Http/Controllers/Auth/LoginController.php
+++ b/app/Http/Controllers/Auth/LoginController.php
@@ -176,7 +176,7 @@ class LoginController extends Controller
       */
     protected function logFailedAccess($request)
     {
-        $log_msg = env('FAILED_ACCESS_MESSAGE', '');
+        $log_msg = config('logging.failed_access_message');
 
         if (!is_string($request->get($this->username())) || !is_string($log_msg) || strlen($log_msg)<1)
             return;

From 9d7ce59b18c5cbeef017349f38f063a63b762188 Mon Sep 17 00:00:00 2001
From: benrubson <6764151+benrubson@users.noreply.github.com>
Date: Sat, 23 May 2020 15:37:38 +0200
Subject: [PATCH 4/4] Move logFailedAccess into Activity

---
 app/Actions/ActivityService.php               | 17 ++++++++++++++
 app/Http/Controllers/Auth/LoginController.php | 22 +++----------------
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/app/Actions/ActivityService.php b/app/Actions/ActivityService.php
index f56f1ca57..ca09aaef1 100644
--- a/app/Actions/ActivityService.php
+++ b/app/Actions/ActivityService.php
@@ -183,4 +183,21 @@ class ActivityService
             session()->flash('success', $message);
         }
     }
+
+    /**
+     * Log failed accesses, for further processing by tools like Fail2Ban
+     *
+     * @param username
+     * @return void
+      */
+    public function logFailedAccess($username)
+    {
+        $log_msg = config('logging.failed_access_message');
+
+        if (!is_string($username) || !is_string($log_msg) || strlen($log_msg)<1)
+            return;
+
+        $log_msg = str_replace("%u", $username, $log_msg);
+        error_log($log_msg, 4);
+    }
 }
diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php
index cf9e44e43..f5479814a 100644
--- a/app/Http/Controllers/Auth/LoginController.php
+++ b/app/Http/Controllers/Auth/LoginController.php
@@ -2,6 +2,7 @@
 
 namespace BookStack\Http\Controllers\Auth;
 
+use Activity;
 use BookStack\Auth\Access\SocialAuthService;
 use BookStack\Exceptions\LoginAttemptEmailNeededException;
 use BookStack\Exceptions\LoginAttemptException;
@@ -102,7 +103,7 @@ class LoginController extends Controller
             $this->fireLockoutEvent($request);
 
             // Also log some error message
-            $this->logFailedAccess($request);
+            Activity::logFailedAccess($request->get($this->username()));
 
             return $this->sendLockoutResponse($request);
         }
@@ -121,7 +122,7 @@ class LoginController extends Controller
         $this->incrementLoginAttempts($request);
 
         // Also log some error message
-        $this->logFailedAccess($request);
+        Activity::logFailedAccess($request->get($this->username()));
 
         return $this->sendFailedLoginResponse($request);
     }
@@ -168,21 +169,4 @@ class LoginController extends Controller
         return redirect('/login');
     }
 
-    /**
-     * Log failed accesses, for further processing by tools like Fail2Ban
-     *
-     * @param  \Illuminate\Http\Request  $request
-     * @return void
-      */
-    protected function logFailedAccess($request)
-    {
-        $log_msg = config('logging.failed_access_message');
-
-        if (!is_string($request->get($this->username())) || !is_string($log_msg) || strlen($log_msg)<1)
-            return;
-
-        $log_msg = str_replace("%u", $request->get($this->username()), $log_msg);
-        error_log($log_msg, 4);
-    }
-
 }