Symfony2 decode and compare pass - php

I need to make a form:
when I choose user from list I will get an input where user will be able to write password (for selected user).
And I must compare if the password agrees with the pass from database.
I found one solution on stack. But I asking if meaby there is other way to make it?
Any ideas?
here is what I already done:
Controller:
public function UserAction(Request $request){
$form = $this->createForm(new UserIncType());
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()){
$valuePass=$form->get('Password')->getData();
$valueUser=$form->get('User')->getData();
$security_encoder = null;
$userRepo= $this->getDoctrine()->getRepository('MainCoreBundle:User');
$user = $userRepo->findById($valueUser);
$security_encoder = $this->get('security.encoder_factory')->getEncoder($user);
$password = $request->get('password');
}
return $this->redirect($this->generateUrl('permits_show'));
}
How to decode pass from database and comapre it with pass from form?
Or is there any other way to make it?

Related

Symfony validate entity using form

$userData = (new User())
->setPersonCode(123)
->setPhone('+470002342342342');
$userForm = $this->toolbar->getForm(UserType::class, $userData);
I'm creating form from entity class where is setted data. If now I try use:
$userForm->isValid();
I'm getting true, because form data is not submitted, how I can do validation, without setting manually data to form and submitting ?
If you don't want to submit data to a form, skip forms entirely; use the Validator service directly:
<?php
// (Assuming you're in a controller, otherwise inject the validator some other way.)
$userData = (new User())
->setPersonCode(123)
->setPhone('+470002342342342');
$validator = $this->get('validator');
$errors = $validator->validate($userData);
$isValid = count($errors) === 0;
Your question is worded a little strange and im not sure exactly what you want, If you want to manually set the data like above then call $form->submit() passing the user data.
$userData = (new User())
->setPersonCode(123)
->setPhone('+470002342342342');
$userForm = $this->toolbar->getForm(UserType::class);
$userForm->submit($userData);
if(!$userForm->isValid()){
// handle errors
}
If you want to have the user submit data on a form then do something like this:
public function createUserAction(Request $request)
{
$userForm = $this->toolbar->getForm(UserType::class);
$userForm->handleRequest();
if(!$userForm->isValid()){
// handle errors
}
}
$userForm->handleRequest(); will handle taking data that was submitted from the form on the page.

Symfony2 - How to preserve request parameter when submitting form?

