Empty dashboard for not ROLE_SUPER_ADMIN user (symfony2, sonata acl) - symfony

I use ACL in Sonata Admin Bundle. Аnd when I log in as a root (which has ROLE_SUPER_ADMIN) I can create new users. I've created one (named qwer) and then loged in as qwer.
PROBLEM: in my situation qwer user has empty dashbord, even having roles like
ROLE_SONATA_USER_ADMIN_USER_GUEST, ROLE_SONATA_USER_ADMIN_USER_STAFF, ROLE_SONATA_USER_ADMIN_USER_EDITOR
Please tell my -- what should I do to understad where the problem is.

Did you follow the documentation for ACL fully? You should add your sonata_admin configuration and security.yml just to be sure. Mine looks like:
sonata_admin:
# ...
security:
handler: sonata.admin.security.handler.acl
# acl security information
information:
LIST: [LIST]
GUEST: [VIEW, LIST]
STAFF: [LIST, CREATE]
EDITOR: [OPERATOR, EXPORT, EDIT]
ADMIN: [MASTER]
admin_permissions: [CREATE, LIST, DELETE, UNDELETE, EXPORT, OPERATOR, MASTER]
# permission related to the objects
object_permissions: [VIEW, EDIT, DELETE, UNDELETE, OPERATOR, MASTER, OWNER]
Also ensure your security.yml has the required configuration:
security:
# ...
providers:
fos_userbundle:
id: fos_user.user_manager
acl:
connection: default
access_decision_manager:
strategy: unanimous
And add a PermissionMap to your app/config/parameters.yml or bundle parameters:
# src/AppBundle/Resources/config/services.yml
parameters:
# ...
# Symfony 3 and above
security.acl.permission.map:
class: Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap
# Symfony < 3
security.acl.permission.map.class: Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap
Then there are 3 commands you will need to run:
Initialize your ACL setup (only once)
php app/console init:acl
Reload changes to the configuration (every change in the sonata_admin configuration file)
php app/console sonata:admin:setup-acl
To generate (new) ACL rules for already existing entities/objects. (every change in the sonata_admin configuration file)
php app/console sonata:admin:generate-object-acl
Then once the configuration is setup, logout and log back in again for the roles to apply.

to resolve this problem check that your have in of your app bundle lines:
services:
security.acl.permission.map:
class: Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap
parameters:

Related

Access Denied for view and download routes in SonataMediaBundle and Symfony 4

