some logic

This commit is contained in:
Diogo Peralta Cordeiro 2022-01-16 17:44:21 +00:00
parent 29f53bb698
commit 4ad1de2616
Signed by: diogo
GPG Key ID: 18D2D35001FBFAB0
5 changed files with 55 additions and 48 deletions

View File

@ -22,6 +22,7 @@ security:
security: false security: false
oauth_token: oauth_token:
pattern: ^/oauth/(token|authorize)$ pattern: ^/oauth/(token|authorize)$
provider: local_user
security: false security: false
api_apps: api_apps:
pattern: ^/api/v1/apps$ pattern: ^/api/v1/apps$

View File

@ -1,3 +1,7 @@
oauth2: oauth2_authorization_code:
resource: '@TrikoderOAuth2Bundle/Resources/config/routes.xml' controller: Trikoder\Bundle\OAuth2Bundle\Controller\AuthorizationController::indexAction
prefix: '/oauth' path: '/oauth/authorize'
oauth2_token:
controller: Trikoder\Bundle\OAuth2Bundle\Controller\TokenController::indexAction
path: '/oauth/token'

View File

@ -52,6 +52,7 @@ use App\Kernel;
use App\Security\EmailVerifier; use App\Security\EmailVerifier;
use App\Util\Common; use App\Util\Common;
use App\Util\Exception\ConfigurationException; use App\Util\Exception\ConfigurationException;
use App\Util\Exception\NoLoggedInUser;
use App\Util\Formatting; use App\Util\Formatting;
use App\Util\HTML; use App\Util\HTML;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
@ -65,6 +66,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
@ -233,7 +235,7 @@ class GNUsocial implements EventSubscriberInterface
public static function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void public static function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
{ {
// Overriding doesn't work as we want, overrides the top-most key, do it manually // Overriding doesn't work as we want, overrides the top-most key, do it manually
$local_file = INSTALLDIR . '/social.local.yaml'; $local_file = INSTALLDIR . \DIRECTORY_SEPARATOR . 'social.local.yaml';
if (!file_exists($local_file)) { if (!file_exists($local_file)) {
file_put_contents($local_file, "parameters:\n locals:\n gnusocial:\n"); file_put_contents($local_file, "parameters:\n locals:\n gnusocial:\n");
} }
@ -289,19 +291,19 @@ class GNUsocial implements EventSubscriberInterface
$event->setUser($user); $event->setUser($user);
} }
public function authRequestResolve(AuthorizationRequestResolveEvent $event): void public function authorizeRequestResolve(AuthorizationRequestResolveEvent $event): void
{ {
$request = $this->request; $request = $this->request;
// only handle post requests for logged-in users: try {
$user = Common::ensureLoggedIn();
// get requests will be intercepted and shown the login form // get requests will be intercepted and shown the login form
// other verbs we will handle as an authorization denied // other verbs we will handle as an authorization denied
// and this implementation ensures a user is set at this point already // and this implementation ensures a user is set at this point already
if ($request->getMethod() !== 'POST' && \is_null($event->getUser())) { if ($request->getMethod() !== 'POST') {
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_DENIED); $event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_DENIED);
return; return;
} } else {
if (!$request->request->has('action')) { if (!$request->request->has('action')) {
// 1. successful login, goes to grant page // 1. successful login, goes to grant page
$content = $this->twig->render('security/grant.html.twig', [ $content = $this->twig->render('security/grant.html.twig', [
@ -313,29 +315,27 @@ class GNUsocial implements EventSubscriberInterface
'email' => $request->request->get('email'), 'email' => $request->request->get('email'),
'password' => $request->request->get('password'), 'password' => $request->request->get('password'),
]); ]);
$response = new Response(200, [], $content); $response = new Response(200, [], $content);
$event->setResponse($response); $event->setResponse($response);
} else { } else {
// 2. grant operation, either grants or denies // 2. grant operation, either grants or denies
if ($request->request->get('action') == OAuth2Grants::AUTHORIZATION_CODE) { if ($request->request->get('action') === OAuth2Grants::AUTHORIZATION_CODE) {
$event->setUser($user);
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED); $event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
} else { } else {
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_DENIED); $event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_DENIED);
} }
} }
}
if (\is_null($event->getUser())) { // Whoops!
throw new BadRequestException();
} catch (NoLoggedInUser) {
$event->setResponse(new Response(302, [ $event->setResponse(new Response(302, [
'Location' => Router::url('security_login', [ 'Location' => Router::url('security_login', [
'returnUrl' => $request->getUri(), 'returnUrl' => $request->getUri(),
]), ]),
])); ]));
return;
} }
$event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED);
} }
/** /**
@ -348,7 +348,7 @@ class GNUsocial implements EventSubscriberInterface
KernelEvents::REQUEST => 'onKernelRequest', KernelEvents::REQUEST => 'onKernelRequest',
'console.command' => 'onCommand', 'console.command' => 'onCommand',
OAuth2Events::USER_RESOLVE => 'userResolve', OAuth2Events::USER_RESOLVE => 'userResolve',
OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE => 'authRequestResolve', OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE => 'authorizeRequestResolve',
]; ];
} }
} }

View File

@ -158,8 +158,7 @@ class Authenticator extends AbstractFormLoginAuthenticator implements Authentica
); );
// TODO: Fix the Open Redirect security flaw here. // TODO: Fix the Open Redirect security flaw here.
$targetPath = $request->request->get('returnUrl'); $targetPath = $request->query->get('returnUrl');
if ($targetPath ??= $this->getTargetPath($request->getSession(), $providerKey)) { if ($targetPath ??= $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath); return new RedirectResponse($targetPath);
} }

View File

@ -135,17 +135,20 @@ abstract class Common
public static function userNickname(): ?string public static function userNickname(): ?string
{ {
return self::ensureLoggedIn()->getNickname(); return self::ensureLoggedIn()?->getNickname();
} }
public static function userId(): ?int public static function userId(): ?int
{ {
return self::ensureLoggedIn()->getId(); return self::ensureLoggedIn()?->getId();
} }
/**
* @throws NoLoggedInUser
*/
public static function ensureLoggedIn(): LocalUser public static function ensureLoggedIn(): LocalUser
{ {
if (($user = self::user()) == null) { if (\is_null($user = self::user())) {
throw new NoLoggedInUser(); throw new NoLoggedInUser();
// TODO Maybe redirect to login page and back // TODO Maybe redirect to login page and back
} else { } else {
@ -160,7 +163,7 @@ abstract class Common
*/ */
public static function isLoggedIn(): bool public static function isLoggedIn(): bool
{ {
return self::user() != null; return !\is_null(self::user());
} }
/** /**
@ -337,6 +340,6 @@ abstract class Common
public static function base64url_decode(string $data): string public static function base64url_decode(string $data): string
{ {
return base64_decode(str_pad(strtr(strtr($data, '_', '/'), '-', '+'), \mb_strlen($data) % 4, '=', \STR_PAD_RIGHT)); return base64_decode(str_pad(strtr(strtr($data, '_', '/'), '-', '+'), mb_strlen($data) % 4, '=', \STR_PAD_RIGHT));
} }
} }