I'm developing an application in Symfony (version 4.2.3) and use also few bundles from the Sonata project as well the API Platform.
We have 4 different user roles with different privilegies. The API is read-only and should be accessed by ROLE_USER, but ROLE_USER must not access the admin area. The other roles should access the admin area.
I have set up the firewalls and access control paths in the file config/packages/security.yaml, created my custom security handler VoterSecurityHandler and use it in config/packages/sonata_admin.yaml:
sonata_admin:
security:
handler: sonata.admin.security.handler.voter
The security handler is registered in config/services.yaml:
sonata.admin.security.handler.voter:
class: App\Security\Handler\VoterSecurityHandler
arguments: ["#security.authorization_checker", ['ROLE_SUPER_ADMIN']]
I wrote tests using LiipFunctionalTestBundle and supplying data fixtures with different users to check if their permissions are properly handled.
I'm trying to follow best practices and map the whole application structure from src/ into the directory tests/. Since I have src/Security/Handler/VoterSecurityHandler.php I created tests/Security/Handler/TestVoterSecurityHandler.php.
However the VoterSecurityHandler should manage the permissions for the sonata admin, and I'm actually testing the configuration settings in config/packages/security.yaml.
It doesn't feel right to place all the tests in the above mentioned class, but I'm wondering where should I put this kind of "smoke tests"?
My question:
Where do I put tests testing the configuration in the YAML files?
The good practice is to put the test files under the same architecture than your src, but it does not mean you can't write other test files.
If you have no controller, put it directly under tests, and name it how you want (FirewallTest?)
I personally use a dedicated functional test which tests different routes for different roles and only check if I get a 403 / 200.
As you can see here in the documentation they put their file directly under tests : tests/ApplicationAvailabilityFunctionalTest.php
Related
I'm trying to create a development enviroment for the frontend developers. As long as they don't change any php code I thought it might be a good idea do this, if possible:
Create a new entry point all app_frontend.php i.e., disabling the debug
Create a config_frontend.yml file and cache php files generation but disable twig cache as well as js and css
Is there any way to do this? I'm not sure if it's possible
You can create as many environments as you want. After all, environments are just sets of different configuration, nothing more.
This means that if you want to create a frontend environment, you have to do just some things:
Create some sort of front controller that constructs AppKernel using new AppKernel('frontend', false);
As AppKernel::registerContainerConfiguration() in the Symfony Standard Edition uses the environment to determine the config file to load, you have to create app/config/config_frontend.yml as well (or change the logic in the AppKernel method)
Inside this config file, make sure you import the settings that are in common. This often means importing app/config/config.yml. Besides that, you can configure things how you like it. E.g.
# app/config/config_frontend.yml
imports:
- { resource: config.yml }
twig:
cache: false
You can read more about this topic in the Symfony docs.
This is the situation i am currently having issues with:
I have 1 webserver, this webserver must run 2 different websites, those websites are all written in symfony2 and share the same Bundle that i wrote.
Currently this bundle is placed in the src/ folder and loaded in the AppKernel.
Right now i am using the apps approach where i have 2 seperate app folders created in 1 folder called apps ( http://jolicode.com/blog/multiple-applications-with-symfony2 )
However right now my situation changed, i have this 1 webserver with 2 different websites but i also have a second webserver which must also be able to have multiple apps.
Both servers should not share the same configuration files which is having me a lot of difficulties with deploying.
I also want to prevent that i have to deploy unused bundles to a server.
I hope i explained everything as clear as possible, it is not easy to make a description.
As I read, the app folder contains all config or not files related to the app ( doctrine, Kernel, cache, logs, etc). Routing, Services or other files related to how works an specific bundle should be within that bundle in my opinion.
I think there is not a standard or good way to do this because symfony right know has the workflow one app - one project. Any structure which separates bundle config and app con
fig is valid if don't mix both kinds
The tutorials I've read for Symfony 2 instructs users to enter their routing information in
app/config/routing.yml
If users want to have routing information in their own bundles, they're instructed to add a routing.yml file to their Bundle, and then point to their file from app/config/routing.yml with something like
my_route_stuff:
resource: "#CustomstuffBundle/resources/config/routing.yml"
Is there any way to skip the "add this extra configuration to the app/config/routing.yml file? I'm looking for the ability to hand off a bundle to someone else, and have them be able to deploy it into their Symfony application without needing to edit their own app/config/routing.yml.
If this isn't possible, bonus point if anyone can explain why (i.e: the general philosophy behind) routing information is part of the AppKernel instead of the individual Bundles. I'm still a little unclear on the differences between routing.yml files and the normal Symfony config.yml files.
Is there any way to skip the "add this extra configuration to the app/config/routing.yml file?
No, this is the way SonataAdminBundle, FOSUserBundle and a bunch of others handle it.
Why?
Routing belongs to the application, not each and every bundle. If every bundle started including their own routing files and Symfony2 autoloaded them, you would quickly have a mess of routes you may or may not want to enable in your application.
What if SonataAdminBundle wanted you to use /admin, but you already had a route there and wanted Sonata to use /sonata/admin instead? You'd need a file to override those routes and then you're back to square one!
Additionally, although caching mitigates this part, looking up files is expensive and would significantly slow down the development environment. This is why translation files are read from cache even in dev mode and you must clear the cache when you add a new translation resource. See: http://symfony.com/doc/current/book/translation.html#message-catalogues
Finally, leaving the routing out of config.yml is simply a matter of organization. Routing and configuration are two different things and don't belong in the same file.
The general idea is that every file is a thing and should only do that thing.
I would like to ask, what is the best way to structure a project with frontend and backend in Symfony2? In other versions of Symfony this is easy to achieve, because you can create two applications - frontend and backend - then all the libraries/models will become shared between those applications.
Now in Symfony2, everything is a bundle. What is not really clear for me is how could I represent the "two" applications, frontend and backend. Should I create two namespaces - frontend and backend? I would like to keep my entities in just one place, rather than accessing them from the two applications.
Just have one application, create an AdminBundle or BackendBundle or whatever for your project that has all the tools you'll need in the back end, and use firewalls and access control lists in security.yml to create separate routes for the two.
No need to create separate app directories, mess with the console script, or anything like that. By default, Symfony knows how to find entities and other resources for any bundle that you have registered, so you'll be able to share them easily.
This documentation entry on Security is a good place to start learning about access control and firewalls. Here's a quick sample of what my security config looks like:
firewalls:
main:
pattern: /.*
anonymous: true
form_login: true
access_control:
- { path: /admin/.*, roles: ROLE_ADMIN }
- { path: /.*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
If you want complete authentication separation for / and /admin, create a new admin firewall: firewalls do not share authentication information between each other, so you can track users and their sessions separately if you'd like.
I have tried the approach suggested by PAStheLoD (creating app_backend and web_backend, etc) but I found it too much hassle; you have to remember which app to target from console, maintain separate bootstrap files, and the directory structure gets messy.
The method recommended by the Symfony documentation Symfony documentation is to have a separate project for each app. You can then create a separate area for your source code, write most (if not all) of your bundles there and then simply adjust how they are included in autoload.php of both apps.
e.g.
admin_app/
app/
bin/
src/
web/
frontend_app/
app/
bin/
src/
web/
common_src/
Acme/
AdminBundle/
DataBundle/
jQueryBundle/
Then in *_app/app/autoload.php:
$loader->registerNamespaces(array(
'Acme' => __DIR__ . '/../../common_src'
));
As far as I know you still can do the more or less the same thing with Symfony2. Just rename app/ to app_frontend and make a copy to app_backend, also duplicate web/ the same way. Then everything else can live in bundles. Bundles are very powerful, because they can contain routes, configuration or anything else, so you can share what you want and perfectly isolate what you don't want to share.
There might be some problems with the bin/ scripts due to renamed directories, but you just have to correctly configure them (or raise it as an issue at Symfony's Github site.)
How about having one app and creating three bundles, src/Vendor/BackendBundle,src/Vendor/FrontendBundle and src/Vendor/SharedBundle. SharedBundle holds the entities and other shared parts betweeen the FrontendBundle and BackendBundle
its my first real project with Symfony. i need to have some settings like permissions on my backend application.
i know, i must do it with sfDoctrineGuardPlugin. but i don't know how? i have read everthing about sfDoctrineGuardPlugin on symfony website. but i still don't find anything about;
how to implements user groups? i need superadmin (i did it), chief editor, editor, author.
how to set permissions between them? For example, every author just see their own data. editors can edit what author wrote...
thanks a lot in advanced...
sfDoctrineGuardPlugin is version 1.4, but should use now symfony2. Anyway, you could use sfDoctrineGuardPlugin + sfDoctrineApplyPlugin. The first is for permissions control and the second if for all the referent about forms and email in the fronted.
Install the plugins is easy check this to links:
http://www.symfony-project.org/plugins/sfGuardPlugin
http://www.symfony-project.org/plugins/sfDoctrineApplyPlugin
Inside all your backend modules, you'll have to create one folder with "config" name inside on it one file with security.yml with this example content:
sets:
is_secure: true
index:
is_secure: true
with this, you'll tell to symfony that can the user read or not. Check this url for more information:
# http://www.symfony-project.org/reference/1_4/en/08-Security
If you want protected all the backend with the same permissions put the same folder with the same file inside your application.