I use Symfony 4 (more precise 4.1) with SonataAdminBundle and SonataMediaBundle.
This is my config/routes/sonata_media.yaml:
sonata_media_gallery:
resource: '#SonataMediaBundle/Resources/config/routing/gallery.xml'
prefix: /media/gallery
sonata_media:
resource: '#SonataMediaBundle/Resources/config/routing/media.xml'
prefix: /media
If I run php bin/console debug:router there are the following routes in the output:
sonata_media_gallery_index ANY ANY ANY /media/gallery/
sonata_media_gallery_view ANY ANY ANY /media/gallery/view/{id}
sonata_media_view ANY ANY ANY /media/view/{id}/{format}
sonata_media_download ANY ANY ANY /media/download/{id}/{format}
The first two routes work fine, but when I try the other two routes, for example:
http://localhost:8000/media/view/
http://localhost:8000/media/view/1/default
http://localhost:8000/media/download/1
http://localhost:8000/media/download/1/default
then I always get AccessDeniedException, even though I'm authenticated as ROLE_SUPER_ADMIN.
The error happens in vendor/sonata-project/media-bundle/src/Controller/MediaController.php in downloadAction and in viewAction. I was digging around in the source code, but can't find the reason for the exception thrown.
After some research I found the culprit and solved the problem. Here I'd like to share my knowledge.
As I mentioned in the question, the exceptions were thrown from:
vendor/sonata-project/media-bundle/src/Controller/MediaController.php
in the methods downloadAction and viewAction. It was the following if-condition:
if (!$this->get('sonata.media.pool')->getDownloadSecurity($media)->isGranted($media, $this->getCurrentRequest())) {
throw new AccessDeniedException();
}
which is present in both methods. This led me to vendor/sonata-project/media-bundle/src/Provider/Pool.php, and further to vendor/sonata-project/media-bundle/src/Security/RolesDownloadStrategy.php. I couldn't find any bug or problem there, but it opened my eyes to another position in my own configuration:
access_control:
- { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
- { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
How could I be so stupid? The path /media is not declared in security.yml and can be accessed by not authenticated users. The SonataMediaBundle requires per default ROLE_ADMIN or ROLE_SUPER_ADMIN for downloading/viewing the media.
The routes for the Gallery were accessible because vendor/sonata-project/media-bundle/src/Controller/GalleryController.php doesn't check if access is granted.
After finding the culprit the question was which approach to chose to solve the problem
1) Change the route prefix:
sonata_media:
resource: '#SonataMediaBundle/Resources/config/routing/media.xml'
prefix: /admin/media
The declared path in security.yml covers now the media and ROLE_ADMIN and ROLE_SUPER_ADMIN can access the routes.
Disadvantage: what if you want to expose the media outside of the admin? And what if other roles should be able to access them.
2) Declare a new path in security.yml:
access_control:
- { path: ^/media/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
Now we can expose the media outside of the admin. But the other issue is still there: what if other roles need to access the media?
3) Configure another download strategy in the config for SonataMedia:
sonata_media:
# ...
contexts:
default: # the default context is mandatory
download:
strategy: sonata.media.security.connected_strategy
mode: http
# ...
and adjust the path:
access_control:
# ...
- { path: ^/media/, role: [IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED] }
# ...
Now every logged in user can access the media. This solution worked for me.
However it is not a one-size-fits-all recipe. Please check the chapter security from the official documentation to get more detailed information.

How can I test a page behind a security firewall in Symfony?

In Symfony's cookbook, there is a page entitled How to Simulate Authentication with a Token in a Functional Test. In it, it is said that:
The technique described in How to Simulate HTTP Authentication in a Functional Test is cleaner and therefore the preferred way.
Also, on the page that the quotation above links to, the documentation says:
The trick is to include the http_basic key in your firewall, along with the form_login key
This tells me that it is all right to have the form_login key, along with the http_basic key, and somehow http_basic should take precedence.
Here is my config_test.yml configuration file:
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
disable_delivery: true
liip_functional_test:
cache_sqlite_db: true
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_sqlite
path: %kernel.cache_dir%/test.db
security:
firewalls:
default:
http_basic: ~
However, when I open my application in the test environment, I still get redirected to the login_form URL.
Why isn't setting the http_basic acting like the documentation says it should, namely it getting activated rather than form_login?
As commented here, having the code I pasted in my original question works just fine. The reason it is loading the login form is because I am not logging in via http_basic. In other words, when I have both form_login and http_basic enabled, I can login both by providing the PHP_AUTH_USER/PHP_AUTH_PASSWORD, and by logging in through the form. In effect, I don't need different security_*.yml files; I just need to add http_basic: ~ to the already-defined firewall.
Just split security.yml to security_test.yml and security_prod.yml.
In security_test.yml put default security configuration (as delivered with Symfony) or other one, which doesn't have firewall restrictions.
Create a specific config file for test environment, like config_test.yml with
imports:
- { resource: config.yml }
- { resource: security_test.yml }
note here config.yml itself doesn't have any security imports, because You will receive some Exception about overriding security directive or smth.
Create a separate config_prod.yml with
imports:
- { resource: config.yml }
- { resource: security_prod.yml }
Now You have separate security for test and prod environments.
If Your environment naming is good, then Kernel will pick config_test.yml only when tests are executed. For development environment Your should use config_dev.yml instead of config_test.yml

restricted by role entity block in Sonata Admin is not displayed

