symfony validation doesn't work - symfony

I guess there is something I'm missing.
I have a User entity which is validated through a yml file but every time I send a post request to the route it seems it doesn't get my request. With this I mean that the route works fine but I keep getting the error messages that the password and username should not be blank (due to the constraints i set). So it seems it's not getting my request validated against the entity.
I made sure to have this settings triggered in my config:
validation: { enabled: true, enable_annotations: true }
Here is my routing.yml:
user_login_homepage:
path: /check
defaults: { _controller: UserLoginBundle:Login:checkCredentials }
methods: [POST]
Here is my validation.yml
User\UserBundle\Entity\User:
properties:
username:
- NotBlank: ~
password:
- NotBlank: ~
Here is my controller (LoginController.php)
public function checkCredentialsAction(Request $request)
{
$recursiveValidator = $this->get('validator');
$user = new User();
$errors = $recursiveValidator->validate($user);
if (count($errors) > 0) {
$errorsString = (string) $errors;
return new Response($errorsString);
}
return new Response('Yuppy');
}
I've just tried to follow the instructions but I'm not able to have it work :(
Am I missing something?

you are creating an empty User so It's correct the error, try this (I have imagine that username and password are passed into POST data right?):
$user = new User();
$postData = $request->request->all();
$user->setUsername($postData['username'];
$user->setPassword($postData['password'];
$errors = $recursiveValidator->validate($user);

Related

No route found for "GET /demo/koco/create" : 404 Not Found - NotFoundHttpException

Why I am getting errors for the route?
Other APIs for the CRUD operation are working fine.
I have added a new controller code for my new API and I am getting a route error.
What could be the mistake?
While I have already written my route in routing.yml
creat:
path: /create
defaults: { _controller: AcmeDemoBundle:DemoController:create }
methods: [GET]
Products:
path: /recentProducts/{id}
defaults: { _controller: AcmeDemoBundle:DemoController:recentProducts }
methods: [GET]
Update:
path: /updateProduct/{id}
defaults: { _controller: AcmeDemoBundle:DemoController:update }
methods: [POST]
Delete:
path: /deleteProduct/{id}
defaults: { _controller: AcmeDemoBundle:DemoController:delete }
methods: [DELETE]
referenceCreation:
path: /koco/create
defaults: { _controller: AcmeDemoBundle:DemoController:createReference }
methods: [GET]
My api is
http://localhost/koco1/web/app_dev.php/demo/koco/create
My Controller is
/**
* #Route("/koco/create", name="referenceCreation")
* #Template()
*/
public function createReferenceAction()
{
$organization = new Organization();
$organization->setName('Sensio Lab');
$user = new User();
$user->setName("Jonathan H. Wage");
$user->setOrganization($organization);
$dm = $this->get('doctrine_mongodb')->getManager();
$dm->persist($organization);
$dm->persist($user);
$dm->flush();
return new Response('Created product id ');
// $response = new Response('Hello Huzaifa ');
// return $response;
}
What is wrong here?
Kindly let me know.
Thanks
Your routing is off.
Also you are creating routes through yaml and through annotations. Should stick to one.
Also server setup looks off too, http://localhost/koco1/web/app_dev.php/demo/koco/create should be more like http://localhost/koco1/web/koco/create, you can try running php server. Going to /public and running php -S localhost:8000 you can read more here: https://www.php.net/manual/en/features.commandline.webserver.php
or symfony cli server https://symfony.com/download
Your routes does not match /demo/koco/create is not equal to /koco/create, you should first of all set up correctly, then it will be easier to debug.

How to query both samaaccountname and userprincipalname symfonyLdap

I have a Symfony login form authenticating against an Ldap server. I can successfully query and authenticate a user using either samaccountname or userprincipalname and the uid key in my config settings. I want to be able to allow the user to enter either their username or their username#domain.com
I have tried a preg_replace on the username in the loadUserbyUsername() method in the LdapUserProviderClass (I know is not ideal). That takes a username such as username#domain.com and passes on username. I was able to verify that the correct user was returned from the Ldap server but I'm still returned to the login form with 'Invalid Credentials'. I believe the reason why this happens in the AuthenticationUtils class request is processed and the username in the request is still username#domain.com and that does not match the username in the user object coming from the Ldap authentication which is username. If anyone has advice on how to accomplish allowing both username#domain.com and username being authenticated against Ldap I would greatly appreciate it.
SecurityController.php
public function login(Request $request, AuthenticationUtils $authenticationUtils): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$newLastUsername = trim(preg_replace('/#.*/', '',$lastUsername));
return $this->render('security/login.html.twig', ['last_username' => $newLastUsername, 'error' => $error]);
}
security.yml
providers:
dsg_ldap:
ldap:
service: Symfony\Component\Ldap\Ldap
base_dn: '%env(BASE_DSN)%'
search_dn: '%env(SEARCH_DN)%'
search_password: '%env(SEARCH_PWD)%'
uid_key: '%env(UID_KEY)%'
#filter: '({uid_key}={_username})'
default_roles: ROLE_USER
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
form_login_ldap:
login_path: login
check_path: login
service: Symfony\Component\Ldap\Ldap
provider: dsg_ldap
dn_string: '%env(DN_STRING)%\{username}'
My LdapUserProvider.php
class LdapUserProvider extends SymfonyLdapUserProvider
{
/** #var array maps ldap groups to roles */
private $groupMapping = [
'**' => '**',
'**' => '**',
'**' => '**',
'**' => '**'
];
/** #var string extracts group name from dn string */
private $groupNameRegExp = '/CN=(.+?),/';
protected function loadUser($username, Entry $entry)
{
$roles = ['ROLE_USER'];
// Check if the entry has attribute with the group
if (!$entry->hasAttribute('memberOf')) {
return new User($username, '', $roles);
}
// Iterate through each group entry line
foreach ($entry->getAttribute('memberOf') as $groupLine) {
// Extract the group name from the line
$groupName = $this->getGroupName($groupLine);
// Check if the group is in the mapping
if (array_key_exists($groupName, $this->groupMapping)) {
// Map the group to the role(s) the user will have
$roles[] = $this->groupMapping[$groupName];
}
}
// Create and return the user object
return new User($username, null, $roles);
}
/**
* Get the group name from the DN
* #param string $dn
* #return string
*/
private function getGroupName($dn)
{
$matches = [];
return preg_match($this->groupNameRegExp, $dn, $matches) ? $matches[1] : '';
}
}
Symfony\Component\Security\Core\User\LdapUserProvider.php
public function loadUserByUsername($username)
{
try {
$this->ldap->bind($this->searchDn, $this->searchPassword);
// what i added
$username = trim(preg_replace('/#.*/', '',$username));
$username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_FILTER);
$query = str_replace('{username}', $username, $this->defaultSearch);
$search = $this->ldap->query($this->baseDn, $query);
} catch (ConnectionException $e) {
throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username), 0, $e);
}
$entries = $search->execute();
$count = \count($entries);
if (!$count) {
throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
}
if ($count > 1) {
throw new UsernameNotFoundException('More than one user found');
}
$entry = $entries[0];
try {
if (null !== $this->uidKey) {
$username = $this->getAttributeValue($entry, $this->uidKey);
}
} catch (InvalidArgumentException $e) {
}
return $this->loadUser($username, $entry);
}
In the loadUserByUsername function, add another query if the first one fails. Your $this->defaultSearch is probably a constant which represents an LDAP filter.
If you create the same line in the first if (!$count) {...} like this:
$query = str_replace('{username}', $username, "(userPrincipalName={username})");
and then execute that query, you are performing a second search for the userPrincipalName which is of the form user#domain

