From 41f6bc042cf24527062c75940d547aae299361eb Mon Sep 17 00:00:00 2001 From: FlorianLB Date: Sat, 14 Dec 2013 11:29:16 +0100 Subject: [PATCH 01/39] [security] adding a tip about supported algorithm for 'hash' function --- book/security.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/book/security.rst b/book/security.rst index 49719291d89..e6f09b8a528 100644 --- a/book/security.rst +++ b/book/security.rst @@ -1358,6 +1358,10 @@ the password is simply run through the ``sha1`` algorithm one time and without any extra encoding. You can now calculate the hashed password either programmatically (e.g. ``hash('sha1', 'ryanpass')``) or via some online tool like `functions-online.com`_ +.. tip:: + + Supported algorithms for this method depend on your PHP version. Full list is available calling the PHP method ``hash_algos()``. + If you're creating your users dynamically (and storing them in a database), you can use even tougher hashing algorithms and then rely on an actual password encoder object to help you encode passwords. For example, suppose your User From 6cd751641c5b31032775661b99961c9e7e80f825 Mon Sep 17 00:00:00 2001 From: FlorianLB Date: Sat, 14 Dec 2013 12:47:28 +0100 Subject: [PATCH 02/39] use a phpfunction link + vocabulary change (method -> function) --- book/security.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/book/security.rst b/book/security.rst index e6f09b8a528..81d8c29120f 100644 --- a/book/security.rst +++ b/book/security.rst @@ -1360,7 +1360,8 @@ any extra encoding. You can now calculate the hashed password either programmati .. tip:: - Supported algorithms for this method depend on your PHP version. Full list is available calling the PHP method ``hash_algos()``. + Supported algorithms for this method depend on your PHP version. + A full list is available calling the PHP function :phpfunction:`hash_algos`. If you're creating your users dynamically (and storing them in a database), you can use even tougher hashing algorithms and then rely on an actual password From 16981f89ee14d8284e3b4125627c96d6dc9fb657 Mon Sep 17 00:00:00 2001 From: FlorianLB Date: Sat, 14 Dec 2013 13:14:03 +0100 Subject: [PATCH 03/39] Change wording of voters --- cookbook/security/voters.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cookbook/security/voters.rst b/cookbook/security/voters.rst index 344285a7e7d..7e1e176e422 100644 --- a/cookbook/security/voters.rst +++ b/cookbook/security/voters.rst @@ -40,12 +40,12 @@ The ``vote()`` method must implement the business logic that verifies whether or not the user is granted access. This method must return one of the following values: -* ``VoterInterface::ACCESS_GRANTED``: The user is allowed to access the application +* ``VoterInterface::ACCESS_GRANTED``: The user is allowed to access something * ``VoterInterface::ACCESS_ABSTAIN``: The voter cannot decide if the user is granted or not -* ``VoterInterface::ACCESS_DENIED``: The user is not allowed to access the application +* ``VoterInterface::ACCESS_DENIED``: The user is not allowed to access something In this example, you'll check if the user's IP address matches against a list of -blacklisted addresses. If the user's IP is blacklisted, you'll return +blacklisted addresses and "something" will be the application. If the user's IP is blacklisted, you'll return ``VoterInterface::ACCESS_DENIED``, otherwise you'll return ``VoterInterface::ACCESS_ABSTAIN`` as this voter's purpose is only to deny access, not to grant access. From fafa019f6e14e2d182cc6eb0aee6aa32f6c5ebd4 Mon Sep 17 00:00:00 2001 From: Zbigniew Czapran Date: Wed, 11 Dec 2013 17:10:39 +0100 Subject: [PATCH 04/39] [Book][Validation] validate method in Validator returns ContraintViolationList object not an array --- book/validation.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/book/validation.rst b/book/validation.rst index 6941d357465..3943464fd16 100644 --- a/book/validation.rst +++ b/book/validation.rst @@ -113,8 +113,9 @@ Next, to actually validate an ``Author`` object, use the ``validate`` method on the ``validator`` service (class :class:`Symfony\\Component\\Validator\\Validator`). The job of the ``validator`` is easy: to read the constraints (i.e. rules) of a class and verify whether or not the data on the object satisfies those -constraints. If validation fails, an array of errors is returned. Take this -simple example from inside a controller:: +constraints. If validation fails, a non-empty list +(class :class:`Symfony\\Component\\Validator\\ConstraintViolationList`) of errors +is returned. Take this simple example from inside a controller:: // ... use Symfony\Component\HttpFoundation\Response; From add83894174ee24bf8edbf33910f15c4b0c2c4f3 Mon Sep 17 00:00:00 2001 From: Zbigniew Czapran Date: Wed, 11 Dec 2013 17:32:17 +0100 Subject: [PATCH 05/39] applies WouterJ suggestion --- book/validation.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/book/validation.rst b/book/validation.rst index 3943464fd16..ac4bacfdbd3 100644 --- a/book/validation.rst +++ b/book/validation.rst @@ -113,9 +113,9 @@ Next, to actually validate an ``Author`` object, use the ``validate`` method on the ``validator`` service (class :class:`Symfony\\Component\\Validator\\Validator`). The job of the ``validator`` is easy: to read the constraints (i.e. rules) of a class and verify whether or not the data on the object satisfies those -constraints. If validation fails, a non-empty list -(class :class:`Symfony\\Component\\Validator\\ConstraintViolationList`) of errors -is returned. Take this simple example from inside a controller:: +constraints. If validation fails, a non-empty list of errors +(class :class:`Symfony\\Component\\Validator\\ConstraintViolationList`) is +returned. Take this simple example from inside a controller: // ... use Symfony\Component\HttpFoundation\Response; From 7d87c7b415f0d2065ed6279a0b694ea253f99812 Mon Sep 17 00:00:00 2001 From: Wouter J Date: Sat, 14 Dec 2013 13:39:09 +0100 Subject: [PATCH 06/39] Small fixes --- book/security.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/security.rst b/book/security.rst index 9977e7754cc..0d959cf2e4d 100644 --- a/book/security.rst +++ b/book/security.rst @@ -319,7 +319,7 @@ First, enable form login under your firewall: - + From 114974023cc78da6c586c7456f111e96704e530d Mon Sep 17 00:00:00 2001 From: Wouter J Date: Sat, 14 Dec 2013 13:39:37 +0100 Subject: [PATCH 07/39] Documented CSRF protection in login forms --- cookbook/security/csrf_in_login_form.rst | 115 +++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 cookbook/security/csrf_in_login_form.rst diff --git a/cookbook/security/csrf_in_login_form.rst b/cookbook/security/csrf_in_login_form.rst new file mode 100644 index 00000000000..b3734f71ee6 --- /dev/null +++ b/cookbook/security/csrf_in_login_form.rst @@ -0,0 +1,115 @@ +.. index:: + single: Security; CSRF in the Login Form + +Using CSRF in the Login Form +============================ + +When using a login form, you should make sure that you are protected for CSRF +(`Cross-site request forgery`_). The Security component already has build-in support +form CSRF. In this article, you'll learn how you can use it in your login form. + +Configuring CSRF +---------------- + +At first, you have to configure the security component so it can use CSRF protection. +The security component needs a CSRF provider. You can set this to use the default +provider provided by the Form component: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + firewalls: + secured_area: + # ... + form_login: + # ... + csrf_provider: form.csrf_provider + + .. code-block:: xml + + + + + + + + + + + + + + + .. code-block:: php + + // app/config/security.php + $container->loadFromExtension('security', array( + 'firewalls' => array( + 'secured_area' => array( + // ... + 'form_login' => array( + // ... + 'csrf_provider' => 'form.csrf_provider', + ) + ) + ) + )); + +The Security component can be configured further, but this is all information it needs +to be able to use CSRF in the login form. + +Rendering the CSRF field +------------------------ + +Now the Security component checks for CSRF tokens, you have to add a *hidden* field +to the login form containing the CSRF token. By default, this field is named as +``_csrf_token``. That hidden field has to contain the CSRF token, which can be generated +by using the ``csrf_token`` function. That function requires a token ID, which is +must be set to ``authenticate`` when using the login form: + +.. configuration-block:: + + .. code-block:: html+twig + + {# src/Acme/SecurityBundle/Resources/views/Security/login.html.twig #} + + {# ... #} +
+ {# ... the login fields #} + + + + +
+ + .. code-block:: html+php + + + + +
+ + + + + +
+ +After this, you have protected your login form for CSRF attacks. + +.. tip:: + + You can change the name of the field by setting ``csrf_parameter`` and the token + ID by setting ``intention`` in your configuration. + +.. _`Cross-site request forgery`: http://en.wikipedia.org/wiki/Cross-site_request_forgery From 7f4b3e8ded568f1729a045c7bb9887330c1e31d1 Mon Sep 17 00:00:00 2001 From: Wouter J Date: Sat, 14 Dec 2013 13:40:59 +0100 Subject: [PATCH 08/39] Added references --- book/security.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/book/security.rst b/book/security.rst index 0d959cf2e4d..35d27275ba8 100644 --- a/book/security.rst +++ b/book/security.rst @@ -519,6 +519,11 @@ Finally, create the corresponding template: +.. caution:: + + This login form is currently not protected against CSRF attacks. Read + :doc:`/cookbook/security/csrf_in_login_form` on how to protect your login form. + .. tip:: The ``error`` variable passed into the template is an instance of From 41178bcfe9be723811e35096542aecbabb64684a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Sat, 14 Dec 2013 14:50:20 +0100 Subject: [PATCH 09/39] Removed all occurences of $this->getRequest() The request is a data object, and so the request should not be inside the container. That's why the request will be removed from the container in Symfony 3.0 So it is better to let the HttpKernel injects the request when the user want to use the request. More over, it is faster. The HttpKernel will always check if the request should be injected. So injecting the request is time constant. However, retrieve the request from the container will execute more calls. --- book/controller.rst | 48 +++++++++++++--------- book/http_cache.rst | 17 +++++--- book/security.rst | 4 +- book/translation.rst | 10 +++-- cookbook/session/locale_sticky_session.rst | 7 +++- quick_tour/the_controller.rst | 36 ++++++++++------ 6 files changed, 77 insertions(+), 45 deletions(-) diff --git a/book/controller.rst b/book/controller.rst index 35b43124111..86005085092 100644 --- a/book/controller.rst +++ b/book/controller.rst @@ -496,9 +496,9 @@ value to each variable. directly by duplicating the current request. When this :ref:`sub request ` is executed via the ``http_kernel`` service the ``HttpKernel`` returns a ``Response`` object:: - + use Symfony\Component\HttpKernel\HttpKernelInterface; - + $path = array( '_controller' => 'AcmeHelloBundle:Hello:fancy', 'name' => $name, @@ -585,8 +585,6 @@ Accessing other Services When extending the base controller class, you can access any Symfony2 service via the ``get()`` method. Here are several common services you might need:: - $request = $this->getRequest(); - $templating = $this->get('templating'); $router = $this->get('router'); @@ -655,16 +653,21 @@ by using the native PHP sessions. Storing and retrieving information from the session can be easily achieved from any controller:: - $session = $this->getRequest()->getSession(); + use Symfony\Component\HttpFoundation\Response; - // store an attribute for reuse during a later user request - $session->set('foo', 'bar'); + public function indexAction(Request $request) + { + $session = $request->getSession(); + + // store an attribute for reuse during a later user request + $session->set('foo', 'bar'); - // in another controller for another request - $foo = $session->get('foo'); + // in another controller for another request + $foo = $session->get('foo'); - // use a default value if the key doesn't exist - $filters = $session->get('filters', array()); + // use a default value if the key doesn't exist + $filters = $session->get('filters', array()); + } These attributes will remain on the user for the remainder of that user's session. @@ -682,11 +685,13 @@ These types of messages are called "flash" messages. For example, imagine you're processing a form submit:: - public function updateAction() + use Symfony\Component\HttpFoundation\Request; + + public function updateAction(Request $request) { $form = $this->createForm(...); - $form->handleRequest($this->getRequest()); + $form->handleRequest($request); if ($form->isValid()) { // do some sort of processing @@ -775,17 +780,22 @@ The Request Object ------------------ Besides the values of the routing placeholders, the controller also has access -to the ``Request`` object when extending the base ``Controller`` class:: +to the ``Request`` object. The framework injects the ``Request`` object in the +controller if a variable is type hinted with +`Symfony\Component\HttpFoundation\Request`:: - $request = $this->getRequest(); + use Symfony\Component\HttpFoundation\Request; - $request->isXmlHttpRequest(); // is it an Ajax request? + public function indexAction(Request $request) + { + $request->isXmlHttpRequest(); // is it an Ajax request? - $request->getPreferredLanguage(array('en', 'fr')); + $request->getPreferredLanguage(array('en', 'fr')); - $request->query->get('page'); // get a $_GET parameter + $request->query->get('page'); // get a $_GET parameter - $request->request->get('page'); // get a $_POST parameter + $request->request->get('page'); // get a $_POST parameter + } Like the ``Response`` object, the request headers are stored in a ``HeaderBag`` object and are easily accessible. diff --git a/book/http_cache.rst b/book/http_cache.rst index b84b6a534db..12f5639a266 100644 --- a/book/http_cache.rst +++ b/book/http_cache.rst @@ -557,12 +557,14 @@ each ``ETag`` must be unique across all representations of the same resource. To see a simple implementation, generate the ETag as the md5 of the content:: - public function indexAction() + use Symfony\Component\HttpFoundation\Request; + + public function indexAction(Request $request) { $response = $this->render('MyBundle:Main:index.html.twig'); $response->setETag(md5($response->getContent())); $response->setPublic(); // make sure the response is public/cacheable - $response->isNotModified($this->getRequest()); + $response->isNotModified($request); return $response; } @@ -604,7 +606,9 @@ For instance, you can use the latest update date for all the objects needed to compute the resource representation as the value for the ``Last-Modified`` header value:: - public function showAction($articleSlug) + use Symfony\Component\HttpFoundation\Request; + + public function showAction($articleSlug, Request $request) { // ... @@ -617,7 +621,7 @@ header value:: // Set response as public. Otherwise it will be private by default. $response->setPublic(); - if ($response->isNotModified($this->getRequest())) { + if ($response->isNotModified($request)) { return $response; } @@ -653,8 +657,9 @@ the better. The ``Response::isNotModified()`` method does exactly that by exposing a simple and efficient pattern:: use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\HttpFoundation\Request; - public function showAction($articleSlug) + public function showAction($articleSlug, Request $request) { // Get the minimum information to compute // the ETag or the Last-Modified value @@ -671,7 +676,7 @@ exposing a simple and efficient pattern:: $response->setPublic(); // Check that the Response is not modified for the given Request - if ($response->isNotModified($this->getRequest())) { + if ($response->isNotModified($request)) { // return the 304 Response immediately return $response; } else { diff --git a/book/security.rst b/book/security.rst index 9977e7754cc..408953dccec 100644 --- a/book/security.rst +++ b/book/security.rst @@ -429,13 +429,13 @@ Next, create the controller that will display the login form:: namespace Acme\SecurityBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\SecurityContext; class SecurityController extends Controller { - public function loginAction() + public function loginAction(Request $request) { - $request = $this->getRequest(); $session = $request->getSession(); // get the login error if there is one diff --git a/book/translation.rst b/book/translation.rst index 6158073ac22..73d771032b0 100644 --- a/book/translation.rst +++ b/book/translation.rst @@ -411,12 +411,14 @@ Handling the User's Locale The locale of the current user is stored in the request and is accessible via the ``request`` object:: - // access the request object in a standard controller - $request = $this->getRequest(); + use Symfony\Component\HttpFoundation\Request; - $locale = $request->getLocale(); + public function indexAction(Request $request) + { + $locale = $request->getLocale(); - $request->setLocale('en_US'); + $request->setLocale('en_US'); + } .. tip:: diff --git a/cookbook/session/locale_sticky_session.rst b/cookbook/session/locale_sticky_session.rst index 5f3da5a5977..172930869d7 100644 --- a/cookbook/session/locale_sticky_session.rst +++ b/cookbook/session/locale_sticky_session.rst @@ -100,4 +100,9 @@ use the :method:`Request::getLocale getRequest()->getLocale(); + use Symfony\Component\HttpFoundation\Request; + + public function indexAction(Request $request) + { + $locale = $request->getLocale(); + } diff --git a/quick_tour/the_controller.rst b/quick_tour/the_controller.rst index ce5f1331657..65e8e9e4da0 100644 --- a/quick_tour/the_controller.rst +++ b/quick_tour/the_controller.rst @@ -90,17 +90,22 @@ Getting information from the Request ------------------------------------ Besides the values of the routing placeholders, the controller also has access -to the ``Request`` object:: +to the ``Request`` object. The framework injects the ``Request`` object in the +controller if a variable is type hinted with +`Symfony\Component\HttpFoundation\Request`:: - $request = $this->getRequest(); + use Symfony\Component\HttpFoundation\Request; - $request->isXmlHttpRequest(); // is it an Ajax request? + public function indexAction(Request $request) + { + $request->isXmlHttpRequest(); // is it an Ajax request? - $request->getPreferredLanguage(array('en', 'fr')); + $request->getPreferredLanguage(array('en', 'fr')); - $request->query->get('page'); // get a $_GET parameter + $request->query->get('page'); // get a $_GET parameter - $request->request->get('page'); // get a $_POST parameter + $request->request->get('page'); // get a $_POST parameter + } In a template, you can also access the ``Request`` object via the ``app.request`` variable: @@ -122,16 +127,21 @@ by using native PHP sessions. Storing and retrieving information from the session can be easily achieved from any controller:: - $session = $this->getRequest()->getSession(); + use Symfony\Component\HttpFoundation\Request; - // store an attribute for reuse during a later user request - $session->set('foo', 'bar'); + public function indexAction(Request $request) + { + $session = $this->request->getSession(); - // in another controller for another request - $foo = $session->get('foo'); + // store an attribute for reuse during a later user request + $session->set('foo', 'bar'); - // use a default value if the key doesn't exist - $filters = $session->get('filters', array()); + // in another controller for another request + $foo = $session->get('foo'); + + // use a default value if the key doesn't exist + $filters = $session->get('filters', array()); + } You can also store small messages that will only be available for the very next request:: From 753ce0f9cad9188a7965e39e3a7b991c2fdebe7c Mon Sep 17 00:00:00 2001 From: Romaric Drigon Date: Sat, 14 Dec 2013 14:51:41 +0100 Subject: [PATCH 10/39] Moved "Impersonating a User" to a cookbook entry --- book/security.rst | 120 +--------------------- cookbook/map.rst.inc | 1 + cookbook/security/impersonating_user.rst | 122 +++++++++++++++++++++++ cookbook/security/index.rst | 1 + 4 files changed, 125 insertions(+), 119 deletions(-) create mode 100644 cookbook/security/impersonating_user.rst diff --git a/book/security.rst b/book/security.rst index 9977e7754cc..81975235691 100644 --- a/book/security.rst +++ b/book/security.rst @@ -1873,125 +1873,6 @@ method of the security context:: A firewall must be active or an exception will be thrown when the ``isGranted`` method is called. See the note above about templates for more details. -Impersonating a User --------------------- - -Sometimes, it's useful to be able to switch from one user to another without -having to log out and log in again (for instance when you are debugging or trying -to understand a bug a user sees that you can't reproduce). This can be easily -done by activating the ``switch_user`` firewall listener: - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/security.yml - security: - firewalls: - main: - # ... - switch_user: true - - .. code-block:: xml - - - - - - - - - - .. code-block:: php - - // app/config/security.php - $container->loadFromExtension('security', array( - 'firewalls' => array( - 'main'=> array( - // ... - 'switch_user' => true - ), - ), - )); - -To switch to another user, just add a query string with the ``_switch_user`` -parameter and the username as the value to the current URL: - -.. code-block:: text - - http://example.com/somewhere?_switch_user=thomas - -To switch back to the original user, use the special ``_exit`` username: - -.. code-block:: text - - http://example.com/somewhere?_switch_user=_exit - -During impersonation, the user is provided with a special role called -``ROLE_PREVIOUS_ADMIN``. In a template, for instance, this role can be used -to show a link to exit impersonation: - -.. configuration-block:: - - .. code-block:: html+jinja - - {% if is_granted('ROLE_PREVIOUS_ADMIN') %} - Exit impersonation - {% endif %} - - .. code-block:: html+php - - isGranted('ROLE_PREVIOUS_ADMIN')): ?> - - Exit impersonation - - - -Of course, this feature needs to be made available to a small group of users. -By default, access is restricted to users having the ``ROLE_ALLOWED_TO_SWITCH`` -role. The name of this role can be modified via the ``role`` setting. For -extra security, you can also change the query parameter name via the ``parameter`` -setting: - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/security.yml - security: - firewalls: - main: - # ... - switch_user: { role: ROLE_ADMIN, parameter: _want_to_be_this_user } - - .. code-block:: xml - - - - - - - - - - .. code-block:: php - - // app/config/security.php - $container->loadFromExtension('security', array( - 'firewalls' => array( - 'main'=> array( - // ... - 'switch_user' => array( - 'role' => 'ROLE_ADMIN', - 'parameter' => '_want_to_be_this_user', - ), - ), - ), - )); Stateless Authentication ------------------------ @@ -2116,6 +1997,7 @@ Learn more from the Cookbook ---------------------------- * :doc:`Forcing HTTP/HTTPS ` +* :doc:`Impersonating a User ` * :doc:`Blacklist users by IP address with a custom voter ` * :doc:`Access Control Lists (ACLs) ` * :doc:`/cookbook/security/remember_me` diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index 9c8260fd929..9a1ea8bc75d 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -124,6 +124,7 @@ * :doc:`/cookbook/security/entity_provider` * :doc:`/cookbook/security/remember_me` + * :doc:`/cookbook/security/impersonating_user` * :doc:`/cookbook/security/voters` * :doc:`/cookbook/security/acl` * :doc:`/cookbook/security/acl_advanced` diff --git a/cookbook/security/impersonating_user.rst b/cookbook/security/impersonating_user.rst new file mode 100644 index 00000000000..95818855156 --- /dev/null +++ b/cookbook/security/impersonating_user.rst @@ -0,0 +1,122 @@ +.. index:: + single: Security; Impersonating User + +How to impersonate a User +========================= + +Sometimes, it's useful to be able to switch from one user to another without +having to log out and log in again (for instance when you are debugging or trying +to understand a bug a user sees that you can't reproduce). This can be easily +done by activating the ``switch_user`` firewall listener: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + firewalls: + main: + # ... + switch_user: true + + .. code-block:: xml + + + + + + + + + + .. code-block:: php + + // app/config/security.php + $container->loadFromExtension('security', array( + 'firewalls' => array( + 'main'=> array( + // ... + 'switch_user' => true + ), + ), + )); + +To switch to another user, just add a query string with the ``_switch_user`` +parameter and the username as the value to the current URL: + +.. code-block:: text + + http://example.com/somewhere?_switch_user=thomas + +To switch back to the original user, use the special ``_exit`` username: + +.. code-block:: text + + http://example.com/somewhere?_switch_user=_exit + +During impersonation, the user is provided with a special role called +``ROLE_PREVIOUS_ADMIN``. In a template, for instance, this role can be used +to show a link to exit impersonation: + +.. configuration-block:: + + .. code-block:: html+jinja + + {% if is_granted('ROLE_PREVIOUS_ADMIN') %} + Exit impersonation + {% endif %} + + .. code-block:: html+php + + isGranted('ROLE_PREVIOUS_ADMIN')): ?> + + Exit impersonation + + + +Of course, this feature needs to be made available to a small group of users. +By default, access is restricted to users having the ``ROLE_ALLOWED_TO_SWITCH`` +role. The name of this role can be modified via the ``role`` setting. For +extra security, you can also change the query parameter name via the ``parameter`` +setting: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + firewalls: + main: + # ... + switch_user: { role: ROLE_ADMIN, parameter: _want_to_be_this_user } + + .. code-block:: xml + + + + + + + + + + .. code-block:: php + + // app/config/security.php + $container->loadFromExtension('security', array( + 'firewalls' => array( + 'main'=> array( + // ... + 'switch_user' => array( + 'role' => 'ROLE_ADMIN', + 'parameter' => '_want_to_be_this_user', + ), + ), + ), + )); diff --git a/cookbook/security/index.rst b/cookbook/security/index.rst index a8edbdc4317..e99d1312c7e 100644 --- a/cookbook/security/index.rst +++ b/cookbook/security/index.rst @@ -6,6 +6,7 @@ Security entity_provider remember_me + impersonating_user voters acl acl_advanced From 886ccd5be40f690626ff610fcc7b3b40d72ef9a9 Mon Sep 17 00:00:00 2001 From: FlorianLB Date: Sat, 14 Dec 2013 15:34:42 +0100 Subject: [PATCH 11/39] switch custom DQL code example from multi-manager to single --- cookbook/doctrine/custom_dql_functions.rst | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/cookbook/doctrine/custom_dql_functions.rst b/cookbook/doctrine/custom_dql_functions.rst index 9c863055c08..57527ed3e1c 100644 --- a/cookbook/doctrine/custom_dql_functions.rst +++ b/cookbook/doctrine/custom_dql_functions.rst @@ -17,17 +17,14 @@ In Symfony, you can register your custom DQL functions as follows: doctrine: orm: # ... - entity_managers: - default: - # ... - dql: - string_functions: - test_string: Acme\HelloBundle\DQL\StringFunction - second_string: Acme\HelloBundle\DQL\SecondStringFunction - numeric_functions: - test_numeric: Acme\HelloBundle\DQL\NumericFunction - datetime_functions: - test_datetime: Acme\HelloBundle\DQL\DatetimeFunction + dql: + string_functions: + test_string: Acme\HelloBundle\DQL\StringFunction + second_string: Acme\HelloBundle\DQL\SecondStringFunction + numeric_functions: + test_numeric: Acme\HelloBundle\DQL\NumericFunction + datetime_functions: + test_datetime: Acme\HelloBundle\DQL\DatetimeFunction .. code-block:: xml From fd4f4f2cc94f0cbaaf7c6710ba65f437dff38238 Mon Sep 17 00:00:00 2001 From: FlorianLB Date: Sun, 15 Dec 2013 09:38:48 +0100 Subject: [PATCH 12/39] switch custom DQL code example from multi-manager to single (PHP and XML) --- cookbook/doctrine/custom_dql_functions.rst | 42 +++++++++------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/cookbook/doctrine/custom_dql_functions.rst b/cookbook/doctrine/custom_dql_functions.rst index 57527ed3e1c..35141309b5e 100644 --- a/cookbook/doctrine/custom_dql_functions.rst +++ b/cookbook/doctrine/custom_dql_functions.rst @@ -38,15 +38,12 @@ In Symfony, you can register your custom DQL functions as follows: - - - - Acme\HelloBundle\DQL\SecondStringFunction - Acme\HelloBundle\DQL\DatetimeFunction - - + + Acme\HelloBundle\DQL\SecondStringFunction + Acme\HelloBundle\DQL\DatetimeFunction + @@ -57,23 +54,16 @@ In Symfony, you can register your custom DQL functions as follows: $container->loadFromExtension('doctrine', array( 'orm' => array( // ... - - 'entity_managers' => array( - 'default' => array( - // ... - - 'dql' => array( - 'string_functions' => array( - 'test_string' => 'Acme\HelloBundle\DQL\StringFunction', - 'second_string' => 'Acme\HelloBundle\DQL\SecondStringFunction', - ), - 'numeric_functions' => array( - 'test_numeric' => 'Acme\HelloBundle\DQL\NumericFunction', - ), - 'datetime_functions' => array( - 'test_datetime' => 'Acme\HelloBundle\DQL\DatetimeFunction', - ), - ), + 'dql' => array( + 'string_functions' => array( + 'test_string' => 'Acme\HelloBundle\DQL\StringFunction', + 'second_string' => 'Acme\HelloBundle\DQL\SecondStringFunction', + ), + 'numeric_functions' => array( + 'test_numeric' => 'Acme\HelloBundle\DQL\NumericFunction', + ), + 'datetime_functions' => array( + 'test_datetime' => 'Acme\HelloBundle\DQL\DatetimeFunction', ), ), ), From 906828808f5b25092eeb46400e1465295d664495 Mon Sep 17 00:00:00 2001 From: Dorian Sarnowski Date: Sat, 14 Dec 2013 15:35:58 +0100 Subject: [PATCH 13/39] [#2362] Documentation for label_attr option in Form Compontent --- reference/forms/types/button.rst | 3 +++ reference/forms/types/checkbox.rst | 3 +++ reference/forms/types/choice.rst | 3 +++ reference/forms/types/collection.rst | 3 +++ reference/forms/types/country.rst | 3 +++ reference/forms/types/currency.rst | 3 +++ reference/forms/types/email.rst | 3 +++ reference/forms/types/entity.rst | 3 +++ reference/forms/types/file.rst | 3 +++ reference/forms/types/form.rst | 4 ++++ reference/forms/types/integer.rst | 3 +++ reference/forms/types/language.rst | 3 +++ reference/forms/types/locale.rst | 3 +++ reference/forms/types/money.rst | 3 +++ reference/forms/types/number.rst | 3 +++ .../forms/types/options/label_attr.rst.inc | 22 +++++++++++++++++++ reference/forms/types/password.rst | 3 +++ reference/forms/types/percent.rst | 3 +++ reference/forms/types/radio.rst | 3 +++ reference/forms/types/reset.rst | 3 +++ reference/forms/types/search.rst | 3 +++ reference/forms/types/submit.rst | 3 +++ reference/forms/types/text.rst | 3 +++ reference/forms/types/textarea.rst | 3 +++ reference/forms/types/timezone.rst | 3 +++ reference/forms/types/url.rst | 3 +++ 26 files changed, 98 insertions(+) create mode 100644 reference/forms/types/options/label_attr.rst.inc diff --git a/reference/forms/types/button.rst b/reference/forms/types/button.rst index 6e8cce6ed57..5c73b5f34e1 100644 --- a/reference/forms/types/button.rst +++ b/reference/forms/types/button.rst @@ -15,6 +15,7 @@ A simple, non-responsive button. | Options | - `attr`_ | | | - `disabled`_ | | | - `label`_ | +| | - `label_attr`_ | | | - `translation_domain`_ | +----------------------+----------------------------------------------------------------------+ | Parent type | none | @@ -31,4 +32,6 @@ Options .. include:: /reference/forms/types/options/button_label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/button_translation_domain.rst.inc diff --git a/reference/forms/types/checkbox.rst b/reference/forms/types/checkbox.rst index ddefd70ee06..171b77bf4c6 100644 --- a/reference/forms/types/checkbox.rst +++ b/reference/forms/types/checkbox.rst @@ -16,6 +16,7 @@ if the box is unchecked, the value will be set to false. | Inherited | - `data`_ | | options | - `required`_ | | | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `error_bubbling`_ | @@ -63,6 +64,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst index 551db27c551..b8068bd2926 100644 --- a/reference/forms/types/choice.rst +++ b/reference/forms/types/choice.rst @@ -22,6 +22,7 @@ option. +-------------+------------------------------------------------------------------------------+ | Inherited | - `required`_ | | options | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `error_bubbling`_ | @@ -116,6 +117,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst index decc14e5e93..f7a8e06bbd0 100644 --- a/reference/forms/types/collection.rst +++ b/reference/forms/types/collection.rst @@ -21,6 +21,7 @@ forms, which is useful when creating forms that expose one-to-many relationships | | - `prototype_name`_ | +-------------+-----------------------------------------------------------------------------+ | Inherited | - `label`_ | +| | - `label_attr`_ | | options | - `error_bubbling`_ | | | - `error_mapping`_ | | | - `by_reference`_ | @@ -341,6 +342,8 @@ Not all options are listed here - only the most applicable to this type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/mapped.rst.inc .. include:: /reference/forms/types/options/error_mapping.rst.inc diff --git a/reference/forms/types/country.rst b/reference/forms/types/country.rst index 8d60cb91d98..4d310514dc5 100644 --- a/reference/forms/types/country.rst +++ b/reference/forms/types/country.rst @@ -33,6 +33,7 @@ you should just use the ``choice`` type directly. | | - `error_mapping`_ | | | - `required`_ | | | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `mapped`_ | @@ -76,6 +77,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/currency.rst b/reference/forms/types/currency.rst index d921ce09a1b..6b7536ecd42 100644 --- a/reference/forms/types/currency.rst +++ b/reference/forms/types/currency.rst @@ -26,6 +26,7 @@ should just use the ``choice`` type directly. | | - `error_bubbling`_ | | | - `required`_ | | | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `mapped`_ | @@ -66,6 +67,8 @@ These options inherit from the :doc:`date` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/email.rst b/reference/forms/types/email.rst index fb6ca9a2868..2e90df2ceb6 100644 --- a/reference/forms/types/email.rst +++ b/reference/forms/types/email.rst @@ -13,6 +13,7 @@ The ``email`` field is a text field that is rendered using the HTML5 | Inherited | - `max_length`_ | | options | - `required`_ | | | - `label`_ | +| | - `label_attr`_ | | | - `trim`_ | | | - `read_only`_ | | | - `disabled`_ | @@ -36,6 +37,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/trim.rst.inc .. include:: /reference/forms/types/options/read_only.rst.inc diff --git a/reference/forms/types/entity.rst b/reference/forms/types/entity.rst index 29b73c2b4af..7b0018f1bfd 100644 --- a/reference/forms/types/entity.rst +++ b/reference/forms/types/entity.rst @@ -23,6 +23,7 @@ objects from the database. +-------------+------------------------------------------------------------------+ | Inherited | - `required`_ | | options | - `label`_ | +| | - `label_attr`_ | | | - `multiple`_ | | | - `expanded`_ | | | - `preferred_choices`_ | @@ -190,6 +191,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/file.rst b/reference/forms/types/file.rst index a33dae8d992..19abd57d0ae 100644 --- a/reference/forms/types/file.rst +++ b/reference/forms/types/file.rst @@ -11,6 +11,7 @@ The ``file`` type represents a file input in your form. +-------------+---------------------------------------------------------------------+ | Inherited | - `required`_ | | options | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `error_bubbling`_ | @@ -85,6 +86,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/form.rst b/reference/forms/types/form.rst index b51fe597078..2991e086446 100644 --- a/reference/forms/types/form.rst +++ b/reference/forms/types/form.rst @@ -13,6 +13,10 @@ on all fields. .. include:: /reference/forms/types/options/required.rst.inc +.. include:: /reference/forms/types/options/label.rst.inc + +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/constraints.rst.inc .. include:: /reference/forms/types/options/cascade_validation.rst.inc diff --git a/reference/forms/types/integer.rst b/reference/forms/types/integer.rst index b11d906e4a4..d65cfbf676c 100644 --- a/reference/forms/types/integer.rst +++ b/reference/forms/types/integer.rst @@ -21,6 +21,7 @@ integers. By default, all non-integer values (e.g. 6.78) will round down (e.g. 6 +-------------+-----------------------------------------------------------------------+ | Inherited | - `required`_ | | options | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `error_bubbling`_ | @@ -71,6 +72,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/language.rst b/reference/forms/types/language.rst index dc83dd0d903..5bb0d946d08 100644 --- a/reference/forms/types/language.rst +++ b/reference/forms/types/language.rst @@ -34,6 +34,7 @@ you should just use the ``choice`` type directly. | | - `error_mapping`_ | | | - `required`_ | | | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `mapped`_ | @@ -77,6 +78,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/locale.rst b/reference/forms/types/locale.rst index 6a5378c87dc..4baed222d44 100644 --- a/reference/forms/types/locale.rst +++ b/reference/forms/types/locale.rst @@ -36,6 +36,7 @@ you should just use the ``choice`` type directly. | | - `error_mapping`_ | | | - `required`_ | | | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `mapped`_ | @@ -79,6 +80,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst index 06dfdb7c2c1..a0bc4110888 100644 --- a/reference/forms/types/money.rst +++ b/reference/forms/types/money.rst @@ -21,6 +21,7 @@ how the input and output of the data is handled. +-------------+---------------------------------------------------------------------+ | Inherited | - `required`_ | | options | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `error_bubbling`_ | @@ -89,6 +90,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/number.rst b/reference/forms/types/number.rst index 29f793cd866..747235ab25a 100644 --- a/reference/forms/types/number.rst +++ b/reference/forms/types/number.rst @@ -17,6 +17,7 @@ you want to use for your number. +-------------+----------------------------------------------------------------------+ | Inherited | - `required`_ | | options | - `label`_ | +| | - `label_attr`_ | | | - `read_only`_ | | | - `disabled`_ | | | - `error_bubbling`_ | @@ -79,6 +80,8 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/label.rst.inc +.. include:: /reference/forms/types/options/label_attr.rst.inc + .. include:: /reference/forms/types/options/read_only.rst.inc .. include:: /reference/forms/types/options/disabled.rst.inc diff --git a/reference/forms/types/options/label_attr.rst.inc b/reference/forms/types/options/label_attr.rst.inc new file mode 100644 index 00000000000..de834c4ae1b --- /dev/null +++ b/reference/forms/types/options/label_attr.rst.inc @@ -0,0 +1,22 @@ +label_attr +~~~~~ + +**type**: ``array`` **default**: ``array()`` + +Sets the html attributes for the ``