Symfony3 - Extend namespace - authentication

I have the following directory structure in my symfony3 structure:
src
AppBundle
AppBundle.php
Entity
User
User.php
UserRepository.php
On top of my User.php:
<?php
namespace AppBundle\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="AppBundle\Entity\User\UserRepository")
*/
class User implements UserInterface {
and it tells me:
undefined constant User
Is there any way extending the namespace?
Thanks and Greetings!
EDIT:
occurrence of "user":
security:
providers:
in_memory:
memory:
users:
admin:
password: admin
roles: 'ROLE_ADMIN'
our_db_provider:
entity:
class: AppBundle:User
property: username
encoders:
AppBundle\Entity\User\User:
algorithm: bcrypt

AppBundle:User alias with your configuration resolves to AppBundle\Entity\User class, which obviously doesn't exist. Either use the full namespace AppBundle\Entity\User\User or the AppBundle:User\User alias.
This is how auto-mapping works. It looks for classes in the Entity folder in each bundle.
See the doctrine reference docs for more.

Related

Laravel 8 Jetstream: unable to login with the account seeded using factories and seeder

I am working on a Laravel 8 project. I have noticed that a couple of things have changed including authentication. I am using Jetstream for authentication.
I have installed the Jetstream and I can register and login going to the route /register and /login on the browser. What I am doing now is that for local development, I am creating seeder class so that I can seed the users and log in using those seeded users for local development. But when I log in using those account, it is always complaining that "These credentials do not match our records.".
This is what I have done. I have registered an account on browser using password, "Testing1234". The password hash is saved in the users table. I copied the password and use it in the UserFactory class as follow.
<?php
namespace Database\Factories;
use App\Models\Role;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
use WithFaker;
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = User::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$tive4vPDzIq02SVERWxkYOAeXeaToAv57KQeF1kXXU7nogh60fYO2', //Testing.1234
'remember_token' => Str::random(10),
];
}
}
Then I created a user using factory as follow.
User::factory()->create(['email' => 'testing#gmail.com']);
Then I tried to log in using the user I just created. But it is always complaining, "These credentials do not match our records.". I cannot use the other passwords too. Even the default password that comes with the default user factory class. What is wrong with my code and how can I fix it?
Try using
User::factory()->make([
'email' => 'testing#gmail.com',
]);
I have finally found the issue.
In the JetstreamServiceProvider class, I have added the following code to customise the login flow.
Fortify::authenticateUsing(function (Request $request) {
});
My bad. That is what makes it failing.

CakePHP Authentication Plugin Identity Associations

I'm using CakePHP 3.8 and migrating to the Authentication Plugin (https://book.cakephp.org/authentication/1.1/en/index.html).
When calling $this->Authentication->getIdentity()->getOriginalData() in a controller, I'd like to access a couple of assocations of my User entity.
At the moment, I'm doing this by implementing the following IdentityInterface method in my User entity:
public function getOriginalData() {
$table = TableRegistry::getTableLocator()->get($this->getSource());
$table->loadInto($this, ['Activities', 'Clients']);
return $this;
}
But I feel there should be a contain parameter somewhere within the Plugin configuration (as there was with the AuthComponent).
Can anyone guide me on how to include assocations on the User entity when calling getIdentity()?
The contain option of the authentication objects for the old Auth component has been deprecated quite some time ago, and the recommended method is to use a custom finder, and that's also how it's done in the new authentication plugin.
The ORM resolver takes a finder option, and it has to be configured via the used identifier, which in your case is probably the password identifier, ie something like:
$service->loadIdentifier('Authentication.Password', [
// ...
'resolver' => [
'className' => 'Authentication.Orm',
'finder' => 'authenticatedUser' // <<< there it goes
],
]);
In the finder method in your table class (probably UsersTable) you can then contain whatever you need:
public function findAuthenticatedUser(\Cake\ORM\Query $query, array $options)
{
return $query->contain(['Activities', 'Clients']);
}
See also
Cookbook > Controllers > Components > AuthComponent > Customizing The Find Query
Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Custom Finder Methods
Authentication Cookbook > Identifiers
Authentication Cookbook > Identifiers > ORM Resolver

Sylius : Catchable Fatal Error: Argument 1 passed to AppBundle\Controller\ProductController::__construct()

I'm trying to override the ProductController,i've followed this docs :
http://docs.sylius.org/en/stable/bundles/general/overriding_controllers.html
but an exception keep appearing:
Catchable Fatal Error: Argument 1 passed to Sylius\Bundle\ResourceBundle\Controller\ResourceController::__construct() must implement interface Sylius\Component\Resource\Metadata\MetadataInterface, none given, called in C:\wamp3\www\sidratsoft_website\app\cache\dev\appDevDebugProjectContainer.php on line 1382 and defined
AppBundle/Controller/ProductController.php:
<?php
namespace AppBundle\Controller;
use FOS\RestBundle\View\View;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sylius\Component\Resource\Metadata\MetadataInterface;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
use Sylius\Component\Resource\ResourceActions;
class ProductController extends ResourceController
{
public function allProdSpecificTaxonAction(Request $request,$t){
$locale = $this->get('sylius.context.locale')->getLocale();
/** #var Taxon $taxon */
$taxon = $this->get('sylius.repository.taxon')
->findByName('Honeywell',$locale);
var_dump($taxon);
exit;
}
}
?>
app/config/routing.yml:
app_bundle_product:
path: /products/cat/{taxon}
defaults:
_controller: AppBundle:Product:allProdSpecificTaxonAction
app/config/config.yml:
sylius_product:
resources:
product:
classes:
controller: AppBundle\Controller\ProductController
I suppose you don't have to register controller as service in AppBundle/Resoures/config/services.yml. As you extend ResourceController (which is totally correct) it has to have many dependency injected - fortunately , you don't have to inject them yourself, as Sylius will do the job and automatically register controller with dependencies injected.
i thiink i fixed it, the problem was in the _controller attribute in the routing :
from this :
app_bundle_product:
path: /products/cat/{taxon}
defaults:
_controller: AppBundle:Product:allProdSpecificTaxonAction
to:
app_bundle_product:
path: /products/cat/{taxon}
defaults:
_controller: sylius.controller.product:allProdSpecificTaxonAction

