Symfony2 SonataAdmin: "Access Denied" Exception when trying to extend SonataUserAdmin - symfony

I need to extend SonataUser to set a field called isAdmin to true when a user is being created from the backend.
I have different User groups for ADMIN => (can create admin users and perform CRUD on other entities) and STAFF => (can perform CRUD on other entities).
Customers register from the frontend.
Both backend_users (STAFF) and customers are instances of the User entity, which extends SonataUser.
Till now I was using the default User and Group Admin classes. Here is how my app/config/config.yml looked
...app/config/config.yml...
users:
label: Users
items: [ sonata.user.admin.user ]
groups:
label: Groups
items: [sonata.user.admin.group]
...
It worked fine for me.
Now I needed to customize the default implementation so I copied the code from Sonata/UserBundle/User/BaseUser.php to <my namespace>/AdminBundle/Admin/BackendUser.php
I created the new service and mapped it in config.yml
...app/config/config.yml...
users:
label: Users
items: [ gd_admin.backend_user ]
groups:
label: Groups
items: [sonata.user.admin.group]
...
...GD/AdminBundle/Resources/services.yml...
parameters:
gd_admin.backend_user.class: GD\AdminBundle\Admin\BackendUserAdmin
..
services:
gd_admin.backend_user:
class: %gd_admin.backend_user.class%
tags:
- { name: sonata.admin, manager_type: orm, label: Backend User }
arguments: [null, GD\AdminBundle\Entity\User, null]
# NOTE: No group defined in tags
...
Earlier I had granted the following roles my ADMIN Group:
'ROLE_SONATA_USER_ADMIN_USER_EDIT',
'ROLE_SONATA_USER_ADMIN_USER_LIST',
'ROLE_SONATA_USER_ADMIN_ USER _CREATE',
'ROLE_SONATA_USER_ADMIN_ USER _VIEW',
'ROLE_SONATA_USER_ADMIN_ USER _DELETE',
'ROLE_SONATA_USER_ADMIN_ USER _OPERATOR',
'ROLE_SONATA_USER_ADMIN_ USER _MASTER',
Now they are:
'ROLE_GD_ADMIN_BACKEND_USER_EDIT',
'ROLE_GD_ADMIN_BACKEND_USER_LIST',
'ROLE_GD_ADMIN_BACKEND_USER_CREATE',
'ROLE_GD_ADMIN_BACKEND_USER_VIEW',
'ROLE_GD_ADMIN_BACKEND_USER_DELETE',
'ROLE_GD_ADMIN_BACKEND_USER_OPERATOR',
'ROLE_GD_ADMIN_BACKEND_USER_MASTER',
When I log into my admin/dashboard
I am able to see the BackendUser in Admin Dashboard widget.
But when I click on the "List" or "Add new" I get a 403: Access Denied Exception.
Where am I going wrong?
Thanks,
Amit

I don't think you have to mess around with the BaseUser class from the sonata user bundle.
Instead you could create a new admin crud in your own bundle based on the sonata user admin crud (Sonata\UserBundle\Admin\Document\UserAdmin) and extend it with a prePersist() method to set isAdmin to true:
public function prePersist($object)
{
$object->setIsAdmin(true);
}
prePersist is actually a hook that is called before persisting a new entity.

Related

how to include an entity join in sonata bundle admin list view

related code:
in services.yml
sonata.admin.domain:
class: MyBundle\AdminBundle\Admin\MyAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Domains", label: "Domains" }
arguments:
- ~
- MyBundle\ServiceBundle\Entity\MyEntity
- ~
calls:
- [ setTranslationDomain, [MyOtherBundle]]
in my admin controller:
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->add('domain')
->add('user.email')
->add('_action', 'actions', array(
'actions' => array(
'show' => array())));
}
which errors in:
Notice: Undefined index: user
to describe the problem further, i have a table that has a user_id column, and i want to be able to include the users email address (using fos user bundle) in that same list with that table. i've tried custom query with no luck also. thanks ahead of time
here is official documentation about list view definition :
http://sonata-project.org/bundles/admin/master/doc/reference/action_list.html
and
http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/list_field_definition.html
if you have a user_id within you entity, i guess your entity is an override of fosUserBundle, right ?
so normally you directly access from the list field definition like this :
->add('user.email') // user is you entity object
otherwise if it s a standalone entity with a user_id, you might have a relationship between this entity and the entity which owns your fosuserbundle object, and like in the above list field definition , you should normally access the object email.

Set the display name using memory provider in Symfony2