I am trying to configure SonataAdmin to display certain entity management for different roles. Read sonata docs, lots of QnA on stackoverflow, cannot find the problem...
Problem:
If I login as ROLE_ADMIN user, I can see all blocks, so sonata admin is working fine. But if I log in with other user, I just see empty page with no blocks. I would say I only need to add role ROLE_SONATA_CONTRACT to my user but as it did not work I tried every role I could think of including all roles auto-generated in user admin form.
I can give more information from configs, now I just copied parts I think are relevant.
My config:
Reference: http://sonata-project.org/bundles/admin/master/doc/reference/security.html#role-handler
# services.yml
services:
sonata.block.admin.contract:
class: STH\OrderBundle\Admin\ContractAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Orders", label: "Orders" }
arguments: [null, STH\OrderBundle\Entity\Contract, SonataAdminBundle:CRUD ]
# security.yml
role_hierarchy:
ROLE_SONATA_CONTRACT:
- ROLE_SONATA_BLOCK_ADMIN_CONTRACT_VIEW
- ROLE_SONATA_BLOCK_ADMIN_CONTRACT_GUEST
ROLE_ADMIN: [ROLE_USER, ROLE_ALLOWED_TO_SWITCH, ROLE_SONATA_PAGE_ADMIN_PAGE_EDIT, ROLE_SONATA_PAGE_ADMIN_BLOCK_EDIT]
ROLE_SUPER_ADMIN: ROLE_ADMIN
SONATA:
- ROLE_SONATA_PAGE_ADMIN_PAGE_EDIT # if you are using acl then this line must be commented
- ROLE_SONATA_PAGE_ADMIN_BLOCK_EDIT
access_decision_manager:
strategy: unanimous
# config.yml
security:
handler: sonata.admin.security.handler.role
# acl security information
information:
GUEST: [VIEW, LIST]
STAFF: [EDIT, LIST, CREATE]
EDITOR: [OPERATOR, EXPORT]
ADMIN: [MASTER, ROLE_ADMIN]
# permissions not related to an object instance and also to be available when objects do not exist
# the DELETE admin permission means the user is allowed to batch delete objects
admin_permissions: [CREATE, LIST, DELETE, UNDELETE, EXPORT, OPERATOR, MASTER]
# permission related to the objects
object_permissions: [VIEW, EDIT, DELETE, UNDELETE, OPERATOR, MASTER, OWNER]
System: Symfony 2.5.2, SonataAdminBundle, SonataUserBundle, FOSUserBundle.
I think you are not correctly defining your role hierearchies. Did you tried something like:
role_hierarchy:
ROLE_USER: [ROLE_SONATA_BLOCK_ADMIN_CONTRACT_VIEW,ROLE_SONATA_BLOCK_ADMIN_CONTRACT_GUEST ]
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
Just to trigger some insights about the way you define your hierarchies. hope it helps.

Sonata Page Bundle - creating a page