Here's the situation : Some form handling action is invoked from twig template with request POST parameter (ie. entity ID). After the form is submitted and action is being invoked once again to modify value of the underlying object, my entity ID parameter from Request object is gone (it's replaced by Symfony Form request object).
Here's the question : What's the best practice to preserve this request parameter between two invokes of the form?
Here's simple code example :
public function editEntityAction(Request $request, $type)
{
$objId = $request->request->get('entityId');
$updateObj = null;
$form = null;
$dbMen = $dbMen->getRepository('BakaMainBundle:Brand');
$updateObj = $dbMen->find($objId);
$form = $this->createForm(new AddBrand(), $updateObj);
if ($updateObj == null && $form == null)
$this->redirectToRoute('baka_main_main_index');
$form->handleRequest($request);
if ($form->isValid() && $form->isSubmitted())
{
$menager = $this->getDoctrine()->getManager();
$menager->flush();
}
return $this->render('#BakaMain/Specs/EditEntity.html.twig',
array('form' => ($form->createView()));
}
There are three possible ways to preserve values
sessions
cookies
hidden form fields
you could store it in parameters.yml only if its a global configuration variable that is used across the application
there are flashbags used to display flash messages such as 'success form submitted' or 'form submission failed' which is valid exactly once for the next request
i've given you all the options, you can choose accordingly, you can ask me additional details if needed

Changing the user object for the current user in Symfony logs me out

I have the following code:
public function editAction(Request $request)
{
$user = $this->get('security.context')->getToken()->getUser();
// Get the user
$user2 = $this->getDoctrine()
->getRepository('OpinionsUserBundle:User')
->findOneById($user->id);
echo $user->email . '<br>'; // Echo me#example.org
echo $user2->email . '<br>'; // Echo me#example.org
$user2->email = 'blah';
echo $user->email; // Echoes blah
die();
}
So I know that Doctrine must be doing something with references. The problem is I have a form where the user can change their name and email, but if the email is already in use I want to show an error. However, Symfony binds data to the user object when I check validation, so somehow the session is being updated with the new user object, logging me out or changing my user.
How can I avoid this?
The solution I ended up using was refreshing the user model (returning it to it's original state) if my form validation failed.
// Reset to default values or else it will get saved to the session
$em = $this->getDoctrine()->getManager();
$em->refresh($user);

Manipulating POST data to work with Symfony2 forms when used in a REST API

Background:
I am writing a RESTful API on symfony. I want the client to be able to post to a url using the content type application/json and post a json object of form that the controller action is looking for.
Im using a pretty basic controller setup for this. Lets assume for demonstration purposes that im trying to authenticate a simple username password combo.
public function loginAction( Request $request )
{
$user = new ApiUser();
$form = $this->createForm(new ApiUserType(), $user);
if ( "POST" == $request->getMethod() ) {
$form->bindRequest($request);
if ( $form->isValid() ) {
$em = $this->getDoctrine()->getEntityManager();
$repo = $this->getDoctrine()->getRepository('ApiBundle:ApiUser');
$userData = $repo->findOneByUsername($user->getUsername());
if ( is_object($userData) ) {
/** do stuff for authenticating **/
}
else{
return new Response(json_encode(array('error'=>'no user by that username found')));
}
else{
return new Response(json_encode(array('error'=>'invalid form')));
}
}
}
Now the issue that i have, and have i have tried var_dumping this till the cows come home, is that for what ever reason symfony does not want to take the application/json content-body and use that data to populate the form data.
Form name: api_apiuser
Fields: username, password
What would be the best way to handle this type of task. I am open to suggestions as long as i can get this working. Thanks for your time with the matter.
Youll need to access the RAW request body and then use json_decode. Youll probably need to change your bindRequest method to something like the following:
public function bindRequest(Request $request)
{
if($request->getFormat() == 'json') {
$data = json_decode($request->getContent());
return $this->bind($data);
} else {
// your standard logic for pulling data form a Request object
return parent::bind($request);
}
}
I havent really messed with SF2 yet so this is more guessing based on the API, exp. with sf1.x and things ive garnered from presentations on the framework. It might also be better to make a completely different method like bindJsonRequest so things are a bit more tidy.
Ive actually found a similar way to fix this, AFTER checking if the method is post and before binding the request to the form i do this:
if ( "POST" === $request->getMethod() ) {
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')){
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
}
$form->bindRequest($request);
/** Rest of logic **/
}
Yeah, what the form is waiting for during binding is an array containing keys that correspond to your ApiUser properties.
So if you send a POST request with the string:
{ username: 'user', password: 'pass' }
You will have to transform it into an array using json_decode for example:
$data = json_decode($request->getContent()); // $request->request->get('json_param_name');
Then you bind this array to the form using $form->bind($data);
The form will update your ApiUser properties corresponding to array's keys (username, password).
If you're building a RESTful json api, I would advice you to automatize this process using serializers/transformers, like https://github.com/schmittjoh/JMSSerializerBundle/blob/master/Resources/doc/index.rst

Show login form on every page using Zend Form

I cant seem to figure out how to create a flexible sidebar containing and login form (Zend_Form) and various module/controller specific links.
The most common solution seems to be using:
echo $this->action('login', 'authentication', 'default');
But apperently this isnt the 'best' way? I've read that this apprently triggers a dispatchloop and thereby take a performance hit?
I've thought about sing a View_Helper for the sidebar:
class Zend_View_Helper_Sidebar extends Zend_View_Helper_Abstract
{
public function sidebar()
{
$sidebar = $this->view->placeholder('sidebar');
$sidebar->setPrefix('<div class="sidebar-element">')
->setSeparator('</div><div class="sidebar-element">')
->setPostfix('</div>');
$sidebar->append(new Form_Login);
$sidebar->append(new Model_Category->getList());
return $sidebar
}
}
In my Form_Login i have action set to /auth/login which contains the following code:
public function loginAction()
{
$request = $this->getRequest();
if($request->isPost()) {
$form = new Form_Login();
$data = $request->getPost();
if($form->isValid($data)) {
$username = $form->getValue('username');
$password = $form->getValue('password');
$users = new Model_DbTable_Users();
$authenticated = $users->login($username, $password);
if($authenticated) {
//Succes - show identity instead of loginForm
} else {
$this->view->loginForm = $form;
$this->render('/index');
}
}
}
}
If I provide the wrong username/password it renders indexAction which is currently empty. This is fine. It also renders my sidebar containing the loginForm as needed, but the form is empty (The user input is not displayed. Neither is no message that the form failed to validate).
The username-field in the form should display the input that the user provided before submitting. And a error message should be displayed.
Any help as to why this is not happing, is very much appriciated.
You are doing your form validation in a loginAction and you said you are currently posting to index action, is that a typo?
Besides that, you are creating two copies of the Form_Login. Once, in the action and once in view helper. If you validate on one instance in the action, you need to display that same instance of the form in the view helper. You could either move all the validation logic into the view helper or you could share the instance between the view helper and the action. I'm going to suggest the latter.
Check in your view helper if a form already exists in the registry. If it does, just use that instance. Otherwise you can create a new instance. Here's a rough example of what I mean:
class Zend_View_Helper_Sidebar extends Zend_View_Helper_Abstract
{
public function sidebar()
{
$sidebar = $this->view->placeholder('sidebar');
$sidebar->setPrefix('<div class="sidebar-element">')
->setSeparator('</div><div class="sidebar-element">')
->setPostfix('</div>');
if(Zend_Registry::isReigistered('loginForm')) {
$loginForm = Zend_Registry::get('loginForm');
} else {
$loginForm = new Form_Login();
}
$sidebar->append($loginForm);
$sidebar->append(new Model_Category->getList());
return $sidebar
}
}
public function loginAction()
{
$form = new Form_Login();
Zend_Registry::set('loginForm', $form);
$request = $this->getRequest();
if($request->isPost()) {
$data = $request->getPost();
if($form->isValid($data)) {
$username = $form->getValue('username');
$password = $form->getValue('password');
$users = new Model_DbTable_Users();
$authenticated = $users->login($username, $password);
if($authenticated) {
//Succes - show identity instead of loginForm
} else {
$this->view->loginForm = $form;
$this->render('/index');
}
}
}
}
Edit:
No, there is no self checking if an instance of a form already exists. You must do this yourself.
I'm pretty sure the suggested way is to use a view helper. As you said in your question, using the action view helper causes another dispatch loop which is bad for performance. I don't know what the verdict is on whether all logic should be kept in the view helper or not.

Categories