Skip to content
Snippets Groups Projects
Commit 16e16d40 authored by Jonathan Sacksick's avatar Jonathan Sacksick
Browse files

Ensure the customer profile belongs to the current customer addressbook before rendering it.

parent c39a12f4
Branches 1.0.x custom_css
No related tags found
No related merge requests found
......@@ -171,7 +171,7 @@ class CustomerProfile extends EntityInlineFormBase {
$user_input = (array) NestedArray::getValue($form_state->getUserInput(), $inline_form['#parents']);
if (!empty($user_input['select_address'])) {
// An option was selected, pre-fill the profile form.
$address_book_profile = $this->getProfileForOption($user_input['select_address']);
$address_book_profile = $this->getProfileForOption($user_input['select_address'], $address_book_profiles);
}
elseif ($this->entity->isNew()) {
// The customer profile form is being rendered for the first time.
......@@ -539,11 +539,13 @@ class CustomerProfile extends EntityInlineFormBase {
*
* @param string $option_id
* The option ID. A profile ID, or a special value ('_original', '_new').
* @param \Drupal\profile\Entity\ProfileInterface[] $address_book_profiles
* The address book profiles.
*
* @return \Drupal\profile\Entity\ProfileInterface|null
* The profile, or NULL if none found.
*/
protected function getProfileForOption($option_id) {
protected function getProfileForOption($option_id, array $address_book_profiles) {
$profile_storage = $this->entityTypeManager->getStorage('profile');
/** @var \Drupal\profile\Entity\ProfileInterface $address_book_profile */
if ($option_id == '_new') {
......@@ -559,7 +561,7 @@ class CustomerProfile extends EntityInlineFormBase {
}
else {
assert(is_numeric($option_id));
$address_book_profile = $profile_storage->load($option_id);
$address_book_profile = $address_book_profiles[$option_id] ?? $this->selectDefaultProfile($address_book_profiles);
}
return $address_book_profile;
......
......@@ -6,13 +6,14 @@ use Drupal\commerce\InlineFormManager;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* A form for testing the customer_profile inline form.
*/
class CustomerProfileTestForm extends FormBase {
class CustomerProfileTestForm extends FormBase implements TrustedCallbackInterface {
/**
* The current user.
......@@ -101,6 +102,7 @@ class CustomerProfileTestForm extends FormBase {
'#type' => 'submit',
'#value' => $this->t('Submit'),
];
$form['#post_render'][] = [static::class, 'postRender'];
return $form;
}
......@@ -123,4 +125,33 @@ class CustomerProfileTestForm extends FormBase {
]));
}
/**
* Alters the rendered form to simulate input forgery.
*
* It's necessary to alter the rendered form here because Mink does not
* support manipulating the DOM tree.
*
* @param string $rendered_form
* The rendered form.
*
* @return string
* The modified rendered form.
*
* @see \Drupal\Tests\commerce_order\FunctionalJavascript\CustomerProfileTest::testMultipleNew()
*/
public static function postRender($rendered_form) {
$forge_profile_selection = \Drupal::state()->get('commerce_order_forge_profile_selection');
if (!$forge_profile_selection) {
return $rendered_form;
}
return str_replace('value="' . $forge_profile_selection['search'] . '"', 'value="' . $forge_profile_selection['replace'] . '"', $rendered_form);
}
/**
* {@inheritdoc}
*/
public static function trustedCallbacks() {
return ['postRender'];
}
}
......@@ -177,13 +177,37 @@ class CustomerProfileTest extends OrderWebDriverTestBase {
], 'Submit');
$this->assertSession()->pageTextContains('The street is "10 Drupal Ave" and the country code is US. Address book: Yes');
// Confirm that selecting "Enter a new address" clears the form.
$this->drupalGet('/commerce_order_test/customer_profile_test_form');
// Create another profile, belonging to another test user.
$user = $this->createUser();
$another_us_profile = Profile::create([
'type' => 'customer',
'uid' => $user->id(),
'address' => array_merge($this->usAddress, [
'postal_code' => '29617',
]),
]);
$another_us_profile->save();
// Attempt forging the profile selection, to ensure the profile that doesn't
// belong to the current profile cannot be edited/viewed.
\Drupal::state()->set('commerce_order_forge_profile_selection', [
'search' => $us_profile->id(),
'replace' => $another_us_profile->id(),
]);
$this->getSession()->reload();
$this->getSession()->getPage()->pressButton('billing_edit');
$this->assertSession()->assertWaitOnAjaxRequest();
$this->assertSession()->pageTextContains('An illegal choice has been detected.');
$this->assertSession()->pageTextContains($this->usAddress['postal_code']);
$this->assertSession()->pageTextNotContains('29617');
\Drupal::state()->delete('commerce_order_forge_profile_selection');
$this->getSession()->reload();
$this->getSession()->getPage()->pressButton('billing_edit');
$this->assertSession()->assertWaitOnAjaxRequest();
foreach ($this->usAddress as $property => $value) {
$this->assertSession()->fieldValueEquals("profile[address][0][address][$property]", $value);
}
// Confirm that selecting "Enter a new address" clears the form.
$this->getSession()->getPage()->fillField('profile[select_address]', '_new');
$this->assertSession()->assertWaitOnAjaxRequest();
$this->saveHtmlOutput();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment