diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 4906962e..faa0ae73 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -50,14 +50,17 @@ security: security: false cust_api_v2: - pattern: ^\/apiv2\/ - #provider: api_provider - #access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler + pattern: ^\/apiv2\/(?!register|register\/|number_confirm|number_confirm\/|code_validate|code_validate\/) + provider: api_provider + access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler stateless: true - #guard: - # authenticators: - # - Catalyst\ApiBundle\Security\Authenticator - security: false # NOTE: Temporary + guard: + authenticators: + - Catalyst\ApiBundle\Security\Authenticator + + cust_api_v2_guest: + pattern: ^\/apiv2\/(register|register\/|number_confirm|number_confirm\/|code_validate|code_validate\/) + security: false warranty_api: pattern: ^\/capi\/ diff --git a/src/Command/CreateRiderAPIUserCommand.php b/src/Command/CreateRiderAPIUserCommand.php index bec98a72..1f60b668 100644 --- a/src/Command/CreateRiderAPIUserCommand.php +++ b/src/Command/CreateRiderAPIUserCommand.php @@ -10,7 +10,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\EntityManagerInterface; -use Catalyst\ApiBundle\Entity\User as APIUser; +use App\Entity\ApiUser as APIUser; use Catalyst\ApiBundle\Entity\Role as APIRole; use App\Entity\Rider; diff --git a/src/Controller/APIUserController.php b/src/Controller/APIUserController.php index 2c11b56f..d707e32c 100644 --- a/src/Controller/APIUserController.php +++ b/src/Controller/APIUserController.php @@ -2,7 +2,7 @@ namespace App\Controller; -use Catalyst\ApiBundle\Entity\User as APIUser; +use App\Entity\ApiUser as APIUser; use Catalyst\ApiBundle\Entity\Role as APIRole; use Doctrine\ORM\Query; diff --git a/src/Controller/CAPI/RiderAppController.php b/src/Controller/CAPI/RiderAppController.php index 1f749e96..d23925af 100644 --- a/src/Controller/CAPI/RiderAppController.php +++ b/src/Controller/CAPI/RiderAppController.php @@ -22,7 +22,7 @@ use App\Entity\BatteryModel; use App\Entity\BatterySize; use App\Entity\RiderAPISession; use App\Entity\User; -use Catalyst\ApiBundle\Entity\User as APIUser; +use App\Entity\ApiUser as APIUser; use App\Service\RedisClientProvider; use App\Service\RiderCache; diff --git a/src/Controller/CustomerAppAPI/ApiController.php b/src/Controller/CustomerAppAPI/ApiController.php index 8f699998..cc742d19 100644 --- a/src/Controller/CustomerAppAPI/ApiController.php +++ b/src/Controller/CustomerAppAPI/ApiController.php @@ -10,9 +10,9 @@ use Catalyst\ApiBundle\Controller\ApiController as BaseApiController; use Catalyst\ApiBundle\Component\Response as ApiResponse; use App\Ramcar\JOStatus; -use App\Entity\MobileSession; use App\Entity\Warranty; use App\Entity\JobOrder; +use App\Entity\CustomerSession; class ApiController extends BaseApiController { @@ -21,7 +21,7 @@ class ApiController extends BaseApiController public function __construct(EntityManagerInterface $em, KernelInterface $kernel) { - $this->session = new MobileSession; // NOTE: original was null + $this->session = new CustomerSession; // NOTE: original was null $this->em = $em; // load env file @@ -40,10 +40,10 @@ class ApiController extends BaseApiController return $this->checkRequiredParameters($req, $params); } - protected function validateSession($api_key) + protected function validateSession($session_key) { // check if the session exists - $session = $this->em->getRepository(MobileSession::class)->find($api_key); + $session = $this->em->getRepository(CustomerSession::class)->find($session_key); if ($session === null) { return false; } @@ -55,10 +55,10 @@ class ApiController extends BaseApiController protected function validateRequest(Request $req, $params = []) { $error = $this->hasMissingParams($req, $params); - $api_key = $req->query->get('api_key'); + $session_key = $req->query->get('session_key'); if (!$error) { - if (empty($api_key) || !$this->validateSession($api_key)) { + if (empty($session_key) || !$this->validateSession($session_key)) { $error = 'Invalid session key.'; } } diff --git a/src/Controller/CustomerAppAPI/AuthController.php b/src/Controller/CustomerAppAPI/AuthController.php index 8ddda9a9..bf541906 100644 --- a/src/Controller/CustomerAppAPI/AuthController.php +++ b/src/Controller/CustomerAppAPI/AuthController.php @@ -7,7 +7,9 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Contracts\Translation\TranslatorInterface; use Catalyst\ApiBundle\Component\Response as ApiResponse; -use App\Entity\MobileSession; +use App\Entity\Customer; +use App\Entity\CustomerUser; +use App\Entity\CustomerSession; use App\Service\RisingTideGateway; use DateTime; @@ -32,7 +34,7 @@ class AuthController extends ApiController while (true) { try { // instantiate session - $sess = new MobileSession(); + $sess = new CustomerSession(); $sess->setPhoneModel($req->request->get('phone_model')) ->setOSType($req->request->get('os_type')) ->setOSVersion($req->request->get('os_version')) @@ -132,6 +134,11 @@ class AuthController extends ApiController return new ApiResponse(false, $validity['error']); } + // already confirmed + if ($this->session->isConfirmed()) { + return new ApiResponse(false, 'User is already confirmed.'); + } + // code is wrong $code = $req->request->get('code'); if ($this->session->getConfirmCode() != $code) { @@ -143,12 +150,17 @@ class AuthController extends ApiController $this->session->setDateConfirmed($date) ->setConfirmed(); + // figure out if we have customer and customer user already + $customer_user = false; // TODO: check if we have the number registered before and merge $dupe_sess = $this->findNumberSession($this->session->getPhoneNumber()); if ($dupe_sess != null) { $dupe_cust = $dupe_sess->getCustomer(); $this->session->setCustomer($dupe_cust); + + // set customer user if it exists + $customer_user = $dupe_sess->getCustomerUser() ?? $dupe_cust->getCustomerUser(); } // TODO: check if mobile matches mobile of customer @@ -159,10 +171,31 @@ class AuthController extends ApiController $this->session->setCustomer($customer); } + if (!$customer_user) { + $customer_user = $this->findCustomerUserByNumber($this->session->getPhoneNumber()); + if ($customer_user != null) { + // dupe_cust_user is the same as the customer we found? + $this->session->setCustomerUser($customer_user); + } else { + $customer_user = new CustomerUser(); + $customer_user->setCustomer($this->session->getCustomer()) + ->setPhoneNumber($this->session->getPhoneNumber()); + + // save + $this->em->persist($customer_user); + } + } + $this->em->flush(); + // set session customer user + $this->session->setCustomerUser($customer_user); + // response - return new ApiResponse(); + return new ApiResponse(true, '', [ + 'api_key' => $customer_user->getApiKey(), + 'secret_key'=> $customer_user->getSecretKey(), + ]); } public function resendCode(Request $req, RisingTideGateway $rt, TranslatorInterface $translator) @@ -208,9 +241,10 @@ class AuthController extends ApiController // TODO: find session customer by phone number protected function findNumberSession($number) { - $query = $this->em->getRepository(MobileSession::class)->createQueryBuilder('s') + $query = $this->em->getRepository(CustomerSession::class)->createQueryBuilder('s') ->where('s.phone_number = :number') ->andWhere('s.customer is not null') + ->andWhere('s.customer_user is not null') ->andWhere('s.confirm_flag = 1') ->setParameter('number', $number) ->setMaxResults(1) @@ -242,4 +276,9 @@ class AuthController extends ApiController return $cust; } + + protected function findCustomerUserByNumber($number) + { + return $this->em->getRepository(CustomerUser::class)->findOneBy(['phone_number' => $number]); + } } diff --git a/src/Controller/RiderController.php b/src/Controller/RiderController.php index 069fb1a8..25e63a4c 100644 --- a/src/Controller/RiderController.php +++ b/src/Controller/RiderController.php @@ -25,7 +25,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Catalyst\MenuBundle\Annotation\Menu; -use Catalyst\ApiBundle\Entity\User as APIUser; +use App\Entity\ApiUser as APIUser; use Catalyst\ApiBundle\Entity\Role as APIRole; use DateTime; diff --git a/src/Entity/ApiUser.php b/src/Entity/ApiUser.php index 1454985f..bb79df89 100644 --- a/src/Entity/ApiUser.php +++ b/src/Entity/ApiUser.php @@ -2,8 +2,13 @@ namespace App\Entity; +use Doctrine\ORM\Mapping as ORM; use Catalyst\ApiBundle\Entity\User as BaseUser; +/** + * @ORM\Entity + * @ORM\Table(name="api_user") + */ class ApiUser extends BaseUser { /** diff --git a/src/Entity/Customer.php b/src/Entity/Customer.php index de2cd92e..e5e2f2c9 100644 --- a/src/Entity/Customer.php +++ b/src/Entity/Customer.php @@ -96,6 +96,13 @@ class Customer */ protected $sessions; + // link to customer user + /** + * @ORM\OneToOne(targetEntity="CustomerUser", inversedBy="customer") + * @ORM\JoinColumn(name="customer_user_id", referencedColumnName="id", nullable=true) + */ + protected $customer_user; + // vehicles linked to customer /** * @ORM\OneToMany(targetEntity="CustomerVehicle", mappedBy="customer", cascade={"persist"}) @@ -682,4 +689,15 @@ class Customer { return $this->car_club_customer_hub; } + + public function setCustomerUser(CustomerUser $cust_user = null) + { + $this->customer_user = $cust_user; + return $this; + } + + public function getCustomeUser() + { + return $this->customer_user; + } } diff --git a/src/Entity/CustomerSession.php b/src/Entity/CustomerSession.php new file mode 100644 index 00000000..125f4677 --- /dev/null +++ b/src/Entity/CustomerSession.php @@ -0,0 +1,273 @@ +id = $this->generateKeyID(); + $this->date_generated = new DateTime(); + $this->customer_user = null; + $this->confirm_flag = false; + $this->date_confirmed = null; + $this->date_code_sent = null; + $this->reviews = new ArrayCollection(); + } + + public function generateKeyID() + { + // use uniqid for now, since primary key dupes will trigger exceptions + return uniqid(); + } + + public function getID() + { + return $this->id; + } + + public function setPhoneNumber($num) + { + $this->phone_number = $num; + return $this; + } + + public function getPhoneNumber() + { + return $this->phone_number; + } + + public function setPhoneModel($model) + { + $this->phone_model = $model; + return $this; + } + + public function getPhoneModel() + { + return $this->phone_model; + } + + public function setOSType($type) + { + $this->os_type = $type; + return $this; + } + + public function getOSType() + { + return $this->os_type; + } + + public function setOSVersion($version) + { + $this->os_version = $version; + return $this; + } + + public function getOSVersion() + { + return $this->os_version; + } + + public function setPhoneID($id) + { + $this->phone_id = $id; + return $this; + } + + public function getPhoneID() + { + return $this->phone_id; + } + + public function setDevicePushID($id) + { + $this->device_push_id = $id; + return $this; + } + + public function getDevicePushID() + { + return $this->device_push_id; + } + + public function setCustomer(Customer $cust = null) + { + $this->customer = $cust; + return $this; + } + + public function getCustomer() + { + return $this->customer; + } + + public function setCustomerUser(CustomerUser $cust_user = null) + { + $this->customer_user = $cust_user; + return $this; + } + + public function getCustomerUser() + { + return $this->customer_user; + } + + public function getDateGenerated() + { + return $this->date_generated; + } + + public function setConfirmCode($code) + { + $this->confirm_code = $code; + return $this; + } + + public function getConfirmCode() + { + return $this->confirm_code; + } + + public function setConfirmed($flag = true) + { + $this->confirm_flag = $flag; + return $this; + } + + public function isConfirmed() + { + return $this->confirm_flag; + } + + public function setDateConfirmed(DateTime $date) + { + $this->date_confirmed = $date; + return $this; + } + + public function getDateConfirmed() + { + return $this->date_confirmed; + } + + public function setDateCodeSent(DateTime $date) + { + $this->date_code_sent = $date; + return $this; + } + + public function getDateCodeSent() + { + return $this->date_code_sent; + } + + public function getReviews() + { + return $this->reviews; + } +} diff --git a/src/Entity/CustomerUser.php b/src/Entity/CustomerUser.php index ec557ed5..725d2d03 100644 --- a/src/Entity/CustomerUser.php +++ b/src/Entity/CustomerUser.php @@ -12,29 +12,95 @@ use Catalyst\ApiBundle\Entity\User as BaseUser; */ class CustomerUser extends BaseUser { + // link to customer + /** + * @ORM\OneToOne(targetEntity="Customer", inversedBy="customer_user") + * @ORM\JoinColumn(name="customer_id", referencedColumnName="id", nullable=true) + */ + protected $customer; + + // phone number + /** + * @ORM\Column(type="string", length=12) + */ + protected $phone_number; + + /** + * @ORM\Column(type="json") + */ + protected $metadata; + + // roles + /** + * @ORM\ManyToMany(targetEntity="Catalyst\ApiBundle\Entity\Role", indexBy="id") + * @ORM\JoinTable(name="customer_user_role") + */ + protected $roles; + + // mobile sessions linked to this customer + /** + * @ORM\OneToMany(targetEntity="CustomerSession", mappedBy="customer") + */ + protected $sessions; + public function __construct() { parent::__construct(); + + $this->metadata = []; + $this->sessions = new ArrayCollection(); } - /** - * @ORM\Column(type="string", length=180) - */ - protected $name; - - /** - * @ORM\Column(type="boolean") - */ - protected $enabled; - - public function setName($name) + public function setMetadata($meta) { - $this->name = $name; + $this->metadata = $meta; return $this; } - public function getName() + public function getMetadata() { - return $this->name; + if ($this->metadata == null) + return []; + + return $this->metadata; } + + public function setPhoneNumber($num) + { + $this->phone_number = $num; + return $this; + } + + public function getPhoneNumber() + { + return $this->phone_number; + } + + public function addMobileSession(MobileSession $session) + { + $this->sessions->add($session); + return $this; + } + + public function clearMobileSessions() + { + $this->sessions->clear(); + return $this; + } + + public function getMobileSessions() + { + return $this->sessions; + } + + public function setCustomer(Customer $cust = null) + { + $this->customer = $cust; + return $this; + } + + public function getCustomer() + { + return $this->customer; + } } diff --git a/src/Entity/Rider.php b/src/Entity/Rider.php index 201ede0d..8fcec623 100644 --- a/src/Entity/Rider.php +++ b/src/Entity/Rider.php @@ -9,7 +9,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; use App\Ramcar\JOStatus; -use Catalyst\ApiBundle\Entity\User as APIUser; +use App\Entity\ApiUser as APIUser; /** * @ORM\Entity @@ -131,7 +131,7 @@ class Rider protected $current_job_order; /** - * @ORM\OneToOne(targetEntity="Catalyst\ApiBundle\Entity\User", inversedBy="rider") + * @ORM\OneToOne(targetEntity="App\Entity\ApiUser", inversedBy="rider") * @ORM\JoinColumn(name="api_user_id", referencedColumnName="id", nullable=true) */ protected $api_user;