Skip to content

Commit 0055142

Browse files
committed
init
0 parents  commit 0055142

16 files changed

+415
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/vendor/
2+
3+
/composer.lock

composer.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "nuvolapl/oauth2-authenticator-bundle",
3+
"type": "library",
4+
"license": "proprietary",
5+
"minimum-stability": "dev",
6+
"prefer-stable": true,
7+
"require": {
8+
"php": "^8.2",
9+
"ext-json": "*",
10+
"lcobucci/jwt": "^5.0",
11+
"symfony/config": "^6.2",
12+
"symfony/http-client": "^6.2",
13+
"symfony/http-foundation": "^6.2",
14+
"symfony/http-kernel": "^6.2",
15+
"symfony/security-core": "^6.2"
16+
},
17+
"config": {
18+
"optimize-autoloader": true,
19+
"preferred-install": {
20+
"*": "dist"
21+
},
22+
"sort-packages": true
23+
},
24+
"autoload": {
25+
"psr-4": {
26+
"Nuvola\\OAuth2AuthenticatorBundle\\": "src/"
27+
}
28+
}
29+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Nuvola\OAuth2AuthenticatorBundle\DependencyInjection;
6+
7+
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
8+
use Symfony\Component\Config\Definition\ConfigurationInterface;
9+
10+
final class Configuration implements ConfigurationInterface
11+
{
12+
public function getConfigTreeBuilder()
13+
{
14+
$treeBuilder = new TreeBuilder('oauth2_authenticator');
15+
$treeBuilder->getRootNode()
16+
->children()
17+
->scalarNode('client_id')->isRequired()->cannotBeEmpty()->end()
18+
->scalarNode('client_secret')->isRequired()->cannotBeEmpty()->end()
19+
->arrayNode('itrospect')
20+
->isRequired()
21+
->children()
22+
->scalarNode('endpoint')->isRequired()->cannotBeEmpty()->end()
23+
->scalarNode('user_identifier_property')->defaultValue('sub')->end()
24+
->end()
25+
->end()
26+
->scalarNode('userinfo_endpoint')->cannotBeEmpty()->end()
27+
->end()
28+
;
29+
30+
return $treeBuilder;
31+
}
32+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Nuvola\OAuth2AuthenticatorBundle\DependencyInjection;
6+
7+
use Symfony\Component\Config\FileLocator;
8+
use Symfony\Component\DependencyInjection\ContainerBuilder;
9+
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
10+
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
11+
use Nuvola\OAuth2AuthenticatorBundle\Repository\UserRepository;
12+
use Nuvola\OAuth2AuthenticatorBundle\Service\IntrospectService;
13+
use Nuvola\OAuth2AuthenticatorBundle\Token\TokenFactory;
14+
15+
final class OAuth2AuthenticatorExtension extends ConfigurableExtension
16+
{
17+
public function loadInternal(array $mergedConfig, ContainerBuilder $container): void
18+
{
19+
$loader = new YamlFileLoader(
20+
$container,
21+
new FileLocator(__DIR__.'/../Resources/config')
22+
);
23+
24+
$loader->load('services.yaml');
25+
26+
$definition = $container->getDefinition(IntrospectService::class);
27+
$definition->replaceArgument(1, $mergedConfig['client_id']);
28+
$definition->replaceArgument(2, $mergedConfig['client_secret']);
29+
$definition->replaceArgument(3, $mergedConfig['itrospect']['endpoint']);
30+
31+
$definition = $container->getDefinition(TokenFactory::class);
32+
$definition->replaceArgument(0, $mergedConfig['itrospect']['user_identifier_property']);
33+
34+
$definition = $container->getDefinition(UserRepository::class);
35+
$definition->replaceArgument(1, $mergedConfig['userinfo_endpoint'] ?? '');
36+
}
37+
38+
public function getAlias(): string
39+
{
40+
return 'oauth2_authenticator';
41+
}
42+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Nuvola\OAuth2AuthenticatorBundle\EventDispatcher\Event;
6+
7+
use Symfony\Component\Security\Core\User\UserInterface;
8+
use Nuvola\OAuth2AuthenticatorBundle\Token\Token;
9+
10+
final class TokenVerifiedEvent
11+
{
12+
private ?UserInterface $user = null;
13+
14+
public function __construct(
15+
public readonly Token $token,
16+
) {
17+
}
18+
19+
public function getUser(): ?UserInterface
20+
{
21+
return $this->user;
22+
}
23+
24+
public function isUserSet(): bool
25+
{
26+
return $this->user instanceof UserInterface;
27+
}
28+
29+
public function setUser(UserInterface $user): void
30+
{
31+
$this->user = $user;
32+
}
33+
}

src/OAuth2AuthenticatorBundle.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Nuvola\OAuth2AuthenticatorBundle;
6+
7+
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
8+
use Symfony\Component\HttpKernel\Bundle\Bundle;
9+
use Nuvola\OAuth2AuthenticatorBundle\DependencyInjection\OAuth2AuthenticatorExtension;
10+
11+
final class OAuth2AuthenticatorBundle extends Bundle
12+
{
13+
public function getContainerExtension(): ?ExtensionInterface
14+
{
15+
return new OAuth2AuthenticatorExtension();
16+
}
17+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Nuvola\OAuth2AuthenticatorBundle\Repository;
6+
7+
interface AuthBearerAwareInterface
8+
{
9+
public function setAuthBearer(string $token);
10+
}

src/Repository/UserRepository.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Nuvola\OAuth2AuthenticatorBundle\Repository;
6+
7+
use Symfony\Component\HttpClient\HttpOptions;
8+
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
9+
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
10+
use Symfony\Contracts\HttpClient\HttpClientInterface;
11+
12+
final class UserRepository implements UserRepositoryInterface, AuthBearerAwareInterface
13+
{
14+
public function __construct(
15+
private HttpClientInterface $client,
16+
private readonly string $endpoint,
17+
) {
18+
}
19+
20+
public function setAuthBearer(string $token): void
21+
{
22+
$options = new HttpOptions();
23+
$options->setAuthBearer($token);
24+
25+
$this->client = $this->client->withOptions($options->toArray());
26+
}
27+
28+
public function getUserInfo(): array
29+
{
30+
try {
31+
return $this->client->request('GET', $this->endpoint)->toArray();
32+
} catch (ExceptionInterface|TransportExceptionInterface $e) {
33+
throw new \RuntimeException($e->getMessage(), 0, $e); // TODO: custom exception
34+
}
35+
}
36+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Nuvola\OAuth2AuthenticatorBundle\Repository;
6+
7+
interface UserRepositoryInterface
8+
{
9+
public function getUserInfo(): array;
10+
}

src/Resources/config/services.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
services:
2+
_defaults:
3+
autowire: false
4+
autoconfigure: false
5+
6+
nuvola.http_client:
7+
class: Symfony\Contracts\HttpClient\HttpClientInterface
8+
factory: [ 'Symfony\Component\HttpClient\HttpClient', 'create' ]
9+
10+
Nuvola\OAuth2AuthenticatorBundle\Token\TokenFactory:
11+
- ~ # compiled
12+
13+
Nuvola\OAuth2AuthenticatorBundle\Token\TokenFactoryInterface: '@Nuvola\OAuth2AuthenticatorBundle\Token\TokenFactory'
14+
15+
Nuvola\OAuth2AuthenticatorBundle\Service\IntrospectService:
16+
- '@nuvola.http_client'
17+
- ~ # compiled
18+
- ~ # compiled
19+
- ~ # compiled
20+
- '@Nuvola\OAuth2AuthenticatorBundle\Token\TokenFactoryInterface'
21+
22+
Nuvola\OAuth2AuthenticatorBundle\Service\IntrospectServiceInterface: '@Nuvola\OAuth2AuthenticatorBundle\Service\IntrospectService'
23+
24+
Nuvola\OAuth2AuthenticatorBundle\Security\OAuth2Authenticator:
25+
- '@Nuvola\OAuth2AuthenticatorBundle\Service\IntrospectServiceInterface'
26+
- '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
27+
28+
Nuvola\OAuth2AuthenticatorBundle\Repository\UserRepository:
29+
- '@nuvola.http_client'
30+
- ~ # compiled
31+
32+
Nuvola\OAuth2AuthenticatorBundle\Repository\UserRepositoryInterface: '@Nuvola\OAuth2AuthenticatorBundle\Repository\UserRepository'

0 commit comments

Comments
 (0)