forked from Sylius/Sylius
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
28 changed files
with
776 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
adr/2022_02_21_using_cart_by_guest_and_logged_in_customer.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Using cart by guest and logged in customer | ||
|
||
* Status: accepted | ||
* Date: 2022-02-22 | ||
|
||
## Context and Problem Statement | ||
|
||
Cart and its processing is one of the key aspects of Sylius. It turned out that it has a vulnerability and there is | ||
possible for an anonymous user to override the cart of logged in customer by using only its email. This is because | ||
when entering an email, during addressing step, the customer with this email is assigned to the cart and from then, | ||
there is no simple way to distinguish between the carts created by the guest and the logged in user. The question is | ||
how should we distinguish the carts to solve the vulnerability. | ||
|
||
## Decision Drivers | ||
|
||
Provided solution should: | ||
* solve the initial problem with overriding cart of logged in customer by anonymous user | ||
* not break a backward compatibility, both code and business behaviour | ||
|
||
## Considered Options | ||
|
||
### Forcing logging in during checkout | ||
|
||
* Good, because it solves the initial problem | ||
* Bad, because it changes the current expected behaviour in checkout | ||
* Bad, because it breaks a backward compatibility from the business perspective | ||
|
||
### Changing priority of cart contexts | ||
|
||
* Good, because it solves the initial problem | ||
* Bad, because it does not solve the case when a logged in customer does not have a cart | ||
* Bad, because it changes the current expected behaviour with keeping cart after logging in | ||
* Bad, because it breaks a backward compatibility from the business perspective | ||
|
||
### Introducing flag on order entity to mark order created by guest | ||
|
||
Adding a flag to order entity allows us to distinguish carts created by guest or by logged in customer. To mark cart | ||
as soon as possible, to solve all cases of the initial problem, the flag needs to be set in Sylius\Component\Core\Cart\Context\ShopBasedCartContext, | ||
where the customer of logged in user is also set on cart. This context is definitely not a proper service to do such operations, | ||
however it is consistent with current approach in Sylius. Setting this value only after logging in would not be enough, | ||
as it doesn't resolve the situation when the already logged in user creates a cart. It is similar with setting flag after | ||
the addressing step, it doesn't resolve the problem as the cart of logged in user is marked too late and before addressing | ||
the cart couldn't be distinguished to whom it belongs. | ||
|
||
* Good, because it solves the initial problem | ||
* Good, because it does not break a backward compatibility | ||
* Good, because it can be used to additional features in the future | ||
* Bad, because it requires to set the flag in Sylius\Component\Core\Cart\Context\ShopBasedCartContext | ||
|
||
## Decision Outcome | ||
|
||
Chosen option: **"Introducing flag on order entity to mark order created by guest"** | ||
|
||
For now, it is the most straightforward solution, that resolves the initial problem, does not introduce any BC break | ||
and it is the solution that could be used to additional features in the future. | ||
|
||
## References | ||
|
||
* [Approach with changing priorities](https://github.com/Sylius/Sylius/pull/13603) | ||
* [Chosen approach with introducing flag](https://github.com/Sylius/Sylius/pull/13676) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
features/checkout/preventing_from_claiming_cart_of_wrong_user.feature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
@checkout | ||
Feature: Preventing from claiming cart of a wrong user | ||
In order to make the checkout cart available only for user who owns the cart | ||
As a Customer | ||
I want to be able to checkout with my previous cart when someone used my email in checkout | ||
|
||
Background: | ||
Given the store operates on a single channel in "United States" | ||
And the store has a product "PHP T-Shirt" priced at "$20.00" | ||
And the store has a product "Kotlin T-Shirt" priced at "$30.00" | ||
And the store has a product "Symfony T-Shirt" priced at "$100.00" | ||
And the store has a product "Sylius T-Shirt" priced at "$150.00" | ||
And the store ships everywhere for free | ||
And the store allows paying offline | ||
And there is a user "robb@stark.com" identified by "KingInTheNorth" | ||
|
||
@ui @no-api | ||
Scenario: Preventing anonymous user from claiming cart of logged in user | ||
Given I am logged in as "robb@stark.com" | ||
And I have product "PHP T-Shirt" in the cart | ||
When an anonymous user in another browser adds products "PHP T-Shirt" and "Kotlin T-Shirt" to the cart | ||
And they complete addressing step with email "robb@stark.com" and "United States" based billing address | ||
And they add product "Symfony T-Shirt" to the cart | ||
Then their cart total should be "$150.00" | ||
|
||
@ui @no-api | ||
Scenario: Preventing anonymous user from claiming cart of logged in user | ||
Given I am logged in as "robb@stark.com" | ||
And I have product "PHP T-Shirt" in the cart | ||
When an anonymous user in another browser adds products "PHP T-Shirt" and "Kotlin T-Shirt" to the cart | ||
And they complete addressing step with email "robb@stark.com" and "United States" based billing address | ||
And they add product "Symfony T-Shirt" to the cart | ||
And I view my cart in the previous session | ||
Then there should be one item in my cart | ||
And my cart's total should be "$20.00" | ||
|
||
@ui @no-api | ||
Scenario: Preventing anonymous user from claiming cart of logged in user | ||
Given I have product "PHP T-Shirt" in the cart | ||
When I sign in with email "robb@stark.com" and password "KingInTheNorth" | ||
And I log out | ||
And an anonymous user in another browser adds products "PHP T-Shirt" and "Kotlin T-Shirt" to the cart | ||
And they complete addressing step with email "robb@stark.com" and "United States" based billing address | ||
And they add product "Symfony T-Shirt" to the cart | ||
And I sign in again with email "robb@stark.com" and password "KingInTheNorth" in the previous session | ||
And I see the summary of my previous cart | ||
Then there should be one item in my cart | ||
And my cart's total should be "$20.00" | ||
|
||
@ui @no-api | ||
Scenario: Preventing anonymous user from claiming cart of logged in user | ||
Given on this channel account verification is not required | ||
And I have product "PHP T-Shirt" in the cart | ||
When I register with email "eddard@stark.com" and password "handOfTheKing" | ||
And I log out | ||
And an anonymous user in another browser adds products "PHP T-Shirt" and "Kotlin T-Shirt" to the cart | ||
And they complete addressing step with email "robb@stark.com" and "United States" based billing address | ||
And they add product "Symfony T-Shirt" to the cart | ||
And I sign in again with email "eddard@stark.com" and password "handOfTheKing" in the previous session | ||
And I see the summary of my previous cart | ||
Then there should be one item in my cart | ||
And my cart's total should be "$20.00" | ||
|
||
@ui @no-api | ||
Scenario: Preventing logged in user from claiming cart of anonymous user | ||
Given an anonymous user added product "Kotlin T-Shirt" to the cart | ||
And they have completed addressing step with email "robb@stark.com" and "United States" based billing address | ||
When I log in as "robb@stark.com" | ||
And I add product "Sylius T-Shirt" to the cart | ||
And I view my cart in the previous session | ||
Then there should be one item in my cart | ||
And my cart's total should be "$150.00" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Sylius package. | ||
* | ||
* (c) Paweł Jędrzejewski | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Sylius\Behat\Context\Ui\Shop; | ||
|
||
use Behat\Behat\Context\Context; | ||
use Sylius\Behat\Element\Shop\Account\RegisterElementInterface; | ||
use Sylius\Behat\Page\Shop\Account\LoginPageInterface; | ||
use Sylius\Behat\Page\Shop\Account\RegisterPageInterface; | ||
|
||
final class AuthorizationContext implements Context | ||
{ | ||
private LoginPageInterface $loginPage; | ||
|
||
private RegisterPageInterface $registerPage; | ||
|
||
private RegisterElementInterface $registerElement; | ||
|
||
public function __construct( | ||
LoginPageInterface $loginPage, | ||
RegisterPageInterface $registerPage, | ||
RegisterElementInterface $registerElement | ||
) { | ||
$this->loginPage = $loginPage; | ||
$this->registerPage = $registerPage; | ||
$this->registerElement = $registerElement; | ||
} | ||
|
||
/** | ||
* @When I sign in with email :email and password :password | ||
* @When I sign in again with email :email and password :password in the previous session | ||
*/ | ||
public function iSignInWithEmailAndPassword(string $email, string $password): void | ||
{ | ||
$this->loginPage->open(); | ||
$this->loginPage->specifyUsername($email); | ||
$this->loginPage->specifyPassword($password); | ||
$this->loginPage->logIn(); | ||
} | ||
|
||
/** | ||
* @When I register with email :email and password :password | ||
*/ | ||
public function iRegisterWithEmailAndPassword(string $email, string $password): void | ||
{ | ||
$this->registerPage->open(); | ||
$this->registerElement->specifyEmail($email); | ||
$this->registerElement->specifyPassword($password); | ||
$this->registerElement->verifyPassword($password); | ||
$this->registerElement->specifyFirstName('Carrot'); | ||
$this->registerElement->specifyLastName('Ironfoundersson'); | ||
$this->registerElement->register(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.