├── .github
└── workflows
│ └── php.yml
├── .gitignore
├── .php-cs-fixer.cache
├── .php_cs-fixer.php
├── Command
├── CleanCommand.php
└── CreateClientCommand.php
├── Controller
├── AuthorizeController.php
└── TokenController.php
├── DependencyInjection
├── Compiler
│ ├── GrantExtensionsCompilerPass.php
│ └── RequestStackCompilerPass.php
├── Configuration.php
├── FOSOAuthServerExtension.php
└── Security
│ └── Factory
│ └── OAuthFactory.php
├── Document
├── AccessToken.php
├── AccessTokenManager.php
├── AuthCode.php
├── AuthCodeManager.php
├── Client.php
├── ClientManager.php
├── RefreshToken.php
├── RefreshTokenManager.php
└── TokenManager.php
├── Entity
├── AccessToken.php
├── AccessTokenManager.php
├── AuthCode.php
├── AuthCodeManager.php
├── Client.php
├── ClientManager.php
├── RefreshToken.php
├── RefreshTokenManager.php
└── TokenManager.php
├── Event
└── OAuthEvent.php
├── FOSOAuthServerBundle.php
├── Form
├── Handler
│ └── AuthorizeFormHandler.php
├── Model
│ └── Authorize.php
└── Type
│ └── AuthorizeFormType.php
├── Makefile
├── Model
├── AccessToken.php
├── AccessTokenInterface.php
├── AccessTokenManagerInterface.php
├── AuthCode.php
├── AuthCodeInterface.php
├── AuthCodeManager.php
├── AuthCodeManagerInterface.php
├── Client.php
├── ClientInterface.php
├── ClientManager.php
├── ClientManagerInterface.php
├── RefreshToken.php
├── RefreshTokenInterface.php
├── RefreshTokenManagerInterface.php
├── Token.php
├── TokenInterface.php
├── TokenManager.php
└── TokenManagerInterface.php
├── README.md
├── Resources
├── config
│ ├── authorize.xml
│ ├── couchdb.xml
│ ├── doctrine
│ │ ├── AccessToken.couchdb.xml
│ │ ├── AccessToken.mongodb.xml
│ │ ├── AccessToken.orm.xml
│ │ ├── AuthCode.couchdb.xml
│ │ ├── AuthCode.mongodb.xml
│ │ ├── AuthCode.orm.xml
│ │ ├── Client.couchdb.xml
│ │ ├── Client.mongodb.xml
│ │ ├── Client.orm.xml
│ │ ├── RefreshToken.couchdb.xml
│ │ ├── RefreshToken.mongodb.xml
│ │ └── RefreshToken.orm.xml
│ ├── mongodb.xml
│ ├── oauth.xml
│ ├── orm.xml
│ ├── routing
│ │ ├── authorize.xml
│ │ └── token.xml
│ ├── security.xml
│ └── validation.xml
├── doc
│ ├── a_note_about_security.md
│ ├── adding_grant_extensions.md
│ ├── configuration_reference.md
│ ├── custom_db_driver.md
│ ├── dealing_with_scopes.md
│ ├── extending_the_authorization_page.md
│ ├── extending_the_model.md
│ ├── index.md
│ └── the_oauth_event_class.md
├── meta
│ └── LICENSE
├── translations
│ ├── FOSOAuthServerBundle.de.yml
│ ├── FOSOAuthServerBundle.en.yml
│ ├── FOSOAuthServerBundle.fr.yml
│ └── FOSOAuthServerBundle.sl.yml
└── views
│ ├── Authorize
│ ├── authorize.html.twig
│ └── authorize_content.html.twig
│ ├── form.html.twig
│ └── layout.html.twig
├── Security
├── Authenticator
│ ├── OAuth2Passport.php
│ ├── Oauth2Authenticator.php
│ ├── Passport
│ │ └── Badge
│ │ │ └── AccessTokenBadge.php
│ └── Token
│ │ └── OAuthToken.php
└── EntryPoint
│ └── OAuthEntryPoint.php
├── Storage
├── GrantExtensionDispatcherInterface.php
├── GrantExtensionInterface.php
└── OAuthStorage.php
├── Tests
├── Command
│ ├── CleanCommandTest.php
│ └── CreateClientCommandTest.php
├── Controller
│ ├── AuthorizeControllerTest.php
│ └── TokenControllerTest.php
├── DependencyInjection
│ ├── Compiler
│ │ ├── GrantExtensionsCompilerPassTest.php
│ │ └── RequestStackCompilerPassTest.php
│ ├── ConfigurationTest.php
│ ├── FOSOAuthServerExtensionTest.php
│ └── Security
│ │ └── Factory
│ │ └── OAuthFactoryTest.php
├── Document
│ ├── AuthCodeManagerTest.php
│ ├── ClientManagerTest.php
│ └── TokenManagerTest.php
├── Entity
│ ├── AuthCodeManagerTest.php
│ ├── ClientManagerTest.php
│ └── TokenManagerTest.php
├── Event
│ └── OAuthEventTest.php
├── FOSOAuthServerBundleTest.php
├── Form
│ ├── Handler
│ │ └── AuthorizeFormHandlerTest.php
│ └── Type
│ │ └── AuthorizeFormTypeTest.php
├── Functional
│ ├── AppKernel.php
│ ├── BootTest.php
│ ├── TestBundle
│ │ ├── Entity
│ │ │ ├── AccessToken.php
│ │ │ ├── AuthCode.php
│ │ │ ├── Client.php
│ │ │ ├── RefreshToken.php
│ │ │ └── User.php
│ │ └── TestBundle.php
│ ├── TestCase.php
│ └── config
│ │ ├── config.yml
│ │ ├── config_orm.yml
│ │ └── routing.yml
├── Model
│ ├── ClientTest.php
│ └── TokenTest.php
├── Security
│ ├── Authenticator
│ │ ├── Oauth2AuthenticatorTest.php
│ │ └── Passport
│ │ │ └── Badge
│ │ │ └── AccessTokenBadgeTest.php
│ └── EntryPoint
│ │ └── OAuthEntryPointTest.php
├── Storage
│ └── OAuthStorageTest.php
├── Util
│ └── RandomTest.php
└── bootstrap.php
├── UPGRADE.md
├── Util
├── LegacyFormHelper.php
└── Random.php
├── composer.json
├── phpstan.neon
└── phpunit.xml.dist
/.github/workflows/php.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | push:
5 | branches: [ "5.1" ]
6 | pull_request:
7 | branches: [ "5.1" ]
8 |
9 | permissions:
10 | contents: read
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v4
19 |
20 | - name: Validate composer.json and composer.lock
21 | run: composer validate --strict
22 |
23 | - name: Cache Composer packages
24 | id: composer-cache
25 | uses: actions/cache@v3
26 | with:
27 | path: vendor
28 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
29 | restore-keys: |
30 | ${{ runner.os }}-php-
31 |
32 | - name: Install dependencies
33 | run: composer install --prefer-dist --no-progress
34 |
35 | # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit"
36 | # Docs: https://getcomposer.org/doc/articles/scripts.md
37 |
38 | - name: Run test suite
39 | uses: php-actions/phpunit@v3
40 | env:
41 | XDEBUG_MODE: coverage
42 | with:
43 | php_extensions: "xdebug"
44 | coverage_clover: "coverage.xml"
45 | args: --log-junit junit.xml
46 |
47 | - name: Upload coverage to Codecov
48 | uses: codecov/codecov-action@v5
49 | env:
50 | CODECOV_TOKEN: ${{ secrets.CODECOV_ORG_TOKEN }}
51 |
52 | - name: Upload test results to Codecov
53 | if: ${{ !cancelled() }}
54 | uses: codecov/test-results-action@v1
55 | with:
56 | token: ${{ secrets.CODECOV_ORG_TOKEN }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .phpunit.cache/
2 | phpunit.xml
3 | Tests/autoload.php
4 | reports/
5 | vendor/
6 | composer.lock
7 | .php-cs-fixer.cache
8 | .phpunit.result.cache
9 | .DS_Store
10 | /phpunit.coverage.xml
11 |
--------------------------------------------------------------------------------
/.php-cs-fixer.cache:
--------------------------------------------------------------------------------
1 | {"php":"8.0.3","version":"3.0.0:v3.0.0#c15377bdfa8d1ecf186f1deadec39c89984e1167","indent":" ","lineEnding":"\n","rules":{"blank_line_after_opening_tag":true,"braces":{"allow_single_line_anonymous_class_with_empty_body":true},"compact_nullable_typehint":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_braces":true,"no_blank_lines_after_class_opening":true,"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_blank_line_before_namespace":true,"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"visibility_required":{"elements":["const","method","property"]},"blank_line_after_namespace":true,"class_definition":true,"constant_case":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_import_per_statement":true,"single_line_after_imports":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true},"hashes":{"Form\/Handler\/AuthorizeFormHandler.php":644364133,"Form\/Type\/AuthorizeFormType.php":2473882551,"Form\/Model\/Authorize.php":2277517082,"Util\/Random.php":802199793,"Util\/LegacyFormHelper.php":3463381423,"Security\/Firewall\/OAuthListener.php":3256280425,"Security\/EntryPoint\/OAuthEntryPoint.php":3300495943,"Security\/Authenticator\/Oauth2Authenticator.php":991017001,"Security\/Authentication\/Token\/OAuthToken.php":645099124,"Security\/Authentication\/Provider\/OAuthProvider.php":3873131618,"Entity\/RefreshToken.php":66504907,"Entity\/ClientManager.php":1452201554,"Entity\/TokenManager.php":3338740552,"Entity\/AccessToken.php":4251529712,"Entity\/RefreshTokenManager.php":414634294,"Entity\/AuthCode.php":2219407473,"Entity\/AuthCodeManager.php":2532413095,"Entity\/AccessTokenManager.php":4224539817,"Entity\/Client.php":1083124177,"FOSOAuthServerBundle.php":4124437143,"Tests\/Form\/Handler\/AuthorizeFormHandlerTest.php":1906221542,"Tests\/Form\/Type\/AuthorizeFormTypeTest.php":2238981306,"Tests\/Util\/RandomTest.php":1191179325,"Tests\/Security\/Firewall\/OAuthListenerTest.php":3407442028,"Tests\/Security\/Authentication\/Provider\/OAuthProviderTest.php":2457218384,"Tests\/Security\/Authentification\/Token\/OAuthTokenTest.php":2945053184,"Tests\/Entity\/AuthCodeManagerTest.php":2007661459,"Tests\/Entity\/ClientManagerTest.php":766396943,"Tests\/Entity\/TokenManagerTest.php":1473952290,"Tests\/Document\/AuthCodeManagerTest.php":3617953485,"Tests\/Document\/ClientManagerTest.php":1071185972,"Tests\/Document\/TokenManagerTest.php":917404959,"Tests\/bootstrap.php":2430042088,"Tests\/Storage\/OAuthStorageTest.php":64232207,"Tests\/Controller\/AuthorizeControllerTest.php":2739608664,"Tests\/Model\/TokenTest.php":1965290733,"Tests\/Command\/CleanCommandTest.php":3055535592,"Tests\/Command\/CreateClientCommandTest.php":2203162721,"Tests\/FOSOAuthServerBundleTest.php":522076447,"Tests\/TestCase.php":4027732966,"Tests\/DependencyInjection\/Security\/Factory\/OAuthFactoryTest.php":3931590390,"Tests\/DependencyInjection\/ConfigurationTest.php":648882677,"Tests\/DependencyInjection\/FOSOAuthServerExtensionTest.php":1379307327,"Tests\/DependencyInjection\/Compiler\/TokenStorageCompilerPassTest.php":2422335141,"Tests\/DependencyInjection\/Compiler\/GrantExtensionsCompilerPassTest.php":3352901713,"Tests\/DependencyInjection\/Compiler\/RequestStackCompilerPassTest.php":2150456782,"Tests\/Functional\/TestBundle\/TestBundle.php":1456131229,"Tests\/Functional\/TestBundle\/Entity\/RefreshToken.php":1237578767,"Tests\/Functional\/TestBundle\/Entity\/User.php":3730762552,"Tests\/Functional\/TestBundle\/Entity\/AccessToken.php":2940885721,"Tests\/Functional\/TestBundle\/Entity\/AuthCode.php":2122232803,"Tests\/Functional\/TestBundle\/Entity\/Client.php":2765761650,"Tests\/Functional\/BootTest.php":977017021,"Tests\/Functional\/AppKernel.php":1114496403,"Tests\/Functional\/TestCase.php":551953486,"Document\/RefreshToken.php":2691281249,"Document\/ClientManager.php":2350236724,"Document\/TokenManager.php":4092676326,"Document\/AccessToken.php":2761752328,"Document\/RefreshTokenManager.php":246784338,"Document\/AuthCode.php":3656095945,"Document\/AuthCodeManager.php":1873472755,"Document\/AccessTokenManager.php":2903162592,"Document\/Client.php":989000811,"Storage\/GrantExtensionDispatcherInterface.php":9006188,"Storage\/GrantExtensionInterface.php":3728531040,"Storage\/OAuthStorage.php":99029901,"Controller\/AuthorizeController.php":295173422,"Controller\/TokenController.php":1989989879,"Model\/ClientManagerInterface.php":404743545,"Model\/AuthCodeManagerInterface.php":3112175094,"Model\/RefreshToken.php":2462104020,"Model\/ClientManager.php":63621513,"Model\/Token.php":4084908361,"Model\/TokenManager.php":1931703876,"Model\/AccessToken.php":1063329293,"Model\/RefreshTokenManagerInterface.php":187414808,"Model\/ClientInterface.php":3292532149,"Model\/AuthCode.php":222711451,"Model\/AccessTokenManagerInterface.php":3048194508,"Model\/AccessTokenInterface.php":3847276407,"Model\/AuthCodeInterface.php":2660786798,"Model\/TokenManagerInterface.php":1010854742,"Model\/AuthCodeManager.php":4277460474,"Model\/TokenInterface.php":3661528244,"Model\/RefreshTokenInterface.php":4089106687,"Model\/Client.php":1588407887,"Command\/CreateClientCommand.php":2312819124,"Command\/CleanCommand.php":131382764,"DependencyInjection\/Security\/Factory\/OAuthFactory.php":4972243,"DependencyInjection\/FOSOAuthServerExtension.php":2654959019,"DependencyInjection\/Configuration.php":1694748975,"DependencyInjection\/Compiler\/RequestStackCompilerPass.php":1420693598,"DependencyInjection\/Compiler\/TokenStorageCompilerPass.php":1937726139,"DependencyInjection\/Compiler\/GrantExtensionsCompilerPass.php":853793336,"Event\/OAuthEvent.php":1210775945}}
--------------------------------------------------------------------------------
/.php_cs-fixer.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | $header = <<
16 |
17 | For the full copyright and license information, please view the LICENSE
18 | file that was distributed with this source code.
19 | EOF;
20 |
21 | $finder = PhpCsFixer\Finder::create()
22 | ->in(__DIR__)
23 | ->exclude('vendor');
24 |
25 | $config = new \PhpCsFixer\Config();
26 |
27 | return $config
28 | ->setFinder($finder)
29 | ->setRiskyAllowed(true)
30 | ->setUsingCache(false)
31 | ->setRules(
32 | [
33 | '@Symfony' => true,
34 | '@PHPUnit60Migration:risky' => true,
35 | 'array_syntax' => ['syntax' => 'short'],
36 | 'combine_consecutive_unsets' => true,
37 | 'declare_strict_types' => true,
38 | 'dir_constant' => true,
39 | 'header_comment' => ['header' => $header],
40 | 'linebreak_after_opening_tag' => true,
41 | 'mb_str_functions' => true,
42 | 'modernize_types_casting' => true,
43 | // 'native_function_invocation' => true,
44 | 'no_extra_blank_lines' => ['tokens' => ['continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block']],
45 | 'multiline_whitespace_before_semicolons' => ['strategy' => 'new_line_for_chained_calls'],
46 | 'no_php4_constructor' => true,
47 | 'echo_tag_syntax' => ['format' => 'long'],
48 | 'no_unreachable_default_argument_value' => true,
49 | 'no_useless_else' => true,
50 | 'no_useless_return' => true,
51 | 'not_operator_with_space' => false,
52 | 'not_operator_with_successor_space' => false,
53 | 'ordered_imports' => true,
54 | 'phpdoc_add_missing_param_annotation' => true,
55 | 'phpdoc_annotation_without_dot' => true,
56 | 'general_phpdoc_tag_rename' => false,
57 | 'phpdoc_no_empty_return' => false,
58 | 'phpdoc_order' => true,
59 | 'phpdoc_to_comment' => false,
60 | 'psr_autoloading' => true,
61 | 'semicolon_after_instruction' => true,
62 | 'single_import_per_statement' => true,
63 | 'strict_comparison' => true,
64 | 'strict_param' => true,
65 | 'yoda_style' => false
66 | ]
67 | );
68 |
--------------------------------------------------------------------------------
/Command/CleanCommand.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Command;
15 |
16 | use FOS\OAuthServerBundle\Model\AuthCodeManagerInterface;
17 | use FOS\OAuthServerBundle\Model\TokenManagerInterface;
18 | use Symfony\Component\Console\Command\Command;
19 | use Symfony\Component\Console\Input\InputInterface;
20 | use Symfony\Component\Console\Output\OutputInterface;
21 |
22 | class CleanCommand extends Command
23 | {
24 | private TokenManagerInterface $accessTokenManager;
25 | private TokenManagerInterface $refreshTokenManager;
26 | private AuthCodeManagerInterface $authCodeManager;
27 |
28 | public function __construct(
29 | TokenManagerInterface $accessTokenManager,
30 | TokenManagerInterface $refreshTokenManager,
31 | AuthCodeManagerInterface $authCodeManager
32 | ) {
33 | parent::__construct();
34 |
35 | $this->accessTokenManager = $accessTokenManager;
36 | $this->refreshTokenManager = $refreshTokenManager;
37 | $this->authCodeManager = $authCodeManager;
38 | }
39 |
40 | /**
41 | * {@inheritdoc}
42 | */
43 | protected function configure(): void
44 | {
45 | parent::configure();
46 |
47 | $this
48 | ->setName('fos:oauth-server:clean')
49 | ->setDescription('Clean expired tokens')
50 | ->setHelp(
51 | <<%command.name% command will remove expired OAuth2 tokens.
53 |
54 | php %command.full_name%
55 | EOT
56 | )
57 | ;
58 | }
59 |
60 | /**
61 | * {@inheritdoc}
62 | */
63 | protected function execute(InputInterface $input, OutputInterface $output): int
64 | {
65 | foreach ([$this->accessTokenManager, $this->refreshTokenManager, $this->authCodeManager] as $service) {
66 | $result = $service->deleteExpired();
67 | $output->writeln(sprintf('Removed %d items from %s storage.', $result, get_class($service)));
68 | }
69 |
70 | return 0;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Command/CreateClientCommand.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Command;
15 |
16 | use FOS\OAuthServerBundle\Model\ClientManagerInterface;
17 | use Symfony\Component\Console\Command\Command;
18 | use Symfony\Component\Console\Input\InputInterface;
19 | use Symfony\Component\Console\Input\InputOption;
20 | use Symfony\Component\Console\Output\OutputInterface;
21 | use Symfony\Component\Console\Style\SymfonyStyle;
22 |
23 | class CreateClientCommand extends Command
24 | {
25 | /**
26 | * @var ClientManagerInterface
27 | */
28 | private $clientManager;
29 |
30 | public function __construct(ClientManagerInterface $clientManager)
31 | {
32 | parent::__construct();
33 |
34 | $this->clientManager = $clientManager;
35 | }
36 |
37 | /**
38 | * {@inheritdoc}
39 | */
40 | protected function configure(): void
41 | {
42 | parent::configure();
43 |
44 | $this
45 | ->setName('fos:oauth-server:create-client')
46 | ->setDescription('Creates a new client')
47 | ->addOption(
48 | 'redirect-uri',
49 | null,
50 | InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
51 | 'Sets redirect uri for client. Use this option multiple times to set multiple redirect URIs.',
52 | null
53 | )
54 | ->addOption(
55 | 'grant-type',
56 | null,
57 | InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
58 | 'Sets allowed grant type for client. Use this option multiple times to set multiple grant types..',
59 | null
60 | )
61 | ->setHelp(
62 | <<%command.name% command creates a new client.
64 |
65 | php %command.full_name% [--redirect-uri=...] [--grant-type=...]
66 |
67 | EOT
68 | )
69 | ;
70 | }
71 |
72 | /**
73 | * {@inheritdoc}
74 | */
75 | protected function execute(InputInterface $input, OutputInterface $output): int
76 | {
77 | $io = new SymfonyStyle($input, $output);
78 |
79 | $io->title('Client Credentials');
80 |
81 | // Create a new client
82 | $client = $this->clientManager->createClient();
83 |
84 | $client->setRedirectUris($input->getOption('redirect-uri'));
85 | $client->setAllowedGrantTypes($input->getOption('grant-type'));
86 |
87 | // Save the client
88 | $this->clientManager->updateClient($client);
89 |
90 | // Give the credentials back to the user
91 | $headers = ['Client ID', 'Client Secret'];
92 | $rows = [
93 | [$client->getPublicId(), $client->getSecret()],
94 | ];
95 |
96 | $io->table($headers, $rows);
97 |
98 | return 0;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/Controller/TokenController.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Controller;
15 |
16 | use OAuth2\OAuth2;
17 | use OAuth2\OAuth2ServerException;
18 | use Symfony\Component\HttpFoundation\Request;
19 | use Symfony\Component\HttpFoundation\Response;
20 |
21 | class TokenController
22 | {
23 | /**
24 | * @var OAuth2
25 | */
26 | protected $server;
27 |
28 | public function __construct(OAuth2 $server)
29 | {
30 | $this->server = $server;
31 | }
32 |
33 | public function tokenAction(Request $request): Response
34 | {
35 | try {
36 | return $this->server->grantAccessToken($request);
37 | } catch (OAuth2ServerException $e) {
38 | return $e->getHttpResponse();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/DependencyInjection/Compiler/GrantExtensionsCompilerPass.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\DependencyInjection\Compiler;
15 |
16 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17 | use Symfony\Component\DependencyInjection\ContainerBuilder;
18 | use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
19 | use Symfony\Component\DependencyInjection\Reference;
20 |
21 | /**
22 | * @author Adrien Brault
23 | */
24 | class GrantExtensionsCompilerPass implements CompilerPassInterface
25 | {
26 | public function process(ContainerBuilder $container): void
27 | {
28 | $storageDefinition = $container->findDefinition('fos_oauth_server.storage');
29 | $className = $container->getParameterBag()->resolveValue($storageDefinition->getClass());
30 | $storageClass = new \ReflectionClass($className);
31 | if (!$storageClass->implementsInterface('FOS\OAuthServerBundle\Storage\GrantExtensionDispatcherInterface')) {
32 | return;
33 | }
34 |
35 | foreach ($container->findTaggedServiceIds('fos_oauth_server.grant_extension') as $id => $tags) {
36 | foreach ($tags as $tag) {
37 | if (empty($tag['uri'])) {
38 | throw new InvalidArgumentException(sprintf('Service "%s" must define the "uri" attribute on "fos_oauth_server.grant_extension" tags.', $id));
39 | }
40 |
41 | $storageDefinition->addMethodCall('setGrantExtension', [$tag['uri'], new Reference($id)]);
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/DependencyInjection/Compiler/RequestStackCompilerPass.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\DependencyInjection\Compiler;
15 |
16 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17 | use Symfony\Component\DependencyInjection\ContainerBuilder;
18 | use Symfony\Component\DependencyInjection\Reference;
19 |
20 | /**
21 | * @author Ener-Getick
22 | *
23 | * @internal
24 | */
25 | final class RequestStackCompilerPass implements CompilerPassInterface
26 | {
27 | /**
28 | * {@inheritdoc}
29 | */
30 | public function process(ContainerBuilder $container): void
31 | {
32 | if ($container->has('request_stack')) {
33 | return;
34 | }
35 |
36 | $definition = $container->getDefinition('fos_oauth_server.authorize.form.handler.default');
37 | $definition->addMethodCall('setContainer', [new Reference('service_container')]);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/DependencyInjection/Security/Factory/OAuthFactory.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\DependencyInjection\Security\Factory;
15 |
16 | use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface;
17 | use Symfony\Component\Config\Definition\Builder\NodeDefinition;
18 | use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
19 | use Symfony\Component\DependencyInjection\ChildDefinition;
20 | use Symfony\Component\DependencyInjection\ContainerBuilder;
21 | use Symfony\Component\DependencyInjection\Reference;
22 |
23 | /**
24 | * OAuthFactory class.
25 | *
26 | * @author Arnaud Le Blanc
27 | */
28 | class OAuthFactory implements AuthenticatorFactoryInterface
29 | {
30 | public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string
31 | {
32 | $authenticatorId = 'security.authenticator.oauth2.'.$firewallName;
33 | $firewallEventDispatcherId = 'security.event_dispatcher.'.$firewallName;
34 |
35 | // authenticator manager
36 | $firewallAuthenticationProviders = [];
37 | $authenticators = array_map(function ($firewallName) {
38 | return new Reference($firewallName);
39 | }, $firewallAuthenticationProviders);
40 | $container
41 | ->setDefinition($managerId = 'security.authenticator.oauth2.'.$firewallName, new ChildDefinition('fos_oauth_server.security.authenticator.manager'))
42 | // ->replaceArgument(0, $authenticators)
43 | // ->replaceArgument(2, new Reference($firewallEventDispatcherId))
44 | ->addTag('monolog.logger', ['channel' => 'security'])
45 | ;
46 |
47 | $managerLocator = $container->getDefinition('security.authenticator.managers_locator');
48 | $managerLocator->replaceArgument(0, array_merge($managerLocator->getArgument(0), [$firewallName => new ServiceClosureArgument(new Reference($managerId))]));
49 |
50 | // authenticator manager listener
51 | $container
52 | ->setDefinition('security.firewall.authenticator.'.$firewallName, new ChildDefinition('security.firewall.authenticator'))
53 | ->replaceArgument(0, new Reference($managerId))
54 | ;
55 |
56 | // user checker listener
57 | $container
58 | ->setDefinition('security.listener.user_checker.'.$firewallName, new ChildDefinition('security.listener.user_checker'))
59 | ->replaceArgument(0, new Reference('security.user_checker.'.$firewallName))
60 | ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId])
61 | ;
62 |
63 | // Add authenticators to the debug:firewall command
64 | if ($container->hasDefinition('security.command.debug_firewall')) {
65 | $debugCommand = $container->getDefinition('security.command.debug_firewall');
66 | $debugCommand->replaceArgument(3, array_merge($debugCommand->getArgument(3), [$firewallName => $authenticators]));
67 | }
68 |
69 | return $authenticatorId;
70 | }
71 |
72 | public function getPriority(): int
73 | {
74 | return 0;
75 | }
76 |
77 | /**
78 | * {@inheritdoc}
79 | */
80 | public function getKey(): string
81 | {
82 | return 'fos_oauth';
83 | }
84 |
85 | /**
86 | * {@inheritdoc}
87 | */
88 | public function addConfiguration(NodeDefinition $builder): void
89 | {
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Document/AccessToken.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Document;
15 |
16 | use FOS\OAuthServerBundle\Model\AccessToken as BaseAccessToken;
17 |
18 | class AccessToken extends BaseAccessToken
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Document/AccessTokenManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Document;
15 |
16 | use FOS\OAuthServerBundle\Model\AccessTokenManagerInterface;
17 |
18 | class AccessTokenManager extends TokenManager implements AccessTokenManagerInterface
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Document/AuthCode.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Document;
15 |
16 | use FOS\OAuthServerBundle\Model\AuthCode as BaseAuthCode;
17 |
18 | /**
19 | * @author Richard Fullmer
20 | */
21 | class AuthCode extends BaseAuthCode
22 | {
23 | }
24 |
--------------------------------------------------------------------------------
/Document/AuthCodeManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Document;
15 |
16 | use Doctrine\ODM\MongoDB\DocumentManager;
17 | use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
18 | use FOS\OAuthServerBundle\Model\AuthCodeInterface;
19 | use FOS\OAuthServerBundle\Model\AuthCodeManager as BaseAuthCodeManager;
20 | use MongoDB\DeleteResult;
21 |
22 | class AuthCodeManager extends BaseAuthCodeManager
23 | {
24 | /**
25 | * @var DocumentManager
26 | */
27 | protected $dm;
28 |
29 | /**
30 | * @var DocumentRepository
31 | */
32 | protected $repository;
33 |
34 | /**
35 | * @var string
36 | */
37 | protected $class;
38 |
39 | public function __construct(DocumentManager $dm, $class)
40 | {
41 | // NOTE: bug in Doctrine, hinting DocumentRepository|ObjectRepository when only DocumentRepository is expected
42 | /** @var DocumentRepository $repository */
43 | $repository = $dm->getRepository($class);
44 |
45 | $this->dm = $dm;
46 | $this->repository = $repository;
47 | $this->class = $class;
48 | }
49 |
50 | /**
51 | * {@inheritdoc}
52 | */
53 | public function getClass(): string
54 | {
55 | return $this->class;
56 | }
57 |
58 | /**
59 | * {@inheritdoc}
60 | */
61 | public function findAuthCodeBy(array $criteria): ?AuthCodeInterface
62 | {
63 | return $this->repository->findOneBy($criteria);
64 | }
65 |
66 | /**
67 | * {@inheritdoc}
68 | */
69 | public function updateAuthCode(AuthCodeInterface $authCode)
70 | {
71 | $this->dm->persist($authCode);
72 | $this->dm->flush();
73 | }
74 |
75 | /**
76 | * {@inheritdoc}
77 | */
78 | public function deleteAuthCode(AuthCodeInterface $authCode)
79 | {
80 | $this->dm->remove($authCode);
81 | $this->dm->flush();
82 | }
83 |
84 | /**
85 | * {@inheritdoc}
86 | */
87 | public function deleteExpired(): int
88 | {
89 | $result = $this
90 | ->repository
91 | ->createQueryBuilder()
92 | ->remove()
93 | ->field('expiresAt')->lt(time())
94 | ->getQuery(['safe' => true])
95 | ->execute()
96 | ;
97 |
98 | return $result instanceof DeleteResult ? $result->getDeletedCount() : $result['n'];
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/Document/Client.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Document;
15 |
16 | use FOS\OAuthServerBundle\Model\Client as BaseClient;
17 |
18 | class Client extends BaseClient
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Document/ClientManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Document;
15 |
16 | use Doctrine\ODM\MongoDB\DocumentManager;
17 | use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
18 | use FOS\OAuthServerBundle\Model\ClientInterface;
19 | use FOS\OAuthServerBundle\Model\ClientManager as BaseClientManager;
20 |
21 | class ClientManager extends BaseClientManager
22 | {
23 | /**
24 | * @var DocumentManager
25 | */
26 | protected $dm;
27 |
28 | /**
29 | * @var DocumentRepository
30 | */
31 | protected $repository;
32 |
33 | /**
34 | * @var string
35 | */
36 | protected $class;
37 |
38 | public function __construct(DocumentManager $dm, $class)
39 | {
40 | // NOTE: bug in Doctrine, hinting DocumentRepository|ObjectRepository when only DocumentRepository is expected
41 | /** @var DocumentRepository $repository */
42 | $repository = $dm->getRepository($class);
43 |
44 | $this->dm = $dm;
45 | $this->repository = $repository;
46 | $this->class = $class;
47 | }
48 |
49 | /**
50 | * {@inheritdoc}
51 | */
52 | public function getClass(): string
53 | {
54 | return $this->class;
55 | }
56 |
57 | /**
58 | * {@inheritdoc}
59 | */
60 | public function findClientBy(array $criteria): ?ClientInterface
61 | {
62 | return $this->repository->findOneBy($criteria);
63 | }
64 |
65 | /**
66 | * {@inheritdoc}
67 | */
68 | public function updateClient(ClientInterface $client)
69 | {
70 | $this->dm->persist($client);
71 | $this->dm->flush();
72 | }
73 |
74 | /**
75 | * {@inheritdoc}
76 | */
77 | public function deleteClient(ClientInterface $client)
78 | {
79 | $this->dm->remove($client);
80 | $this->dm->flush();
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/Document/RefreshToken.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Document;
15 |
16 | use FOS\OAuthServerBundle\Model\RefreshToken as BaseRefreshToken;
17 |
18 | class RefreshToken extends BaseRefreshToken
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Document/RefreshTokenManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Document;
15 |
16 | use FOS\OAuthServerBundle\Model\RefreshTokenManagerInterface;
17 |
18 | class RefreshTokenManager extends TokenManager implements RefreshTokenManagerInterface
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Document/TokenManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Document;
15 |
16 | use Doctrine\ODM\MongoDB\DocumentManager;
17 | use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
18 | use FOS\OAuthServerBundle\Model\TokenInterface;
19 | use FOS\OAuthServerBundle\Model\TokenManager as BaseTokenManager;
20 | use MongoDB\DeleteResult;
21 |
22 | class TokenManager extends BaseTokenManager
23 | {
24 | /**
25 | * @var DocumentManager
26 | */
27 | protected $dm;
28 |
29 | /**
30 | * @var DocumentRepository
31 | */
32 | protected $repository;
33 |
34 | /**
35 | * @var string
36 | */
37 | protected $class;
38 |
39 | public function __construct(DocumentManager $dm, $class)
40 | {
41 | // NOTE: bug in Doctrine, hinting DocumentRepository|ObjectRepository when only DocumentRepository is expected
42 | /** @var DocumentRepository $repository */
43 | $repository = $dm->getRepository($class);
44 |
45 | $this->dm = $dm;
46 | $this->repository = $repository;
47 | $this->class = $class;
48 | }
49 |
50 | /**
51 | * {@inheritdoc}
52 | */
53 | public function getClass(): string
54 | {
55 | return $this->class;
56 | }
57 |
58 | /**
59 | * {@inheritdoc}
60 | */
61 | public function findTokenBy(array $criteria): ?TokenInterface
62 | {
63 | return $this->repository->findOneBy($criteria);
64 | }
65 |
66 | /**
67 | * {@inheritdoc}
68 | */
69 | public function updateToken(TokenInterface $token)
70 | {
71 | $this->dm->persist($token);
72 | $this->dm->flush();
73 | }
74 |
75 | /**
76 | * {@inheritdoc}
77 | */
78 | public function deleteToken(TokenInterface $token)
79 | {
80 | $this->dm->remove($token);
81 | $this->dm->flush();
82 | }
83 |
84 | /**
85 | * {@inheritdoc}
86 | */
87 | public function deleteExpired(): int
88 | {
89 | $result = $this
90 | ->repository
91 | ->createQueryBuilder()
92 | ->remove()
93 | ->field('expiresAt')->lt(time())
94 | ->getQuery(['safe' => true])
95 | ->execute()
96 | ;
97 |
98 | return $result instanceof DeleteResult ? $result->getDeletedCount() : $result['n'];
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/Entity/AccessToken.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Entity;
15 |
16 | use FOS\OAuthServerBundle\Model\AccessToken as BaseAccessToken;
17 |
18 | class AccessToken extends BaseAccessToken
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Entity/AccessTokenManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Entity;
15 |
16 | use FOS\OAuthServerBundle\Model\AccessTokenManagerInterface;
17 |
18 | class AccessTokenManager extends TokenManager implements AccessTokenManagerInterface
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Entity/AuthCode.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Entity;
15 |
16 | use FOS\OAuthServerBundle\Model\AuthCode as BaseAuthCode;
17 |
18 | class AuthCode extends BaseAuthCode
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Entity/AuthCodeManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Entity;
15 |
16 | use Doctrine\ORM\EntityManagerInterface;
17 | use FOS\OAuthServerBundle\Model\AuthCodeInterface;
18 | use FOS\OAuthServerBundle\Model\AuthCodeManager as BaseAuthCodeManager;
19 |
20 | class AuthCodeManager extends BaseAuthCodeManager
21 | {
22 | /**
23 | * @var EntityManagerInterface
24 | */
25 | protected $em;
26 |
27 | /**
28 | * @var string
29 | */
30 | protected $class;
31 |
32 | public function __construct(EntityManagerInterface $em, string $class)
33 | {
34 | $this->em = $em;
35 | $this->class = $class;
36 | }
37 |
38 | /**
39 | * {@inheritdoc}
40 | */
41 | public function getClass(): string
42 | {
43 | return $this->class;
44 | }
45 |
46 | /**
47 | * {@inheritdoc}
48 | */
49 | public function findAuthCodeBy(array $criteria): ?AuthCodeInterface
50 | {
51 | return $this->em->getRepository($this->class)->findOneBy($criteria);
52 | }
53 |
54 | /**
55 | * {@inheritdoc}
56 | */
57 | public function updateAuthCode(AuthCodeInterface $authCode)
58 | {
59 | $this->em->persist($authCode);
60 | $this->em->flush();
61 | }
62 |
63 | /**
64 | * {@inheritdoc}
65 | */
66 | public function deleteAuthCode(AuthCodeInterface $authCode)
67 | {
68 | $this->em->remove($authCode);
69 | $this->em->flush();
70 | }
71 |
72 | /**
73 | * {@inheritdoc}
74 | */
75 | public function deleteExpired(): int
76 | {
77 | /** @var \Doctrine\ORM\EntityRepository $repository */
78 | $repository = $this->em->getRepository($this->class);
79 |
80 | $qb = $repository->createQueryBuilder('a');
81 | $qb
82 | ->delete()
83 | ->where('a.expiresAt < :time')
84 | ->setParameter('time', time())
85 | ;
86 |
87 | return $qb->getQuery()->execute();
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Entity/Client.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Entity;
15 |
16 | use FOS\OAuthServerBundle\Model\Client as BaseClient;
17 |
18 | class Client extends BaseClient
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Entity/ClientManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Entity;
15 |
16 | use Doctrine\ORM\EntityManagerInterface;
17 | use Doctrine\ORM\EntityRepository;
18 | use FOS\OAuthServerBundle\Model\ClientInterface;
19 | use FOS\OAuthServerBundle\Model\ClientManager as BaseClientManager;
20 |
21 | class ClientManager extends BaseClientManager
22 | {
23 | /**
24 | * @var EntityManagerInterface
25 | */
26 | protected $em;
27 |
28 | /**
29 | * @var EntityRepository
30 | */
31 | protected $repository;
32 |
33 | /**
34 | * @var string
35 | */
36 | protected $class;
37 |
38 | public function __construct(EntityManagerInterface $em, $class)
39 | {
40 | // NOTE: bug in Doctrine, hinting EntityRepository|ObjectRepository when only EntityRepository is expected
41 | /** @var EntityRepository $repository */
42 | $repository = $em->getRepository($class);
43 |
44 | $this->em = $em;
45 | $this->repository = $repository;
46 | $this->class = $class;
47 | }
48 |
49 | /**
50 | * {@inheritdoc}
51 | */
52 | public function getClass(): string
53 | {
54 | return $this->class;
55 | }
56 |
57 | /**
58 | * {@inheritdoc}
59 | */
60 | public function findClientBy(array $criteria): ?ClientInterface
61 | {
62 | return $this->repository->findOneBy($criteria);
63 | }
64 |
65 | /**
66 | * {@inheritdoc}
67 | */
68 | public function updateClient(ClientInterface $client)
69 | {
70 | $this->em->persist($client);
71 | $this->em->flush();
72 | }
73 |
74 | /**
75 | * {@inheritdoc}
76 | */
77 | public function deleteClient(ClientInterface $client)
78 | {
79 | $this->em->remove($client);
80 | $this->em->flush();
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/Entity/RefreshToken.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Entity;
15 |
16 | use FOS\OAuthServerBundle\Model\RefreshToken as BaseRefreshToken;
17 |
18 | class RefreshToken extends BaseRefreshToken
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Entity/RefreshTokenManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Entity;
15 |
16 | use FOS\OAuthServerBundle\Model\RefreshTokenManagerInterface;
17 |
18 | class RefreshTokenManager extends TokenManager implements RefreshTokenManagerInterface
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Entity/TokenManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Entity;
15 |
16 | use Doctrine\ORM\EntityManagerInterface;
17 | use Doctrine\ORM\EntityRepository;
18 | use FOS\OAuthServerBundle\Model\TokenInterface;
19 | use FOS\OAuthServerBundle\Model\TokenManager as BaseTokenManager;
20 |
21 | class TokenManager extends BaseTokenManager
22 | {
23 | /**
24 | * @var EntityManagerInterface
25 | */
26 | protected $em;
27 |
28 | /**
29 | * @var EntityRepository
30 | */
31 | protected $repository;
32 |
33 | /**
34 | * @var string
35 | */
36 | protected $class;
37 |
38 | public function __construct(EntityManagerInterface $em, $class)
39 | {
40 | // NOTE: bug in Doctrine, hinting EntityRepository|ObjectRepository when only EntityRepository is expected
41 | /** @var EntityRepository $repository */
42 | $repository = $em->getRepository($class);
43 |
44 | $this->em = $em;
45 | $this->repository = $repository;
46 | $this->class = $class;
47 | }
48 |
49 | /**
50 | * {@inheritdoc}
51 | */
52 | public function getClass(): string
53 | {
54 | return $this->class;
55 | }
56 |
57 | /**
58 | * {@inheritdoc}
59 | */
60 | public function findTokenBy(array $criteria): ?TokenInterface
61 | {
62 | return $this->repository->findOneBy($criteria);
63 | }
64 |
65 | /**
66 | * {@inheritdoc}
67 | */
68 | public function updateToken(TokenInterface $token)
69 | {
70 | $this->em->persist($token);
71 | $this->em->flush();
72 | }
73 |
74 | /**
75 | * {@inheritdoc}
76 | */
77 | public function deleteToken(TokenInterface $token)
78 | {
79 | $this->em->remove($token);
80 | $this->em->flush();
81 | }
82 |
83 | /**
84 | * {@inheritdoc}
85 | */
86 | public function deleteExpired(): int
87 | {
88 | $qb = $this->repository->createQueryBuilder('t');
89 | $qb
90 | ->delete()
91 | ->where('t.expiresAt < :time')
92 | ->setParameter('time', time())
93 | ;
94 |
95 | return $qb->getQuery()->execute();
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/Event/OAuthEvent.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Event;
15 |
16 | use FOS\OAuthServerBundle\Model\ClientInterface;
17 | use Symfony\Component\Security\Core\User\UserInterface;
18 | use Symfony\Contracts\EventDispatcher\Event;
19 |
20 | class OAuthEvent extends Event
21 | {
22 | public const PRE_AUTHORIZATION_PROCESS = 'fos_oauth_server.pre_authorization_process';
23 |
24 | public const POST_AUTHORIZATION_PROCESS = 'fos_oauth_server.post_authorization_process';
25 |
26 | public function __construct(
27 | private UserInterface $user,
28 | private ClientInterface $client,
29 | private bool $isAuthorizedClient = false)
30 | {
31 | }
32 |
33 | public function getUser(): UserInterface
34 | {
35 | return $this->user;
36 | }
37 |
38 |
39 | public function setAuthorizedClient(bool $isAuthorizedClient): void
40 | {
41 | $this->isAuthorizedClient = $isAuthorizedClient;
42 | }
43 |
44 | public function isAuthorizedClient(): bool
45 | {
46 | return $this->isAuthorizedClient;
47 | }
48 |
49 | public function getClient(): ClientInterface
50 | {
51 | return $this->client;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/FOSOAuthServerBundle.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle;
15 |
16 | use FOS\OAuthServerBundle\DependencyInjection\Compiler\GrantExtensionsCompilerPass;
17 | use FOS\OAuthServerBundle\DependencyInjection\Compiler\RequestStackCompilerPass;
18 | use FOS\OAuthServerBundle\DependencyInjection\FOSOAuthServerExtension;
19 | use FOS\OAuthServerBundle\DependencyInjection\Security\Factory\OAuthFactory;
20 | use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension;
21 | use Symfony\Component\DependencyInjection\ContainerBuilder;
22 | use Symfony\Component\HttpKernel\Bundle\Bundle;
23 |
24 | class FOSOAuthServerBundle extends Bundle
25 | {
26 | public function __construct()
27 | {
28 | $this->extension = new FOSOAuthServerExtension();
29 | }
30 |
31 | public function build(ContainerBuilder $container): void
32 | {
33 | parent::build($container);
34 |
35 | /** @var SecurityExtension $extension */
36 | $extension = $container->getExtension('security');
37 | $extension->addAuthenticatorFactory(new OAuthFactory());
38 |
39 | $container->addCompilerPass(new GrantExtensionsCompilerPass());
40 | $container->addCompilerPass(new RequestStackCompilerPass());
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Form/Handler/AuthorizeFormHandler.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Form\Handler;
15 |
16 | use FOS\OAuthServerBundle\Form\Model\Authorize;
17 | use Symfony\Component\DependencyInjection\ContainerInterface;
18 | use Symfony\Component\Form\FormInterface;
19 | use Symfony\Component\HttpFoundation\Request;
20 | use Symfony\Component\HttpFoundation\RequestStack;
21 |
22 | /**
23 | * @author Chris Jones
24 | */
25 | class AuthorizeFormHandler
26 | {
27 | /**
28 | * @var FormInterface
29 | */
30 | protected $form;
31 |
32 | /**
33 | * @var ContainerInterface
34 | */
35 | protected $container;
36 |
37 | /**
38 | * @var RequestStack|Request|null
39 | */
40 | private $requestStack;
41 |
42 | /**
43 | * @param Request|RequestStack $requestStack
44 | */
45 | public function __construct(FormInterface $form, $requestStack = null)
46 | {
47 | if (null !== $requestStack && !$requestStack instanceof RequestStack && !$requestStack instanceof Request) {
48 | throw new \InvalidArgumentException(sprintf('Argument 2 of %s must be an instanceof RequestStack or Request', __CLASS__));
49 | }
50 |
51 | $this->form = $form;
52 | $this->requestStack = $requestStack;
53 | }
54 |
55 | /**
56 | * Sets the container.
57 | *
58 | * @param ContainerInterface|null $container A ContainerInterface instance or null
59 | */
60 | public function setContainer(?ContainerInterface $container = null)
61 | {
62 | $this->container = $container;
63 | }
64 |
65 | public function isAccepted()
66 | {
67 | return $this->form->getData()->accepted;
68 | }
69 |
70 | public function isRejected()
71 | {
72 | return !$this->form->getData()->accepted;
73 | }
74 |
75 | /**
76 | * @return bool
77 | */
78 | public function process()
79 | {
80 | $request = $this->getCurrentRequest();
81 |
82 | if (null === $request) {
83 | return false;
84 | }
85 |
86 | $this->form->setData(new Authorize(
87 | $request->request->has('accepted'),
88 | $request->query->all()
89 | ));
90 |
91 | if ('POST' !== $request->getMethod()) {
92 | return false;
93 | }
94 |
95 | $this->form->handleRequest($request);
96 | if ($this->form->isSubmitted() && !$this->form->isValid()) {
97 | return false;
98 | }
99 |
100 | $this->onSuccess();
101 |
102 | return true;
103 | }
104 |
105 | public function getScope()
106 | {
107 | return $this->form->getData()->scope;
108 | }
109 |
110 | /**
111 | * Put form data in $_GET so that OAuth2 library will call Request::createFromGlobals().
112 | *
113 | * @todo finishClientAuthorization() is a bit odd since it accepts $data
114 | * but then proceeds to ignore it and forces everything to be in $request->query
115 | */
116 | protected function onSuccess()
117 | {
118 | $_GET = [
119 | 'client_id' => $this->form->getData()->client_id,
120 | 'response_type' => $this->form->getData()->response_type,
121 | 'redirect_uri' => $this->form->getData()->redirect_uri,
122 | 'state' => $this->form->getData()->state,
123 | 'scope' => $this->form->getData()->scope,
124 | ];
125 | }
126 |
127 | private function getCurrentRequest()
128 | {
129 | if (null === $this->requestStack) {
130 | return $this->container->get('request');
131 | }
132 |
133 | if ($this->requestStack instanceof Request) {
134 | return $this->requestStack;
135 | }
136 |
137 | return $this->requestStack->getCurrentRequest();
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/Form/Model/Authorize.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Form\Model;
15 |
16 | /**
17 | * @author Chris Jones
18 | */
19 | #[\AllowDynamicProperties]
20 | class Authorize
21 | {
22 | /**
23 | * @var bool
24 | */
25 | public $accepted;
26 |
27 | /**
28 | * @var string
29 | */
30 | public $client_id;
31 |
32 | /**
33 | * @var string
34 | */
35 | public $response_type;
36 |
37 | /**
38 | * @var string
39 | */
40 | public $redirect_uri;
41 |
42 | /**
43 | * @var string
44 | */
45 | public $state;
46 |
47 | /**
48 | * @var string
49 | */
50 | public $scope;
51 |
52 | public function __construct(bool $accepted, array $query = [])
53 | {
54 | foreach ($query as $key => $value) {
55 | $this->{$key} = $value;
56 | }
57 |
58 | $this->accepted = $accepted;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Form/Type/AuthorizeFormType.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Form\Type;
15 |
16 | use FOS\OAuthServerBundle\Util\LegacyFormHelper;
17 | use Symfony\Component\Form\AbstractType;
18 | use Symfony\Component\Form\FormBuilderInterface;
19 | use Symfony\Component\OptionsResolver\OptionsResolver;
20 |
21 | /**
22 | * @author Chris Jones
23 | */
24 | class AuthorizeFormType extends AbstractType
25 | {
26 | public function buildForm(FormBuilderInterface $builder, array $options): void
27 | {
28 | $hiddenType = LegacyFormHelper::getType('Symfony\Component\Form\Extension\Core\Type\HiddenType');
29 |
30 | $builder->add('client_id', $hiddenType);
31 | $builder->add('response_type', $hiddenType);
32 | $builder->add('redirect_uri', $hiddenType);
33 | $builder->add('state', $hiddenType);
34 | $builder->add('scope', $hiddenType);
35 | }
36 |
37 | /**
38 | * {@inheritdoc}
39 | */
40 | public function configureOptions(OptionsResolver $resolver): void
41 | {
42 | $resolver->setDefaults([
43 | 'data_class' => 'FOS\OAuthServerBundle\Form\Model\Authorize',
44 | ]);
45 | }
46 |
47 | /**
48 | * @return string
49 | */
50 | public function getBlockPrefix()
51 | {
52 | return 'fos_oauth_server_authorize';
53 | }
54 |
55 | /**
56 | * @return string
57 | */
58 | public function getName()
59 | {
60 | return $this->getBlockPrefix();
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | QA_DOCKER_IMAGE=jakzal/phpqa:alpine
2 | QA_DOCKER_COMMAND=docker run -it --rm -v "$(shell pwd):/project" -w /project ${QA_DOCKER_IMAGE}
3 |
4 | dist: cs-full phpstan phpunit
5 | ci: cs-full-check phpstan phpunit-coverage
6 | lint: cs-full-check phpstan
7 |
8 | phpstan:
9 | sh -c "${QA_DOCKER_COMMAND} phpstan analyse --configuration phpstan.neon --level 6 ."
10 |
11 | cs:
12 | sh -c "${QA_DOCKER_COMMAND} php-cs-fixer fix -vvv --diff --config .php_cs-fixer.php"
13 |
14 | cs-full:
15 | sh -c "${QA_DOCKER_COMMAND} php-cs-fixer fix -vvv --using-cache=no --diff --config .php_cs-fixer.php"
16 |
17 | cs-full-check:
18 | sh -c "${QA_DOCKER_COMMAND} php-cs-fixer fix -vvv --using-cache=no --diff --dry-run --config .php_cs-fixer.php"
19 |
20 | composer-compat:
21 | composer config "platform.ext-mongo" "1.6.16"
22 | composer require alcaeus/mongo-php-adapter --no-update
23 |
24 | composer-config-beta:
25 | composer config "minimum-stability" "beta"
26 |
27 | composer-install:
28 | rm -f composer.lock && cp composer.json composer.json~
29 | [[ -v SYMFONY_VERSION ]] && composer require "symfony/symfony:${SYMFONY_VERSION}" --no-update || true
30 | composer update --prefer-dist --no-interaction
31 | mv composer.json~ composer.json
32 |
33 | phpunit:
34 | vendor/bin/phpunit
35 |
36 | # TODO: output to COV
37 | phpunit-coverage:
38 | phpdbg -qrr vendor/bin/phpunit --coverage-text
39 |
--------------------------------------------------------------------------------
/Model/AccessToken.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | class AccessToken extends Token implements AccessTokenInterface
17 | {
18 | }
19 |
--------------------------------------------------------------------------------
/Model/AccessTokenInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | use OAuth2\Model\IOAuth2AccessToken;
17 |
18 | interface AccessTokenInterface extends TokenInterface, IOAuth2AccessToken
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Model/AccessTokenManagerInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | interface AccessTokenManagerInterface extends TokenManagerInterface
17 | {
18 | }
19 |
--------------------------------------------------------------------------------
/Model/AuthCode.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | /**
17 | * @author Richard Fullmer
18 | */
19 | class AuthCode extends Token implements AuthCodeInterface
20 | {
21 | protected string $redirectUri;
22 |
23 | /**
24 | * {@inheritdoc}
25 | */
26 | public function setRedirectUri( string $redirectUri)
27 | {
28 | $this->redirectUri = $redirectUri;
29 | }
30 |
31 | /**
32 | * {@inheritdoc}
33 | */
34 | public function getRedirectUri(): string
35 | {
36 | return $this->redirectUri;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Model/AuthCodeInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | use OAuth2\Model\IOAuth2AuthCode;
17 |
18 | /**
19 | * @author Richard Fullmer
20 | */
21 | interface AuthCodeInterface extends TokenInterface, IOAuth2AuthCode
22 | {
23 | /**
24 | * @param string $redirectUri
25 | */
26 | public function setRedirectUri( string $redirectUri );
27 | }
28 |
--------------------------------------------------------------------------------
/Model/AuthCodeManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | abstract class AuthCodeManager implements AuthCodeManagerInterface
17 | {
18 | /**
19 | * {@inheritdoc}
20 | */
21 | public function createAuthCode(): AuthCodeInterface
22 | {
23 | $class = $this->getClass();
24 |
25 | return new $class();
26 | }
27 |
28 | /**
29 | * {@inheritdoc}
30 | */
31 | public function findAuthCodeByToken(string $token): ?AuthCodeInterface
32 | {
33 | return $this->findAuthCodeBy(['token' => $token]);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Model/AuthCodeManagerInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | /**
17 | * @author Richard Fullmer
18 | */
19 | interface AuthCodeManagerInterface
20 | {
21 | /**
22 | * Create a new auth code.
23 | */
24 | public function createAuthCode(): AuthCodeInterface;
25 |
26 | /**
27 | * Return the class name.
28 | */
29 | public function getClass(): string;
30 |
31 | /**
32 | * Retrieve an auth code using a set of criteria.
33 | */
34 | public function findAuthCodeBy(array $criteria): ?AuthCodeInterface;
35 |
36 | /**
37 | * Retrieve an auth code by its token.
38 | */
39 | public function findAuthCodeByToken(string $token): ?AuthCodeInterface;
40 |
41 | /**
42 | * Update a given auth code.
43 | */
44 | public function updateAuthCode(AuthCodeInterface $authCode);
45 |
46 | /**
47 | * Delete a given auth code.
48 | */
49 | public function deleteAuthCode(AuthCodeInterface $authCode);
50 |
51 | /**
52 | * Delete expired auth codes.
53 | */
54 | public function deleteExpired(): int;
55 | }
56 |
--------------------------------------------------------------------------------
/Model/Client.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | use FOS\OAuthServerBundle\Util\Random;
17 | use OAuth2\OAuth2;
18 |
19 | class Client implements ClientInterface
20 | {
21 | /**
22 | * @var int
23 | */
24 | protected $id;
25 |
26 | protected ?string $randomId = null;
27 |
28 | protected ?string $secret = null;
29 |
30 | protected array $redirectUris = [];
31 |
32 | protected array $allowedGrantTypes = [];
33 |
34 | public function __construct()
35 | {
36 | $this->allowedGrantTypes[] = OAuth2::GRANT_TYPE_AUTH_CODE;
37 |
38 | $this->setRandomId(Random::generateToken());
39 | $this->setSecret(Random::generateToken());
40 | }
41 |
42 | public function getId()
43 | {
44 | return $this->id;
45 | }
46 |
47 | /**
48 | * {@inheritdoc}
49 | */
50 | public function setRandomId(string $random)
51 | {
52 | $this->randomId = $random;
53 | }
54 |
55 | /**
56 | * {@inheritdoc}
57 | */
58 | public function getRandomId(): ?string
59 | {
60 | return $this->randomId;
61 | }
62 |
63 | /**
64 | * {@inheritdoc}
65 | */
66 | public function getPublicId(): string
67 | {
68 | return sprintf('%s_%s', $this->getId(), $this->getRandomId());
69 | }
70 |
71 | /**
72 | * {@inheritdoc}
73 | */
74 | public function setSecret($secret)
75 | {
76 | $this->secret = $secret;
77 | }
78 |
79 | /**
80 | * {@inheritdoc}
81 | */
82 | public function getSecret(): ?string
83 | {
84 | return $this->secret;
85 | }
86 |
87 | /**
88 | * {@inheritdoc}
89 | */
90 | public function checkSecret(?string $secret): bool
91 | {
92 | return null === $this->secret || $secret === $this->secret;
93 | }
94 |
95 | /**
96 | * {@inheritdoc}
97 | */
98 | public function setRedirectUris(array $redirectUris)
99 | {
100 | $this->redirectUris = $redirectUris;
101 | }
102 |
103 | /**
104 | * {@inheritdoc}
105 | */
106 | public function getRedirectUris(): array
107 | {
108 | return $this->redirectUris;
109 | }
110 |
111 | /**
112 | * {@inheritdoc}
113 | */
114 | public function setAllowedGrantTypes(array $grantTypes)
115 | {
116 | $this->allowedGrantTypes = $grantTypes;
117 | }
118 |
119 | /**
120 | * {@inheritdoc}
121 | */
122 | public function getAllowedGrantTypes(): array
123 | {
124 | return $this->allowedGrantTypes;
125 | }
126 |
127 | public function getRoles(): array
128 | {
129 | return ['ROLE_USER'];
130 | }
131 |
132 | public function getPassword(): string
133 | {
134 | if (null === $this->secret) {
135 | throw new \LogicException('The client has no secret.');
136 | }
137 | return $this->getSecret();
138 | }
139 |
140 | public function getSalt(): ?string
141 | {
142 | // Will use auto salt system
143 | return null;
144 | }
145 |
146 | public function eraseCredentials(): void
147 | {
148 | // nothind to erase
149 | }
150 |
151 | public function getUsername(): string
152 | {
153 | return $this->getRandomId();
154 | }
155 |
156 | public function getUserIdentifier(): string
157 | {
158 | return $this->getRandomId();
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/Model/ClientInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | use OAuth2\Model\IOAuth2Client;
17 |
18 | interface ClientInterface extends IOAuth2Client
19 | {
20 | public function setRandomId(string $random);
21 |
22 | public function getRandomId(): ?string;
23 |
24 | public function setSecret(string $secret);
25 |
26 | public function checkSecret(?string $secret): bool;
27 |
28 | public function getSecret(): ?string;
29 |
30 | public function setRedirectUris(array $redirectUris);
31 |
32 | public function setAllowedGrantTypes(array $grantTypes);
33 |
34 | public function getAllowedGrantTypes(): ?array;
35 | }
36 |
--------------------------------------------------------------------------------
/Model/ClientManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | abstract class ClientManager implements ClientManagerInterface
17 | {
18 | /**
19 | * {@inheritdoc}
20 | */
21 | public function createClient(): ClientInterface
22 | {
23 | $class = $this->getClass();
24 |
25 | return new $class();
26 | }
27 |
28 | /**
29 | * {@inheritdoc}
30 | */
31 | public function findClientByPublicId($publicId): ?ClientInterface
32 | {
33 | if (false === $pos = mb_strpos($publicId, '_')) {
34 | return null;
35 | }
36 |
37 | $id = mb_substr($publicId, 0, $pos);
38 | $randomId = mb_substr($publicId, $pos + 1);
39 |
40 | return $this->findClientBy([
41 | 'id' => $id,
42 | 'randomId' => $randomId,
43 | ]);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Model/ClientManagerInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | interface ClientManagerInterface
17 | {
18 | public function createClient(): ClientInterface;
19 |
20 | public function getClass(): string;
21 |
22 | public function findClientBy(array $criteria): ?ClientInterface;
23 |
24 | /**
25 | * @param mixed $publicId
26 | */
27 | public function findClientByPublicId($publicId): ?ClientInterface;
28 |
29 | public function updateClient(ClientInterface $client);
30 |
31 | public function deleteClient(ClientInterface $client);
32 | }
33 |
--------------------------------------------------------------------------------
/Model/RefreshToken.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | class RefreshToken extends Token implements RefreshTokenInterface
17 | {
18 | }
19 |
--------------------------------------------------------------------------------
/Model/RefreshTokenInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | use OAuth2\Model\IOAuth2RefreshToken;
17 |
18 | interface RefreshTokenInterface extends TokenInterface, IOAuth2RefreshToken
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/Model/RefreshTokenManagerInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | interface RefreshTokenManagerInterface extends TokenManagerInterface
17 | {
18 | }
19 |
--------------------------------------------------------------------------------
/Model/Token.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | use Symfony\Component\Security\Core\User\UserInterface;
17 |
18 | class Token implements TokenInterface
19 | {
20 | /**
21 | * @var int
22 | */
23 | protected $id;
24 |
25 | protected ClientInterface $client;
26 |
27 | protected string $token;
28 |
29 | protected ?int $expiresAt = null;
30 |
31 | protected ?string $scope = null;
32 |
33 | protected ?UserInterface $user = null;
34 |
35 | public function getId()
36 | {
37 | return $this->id;
38 | }
39 |
40 | /**
41 | * {@inheritdoc}
42 | */
43 | public function getClientId(): string
44 | {
45 | return $this->getClient()->getPublicId();
46 | }
47 |
48 | /**
49 | * {@inheritdoc}
50 | */
51 | public function setExpiresAt(?int $timestamp)
52 | {
53 | $this->expiresAt = $timestamp;
54 | }
55 |
56 | /**
57 | * {@inheritdoc}
58 | */
59 | public function getExpiresAt(): ?int
60 | {
61 | return $this->expiresAt;
62 | }
63 |
64 | /**
65 | * {@inheritdoc}
66 | */
67 | public function getExpiresIn(): int
68 | {
69 | if ($this->expiresAt) {
70 | return $this->expiresAt - time();
71 | }
72 |
73 | return PHP_INT_MAX;
74 | }
75 |
76 | /**
77 | * {@inheritdoc}
78 | */
79 | public function hasExpired(): bool
80 | {
81 | if ($this->expiresAt) {
82 | return time() > $this->expiresAt;
83 | }
84 |
85 | return false;
86 | }
87 |
88 | /**
89 | * {@inheritdoc}
90 | */
91 | public function setToken(string $token)
92 | {
93 | $this->token = $token;
94 | }
95 |
96 | /**
97 | * {@inheritdoc}
98 | */
99 | public function getToken(): string
100 | {
101 | return $this->token;
102 | }
103 |
104 | /**
105 | * {@inheritdoc}
106 | */
107 | public function setScope(?string $scope)
108 | {
109 | $this->scope = $scope;
110 | }
111 |
112 | /**
113 | * {@inheritdoc}
114 | */
115 | public function getScope(): ?string
116 | {
117 | return $this->scope;
118 | }
119 |
120 | /**
121 | * {@inheritdoc}
122 | */
123 | public function setUser(?UserInterface $user)
124 | {
125 | $this->user = $user;
126 | }
127 |
128 | /**
129 | * {@inheritdoc}
130 | */
131 | public function getUser(): ?UserInterface
132 | {
133 | return $this->user;
134 | }
135 |
136 | /**
137 | * {@inheritdoc}
138 | *
139 | * @return mixed
140 | */
141 | public function getData()
142 | {
143 | return $this->getUser();
144 | }
145 |
146 | /**
147 | * {@inheritdoc}
148 | */
149 | public function setClient(ClientInterface $client)
150 | {
151 | $this->client = $client;
152 | }
153 |
154 | /**
155 | * {@inheritdoc}
156 | */
157 | public function getClient()
158 | {
159 | return $this->client;
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/Model/TokenInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | use OAuth2\Model\IOAuth2Token;
17 | use Symfony\Component\Security\Core\User\UserInterface;
18 |
19 | interface TokenInterface extends IOAuth2Token
20 | {
21 | public function setExpiresAt(?int $timestamp);
22 |
23 | public function getExpiresAt(): ?int;
24 |
25 | public function setToken(string $token);
26 |
27 | public function setScope(string $scope);
28 |
29 | public function setUser(UserInterface $user);
30 |
31 | public function getUser(): ?UserInterface;
32 |
33 | public function setClient(ClientInterface $client);
34 | }
35 |
--------------------------------------------------------------------------------
/Model/TokenManager.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | abstract class TokenManager implements TokenManagerInterface
17 | {
18 | /**
19 | * {@inheritdoc}
20 | */
21 | public function createToken(): TokenInterface
22 | {
23 | $class = $this->getClass();
24 |
25 | return new $class();
26 | }
27 |
28 | /**
29 | * {@inheritdoc}
30 | */
31 | public function findTokenByToken($token): ?TokenInterface
32 | {
33 | return $this->findTokenBy(['token' => $token]);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Model/TokenManagerInterface.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * For the full copyright and license information, please view the LICENSE
11 | * file that was distributed with this source code.
12 | */
13 |
14 | namespace FOS\OAuthServerBundle\Model;
15 |
16 | interface TokenManagerInterface
17 | {
18 | /**
19 | * Create a new TokenInterface.
20 | */
21 | public function createToken(): TokenInterface;
22 |
23 | /**
24 | * Return the class name of the Token.
25 | */
26 | public function getClass(): string;
27 |
28 | /**
29 | * Retrieve a token using a set of criteria.
30 | */
31 | public function findTokenBy(array $criteria): ?TokenInterface;
32 |
33 | /**
34 | * Retrieve a token (object) by its token string.
35 | */
36 | public function findTokenByToken(string $token): ?TokenInterface;
37 |
38 | /**
39 | * Save or update a given token.
40 | */
41 | public function updateToken(TokenInterface $token);
42 |
43 | /**
44 | * Delete a given token.
45 | */
46 | public function deleteToken(TokenInterface $token);
47 |
48 | /**
49 | * Delete expired tokens.
50 | */
51 | public function deleteExpired(): int;
52 | }
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | FOSOAuthServerBundle
2 | ====================
3 | [](https://github.com/klapaudius/FOSOAuthServerBundle/actions/workflows/php.yml)
4 | [](https://codecov.io/gh/klapaudius/FOSOAuthServerBundle)
5 | 
6 |
7 | ## Documentation
8 |
9 | The bulk of the documentation is stored in the `Resources/doc/index.md` file in this bundle:
10 |
11 | [Read the Documentation for master](https://github.com/klapaudius/FOSOAuthServerBundle/blob/master/Resources/doc/index.md)
12 |
13 | ## Repository history
14 |
15 | This repository has been initialy created to remove the deprecated warnings on Symfony 4.2 since several pull requests were not reviewed on FriendsOfSymfony/FOSOAuthServerBundle.
16 | It is actively maintained and works on Symfony 5 (branch 3.0), Symfony 6 (branch 4.0) and Symfony 7 (branch 5.0 / 5.1).
17 |
18 | Feel free to PR.
19 |
20 | ## License
21 |
22 | This bundle is under the MIT license. See the complete license in the bundle:
23 |
24 | Resources/meta/LICENSE
25 |
26 |
27 | ## Credits
28 |
29 | - Boris AUBE
30 | - Arnaud Le Blanc, and [all contributors](https://github.com/klapaudius/FOSOAuthServerBundle/contributors)
31 | - Inspired by [BazingaOAuthBundle](https://github.com/willdurand/BazingaOAuthServerBundle) and [FOSUserBundle](https://github.com/FriendsOfSymfony/FOSUserBundle)
32 | - Installation doc adapted from [FOSUserBundle](https://github.com/FriendsOfSymfony/FOSUserBundle) doc.
33 |
--------------------------------------------------------------------------------
/Resources/config/authorize.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 | %fos_oauth_server.authorize.form.name%
10 | %fos_oauth_server.authorize.form.type%
11 | null
12 |
13 | %fos_oauth_server.authorize.form.validation_groups%
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Resources/config/couchdb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 | %fos_oauth_server.model.client.class%
11 |
12 |
13 |
14 |
15 | %fos_oauth_server.model.access_token.class%
16 |
17 |
18 |
19 |
20 | %fos_oauth_server.model.auth_code.class%
21 |
22 |
23 |
24 |
25 | %fos_oauth_server.model.refresh_token.class%
26 |
27 |
28 |
29 | %fos_oauth_server.model_manager_name%
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/AccessToken.couchdb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/AccessToken.mongodb.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/AccessToken.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/AuthCode.couchdb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/AuthCode.mongodb.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/AuthCode.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/Client.couchdb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/Client.mongodb.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/Client.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/RefreshToken.couchdb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/RefreshToken.mongodb.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/RefreshToken.orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Resources/config/mongodb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 | %fos_oauth_server.model.client.class%
11 |
12 |
13 |
14 |
15 | %fos_oauth_server.model.access_token.class%
16 |
17 |
18 |
19 |
20 | %fos_oauth_server.model.auth_code.class%
21 |
22 |
23 |
24 |
25 | %fos_oauth_server.model.refresh_token.class%
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Resources/config/oauth.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | OAuth2\OAuth2
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | %fos_oauth_server.server.options%
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Resources/config/orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 | %fos_oauth_server.model.client.class%
11 |
12 |
13 |
14 |
15 | %fos_oauth_server.model.access_token.class%
16 |
17 |
18 |
19 |
20 | %fos_oauth_server.model.refresh_token.class%
21 |
22 |
23 |
24 |
25 | %fos_oauth_server.model.auth_code.class%
26 |
27 |
28 |
29 | %fos_oauth_server.model_manager_name%
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Resources/config/routing/authorize.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | fos_oauth_server.controller.authorize::authorizeAction
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/config/routing/token.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | fos_oauth_server.controller.token::tokenAction
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/config/security.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | FOS\OAuthServerBundle\Security\EntryPoint\OAuthEntryPoint
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Resources/config/validation.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Resources/doc/a_note_about_security.md:
--------------------------------------------------------------------------------
1 | A Note About Security
2 | =====================
3 |
4 | ## OAuth Implementation with Flawed Session Management
5 |
6 | As described in this great article about [OAuth Authorization attacks](http://software-security.sans.org/blog/2011/03/07/oauth-authorization-attacks-secure-implementation),
7 | if you use the same firewall for the `authorization` page, and for the rest of your application, a malicious user with access to the unattended
8 | browser can use the user's session.
9 |
10 | To protect against that, the FOSOAuthServerBundle comes with a built-in solution.
11 | In the `loginAction()` of your `SecurityController`, just add few lines before to render the response:
12 |
13 | ``` php
14 | getSession();
28 |
29 | // get the login error if there is one
30 | if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
31 | $error = $request->attributes->get(Security::AUTHENTICATION_ERROR);
32 | } else {
33 | $error = $session->get(Security::AUTHENTICATION_ERROR);
34 | $session->remove(Security::AUTHENTICATION_ERROR);
35 | }
36 |
37 | // Add the following lines
38 | if ($session->has('_security.target_path')) {
39 | if (false !== strpos($session->get('_security.target_path'), $this->generateUrl('fos_oauth_server_authorize'))) {
40 | $session->set('_fos_oauth_server.ensure_logout', true);
41 | }
42 | }
43 |
44 | return $this->render('AcmeSecurityBundle:Security:login.html.twig', array(
45 | // last username entered by the user
46 | 'last_username' => $session->get(Security::LAST_USERNAME),
47 | 'error' => $error,
48 | ));
49 | }
50 | }
51 | ```
52 |
53 | Now, when a user will login in order to access the Authorization page, he will be logged out just after his action.
54 | But, in the same time, if he is already logged, he won't be logged out.
55 |
56 |
57 | ## SSL
58 |
59 | Even if the FOSOAuthServerBundle doesn't enforce that, the use of TLS/SSL is the recommended approach.
60 |
61 |
62 | [Back to index](index.md)
63 |
--------------------------------------------------------------------------------
/Resources/doc/adding_grant_extensions.md:
--------------------------------------------------------------------------------
1 | Adding Grant Extensions
2 | =======================
3 |
4 | OAuth2 allows to use [grant extensions](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.5).
5 | It will let you define your own new *grant_types*, when legacy grant_types do not cover your requirements.
6 |
7 | Like classic grants, the grant extensions still requires valid client credentials, and the grant extension has to be added on the `allowedGrantTypes` property of the client.
8 |
9 | ## Creating the GrantExtension
10 |
11 | The GrantExtension class responsibility is to grant an access token, or not, based on the request parameters/headers.
12 |
13 | To illustrate the use of a new grant extension, we'll create one that grants access_token like the bingo game. This is of course not something to do :)
14 |
15 | ### Create your extension class:
16 |
17 | ``` php
18 | $userManager->findRandomUser()
54 | );
55 | }
56 |
57 | if ($numberToGuess1 == $inputData['number_1'] || $numberToGuess2 == $inputData['number_2']) {
58 | // Only one of the numbers were guessed
59 | // We grant a simple access token
60 |
61 | return true;
62 | }
63 |
64 | return false; // No number guessed, the grant will fail
65 | }
66 | }
67 | ```
68 |
69 | ### Register the extension
70 |
71 | You then have to register your class as a service, add the tag `fos_oauth_server.grant_extension` with the uri parameter (ie: the name of your grant type).
72 |
73 | ``` yaml
74 | services:
75 | acme.api.oauth.bingo_extension:
76 | class: Acme\ApiBundle\OAuth\BingoGrantExtension
77 | tags:
78 | - { name: fos_oauth_server.grant_extension, uri: 'http://acme.com/grants/bingo' }
79 | ```
80 |
81 | ### Usage
82 |
83 | ```
84 | $ curl -XGET "http://acme.com/oauth/v2/token? \
85 | grant_type=http://acme.com/grants/bingo& \
86 | client_id=1_1& \
87 | client_secret=secret& \
88 | number_1=42& \
89 | number_2=66"
90 | ```
91 |
--------------------------------------------------------------------------------
/Resources/doc/configuration_reference.md:
--------------------------------------------------------------------------------
1 | FOSOAuthServerBundle Configuration Reference
2 | ============================================
3 |
4 | All available configuration options are listed below with their default values.
5 |
6 | ``` yaml
7 | fos_oauth_server:
8 | db_driver: ~ # Required. Available: mongodb, orm
9 | client_class: ~ # Required
10 | access_token_class: ~ # Required
11 | refresh_token_class: ~ # Required
12 | auth_code_class: ~ # Required
13 | model_manager_name: ~ # change it to the name of your entity/document manager if you don't want to use the default one.
14 | authorize:
15 | form:
16 | type: fos_oauth_server_authorize
17 | handler: fos_oauth_server.authorize.form.handler.default
18 | name: fos_oauth_server_authorize_form
19 | validation_groups:
20 |
21 | # Defaults:
22 | - Authorize
23 | - Default
24 | service:
25 | storage: fos_oauth_server.storage.default
26 | user_provider: ~
27 | client_manager: fos_oauth_server.client_manager.default
28 | access_token_manager: fos_oauth_server.access_token_manager.default
29 | refresh_token_manager: fos_oauth_server.refresh_token_manager.default
30 | auth_code_manager: fos_oauth_server.auth_code_manager.default
31 | options:
32 | # Prototype
33 | key: []
34 |
35 | # Example
36 | # supported_scopes: string
37 |
38 | # Changing tokens and authcode lifetime
39 | #access_token_lifetime: 3600
40 | #refresh_token_lifetime: 1209600
41 | #auth_code_lifetime: 30
42 |
43 | # Token type to respond with. Currently only "Bearer" supported.
44 | #token_type: string
45 |
46 | #realm:
47 |
48 | # Enforce redirect_uri on input for both authorize and token steps.
49 | #enforce_redirect: true or false
50 |
51 | # Enforce state to be passed in authorization (see RFC 6749, section 10.12)
52 | #enforce_state: true or false
53 | ```
54 |
55 | [Back to index](index.md)
56 |
--------------------------------------------------------------------------------
/Resources/doc/custom_db_driver.md:
--------------------------------------------------------------------------------
1 | Custom db driver.
2 | =================
3 |
4 | The bundle provides drivers for Doctrine ORM and Doctrine MongoDB libraries.
5 | Though sometimes you might want to use the bundle with a custom or in-house written storage.
6 | For that, the bundle has support for custom storage.
7 | Once set, setting manager options in fos_oauth_server.service section becomes mandatory.
8 |
9 | Here's an example of custom configuration:
10 |
11 | ```yaml
12 | # config/packages/fos_oauth_server.yaml
13 |
14 | fos_oauth_server:
15 | db_driver: custom
16 | service:
17 | user_provider: 'user_provider_manager_service_id'
18 | client_manager: 'client_provider_manager_service_id'
19 | access_token_manager: 'access_token_manager_service_id'
20 | refresh_token_manager: 'refresh_token_manager_service_id'
21 | auth_code_manager: 'auth_code_manager_service_id'
22 |
23 | ```
24 |
25 | [Back to index](index.md)
26 |
27 |
--------------------------------------------------------------------------------
/Resources/doc/dealing_with_scopes.md:
--------------------------------------------------------------------------------
1 | Dealing With Scopes
2 | ===================
3 |
4 | OAuth2 allows to use [access token scopes](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.3).
5 | Scopes are what you want, there is not real constraint except to list scopes as a list of strings separated by a space:
6 |
7 | scope1 scope2
8 |
9 | That's why the `scope` column in the model layer is a string, not an array for instance.
10 |
11 |
12 | ## Configuring scopes
13 |
14 | To configure allowed scopes in your application, you have to edit your `app/config/config.yml` file:
15 |
16 | ``` yaml
17 | # app/config/config.yml
18 | fos_oauth_server:
19 | service:
20 | options:
21 | supported_scopes:
22 | - scope1
23 | - scope2
24 | - scope3
25 | - scope4
26 | ```
27 |
28 | If you have a short list of scopes, you can define them as a simple string:
29 | ``` yaml
30 | # app/config/config.yml
31 | fos_oauth_server:
32 | service:
33 | options:
34 | supported_scopes: scope1 scope2
35 | ```
36 |
37 |
38 | Now, clients will be able to pass a `scope` parameter when they request an access token.
39 |
40 |
41 | ## Using scopes
42 |
43 | The default behavior of the FOSOAuthServerBundle is to use scopes as [roles](http://symfony.com/doc/master/book/security.html#roles).
44 | In the previous example, it would allow us to use the roles `ROLE_SCOPE1`, and `ROLE_SCOPE2` (scopes are automatically uppercased).
45 |
46 | That way, you can configure the `access_control` section of the security layer:
47 |
48 | ``` yaml
49 | # app/config/security.yml
50 | security:
51 | access_control:
52 | - { path: ^/api/super/secured, role: ROLE_SCOPE1 }
53 | ```
54 |
55 | For more information, you can read the [Security documentation](http://symfony.com/doc/master/book/security.html#authorization).
56 |
57 |
58 | [Back to index](index.md)
59 |
--------------------------------------------------------------------------------
/Resources/doc/extending_the_authorization_page.md:
--------------------------------------------------------------------------------
1 | Extending the Authorization page
2 | ================================
3 |
4 | The "Authorization Page" is the page you will present to your users, in order to ask them to share their
5 | data with a third-party consumer. This is most of the time a page with two buttons _Deny_, and _Allow_.
6 |
7 | By default, the FOSOAuthServerBundle's authorization page is really basic, and it's probably a good idea to improve it.
8 |
9 | The first step is to copy the [`authorize_content.html.twig`](https://github.com/klapaudius/FOSOAuthServerBundle/blob/master/Resources/views/Authorize/authorize_content.html.twig) template to the `app/Resources/FOSOAuthServerBundle/views/Authorize/` directory.
10 |
11 | You're almost done, now you just have to customize it. By default a _client_ in the FOSOAuthServerBundle
12 | doesn't have any _name_ or _title_ because it depends on your application, and what you really need.
13 | But most of the time, you will give a name to each of your clients, this part is described in the [extending the model](extending_the_model.md) section.
14 |
15 | Now, assuming your clients have a nice _name_, it's a pretty nice idea to expose it to your
16 | users. That way, they will know which consumer asks for their data. If you take a look at the `AuthorizeController`,
17 | you will see a `client` variable which is passed to the templating engine. That means you can use it in your custom template:
18 |
19 | ``` html+jinja
20 |
The application "{{ client.name }}" would like to connect to your account
21 |
22 | {{ form_start(form, {'method': 'POST', 'action': path('fos_oauth_server_authorize'), 'label_attr': {'class': 'fos_oauth_server_authorize'} }) }}
23 |
24 |
25 |
26 | {{ form_row(form.client_id) }}
27 | {{ form_row(form.response_type) }}
28 | {{ form_row(form.redirect_uri) }}
29 | {{ form_row(form.state) }}
30 | {{ form_row(form.scope) }}
31 | {{ form_rest(form) }}
32 |
33 | ```
34 |
35 | [Back to index](index.md)
36 |
--------------------------------------------------------------------------------
/Resources/doc/extending_the_model.md:
--------------------------------------------------------------------------------
1 | Extending the Model
2 | ===================
3 |
4 | This bundle provides a complete solution to quickly setup an OAuth2 security layer for your APIs.
5 | But, as all applications are often different, the bundle has a basic database model.
6 | Thanks to an abstraction layer (see the `Model/` directory), it's really easy to deal with various
7 | database abstraction layers, but in the same time to extend each layer. In this chapter, you will see
8 | how to properly extend the model of the FOSOAuthServerBundle to add your business logic.
9 |
10 | [Back to index](index.md)
11 |
--------------------------------------------------------------------------------
/Resources/doc/the_oauth_event_class.md:
--------------------------------------------------------------------------------
1 | The OAuthEvent class
2 | ====================
3 |
4 | When a user accepts to share his data with a client, it's a nice idea to save this state.
5 | By default, the FOSOAuthServerBundle will always show the authorization page to the user
6 | when an access token is asked. As an access token has a lifetime, it can be annoying for your
7 | users to always accept a client.
8 |
9 | Thanks to the [Event Dispatcher](http://symfony.com/doc/current/components/event_dispatcher.html),
10 | you can listen before, and after the authorization form process. So, you can save the user's choice,
11 | and even bypass the authorization process. Let's look at an example.
12 |
13 | Assuming we have a _Many to Many_ relation between clients, and users. An `OAuthEvent` contains
14 | a `ClientInterface` instance, a `UserInterface` instance (coming from the [Security Component](http://symfony.com/doc/current/book/security.html)),
15 | and a flag to determine whether the client has been accepted, or not.
16 |
17 | ### Registering the listener
18 |
19 | ``` yaml
20 | services:
21 | oauth_event_listener:
22 | class: Acme\DemoBundle\EventListener\OAuthEventListener
23 | tags:
24 | - { name: kernel.event_listener, event: fos_oauth_server.pre_authorization_process, method: onPreAuthorizationProcess }
25 | - { name: kernel.event_listener, event: fos_oauth_server.post_authorization_process, method: onPostAuthorizationProcess }
26 | ```
27 |
28 |
29 | ### Next?
30 |
31 | You can build a panel for your users displaying this list. If they remove an entry from this list,
32 | then the authorization page will be displayed to the user like the first time. And, if the user
33 | accepts the client, then the system will save this client to the user's list once again.
34 |
35 |
36 | [Back to index](index.md)
37 |
--------------------------------------------------------------------------------
/Resources/meta/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011-2012 FriendsOfSymfony
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Resources/translations/FOSOAuthServerBundle.de.yml:
--------------------------------------------------------------------------------
1 | lang: "de"
2 | title: "Authentifizierung"
3 | authorize:
4 | accept: "Erlauben"
5 | reject: "Verweigern"
6 |
--------------------------------------------------------------------------------
/Resources/translations/FOSOAuthServerBundle.en.yml:
--------------------------------------------------------------------------------
1 | lang: "en"
2 | title: "authentication"
3 | authorize:
4 | accept: "Allow"
5 | reject: "Deny"
6 |
--------------------------------------------------------------------------------
/Resources/translations/FOSOAuthServerBundle.fr.yml:
--------------------------------------------------------------------------------
1 | lang: "fr"
2 | title: "Authentification"
3 | authorize:
4 | accept: "Accepter"
5 | reject: "Refuser"
6 |
--------------------------------------------------------------------------------
/Resources/translations/FOSOAuthServerBundle.sl.yml:
--------------------------------------------------------------------------------
1 | lang: "sl"
2 | title: "Avtentikacija"
3 | authorize:
4 | accept: "Dovoli"
5 | reject: "Ne dovoli"
6 |
--------------------------------------------------------------------------------
/Resources/views/Authorize/authorize.html.twig:
--------------------------------------------------------------------------------
1 | {% extends "@FOSOAuthServer/layout.html.twig" %}
2 |
3 | {% block fos_oauth_server_content %}
4 | {% include "@FOSOAuthServer/Authorize/authorize_content.html.twig" %}
5 | {% endblock fos_oauth_server_content %}
6 |
--------------------------------------------------------------------------------
/Resources/views/Authorize/authorize_content.html.twig:
--------------------------------------------------------------------------------
1 | {{ form_start(form, {'method': 'POST', 'action': path('fos_oauth_server_authorize'), 'label_attr': {'class': 'fos_oauth_server_authorize'} }) }}
2 |
3 |
4 |
5 | {{ form_row(form.client_id) }}
6 | {{ form_row(form.response_type) }}
7 | {{ form_row(form.redirect_uri) }}
8 | {{ form_row(form.state) }}
9 | {{ form_row(form.scope) }}
10 | {{ form_rest(form) }}
11 |
12 |
--------------------------------------------------------------------------------
/Resources/views/form.html.twig:
--------------------------------------------------------------------------------
1 |
2 | {%- block field_label -%}
3 |
4 | {%- endblock field_label -%}
5 |
--------------------------------------------------------------------------------
/Resources/views/layout.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% block title %}{{ 'title'|trans }}{% endblock %}
5 |
6 |
7 |
8 |