Skip to content

Commit

Permalink
Configuration, Authentificator
Browse files Browse the repository at this point in the history
  • Loading branch information
haskel committed Aug 11, 2023
1 parent 400ce4c commit 2998814
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 46 deletions.
2 changes: 1 addition & 1 deletion ArgumentResolver/GrpcRequestValueResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): Generator
return;
}

[$protocol, $encoding] = explode('+', $contentType, 2);
[$protocol, $encoding] = explode('+', $contentType, 2) + [null, null];

if ($protocol === ProtocolContentType::GRPC) {
throw new BaseGrpcException('Can\'t process common gRPC. Only gRPC-Web is supported');
Expand Down
43 changes: 24 additions & 19 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,38 @@ class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('grpc');
$treeBuilder = new TreeBuilder('grpc_web');

$treeBuilder->getRootNode()
$rootNode = $treeBuilder->getRootNode();

$rootNode
->children()
->scalarNode('proto_namespace')->end()
->scalarNode('response_type_attribute_name')->end()
->arrayNode('exception_code_map')->defaultValue([])
->arrayPrototype()
->children()
->scalarNode('exception')->end()
->scalarNode('code')->end()
->end();

$rootNode
->children()
->arrayNode('exception_code_map')
->useAttributeAsKey('exception') // Use exception names as keys
->prototype('scalar') // Expect a scalar value for each key
->end()
->end()
->arrayNode('security')->defaultValue([])
->arrayPrototype()
->children()
->scalarNode('success_response_builder')->end()
->scalarNode('failure_response_builder')->end()
->scalarNode('identifier_field')->end()
->scalarNode('password_field')->end()
->scalarNode('jwt_cookie_builder')->end()
->end()
->end();

$rootNode
->children()
->arrayNode('security')
->children()
->scalarNode('success_response_builder')->defaultValue(null)->end()
->scalarNode('failure_response_builder')->defaultValue(null)->end()
->scalarNode('sign_in_request_class')->end()
->scalarNode('identifier_field')->defaultValue(null)->end()
->scalarNode('password_field')->defaultValue(null)->end()
->scalarNode('jwt_cookie_builder')->defaultValue(null)->end()
->end()
->end()
->end()
->end();
;
->end();

return $treeBuilder;
}
Expand Down
30 changes: 30 additions & 0 deletions DependencyInjection/GrpcWebExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Definition;

class GrpcWebExtension extends Extension
{
Expand All @@ -35,5 +36,34 @@ static function (
$definition->addTag('controller.service_arguments');
}
);

$authentificator = $container->getDefinition('haskel.grpc_web.security.grpc_login_authenticator');

if (!isset($config['security']['sign_in_request_class'])) {
throw new \InvalidArgumentException('You must provide a sign in request class');
}
$authentificator->setArgument('$signInRequestClass', $config['security']['sign_in_request_class']);

if (isset($config['security']['identifier_field'])) {
$authentificator->setArgument('$identifierField', $config['security']['identifier_field']);
}
if (isset($config['security']['password_field'])) {
$authentificator->setArgument('$passwordField', $config['security']['password_field']);
}
if (isset($config['security']['jwt_cookie_builder'])) {
$jwtCookieBuilder = new Definition($config['security']['jwt_cookie_builder']);
$jwtCookieBuilder->setAutowired(true);
$authentificator->setArgument('$jwtCookieBuilder', $jwtCookieBuilder);
}
if (isset($config['security']['success_response_builder'])) {
$successResponseBuilder = new Definition($config['security']['success_response_builder']);
$successResponseBuilder->setAutowired(true);
$authentificator->setArgument('$successResponseBuilder', $successResponseBuilder);
}
if (isset($config['security']['failure_response_builder'])) {
$failureResponseBuilder = new Definition($config['security']['failure_response_builder']);
$failureResponseBuilder->setAutowired(true);
$authentificator->setArgument('$failureResponseBuilder', $failureResponseBuilder);
}
}
}
19 changes: 19 additions & 0 deletions GrpcBundle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Haskel\GrpcWebBundle;

use Haskel\GrpcWebBundle\DependencyInjection\RouterCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class GrpcBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);

