<?php
namespace App\Controller\BackendBundle;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use App\BackendBundle\Helper\OAuth2Helper;
use App\BackendBundle\Helper\SiteTitleHelper;
use App\BackendBundle\Security\UserManager\UserNormalProvider;
use App\Entity\User;
class OAuth2Controller extends AbstractController {
private AuthenticationManagerInterface $authManager;
private CsrfTokenManagerInterface $csrfTokenManager;
private EntityManagerInterface $em;
private OAuth2Helper $oauth2Helper;
private TokenStorageInterface $tokenStorage;
private UserNormalProvider $userNormalProvider;
private UserPasswordHasherInterface $userPasswordHasher;
private SessionInterface $session;
private SiteTitleHelper $siteTitleHelper;
private $sessionEmail = 'oauth2_session_email';
/* needs to match with \App\BackendBundle\Security\Authenticator\OAuth2Authenticator */
private $sessionOAuthKey = 'oauth2_session_username';
public function __construct(CsrfTokenManagerInterface $csrfTokenManager, EntityManagerInterface $em,
SiteTitleHelper $sitehelper, UserNormalProvider $userNormalProvider, UserPasswordHasherInterface $userPasswordHasher,
AuthenticationManagerInterface $authManager, TokenStorageInterface $tokenStorage, OAuth2Helper $oauth2Helper,
SessionInterface $session) {
$this->authManager = $authManager;
$this->csrfTokenManager = $csrfTokenManager;
$this->em = $em;
$this->oauth2Helper = $oauth2Helper;
$this->session = $session;
$this->siteTitleHelper = $sitehelper;
$this->tokenStorage = $tokenStorage;
$this->userNormalProvider = $userNormalProvider;
$this->userPasswordHasher = $userPasswordHasher;
}
/**
* @return \Symfony\Component\HttpFoundation\Response
* @Route("/oauthlogin", name="oauth2_login", defaults={"title": "Berufsreise Login", "description": "Berufsreise Login"})
*/
public function oauthLoginAction(Request $request, Session $session) {
$this->siteTitleHelper->setTitleDescription($request);
$username = '';
if ($session->has($this->sessionEmail)) {
$username = $session->get($this->sessionEmail, '');
}
$error = false;
if ($session->has(Security::AUTHENTICATION_ERROR)) {
$error = true;
}
return $this->render('@frontend/oauth2/login.html.twig', array(
'username' => $username,
'error' => $error
));
}
private function processForm(Request $request) {
/* get data from submitted form */
$csrfToken = $request->request->get("_csrf_token");
$username = $request->request->get('username');
$password = $request->request->get('password');
$isCsrfTokenValid = $this->isCsrfTokenValid('oauth2_authenticate', $csrfToken);
if (!$isCsrfTokenValid) {
return null;
}
/* try to get user from submitted data */
$user = $this->processUserData($username, $password);
if (empty($user)) {
return null;
}
$this->session->set('symfony_username', $user->getUsername());
$parameters = $request->query->all();
$url = $this->generateUrl('oauth2_authorize', $parameters);
return new RedirectResponse($url);
}
private function processUserData($username, $password) {
/* @var $user User */
$user = $this->userNormalProvider->loadUserByUsername($username);
if (empty($user)) {
return null;
}
if (!$user->getIsActive()) {
return null;
}
$isPasswordValid = $this->userPasswordHasher->isPasswordValid($user, $password);
if (!$isPasswordValid) {
return null;
}
return $user;
}
/**
* @return \Symfony\Component\HttpFoundation\Response
* @Route("/oauthlogout", name="oauth2_logout", defaults={"title": "", "description": ""})
*/
public function oauthLogoutAction(Request $request) {
$user = $this->getUser();
if (empty($user)) {
return $this->getLogoutRedirect($request);
}
$userName = $user->getUsername();
$this->oauth2Helper->revokeTokens($userName);
$this->session->remove($this->sessionOAuthKey);
return $this->getLogoutRedirect($request);
}
private function getLogoutRedirect(Request $request) {
$redirectURI = $request->query->get('post_logout_redirect_uri');
if (empty($redirectURI)) {
$redirectURI = 'https://www.berufsreise.at';
}
$url = urldecode($redirectURI);
return $this->redirect($url);
}
}