Get logged user information in sonata-admin

8,281 views
Skip to first unread message

Jose Grieco

unread,
Jul 10, 2012, 1:09:31 PM7/10/12
to sonata...@googlegroups.com
I recently configure SonataUserBundle, and I need hidden some EntityAdmin fields based on which user is logged 

1.) How I get logged user inside admin class?

2.) How to set a value to hidden filed (in my case a associated entity)?

Thomas Rabaix

unread,
Jul 11, 2012, 6:35:39 PM7/11/12
to sonata...@googlegroups.com
If the value is hidden then it is certainly useless. You can do some logic inside the Admin class or you can extends the CrudController to define some default values.

and admin is a standard service, so you can inject the logger through the DIC definition, please review the symfony documentation to learn how to do it.

--
You received this message because you are subscribed to the Google Groups "sonata-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sonata-users/-/-_yohMyrp40J.
To post to this group, send email to sonata...@googlegroups.com.
To unsubscribe from this group, send email to sonata-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sonata-users?hl=en.



--
Thomas Rabaix
http://rabaix.net | http://sonata-project.org

Nelson Suniaga

unread,
Aug 6, 2012, 1:58:36 PM8/6/12
to sonata...@googlegroups.com, tho...@rabaix.net
I don't think is that useless to hide a value in a form.

I'm in the same situation (and that's a guess) than Jose: I need to register the system_user_id value in almost every single table in the database, getting it from the user logged. If I don't hide that field, any user could choose any user listed in the droplist "System User" and obviously that's not the idea.

I can disable that field in the form and capture the ID value in the repository class and save it (I think that's the way I used to do it back in Symfony 1.4).

Right now I'm not sure how to manage to get that done. I'll take your advice and read the symfony documentation.


On Wednesday, July 11, 2012 6:05:39 PM UTC-4:30, Thomas Rabaix wrote:
If the value is hidden then it is certainly useless. You can do some logic inside the Admin class or you can extends the CrudController to define some default values.

and admin is a standard service, so you can inject the logger through the DIC definition, please review the symfony documentation to learn how to do it.

On Tue, Jul 10, 2012 at 7:09 PM, Jose Grieco <jdgr...@gmail.com> wrote:
I recently configure SonataUserBundle, and I need hidden some EntityAdmin fields based on which user is logged 

1.) How I get logged user inside admin class?

2.) How to set a value to hidden filed (in my case a associated entity)?

--
You received this message because you are subscribed to the Google Groups "sonata-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sonata-users/-/-_yohMyrp40J.
To post to this group, send email to sonata...@googlegroups.com.
To unsubscribe from this group, send email to sonata-users+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/sonata-users?hl=en.

Thomas Rabaix

unread,
Aug 6, 2012, 6:25:26 PM8/6/12
to sonata...@googlegroups.com
It is useless to render a hidden field managed by the user session. your solution introduce a security risk as an user can still change the hidden value.

So just assign the logger user to the edited data object when the request is bound ...

To view this discussion on the web visit https://groups.google.com/d/msg/sonata-users/-/OGSblGMGrgUJ.

To post to this group, send email to sonata...@googlegroups.com.
To unsubscribe from this group, send email to sonata-users...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/sonata-users?hl=en.

Nelson Jesús Suniaga Romero

unread,
Aug 6, 2012, 11:29:43 PM8/6/12
to sonata...@googlegroups.com
I'm have to confess that I'm confused. What is the purpose of the CSRF Token in a Symfony form...? Is not exactly for avoid security risks by changing HTML values? I think I understand the use of the logger user information in the controller or just before saving the data form... but, again, I'm kind of confused...

Grzegorz Floryański

unread,
Aug 7, 2012, 5:15:28 PM8/7/12
to sonata...@googlegroups.com, nelson...@gmail.com
Hi Nelson,

I have a similar problem with Yours. Have You managed to solve that issue ? I am still digging but without success.

Nelson Suniaga

unread,
Aug 7, 2012, 7:18:55 PM8/7/12
to sonata...@googlegroups.com, nelson...@gmail.com
Hello Grzegorz,

I'm afraid not. I've been looking for the solution almost the whole (I've been lazy today), but it seems logical capture the user data logged in a repository class. When I achieve it I'll post the solution :-)


On Tuesday, August 7, 2012 4:45:28 PM UTC-4:30, Grzegorz Floryański wrote:
Hi Nelson,

I have a similar problem with Yours. Have You managed to solve that issue ? I am still digging but without success.