Regenerating password hash during user authentication with Symfony

I'm using Symfony3 and FOSUserBundle and have the below code which enables member entities (that are from a migrated database) to log in with their usual password by using my class "clubEncoder" instead of Symfony's default bcrypt. "clubEncoder" is working fine (as below) for logging members in. Ideally I want to be able to do the following in the background:
Try to authenticate the user using bcrypt
If that fails, then try to authenticate again using the "clubEncoder" class
If a user is authenticated using "clubEncoder" then the password hash in the database should be re-generated using bcrypt (so step #1 works).
My questions:
I assume I need to change my security.yml to specify both encoders. However, the articles I've read only describe using different encoders for handling different subsets of users - whereas I want to try them both on all users...can this still be done?
To regenerate the password hash in the database, I'm assuming the controller needs to be changed however as I'm using FOSUserBundle I do not have the routes to customise. Is this the wrong place to be looking to add the code?
** Below is the code I currently have stable and working for step #2:
config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
fos_user:
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\Member
security.yml
security:
encoders:
AppBundle\Entity\Member:
id: club.member_encoder
// AppBundle\Entity\Member:
// id: bcrypt
parameters.yml
services:
club.member_encoder:
class: AppBundle\Service\clubEncoder
clubEncoder.php
namespace AppBundle\Service;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
class clubEncoder extends \Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder implements PasswordEncoderInterface
{
function __construct($cost=13)
{
parent::__construct($cost);
}
function isPasswordValid($encoded, $raw,$salt)
{
if (parent::isPasswordValid($cost=13, $encoded,$raw,$salt)) return true ;
else if ($this->comparePasswords($encoded, sha1("3^1nD".$raw."Hx&&%"))) {
// ADD SOMETHING HERE TO RE-HASH THE PASSWORD TO BCRYPT???????????????????
return !$this->isPasswordTooLong($raw) &&
$this->comparePasswords($encoded, sha1("ThisIsSaltA".$raw."ThisIsSaltB"));
}
}
}

Create entity test for Symfony 2 bundle which doesn't have entities: The class was not found in the chain configured namespaces

We have created a bundle to integrate CartoDB in Symfony2 projects. This bundle doesn't create any entity itself, because it 'listen' for events such as persist or flush on your own entities to synchronize info between your data and cartodb data. Here is the workflow:
Create an entity object --> persist --> listen event --> add data to cartoDB throught their API --> get cartoDB object id --> update it in your created object
Here is an example for CartoDB Bundle annotations:
/**
* #ORM\Entity
* #ORM\Table(name="testDB", options={"collate"="utf8_general_ci"})
* #CartoDB\CartoDBLink(connection="private", table="testDB", cascade={"persist", "remove"})
*/
class TestDB
{
/**
* #ORM\Column(name="cartodb_index", type="integer", nullable=true)
* #CartoDB\CartoDBColumn(column="testdb_id", index=true)
*/
protected $cartodbId;
We would like to create tests that cover any part of the code, so we have decided to include an Entity in the test folder to test synchronization with cartoDB data, and add it in the test folder, we have followed this steps:
Add Doctrine Bundle to our bundle composer.json.
Create an entity class in this route:
Company/Tests/CartoDB/Entity/TestDB.php
This entity looks like this:
<?php
namespace Company\CartoDBBundle\Tests\CartoDB\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="testDB", options={"collate"="utf8_general_ci"})
* #CartoDB\CartoDBLink(connection="private", table="testDB", cascade={"persist", "remove"})
*/
class TestDB
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
.....
?>
Now its turn for the test script. We use the entity namespace:
use Company\CartoDBBundle\Tests\CartoDB\Entity\TestDB;
Next, we create an entity object:
$test = new TestDB();
$test->setText("HI");
It runs ok, we call objects methods and everything goes right, and last pass:
$em->persist($test);
$em->flush();
Doctrine\Common\Persistence\Mapping\MappingException: The class 'Company\CartoDBBundle\Tests\CartoDB\Entity\TestDB' was not found in the chain configured namespaces
Here is our doctrine configuration:
doctrine:
dbal:
driver: pdo_sqlite
path: "%kernel.root_dir%/sqlite.db"
charset: UTF8
orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: true
Don't know what we are missing, can anyone help us?
The basic problem is that by default, Doctrine only looks in the Bundle/Entity directory. So you need a bit more info under orm: in your configuration file.
The manual has more details: http://symfony.com/doc/current/reference/configuration/doctrine.html
doctrine:
orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: false
mappings:
name:
type: php
dir: %kernel.root_dir%/../src/Company/CartoDBBundle/Tests/CartoDB/Entity
# alias: MyModels
# prefix: MyBundle\OtherNamespacePart\Entity
# is_bundle: true
You may or may not need to futz around with alias and prefix. When it's properly configured then running:
app/console doctrine:schema:update --dump-sql
Will dump the table information.