Skip to content

Commit

Permalink
[shopsys] refresh tokens for FE API (#1736)
Browse files Browse the repository at this point in the history
[shopsys] refresh tokens for FE API (#1736)
  • Loading branch information
pesektomas authored Mar 31, 2020
1 parent dec2abd commit 5cb6656
Show file tree
Hide file tree
Showing 16 changed files with 430 additions and 10 deletions.
6 changes: 4 additions & 2 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1313,7 +1313,9 @@
<if>
<equals arg1="${yaml-standards.executable.exists}" arg2="true"/>
<then>
<exec executable="${path.yaml-standards.executable}" logoutput="true" passthru="true" checkreturn="true"/>
<exec executable="${path.yaml-standards.executable}" logoutput="true" passthru="true" checkreturn="true">
<arg value="${yaml-standards.args}"/>
</exec>
</then>
<else>
<echo level="warning" message="The executable '${path.yaml-standards.executable}' is not available, your YAML files cannot be checked."/>
Expand All @@ -1323,7 +1325,7 @@
</target>

<target name="yaml-standards-fix" description="Checks YAML standards and fixes the violations automatically if possible" hidden="true">
<property name="yaml-standards.args" value="${yaml-standards.args} --fix" override="true"/>
<property name="yaml-standards.args" value="--fix" override="true"/>
<phingcall target="yaml-standards"/>
</target>
</project>
39 changes: 39 additions & 0 deletions src/Migrations/Version20200327080840.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Shopsys\FrameworkBundle\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Shopsys\MigrationBundle\Component\Doctrine\Migrations\AbstractMigration;

class Version20200327080840 extends AbstractMigration
{
/**
* @param \Doctrine\DBAL\Schema\Schema $schema
*/
public function up(Schema $schema): void
{
$this->sql('
CREATE TABLE customer_user_refresh_token_chain (
uuid UUID NOT NULL,
customer_user_id INT NOT NULL,
token_chain VARCHAR(255) NOT NULL,
expired_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
PRIMARY KEY(uuid)
)');
$this->sql('CREATE INDEX IDX_DA9A5BFDBBB3772B ON customer_user_refresh_token_chain (customer_user_id)');
$this->sql('
ALTER TABLE
customer_user_refresh_token_chain
ADD
CONSTRAINT FK_DA9A5BFDBBB3772B FOREIGN KEY (customer_user_id) REFERENCES customer_users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
}

/**
* @param \Doctrine\DBAL\Schema\Schema $schema
*/
public function down(Schema $schema): void
{
}
}
25 changes: 20 additions & 5 deletions src/Model/Customer/User/CurrentCustomerUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Shopsys\FrameworkBundle\Model\Customer\User;

use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupSettingFacade;
use Shopsys\FrontendApiBundle\Model\User\FrontendApiUser;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class CurrentCustomerUser
Expand All @@ -17,16 +18,24 @@ class CurrentCustomerUser
*/
protected $pricingGroupSettingFacade;

/**
* @var \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserFacade
*/
protected $customerUserFacade;

/**
* @param \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface $tokenStorage
* @param \Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroupSettingFacade $pricingGroupSettingFacade
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserFacade $customerUserFacade
*/
public function __construct(
TokenStorageInterface $tokenStorage,
PricingGroupSettingFacade $pricingGroupSettingFacade
PricingGroupSettingFacade $pricingGroupSettingFacade,
CustomerUserFacade $customerUserFacade
) {
$this->tokenStorage = $tokenStorage;
$this->pricingGroupSettingFacade = $pricingGroupSettingFacade;
$this->customerUserFacade = $customerUserFacade;
}

/**
Expand All @@ -48,15 +57,21 @@ public function getPricingGroup()
public function findCurrentCustomerUser()
{
$token = $this->tokenStorage->getToken();

if ($token === null) {
return null;
}

$customerUser = $token->getUser();
if (!$customerUser instanceof CustomerUser) {
return null;
$user = $token->getUser();

if ($user instanceof FrontendApiUser) {
return $this->customerUserFacade->getByUuid($user->getUuid());
}

if ($user instanceof CustomerUser) {
return $user;
}

return $customerUser;
return null;
}
}
17 changes: 17 additions & 0 deletions src/Model/Customer/User/CustomerUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Shopsys\FrameworkBundle\Model\Customer\User;

use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;
use Serializable;
Expand Down Expand Up @@ -124,6 +125,13 @@ class CustomerUser implements UserInterface, TimelimitLoginInterface, Serializab
*/
protected $uuid;

/**
* @var \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserRefreshTokenChain[]|\Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="CustomerUserRefreshTokenChain", mappedBy="customerUser", cascade={"persist"})
*/
protected $refreshTokenChain;

/**
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserData $customerUserData
*/
Expand All @@ -143,6 +151,7 @@ public function __construct(CustomerUserData $customerUserData)
$this->customer = $customerUserData->customer;
$this->defaultDeliveryAddress = $customerUserData->defaultDeliveryAddress;
$this->uuid = $customerUserData->uuid ?: Uuid::uuid4()->toString();
$this->refreshTokenChain = new ArrayCollection();
}

/**
Expand Down Expand Up @@ -412,4 +421,12 @@ public function getUuid(): string
{
return $this->uuid;
}

/**
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserRefreshTokenChain $customerUserRefreshTokenChain
*/
public function addRefreshTokenChain(CustomerUserRefreshTokenChain $customerUserRefreshTokenChain): void
{
$this->refreshTokenChain->add($customerUserRefreshTokenChain);
}
}
31 changes: 30 additions & 1 deletion src/Model/Customer/User/CustomerUserFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ class CustomerUserFacade
*/
protected $billingAddressFacade;

/**
* @var \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserRefreshTokenChainFacade
*/
protected $customerUserRefreshTokenChainFacade;

/**
* @param \Doctrine\ORM\EntityManagerInterface $em
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserRepository $customerUserRepository
Expand All @@ -92,6 +97,7 @@ class CustomerUserFacade
* @param \Shopsys\FrameworkBundle\Model\Customer\DeliveryAddressFacade $deliveryAddressFacade
* @param \Shopsys\FrameworkBundle\Model\Customer\CustomerDataFactoryInterface $customerDataFactory
* @param \Shopsys\FrameworkBundle\Model\Customer\BillingAddressFacade $billingAddressFacade
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserRefreshTokenChainFacade $customerUserRefreshTokenChainFacade
*/
public function __construct(
EntityManagerInterface $em,
Expand All @@ -105,7 +111,8 @@ public function __construct(
CustomerFacade $customerFacade,
DeliveryAddressFacade $deliveryAddressFacade,
CustomerDataFactoryInterface $customerDataFactory,
BillingAddressFacade $billingAddressFacade
BillingAddressFacade $billingAddressFacade,
CustomerUserRefreshTokenChainFacade $customerUserRefreshTokenChainFacade
) {
$this->em = $em;
$this->customerUserRepository = $customerUserRepository;
Expand All @@ -119,6 +126,7 @@ public function __construct(
$this->deliveryAddressFacade = $deliveryAddressFacade;
$this->customerDataFactory = $customerDataFactory;
$this->billingAddressFacade = $billingAddressFacade;
$this->customerUserRefreshTokenChainFacade = $customerUserRefreshTokenChainFacade;
}

/**
Expand Down Expand Up @@ -329,4 +337,25 @@ protected function createCustomerWithBillingAddress(int $domainId, BillingAddres

return $customer;
}

/**
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser $customerUser
* @param string $refreshTokenChain
* @param \DateTime $tokenExpiration
*/
public function addRefreshTokenChain(CustomerUser $customerUser, string $refreshTokenChain, \DateTime $tokenExpiration): void
{
$refreshTokenChain = $this->customerUserRefreshTokenChainFacade->createCustomerUserRefreshTokenChain($customerUser, $refreshTokenChain, $tokenExpiration);
$customerUser->addRefreshTokenChain($refreshTokenChain);
$this->em->flush();
}

/**
* @param string $uuid
* @return \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser
*/
public function getByUuid(string $uuid): CustomerUser
{
return $this->customerUserRepository->getOneByUuid($uuid);
}
}
64 changes: 64 additions & 0 deletions src/Model/Customer/User/CustomerUserRefreshTokenChain.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

namespace Shopsys\FrameworkBundle\Model\Customer\User;

use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;

/**
* @ORM\Table(name="customer_user_refresh_token_chain")
* @ORM\Entity
*/
class CustomerUserRefreshTokenChain
{
/**
* @var string
*
* @ORM\Id
* @ORM\Column(type="guid", unique=true)
*/
protected $uuid;

/**
* @var \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser
*
* @ORM\ManyToOne(targetEntity="Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser", inversedBy="refreshTokenChain")
* @ORM\JoinColumn(nullable=false)
*/
protected $customerUser;

/**
* @var string
*
* @ORM\Column(type="string", nullable=false)
*/
protected $tokenChain;

/**
* @var \DateTime
*
* @ORM\Column(type="datetime")
*/
protected $expiredAt;

/**
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserRefreshTokenChainData $customerUserRefreshTokenChainData
*/
public function __construct(CustomerUserRefreshTokenChainData $customerUserRefreshTokenChainData)
{
$this->uuid = $customerUserRefreshTokenChainData->uuid ?: Uuid::uuid4()->toString();
$this->customerUser = $customerUserRefreshTokenChainData->customerUser;
$this->tokenChain = $customerUserRefreshTokenChainData->tokenChain;
$this->expiredAt = $customerUserRefreshTokenChainData->expiredAt;
}

/**
* @return string
*/
public function getTokenChain(): string
{
return $this->tokenChain;
}
}
28 changes: 28 additions & 0 deletions src/Model/Customer/User/CustomerUserRefreshTokenChainData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Shopsys\FrameworkBundle\Model\Customer\User;

class CustomerUserRefreshTokenChainData
{
/**
* @var string|null
*/
public $uuid;

/**
* @var \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser|null
*/
public $customerUser;

/**
* @var string|null
*/
public $tokenChain;

/**
* @var \DateTime|null
*/
public $expiredAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Shopsys\FrameworkBundle\Model\Customer\User;

class CustomerUserRefreshTokenChainDataFactory implements CustomerUserRefreshTokenChainDataFactoryInterface
{
/**
* @return \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserRefreshTokenChainData
*/
public function create(): CustomerUserRefreshTokenChainData
{
return new CustomerUserRefreshTokenChainData();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Shopsys\FrameworkBundle\Model\Customer\User;

interface CustomerUserRefreshTokenChainDataFactoryInterface
{
/**
* @return \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserRefreshTokenChainData
*/
public function create(): CustomerUserRefreshTokenChainData;
}
Loading

0 comments on commit 5cb6656

Please sign in to comment.