W dniu wtorek, 7 sierpnia 2012 05:29:43 UTC+2 użytkownik Nelson Suniaga napisał:
I'm have to confess that I'm confused. What is the purpose of the CSRF Token in a Symfony form...? Is not exactly for avoid security risks by changing HTML values? I think I understand the use of the logger user information in the controller or just before saving the data form... but, again, I'm kind of confused...

On Mon, Aug 6, 2012 at 5:55 PM, Thomas Rabaix <tho...@rabaix.net> wrote:
It is useless to render a hidden field managed by the user session. your solution introduce a security risk as an user can still change the hidden value.

So just assign the logger user to the edited data object when the request is bound ...
On Mon, Aug 6, 2012 at 7:58 PM, Nelson Suniaga <nelson....@gmail.com> wrote:
I don't think is that useless to hide a value in a form.

I'm in the same situation (and that's a guess) than Jose: I need to register the system_user_id value in almost every single table in the database, getting it from the user logged. If I don't hide that field, any user could choose any user listed in the droplist "System User" and obviously that's not the idea.

I can disable that field in the form and capture the ID value in the repository class and save it (I think that's the way I used to do it back in Symfony 1.4).

Right now I'm not sure how to manage to get that done. I'll take your advice and read the symfony documentation.


On Wednesday, July 11, 2012 6:05:39 PM UTC-4:30, Thomas Rabaix wrote:
If the value is hidden then it is certainly useless. You can do some logic inside the Admin class or you can extends the CrudController to define some default values.

and admin is a standard service, so you can inject the logger through the DIC definition, please review the symfony documentation to learn how to do it.

On Tue, Jul 10, 2012 at 7:09 PM, Jose Grieco <jdgr...@gmail.com> wrote:
I recently configure SonataUserBundle, and I need hidden some EntityAdmin fields based on which user is logged 

1.) How I get logged user inside admin class?

2.) How to set a value to hidden filed (in my case a associated entity)?

--
You received this message because you are subscribed to the Google Groups "sonata-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sonata-users/-/-_yohMyrp40J.
To post to this group, send email to sonata...@googlegroups.com.
To unsubscribe from this group, send email to sonata-users...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/sonata-users?hl=en.

--
You received this message because you are subscribed to the Google Groups "sonata-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sonata-users/-/OGSblGMGrgUJ.

To post to this group, send email to sonata...@googlegroups.com.
To unsubscribe from this group, send email to sonata-users...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/sonata-users?hl=en.



--
Thomas Rabaix
http://rabaix.net | http://sonata-project.org

--
You received this message because you are subscribed to the Google Groups "sonata-users" group.
To post to this group, send email to sonata...@googlegroups.com.
To unsubscribe from this group, send email to sonata-users...@googlegroups.com.

Grzegorz Floryański

unread,
Aug 13, 2012, 3:14:34 PM8/13/12
to sonata...@googlegroups.com, nelson...@gmail.com
Anyone with a solution ?

Grzegorz Floryański

unread,
Aug 14, 2012, 4:59:52 AM8/14/12
to sonata...@googlegroups.com, nelson...@gmail.com
Nelson I have a solution.

You need to overwrite the createAction function:

public function createAction()
    {
       

  // the key used to lookup the template
        $templateKey = 'edit';
        
        if (false === $this->admin->isGranted('CREATE')) {
            throw new AccessDeniedException();
        }

        $object = $this->admin->getNewInstance();
$user = $this->container->get('security.context')->getToken()->getUser();
$object->setUser($user);
        $this->admin->setSubject($object);

        $form = $this->admin->getForm();
        $form->setData($object);
        if ($this->get('request')->getMethod() == 'POST') {
            $form->bindRequest($this->get('request'));
            
            $isFormValid = $form->isValid(); 
            
            // persist if the form was valid and if in preview mode the preview was approved
            if ($isFormValid && (!$this->isInPreviewMode() || $this->isPreviewApproved())) {
                $this->admin->create($object);

                if ($this->isXmlHttpRequest()) {
                    return $this->renderJson(array(
                        'result' => 'ok',
                        'objectId' => $this->admin->getNormalizedIdentifier($object)
                    ));
                }

                $this->get('session')->setFlash('sonata_flash_success','flash_create_success');
                // redirect to edit mode
                return $this->redirectTo($object);
            }
            
            // show an error message if the form failed validation
            if (!$isFormValid) {
                $this->get('session')->setFlash('sonata_flash_error', 'flash_create_error');
            } elseif ($this->isPreviewRequested()) {
                // pick the preview template if the form was valid and preview was requested
                $templateKey = 'preview';
            }
        }

        $view = $form->createView();

        // set the theme for the current Admin Form
        $this->get('twig')->getExtension('form')->setTheme($view, $this->admin->getFormTheme());

        return $this->render($this->admin->getTemplate($templateKey), array(
            'action' => 'create',
            'form'   => $view,
            'object' => $object
        ));
    }
    }