$container->addCompilerPass(new RouterCompilerPass());
}
}
2 changes: 1 addition & 1 deletion GrpcWebBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

class GrpcWebBundle extends Bundle
{
public function build(ContainerBuilder $container)
public function build(ContainerBuilder $container): void
{
parent::build($container);

Expand Down
41 changes: 41 additions & 0 deletions Resources/config/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
services:
haskel.grpc_web.argument_resolver.grpc_request_value_resolver:
class: 'Haskel\GrpcWebBundle\ArgumentResolver\GrpcRequestValueResolver'
tags:
- { name: 'controller.argument_value_resolver', priority: 0 }

haskel.grpc_web.listener.response_listener:
class: 'Haskel\GrpcWebBundle\Listener\ResponseListener'
arguments:
$logger: '@logger'
tags:
- { name: 'kernel.event_listener', event: 'kernel.view', method: 'onKernelView', priority: 0 }
- { name: 'kernel.event_listener', event: 'kernel.exception', method: 'onKernelException', priority: 0 }

haskel.grpc_web.listener.controller_listener:
class: 'Haskel\GrpcWebBundle\Listener\ControllerListener'
tags:
- { name: 'kernel.event_listener', event: 'kernel.controller', method: 'onKernelController', priority: 0 }

haskel.grpc_web.routing.grpc_service_route_loader:
class: 'Haskel\GrpcWebBundle\Routing\GrpcServiceRouteLoader'
tags:
- { name: 'routing.loader' }
arguments:
$locator: '@file_locator'
$loader: '@routing.loader.annotation'

haskel.grpc_web.default_jwt_cookie_builder:
class: 'Haskel\GrpcWebBundle\Security\DefaultJwtCookieBuilder'
arguments:
$jwtManager: '@lexik_jwt_authentication.jwt_manager'

haskel.grpc_web.security.grpc_login_authenticator:
class: 'Haskel\GrpcWebBundle\Security\GrpcLoginAuthenticator'
arguments:
$userProvider: '@security.user.provider.concrete.database_user_provider'
$dispatcher: '@event_dispatcher'
$jwtCookieBuilder: '@haskel.grpc_web.default_jwt_cookie_builder'
tags:
- { name: 'security.authenticator' }

20 changes: 0 additions & 20 deletions Resources/config/services.yml

This file was deleted.

2 changes: 1 addition & 1 deletion Routing/GrpcServiceRouteLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,6 @@ public function load($path, string $type = null): RouteCollection

public function supports($resource, string $type = null): bool
{
return 'grpc' === $type;
return 'grpc-web' === $type;
}
}
9 changes: 5 additions & 4 deletions Security/GrpcLoginAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Lexik\Bundle\JWTAuthenticationBundle\Events;
use LogicException;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
Expand Down Expand Up @@ -101,7 +102,7 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token,

$jwtCookie = $this->jwtCookieBuilder->build($user);

$response = $this->buildSuccessResponse($user, $request);
$response = $this->buildSuccessResponse($user, $request, $jwtCookie);
$response->headers->setCookie($jwtCookie);

$this->dispatcher->dispatch(
Expand All @@ -112,18 +113,18 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token,
return $response;
}

protected function buildSuccessResponse(UserInterface $user, Request $request): GrpcResponse
protected function buildSuccessResponse(UserInterface $user, Request $request, Cookie $jwtCookie): GrpcResponse
{
if (is_callable($this->successResponseBuilder)) {
return call_user_func($this->successResponseBuilder, $user, $request);
return call_user_func($this->successResponseBuilder, $user, $request, $jwtCookie);
}

if ($this->successResponseBuilder instanceof GrpcResponse) {
return $this->successResponseBuilder;
}

if ($this->successResponseBuilder instanceof GrpcResponseBuilderInterface) {
return $this->successResponseBuilder->build($user, $request);
return $this->successResponseBuilder->build($user, $request, $jwtCookie);
}

return new GrpcResponse(new GpbEmpty(), StatusCode::Ok);
Expand Down
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
### gRPC-Web Bundle

0 comments on commit 2998814

Please sign in to comment.