I am currently trying to create some tests for an application, but I'm stuck on authentication.
In the app I use ldap authentication, which also determines the role of each user. It works well, but to simplify the testing (and to not use real users) I use the in_memory provider in my tests.
The problem is that in my views I use {{ app.user.displayname }}, and the display name is not available with the in_memory provider.
Is there a way to add it ? For example this solution (which does not work) would be perfect :
providers:
in_memory:
memory:
users:
john: { password: john, roles: 'ROLE_USER', displayname: 'John Doe' }
admin: { password: admin, roles: 'ROLE_ADMIN', displayname: 'Admin' }
You could either modify the class
src/Symfony/Component/Security/Core/User/InMemoryUserProvider.php
so it uses the displayname as well or (even better) create your own class which will extend the InMemoryUserProvider and use your own provider (http://symfony.com/doc/current/cookbook/security/custom_provider.html)

FOSUserBundle : handling different types of user

I'm starting a new project, using a symfony2 architercture and the usefull FosUserBundle to handle my users.
In my application, i have 2 different types of users, which are : User and Entreprise.
I created a Userform (with embedded form in it).
Now i want to create a EntrepriseForm (with a different embedded form) but i'm stuck, due to FosUserConfiguration allowing only 1 registration form type.
If it can helps, here is how my config.yml looks like :
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
user_class: Digin\UserBundle\Entity\User
registration:
confirmation:
from_email: # Use this node only if you don't want the global email address for the confirmation email
address: xxx#xxx.org
sender_name: xxx
enabled: true # change to true for required email confirmation
template: FOSUserBundle:Registration:email.txt.twig
form:
type: mybundle_user_registration
handler: fos_user.registration.form.handler.default
name: fos_user_registration_form
validation_groups: [Registration]
Any idea about how i should do that ?
On your place I will add a new Role in your security.yml(remember to start it with ROLE_ symfony ignores other roles). Then add the Listener InteractiveLoginListener to do some extra stuff redirections after login on diffrent roles. And then add JMSSecurityExtraBundle That will help you to validate the access in accions and controllers just by annotations:
use JMS\SecurityExtraBundle\Annotation\PreAuthorize;
class MyService
{
/** #PreAuthorize("hasRole('A') or (hasRole('B') and hasRole('C'))") */
public function secureMethod()
{
// ...
}
}
Look at the documentation: http://jmsyst.com/bundles/JMSSecurityExtraBundle/master/installation

Sonata Admin configuration with FosUser but *not* SonataUser

As per the title I'm using Sonata Admin and FosUser.
Sonata Admin is working fine for my normal entities; I can do the usual CRUD things.
I then followed this example in the docs for hooking into FosUser
My services.yml is thus:
sonata.admin.user:
class: Company\MyBundle\Admin\UserAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Administration", label: "Users" }
arguments: [ null, Company\UserBundle\Entity\User, SonataAdminBundle:CRUD ]
calls:
- [ setUserManager, [ #fos_user.user_manager ] ]
... and I've created UserAdmin.php:
namespace Company\MyBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
use FOS\UserBundle\Model\UserManagerInterface;
class UserAdmin extends Admin
{
I get a user link in the dashboard but when I follow create new or click to edit my fixtures user (BTW the rendered route is http://dev.url/app_dev.php/admin/company/user/user/create) I get a 500 server error saying "Class does not exist":
in /my/path/company/codebase/vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php at line 199
$class = $this->getAliasNamespace($namespaceAlias) . '\\' . $simpleClassName;
}
$proxyClass = new \ReflectionClass($class);
if ($proxyClass->implementsInterface($this->proxyInterfaceName)) {
$class = $proxyClass->getParentClass()->getName();
}
I've fiddled with some of the service settings, the only things I can see different to the example are:
I've changed the namespace to point to my admin class folder
%fos.user.admin.user.entity% wasn't configured anywhere so I've hardcoded it to be Company\UserBundle\Entity\User
I did start to look at adding the SonataUser bundle but as I'm still finding my feet with Symfony2 I figured I'd keep things simple for now and get an unserstanding of what's going wrong here. given the example doesn't mention it as a dependency I assume I can run without it?

Is there a smart way to override form action links in sfDoctrineGuard plugin?

I've set up my Symfony 1.4 project to route /admin in the URL to my backend app. This works fine until I want to edit a user or interact with the generated forms in any way. This is because the generated links are not aware of my /admin prefix.
Is there a smart way to prefix these links without copying the generated templates to my app folder structure?
UPDATE
Contents of generator.yml for the sfGuardUser module:
generator:
class: sfDoctrineGenerator
param:
model_class: sfGuardUser
theme: admin
non_verbose_templates: true
with_show: false
singular: ~
plural: ~
route_prefix: sf_guard_user
with_doctrine_route: true
config:
fields:
password_again: { label: "Password (again)" }
list:
title: User list
display: [=username, created_at, updated_at, last_login]
form:
class: sfGuardUserAdminForm
display:
"User": [first_name, last_name, email_address, username, password, password_again]
"Permissions and groups": [is_active, is_super_admin, groups_list, permissions_list]
edit:
title: Editing User "%%username%%"
new:
title: New User
I have added my own sf_guard_user in my routing.yml which works for new links I create but the generator doesn't pick this up.
Take a look at a sample configuration file for the admin generator (generator.yml): http://www.symfony-project.org/jobeet/1_4/Doctrine/en/12#chapter_12_final_configuration
Most specifically, look at the route_prefix: parameter.
Try setting the route_prefix to
route_prefix: admin

Resources