Symfony2 Payum Bundle - Request SecuredCaptureRequest{model: Payment} is not supported

I have just installed and configured the payum bundle. I am having an exception:
Request SecuredCaptureRequest{model: Payment} is not supported.
It occurs after the redirect in the preparePaypalExpressCheckoutPaymentAction in the PaymentController.
Payum config:
payum:
contexts:
payment_with_paypal_express:
storages:
Service\Bundle\PaymentBundle\Entity\Payment:
doctrine:
driver: orm
paypal_express_checkout_nvp:
api:
options:
username: %paypal.express.username%
password: %paypal.express.password%
signature: %paypal.express.signature%
sandbox: %paypal.express.sandbox%
security:
token_storage:
Service\Bundle\PaymentBundle\Entity\PayumSecurityToken:
doctrine:
driver: orm
Payment controller:
class PaymentController extends HelperController
{
public function preparePaypalExpressCheckoutPaymentAction()
{
$paymentName = 'payment_with_paypal_express';
$storage = $this->get('payum')->getStorageForClass(
'Service\Bundle\PaymentBundle\Entity\Payment',
$paymentName
);
# ---- Set payment details below
$package = $this->getPackageRepository()->loadOneByAliasAndDuration(Package::TYPE_SUBSCRIPTION,1);
$accountPackages = new ArrayCollection();
$accountPackages->add((new AccountPackage())->setPackage($package)->setQuantity(1));
/**
* #var Payment $payment
*/
$payment = $storage->createModel();
# Account must be set first, packages must be set before paid attribute
$payment->setAccount($this->getAccount())
->setPackages($accountPackages)
->setPaid(false);
# ---- Set payment details above
$storage->updateModel($payment);
$captureToken = $this->get('payum.security.token_factory')->createCaptureToken(
$paymentName,
$payment,
'service_payment_done' // the route to redirect after capture;
);
$payment->setReturnUrl($captureToken->getTargetUrl())
->setCancelUrl($captureToken->getTargetUrl());
$storage->updateModel($payment);
return $this->redirect($captureToken->getTargetUrl());
}
public function paymentDoneAction(Request $request)
{
$token = $this->get('payum.security.http_request_verifier')->verify($request);
$payment = $this->get('payum')->getPayment($token->getPaymentName());
# $paymentDetails = $token->getDetails();
$status = new BinaryMaskStatusRequest($token);
$payment->execute($status);
if ($status->isSuccess()) {
$this->getUser()->addCredits(100);
$this->get('session')->getFlashBag()->set(
'notice',
'Payment success. Credits were added'
);
}
else if ($status->isPending()) {
$this->get('session')->getFlashBag()->set(
'notice',
'Payment is still pending. Credits were not added'
);
}
else {
$this->get('session')->getFlashBag()->set('error', 'Payment failed');
}
return $this->redirect('service_home');
}
}
Does someone have any hints what I am doing wrong? In the official documentation the payment details were presented as an object/array (a little confusing), but in my controller I made it an object, any thoughts there?
I worked it out. Forgot to extend my Payment details with ArrayObject from Payum:)

