feature/RVRNEXT-2-implement-login-to-old-rvr #6
							
								
								
									
										124
									
								
								src/Controller/OAuthLoginController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/Controller/OAuthLoginController.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,124 @@
 | 
			
		||||
<?php namespace RVR\Controller;
 | 
			
		||||
 | 
			
		||||
use DateTime;
 | 
			
		||||
use Firebase\JWT\JWT;
 | 
			
		||||
use RVR\PersistentData\Model\OAuthToken;
 | 
			
		||||
use RVR\Repository\OAuthTokenRepository;
 | 
			
		||||
use RVR\Repository\UserRepository;
 | 
			
		||||
use RVR\PersistentData\Model\User;
 | 
			
		||||
use SokoWeb\Interfaces\Request\IRequest;
 | 
			
		||||
use SokoWeb\Interfaces\Response\IContent;
 | 
			
		||||
use SokoWeb\Interfaces\Response\IRedirect;
 | 
			
		||||
use SokoWeb\Response\Redirect;
 | 
			
		||||
use SokoWeb\PersistentData\PersistentDataManager;
 | 
			
		||||
use SokoWeb\Response\HtmlContent;
 | 
			
		||||
use SokoWeb\Response\JsonContent;
 | 
			
		||||
 | 
			
		||||
class OAuthLoginController
 | 
			
		||||
{
 | 
			
		||||
    private IRequest $request;
 | 
			
		||||
 | 
			
		||||
    private PersistentDataManager $pdm;
 | 
			
		||||
 | 
			
		||||
    public function __construct(IRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $this->request = $request;
 | 
			
		||||
        $this->pdm = new PersistentDataManager();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function startOauth()
 | 
			
		||||
    {
 | 
			
		||||
        $redirectUri = $this->request->query('redirect_uri');
 | 
			
		||||
        $state = $this->request->query('state');
 | 
			
		||||
        $nonce = $this->request->query('nonce');
 | 
			
		||||
 | 
			
		||||
        if (!$redirectUri || !$state) {
 | 
			
		||||
            return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->request->session()->set('oauth_state', [
 | 
			
		||||
            'redirect_uri' => $redirectUri,
 | 
			
		||||
            'state' => $state,
 | 
			
		||||
            'nonce' => $nonce === null ? '' : $nonce
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $this->request->session()->set('redirect_after_login', \Container::$routeCollection->getRoute('oauth-finish')->generateLink());
 | 
			
		||||
 | 
			
		||||
        return new Redirect(\Container::$routeCollection->getRoute('login')->generateLink(), IRedirect::TEMPORARY);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function finishOauth()
 | 
			
		||||
    {
 | 
			
		||||
        $oauthState = $this->request->session()->get('oauth_state');
 | 
			
		||||
        if ($oauthState === null) {
 | 
			
		||||
            return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->request->session()->delete('oauth_state');
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @var ?User $user
 | 
			
		||||
         */
 | 
			
		||||
        $user = $this->request->user();
 | 
			
		||||
        if ($user === null) {
 | 
			
		||||
            return new HtmlContent('oauth/oauth_error', ['error' => 'You are not logged in. Please start authentication again.']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $code = bin2hex(random_bytes(16));
 | 
			
		||||
 | 
			
		||||
        $token = new OAuthToken();
 | 
			
		||||
        $token->setNonce($oauthState['nonce']);
 | 
			
		||||
        $token->setUser($user);
 | 
			
		||||
        $token->setCode($code);
 | 
			
		||||
        $token->setCreatedDate(new DateTime());
 | 
			
		||||
        $token->setExpiresDate(new DateTime('+5 minutes'));
 | 
			
		||||
        $this->pdm->saveToDb($token);
 | 
			
		||||
 | 
			
		||||
        $redirectUri = $oauthState['redirect_uri'];
 | 
			
		||||
        $additionalUriParams = [
 | 
			
		||||
            'state' => $oauthState['state'],
 | 
			
		||||
            'code' => $code
 | 
			
		||||
        ];
 | 
			
		||||
        $and = (strpos($redirectUri, '?') !== false) ? '&' : '?';
 | 
			
		||||
        $finalRedirectUri = $redirectUri . $and .  http_build_query($additionalUriParams);
 | 
			
		||||
 | 
			
		||||
        return new Redirect($finalRedirectUri, IRedirect::TEMPORARY);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getToken(): ?IContent
 | 
			
		||||
    {
 | 
			
		||||
        $oAuthTokenRepository = new OAuthTokenRepository();
 | 
			
		||||
        $userRepository = new UserRepository();
 | 
			
		||||
        $token = $oAuthTokenRepository->getByCode($this->request->query('code'));
 | 
			
		||||
 | 
			
		||||
        if ($token === null || $token->getExpiresDate() < new DateTime()) {
 | 
			
		||||
            return new JsonContent([
 | 
			
		||||
                'error' => 'The provided code is invalid.'
 | 
			
		||||
            ]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $user = $userRepository->getById($token->getUserId());
 | 
			
		||||
 | 
			
		||||
        $payload = [
 | 
			
		||||
            'iss' => $_ENV['APP_URL'],
 | 
			
		||||
            'iat' => (int)$token->getCreatedDate()->format('U'),
 | 
			
		||||
            'nbf' => (int)$token->getCreatedDate()->format('U'),
 | 
			
		||||
            'exp' => (int)$token->getExpiresDate()->format('U'),
 | 
			
		||||
            'nonce' => $token->getNonce(),
 | 
			
		||||
            'sub' => $user->getId(),
 | 
			
		||||
            'email' => $user->getEmail()
 | 
			
		||||
        ];
 | 
			
		||||
        $privateKey = file_get_contents(ROOT . '/' . $_ENV['JWT_RSA_PRIVATE_KEY']);
 | 
			
		||||
        $jwt = JWT::encode($payload, $privateKey, 'RS256');
 | 
			
		||||
 | 
			
		||||
        return new JsonContent([
 | 
			
		||||
            'id_token' => $jwt
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getJwtPublicKey(): IContent
 | 
			
		||||
    {
 | 
			
		||||
        $publicKey = file_get_contents(ROOT . '/' . $_ENV['JWT_RSA_PUBLIC_KEY']);
 | 
			
		||||
        return new JsonContent(['pubkey' => $publicKey]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								views/oauth/oauth_error.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								views/oauth/oauth_error.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
@extends(templates/layout_normal)
 | 
			
		||||
 | 
			
		||||
@section(main)
 | 
			
		||||
    <h2>OAuth error</h2>
 | 
			
		||||
    <div class="box">
 | 
			
		||||
        <p class="error justify"><?= $error ?></p>
 | 
			
		||||
    </div>
 | 
			
		||||
@endsection
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user