diff --git a/best_practices/security.rst b/best_practices/security.rst index 6b25a7f54b5..93a3b6e1229 100644 --- a/best_practices/security.rst +++ b/best_practices/security.rst @@ -57,8 +57,8 @@ which uses a login form to load users from the database: pattern: ^/ anonymous: true form_login: - check_path: security_login_check - login_path: security_login_form + check_path: login + login_path: login logout: path: security_logout diff --git a/book/configuration.rst b/book/configuration.rst index 2574096f4d6..6562832ef09 100644 --- a/book/configuration.rst +++ b/book/configuration.rst @@ -87,8 +87,8 @@ format you prefer: .. note:: - You'll learn exactly how to load each file/format in the next section - `Environments`_. + You'll learn exactly how to load each file/format in the next section + `Environments`_. Each top-level entry like ``framework`` or ``twig`` defines the configuration for a particular bundle. For example, the ``framework`` key defines the configuration @@ -122,13 +122,13 @@ FrameworkBundle configuration: .. code-block:: bash - $ app/console config:dump-reference FrameworkBundle + $ php app/console config:dump-reference FrameworkBundle The extension alias (configuration key) can also be used: .. code-block:: bash - $ app/console config:dump-reference framework + $ php app/console config:dump-reference framework .. note:: @@ -195,6 +195,12 @@ cached files and allow them to rebuild: be accessed directly through the browser. See the :doc:`testing chapter ` for more details. +.. tip:: + + When using the ``server:run`` command to start a server, + ``http://localhost:8000/`` will use the dev front controller of your + application. + .. index:: single: Environments; Configuration diff --git a/book/page_creation.rst b/book/page_creation.rst index 4a762d61478..ce3be3ce65b 100644 --- a/book/page_creation.rst +++ b/book/page_creation.rst @@ -59,11 +59,12 @@ a method inside of it that will be executed when someone goes to ``/lucky/number Before diving into this, test it out! - http://localhost:8000/app_dev.php/lucky/number + http://localhost:8000/lucky/number .. tip:: - If you setup a proper virtual host in :doc:`Apache or Nginx `, + If you set up a proper virtual host in + :doc:`Apache or Nginx `, replace ``http://localhost:8000`` with your host name - like ``http://symfony.dev/app_dev.php/lucky/number``. @@ -80,16 +81,6 @@ and is where you build the page. The only rule is that a controller *must* return a Symfony :ref:`Response ` object (and you'll even learn to bend this rule eventually). -.. sidebar:: What's the ``app_dev.php`` in the URL? - - Great question! By including ``app_dev.php`` in the URL, you're executing - Symfony through a file - ``web/app_dev.php`` - that boots it in the ``dev`` - environment. This enables great debugging tools and rebuilds cached - files automatically. For production, you'll use clean URLs - like - ``http://localhost:8000/lucky/number`` - that execute a different file - - ``app.php`` - that's optimized for speed. To learn more about this and - environments, see :ref:`book-page-creation-prod-cache-clear`. - Creating a JSON Response ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -126,7 +117,7 @@ Just add a second method to ``LuckyController``:: Try this out in your browser: - http://localhost:8000/app_dev.php/api/lucky/number + http://localhost:8000/api/lucky/number You can even shorten this with the handy :class:`Symfony\\Component\\HttpFoundation\\JsonResponse`:: @@ -247,7 +238,7 @@ The best part is that you can access this value and use it in your controller:: Try it by going to ``/lucky/number/XX`` - replacing XX with *any* number: - http://localhost:8000/app_dev.php/lucky/number/7 + http://localhost:8000/lucky/number/7 You should see *7* lucky numbers printed out! You can get the value of any ``{placeholder}`` in your route by adding a ``$placeholder`` argument to @@ -404,7 +395,7 @@ to put the content into the middle of the ``base.html.twig`` layout. Refresh to see your template in action! - http://localhost:8000/app_dev.php/lucky/number/9 + http://localhost:8000/lucky/number/9 If you view the source code, you now have a basic HTML structure thanks to ``base.html.twig``. diff --git a/book/security.rst b/book/security.rst index 0a2e00ce1d9..49ce1f9f4c2 100644 --- a/book/security.rst +++ b/book/security.rst @@ -1192,6 +1192,14 @@ is defined by the ``target`` parameter above (e.g. the ``homepage``). :class:`Symfony\\Component\\Security\\Http\\Logout\\LogoutSuccessHandlerInterface`. See :doc:`Security Configuration Reference `. +.. caution:: + + Notice that when using http-basic authenticated firewalls, there is no + real way to log out : the only way to *log out* is to have the browser + stop sending your name and password on every request. Clearing your + browser cache or restarting your browser usually helps. Some web developer + tools might be helpful here too. + .. _`security-encoding-password`: Dynamically Encoding a Password diff --git a/changelog.rst b/changelog.rst index 42916827635..6e951b8a671 100644 --- a/changelog.rst +++ b/changelog.rst @@ -13,6 +13,79 @@ documentation. Do you also want to participate in the Symfony Documentation? Take a look at the ":doc:`/contributing/documentation/overview`" article. +December, 2015 +-------------- + +New Documentation +~~~~~~~~~~~~~~~~~ + +* `#5906 `_ Added documentation for choice_translation_domain option (peterrehm) +* `#6017 `_ Documented the Symfony Console Styles (javiereguiluz) +* `#5811 `_ Conversion from mysql to PDO (iqbalmalik89) +* `#5962 `_ Simplify code example in "Adding custom extensions" section (snoek09) +* `#6022 `_ clarify custom route loader documentation (dbu) +* `#5994 `_ Updated the release process for Symfony 3.x and future releases (javiereguiluz) + +Fixed Documentation +~~~~~~~~~~~~~~~~~~~ + +* `#6063 `_ minor #5829 Fix broken composer command (JHGitty) +* `#5904 `_ Update php_soap_extension.rst (xDaizu) +* `#5819 `_ Remove AppBundle (roukmoute) +* `#6001 `_ Fix class name (BlueM) + +Minor Documentation Changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* `#6043 `_ Mention commiting only bower.json (krike, WouterJ) +* `#5848 `_ Added hints to spool config section (martinczerwi) +* `#6042 `_ some tweaks to unit testing form types (xabbuh) +* `#6059 `_ Add best practice about the Form type namespace (WouterJ) +* `#6068 `_ Remove references to API tagging (dunglas) +* `#6088 `_ Update validation.rst (syedi) +* `#6085 `_ Update validation.rst (syedi) +* `#6094 `_ [Form] Added a missing php opening tag (dev-symfony-void) +* `#5840 `_ [Contributing] [Standards] Add note about `trigger_error()` and deprecation messages (phansys) +* `#6050 `_ Lots of minor fixes & applying best practices to form cookbook doc (ThomasLandauer, WouterJ) +* `#5570 `_ Quick review of 'create framework' tutorial (WouterJ) +* `#5445 `_ Reworded the explanation about the kernel.event_listener tag (javiereguiluz) +* `#6054 `_ Remove 2.8 branch from patch documentation (Triiistan) +* `#6057 `_ Fix PHP code for registering service (WouterJ) +* `#6067 `_ improve phrasing (greg0ire) +* `#6063 `_ minor #5829 Fix broken composer command (JHGitty) +* `#6041 `_ Fixed misspelling of human in glossary.rst YAML (Wasserschlange) +* `#6049 `_ Finish #5798 Add app_ prefix to form type names (OskarStark, WouterJ) +* `#5829 `_ use composer command instead of editing json file (OskarStark) +* `#6046 `_ Update framework.rst (typo in sesssion) (patrick-mota) +* `#5662 `_ Fixed wrong version of symfony with composer install (Nek-) +* `#5890 `_ Updated article for modern Symfony practices and the use of bcrypt (javiereguiluz) +* `#6015 `_ [Assetic] complete XML configuration examples (xabbuh) +* `#5963 `_ Add note about 'phar extension' dependency (snoek09) +* `#6006 `_ [Book] use AppBundle examples and follow best practices (xabbuh) +* `#6016 `_ Corrected the line references for the basic controller example (theTeddyBear) +* `#5446 `_ [Contributing] [Standards] Added note about phpdoc_separation (phansys) +* `#5820 `_ Fixed an issue with command option shortcuts (javiereguiluz) +* `#6033 `_ Fix Typo (Shine-neko) +* `#6011 `_ Fixed formatting issues (javiereguiluz) +* `#6012 `_ Use HTTPS for downloading the Symfony Installer (javiereguiluz) +* `#6009 `_ Fix missing constant usage for generating urls (Tobion) +* `#5965 `_ Removing php opening tags (Deamon) +* `#6003 `_ #5999 fix files names (vincentaubert) +* `#5996 `_ Clarify example for SUBMIT form event (bkosborne) +* `#6000 `_ Update registration_form.rst (afurculita) +* `#5989 `_ Fix words according context (richardpq) +* `#5992 `_ More use single quotes for YAML strings (snoek09) +* `#5957 `_ mark deep option as deprecated (snoek09) +* `#5943 `_ Add tip for when returning `null` from `createToken()` (jeroenseegers) +* `#5956 `_ Update security.rst (mpaquet) +* `#5959 `_ Fix #5912 Ambiguity on Access Decision Manager's Strategy (Pierre Maraitre) +* `#5955 `_ use single quotes for YAML strings (snoek09) +* `#5979 `_ [Book] Do not extend the base controller before introducing it (ogizanagi) +* `#5970 `_ Remove isSubmitted call (DanielSiepmann) +* `#5972 `_ Add isSubmitted call (DanielSiepmann) +* `#5961 `_ update from_flat_php_to_symfony2.rst (thao-witkam) + + November, 2015 -------------- diff --git a/components/expression_language/syntax.rst b/components/expression_language/syntax.rst index ba153905aa6..c3140ace7a2 100644 --- a/components/expression_language/syntax.rst +++ b/components/expression_language/syntax.rst @@ -20,6 +20,18 @@ The component supports: * **booleans** - ``true`` and ``false`` * **null** - ``null`` +.. caution:: + + A backslash (``\``) must be escaped by 4 backslashes (``\\\\``) in a string + and 8 backslashes (``\\\\\\\\``) in a regex:: + + echo $language->evaluate('"\\\\"'); // prints \ + $language->evaluate('"a\\\\b" matches "/^a\\\\\\\\b$/"'); // returns true + + Control characters (e.g. ``\n``) in expressions are replaced with + whitespace. To avoid this, escape the sequence with a single backslash + (e.g. ``\\n``). + .. _component-expression-objects: Working with Objects diff --git a/components/security/secure_tools.rst b/components/security/secure_tools.rst index 420a8abb218..16a2c5256f8 100644 --- a/components/security/secure_tools.rst +++ b/components/security/secure_tools.rst @@ -5,7 +5,27 @@ The Symfony Security component comes with a collection of nice utilities related to security. These utilities are used by Symfony, but you should also use them if you want to solve the problem they address. -Generating a Secure random String +.. note:: + + The functions described in this article were introduced in PHP 5.6 or 7. + For older PHP versions, a polyfill is provided by the + `Symfony Polyfill Component`_. + +Comparing Strings +~~~~~~~~~~~~~~~~~ + +The time it takes to compare two strings depends on their differences. This +can be used by an attacker when the two strings represent a password for +instance; it is known as a `Timing attack`_. + +When comparing two passwords, you should use the :phpfunction:`hash_equals` +function:: + + if (hash_equals($knownString, $userInput)) { + // ... + } + +Generating a Secure Random String ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Whenever you need to generate a secure random string, you are highly @@ -33,11 +53,5 @@ use the :phpfunction:`random_int` function:: $random = random_int(1, 10); -.. note:: - - PHP 7 and up provide the ``random_bytes()`` and ``random_int()`` functions - natively, for older versions of PHP a polyfill is provided by the - `Symfony Polyfill Component`_ and the `paragonie/random_compat package`_. - +.. _`Timing attack`: https://en.wikipedia.org/wiki/Timing_attack .. _`Symfony Polyfill Component`: https://github.com/symfony/polyfill -.. _`paragonie/random_compat package`: https://github.com/paragonie/random_compat diff --git a/cookbook/controller/error_pages.rst b/cookbook/controller/error_pages.rst index 8789cfe9d76..31081b148f6 100644 --- a/cookbook/controller/error_pages.rst +++ b/cookbook/controller/error_pages.rst @@ -267,7 +267,7 @@ In that case, you might want to override one or both of the ``showAction()`` and # app/config/services.yml services: app.exception_controller: - class: AppBundle\CustomExceptionController + class: AppBundle\Controller\CustomExceptionController arguments: ['@twig', '%kernel.debug%'] .. code-block:: xml @@ -298,6 +298,7 @@ In that case, you might want to override one or both of the ``showAction()`` and new Reference('twig'), '%kernel.debug%' )); + $container->setDefinition('app.exception_controller', $definition); And then configure ``twig.exception_controller`` using the controller as services syntax (e.g. ``app.exception_controller:showAction``). diff --git a/cookbook/email/dev_environment.rst b/cookbook/email/dev_environment.rst index c9eb21433dc..c8bfc8b3e55 100644 --- a/cookbook/email/dev_environment.rst +++ b/cookbook/email/dev_environment.rst @@ -141,12 +141,9 @@ by adding the ``delivery_whitelist`` option: swiftmailer: delivery_address: dev@example.com delivery_whitelist: - # all email addresses matching this regex will *not* be - # redirected to dev@example.com + # all email addresses matching these regexes will be delivered + # like normal, as well as being sent to dev@example.com - '/@specialdomain\.com$/' - - # all emails sent to admin@mydomain.com won't - # be redirected to dev@example.com too - '/^admin@mydomain\.com$/' .. code-block:: xml @@ -162,10 +159,9 @@ by adding the ``delivery_whitelist`` option: http://symfony.com/schema/dic/swiftmailer http://symfony.com/schema/dic/swiftmailer/swiftmailer-1.0.xsd"> - + /@specialdomain\.com$/ - - /^admin@mydomain\.com$/ @@ -176,19 +172,16 @@ by adding the ``delivery_whitelist`` option: $container->loadFromExtension('swiftmailer', array( 'delivery_address' => "dev@example.com", 'delivery_whitelist' => array( - // all email addresses matching this regex will *not* be - // redirected to dev@example.com + // all email addresses matching these regexes will be delivered + // like normal, as well as being sent to dev@example.com '/@specialdomain\.com$/', - - // all emails sent to admin@mydomain.com won't be - // redirected to dev@example.com too '/^admin@mydomain\.com$/', ), )); -In the above example all email messages will be redirected to ``dev@example.com``, -except messages sent to the ``admin@mydomain.com`` address or to any email -address belonging to the domain ``specialdomain.com``, which will be delivered as normal. +In the above example all email messages will be redirected to ``dev@example.com`` +and messages sent to the ``admin@mydomain.com`` address or to any email address +belonging to the domain ``specialdomain.com`` will also be delivered as normal. Viewing from the Web Debug Toolbar ---------------------------------- diff --git a/cookbook/security/csrf_in_login_form.rst b/cookbook/security/csrf_in_login_form.rst index be8f3f9d569..762801d6554 100644 --- a/cookbook/security/csrf_in_login_form.rst +++ b/cookbook/security/csrf_in_login_form.rst @@ -92,7 +92,7 @@ using the login form: {# src/AppBundle/Resources/views/Security/login.html.twig #} {# ... #} -
+ {# ... the login fields #} - + {{ error.message }} {% endif %} - + @@ -255,7 +255,7 @@ redirect to the URL defined by some ``account`` route, use the following: - + diff --git a/cookbook/security/form_login_setup.rst b/cookbook/security/form_login_setup.rst index 527c971b197..02b71d7c0cc 100644 --- a/cookbook/security/form_login_setup.rst +++ b/cookbook/security/form_login_setup.rst @@ -26,8 +26,8 @@ First, enable form login under your firewall: main: anonymous: ~ form_login: - login_path: /login - check_path: /login_check + login_path: login + check_path: login .. code-block:: xml @@ -42,7 +42,7 @@ First, enable form login under your firewall: - + @@ -55,8 +55,8 @@ First, enable form login under your firewall: 'main' => array( 'anonymous' => null, 'form_login' => array( - 'login_path' => '/login', - 'check_path' => '/login_check', + 'login_path' => 'login', + 'check_path' => 'login', ), ), ), @@ -82,8 +82,8 @@ bundle:: { } -Next, create two routes: one for each of the paths you configured earlier -under your ``form_login`` configuration (``/login`` and ``/login_check``): +Next, configure the route that you earlier used under your ``form_login`` +configuration (``login``): .. configuration-block:: @@ -98,34 +98,20 @@ under your ``form_login`` configuration (``/login`` and ``/login_check``): class SecurityController extends Controller { /** - * @Route("/login", name="login_route") + * @Route("/login", name="login") */ public function loginAction(Request $request) { } - - /** - * @Route("/login_check", name="login_check") - */ - public function loginCheckAction() - { - // this controller will not be executed, - // as the route is handled by the Security system - } } .. code-block:: yaml # app/config/routing.yml - login_route: + login: path: /login defaults: { _controller: AppBundle:Security:login } - login_check: - path: /login_check - # no controller is bound to this route - # as it's handled by the Security system - .. code-block:: xml @@ -135,13 +121,9 @@ under your ``form_login`` configuration (``/login`` and ``/login_check``): xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - + AppBundle:Security:login - - - .. code-block:: php @@ -151,14 +133,10 @@ under your ``form_login`` configuration (``/login`` and ``/login_check``): use Symfony\Component\Routing\Route; $collection = new RouteCollection(); - $collection->add('login_route', new Route('/login', array( + $collection->add('login', new Route('/login', array( '_controller' => 'AppBundle:Security:login', ))); - $collection->add('login_check', new Route('/login_check')); - // no controller is bound to this route - // as it's handled by the Security system - return $collection; Great! Next, add the logic to ``loginAction`` that will display the login @@ -209,7 +187,7 @@ Finally, create the template:
{{ error.messageKey|trans(error.messageData, 'security') }}
{% endif %} - + @@ -234,7 +212,7 @@ Finally, create the template: - + @@ -260,7 +238,7 @@ Finally, create the template: The form can look like anything, but has a few requirements: -* The form must POST to ``/login_check``, since that's what you configured +* The form must POST to the ``login`` route, since that's what you configured under the ``form_login`` key in ``security.yml``. * The username must have the name ``_username`` and the password must have @@ -288,7 +266,7 @@ To review the whole process: user to the login form (``/login``); #. The ``/login`` page renders login form via the route and controller created in this example; -#. The user submits the login form to ``/login_check``; +#. The user submits the login form to ``/login``; #. The security system intercepts the request, checks the user's submitted credentials, authenticates the user if they are correct, and sends the user back to the login form if they are not. @@ -315,12 +293,11 @@ When setting up your login form, watch out for a few common pitfalls. 1. Create the Correct Routes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -First, be sure that you've defined the ``/login`` and ``/login_check`` -routes correctly and that they correspond to the ``login_path`` and -``check_path`` config values. A misconfiguration here can mean that you're -redirected to a 404 page instead of the login page, or that submitting -the login form does nothing (you just see the login form over and over -again). +First, be sure that you've defined the ``/login`` route correctly and that +it corresponds to the ``login_path`` and``check_path`` config values. +A misconfiguration here can mean that you're redirected to a 404 page instead +of the login page, or that submitting the login form does nothing (you just see +the login form over and over again). 2. Be Sure the Login Page Isn't Secure (Redirect Loop!) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -463,14 +440,14 @@ for the login page: ), ), -3. Be Sure /login_check Is Behind a Firewall -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +3. Be Sure check_path Is Behind a Firewall +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Next, make sure that your ``check_path`` URL (e.g. ``/login_check``) is behind +Next, make sure that your ``check_path`` URL (e.g. ``/login``) is behind the firewall you're using for your form login (in this example, the single -firewall matches *all* URLs, including ``/login_check``). If ``/login_check`` +firewall matches *all* URLs, including ``/login``). If ``/login`` doesn't match any firewall, you'll receive a ``Unable to find the controller -for path "/login_check"`` exception. +for path "/login"`` exception. 4. Multiple Firewalls Don't Share the Same Security Context ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/cookbook/security/remember_me.rst b/cookbook/security/remember_me.rst index 75db0cc7861..7885b43922f 100644 --- a/cookbook/security/remember_me.rst +++ b/cookbook/security/remember_me.rst @@ -156,7 +156,7 @@ this:
{{ error.message }}
{% endif %} - + @@ -178,7 +178,7 @@ this: - + diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst index 7b3efece11a..541dac8bc11 100644 --- a/reference/dic_tags.rst +++ b/reference/dic_tags.rst @@ -552,6 +552,13 @@ tag: The ``priority`` value is optional and defaults to 0. The higher the priority, the sooner it gets executed. +.. caution:: + + If your cache warmer fails its execution because of any exception, Symfony + won't try to execute it again for the next requests. Therefore, your + application and/or bundles should be prepared for when the contents + generated by the cache warmer are not available. + Core Cache Warmers ~~~~~~~~~~~~~~~~~~