diff --git a/app.php b/app.php index d73a4f2..7f1399d 100644 --- a/app.php +++ b/app.php @@ -16,6 +16,7 @@ class Container { static SokoWeb\Interfaces\Database\IConnection $dbConnection; static SokoWeb\Interfaces\Database\IAuditLogger $auditLogger; + static SokoWeb\Interfaces\PersistentData\IPersistentDataManager $persistentDataManager; static SokoWeb\Routing\RouteCollection $routeCollection; static SokoWeb\Interfaces\Session\ISessionHandler $sessionHandler; static SokoWeb\Interfaces\Request\IRequest $request; @@ -23,3 +24,4 @@ class Container Container::$dbConnection = new SokoWeb\Database\Mysql\Connection($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME']); Container::$auditLogger = new RVR\Database\AuditLogger(Container::$dbConnection, 'audit_log'); +Container::$persistentDataManager = new SokoWeb\PersistentData\PersistentDataManager(Container::$dbConnection, Container::$auditLogger); diff --git a/composer.json b/composer.json index 1c356ae..49243fc 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "esoko/soko-web": "0.5", + "esoko/soko-web": "0.6", "firebase/php-jwt": "^6.4" }, "require-dev": { diff --git a/composer.lock b/composer.lock index b75ddce..24789aa 100644 --- a/composer.lock +++ b/composer.lock @@ -4,15 +4,15 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "05dba423c5e5dd40b5a7b9d4180d3673", + "content-hash": "7b9e3854a5b7ef69d360c1dfbac75c17", "packages": [ { "name": "esoko/soko-web", - "version": "v0.5", + "version": "0.6", "source": { "type": "git", "url": "https://git.esoko.eu/esoko/soko-web.git", - "reference": "3893ed22316e84aa4ffab7fbb3d5e823b928b001" + "reference": "5e0579463cf0f4203c46e0d4f9c09cd283dbf0b8" }, "require": { "phpmailer/phpmailer": "^6.8", @@ -33,7 +33,7 @@ "GNU GPL 3.0" ], "description": "Lightweight web framework", - "time": "2023-04-18T21:17:08+00:00" + "time": "2023-04-19T21:35:03+00:00" }, { "name": "firebase/php-jwt", diff --git a/src/Cli/AddOAuthClientCommand.php b/src/Cli/AddOAuthClientCommand.php index 21461e4..72ca266 100644 --- a/src/Cli/AddOAuthClientCommand.php +++ b/src/Cli/AddOAuthClientCommand.php @@ -1,7 +1,6 @@ saveToDb($oAuthClient); + \Container::$persistentDataManager->saveToDb($oAuthClient); } catch (\Exception $e) { $output->writeln('Adding OAuth client failed!'); $output->writeln(''); diff --git a/src/Cli/AddOAuthRedirectUriCommand.php b/src/Cli/AddOAuthRedirectUriCommand.php index 276e46a..cce1544 100644 --- a/src/Cli/AddOAuthRedirectUriCommand.php +++ b/src/Cli/AddOAuthRedirectUriCommand.php @@ -1,6 +1,5 @@ setRedirectUrisArray($redirectUris); try { - $pdm = new PersistentDataManager(); - $pdm->saveToDb($oAuthClient); + \Container::$persistentDataManager->saveToDb($oAuthClient); } catch (\Exception $e) { $output->writeln('Adding redirect URI failed!'); $output->writeln(''); diff --git a/src/Cli/AddUserCommand.php b/src/Cli/AddUserCommand.php index 980cb79..c5bda9a 100644 --- a/src/Cli/AddUserCommand.php +++ b/src/Cli/AddUserCommand.php @@ -1,7 +1,6 @@ saveToDb($user); + \Container::$persistentDataManager->saveToDb($user); } catch (\Exception $e) { $output->writeln('Adding user failed!'); $output->writeln(''); diff --git a/src/Cli/MaintainDatabaseCommand.php b/src/Cli/MaintainDatabaseCommand.php index 0930c96..c17b876 100644 --- a/src/Cli/MaintainDatabaseCommand.php +++ b/src/Cli/MaintainDatabaseCommand.php @@ -4,7 +4,6 @@ use DateTime; use SokoWeb\Database\Query\Modify; use SokoWeb\Database\Query\Select; use SokoWeb\Interfaces\Database\IResultSet; -use SokoWeb\PersistentData\PersistentDataManager; use RVR\Repository\UserPasswordResetterRepository; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -12,15 +11,12 @@ use Symfony\Component\Console\Output\OutputInterface; class MaintainDatabaseCommand extends Command { - private PersistentDataManager $pdm; - private UserPasswordResetterRepository $userPasswordResetterRepository; public function __construct() { parent::__construct(); - $this->pdm = new PersistentDataManager(); $this->userPasswordResetterRepository = new UserPasswordResetterRepository(); } @@ -54,7 +50,7 @@ class MaintainDatabaseCommand extends Command private function deleteExpiredPasswordResetters(): void { foreach ($this->userPasswordResetterRepository->getAllExpired() as $passwordResetter) { - $this->pdm->deleteFromDb($passwordResetter); + \Container::$persistentDataManager->deleteFromDb($passwordResetter); } } diff --git a/src/Cli/RemoveOAuthRedirectUriCommand.php b/src/Cli/RemoveOAuthRedirectUriCommand.php index c784a8d..6467c6d 100644 --- a/src/Cli/RemoveOAuthRedirectUriCommand.php +++ b/src/Cli/RemoveOAuthRedirectUriCommand.php @@ -1,6 +1,5 @@ setRedirectUrisArray($redirectUris); try { - $pdm = new PersistentDataManager(); - $pdm->saveToDb($oAuthClient); + \Container::$persistentDataManager->saveToDb($oAuthClient); } catch (\Exception $e) { $output->writeln('Removing redirect URI failed!'); $output->writeln(''); diff --git a/src/Controller/CommunityController.php b/src/Controller/CommunityController.php index b7a6d0f..8f76ff5 100644 --- a/src/Controller/CommunityController.php +++ b/src/Controller/CommunityController.php @@ -8,28 +8,20 @@ use RVR\Repository\CommunityRepository; use RVR\Repository\CommunityMemberRepository; use RVR\Repository\UserRepository; use SokoWeb\Interfaces\Authentication\IAuthenticationRequired; -use SokoWeb\Interfaces\Request\IRequest; use SokoWeb\Interfaces\Response\IContent; -use SokoWeb\PersistentData\PersistentDataManager; use SokoWeb\Response\HtmlContent; use SokoWeb\Response\JsonContent; class CommunityController implements IAuthenticationRequired { - private IRequest $request; - - private PersistentDataManager $pdm; - private UserRepository $userRepository; private CommunityRepository $communityRepository; private CommunityMemberRepository $communityMemberRepository; - public function __construct(IRequest $request) + public function __construct() { - $this->request = $request; - $this->pdm = new PersistentDataManager(); $this->userRepository = new UserRepository(); $this->communityRepository = new CommunityRepository(); $this->communityMemberRepository = new CommunityMemberRepository(); @@ -42,7 +34,7 @@ class CommunityController implements IAuthenticationRequired public function getCommunityHome(): ?IContent { - if (!$this->checkPermission($this->request->query('communityId'), false, $community, $ownCommunityMember)) { + if (!$this->checkPermission(\Container::$request->query('communityId'), false, $community, $ownCommunityMember)) { return null; } @@ -62,7 +54,7 @@ class CommunityController implements IAuthenticationRequired public function getCommunityEdit(): ?IContent { - if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) { + if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) { return null; } @@ -73,7 +65,7 @@ class CommunityController implements IAuthenticationRequired public function getMembersEdit(): ?IContent { - if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) { + if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) { return null; } @@ -95,60 +87,60 @@ class CommunityController implements IAuthenticationRequired public function newMember(): ?IContent { - if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) { + if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) { return null; } - $user = $this->userRepository->getById($this->request->post('user_id')); + $user = $this->userRepository->getById(\Container::$request->post('user_id')); $communityMember = new CommunityMember(); $communityMember->setCommunity($community); $communityMember->setUser($user); - $this->pdm->saveToDb($communityMember); + \Container::$persistentDataManager->saveToDb($communityMember); return new JsonContent(['success' => true]); } public function editMember(): ?IContent { - if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) { + if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) { return null; } - $communityMember = $this->communityMemberRepository->getById($this->request->post('community_member_id')); - if ($communityMember->getUserId() === $this->request->user()->getUniqueId()) { + $communityMember = $this->communityMemberRepository->getById(\Container::$request->post('community_member_id')); + if ($communityMember->getUserId() === \Container::$request->user()->getUniqueId()) { return new JsonContent([ 'error' => ['errorText' => 'Own user cannot be edited.'] ]); } - $communityMember->setOwner($this->request->post('owner')); - $this->pdm->saveToDb($communityMember); + $communityMember->setOwner(\Container::$request->post('owner')); + \Container::$persistentDataManager->saveToDb($communityMember); return new JsonContent(['success' => true]); } public function deleteMember(): ?IContent { - if (!$this->checkPermission($this->request->query('communityId'), true, $community, $ownCommunityMember)) { + if (!$this->checkPermission(\Container::$request->query('communityId'), true, $community, $ownCommunityMember)) { return null; } - $communityMember = $this->communityMemberRepository->getById($this->request->post('community_member_id')); - if ($communityMember->getUserId() === $this->request->user()->getUniqueId()) { + $communityMember = $this->communityMemberRepository->getById(\Container::$request->post('community_member_id')); + if ($communityMember->getUserId() === \Container::$request->user()->getUniqueId()) { return new JsonContent([ 'error' => ['errorText' => 'Own user cannot be deleted.'] ]); } - $this->pdm->deleteFromDb($communityMember); + \Container::$persistentDataManager->deleteFromDb($communityMember); return new JsonContent(['success' => true]); } public function saveCommunity(): ?IContent { - $communityId = $this->request->query('communityId'); + $communityId = \Container::$request->query('communityId'); if ($communityId){ if (!$this->checkPermission($communityId, true, $community, $ownCommunityMember)) { return null; @@ -157,8 +149,8 @@ class CommunityController implements IAuthenticationRequired $community = new Community(); } - $name = $this->request->post('name'); - $currency = $this->request->post('currency'); + $name = \Container::$request->post('name'); + $currency = \Container::$request->post('currency'); if (strlen($name) === 0 || strlen($currency) === 0 || strlen($currency) > 3) { return new JsonContent([ 'error' => ['errorText' => 'Please fill all required fields!'] @@ -170,19 +162,19 @@ class CommunityController implements IAuthenticationRequired if (!$communityId) { $community->setCreatedDate(new DateTime()); } - $this->pdm->saveToDb($community); + \Container::$persistentDataManager->saveToDb($community); if (!$communityId) { /** * @var User $user */ - $user = $this->request->user(); + $user = \Container::$request->user(); $communityMember = new CommunityMember(); $communityMember->setCommunity($community); $communityMember->setUser($user); $communityMember->setOwner(true); - $this->pdm->saveToDb($communityMember); + \Container::$persistentDataManager->saveToDb($communityMember); } return new JsonContent([ @@ -204,7 +196,7 @@ class CommunityController implements IAuthenticationRequired /** * @var User $user */ - $user = $this->request->user(); + $user = \Container::$request->user(); $ownCommunityMember = $this->communityMemberRepository->getByCommunityAndUser($community, $user); if ($ownCommunityMember === null || ($needToBeOwner && !$ownCommunityMember->getOwner())) { diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php index b9233f9..f17ceff 100644 --- a/src/Controller/HomeController.php +++ b/src/Controller/HomeController.php @@ -3,19 +3,15 @@ use RVR\PersistentData\Model\User; use RVR\Repository\CommunityMemberRepository; use SokoWeb\Interfaces\Authentication\IAuthenticationRequired; -use SokoWeb\Interfaces\Request\IRequest; use SokoWeb\Interfaces\Response\IContent; use SokoWeb\Response\HtmlContent; class HomeController implements IAuthenticationRequired { - private IRequest $request; - private CommunityMemberRepository $communityMemberRepository; - public function __construct(IRequest $request) + public function __construct() { - $this->request = $request; $this->communityMemberRepository = new CommunityMemberRepository(); } @@ -29,7 +25,7 @@ class HomeController implements IAuthenticationRequired /** * @var User $user */ - $user = $this->request->user(); + $user = \Container::$request->user(); $ownCommunityMembers = $this->communityMemberRepository->getAllByUser($user, true); $communities = []; diff --git a/src/Controller/LoginController.php b/src/Controller/LoginController.php index 94e7c82..cca513f 100644 --- a/src/Controller/LoginController.php +++ b/src/Controller/LoginController.php @@ -2,13 +2,11 @@ use DateTime; use SokoWeb\Http\Request; -use SokoWeb\Interfaces\Request\IRequest; use SokoWeb\Interfaces\Response\IContent; use SokoWeb\Interfaces\Response\IRedirect; use SokoWeb\Mailing\Mail; use SokoWeb\OAuth\GoogleOAuth; use RVR\PersistentData\Model\UserPasswordResetter; -use SokoWeb\PersistentData\PersistentDataManager; use RVR\Repository\UserPasswordResetterRepository; use RVR\Repository\UserRepository; use SokoWeb\Response\HtmlContent; @@ -19,30 +17,24 @@ use SokoWeb\Util\JwtParser; class LoginController { - private IRequest $request; - - private PersistentDataManager $pdm; - private UserRepository $userRepository; private UserPasswordResetterRepository $userPasswordResetterRepository; private string $redirectUrl; - public function __construct(IRequest $request) + public function __construct() { - $this->request = $request; - $this->pdm = new PersistentDataManager(); $this->userRepository = new UserRepository(); $this->userPasswordResetterRepository = new UserPasswordResetterRepository(); - $this->redirectUrl = $this->request->session()->has('redirect_after_login') ? - $this->request->session()->get('redirect_after_login') : + $this->redirectUrl = \Container::$request->session()->has('redirect_after_login') ? + \Container::$request->session()->get('redirect_after_login') : \Container::$routeCollection->getRoute('home')->generateLink(); } public function getLoginForm() { - if ($this->request->user() !== null) { + if (\Container::$request->user() !== null) { $this->deleteRedirectUrl(); return new Redirect($this->redirectUrl, IRedirect::TEMPORARY); } @@ -55,13 +47,13 @@ class LoginController $state = bin2hex(random_bytes(16)); $nonce = bin2hex(random_bytes(16)); - $this->request->session()->set('oauth_state', $state); - $this->request->session()->set('oauth_nonce', $nonce); + \Container::$request->session()->set('oauth_state', $state); + \Container::$request->session()->set('oauth_nonce', $nonce); $oAuth = new GoogleOAuth(new Request()); $url = $oAuth->getDialogUrl( $state, - $this->request->getBase() . \Container::$routeCollection->getRoute('login-google-action')->generateLink(), + \Container::$request->getBase() . \Container::$routeCollection->getRoute('login-google-action')->generateLink(), $nonce ); @@ -70,12 +62,12 @@ class LoginController public function getRequestPasswordResetForm() { - if ($this->request->user() !== null) { + if (\Container::$request->user() !== null) { $this->deleteRedirectUrl(); return new Redirect($this->redirectUrl, IRedirect::TEMPORARY); } - return new HtmlContent('login/password_reset_request', ['email' => $this->request->query('email')]); + return new HtmlContent('login/password_reset_request', ['email' => \Container::$request->query('email')]); } public function getRequestPasswordResetSuccess(): IContent @@ -85,12 +77,12 @@ class LoginController public function getResetPasswordForm() { - if ($this->request->user() !== null) { + if (\Container::$request->user() !== null) { $this->deleteRedirectUrl(); return new Redirect($this->redirectUrl, IRedirect::TEMPORARY); } - $token = $this->request->query('token'); + $token = \Container::$request->query('token'); $resetter = $this->userPasswordResetterRepository->getByToken($token); if ($resetter === null || $resetter->getExpiresDate() < new DateTime()) { @@ -104,22 +96,22 @@ class LoginController public function login(): IContent { - if ($this->request->user() !== null) { + if (\Container::$request->user() !== null) { $this->deleteRedirectUrl(); return new JsonContent(['success' => true]); } - $user = $this->userRepository->getByEmailOrUsername($this->request->post('email')); - if ($user === null || !$user->checkPassword($this->request->post('password'))) { + $user = $this->userRepository->getByEmailOrUsername(\Container::$request->post('email')); + if ($user === null || !$user->checkPassword(\Container::$request->post('password'))) { return new JsonContent([ 'error' => [ 'errorText' => 'No user found with the given email address / username or the given password is wrong. You can request password reset!' + \Container::$routeCollection->getRoute('password-requestReset')->generateLink(['email' => \Container::$request->post('email')]) . '" title="Request password reset">request password reset!' ] ]); } - $this->request->setUser($user); + \Container::$request->setUser($user); $this->deleteRedirectUrl(); return new JsonContent(['success' => true]); @@ -129,19 +121,19 @@ class LoginController { $defaultError = 'Authentication with Google failed. Please try again!'; - if ($this->request->user() !== null) { + if (\Container::$request->user() !== null) { $this->deleteRedirectUrl(); return new Redirect($this->redirectUrl, IRedirect::TEMPORARY); } - if ($this->request->query('state') !== $this->request->session()->get('oauth_state')) { + if (\Container::$request->query('state') !== \Container::$request->session()->get('oauth_state')) { return new HtmlContent('login/google_login_error', ['error' => $defaultError]); } $oAuth = new GoogleOAuth(new Request()); $tokenData = $oAuth->getToken( - $this->request->query('code'), - $this->request->getBase() . \Container::$routeCollection->getRoute('login-google-action')->generateLink() + \Container::$request->query('code'), + \Container::$request->getBase() . \Container::$routeCollection->getRoute('login-google-action')->generateLink() ); if (!isset($tokenData['id_token'])) { @@ -151,7 +143,7 @@ class LoginController $jwtParser = new JwtParser($tokenData['id_token']); $idToken = $jwtParser->getPayload(); - if ($idToken['nonce'] !== $this->request->session()->get('oauth_nonce')) { + if ($idToken['nonce'] !== \Container::$request->session()->get('oauth_nonce')) { return new HtmlContent('login/google_login_error', ['error' => $defaultError]); } @@ -164,7 +156,7 @@ class LoginController return new HtmlContent('login/google_login_error', ['error' => 'No user found for this Google account.']); } - $this->request->setUser($user); + \Container::$request->setUser($user); $this->deleteRedirectUrl(); return new Redirect($this->redirectUrl, IRedirect::TEMPORARY); @@ -172,14 +164,14 @@ class LoginController public function logout(): IRedirect { - $this->request->setUser(null); + \Container::$request->setUser(null); return new Redirect(\Container::$routeCollection->getRoute('home')->generateLink(), IRedirect::TEMPORARY); } public function requestPasswordReset(): IContent { - if ($this->request->user() !== null) { + if (\Container::$request->user() !== null) { $this->deleteRedirectUrl(); return new JsonContent([ 'redirect' => [ @@ -189,18 +181,18 @@ class LoginController } if (!empty($_ENV['RECAPTCHA_SITEKEY'])) { - if (!$this->request->post('g-recaptcha-response')) { + if (!\Container::$request->post('g-recaptcha-response')) { return new JsonContent(['error' => ['errorText' => 'Please check "I\'m not a robot" in the reCAPTCHA box!']]); } $captchaValidator = new CaptchaValidator(); - $captchaResponse = $captchaValidator->validate($this->request->post('g-recaptcha-response')); + $captchaResponse = $captchaValidator->validate(\Container::$request->post('g-recaptcha-response')); if (!$captchaResponse['success']) { return new JsonContent(['error' => ['errorText' => 'reCAPTCHA challenge failed. Please try again!']]); } } - $user = $this->userRepository->getByEmailOrUsername($this->request->post('email')); + $user = $this->userRepository->getByEmailOrUsername(\Container::$request->post('email')); if ($user === null) { return new JsonContent([ 'error' => [ @@ -227,10 +219,10 @@ class LoginController $passwordResetter->setExpiresDate($expires); if ($existingResetter !== null) { - $this->pdm->deleteFromDb($existingResetter); + \Container::$persistentDataManager->deleteFromDb($existingResetter); } - $this->pdm->saveToDb($passwordResetter); + \Container::$persistentDataManager->saveToDb($passwordResetter); $this->sendPasswordResetEmail($user->getEmail(), $token, $expires); @@ -239,7 +231,7 @@ class LoginController public function resetPassword(): IContent { - if ($this->request->user() !== null) { + if (\Container::$request->user() !== null) { $this->deleteRedirectUrl(); return new JsonContent([ 'redirect' => [ @@ -248,7 +240,7 @@ class LoginController ]); } - $token = $this->request->query('token'); + $token = \Container::$request->query('token'); $resetter = $this->userPasswordResetterRepository->getByToken($token); if ($resetter === null || $resetter->getExpiresDate() < new DateTime()) { @@ -259,7 +251,7 @@ class LoginController ]); } - if (strlen($this->request->post('password')) < 6) { + if (strlen(\Container::$request->post('password')) < 6) { return new JsonContent([ 'error' => [ 'errorText' => 'The given password is too short. Please choose a password that is at least 6 characters long!' @@ -267,18 +259,18 @@ class LoginController ]); } - if ($this->request->post('password') !== $this->request->post('password_confirm')) { + if (\Container::$request->post('password') !== \Container::$request->post('password_confirm')) { return new JsonContent(['error' => ['errorText' => 'The given passwords do not match.']]); } - $this->pdm->deleteFromDb($resetter); + \Container::$persistentDataManager->deleteFromDb($resetter); $user = $this->userRepository->getById($resetter->getUserId()); - $user->setPlainPassword($this->request->post('password')); + $user->setPlainPassword(\Container::$request->post('password')); - $this->pdm->saveToDb($user); + \Container::$persistentDataManager->saveToDb($user); - $this->request->setUser($user); + \Container::$request->setUser($user); $this->deleteRedirectUrl(); return new JsonContent(['success' => true]); @@ -291,7 +283,7 @@ class LoginController $mail->setSubject($_ENV['APP_NAME'] . ' - Password reset'); $mail->setBodyFromTemplate('password-reset', [ 'EMAIL' => $email, - 'RESET_LINK' => $this->request->getBase() . + 'RESET_LINK' => \Container::$request->getBase() . \Container::$routeCollection->getRoute('password-reset')->generateLink(['token' => $token]), 'EXPIRES' => $expires->format('Y-m-d H:i T') ]); @@ -300,6 +292,6 @@ class LoginController private function deleteRedirectUrl(): void { - $this->request->session()->delete('redirect_after_login'); + \Container::$request->session()->delete('redirect_after_login'); } } diff --git a/src/Controller/OAuthAuthController.php b/src/Controller/OAuthAuthController.php index e8d636c..7c5d3e6 100644 --- a/src/Controller/OAuthAuthController.php +++ b/src/Controller/OAuthAuthController.php @@ -5,24 +5,16 @@ use RVR\PersistentData\Model\OAuthToken; use RVR\PersistentData\Model\User; use RVR\Repository\OAuthClientRepository; use SokoWeb\Interfaces\Authentication\IAuthenticationRequired; -use SokoWeb\Interfaces\Request\IRequest; use SokoWeb\Interfaces\Response\IRedirect; use SokoWeb\Response\Redirect; -use SokoWeb\PersistentData\PersistentDataManager; use SokoWeb\Response\HtmlContent; class OAuthAuthController implements IAuthenticationRequired { - private IRequest $request; - - private PersistentDataManager $pdm; - private OAuthClientRepository $oAuthClientRepository; - public function __construct(IRequest $request) + public function __construct() { - $this->request = $request; - $this->pdm = new PersistentDataManager(); $this->oAuthClientRepository = new OAuthClientRepository(); } @@ -33,11 +25,11 @@ class OAuthAuthController implements IAuthenticationRequired public function auth() { - $redirectUri = $this->request->query('redirect_uri'); - $clientId = $this->request->query('client_id'); - $scope = $this->request->query('scope') ? $this->request->query('scope'): ''; - $state = $this->request->query('state'); - $nonce = $this->request->query('nonce') ? $this->request->query('nonce'): ''; + $redirectUri = \Container::$request->query('redirect_uri'); + $clientId = \Container::$request->query('client_id'); + $scope = \Container::$request->query('scope') ? \Container::$request->query('scope'): ''; + $state = \Container::$request->query('state'); + $nonce = \Container::$request->query('nonce') ? \Container::$request->query('nonce'): ''; if (!$clientId || !$redirectUri || !$state) { return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']); @@ -62,7 +54,7 @@ class OAuthAuthController implements IAuthenticationRequired /** * @var ?User $user */ - $user = $this->request->user(); + $user = \Container::$request->user(); $code = bin2hex(random_bytes(16)); $accessToken = bin2hex(random_bytes(16)); @@ -74,7 +66,7 @@ class OAuthAuthController implements IAuthenticationRequired $token->setAccessToken($accessToken); $token->setCreatedDate(new DateTime()); $token->setExpiresDate(new DateTime('+5 minutes')); - $this->pdm->saveToDb($token); + \Container::$persistentDataManager->saveToDb($token); $redirectUriQuery = array_merge($redirectUriQuery, [ 'state' => $state, diff --git a/src/Controller/OAuthController.php b/src/Controller/OAuthController.php index 9c26391..ee41154 100644 --- a/src/Controller/OAuthController.php +++ b/src/Controller/OAuthController.php @@ -6,23 +6,19 @@ use RVR\Repository\OAuthTokenRepository; use RVR\Repository\UserRepository; use RVR\PersistentData\Model\User; use RVR\Repository\OAuthClientRepository; -use SokoWeb\Interfaces\Request\IRequest; use SokoWeb\Interfaces\Response\IContent; use SokoWeb\Response\JsonContent; class OAuthController { - private IRequest $request; - private OAuthClientRepository $oAuthClientRepository; private OAuthTokenRepository $oAuthTokenRepository; private UserRepository $userRepository; - public function __construct(IRequest $request) + public function __construct() { - $this->request = $request; $this->oAuthClientRepository = new OAuthClientRepository(); $this->oAuthTokenRepository = new OAuthTokenRepository(); $this->userRepository = new UserRepository(); @@ -30,9 +26,9 @@ class OAuthController public function getToken(): ?IContent { - $clientId = $this->request->post('client_id'); - $clientSecret = $this->request->post('client_secret'); - $code = $this->request->post('code'); + $clientId = \Container::$request->post('client_id'); + $clientSecret = \Container::$request->post('client_secret'); + $code = \Container::$request->post('code'); if (!$clientId || !$clientSecret || !$code) { return new JsonContent([ @@ -80,7 +76,7 @@ class OAuthController public function getUserInfo() : IContent { - $authorization = $this->request->header('Authorization'); + $authorization = \Container::$request->header('Authorization'); if ($authorization === null) { return new JsonContent([ 'error' => 'No Authorization header was sent.' @@ -108,10 +104,10 @@ class OAuthController { return new JsonContent([ 'issuer' => $_ENV['APP_URL'], - 'authorization_endpoint' => $this->request->getBase() . \Container::$routeCollection->getRoute('oauth-auth')->generateLink(), - 'token_endpoint' => $this->request->getBase() . \Container::$routeCollection->getRoute('oauth-token')->generateLink(), - 'userinfo_endpoint' => $this->request->getBase() . \Container::$routeCollection->getRoute('oauth-userinfo')->generateLink(), - 'jwks_uri' => $this->request->getBase() . \Container::$routeCollection->getRoute('oauth-certs')->generateLink(), + 'authorization_endpoint' => \Container::$request->getBase() . \Container::$routeCollection->getRoute('oauth-auth')->generateLink(), + 'token_endpoint' => \Container::$request->getBase() . \Container::$routeCollection->getRoute('oauth-token')->generateLink(), + 'userinfo_endpoint' => \Container::$request->getBase() . \Container::$routeCollection->getRoute('oauth-userinfo')->generateLink(), + 'jwks_uri' => \Container::$request->getBase() . \Container::$routeCollection->getRoute('oauth-certs')->generateLink(), 'response_types_supported' => [ 'code', diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 89edd12..8ae40a6 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -3,11 +3,9 @@ use DateTime; use SokoWeb\Http\Request; use SokoWeb\Interfaces\Authentication\IAuthenticationRequired; -use SokoWeb\Interfaces\Request\IRequest; use SokoWeb\Interfaces\Response\IContent; use SokoWeb\Interfaces\Response\IRedirect; use SokoWeb\OAuth\GoogleOAuth; -use SokoWeb\PersistentData\PersistentDataManager; use RVR\PersistentData\Model\User; use SokoWeb\Response\HtmlContent; use SokoWeb\Response\JsonContent; @@ -17,16 +15,10 @@ use RVR\Repository\UserRepository; class UserController implements IAuthenticationRequired { - private IRequest $request; - - private PersistentDataManager $pdm; - private UserRepository $userRepository; - public function __construct(IRequest $request) + public function __construct() { - $this->request = $request; - $this->pdm = new PersistentDataManager(); $this->userRepository = new UserRepository(); } @@ -40,7 +32,7 @@ class UserController implements IAuthenticationRequired /** * @var User $user */ - $user = $this->request->user(); + $user = \Container::$request->user(); return new HtmlContent('account/account', ['user' => $user->toArray()]); } @@ -50,19 +42,19 @@ class UserController implements IAuthenticationRequired /** * @var User $user */ - $user = $this->request->user(); + $user = \Container::$request->user(); $state = bin2hex(random_bytes(16)); $nonce = bin2hex(random_bytes(16)); - $this->request->session()->set('oauth_state', $state); - $this->request->session()->set('oauth_nonce', $nonce); + \Container::$request->session()->set('oauth_state', $state); + \Container::$request->session()->set('oauth_nonce', $nonce); $oAuth = new GoogleOAuth(new Request()); $url = $oAuth->getDialogUrl( $state, - $this->request->getBase() . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink(), + \Container::$request->getBase() . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink(), $nonce, $user->getEmail() ); @@ -75,16 +67,16 @@ class UserController implements IAuthenticationRequired /** * @var User $user */ - $user = $this->request->user(); + $user = \Container::$request->user(); - if ($this->request->query('state') !== $this->request->session()->get('oauth_state')) { + if (\Container::$request->query('state') !== \Container::$request->session()->get('oauth_state')) { return new HtmlContent('account/google_authenticate', ['success' => false]); } $oAuth = new GoogleOAuth(new Request()); $tokenData = $oAuth->getToken( - $this->request->query('code'), - $this->request->getBase() . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink() + \Container::$request->query('code'), + \Container::$request->getBase() . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink() ); if (!isset($tokenData['id_token'])) { @@ -94,7 +86,7 @@ class UserController implements IAuthenticationRequired $jwtParser = new JwtParser($tokenData['id_token']); $idToken = $jwtParser->getPayload(); - if ($idToken['nonce'] !== $this->request->session()->get('oauth_nonce')) { + if ($idToken['nonce'] !== \Container::$request->session()->get('oauth_nonce')) { return new HtmlContent('account/google_authenticate', ['success' => false]); } @@ -106,7 +98,7 @@ class UserController implements IAuthenticationRequired } $authenticatedWithGoogleUntil = new DateTime('+45 seconds'); - $this->request->session()->set('authenticated_with_google_until', $authenticatedWithGoogleUntil); + \Container::$request->session()->set('authenticated_with_google_until', $authenticatedWithGoogleUntil); return new HtmlContent('account/google_authenticate', [ 'success' => true, @@ -119,18 +111,18 @@ class UserController implements IAuthenticationRequired /** * @var User $user */ - $user = $this->request->user(); + $user = \Container::$request->user(); if (!$this->confirmUserIdentity( $user, - $this->request->session()->get('authenticated_with_google_until'), - $this->request->post('password'), + \Container::$request->session()->get('authenticated_with_google_until'), + \Container::$request->post('password'), $error )) { return new JsonContent(['error' => ['errorText' => $error]]); } - $newEmail = $this->request->post('email'); + $newEmail = \Container::$request->post('email'); if ($newEmail !== $user->getEmail()) { if (!filter_var($newEmail, FILTER_VALIDATE_EMAIL)) { return new JsonContent(['error' => ['errorText' => 'Please provide a valid email address.']]); @@ -143,7 +135,7 @@ class UserController implements IAuthenticationRequired $user->setEmail($newEmail); } - $newUsername = $this->request->post('username'); + $newUsername = \Container::$request->post('username'); if ($newUsername !== $user->getUsername()) { if (strlen($newUsername) > 0) { if (filter_var($newUsername, FILTER_VALIDATE_EMAIL)) { @@ -160,7 +152,7 @@ class UserController implements IAuthenticationRequired } } - $newPassword = $this->request->post('password_new'); + $newPassword = \Container::$request->post('password_new'); if (strlen($newPassword) > 0) { if (strlen($newPassword) < 6) { return new JsonContent([ @@ -170,7 +162,7 @@ class UserController implements IAuthenticationRequired ]); } - if ($newPassword !== $this->request->post('password_new_confirm')) { + if ($newPassword !== \Container::$request->post('password_new_confirm')) { return new JsonContent([ 'error' => [ 'errorText' => 'The given new passwords do not match.' @@ -181,13 +173,13 @@ class UserController implements IAuthenticationRequired $user->setPlainPassword($newPassword); } - $user->setNickname($this->request->post('nickname')); - $user->setPhone($this->request->post('phone')); - $user->setIdNumber($this->request->post('id_number')); + $user->setNickname(\Container::$request->post('nickname')); + $user->setPhone(\Container::$request->post('phone')); + $user->setIdNumber(\Container::$request->post('id_number')); - $this->pdm->saveToDb($user); + \Container::$persistentDataManager->saveToDb($user); - $this->request->session()->delete('authenticated_with_google_until'); + \Container::$request->session()->delete('authenticated_with_google_until'); return new JsonContent(['success' => true]); } diff --git a/src/Controller/UserSearchController.php b/src/Controller/UserSearchController.php index 69d8c33..b05c7a4 100644 --- a/src/Controller/UserSearchController.php +++ b/src/Controller/UserSearchController.php @@ -2,19 +2,15 @@ use RVR\Repository\UserRepository; use SokoWeb\Interfaces\Authentication\IAuthenticationRequired; -use SokoWeb\Interfaces\Request\IRequest; use SokoWeb\Interfaces\Response\IContent; use SokoWeb\Response\JsonContent; class UserSearchController implements IAuthenticationRequired { - private IRequest $request; - private UserRepository $userRepository; - public function __construct(IRequest $request) + public function __construct() { - $this->request = $request; $this->userRepository = new UserRepository(); } @@ -25,7 +21,7 @@ class UserSearchController implements IAuthenticationRequired public function searchUser(): IContent { - $users = iterator_to_array($this->userRepository->searchByName($this->request->query('q'))); + $users = iterator_to_array($this->userRepository->searchByName(\Container::$request->query('q'))); usort($users, function($a, $b) { return strnatcmp($a->getDisplayName(), $b->getDisplayName()); }); diff --git a/src/Repository/CommunityMemberRepository.php b/src/Repository/CommunityMemberRepository.php index adb2598..b15b8ff 100644 --- a/src/Repository/CommunityMemberRepository.php +++ b/src/Repository/CommunityMemberRepository.php @@ -5,20 +5,12 @@ use RVR\PersistentData\Model\Community; use RVR\PersistentData\Model\CommunityMember; use RVR\PersistentData\Model\User; use SokoWeb\Database\Query\Select; -use SokoWeb\PersistentData\PersistentDataManager; class CommunityMemberRepository { - private PersistentDataManager $pdm; - - public function __construct() - { - $this->pdm = new PersistentDataManager(); - } - public function getById(int $id): ?CommunityMember { - return $this->pdm->selectFromDbById($id, CommunityMember::class); + return \Container::$persistentDataManager->selectFromDbById($id, CommunityMember::class); } public function getAllByCommunity(Community $community, bool $useRelations = false): Generator @@ -26,7 +18,7 @@ class CommunityMemberRepository $select = new Select(\Container::$dbConnection); $select->where('community_id', '=', $community->getId()); - yield from $this->pdm->selectMultipleFromDb($select, CommunityMember::class, $useRelations); + yield from \Container::$persistentDataManager->selectMultipleFromDb($select, CommunityMember::class, $useRelations); } public function getAllByUser(User $user, bool $useRelations = false): Generator @@ -34,7 +26,7 @@ class CommunityMemberRepository $select = new Select(\Container::$dbConnection); $select->where('user_id', '=', $user->getId()); - yield from $this->pdm->selectMultipleFromDb($select, CommunityMember::class, $useRelations); + yield from \Container::$persistentDataManager->selectMultipleFromDb($select, CommunityMember::class, $useRelations); } public function getByCommunityAndUser(Community $community, User $user) : ?CommunityMember @@ -43,6 +35,6 @@ class CommunityMemberRepository $select->where('community_id', '=', $community->getId()); $select->where('user_id', '=', $user->getId()); - return $this->pdm->selectFromDb($select, CommunityMember::class); + return \Container::$persistentDataManager->selectFromDb($select, CommunityMember::class); } } diff --git a/src/Repository/CommunityRepository.php b/src/Repository/CommunityRepository.php index 48bd439..a1b4c96 100644 --- a/src/Repository/CommunityRepository.php +++ b/src/Repository/CommunityRepository.php @@ -1,19 +1,11 @@ pdm = new PersistentDataManager(); - } - public function getById(int $id): ?Community { - return $this->pdm->selectFromDbById($id, Community::class); + return \Container::$persistentDataManager->selectFromDbById($id, Community::class); } } diff --git a/src/Repository/OAuthClientRepository.php b/src/Repository/OAuthClientRepository.php index ba99961..b547a53 100644 --- a/src/Repository/OAuthClientRepository.php +++ b/src/Repository/OAuthClientRepository.php @@ -2,20 +2,12 @@ use SokoWeb\Database\Query\Select; use RVR\PersistentData\Model\OAuthClient; -use SokoWeb\PersistentData\PersistentDataManager; class OAuthClientRepository { - private PersistentDataManager $pdm; - - public function __construct() - { - $this->pdm = new PersistentDataManager(); - } - public function getById(int $id): ?OAuthClient { - return $this->pdm->selectFromDbById($id, OAuthClient::class); + return \Container::$persistentDataManager->selectFromDbById($id, OAuthClient::class); } public function getByClientId(string $clientId): ?OAuthClient @@ -23,6 +15,6 @@ class OAuthClientRepository $select = new Select(\Container::$dbConnection); $select->where('client_id', '=', $clientId); - return $this->pdm->selectFromDb($select, OAuthClient::class); + return \Container::$persistentDataManager->selectFromDb($select, OAuthClient::class); } } diff --git a/src/Repository/OAuthTokenRepository.php b/src/Repository/OAuthTokenRepository.php index 492959e..4aaa05b 100644 --- a/src/Repository/OAuthTokenRepository.php +++ b/src/Repository/OAuthTokenRepository.php @@ -4,20 +4,12 @@ use DateTime; use Generator; use SokoWeb\Database\Query\Select; use RVR\PersistentData\Model\OAuthToken; -use SokoWeb\PersistentData\PersistentDataManager; class OAuthTokenRepository { - private PersistentDataManager $pdm; - - public function __construct() - { - $this->pdm = new PersistentDataManager(); - } - public function getById(int $id): ?OAuthToken { - return $this->pdm->selectFromDbById($id, OAuthToken::class); + return \Container::$persistentDataManager->selectFromDbById($id, OAuthToken::class); } public function getByCode(string $code): ?OAuthToken @@ -25,7 +17,7 @@ class OAuthTokenRepository $select = new Select(\Container::$dbConnection); $select->where('code', '=', $code); - return $this->pdm->selectFromDb($select, OAuthToken::class); + return \Container::$persistentDataManager->selectFromDb($select, OAuthToken::class); } public function getByAccessToken(string $accessToken): ?OAuthToken @@ -33,7 +25,7 @@ class OAuthTokenRepository $select = new Select(\Container::$dbConnection); $select->where('access_token', '=', $accessToken); - return $this->pdm->selectFromDb($select, OAuthToken::class); + return \Container::$persistentDataManager->selectFromDb($select, OAuthToken::class); } public function getAllExpired(): Generator @@ -41,6 +33,6 @@ class OAuthTokenRepository $select = new Select(\Container::$dbConnection); $select->where('expires', '<', (new DateTime())->format('Y-m-d H:i:s')); - yield from $this->pdm->selectMultipleFromDb($select, OAuthToken::class); + yield from \Container::$persistentDataManager->selectMultipleFromDb($select, OAuthToken::class); } } diff --git a/src/Repository/UserPasswordResetterRepository.php b/src/Repository/UserPasswordResetterRepository.php index c06c1fc..e026328 100644 --- a/src/Repository/UserPasswordResetterRepository.php +++ b/src/Repository/UserPasswordResetterRepository.php @@ -5,20 +5,12 @@ use Generator; use SokoWeb\Database\Query\Select; use RVR\PersistentData\Model\User; use RVR\PersistentData\Model\UserPasswordResetter; -use SokoWeb\PersistentData\PersistentDataManager; class UserPasswordResetterRepository { - private PersistentDataManager $pdm; - - public function __construct() - { - $this->pdm = new PersistentDataManager(); - } - public function getById(int $userConfirmationId): ?UserPasswordResetter { - return $this->pdm->selectFromDbById($userConfirmationId, UserPasswordResetter::class); + return \Container::$persistentDataManager->selectFromDbById($userConfirmationId, UserPasswordResetter::class); } public function getByToken(string $token): ?UserPasswordResetter @@ -26,7 +18,7 @@ class UserPasswordResetterRepository $select = new Select(\Container::$dbConnection); $select->where('token', '=', $token); - return $this->pdm->selectFromDb($select, UserPasswordResetter::class); + return \Container::$persistentDataManager->selectFromDb($select, UserPasswordResetter::class); } public function getByUser(User $user): ?UserPasswordResetter @@ -34,7 +26,7 @@ class UserPasswordResetterRepository $select = new Select(\Container::$dbConnection); $select->where('user_id', '=', $user->getId()); - return $this->pdm->selectFromDb($select, UserPasswordResetter::class); + return \Container::$persistentDataManager->selectFromDb($select, UserPasswordResetter::class); } public function getAllExpired(): Generator @@ -42,6 +34,6 @@ class UserPasswordResetterRepository $select = new Select(\Container::$dbConnection); $select->where('expires', '<', (new DateTime())->format('Y-m-d H:i:s')); - yield from $this->pdm->selectMultipleFromDb($select, UserPasswordResetter::class); + yield from \Container::$persistentDataManager->selectMultipleFromDb($select, UserPasswordResetter::class); } } diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 36d9482..6d48fa2 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -4,20 +4,12 @@ use Generator; use SokoWeb\Interfaces\Repository\IUserRepository; use SokoWeb\Database\Query\Select; use RVR\PersistentData\Model\User; -use SokoWeb\PersistentData\PersistentDataManager; class UserRepository implements IUserRepository { - private PersistentDataManager $pdm; - - public function __construct() - { - $this->pdm = new PersistentDataManager(); - } - public function getById(int $userId): ?User { - return $this->pdm->selectFromDbById($userId, User::class); + return \Container::$persistentDataManager->selectFromDbById($userId, User::class); } public function getByEmail(string $email): ?User @@ -25,7 +17,7 @@ class UserRepository implements IUserRepository $select = new Select(\Container::$dbConnection); $select->where('email', '=', $email); - return $this->pdm->selectFromDb($select, User::class); + return \Container::$persistentDataManager->selectFromDb($select, User::class); } public function getByUsername(string $username): ?User @@ -33,7 +25,7 @@ class UserRepository implements IUserRepository $select = new Select(\Container::$dbConnection); $select->where('username', '=', $username); - return $this->pdm->selectFromDb($select, User::class); + return \Container::$persistentDataManager->selectFromDb($select, User::class); } public function getByEmailOrUsername(string $emailOrUsername): ?User @@ -50,7 +42,7 @@ class UserRepository implements IUserRepository $select = new Select(\Container::$dbConnection); $select->where('google_sub', '=', $sub); - return $this->pdm->selectFromDb($select, User::class); + return \Container::$persistentDataManager->selectFromDb($select, User::class); } public function searchByName(string $name): Generator @@ -60,6 +52,6 @@ class UserRepository implements IUserRepository $select->orWhere('nickname', 'LIKE', '%' . $name . '%'); $select->limit(10); - yield from $this->pdm->selectMultipleFromDb($select, User::class); + yield from \Container::$persistentDataManager->selectMultipleFromDb($select, User::class); } } diff --git a/web.php b/web.php index 64d46f7..991180b 100644 --- a/web.php +++ b/web.php @@ -69,7 +69,7 @@ Container::$routeCollection->group('communities', function (RouteCollection $rou }); }); -Container::$sessionHandler = new DatabaseSessionHandler(); +Container::$sessionHandler = new DatabaseSessionHandler(Container::$dbConnection); session_set_save_handler(Container::$sessionHandler, true); session_start([