Forums › Forums › OroCommerce › Authentication Anonymous CustomerUser Authentication during Checkout
This topic contains 2 replies, has 2 voices, and was last updated by Frank 4 years, 5 months ago.
Starting from March 1, 2020 the forum has been switched to the read-only mode. Please head to StackOverflow for support.
- CreatorTopic
- September 24, 2019 at 1:57 am #40552
Hi there,
I am trying to modify Anonymous Customer User Authentification:
PHP123456789101112131415161718192021222324252627282930313233343536373839404142#<?phpnamespace Oro\Bundle\CustomerBundle\Security;use ..class AnonymousCustomerUserAuthenticationProvider implements AuthenticationProviderInterface{# .../*** {@inheritDoc}*/public function authenticate(TokenInterface $token){if (!$this->supports($token)) {return null;}$credentials = $token->getCredentials();$visitor =$this->visitorManager->findOrCreate($credentials['visitor_id'], $credentials['session_id']);$this->visitorManager->updateLastVisitTime($visitor, $this->updateLatency);$organization = null;$website = $this->websiteManager->getCurrentWebsite();if ($website !== null) {$organization = $website->getOrganization();}return new AnonymousCustomerUserToken($token->getUser(),$token->getRoles(),$visitor,$organization);}}#I want to customize authenticate()-method (for checkout only) and depending on shoppinglist (my anonymous customer user can create multiple ones), which he uses during enabled guest-checkout-process.
What would be the best way to pass which object into the authenticate-method():
* Checkout (contains shoppinglist as a source)?
* Request (should contain shoppingListId via Get)?
* ..?I’m also unsure about the performance.
Could you roughly sketch me a meaningful approach?
Thanks a lot
Frank - CreatorTopic
- AuthorReplies
- September 25, 2019 at 6:17 am #40569
Hi Frank,
I’m afraid, this is not the right place to extend.
Please specify what are you trying to do with checkout and request data during the authentication process?Also, take a look at the possibility to extend the checkout workflow instead of using the listener. In the workflow, you have access to all the required data, including Checkout entity itself and it should not affect the performance.
October 2, 2019 at 3:56 am #40625Hi Andrey,
yes, AnonymousCustomerUserAuthenticationProvider is really not the right place to extend … !
I followed your suggestion, and looked for some central place in the checkout-workflow to find a pracicable solution for my problem:
What I found useful, was to extend the website-manager in OroWebsiteBundle:
PHP1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980<?phpnamespace Dergraf\CeeWebsiteBundle\Manager;use Dergraf\CeeFrontendBundle\Request\CeeFrontendHelper;use Doctrine\Common\Persistence\ManagerRegistry;use Oro\Bundle\CheckoutBundle\Entity\Checkout;use Oro\Bundle\ShoppingListBundle\Entity\ShoppingList;use Oro\Bundle\WebsiteBundle\Entity\Website;use Oro\Bundle\WebsiteBundle\Manager\WebsiteManager;/*** Basic website manager.* Provides current website.*/class CeeWebsiteManager extends WebsiteManager{/*** @var ManagerRegistry*/protected $managerRegistry;/*** @var*/protected $entityManager;/*** @var CeeFrontendHelper*/protected $frontendHelper;/*** @var Website*/protected $currentWebsite;/*** @param ManagerRegistry $managerRegistry* @param CeeFrontendHelper $frontendHelper*/public function __construct(ManagerRegistry $managerRegistry,CeeFrontendHelper $frontendHelper){parent::__construct($managerRegistry, $frontendHelper);$this->managerRegistry = $managerRegistry;$this->frontendHelper = $frontendHelper;}/**** @return Checkout|null*/public function getCurrentCheckout() {if($this->frontendHelper->isFrontendRequest()) {$request = $this->frontendHelper->getFrontendRequest();$params = [];foreach ($request->attributes as $key => $value) {if ($key[0] !== '_') {$params[$key] = $value;}}if (null !== $params['checkout']) {return $params['checkout'];} elsereturn null;}}}Method CeeWebsiteManager::getCurrentCheckout() allows access to Checkout-object using Request (slightly modified FrontendHelper).
Now I can retrieve my previously to Checkout assigned (businessUnitOwner-driven, modified) owner-property and ‘transfer’ it to everything I want.
For example to customer/customerUser (non-authenticated visitor/guest) creation after input of billing/shippment-addresses:
PHP123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127<?phpnamespace Dergraf\CeeCustomerBundle\Entity;use Dergraf\CeeWebsiteBundle\Manager\CeeWebsiteManager;use Oro\Bundle\CustomerBundle\DependencyInjection\OroCustomerExtension;use Oro\Bundle\CustomerBundle\Entity\CustomerUser;use Oro\Bundle\CustomerBundle\Entity\CustomerUserManager;use Oro\Bundle\CustomerBundle\Entity\GuestCustomerUserManager;use Oro\Bundle\CustomerBundle\EventListener\SystemConfigListener;use Oro\Bundle\CustomerBundle\Provider\CustomerUserRelationsProvider;use Oro\Bundle\UserBundle\Provider\DefaultUserProvider;use Symfony\Component\PropertyAccess\PropertyAccessor;class CeeGuestCustomerUserManager extends GuestCustomerUserManager{/*** @var CeeWebsiteManager*/protected $websiteManager;/*** @var CustomerUserManager*/protected $customerUserManager;/*** @var CustomerUserRelationsProvider*/protected $customerUserRelationsProvider;/*** @var DefaultUserProvider*/protected $defaultUserProvider;/*** @var PropertyAccessor*/protected $propertyAccessor;/*** @param CeeWebsiteManager $websiteManager* @param CustomerUserManager $customerUserManager* @param CustomerUserRelationsProvider $customerUserRelationsProvider* @param DefaultUserProvider $defaultUserProvider* @param PropertyAccessor $propertyAccessor*/public function __construct(CeeWebsiteManager $websiteManager,CustomerUserManager $customerUserManager,CustomerUserRelationsProvider $customerUserRelationsProvider,DefaultUserProvider $defaultUserProvider,PropertyAccessor $propertyAccessor) {parent::__construct($websiteManager,$customerUserManager,$customerUserRelationsProvider,$defaultUserProvider,$propertyAccessor);$this->websiteManager = $websiteManager;$this->customerUserManager = $customerUserManager;$this->customerUserRelationsProvider = $customerUserRelationsProvider;$this->defaultUserProvider = $defaultUserProvider;$this->propertyAccessor = $propertyAccessor;}/*** @param array $properties** @return CustomerUser*/public function generateGuestCustomerUser(array $properties = []){$customerUser = new CustomerUser();$customerUser->setIsGuest(true);$customerUser->setEnabled(false);$customerUser->setConfirmed(false);$website = $this->websiteManager->getCurrentWebsite();$customerUser->setWebsite($website);if ($website && $website->getOrganization()) {$customerUser->setOrganization($website->getOrganization());}// restricted to frontend.if($checkout = $this->websiteManager->getCurrentCheckout()) {$customerUser->setOwner($checkout->getOwner());}// is oro core versionelse {$owner = $this->defaultUserProvider->getDefaultUser(OroCustomerExtension::ALIAS,SystemConfigListener::SETTING);$customerUser->setOwner($owner);}foreach ($properties as $propertyPath => $value) {if ($this->propertyAccessor->isWritable($customerUser, $propertyPath)) {$this->propertyAccessor->setValue($customerUser, $propertyPath, $value);}}$generatedPassword = $this->customerUserManager->generatePassword(10);$customerUser->setPlainPassword($generatedPassword);$this->customerUserManager->updatePassword($customerUser);$customerUser->createCustomer();$anonymousGroup = $this->customerUserRelationsProvider->getCustomerGroup();$customerUser->getCustomer()->setGroup($anonymousGroup);return $customerUser;}}I have to change owner-assignment in similiar way at all places during checkout-workflow, where customer/customerUser creation takes place.
Another target is, for example the late-registration process (last step in checkout-workflow):PHP123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115?phpnamespace Dergraf\CeeCustomerBundle\Layout\DataProvider;use Dergraf\CeeWebsiteBundle\Manager\CeeWebsiteManager;use Oro\Bundle\ConfigBundle\Config\ConfigManager;use Oro\Bundle\CustomerBundle\Entity\CustomerUser;use Oro\Bundle\CustomerBundle\Entity\CustomerUserRole;use Oro\Bundle\CustomerBundle\Layout\DataProvider\FrontendCustomerUserRegistrationFormProvider;use Oro\Bundle\OrganizationBundle\Entity\Organization;use Oro\Bundle\UserBundle\Entity\User;use Oro\Bundle\UserBundle\Entity\UserManager;use Symfony\Component\Form\FormFactoryInterface;use Symfony\Component\Routing\Generator\UrlGeneratorInterface;/*** Returns CustomerUser register form*/class CeeFrontendCustomerUserRegistrationFormProvider extends ...... FrontendCustomerUserRegistrationFormProvider{//const ACCOUNT_USER_REGISTER_ROUTE_NAME = 'oro_customer_frontend_customer_user_register';/** @var ConfigManager */private $configManager;/** @var CeeWebsiteManager */private $websiteManager;/** @var UserManager */private $userManager;/*** @param FormFactoryInterface $formFactory* @param ConfigManager $configManager* @param CeeWebsiteManager $websiteManager* @param UserManager $userManager* @param UrlGeneratorInterface $router*/public function __construct(FormFactoryInterface $formFactory,ConfigManager $configManager,CeeWebsiteManager $websiteManager,UserManager $userManager,UrlGeneratorInterface $router) {parent::__construct($formFactory,$configManager,$websiteManager,$userManager,$router);$this->configManager = $configManager;$this->websiteManager = $websiteManager;$this->userManager = $userManager;}/*** @return CustomerUser*/public function createCustomerUser(){$customerUser = new CustomerUser();$website = $this->websiteManager->getCurrentWebsite();if (!$website) {throw new \RuntimeException('Website is empty');}/** @var Organization $organization */$organization = $website->getOrganization();if (!$organization) {throw new \RuntimeException('Website organization is empty');}/** @var CustomerUserRole $defaultRole */$defaultRole = $website->getDefaultRole();if (!$defaultRole) {throw new \RuntimeException(sprintf('Role "%s" was not found', ...... CustomerUser::ROLE_DEFAULT));}// restricted to frontend.if($checkout = $this->websiteManager->getCurrentCheckout()) {$owner = $checkout->getOwner();}// oro core versionelse {$defaultOwnerId = $this->configManager->get('oro_customer.default_customer_owner');if (!$defaultOwnerId) {throw new \RuntimeException('Application Owner is empty');}/** @var User $owner */$owner = $this->userManager->getRepository()->find($defaultOwnerId);}$customerUser->setOwner($owner)->setOrganization($organization)->setWebsite($website)->addRole($defaultRole);return $customerUser;}}Hope, this makes sense from the oro-developer-team point of view, too. And, may be, it is helpful for someone, who has a similiar problem to solve.
Kind regards
Frank - AuthorReplies
The forum ‘OroCommerce’ is closed to new topics and replies.