Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add the _locale parameter to security paths?

I setup my security settings to protect everything which is under the root path /, exept for a public page to view the privacy policy, /privacy. Everything works fine.

# security.yml
access_control:
    - { path: ^/privacy$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/,         role: ROLE_USER }

Now I added some different translations to the privacy policy page, so that the route changes from /privacy to /{_locale}/privacy. Unfortunately I cannot add the _locale parameter to the security path like this:

access_control:
    ...
    - { path: ^/{_locale}/privacy$, role: IS_AUTHENTICATED_ANONYMOUSLY }

So how do I have to modify my security.yml so that I can add the _locale to the path and to restrict it to predefined languages, e.g. (en|fr|es|de)?

like image 269
Gottlieb Notschnabel Avatar asked Nov 05 '13 10:11

Gottlieb Notschnabel


3 Answers

If all your locales are 2-character ones (en|fr|es|de|...) you can use a more generic regex like this:

- { path: '^/[a-z]{2}/privacy$', role: 'IS_AUTHENTICATED_ANONYMOUSLY' }

This way you won't have to touch your security.access_control every time you add a new locale.

For locales in the form EN_en you could use something like this btw:

- { path: '^/[a-zA-Z]{2}_[a-zA-Z]{2}/privacy$', role: 'IS_AUTHENTICATED_ANONYMOUSLY' }
like image 75
Nicolai Fröhlich Avatar answered Oct 10 '22 05:10

Nicolai Fröhlich


Nowadays (since Symfony 4.1 or later) you can define the locales in one place and use it everywhere in your application

in config/services.yaml add

parameters:
    myAppName.locales: en|fr|es|de

in config/routes.yaml

cms:
    prefix:   /{_locale}/
    controller: App\Controller\DefaultController::index
    requirements:
        _locale: '%myAppName.locales%'

in config/packages/security.yaml

security:
    ## .... no changes here
    access_control:
        - { path: ^/(%myAppName.locales%)/cms, roles: ROLE_ADMIN }
like image 24
caramba Avatar answered Oct 10 '22 04:10

caramba


I managed to solve the problem like this

access_control:
    ...
    - { path: ^/(en|fr|es|de)/privacy$, role: IS_AUTHENTICATED_ANONYMOUSLY }

A recommendation for other answerers: I now have to enter this string (en|fr|de) into all routes manually. When I add a language I have to modifiy this string in many occurences. It would be much better if one could define a string

parameters:
    languages: "(en|fr|es|de)"

And use this in the route

    - { path: ^/%languages%/privacy$, role: IS_AUTHENTICATED_ANONYMOUSLY }

But I don't think this will work.

like image 42
Gottlieb Notschnabel Avatar answered Oct 10 '22 06:10

Gottlieb Notschnabel