Error when updating datas in the database

I'm trying to solve this little problem.
I have a form that allows to modify datas to a db, but when I click on the submit button(even if it changes the values), it shows an error:
Some mandatory parameters are missing ("name") to generate a URL for route "update_page".
500 Internal Server Error - MissingMandatoryParametersException
Can anybody help me?
This is my controller:
class updateElementController extends Controller
{
public function updateAction($name)
{
$request = $this->get('request');
$ingrediente = $this->getDoctrine()
->getRepository('MyCrudBundle:Elements')
->findOneByName($name);
$em = $this->getDoctrine()->getManager();
$elementsmod = new Elements();
$formupdate = $this->createFormBuilder($elementsmod)
->add('name', 'text')
->add('quantity', 'text')
->add('Change element', 'submit')
->getForm();
$formupdate->handleRequest($request);
if ($formupdate->isValid()) {
$newval = $formupdate->getData();
// change "entity" / object values we want to edit
$namevalue= $newval->getName();
$quantityvalue= $newval->getQuantity();
$element->setName($namevalue);
$element->setQuantity($quantityvalue);
// call to flush that entity manager from which we create $item
$em->flush();
return new RedirectResponse($this->generateUrl('update_page'));
}
return $this->render('MyCrudBundle:Default:index.html.twig', array(
'form' => $formupdate->createView(),
));
}
}
And my route:
update_page:
pattern: /updatePage/{name}
defaults: { _controller: MyCrudBundle:updateElement:update }
(if you need other parts of code, just tell me, I'm a beginner and most certainly it's horribly written)
I suggest two options:
If the name is not mandatory in your routing you can change your routing as below
update_page:
pattern: /updatePage/{name}
defaults: { _controller: MyCrudBundle:updateElement:update, name: null }
If the name is mandatory for the generated url you need to pass the name as the pattern param
if ($formupdate->isValid()) {
$newval = $formupdate->getData();
$namevalue= $newval->getName();
$quantityvalue= $newval->getQuantity();
$element->setName($namevalue);
$element->setQuantity($quantityvalue);
$em->flush();
return new RedirectResponse($this->generateUrl('update_page', array('name' => $name)));
}
base on your query selection you have in your controller the $name is mandatory and I suggest to try the second one

Symfony 2 FOSUserBundle with rest login and registration

I have gone through lots of stackoveflow question and articles, but can't find a suitable answer.
I'm using fosuserbundle, hwiouthbundle and lexikjwt bundle.
I'm developing an api based on symfony which will be consumed by an android app and angular app.
Now I need the register and login system with fosuserbundle facebook login with hwiouthbundle and api protection with lexikjwt bundle.
I have implemented fosuserbundle and hwiouthbundke and both working without even writing user controller. But I need this with rest not with form. But I can't out type : rest in router.
Now how can I login, register user with fosuserbundle with rest? I don't want to use fosouth server. Just need registration and login with api not rest from web.
So, if you want register user manually using FOSUserBundle, create a controller and add a register method :
// Acme/AppBundle/Controller/SecurityController
public function registerAction(Request $request)
{
$userManager = $this->get('fos_user.user_manager');
$entityManager = $this->get('doctrine')->getManager();
$data = $request->request->all();
// Do a check for existing user with userManager->findByUsername
$user = $userManager->createUser();
$user->setUsername($data['username']);
// ...
$user->setPlainPassword($data['password']);
$user->setEnabled(true);
$userManager->updateUser($user);
return $this->generateToken($user, 201);
}
And, the generateToken method
protected function generateToken($user, $statusCode = 200)
{
// Generate the token
$token = $this->get('lexik_jwt_authentication.jwt_manager')->create($user)
$response = array(
'token' => $token,
'user' => $user // Assuming $user is serialized, else you can call getters manually
);
return new JsonResponse($response, $statusCode); // Return a 201 Created with the JWT.
}
And the route
security_register:
path: /api/register
defaults: { _controller: AcmeAppBundle:Security:registerAction }
methods: POST
Configure the firewall same as login
// app/config/security.yml
firewalls:
// ...
register:
pattern: ^/api/register
anonymous: true
stateless: true
// ...
access_control:
// ...
- { path: ^/api/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
For login, juste use the check_path of your FOSUser login firewall.
For more information about the token generation, see JWTManager.
Hope this help you.
EDIT
If you want a full example of LexikJWTAuthenticationBundle + FOSUserBundle + FOSRestBundle implementation see my symfony-rest-api

Resources