mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 09:39:57 +00:00
More authentication refactoring to also provide "plugable" credentials handling (references #921, needed for #305)
This commit is contained in:
parent
9f88dd3af3
commit
94214b867a
7
app.php
7
app.php
@ -11,9 +11,7 @@ require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
// Load config files
|
||||
require_once GROCY_DATAPATH . '/config.php';
|
||||
require_once __DIR__ . '/config-dist.php';
|
||||
|
||||
// For not in own config defined values we use the default ones
|
||||
require_once __DIR__ . '/config-dist.php'; // For not in own config defined values we use the default ones
|
||||
|
||||
// Definitions for dev/demo/prerelease mode
|
||||
if ((GROCY_MODE === 'dev' || GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease') && !defined('GROCY_USER_ID'))
|
||||
@ -41,9 +39,6 @@ $container = $app->getContainer();
|
||||
$container->set('view', function (Container $container) {
|
||||
return new Slim\Views\Blade(__DIR__ . '/views', GROCY_DATAPATH . '/viewcache');
|
||||
});
|
||||
$container->set('LoginControllerInstance', function (Container $container) {
|
||||
return new LoginController($container, 'grocy_session');
|
||||
});
|
||||
$container->set('UrlManager', function (Container $container) {
|
||||
return new UrlManager(GROCY_BASE_URL);
|
||||
});
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
namespace Grocy\Controllers;
|
||||
|
||||
use Grocy\Services\SessionService;
|
||||
|
||||
class LoginController extends BaseController
|
||||
{
|
||||
protected $SessionCookieName;
|
||||
|
||||
public function GetSessionCookieName()
|
||||
public function __construct(\DI\Container $container)
|
||||
{
|
||||
return $this->SessionCookieName;
|
||||
parent::__construct($container);
|
||||
}
|
||||
|
||||
public function LoginPage(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
@ -18,50 +18,20 @@ class LoginController extends BaseController
|
||||
|
||||
public function Logout(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
$this->getSessionService()->RemoveSession($_COOKIE[$this->SessionCookieName]);
|
||||
$this->getSessionService()->RemoveSession($_COOKIE[SessionService::SESSION_COOKIE_NAME]);
|
||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/'));
|
||||
}
|
||||
|
||||
public function ProcessLogin(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
$postParams = $this->GetParsedAndFilteredRequestBody($request);
|
||||
|
||||
if (isset($postParams['username']) && isset($postParams['password']))
|
||||
$authMiddlewareClass = GROCY_AUTH_CLASS;
|
||||
if ($authMiddlewareClass::ProcessLogin($this->GetParsedAndFilteredRequestBody($request)))
|
||||
{
|
||||
$user = $this->getDatabase()->users()->where('username', $postParams['username'])->fetch();
|
||||
$inputPassword = $postParams['password'];
|
||||
$stayLoggedInPermanently = $postParams['stay_logged_in'] == 'on';
|
||||
|
||||
if ($user !== null && password_verify($inputPassword, $user->password))
|
||||
{
|
||||
$sessionKey = $this->getSessionService()->CreateSession($user->id, $stayLoggedInPermanently);
|
||||
setcookie($this->SessionCookieName, $sessionKey, PHP_INT_SIZE == 4 ? PHP_INT_MAX : PHP_INT_MAX >> 32);
|
||||
|
||||
// Cookie expires never, but session validity is up to SessionService
|
||||
|
||||
if (password_needs_rehash($user->password, PASSWORD_DEFAULT))
|
||||
{
|
||||
$user->update([
|
||||
'password' => password_hash($inputPassword, PASSWORD_DEFAULT)
|
||||
]);
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/'));
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/login?invalid=true'));
|
||||
}
|
||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/'));
|
||||
}
|
||||
else
|
||||
{
|
||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/login?invalid=true'));
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct(\DI\Container $container, string $sessionCookieName)
|
||||
{
|
||||
parent::__construct($container);
|
||||
$this->SessionCookieName = $sessionCookieName;
|
||||
}
|
||||
}
|
||||
|
@ -72,4 +72,9 @@ class ApiKeyAuthMiddleware extends AuthMiddleware
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function ProcessLogin(array $postParams)
|
||||
{
|
||||
throw new \Exception('Not implemented');
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,19 @@ abstract class AuthMiddleware extends BaseMiddleware
|
||||
}
|
||||
}
|
||||
|
||||
protected static function SetSessionCookie($sessionKey)
|
||||
{
|
||||
// Cookie never expires, session validity is up to SessionService
|
||||
setcookie(SessionService::SESSION_COOKIE_NAME, $sessionKey, PHP_INT_SIZE == 4 ? PHP_INT_MAX : PHP_INT_MAX >> 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $postParams
|
||||
* @return bool True/False if the provided credentials were valid
|
||||
* @throws \Exception Throws an \Exception if an error happended during credentials processing or if this AuthMiddleware doesn't provide credentials processing (e. g. handles this externally)
|
||||
*/
|
||||
abstract public static function ProcessLogin(array $postParams);
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return mixed|null the user row or null if the request is not authenticated
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace Grocy\Middleware;
|
||||
|
||||
use Grocy\Services\DatabaseService;
|
||||
use Grocy\Services\SessionService;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class DefaultAuthMiddleware extends AuthMiddleware
|
||||
@ -22,4 +24,39 @@ class DefaultAuthMiddleware extends AuthMiddleware
|
||||
$user = $auth->authenticate($request);
|
||||
return $user;
|
||||
}
|
||||
|
||||
public static function ProcessLogin(array $postParams)
|
||||
{
|
||||
if (isset($postParams['username']) && isset($postParams['password']))
|
||||
{
|
||||
$db = DatabaseService::getInstance()->GetDbConnection();
|
||||
|
||||
$user = $db->users()->where('username', $postParams['username'])->fetch();
|
||||
$inputPassword = $postParams['password'];
|
||||
$stayLoggedInPermanently = $postParams['stay_logged_in'] == 'on';
|
||||
|
||||
if ($user !== null && password_verify($inputPassword, $user->password))
|
||||
{
|
||||
$sessionKey = SessionService::getInstance()->CreateSession($user->id, $stayLoggedInPermanently);
|
||||
parent::SetSessionCookie($sessionKey);
|
||||
|
||||
if (password_needs_rehash($user->password, PASSWORD_DEFAULT))
|
||||
{
|
||||
$user->update([
|
||||
'password' => password_hash($inputPassword, PASSWORD_DEFAULT)
|
||||
]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,4 +36,9 @@ class ReverseProxyAuthMiddleware extends AuthMiddleware
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public static function ProcessLogin(array $postParams)
|
||||
{
|
||||
throw new \Exception('Not implemented');
|
||||
}
|
||||
}
|
||||
|
@ -8,12 +8,9 @@ use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class SessionAuthMiddleware extends AuthMiddleware
|
||||
{
|
||||
protected $SessionCookieName;
|
||||
|
||||
public function __construct(\DI\Container $container, ResponseFactoryInterface $responseFactory)
|
||||
{
|
||||
parent::__construct($container, $responseFactory);
|
||||
$this->SessionCookieName = $this->AppContainer->get('LoginControllerInstance')->GetSessionCookieName();
|
||||
}
|
||||
|
||||
public function authenticate(Request $request)
|
||||
@ -25,13 +22,18 @@ class SessionAuthMiddleware extends AuthMiddleware
|
||||
|
||||
$sessionService = SessionService::getInstance();
|
||||
|
||||
if (!isset($_COOKIE[$this->SessionCookieName]) || !$sessionService->IsValidSession($_COOKIE[$this->SessionCookieName]))
|
||||
if (!isset($_COOKIE[SessionService::SESSION_COOKIE_NAME]) || !$sessionService->IsValidSession($_COOKIE[SessionService::SESSION_COOKIE_NAME]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $sessionService->GetUserBySessionKey($_COOKIE[$this->SessionCookieName]);
|
||||
return $sessionService->GetUserBySessionKey($_COOKIE[SessionService::SESSION_COOKIE_NAME]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function ProcessLogin(array $postParams)
|
||||
{
|
||||
throw new \Exception('Not implemented');
|
||||
}
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ $app->group('', function (RouteCollectorProxy $group) {
|
||||
$group->get('/barcodescannertesting', '\Grocy\Controllers\SystemController:BarcodeScannerTesting');
|
||||
|
||||
// Login routes
|
||||
$group->get('/login', 'LoginControllerInstance:LoginPage')->setName('login');
|
||||
$group->post('/login', 'LoginControllerInstance:ProcessLogin')->setName('login');
|
||||
$group->get('/logout', 'LoginControllerInstance:Logout');
|
||||
$group->get('/login', '\Grocy\Controllers\LoginController:LoginPage')->setName('login');
|
||||
$group->post('/login', '\Grocy\Controllers\LoginController:ProcessLogin')->setName('login');
|
||||
$group->get('/logout', '\Grocy\Controllers\LoginController:Logout');
|
||||
|
||||
// Generic entity interaction
|
||||
$group->get('/userfields', '\Grocy\Controllers\GenericEntityController:UserfieldsList');
|
||||
|
@ -4,6 +4,8 @@ namespace Grocy\Services;
|
||||
|
||||
class SessionService extends BaseService
|
||||
{
|
||||
const SESSION_COOKIE_NAME = 'grocy_session';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user