I'm trying to use Sonata Page Bundle and I've installed it without any issues but I'm having trouble adding blocks to pages. When I looked at Sonata Sandbox I can create page and when I click View Page it will generate blocks automatically which it doesn't do in my project.
I have basically copied settings from sonata sandbox. Also in sanbox if I'm logged in I can access the page without creating publication which in my project I'm getting an error route not found.
cmf_routing:
chain:
routers_by_id:
# enable the DynamicRouter with high priority to allow overwriting configured routes with content
#symfony_cmf_routing_extra.dynamic_router: 200
# enable the symfony default router with a lower priority
sonata.page.router: 150
router.default: 100
sonata_page:
multisite: host # host_with_path
use_streamed_response: false # set the value to false in debug mode or if the reverse proxy does not handle streamed response
ignore_route_patterns:
- (.*)admin(.*) # ignore admin route, ie route containing 'admin'
- ^_(.*) # ignore symfony routes
ignore_routes:
- sonata_page_cache_esi
- sonata_page_cache_ssi
- sonata_page_js_sync_cache
- sonata_page_js_async_cache
- sonata_cache_esi
- sonata_cache_ssi
- sonata_cache_js_async
- sonata_cache_js_sync
- sonata_cache_apc
ignore_uri_patterns:
- admin(.*) # ignore admin route, ie route containing 'admin'
cache_invalidation:
service: sonata.page.cache.invalidation.simple
recorder: sonata.page.cache.recorder
classes:
"Application\Sonata\PageBundle\Entity\Block": getId
default_template: default
templates:
default: { path: 'SonataPageBundle::layout.html.twig', name: 'default' }
2col: { path: 'SonataPageBundle::2columns_layout.html.twig', name: '2 column' }
page_defaults:
homepage: {decorate: false, enabled: true}
#caches:
# esi:
# token: add an unique token here # default is a random value
# version: 3 # version 3 is the default on debian wheezy ...
# servers:
# # you need to ajust this configuration to match your varnish configuration
# - %sonata_page.varnish.command%
# ssi:
# token: add an unique token here # default is a random value
catch_exceptions:
not_found: [404] # render 404 page with "not_found" key (name generated: _page_internal_error_{key})
fatal: [500] # so you can use the same page for different http errors or specify specific page for each error
# Enable Doctrine to map the provided entities
doctrine:
orm:
entity_managers:
default:
mappings:
ApplicationSonataPageBundle: ~
SonataPageBundle: ~
Thanks for any advice
1 - You are right, from front-end site, being logged-in, creating page and then clicking on View Page will generate blocks automatically. This is awesome, but unfortunately the feature will be deleted in futur versions (explanations included)
To use it for now, read the Full configuration options
sonata_page:
(...)
is_inline_edition_on: true
2 - No idea. To perform a global publication, just in case:
php app/console sonata:page:update-core-routes --site=all
php app/console sonata:page:create-snapshots --site=all

Installation HWIOAuthBundle?

I try 10 times to find out how to install HWIOAuthBundle But there is no enough documentation,
I install the Bundle and I follow exactly the documentation in Git But it shows me this error:
InvalidConfigurationException: Unrecognized options "anonymous" under "security.firewalls.secured_area.oauth"
Somehow I didn't understand the Part A) 'Have a user provider that implements'.What should I do?Or where can I find easy documentation
A) Have a user provider that implements OAuthAwareUserProviderInterface
The bundle needs a service that is able to load users based on the user response of the oauth endpoint. If you have a custom service it should implement the interface: HWI\Bundle\OAuthBundle\Security\Core\User\OAuthAwareUserProviderInterface.
The HWIOAuthBundle also ships with three default implementations:
OAuthUserProvider (service name: hwi_oauth.user.provider) - doesn't persist users
EntityUserProvider (service name: hwi_oauth.user.provider.entity) - loads users from a database
FOSUserBundle integration (service name: hwi_oauth.user.provider.fosub_bridge). Checkout the documentation for integrating HWIOAuthBundle with FOSUserBundle for more information: (todo)
what should I do here ?
You should replace/comment out the line of the service:
oauth_user_provider:
service: my.oauth_aware.user_provider.service
and then replace by:
oauth_user_provider:
oauth: ~
Source: https://github.com/hwi/HWIOAuthBundle/issues/72
Go further:
https://gist.github.com/danvbe/4476697
http://m2mdas.github.io/blog/2013/11/21/integrate-hwioauthbundle-with-fosuserbundle/
Ahh, seems like a typo in docs, could you move that anonymous 4 spaces lower to something like:
# app/config/security.yml
security:
firewalls:
secured_area:
anonymous: ~
oauth:
resource_owners:
facebook: "/login/check-facebook"
login_path: /login
failure_path: /login
oauth_user_provider:
service: my.oauth_aware.user_provider.service
Easy fix for this is to define a service like this :
In security.yml keep this :
oauth_user_provider:
service: my.oauth_aware.user_provider.service
In services.yml put this :
services:
my.oauth_aware.user_provider.service:
class: HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider
arguments:
userManager: "#fos_user.user_manager"
properties: ["pass properties as array"]
Thats it !

Resources