From 97ebb4faaa86e513102d75bf3c1fb2fe6cb1d307 Mon Sep 17 00:00:00 2001 From: Evan Sims Date: Fri, 8 Dec 2023 19:22:27 -0500 Subject: [PATCH] chore: Support Symfony 6.4 and PHP 8.1 (#165) --- .gitattributes | 19 + .gitignore | 3 + .php-cs-fixer.dist.php | 230 ++++++++ .phpcs-compat.xml.dist | 16 - .phpcs.xml.dist | 115 ---- .semgrepignore | 2 + .styleci.yml | 258 -------- README.md | 4 +- composer.json | 100 ++-- example/.editorconfig | 12 + example/.env.example | 54 ++ example/.env.test | 6 + example/.gitignore | 22 + example/README.md | 97 +++ example/bin/console | 17 + example/composer.json | 129 ++++ example/config/bundles.php | 16 + example/config/packages/auth0.yaml | 27 + example/config/packages/cache.yaml | 22 + example/config/packages/debug.yaml | 5 + example/config/packages/doctrine.yaml | 45 ++ .../config/packages/doctrine_migrations.yaml | 6 + example/config/packages/framework.yaml | 24 + example/config/packages/http_discovery.yaml | 10 + example/config/packages/mailer.yaml | 3 + example/config/packages/messenger.yaml | 24 + example/config/packages/monolog.yaml | 61 ++ example/config/packages/notifier.yaml | 16 + example/config/packages/nyholm_psr7.yaml | 21 + example/config/packages/routing.yaml | 12 + example/config/packages/security.yaml | 36 ++ .../packages/sensio_framework_extra.yaml | 3 + example/config/packages/translation.yaml | 6 + example/config/packages/twig.yaml | 6 + example/config/packages/validator.yaml | 8 + example/config/packages/web_profiler.yaml | 17 + example/config/preload.php | 5 + example/config/routes.yaml | 39 ++ example/config/routes/framework.yaml | 4 + example/config/routes/web_profiler.yaml | 8 + example/config/services.yaml | 24 + example/migrations/.gitignore | 0 example/phpunit.xml.dist | 38 ++ example/public/index.php | 9 + .../Command/RegenerateAppSecretCommand.php | 50 ++ example/src/Controller/.gitignore | 0 example/src/Controller/ExampleController.php | 69 +++ example/src/Entity/.gitignore | 0 example/src/Kernel.php | 11 + example/src/Repository/.gitignore | 0 example/symfony.lock | 282 +++++++++ example/templates/base.html.twig | 19 + example/tests/bootstrap.php | 11 + example/translations/.gitignore | 0 phpdoc.dist.xml | 23 + phpstan.neon.dist | 43 +- phpunit.xml.dist | 24 +- pint.json | 4 - psalm.xml.dist | 6 + rector.php | 553 +++++++++++++++++- src/Auth0Bundle.php | 147 +++-- .../Exceptions/ExceptionInterface.php | 4 +- src/Contracts/Models/UserInterface.php | 3 +- src/Controllers/AuthenticationController.php | 78 +-- src/Exceptions/AuthenticationException.php | 6 +- src/Exceptions/TokenException.php | 19 +- src/Exceptions/UnsupportedUserException.php | 6 +- src/Exceptions/UserNotFoundException.php | 6 +- src/Models/Stateful/User.php | 2 + src/Models/User.php | 172 +++--- src/Security/Authenticator.php | 38 +- src/Security/Authorizer.php | 58 +- src/Security/UserProvider.php | 30 +- src/Service.php | 11 +- src/Stores/SessionStore.php | 69 ++- 75 files changed, 2540 insertions(+), 783 deletions(-) create mode 100644 .gitattributes create mode 100644 .php-cs-fixer.dist.php delete mode 100644 .phpcs-compat.xml.dist delete mode 100644 .phpcs.xml.dist create mode 100644 .semgrepignore delete mode 100644 .styleci.yml create mode 100644 example/.editorconfig create mode 100644 example/.env.example create mode 100644 example/.env.test create mode 100644 example/.gitignore create mode 100644 example/README.md create mode 100755 example/bin/console create mode 100644 example/composer.json create mode 100644 example/config/bundles.php create mode 100644 example/config/packages/auth0.yaml create mode 100644 example/config/packages/cache.yaml create mode 100644 example/config/packages/debug.yaml create mode 100644 example/config/packages/doctrine.yaml create mode 100644 example/config/packages/doctrine_migrations.yaml create mode 100644 example/config/packages/framework.yaml create mode 100644 example/config/packages/http_discovery.yaml create mode 100644 example/config/packages/mailer.yaml create mode 100644 example/config/packages/messenger.yaml create mode 100644 example/config/packages/monolog.yaml create mode 100644 example/config/packages/notifier.yaml create mode 100644 example/config/packages/nyholm_psr7.yaml create mode 100644 example/config/packages/routing.yaml create mode 100644 example/config/packages/security.yaml create mode 100644 example/config/packages/sensio_framework_extra.yaml create mode 100644 example/config/packages/translation.yaml create mode 100644 example/config/packages/twig.yaml create mode 100644 example/config/packages/validator.yaml create mode 100644 example/config/packages/web_profiler.yaml create mode 100644 example/config/preload.php create mode 100644 example/config/routes.yaml create mode 100644 example/config/routes/framework.yaml create mode 100644 example/config/routes/web_profiler.yaml create mode 100644 example/config/services.yaml create mode 100644 example/migrations/.gitignore create mode 100644 example/phpunit.xml.dist create mode 100644 example/public/index.php create mode 100644 example/src/Command/RegenerateAppSecretCommand.php create mode 100644 example/src/Controller/.gitignore create mode 100644 example/src/Controller/ExampleController.php create mode 100644 example/src/Entity/.gitignore create mode 100644 example/src/Kernel.php create mode 100644 example/src/Repository/.gitignore create mode 100644 example/symfony.lock create mode 100644 example/templates/base.html.twig create mode 100644 example/tests/bootstrap.php create mode 100644 example/translations/.gitignore create mode 100644 phpdoc.dist.xml delete mode 100644 pint.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..261c33f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,19 @@ +.github/ export-ignore +docs/ export-ignore +example/ export-ignore +tests/ export-ignore +vendor/ export-ignore +.editorconfig export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.php-cs-fixer.dist.php export-ignore +.semgrepignore export-ignore +.shiprc export-ignore +CHANGELOG.md export-ignore +opslevel.yml export-ignore +phpdoc.dist.xml export-ignore +phpstan.neon.dist export-ignore +phpunit.xml.dist export-ignore +psalm.xml.dist export-ignore +rector.php export-ignore +UPGRADE.md export-ignore diff --git a/.gitignore b/.gitignore index 65d7216..cd1c9f2 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,7 @@ composer.lock /example/composer.phar **/.DS_Store + .phpunit.result.cache +.php-cs-fixer.cache +/coverage/ diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..5a9e5d0 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,230 @@ +setRiskyAllowed(true) + ->setRules([ + 'array_indentation' => true, + 'array_push' => true, + 'array_syntax' => ['syntax' => 'short'], + 'assign_null_coalescing_to_coalesce_equal' => true, + 'backtick_to_shell_exec' => true, + 'binary_operator_spaces' => true, + 'blank_line_after_namespace' => true, + 'blank_line_after_opening_tag' => true, + 'blank_line_before_statement' => true, + 'blank_line_between_import_groups' => true, + 'braces' => true, + 'cast_spaces' => true, + 'class_attributes_separation' => ['elements' => ['const' => 'one', 'method' => 'one', 'property' => 'one', 'trait_import' => 'one', 'case' => 'one']], + 'class_definition' => ['multi_line_extends_each_single_line' => true, 'single_line' => true, 'single_item_single_line' => true, 'space_before_parenthesis' => false, 'inline_constructor_arguments' => false], + 'class_reference_name_casing' => true, + 'clean_namespace' => true, + 'combine_consecutive_issets' => true, + 'combine_consecutive_unsets' => true, + 'combine_nested_dirname' => true, + 'comment_to_phpdoc' => ['ignored_tags' => ['codeCoverageIgnoreStart', 'codeCoverageIgnoreEnd', 'phpstan-ignore-next-line']], + 'compact_nullable_typehint' => true, + 'concat_space' => ['spacing' => 'one'], + 'constant_case' => ['case' => 'lower'], + 'curly_braces_position' => ['control_structures_opening_brace' => 'same_line', 'functions_opening_brace' => 'next_line_unless_newline_at_signature_end', 'anonymous_functions_opening_brace' => 'same_line', 'classes_opening_brace' => 'next_line_unless_newline_at_signature_end', 'anonymous_classes_opening_brace' => 'same_line', 'allow_single_line_empty_anonymous_classes' => true, 'allow_single_line_anonymous_functions' => true], + 'date_time_create_from_format_call' => true, + 'date_time_immutable' => true, + 'declare_equal_normalize' => ['space' => 'none'], + 'declare_parentheses' => true, + 'declare_strict_types' => true, + 'dir_constant' => true, + 'doctrine_annotation_array_assignment' => true, + 'doctrine_annotation_braces' => true, + 'doctrine_annotation_indentation' => true, + 'doctrine_annotation_spaces' => true, + 'echo_tag_syntax' => ['format' => 'long'], + 'elseif' => true, + 'empty_loop_body' => true, + 'empty_loop_condition' => true, + 'encoding' => true, + 'ereg_to_preg' => true, + 'error_suppression' => true, + 'escape_implicit_backslashes' => true, + 'explicit_indirect_variable' => true, + 'explicit_string_variable' => true, + 'final_class' => true, + 'final_internal_class' => true, + 'final_public_method_for_abstract_class' => true, + 'fopen_flag_order' => true, + 'fopen_flags' => true, + 'full_opening_tag' => true, + 'fully_qualified_strict_types' => true, + 'function_declaration' => true, + 'function_to_constant' => true, + 'function_typehint_space' => true, + 'general_phpdoc_annotation_remove' => true, + 'general_phpdoc_tag_rename' => true, + 'get_class_to_class_keyword' => true, + 'global_namespace_import' => ['import_classes' => true, 'import_constants' => true, 'import_functions' => true], + 'group_import' => true, + 'heredoc_indentation' => true, + 'heredoc_to_nowdoc' => true, + 'implode_call' => true, + 'include' => true, + 'increment_style' => ['style' => 'pre'], + 'indentation_type' => true, + 'integer_literal_case' => true, + 'is_null' => true, + 'lambda_not_used_import' => true, + 'line_ending' => true, + 'linebreak_after_opening_tag' => true, + 'list_syntax' => ['syntax' => 'short'], + 'logical_operators' => true, + 'lowercase_cast' => true, + 'lowercase_keywords' => true, + 'lowercase_static_reference' => true, + 'magic_constant_casing' => true, + 'magic_method_casing' => true, + 'mb_str_functions' => false, + 'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline', 'after_heredoc' => true], + 'method_chaining_indentation' => true, + 'modernize_strpos' => true, + 'modernize_types_casting' => true, + 'multiline_comment_opening_closing' => true, + 'multiline_whitespace_before_semicolons' => true, + 'native_function_casing' => true, + 'native_function_invocation' => true, + 'native_function_type_declaration_casing' => true, + 'new_with_braces' => true, + 'no_alias_functions' => true, + 'no_alias_language_construct_call' => true, + 'no_alternative_syntax' => true, + 'no_binary_string' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_break_comment' => true, + 'no_closing_tag' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_homoglyph_names' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => true, + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_multiple_statements_per_line' => true, + 'no_php4_constructor' => true, + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_space_around_double_colon' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_around_offset' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_superfluous_elseif' => true, + 'no_trailing_comma_in_singleline' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_trailing_whitespace_in_string' => true, + 'no_trailing_whitespace' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unneeded_curly_braces' => true, + 'no_unneeded_final_method' => true, + 'no_unneeded_import_alias' => true, + 'no_unreachable_default_argument_value' => true, + 'no_unset_cast' => true, + 'no_unused_imports' => true, + 'no_useless_concat_operator' => true, + 'no_useless_else' => true, + 'no_useless_nullsafe_operator' => true, + 'no_useless_return' => true, + 'no_useless_sprintf' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'non_printable_character' => true, + 'normalize_index_brace' => true, + 'not_operator_with_successor_space' => true, + 'nullable_type_declaration_for_default_null_value' => true, + 'object_operator_without_whitespace' => true, + 'octal_notation' => true, + 'operator_linebreak' => true, + 'ordered_class_elements' => ['sort_algorithm' => 'alpha', 'order' => ['use_trait', 'case', 'constant', 'constant_private', 'constant_protected', 'constant_public', 'property_private', 'property_private_readonly', 'property_private_static', 'property_protected', 'property_protected_readonly', 'property_protected_static', 'property_public', 'property_public_readonly', 'property_public_static', 'property_static', 'protected', 'construct', 'destruct', 'magic', 'method', 'public', 'method_public', 'method_abstract', 'method_public_abstract', 'method_public_abstract_static', 'method_public_static', 'method_static', 'method_private', 'method_private_abstract', 'method_private_abstract_static', 'method_private_static', 'method_protected', 'method_protected_abstract', 'method_protected_abstract_static', 'method_protected_static', 'phpunit', 'private', 'property']], + 'ordered_imports' => ['sort_algorithm' => 'alpha', 'imports_order' => ['const', 'class', 'function']], + 'ordered_interfaces' => true, + 'ordered_traits' => true, + 'php_unit_fqcn_annotation' => true, + 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], + 'phpdoc_align' => ['align' => 'vertical'], + 'phpdoc_indent' => true, + 'phpdoc_inline_tag_normalizer' => true, + 'phpdoc_line_span' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_order_by_value' => true, + 'phpdoc_order' => true, + 'phpdoc_return_self_reference' => ['replacements' => ['this' => 'self']], + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_summary' => true, + 'phpdoc_tag_type' => true, + 'phpdoc_to_comment' => ['ignored_tags' => ['var']], + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_trim' => true, + 'phpdoc_types_order' => true, + 'phpdoc_types' => true, + 'phpdoc_var_annotation_correct_order' => true, + 'phpdoc_var_without_name' => true, + 'pow_to_exponentiation' => true, + 'protected_to_private' => true, + 'psr_autoloading' => true, + 'random_api_migration' => true, + 'regular_callable_call' => true, + 'return_assignment' => true, + 'return_type_declaration' => ['space_before' => 'none'], + 'return_type_declaration' => true, + 'self_accessor' => true, + 'self_static_accessor' => true, + 'semicolon_after_instruction' => true, + 'set_type_to_cast' => true, + 'short_scalar_cast' => true, + 'simple_to_complex_string_variable' => true, + 'simplified_if_return' => true, + 'single_blank_line_at_eof' => true, + 'single_blank_line_before_namespace' => true, + 'single_class_element_per_statement' => true, + 'single_line_after_imports' => true, + 'single_line_comment_spacing' => true, + 'single_line_comment_style' => ['comment_types' => ['hash']], + 'single_line_throw' => true, + 'single_quote' => true, + 'single_space_after_construct' => true, + 'single_space_around_construct' => true, + 'single_trait_insert_per_statement' => true, + 'space_after_semicolon' => true, + 'standardize_increment' => true, + 'standardize_not_equals' => true, + 'statement_indentation' => true, + 'static_lambda' => true, + 'strict_comparison' => true, + 'strict_param' => true, + 'string_length_to_empty' => true, + 'string_line_ending' => true, + 'switch_case_semicolon_to_colon' => true, + 'switch_case_space' => true, + 'switch_continue_to_break' => true, + 'ternary_operator_spaces' => true, + 'ternary_to_elvis_operator' => true, + 'ternary_to_null_coalescing' => true, + 'trailing_comma_in_multiline' => ['after_heredoc' => true, 'elements' => ['arguments', 'arrays', 'match', 'parameters']], + 'trim_array_spaces' => true, + 'types_spaces' => ['space' => 'single', 'space_multiple_catch' => 'single'], + 'unary_operator_spaces' => true, + 'use_arrow_functions' => true, + 'visibility_required' => true, + 'void_return' => true, + 'whitespace_after_comma_in_array' => true, + 'yoda_style' => true, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('vendor') + ->in([__DIR__.'/src/']) + ) +; diff --git a/.phpcs-compat.xml.dist b/.phpcs-compat.xml.dist deleted file mode 100644 index 3be6f4e..0000000 --- a/.phpcs-compat.xml.dist +++ /dev/null @@ -1,16 +0,0 @@ - - - PHPCompatibility check for Auth0 PHP SDK - ./src - - - - - - - - - diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist deleted file mode 100644 index b3ec2f8..0000000 --- a/.phpcs.xml.dist +++ /dev/null @@ -1,115 +0,0 @@ - - - A custom coding standard for the Auth0 PHP SDK - - ./src - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - tests/*\.php - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.semgrepignore b/.semgrepignore new file mode 100644 index 0000000..fbf53d0 --- /dev/null +++ b/.semgrepignore @@ -0,0 +1,2 @@ +example/ +tests/ diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index 6f1da91..0000000 --- a/.styleci.yml +++ /dev/null @@ -1,258 +0,0 @@ -risky: true -version: 8.0 -preset: none -enabled: - - align_double_arrow - - align_phpdoc - - alpha_ordered_imports - - alpha_ordered_traits - - array_indentation - - array_push - - assign_null_coalescing_to_coalesce_equal - - backtick_to_shell_exec - - binary_operator_spaces - - blank_line_after_namespace - - blank_line_after_opening_tag - - blank_line_before_break - - blank_line_before_cases - - blank_line_before_continue - - blank_line_before_declare - - blank_line_before_do - - blank_line_before_exit - - blank_line_before_for - - blank_line_before_goto - - blank_line_before_if - - blank_line_before_include - - blank_line_before_return - - blank_line_before_switch - - blank_line_before_throw - - blank_line_before_try - - blank_line_before_while - - blank_line_before_yield - - cast_spaces - - class_reference_name_casing - - clean_namespace - - combine_consecutive_issets - - combine_consecutive_unsets - - combine_nested_dirname - - comment_to_phpdoc - - compact_nullable_typehint - - concat_with_spaces - - const_separation - - const_visibility_required - - declare_equal_normalize - - declare_strict_types - - deprecation_error_suppression - - die_to_exit - - dir_constant - - doctrine_annotation_array_assignment - - doctrine_annotation_braces - - doctrine_annotation_indentation - - doctrine_annotation_spaces - - elseif - - empty_loop_body_braces - - empty_loop_condition - - encoding - - ereg_to_preg - - escape_implicit_backslashes - - explicit_indirect_variable - - explicit_string_variable - - final_internal_class - - final_public_method_for_abstract_class - - fopen_flag_order - - fopen_flags - - full_opening_tag - - fully_qualified_strict_types - - function_declaration - - function_to_constant - - function_typehint_space - - get_class_to_class_keyword - - hash_to_slash_comment - - heredoc_indentation - - heredoc_to_nowdoc - - implode_call - - include - - indentation - - integer_literal_case - - is_null - - laravel_braces - - laravel_phpdoc_alignment - - laravel_phpdoc_order - - laravel_phpdoc_separation - - linebreak_after_opening_tag - - logical_operators - - lowercase_cast - - lowercase_constants - - lowercase_keywords - - lowercase_static_reference - - magic_constant_casing - - magic_method_casing - - mb_str_functions - - method_argument_space_strict - - method_chaining_indentation - - method_separation - - method_visibility_required - - modernize_strpos - - modernize_types_casting - - multiline_comment_opening_closing - - native_function_casing - - native_function_invocation_symfony - - native_function_type_declaration_casing - - new_with_braces - - no_alias_functions - - no_alternative_syntax - - no_binary_string - - no_blank_lines_after_class_opening - - no_blank_lines_after_phpdoc - - no_blank_lines_after_return - - no_blank_lines_after_throw - - no_blank_lines_around_break - - no_blank_lines_around_cases - - no_blank_lines_around_continue - - no_blank_lines_around_switch - - no_blank_lines_between_imports - - no_break_comment - - no_closing_tag - - no_empty_comment - - no_empty_phpdoc - - no_empty_statement - - no_extra_block_blank_lines - - no_extra_consecutive_blank_lines - - no_homoglyph_names - - no_leading_import_slash - - no_leading_namespace_whitespace - - no_multiline_whitespace_around_double_arrow - - no_multiline_whitespace_before_semicolons - - no_php4_constructor - - no_short_bool_cast - - no_short_echo_tag - - no_singleline_whitespace_before_semicolons - - no_space_around_double_colon - - no_spaces_after_function_name - - no_spaces_inside_offset - - no_spaces_inside_parenthesis - - no_spaces_outside_offset - - no_superfluous_elseif - - no_superfluous_phpdoc_tags_symfony - - no_trailing_comma_in_list_call - - no_trailing_comma_in_singleline_array - - no_trailing_comma_in_singleline_function_call - - no_trailing_whitespace - - no_trailing_whitespace_in_comment - - no_trailing_whitespace_in_string - - no_unneeded_control_parentheses - - no_unneeded_curly_braces - - no_unneeded_final_method - - no_unneeded_import_alias - - no_unreachable_default_argument_value - - no_unset_cast - - no_unused_imports - - no_unused_lambda_imports - - no_useless_else - - no_useless_return - - no_useless_sprintf - - no_whitespace_before_comma_in_array - - no_whitespace_in_blank_line - - non_printable_character - - normalize_index_brace - - not_operator_with_successor_space - - nullable_type_declarations - - object_operator_without_whitespace - - operator_linebreak_end - - ordered_class_elements - - php_unit_fqcn_annotation - - phpdoc_add_missing_param_annotation - - phpdoc_annotation_without_dot - - phpdoc_indent - - phpdoc_inline_inheritdoc - - phpdoc_inline_tag_normalizer - - phpdoc_link_to_see - - phpdoc_no_access - - phpdoc_no_empty_return - - phpdoc_no_package - - phpdoc_no_useless_inheritdoc - - phpdoc_property - - phpdoc_return_self_reference - - phpdoc_scalar - - phpdoc_single_line_var_spacing - - phpdoc_singular_inheritdoc - - phpdoc_summary - - phpdoc_to_comment - - phpdoc_trim - - phpdoc_trim_consecutive_blank_line_separation - - phpdoc_type_to_var - - phpdoc_types - - phpdoc_types_order - - phpdoc_var_order - - phpdoc_var_without_name - - pow_to_exponentiation - - pre_increment - - print_to_echo - - property_separation - - property_visibility_required - - protected_to_private - - psr4 - - random_api_migration - - regular_callable_call - - return_assignment - - return_type_declaration - - self_accessor - - self_static_accessor - - semicolon_after_instruction - - set_type_to_cast - - short_array_syntax - - short_list_syntax - - short_scalar_cast - - simple_to_complex_string_variable - - simplified_if_return - - single_blank_line_at_eof - - single_blank_line_before_namespace - - single_class_element_per_statement - - single_import_per_statement - - single_line_after_imports - - single_line_comment_spacing - - single_line_throw - - single_quote - - single_space_after_construct - - single_trait_insert_per_statement - - space_after_semicolon - - standardize_increment - - standardize_not_equals - - static_lambda - - strict_comparison - - strict_param - - string_length_to_empty - - string_line_ending - - switch_case_semicolon_to_colon - - switch_case_space - - switch_continue_to_break - - symfony_class_definition - - ternary_operator_spaces - - ternary_to_elvis_operator - - ternary_to_null_coalescing - - trailing_comma_in_multiline_array - - trailing_comma_in_multiline_call - - trailing_comma_in_multiline_definition - - trim_array_spaces - - unalign_equals - - unary_operator_spaces - - union_type_without_spaces - - unix_line_endings - - use_arrow_functions - - void_return - - whitespace_after_comma_in_array - - yoda_style -finder: - exclude: - - "modules" - - "node_modules" - - "nova" - - "nova-components" - - "storage" - - "spark" - - "vendor" - - "tests" - name: "*.php" - not-name: - - "*.blade.php" - - "_ide_helper.php" diff --git a/README.md b/README.md index 0a515b3..7b75393 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Symfony SDK for [Auth0](https://auth0.com) Authentication and Management APIs. ### Requirements - [PHP](http://php.net/) 8.1+ -- [Symfony](https://symfony.com/) 6.1+, <6.4 +- [Symfony](https://symfony.com/) 6.4 LTS - Symfony 7.0 is not currently supported. > Please review our [support policy](#support-policy) to learn when language and framework versions will exit support in the future. @@ -166,7 +166,7 @@ return [ * Leave any existing entries in this array as they are. * You should just append this line to the end: */ - + Auth0\Symfony\Auth0Bundle::class => ['all' => true], ]; ``` diff --git a/composer.json b/composer.json index 2815f69..f2cd315 100644 --- a/composer.json +++ b/composer.json @@ -30,27 +30,32 @@ "homepage": "https://github.com/auth0/symfony", "require": { "php": "^8.1", - "auth0/auth0-php": "^8.7", - "symfony/cache": "^6.1", - "symfony/framework-bundle": "^6.1", - "symfony/security-bundle": "^6.1" + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "auth0/auth0-php": "^8.10", + "symfony/cache": "^6.4", + "symfony/framework-bundle": "^6.4", + "symfony/security-bundle": "^6.4" }, "require-dev": { - "ergebnis/composer-normalize": "^2.28", - "firebase/php-jwt": "^6.3", - "hyperf/event": "^2.2", - "laravel/pint": "^1.2", - "mockery/mockery": "^1.5", - "nyholm/psr7": "^1.5", - "pestphp/pest": "^1.21", - "php-http/mock-client": "^1.5", - "phpstan/phpstan": "^1.9", - "phpstan/phpstan-strict-rules": "^1.4.4", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.14.7", - "squizlabs/php_codesniffer": "^3.7", - "vimeo/psalm": "^4.30", - "wikimedia/composer-merge-plugin": "^2.0" + "ergebnis/composer-normalize": "^2", + "firebase/php-jwt": "^6", + "friendsofphp/php-cs-fixer": "^3", + "hyperf/event": "^2", + "mockery/mockery": "^1", + "nyholm/psr7": "^1", + "pestphp/pest": "^2", + "php-http/mock-client": "^1", + "phpstan/phpstan": "^1", + "phpstan/phpstan-strict-rules": "^1", + "rector/rector": "0.17.6", + "vimeo/psalm": "^5", + "wikimedia/composer-merge-plugin": "^2" + }, + "suggest": { + "psr/cache-implementation": "(PSR-6 Cache) Improve performance by avoiding making redundant network requests.", + "psr/event-dispatcher-implementation": "(PSR-14 Event Dispatcher) Observe and react to events when they occur." }, "prefer-stable": true, "autoload": { @@ -65,29 +70,58 @@ }, "config": { "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true, - "pestphp/pest-plugin": true, "ergebnis/composer-normalize": true, - "wikimedia/composer-merge-plugin": true, - "symfony/flex": true, - "phpstan/extension-installer": true - }, - "composer-normalize": { - "indent-size": 4, - "indent-style": "space" + "infection/extension-installer": false, + "pestphp/pest-plugin": true, + "php-http/discovery": false, + "wikimedia/composer-merge-plugin": true }, "optimize-autoloader": true, + "preferred-install": "dist", + "process-timeout": 0, "sort-packages": true }, + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, "scripts": { - "phpstan": "@php vendor/bin/phpstan analyse", - "phpstan:pro": "@php vendor/bin/phpstan analyse --pro", - "pint": "@php vendor/bin/pint --test", - "pint:fix": "@php vendor/bin/pint", + "pest": [ + "@putenv XDEBUG_MODE=coverage", + "@php vendor/bin/pest --colors=always --strict-global-state --fail-on-risky --fail-on-warning --coverage --strict-coverage --compact" + ], + "pest:ci": [ + "@pest:fast --order-by=random --no-progress" + ], + "pest:fast": [ + "@pest --parallel" + ], + "phpcs": [ + "@putenv PHP_CS_FIXER_IGNORE_ENV=1", + "@php vendor/bin/php-cs-fixer fix --dry-run --diff" + ], + "phpcs:fix": "@php vendor/bin/php-cs-fixer fix", + "phpstan": "@php vendor/bin/phpstan analyze", "psalm": "@php vendor/bin/psalm", "psalm:fix": "@php vendor/bin/psalter --issues=all", "rector": "@php vendor/bin/rector process src --dry-run", "rector:fix": "@php vendor/bin/rector process src", - "test": "@php vendor/bin/pest --order-by random" + "test": [ + "@pest", + "@phpstan", + "@psalm", + "@rector", + "@phpcs" + ] } } diff --git a/example/.editorconfig b/example/.editorconfig new file mode 100644 index 0000000..7cbaed6 --- /dev/null +++ b/example/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +# We use 4 space indentation for PHP +[*.php] +indent_style = space +indent_size = 4 diff --git a/example/.env.example b/example/.env.example new file mode 100644 index 0000000..0584e76 --- /dev/null +++ b/example/.env.example @@ -0,0 +1,54 @@ +# In all environments, the following files are loaded if they exist, +# the latter taking precedence over the former: +# +# * .env contains default values for the environment variables needed by the app +# * .env.local uncommitted file with local overrides +# * .env.$APP_ENV committed environment-specific defaults +# * .env.$APP_ENV.local uncommitted environment-specific overrides +# +# Real environment variables win over .env files. +# +# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. +# https://symfony.com/doc/current/configuration/secrets.html +# +# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). +# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_SECRET= +###< symfony/framework-bundle ### + +###> symfony/webapp-pack ### +MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 +###< symfony/webapp-pack ### + +###> doctrine/doctrine-bundle ### +# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url +# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml +# +# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4" +DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=14&charset=utf8" +###< doctrine/doctrine-bundle ### + +###> symfony/messenger ### +# Choose one of the transports below +# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages +###< symfony/messenger ### + +###> symfony/mailer ### +# MAILER_DSN=null://null +###< symfony/mailer ### + +###> auth0/symfony ### +AUTH0_DOMAIN={DOMAIN} +AUTH0_CLIENT_ID={CLIENT_ID} +AUTH0_CLIENT_SECRET={CLIENT_SECRET} +AUTH0_CUSTOM_DOMAIN={CUSTOM_DOMAIN} + +AUTH0_ROUTE_CALLBACK=callback +AUTH0_ROUTE_LOGIN=login +AUTH0_ROUTE_SUCCESS=private +AUTH0_ROUTE_FAILURE=public +AUTH0_ROUTE_LOGOUT=public +###< auth0/symfony ### diff --git a/example/.env.test b/example/.env.test new file mode 100644 index 0000000..9e7162f --- /dev/null +++ b/example/.env.test @@ -0,0 +1,6 @@ +# define your env variables for the test env here +KERNEL_CLASS='App\Kernel' +APP_SECRET='$ecretf0rt3st' +SYMFONY_DEPRECATIONS_HELPER=999999 +PANTHER_APP_ENV=panther +PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..399634f --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,22 @@ +.env + + +###> symfony/framework-bundle ### +/.env.local +/.env.local.php +/.env.*.local +/config/secrets/prod/prod.decrypt.private.php +/public/bundles/ +/var/ +/vendor/ +###< symfony/framework-bundle ### + +###> phpunit/phpunit ### +/phpunit.xml +.phpunit.result.cache +###< phpunit/phpunit ### + +###> symfony/phpunit-bridge ### +.phpunit.result.cache +/phpunit.xml +###< symfony/phpunit-bridge ### diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..de03a1e --- /dev/null +++ b/example/README.md @@ -0,0 +1,97 @@ +# Auth0 Symfony SDK Sample Application + +> **Warning** +> This sample application is built for a beta version of the Symfony SDK that is currently under development and not yet intended for production use. + +This sample application demonstrates how to use the Symfony SDK. It's a basic application that uses the SDK to demonstrate: + +- Authenticating users with Auth0 and retrieving user profile information. +- Authorizing requests to protected routes. + +This sample application is built for the [Symfony 6](https://symfony.com/) framework. Although we strive to keep this sample up-to-date, you may need to make adjustments for newer or older versions of the framework. + +If you find any issues, please help us improve our experience for other developers by submitting a pull request. + +## Requirements + +- PHP 8.1+ +- [Composer](https://getcomposer.org/) +- [Symfony CLI](https://symfony.com/download) (recommended) + +## Setup + +From your shell/terminal, run the following commands to get started: + +1. Create an Auth0 Application at https://manage.auth0.com/#/applications +2. Optional: Create an Auth0 API at https://manage.auth0.com/#/apis + +Please make a note of your domain, client ID, and client secret. If you're using an API, also note your API identifier/audience. You will need these in the next steps. + +Complete application setup by using the quick setup script: + +1. Run `chmod +x ./setup.sh` to make the quick setup script executable +2. Run `./setup.sh` to install the dependencies and follow the instructions to create a local environment file + +
+ Alternatively, setup the application manually ... + +1. Run `composer install` to install the dependencies +2. Run `cp .env .env.local` to create a local environment file +3. Edit your `.env.local` file and fill in the values for variables starting with `AUTH0_` using the details you noted above +
+ +## Starting the application + +Run the following command to start the application using the built-in web server using [the Symfony CLI](https://symfony.com/download) (recommended): + +```bash +symfony server:start --no-tls +``` + +
+ Alternatively, use PHP's `-S` option ... + +Note that this may provide fewer troubleshooting details in the event of errors: + +```bash +php -S localhost:8000 -t public +``` + +
+ +## Access the application + +You should now be able to access the sample from your browser at `http://localhost:8000`. You'll find the following routes are available for use: + +### Authentication routes + +These demonstrate how a traditional web application can authenticate users with Auth0. + +- `/` - This route serves as a health check to ensure the app is running successfully. It does not leverage the SDK. +- `/private` - This is a protected route that requires a user to be authenticated to access. +- `/login` - This route begins the login flow with Auth0. It sets up the user session and redirects to Auth0 for authentication. +- `/callback` - The user is returned to this route after authenticating with Auth0. This finishes setting up the user session and redirects to the `/private` route. You should not need to access this route directly. +- `/logout` - This route clears the user's session and logs them out. It will briefly redirect them to Auth0 to clear their session there as well, then redirect them back to the home page (or whatever route is configured with `AUTH0_ROUTE_LOGOUT` in your `.env.local` file.) + +### Authorization routes + +These demonstrate how an API can authorize requests with Auth0. Note that you must uncomment the `audiences` array in the `config/packages/auth0.yaml` file to use these routes, and provide the identifier for your Auth0 API. + +- `/api` - A public route that does not require anything special to access. +- `/api/private` - A protected route that requires a valid token to access. +- `/api/scoped` - A protected route that requires a valid token with the `read:messages` scope to access. + +## Customizing the application + +You can customize the sample to suit your needs by altering the following files: + +- The `.env.local` file's AUTH0\_\* values +- The `config/packages/security.yaml` file for changing expected scopes or adjusting firewall settings +- The `config/packages/auth0.yaml` file for using a custom domain or an API identifier + +> **Note** +> Comments have been inserted throughout the application to identify what portions were modified from the boilerplate Symfony template application. You can locate these by searching for `[AUTH0/SYMFONY]` within the _.yaml and _.php files. For example: + +```bash +grep -lr "\[AUTH0\/SYMFONY\]" +``` diff --git a/example/bin/console b/example/bin/console new file mode 100755 index 0000000..c933dc5 --- /dev/null +++ b/example/bin/console @@ -0,0 +1,17 @@ +#!/usr/bin/env php +=8.1", + "ext-ctype": "*", + "ext-iconv": "*", + "auth0/symfony": "dev-main", + "doctrine/annotations": "^1.0", + "doctrine/doctrine-bundle": "^2.7", + "doctrine/doctrine-migrations-bundle": "^3.2", + "doctrine/orm": "^2.13", + "nyholm/psr7": "^1.5", + "phpdocumentor/reflection-docblock": "^5.3", + "phpstan/phpdoc-parser": "^1.13", + "predis/predis": "^2.2", + "sensio/framework-extra-bundle": "^6.1", + "sixlive/dotenv-editor": "^2.0", + "symfony/asset": "6.1.*", + "symfony/console": "6.1.*", + "symfony/doctrine-messenger": "6.1.*", + "symfony/dotenv": "6.1.*", + "symfony/expression-language": "6.1.*", + "symfony/flex": "^2", + "symfony/form": "6.1.*", + "symfony/framework-bundle": "6.1.*", + "symfony/http-client": "6.1.*", + "symfony/intl": "6.1.*", + "symfony/mailer": "6.1.*", + "symfony/mime": "6.1.*", + "symfony/monolog-bundle": "^3.0", + "symfony/notifier": "6.1.*", + "symfony/process": "6.1.*", + "symfony/property-access": "6.1.*", + "symfony/property-info": "6.1.*", + "symfony/proxy-manager-bridge": "6.1.*", + "symfony/psr-http-message-bridge": "^2.1", + "symfony/runtime": "6.1.*", + "symfony/security-bundle": "6.1.*", + "symfony/serializer": "6.1.*", + "symfony/string": "6.1.*", + "symfony/translation": "6.1.*", + "symfony/twig-bundle": "6.1.*", + "symfony/validator": "6.1.*", + "symfony/web-link": "6.1.*", + "symfony/yaml": "6.1.*", + "twig/extra-bundle": "^2.12|^3.0", + "twig/twig": "^2.12|^3.0" + }, + "config": { + "allow-plugins": { + "composer/package-versions-deprecated": true, + "symfony/flex": true, + "symfony/runtime": true, + "wikimedia/composer-merge-plugin": true, + "php-http/discovery": false + }, + "optimize-autoloader": true, + "preferred-install": { + "*": "dist" + }, + "sort-packages": true + }, + "autoload": { + "psr-4": { + "App\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "App\\Tests\\": "tests/" + } + }, + "replace": { + "symfony/polyfill-ctype": "*", + "symfony/polyfill-iconv": "*", + "symfony/polyfill-php72": "*", + "symfony/polyfill-php73": "*", + "symfony/polyfill-php74": "*", + "symfony/polyfill-php80": "*", + "symfony/polyfill-php81": "*" + }, + "scripts": { + "auto-scripts": { + "cache:clear": "symfony-cmd", + "assets:install %PUBLIC_DIR%": "symfony-cmd" + }, + "post-install-cmd": [ + "@auto-scripts" + ], + "post-update-cmd": [ + "@auto-scripts" + ] + }, + "conflict": { + "symfony/symfony": "*" + }, + "extra": { + "symfony": { + "allow-contrib": false, + "require": "6.1.*" + }, + "merge-plugin": { + "include": [ + "composer.local.json" + ], + "recurse": true, + "replace": true, + "ignore-duplicates": false, + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false + } + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "symfony/browser-kit": "6.1.*", + "symfony/css-selector": "6.1.*", + "symfony/debug-bundle": "6.1.*", + "symfony/maker-bundle": "^1.48", + "symfony/phpunit-bridge": "^6.1", + "symfony/stopwatch": "6.1.*", + "symfony/web-profiler-bundle": "6.1.*", + "wikimedia/composer-merge-plugin": "^2.0" + } +} diff --git a/example/config/bundles.php b/example/config/bundles.php new file mode 100644 index 0000000..b1b34ea --- /dev/null +++ b/example/config/bundles.php @@ -0,0 +1,16 @@ + ['all' => true], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], + Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], + Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], + Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], + Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], + Auth0\Symfony\Auth0Bundle::class => ['all' => true], +]; diff --git a/example/config/packages/auth0.yaml b/example/config/packages/auth0.yaml new file mode 100644 index 0000000..204148d --- /dev/null +++ b/example/config/packages/auth0.yaml @@ -0,0 +1,27 @@ +auth0: + sdk: + domain: "%env(string:key:host:url:AUTH0_DOMAIN)%" + # custom_domain: "%env(string:key:host:url:AUTH0_CUSTOM_DOMAIN)%" + client_id: "%env(trim:string:AUTH0_CLIENT_ID)%" + client_secret: "%env(trim:string:AUTH0_CLIENT_SECRET)%" + token_cache: "auth0_token_cache" + management_token_cache: "auth0_management_token_cache" + cookie_secret: "%kernel.secret%" + cookie_expires: 3600 + cookie_path: "/" + cookie_secure: false + # audiences: + # - symfony-quickstart-api + scopes: + - openid + - profile + - email + - offline_access + + authenticator: + routes: + callback: "%env(string:AUTH0_ROUTE_CALLBACK)%" + success: "%env(string:AUTH0_ROUTE_SUCCESS)%" + failure: "%env(string:AUTH0_ROUTE_FAILURE)%" + login: "%env(string:AUTH0_ROUTE_LOGIN)%" + logout: "%env(string:AUTH0_ROUTE_LOGOUT)%" diff --git a/example/config/packages/cache.yaml b/example/config/packages/cache.yaml new file mode 100644 index 0000000..81ae55c --- /dev/null +++ b/example/config/packages/cache.yaml @@ -0,0 +1,22 @@ +framework: + cache: + # app: cache.adapter.filesystem + + # Unique name of your app: used to compute stable namespaces for cache keys. + prefix_seed: auth0_symfony_sample + + # The "app" cache stores to the filesystem by default. + # The data in this cache should persist between deploys. + # Other options include: + + # Redis + app: cache.adapter.redis + default_redis_provider: redis://localhost + + # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) + #app: cache.adapter.apcu + + # Namespaced pools use the above "app" backend by default + pools: + auth0_token_cache: { adapter: cache.adapter.redis } + auth0_management_token_cache: { adapter: cache.adapter.redis } diff --git a/example/config/packages/debug.yaml b/example/config/packages/debug.yaml new file mode 100644 index 0000000..ce519f3 --- /dev/null +++ b/example/config/packages/debug.yaml @@ -0,0 +1,5 @@ +when@dev: + debug: + # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser. + # See the "server:dump" command to start a new server. + dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%" diff --git a/example/config/packages/doctrine.yaml b/example/config/packages/doctrine.yaml new file mode 100644 index 0000000..9177455 --- /dev/null +++ b/example/config/packages/doctrine.yaml @@ -0,0 +1,45 @@ +doctrine: + dbal: + url: "%env(resolve:DATABASE_URL)%" + + # IMPORTANT: You MUST configure your server version, + # either here or in the DATABASE_URL env var (see .env file) + #server_version: '13' + orm: + auto_generate_proxy_classes: true + naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware + auto_mapping: true + mappings: + App: + is_bundle: false + dir: "%kernel.project_dir%/src/Entity" + prefix: 'App\Entity' + alias: App + Auth0Bundle: + is_bundle: true + prefix: 'Auth0\Symfony' + +when@test: + doctrine: + dbal: + # "TEST_TOKEN" is typically set by ParaTest + dbname_suffix: "_test%env(default::TEST_TOKEN)%" + +when@prod: + doctrine: + orm: + auto_generate_proxy_classes: false + query_cache_driver: + type: pool + pool: doctrine.system_cache_pool + result_cache_driver: + type: pool + pool: doctrine.result_cache_pool + + framework: + cache: + pools: + doctrine.result_cache_pool: + adapter: cache.app + doctrine.system_cache_pool: + adapter: cache.system diff --git a/example/config/packages/doctrine_migrations.yaml b/example/config/packages/doctrine_migrations.yaml new file mode 100644 index 0000000..9300c9b --- /dev/null +++ b/example/config/packages/doctrine_migrations.yaml @@ -0,0 +1,6 @@ +doctrine_migrations: + migrations_paths: + # namespace is arbitrary but should be different from App\Migrations + # as migrations classes should NOT be autoloaded + "DoctrineMigrations": "%kernel.project_dir%/migrations" + enable_profiler: false diff --git a/example/config/packages/framework.yaml b/example/config/packages/framework.yaml new file mode 100644 index 0000000..60fcd3a --- /dev/null +++ b/example/config/packages/framework.yaml @@ -0,0 +1,24 @@ +# see https://symfony.com/doc/current/reference/configuration/framework.html +framework: + secret: "%env(APP_SECRET)%" + csrf_protection: true + http_method_override: false + + # Enables session support. Note that the session will ONLY be started if you read or write from it. + # Remove or comment this section to explicitly disable session support. + session: + handler_id: null + cookie_secure: auto + cookie_samesite: lax + storage_factory_id: session.storage.factory.native + + #esi: true + #fragments: true + php_errors: + log: true + +when@test: + framework: + test: true + session: + storage_factory_id: session.storage.factory.mock_file diff --git a/example/config/packages/http_discovery.yaml b/example/config/packages/http_discovery.yaml new file mode 100644 index 0000000..2a789e7 --- /dev/null +++ b/example/config/packages/http_discovery.yaml @@ -0,0 +1,10 @@ +services: + Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory' + + http_discovery.psr17_factory: + class: Http\Discovery\Psr17Factory diff --git a/example/config/packages/mailer.yaml b/example/config/packages/mailer.yaml new file mode 100644 index 0000000..813f6e1 --- /dev/null +++ b/example/config/packages/mailer.yaml @@ -0,0 +1,3 @@ +framework: + mailer: + dsn: "%env(MAILER_DSN)%" diff --git a/example/config/packages/messenger.yaml b/example/config/packages/messenger.yaml new file mode 100644 index 0000000..0d03b81 --- /dev/null +++ b/example/config/packages/messenger.yaml @@ -0,0 +1,24 @@ +framework: + messenger: + failure_transport: failed + + transports: + # https://symfony.com/doc/current/messenger.html#transport-configuration + async: + dsn: "%env(MESSENGER_TRANSPORT_DSN)%" + options: + use_notify: true + check_delayed_interval: 60000 + retry_strategy: + max_retries: 3 + multiplier: 2 + failed: "doctrine://default?queue_name=failed" + # sync: 'sync://' + + routing: + Symfony\Component\Mailer\Messenger\SendEmailMessage: async + Symfony\Component\Notifier\Message\ChatMessage: async + Symfony\Component\Notifier\Message\SmsMessage: async + + # Route your messages to the transports + # 'App\Message\YourMessage': async diff --git a/example/config/packages/monolog.yaml b/example/config/packages/monolog.yaml new file mode 100644 index 0000000..8edf82e --- /dev/null +++ b/example/config/packages/monolog.yaml @@ -0,0 +1,61 @@ +monolog: + channels: + - deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists + +when@dev: + monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + channels: ["!event"] + # uncomment to get logging in your browser + # you may have to allow bigger header sizes in your Web server configuration + #firephp: + # type: firephp + # level: info + #chromephp: + # type: chromephp + # level: info + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine", "!console"] + +when@test: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + excluded_http_codes: [404, 405] + channels: ["!event"] + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + +when@prod: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + excluded_http_codes: [404, 405] + buffer_size: 50 # How many messages should be saved? Prevent memory leaks + nested: + type: stream + path: php://stderr + level: debug + formatter: monolog.formatter.json + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine"] + deprecation: + type: stream + channels: [deprecation] + path: php://stderr diff --git a/example/config/packages/notifier.yaml b/example/config/packages/notifier.yaml new file mode 100644 index 0000000..4e40446 --- /dev/null +++ b/example/config/packages/notifier.yaml @@ -0,0 +1,16 @@ +framework: + notifier: + #chatter_transports: + # slack: '%env(SLACK_DSN)%' + # telegram: '%env(TELEGRAM_DSN)%' + #texter_transports: + # twilio: '%env(TWILIO_DSN)%' + # nexmo: '%env(NEXMO_DSN)%' + channel_policy: + # use chat/slack, chat/telegram, sms/twilio or sms/nexmo + urgent: ["email"] + high: ["email"] + medium: ["email"] + low: ["email"] + admin_recipients: + - { email: admin@example.com } diff --git a/example/config/packages/nyholm_psr7.yaml b/example/config/packages/nyholm_psr7.yaml new file mode 100644 index 0000000..7e2629c --- /dev/null +++ b/example/config/packages/nyholm_psr7.yaml @@ -0,0 +1,21 @@ +services: + # Register nyholm/psr7 services for autowiring with PSR-17 (HTTP factories) + Psr\Http\Message\RequestFactoryInterface: "@nyholm.psr7.psr17_factory" + Psr\Http\Message\ResponseFactoryInterface: "@nyholm.psr7.psr17_factory" + Psr\Http\Message\ServerRequestFactoryInterface: "@nyholm.psr7.psr17_factory" + Psr\Http\Message\StreamFactoryInterface: "@nyholm.psr7.psr17_factory" + Psr\Http\Message\UploadedFileFactoryInterface: "@nyholm.psr7.psr17_factory" + Psr\Http\Message\UriFactoryInterface: "@nyholm.psr7.psr17_factory" + + # Register nyholm/psr7 services for autowiring with HTTPlug factories + Http\Message\MessageFactory: "@nyholm.psr7.httplug_factory" + Http\Message\RequestFactory: "@nyholm.psr7.httplug_factory" + Http\Message\ResponseFactory: "@nyholm.psr7.httplug_factory" + Http\Message\StreamFactory: "@nyholm.psr7.httplug_factory" + Http\Message\UriFactory: "@nyholm.psr7.httplug_factory" + + nyholm.psr7.psr17_factory: + class: Nyholm\Psr7\Factory\Psr17Factory + + nyholm.psr7.httplug_factory: + class: Nyholm\Psr7\Factory\HttplugFactory diff --git a/example/config/packages/routing.yaml b/example/config/packages/routing.yaml new file mode 100644 index 0000000..c0f1474 --- /dev/null +++ b/example/config/packages/routing.yaml @@ -0,0 +1,12 @@ +framework: + router: + utf8: true + + # Configure how to generate URLs in non-HTTP contexts, such as CLI commands. + # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands + #default_uri: http://localhost + +when@prod: + framework: + router: + strict_requirements: null diff --git a/example/config/packages/security.yaml b/example/config/packages/security.yaml new file mode 100644 index 0000000..8cfb083 --- /dev/null +++ b/example/config/packages/security.yaml @@ -0,0 +1,36 @@ +security: + enable_authenticator_manager: true + + providers: + # [AUTH0/SYMFONY] You must assign a compatible UserProvider to the firewall. We provide one for you, but you can also create your own. + auth0_provider: + id: Auth0\Symfony\Security\UserProvider + + firewalls: + # [AUTH0/SYMFONY] The following firewall demonstrates how to use the Auth0 Symfony SDK for authentication. + auth0: + pattern: ^/private$ + provider: auth0_provider + custom_authenticators: + - auth0.authenticator + + # [AUTH0/SYMFONY] The following firewall demonstrates how to use the Auth0 Symfony SDK for authorization. + api: + pattern: ^/api + stateless: true + provider: auth0_provider + custom_authenticators: + - auth0.authorizer + + # These are unrelated routes that are not protected by the SDK. + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + main: + lazy: true + + # [AUTH0/SYMFONY] The following customizes the access control for the demonstration `api` firewall. + access_control: + - { path: ^/api$, roles: PUBLIC_ACCESS } + - { path: ^/api/private$, roles: ROLE_USING_TOKEN } + - { path: ^/api/scoped$, roles: ROLE_READ_MESSAGES } diff --git a/example/config/packages/sensio_framework_extra.yaml b/example/config/packages/sensio_framework_extra.yaml new file mode 100644 index 0000000..bc400a1 --- /dev/null +++ b/example/config/packages/sensio_framework_extra.yaml @@ -0,0 +1,3 @@ +sensio_framework_extra: + router: + annotations: false diff --git a/example/config/packages/translation.yaml b/example/config/packages/translation.yaml new file mode 100644 index 0000000..1eeb15e --- /dev/null +++ b/example/config/packages/translation.yaml @@ -0,0 +1,6 @@ +framework: + default_locale: en + translator: + default_path: "%kernel.project_dir%/translations" + fallbacks: + - en diff --git a/example/config/packages/twig.yaml b/example/config/packages/twig.yaml new file mode 100644 index 0000000..0741d3e --- /dev/null +++ b/example/config/packages/twig.yaml @@ -0,0 +1,6 @@ +twig: + default_path: "%kernel.project_dir%/templates" + +when@test: + twig: + strict_variables: true diff --git a/example/config/packages/validator.yaml b/example/config/packages/validator.yaml new file mode 100644 index 0000000..638e060 --- /dev/null +++ b/example/config/packages/validator.yaml @@ -0,0 +1,8 @@ +framework: + validation: + email_validation_mode: html5 + +when@test: + framework: + validation: + not_compromised_password: false diff --git a/example/config/packages/web_profiler.yaml b/example/config/packages/web_profiler.yaml new file mode 100644 index 0000000..a529921 --- /dev/null +++ b/example/config/packages/web_profiler.yaml @@ -0,0 +1,17 @@ +when@dev: + web_profiler: + toolbar: true + intercept_redirects: false + + framework: + profiler: + only_exceptions: false + collect_serializer_data: true + +when@test: + web_profiler: + toolbar: false + intercept_redirects: false + + framework: + profiler: { collect: false } diff --git a/example/config/preload.php b/example/config/preload.php new file mode 100644 index 0000000..5ebcdb2 --- /dev/null +++ b/example/config/preload.php @@ -0,0 +1,5 @@ + + + + + + + + + + + + + + + + tests + + + + + + src + + + + + + + + + + diff --git a/example/public/index.php b/example/public/index.php new file mode 100644 index 0000000..9982c21 --- /dev/null +++ b/example/public/index.php @@ -0,0 +1,9 @@ +addArgument('envfile', InputArgument::REQUIRED, 'env File {.env, .env.local}'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $envname = $input->getArgument('envfile'); + + if ($envname && ($envname == '.env' || $envname == '.env.local')) { + $io->note(sprintf('You chose to update: %s', $envname)); + $secret = bin2hex(random_bytes(16)); + $filepath = realpath(dirname(__file__).'/../..') . '/' . $envname; + $io->note(sprintf('Editing file: %s', $filepath)); + + $editor = new DotenvEditor(); + $editor->load($filepath); + $editor->set('APP_SECRET', $secret); + $editor->save(); + $io->success('New APP_SECRET was generated: ' . $secret); + return Command::SUCCESS; + } + $io->error("You did not provide a valid environment file to change"); + return Command::INVALID; + } +} diff --git a/example/src/Controller/.gitignore b/example/src/Controller/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/example/src/Controller/ExampleController.php b/example/src/Controller/ExampleController.php new file mode 100644 index 0000000..b9850c8 --- /dev/null +++ b/example/src/Controller/ExampleController.php @@ -0,0 +1,69 @@ + + +

Lucky number: ' . random_int(0, 100) . '

+

Login

+ + ' + ); + } + + /* + * [AUTH0/SYMFONY] This demonstrates a route that requires authentication. + */ + public function private(): Response + { + return new Response( + ' + +

' . print_r($this->getUser(), true) . '

+

Logout

+ + ' + ); + } + + /* + * [AUTH0/SYMFONY] This demonstrates an unprotected API route. + */ + public function apiPublic(): Response + { + return new JsonResponse([ + 'message' => 'Public API' + ]); + } + + /* + * [AUTH0/SYMFONY] This demonstrates a protected API route; it requires a valid token to access. Allowed scopes are defined in `config/packages/security.yaml` file. In this case, the route is protected by the `ROLE_USING_TOKEN` role, which simply means it requires a valid token. + */ + public function apiPrivate(): Response + { + return new JsonResponse([ + 'message' => 'Private API', + 'roles' => $this->getUser()->getRoles() + ]); + } + + /* + * [AUTH0/SYMFONY] This demonstrates a protected API route; it requires a valid token with the "read:messages" scope to access. Allowed scopes are defined in `config/packages/security.yaml` file. + */ + public function apiPrivateScopes(): Response + { + return new JsonResponse([ + 'message' => 'Private API with scope!', + 'roles' => $this->getUser()->getRoles() + ]); + } +} diff --git a/example/src/Entity/.gitignore b/example/src/Entity/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/example/src/Kernel.php b/example/src/Kernel.php new file mode 100644 index 0000000..779cd1f --- /dev/null +++ b/example/src/Kernel.php @@ -0,0 +1,11 @@ + + + + + {% block title %}Welcome!{% endblock %} + + {# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #} + {% block stylesheets %} + {{ encore_entry_link_tags('app') }} + {% endblock %} + + {% block javascripts %} + {{ encore_entry_script_tags('app') }} + {% endblock %} + + + {% block body %}{% endblock %} + + diff --git a/example/tests/bootstrap.php b/example/tests/bootstrap.php new file mode 100644 index 0000000..469dcce --- /dev/null +++ b/example/tests/bootstrap.php @@ -0,0 +1,11 @@ +bootEnv(dirname(__DIR__).'/.env'); +} diff --git a/example/translations/.gitignore b/example/translations/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/phpdoc.dist.xml b/phpdoc.dist.xml new file mode 100644 index 0000000..90104dd --- /dev/null +++ b/phpdoc.dist.xml @@ -0,0 +1,23 @@ + + + Auth0-PHP + + docs + + + + + src + + + php + + Auth0\/SDK + + +