Thomas Rabaix

unread,
Aug 14, 2012, 5:09:03 AM8/14/12
to sonata...@googlegroups.com
The CSRF token is used to make sure the request is valid (and not coming from a hacked site ...).

Now you don't need to pass the user id in the form (html) as the value is known by the application by accessing the sercurity layer.

An Admin instance is just a service so you can inject the security context and then move overwrite the getInstance method to set the user attribute

Nelson Suniaga

unread,
Aug 15, 2012, 4:13:28 PM8/15/12
to sonata...@googlegroups.com, nelson...@gmail.com
Hey Grzegorz, thanks for posting your solution. I replay your message throught gmail but I don't see it here. I got a solution a few hours before you, but I was getting two records instead just one, so I use your solution and now it works perfect. I post here the controller and the service:

<?php

namespace Mercury\CargoRecognitionBundle\Controller;

use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Bridge\Monolog\Logger;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Application\Sonata\UserBundle\Entity\User;
use Mercury\CargoRecognitionBundle\Entity\Attachment;
use Mercury\CargoRecognitionBundle\Entity\SystemUser;
use Mercury\CargoRecognitionBundle\Repository\SystemUserRepository;

class AttachmentAdminController extends Controller
{
     /**
    * Set the system user ID
    */
    private function updateFields($object)
    {
        $userName = $this->container->get('security.context')
                        ->getToken()
                        ->getUser()
                        ->getUsername();

        $user = $this->getDoctrine()
                    ->getRepository('ApplicationSonataUserBundle:User')
                    ->findOneByUsername($userName);

        $object->setSystemUser($user);

        return $object;
    }

    /**
    * (non-PHPdoc)
    * @see Sonata\AdminBundle\Controller.CRUDController::createAction()
    */
    public function createAction()
    {
        // the key used to lookup the template
        $templateKey = 'edit';

        if (false === $this->admin->isGranted('CREATE')) {
            throw new AccessDeniedException();
        }

        $object = $this->admin->getNewInstance();

        $object = $this->updateFields($object);

        // custom method
            'object' => $object,
        ));
    }
}


    mercury.cargo_recognition.admin.attachment:
        class: Mercury\CargoRecognitionBundle\Admin\AttachmentAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: General, label: Attachments }
        arguments: [ null, Mercury\CargoRecognitionBundle\Entity\Attachment, "MercuryCargoRecognitionBundle:AttachmentAdmin" ]

Thanks so much!

Wandi Lin

unread,
Nov 27, 2012, 2:51:26 AM11/27/12
to sonata...@googlegroups.com
You can use prePersist() instead of hidden field.

To security.context, you can inject it in the admin services like this:

    acme.blog.admin.article:
        class: Acme\BlogBundle\Admin\ArticleAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: Blog, label: Article }
        arguments: [ null, Acme\BlogBundle\Entity\Article, SonataAdminBundle:CRUD ]
        calls:
            - [ setSecurityContext, [ @security.context ] ]

Then in the Admin Class define setSecurityContext public function:

    public function setSecurityContext($securityContext) {
        $this->securityContext = $securityContext;
    }

    public function getSecurityContext() {
        return $this->securityContext;
    }

    public function prePersist($article) {
        $user = $this->getSecurityContext()->getToken()->getUser();
        $article->setAuthor($user->getUsername());
    }




matteo bruno

unread,
Sep 18, 2013, 4:39:42 AM9/18/13
to sonata...@googlegroups.com
Hi

I've injected security context in my admin class

        calls:
            - [ setTranslationDomain, [QMAdminBundle]]
            - [ setSecurityContext, [@security.context]]



then I wrote my setSecurityContext

public function setSecurityContext($securityContext) {
    $this->securityContext = $securityContext;
}

public function getSecurityContext() {
    return $this->securityContext;
}

public function prePersist($article) {
    $user = $this->getSecurityContext()->getToken()->getUser();

    $appunto->setOperatore($user->getUsername());
}

Unfortunately it doesn't write the user... maybe this happens because I've got a parent document (where I don't need to write the user) and some embedded documents (where I want to write the user)?

Do you have any suggestions to solve this issue?

Thanks a lot


Reply all
Reply to author
Forward
0 new messages