From fa8c641af61636cb133930e536ff874c0b8baed5 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Mon, 8 Mar 2021 16:15:10 +1300 Subject: [PATCH] NEW Add onBeforeRemoveLoginSession extension hook --- composer.json | 3 +- src/Control/LoginSessionController.php | 88 +++++++++++++++++++++ src/Security/LogInAuthenticationHandler.php | 6 +- 3 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 src/Control/LoginSessionController.php diff --git a/composer.json b/composer.json index d157d94..f973b9b 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ "symbiote/silverstripe-queuedjobs": "^4" }, "suggest": { - "symbiote/silverstripe-queuedjobs": "^4" + "symbiote/silverstripe-queuedjobs": "^4", + "silverstripe/auditor": "^2.3" }, "autoload": { "psr-4": { diff --git a/src/Control/LoginSessionController.php b/src/Control/LoginSessionController.php new file mode 100644 index 0000000..83dc5b9 --- /dev/null +++ b/src/Control/LoginSessionController.php @@ -0,0 +1,88 @@ + 'remove', + 'DELETE remove/$ID' => 'removeLoginSession' + ]; + + private static $allowed_actions = [ + // TODO: 'remove' + 'removeLoginSession', + ]; + + /** + * Remove the specified login session + * + * @param HTTPRequest $request + * @return HTTPResponse + */ + // TODO: rename to 'remove' + public function removeLoginSession(HTTPRequest $request): HTTPResponse + { + // Ensure CSRF protection + if (!SecurityToken::inst()->checkRequest($request)) { + return $this->jsonResponse( + ['errors' => 'Request timed out, please try again'], + 400 + ); + } + + $id = $request->param('ID'); + $loginSession = LoginSession::get()->byID($id); + if (!$loginSession) { + return $this->jsonResponse( + ['errors' => 'Something went wrong.'], + 400 + ); + } + + if (!$loginSession->canDelete()) { + return $this->jsonResponse( + ['errors' => 'You do not have permission to delete this record.'], + 400 + ); + } + + $this->extend('onBeforeRemoveLoginSession', $loginSession); + + $loginSession->delete(); + + return $this->jsonResponse([ + 'success' => true, + ]); + } + + /** + * Respond with the given array as a JSON response + * + * @param array $response + * @param int $code The HTTP response code to set on the response + * @return HTTPResponse + */ + // TODO: change visibility to private + protected function jsonResponse(array $response, int $code = 200): HTTPResponse + { + return HTTPResponse::create(json_encode($response)) + ->addHeader('Content-Type', 'application/json') + ->setStatusCode($code); + } +} diff --git a/src/Security/LogInAuthenticationHandler.php b/src/Security/LogInAuthenticationHandler.php index d41c1e5..7d6121d 100644 --- a/src/Security/LogInAuthenticationHandler.php +++ b/src/Security/LogInAuthenticationHandler.php @@ -94,7 +94,7 @@ public function logIn(Member $member, $persistent = false, HTTPRequest $request } $loginSession->LastAccessed = DBDatetime::now()->Rfc2822(); - $loginSession->IPAddress = $request->getIP(); + $loginSession->IPAddress = $request ? $request->getIP() : ''; $loginSession->write(); if ($persistent && $rememberLoginHash = $this->getRememberLoginHash()) { @@ -102,7 +102,9 @@ public function logIn(Member $member, $persistent = false, HTTPRequest $request $rememberLoginHash->write(); } - $request->getSession()->set($this->getSessionVariable(), $loginSession->ID); + if ($request) { + $request->getSession()->set($this->getSessionVariable(), $loginSession->ID); + } } /**