php - Symfony - user gets logged out even on a name change -
i facing weird situation user role_admin
gets logged out change name , if dont change , press save button gets logged out. if change user's role directly in database role_user
same code works fine , user not logged out.
following controller takes care of profile update
/** * @route("/profile", name="profile") */ public function profileaction(request $request) { $em = $this->getdoctrine()->getmanager(); $userinfo = $this->getuser(); //create form object $profileform = $this->createform(usertype::class, $userinfo); $profileform->handlerequest($request); //check data validity if($profileform->isvalid()){ $em->persist($userinfo); $em->flush(); $this->get('session')->getflashbag()->add( 'success', 'your profile information has been updated' ); return $this->render('appbundle:admin/user:admin-edit.html.twig',array( 'edit_form' => $profileform->createview() )); } // render registration form return $this->render('appbundle:admin/user:admin-edit.html.twig',array( 'edit_form' => $profileform->createview() )); } }
this security.yml
security: encoders: # our user class , algorithm we'll use encode passwords # http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password appbundle\entity\user: bcrypt providers: # simple example of loading users via doctrine # load users somewhere else: http://symfony.com/doc/current/cookbook/security/custom_provider.html database_users: entity: { class: appbundle:user, property: username } firewalls: # disables authentication assets , profiler, adapt according needs dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: http_basic: ~ anonymous: ~ logout: ~ guard: authenticators: - app.form_login_authenticator - app.facebook_authenticator # default, use start() function formloginauthenticator entry_point: app.form_login_authenticator access_control: - { path: ^/login, roles: is_authenticated_anonymously } - { path: ^/admin/, roles: role_admin } - { path: ^/user, roles: role_user }
update 1
this usertype
namespace appbundle\form; use appbundle\form\eventlistener\adddepartmentdegreecoursefieldsubscriber; use appbundle\form\eventlistener\addprofilefieldsubscriber; use doctrine\orm\entitymanager; use symfony\component\form\abstracttype; use symfony\component\form\formbuilderinterface; use symfony\component\optionsresolver\optionsresolver; class usertype extends abstracttype { private $adddepartmentdegreecoursefieldsubscriber; private $addprofilefieldsubscriver; function __construct(adddepartmentdegreecoursefieldsubscriber $subscriber, addprofilefieldsubscriber $fields) { $this->adddepartmentdegreecoursefieldsubscriber = $subscriber; $this->addprofilefieldsubscriver = $fields; } /** * @param formbuilderinterface $builder * @param array $options */ public function buildform(formbuilderinterface $builder, array $options) { $builder->addeventsubscriber($this->addprofilefieldsubscriver); $builder->addeventsubscriber($this->adddepartmentdegreecoursefieldsubscriber); } /** * @param optionsresolver $resolver */ public function configureoptions(optionsresolver $resolver) { $resolver->setdefaults(array( 'data_class' => 'appbundle\entity\user' )); } }
this addprofilefieldsubscriber
namespace appbundle\form\eventlistener; use symfony\bridge\doctrine\form\type\entitytype; use symfony\component\form\extension\core\type\choicetype; use symfony\component\form\extension\core\type\emailtype; use symfony\component\form\extension\core\type\filetype; use symfony\component\form\extension\core\type\passwordtype; use symfony\component\form\extension\core\type\texttype; use symfony\component\form\formevent; use symfony\component\form\formevents; use symfony\component\eventdispatcher\eventsubscriberinterface; use symfony\component\security\core\authentication\token\storage\tokenstorageinterface; use symfony\component\security\core\authorization\authorizationchecker; use symfony\component\validator\constraints\notblank; class addprofilefieldsubscriber implements eventsubscriberinterface { protected $authorizationchecker; function __construct(authorizationchecker $authorizationchecker) { $this->authorizationchecker = $authorizationchecker; } public static function getsubscribedevents() { // tells dispatcher want listen on form.pre_set_data // event , presetdata method should called. return array(formevents::pre_set_data => 'presetdata'); } public function presetdata(formevent $event) { $user = $event->getdata(); $form = $event->getform(); if($user){ $form->add('firstname', texttype::class); $form->add('lastname', texttype::class); $form->add('password', passwordtype::class, array( 'mapped' => false )); $form->add('profileimage', filetype::class, array( 'data_class' => null )); if (in_array("role_user", $user->getroles())) { $form->add('contactnumber', texttype::class); $form->add('gender', choicetype::class, array( 'choices' => array( 'male' => 'm', 'female' => 'f' ), 'placeholder' => 'provide_gender' )); $form->add('college', entitytype::class, array( 'placeholder' => 'provide_college', 'class' => 'appbundle\entity\college') ); $form->add('interest', entitytype::class, array( 'class' => 'appbundle\entity\interest', 'multiple' => true, 'expanded' => false, 'by_reference' => false, ) ); } if($this->authorizationchecker->isgranted('role_admin') ) { $form->add('isactive', choicetype::class, array( 'choices' => array( 'account_active' => '1', 'account_inactive' => '0' ), 'placeholder' => 'provide_status' )); } } //if selected user has role_user display following fields in edit profile view else { $form->add('username', emailtype::class); $form->add('password', passwordtype::class, array( 'constraints' => array(new notblank(array( 'message' => 'user.password.not_blank' ) ),), )); } } }
this adddepartmentdegreecoursefieldsubscriber
namespace appbundle\form\eventlistener; use appbundle\entity\degree; use appbundle\entity\department; use doctrine\orm\entitymanager; use symfony\bridge\doctrine\form\type\entitytype; use symfony\component\form\extension\core\type\texttype; use symfony\component\form\formevent; use symfony\component\form\formevents; use symfony\component\eventdispatcher\eventsubscriberinterface; use symfony\component\form\forminterface; class adddepartmentdegreecoursefieldsubscriber implements eventsubscriberinterface { protected $em; function __construct(entitymanager $em) { $this->em = $em; } public static function getsubscribedevents() { // tells dispatcher want listen on form.pre_set_data // event , presetdata method should called. return array( formevents::pre_set_data => 'onpresetdata', formevents::pre_submit => 'onpresubmit' ); } protected function addelements(forminterface $form, department $departments = null, degree $degree = null) { // add department element $form->add('department', entitytype::class, array( 'data' => $departments, 'placeholder' => 'provide_department', 'class' => 'appbundle\entity\department') ); // degree empty, unless supplied department $degree = array(); if ($departments) { // fetch courses specified degree $repo = $this->em->getrepository('appbundle:degree'); $degree = $repo->findbydepartment($departments, array('name' => 'asc')); } // add province element $form->add('degree', entitytype::class, array( 'placeholder' => 'provide_degree', 'class' => 'appbundle\entity\degree', 'choices' => $degree) ); // cities empty, unless supplied province $courses = array(); if ($degree) { // fetch cities specified province $repo = $this->em->getrepository('appbundle:course'); $courses = $repo->findbydegree($degree, array('name' => 'asc')); } // add course element $form->add('course', entitytype::class, array( 'class' => 'appbundle\entity\course', 'choices' => $courses, )); } function onpresubmit(formevent $event) { $form = $event->getform(); $data = $event->getdata(); if (isset($data['degree'])) { // note data not yet hydrated entity. $degree = $this->em->getrepository('appbundle:degree')->find($data['degree']); $department = $this->em->getrepository('appbundle:department')->find($data['department']); $this->addelements($form, $department, $degree); } } function onpresetdata(formevent $event) { //echo "before submit";die; $user = $event->getdata(); $form = $event->getform(); if($user){ //if selected user has role_user display following fields in edit profile view if (in_array("role_user", $user->getroles())) { $degree = ( !empty($user) && !empty($user->getcourse())) ? $user->getcourse()->getdegree() : null; $departments = ( !empty($user) && !empty($user->getcourse())) ? $user->getcourse()->getdegree()->getdepartment() : null; $this->addelements($form, $departments, $degree); } } } }
at point clueless causing this, appreciate here...
there's quite few things wrong in you've provided. elements of may contribute behaviour you're seeing.
security rules
in security.yml, have line:
- { path: ^/admin/, roles: role_admin }
which means use without role_admin going shot login screen if access pattern.
meanwhile, in controller, you're directing user admin based route:
/* * @route("admin/profile", name="admin_profile") */
which means, no matter do, they're sent admin pattern. means if change role, they'll kicked firewall.
controller
in controller you're binding user entity formtype, fine. way you're coding implies don't understand how works.
when call handlerequest
, symfony pulls data form (if been submitted), , 'merges' entity passed it. means don't have call setters on object, that's been done you.
user entity
what should have on user
entity, plainpassword
field, , password
field. form maps plainpassword
field.. then, in controller, take plainpassword
value, encode it, set entity's password
field, , make sure clear plainpassword
value (you dont want store that). if you've implemented userinterface
(which should have) on custom user entity, should have method called erasecredentials
, for. here example.
the upshot of when you're checking something, say, new password, have this:
if($profileform->isvalid()){ // $userinfo populated handlerequest if ($userinfo->getplainpassword()) { // encoding/erasing credentials here } // ... }
what suggest, write proper usermanager
class handle of things. centralises things , makes easier debug. heres example
if use such as i've written in example, means when want update users info, have call $usermanager->updateuser($user)
, it'll donkey work you.
Comments
Post a Comment