From 99579f2ee06259e034c77c56023893bad69e4c40 Mon Sep 17 00:00:00 2001 From: Paulo Rodrigues Pinto Date: Fri, 27 Jan 2017 17:12:25 +0000 Subject: [PATCH 1/2] Refactor functional tests --- Form/ChoosePaymentMethodType.php | 5 +- Tests/Functional/BasePaymentWorkflowTest.php | 51 ------------------ .../BasePaymentWorkflowTest.php | 52 +++++++++++++++++++ .../PaymentWorkflowMcryptTest.php | 43 +++++++++++++++ .../PaymentWorkflowNoEncryptionTest.php | 37 +++++++++++++ .../PaymentWorkflow/PaymentWorkflowTest.php | 29 +++++++++++ .../Functional/PaymentWorkflowMcryptTest.php | 27 ---------- .../PaymentWorkflowNoEncryptionTest.php | 23 -------- Tests/Functional/PaymentWorkflowTest.php | 18 ------- .../TestBundle/Controller/OrderController.php | 37 +++++++------ ...ymentDetails.html.twig => order.html.twig} | 0 11 files changed, 184 insertions(+), 138 deletions(-) delete mode 100755 Tests/Functional/BasePaymentWorkflowTest.php create mode 100755 Tests/Functional/PaymentWorkflow/BasePaymentWorkflowTest.php create mode 100755 Tests/Functional/PaymentWorkflow/PaymentWorkflowMcryptTest.php create mode 100755 Tests/Functional/PaymentWorkflow/PaymentWorkflowNoEncryptionTest.php create mode 100755 Tests/Functional/PaymentWorkflow/PaymentWorkflowTest.php delete mode 100755 Tests/Functional/PaymentWorkflowMcryptTest.php delete mode 100755 Tests/Functional/PaymentWorkflowNoEncryptionTest.php delete mode 100755 Tests/Functional/PaymentWorkflowTest.php rename Tests/Functional/TestBundle/Resources/views/Order/{paymentDetails.html.twig => order.html.twig} (100%) diff --git a/Form/ChoosePaymentMethodType.php b/Form/ChoosePaymentMethodType.php index f0439064..4d540588 100755 --- a/Form/ChoosePaymentMethodType.php +++ b/Form/ChoosePaymentMethodType.php @@ -60,10 +60,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) // To maintain BC, we instantiate a new ChoosePaymentMethodTransformer in // case it hasn't been supplied. - $transformer = $this->transformer - ? $this->transformer - : new ChoosePaymentMethodTransformer() - ; + $transformer = $this->transformer ?: new ChoosePaymentMethodTransformer(); $transformer->setOptions($options); $builder->addModelTransformer($transformer); diff --git a/Tests/Functional/BasePaymentWorkflowTest.php b/Tests/Functional/BasePaymentWorkflowTest.php deleted file mode 100755 index 6fa5c5d2..00000000 --- a/Tests/Functional/BasePaymentWorkflowTest.php +++ /dev/null @@ -1,51 +0,0 @@ -getContainer()->get('em'); - - $stmt = $em->getConnection()->prepare( - 'SELECT extended_data FROM payment_instructions WHERE id = '.$paymentInstruction->getId() - ); - - $stmt->execute(); - $result = $stmt->fetchAll(); - - return unserialize($result[0]['extended_data']); - } - - protected function doTestPaymentDetails() - { - $client = $this->createClient(); - $this->importDatabaseSchema(); - - $em = self::$kernel->getContainer()->get('em'); - $router = self::$kernel->getContainer()->get('router'); - - $order = new Order(123.45); - $em->persist($order); - $em->flush(); - - $crawler = $client->request('GET', $router->generate('payment_details', array('id' => $order->getId()))); - $form = $crawler->selectButton('submit_btn')->form(); - $form['jms_choose_payment_method[method]']->select('paypal_express_checkout'); - $client->submit($form); - - $response = $client->getResponse(); - $this->assertSame(201, $response->getStatusCode(), substr($response, 0, 2000)); - - $em->clear(); - $order = $em->getRepository('TestBundle:Order')->find($order->getId()); - $this->assertTrue(Number::compare(123.45, $order->getPaymentInstruction()->getAmount(), '==')); - $this->assertEquals('bar', $order->getPaymentInstruction()->getExtendedData()->get('foo')); - - return $order; - } -} diff --git a/Tests/Functional/PaymentWorkflow/BasePaymentWorkflowTest.php b/Tests/Functional/PaymentWorkflow/BasePaymentWorkflowTest.php new file mode 100755 index 00000000..cba8f66b --- /dev/null +++ b/Tests/Functional/PaymentWorkflow/BasePaymentWorkflowTest.php @@ -0,0 +1,52 @@ +getContainer()->get('em'); + + $stmt = $em->getConnection()->prepare(' + SELECT extended_data + FROM payment_instructions + WHERE id = '.$order->getPaymentInstruction()->getId() + ); + + $stmt->execute(); + $result = $stmt->fetchAll(); + + return unserialize($result[0]['extended_data']); + } + + protected function doRequest($order, $route) + { + $client = $this->createClient(); + $this->importDatabaseSchema(); + + $em = self::$kernel->getContainer()->get('em'); + $router = self::$kernel->getContainer()->get('router'); + + $em->persist($order); + $em->flush(); + + $crawler = $client->request('GET', $router->generate($route, array('id' => $order->getId()))); + $form = $crawler->selectButton('submit_btn')->form(); + $form['jms_choose_payment_method[method]']->select('paypal_express_checkout'); + $client->submit($form); + + return $client->getResponse(); + } + + protected function refreshOrder($order) + { + $em = self::$kernel->getContainer()->get('em'); + $em->clear(); + + return $em->getRepository('TestBundle:Order')->find($order->getId()); + } +} diff --git a/Tests/Functional/PaymentWorkflow/PaymentWorkflowMcryptTest.php b/Tests/Functional/PaymentWorkflow/PaymentWorkflowMcryptTest.php new file mode 100755 index 00000000..91ea4e9b --- /dev/null +++ b/Tests/Functional/PaymentWorkflow/PaymentWorkflowMcryptTest.php @@ -0,0 +1,43 @@ + 'config_mcrypt.yml')); + } + + public function setUp() + { + if (version_compare(phpversion(), '7.1', '>=')) { + $this->markTestSkipped('mcrypt is deprecated since PHP 7.1'); + } + + parent::setUp(); + } + + /** + * @runInSeparateProcess + */ + public function testPayment() + { + $amount = 123.45; + $order = new Order($amount); + + $response = parent::doRequest($order, 'payment'); + $order = $this->refreshOrder($order); + + $this->assertSame(201, $response->getStatusCode(), substr($response, 0, 2000)); + $this->assertTrue(Number::compare($amount, $order->getPaymentInstruction()->getAmount(), '==')); + $this->assertEquals('bar', $order->getPaymentInstruction()->getExtendedData()->get('foo')); + + $extendedData = $this->getRawExtendedData($order); + $this->assertArrayHasKey('foo', $extendedData); + $this->assertNotEquals('bar', $extendedData['foo'][0]); + } +} diff --git a/Tests/Functional/PaymentWorkflow/PaymentWorkflowNoEncryptionTest.php b/Tests/Functional/PaymentWorkflow/PaymentWorkflowNoEncryptionTest.php new file mode 100755 index 00000000..ca339359 --- /dev/null +++ b/Tests/Functional/PaymentWorkflow/PaymentWorkflowNoEncryptionTest.php @@ -0,0 +1,37 @@ + 'config_no_encryption.yml')); + } + + /** + * @runInSeparateProcess + */ + public function testPayment() + { + $amount = 123.45; + $order = new Order($amount); + + $response = parent::doRequest($order, 'payment'); + $order = $this->refreshOrder($order); + + $this->assertSame(201, $response->getStatusCode(), substr($response, 0, 2000)); + $this->assertTrue(Number::compare($amount, $order->getPaymentInstruction()->getAmount(), '==')); + $this->assertEquals('bar', $order->getPaymentInstruction()->getExtendedData()->get('foo')); + + $extendedData = $this->getRawExtendedData($order); + $this->assertArrayHasKey('foo', $extendedData); + $this->assertEquals('bar', $extendedData['foo'][0]); + } +} diff --git a/Tests/Functional/PaymentWorkflow/PaymentWorkflowTest.php b/Tests/Functional/PaymentWorkflow/PaymentWorkflowTest.php new file mode 100755 index 00000000..01bd50ff --- /dev/null +++ b/Tests/Functional/PaymentWorkflow/PaymentWorkflowTest.php @@ -0,0 +1,29 @@ +refreshOrder($order); + + $this->assertSame(201, $response->getStatusCode(), substr($response, 0, 2000)); + $this->assertTrue(Number::compare($amount, $order->getPaymentInstruction()->getAmount(), '==')); + $this->assertEquals('bar', $order->getPaymentInstruction()->getExtendedData()->get('foo')); + + $extendedData = $this->getRawExtendedData($order); + $this->assertArrayHasKey('foo', $extendedData); + $this->assertNotEquals('bar', $extendedData['foo'][0]); + } +} diff --git a/Tests/Functional/PaymentWorkflowMcryptTest.php b/Tests/Functional/PaymentWorkflowMcryptTest.php deleted file mode 100755 index c10d224f..00000000 --- a/Tests/Functional/PaymentWorkflowMcryptTest.php +++ /dev/null @@ -1,27 +0,0 @@ - 'config_mcrypt.yml')); - } - - /** - * @runInSeparateProcess - */ - public function testPaymentDetails() - { - if (version_compare(phpversion(), '7.1', '>=')) { - $this->markTestSkipped('mcrypt is deprecated since PHP 7.1'); - } - - $order = parent::doTestPaymentDetails(); - - $extendedData = $this->getRawExtendedData($order->getPaymentInstruction()); - $this->assertArrayHasKey('foo', $extendedData); - $this->assertNotEquals('bar', $extendedData['foo'][0]); - } -} diff --git a/Tests/Functional/PaymentWorkflowNoEncryptionTest.php b/Tests/Functional/PaymentWorkflowNoEncryptionTest.php deleted file mode 100755 index a12ec5a1..00000000 --- a/Tests/Functional/PaymentWorkflowNoEncryptionTest.php +++ /dev/null @@ -1,23 +0,0 @@ - 'config_no_encryption.yml')); - } - - /** - * @runInSeparateProcess - */ - public function testPaymentDetails() - { - $order = parent::doTestPaymentDetails(); - - $extendedData = $this->getRawExtendedData($order->getPaymentInstruction()); - $this->assertArrayHasKey('foo', $extendedData); - $this->assertEquals('bar', $extendedData['foo'][0]); - } -} diff --git a/Tests/Functional/PaymentWorkflowTest.php b/Tests/Functional/PaymentWorkflowTest.php deleted file mode 100755 index f6fb7829..00000000 --- a/Tests/Functional/PaymentWorkflowTest.php +++ /dev/null @@ -1,18 +0,0 @@ -getRawExtendedData($order->getPaymentInstruction()); - $this->assertArrayHasKey('foo', $extendedData); - $this->assertNotEquals('bar', $extendedData['foo'][0]); - } -} diff --git a/Tests/Functional/TestBundle/Controller/OrderController.php b/Tests/Functional/TestBundle/Controller/OrderController.php index a4c5adcd..82178062 100755 --- a/Tests/Functional/TestBundle/Controller/OrderController.php +++ b/Tests/Functional/TestBundle/Controller/OrderController.php @@ -11,36 +11,40 @@ /** * @Route("/order") + * @Template("TestBundle:Order:order.html.twig") * * @author Johannes */ class OrderController extends Controller { /** - * @Route("/{id}/payment-details", name = "payment_details") - * @Template("TestBundle:Order:paymentDetails.html.twig") + * @Route("/{id}/payment", name="payment") * * @param Order $order */ - public function paymentDetailsAction(Order $order) + public function paymentAction(Order $order) { + return $this->handleRequest($order, array( + 'paypal_express_checkout' => array( + 'foo' => 'bar', + ), + )); + } + + private function handleRequest($order, array $predefinedData) + { + $formData = array( + 'currency' => 'EUR', + 'amount' => $order->getAmount(), + 'predefined_data' => $predefinedData, + ); + $formType = Legacy::supportsFormTypeName() ? 'jms_choose_payment_method' : 'JMS\Payment\CoreBundle\Form\ChoosePaymentMethodType' ; - $form = $this->get('form.factory')->create($formType, null, array( - 'currency' => 'EUR', - 'amount' => $order->getAmount(), - 'predefined_data' => array( - 'paypal_express_checkout' => array( - 'foo' => 'bar', - ), - ), - )); - - $em = $this->getDoctrine()->getManager(); - $ppc = $this->get('payment.plugin_controller'); + $form = $this->get('form.factory')->create($formType, null, $formData); $request = Legacy::supportsRequestService() ? $this->getRequest() @@ -50,6 +54,9 @@ public function paymentDetailsAction(Order $order) $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $ppc = $this->get('payment.plugin_controller'); + $instruction = $form->getData(); $ppc->createPaymentInstruction($instruction); diff --git a/Tests/Functional/TestBundle/Resources/views/Order/paymentDetails.html.twig b/Tests/Functional/TestBundle/Resources/views/Order/order.html.twig similarity index 100% rename from Tests/Functional/TestBundle/Resources/views/Order/paymentDetails.html.twig rename to Tests/Functional/TestBundle/Resources/views/Order/order.html.twig From c4dd33fc3bb94a45b01c1b2f09194d4138a01aa4 Mon Sep 17 00:00:00 2001 From: Paulo Rodrigues Pinto Date: Thu, 15 Jun 2017 13:43:21 +0100 Subject: [PATCH 2/2] WIP --- CHANGELOG.md | 4 ++ Resources/doc/backends.rst | 2 +- Resources/doc/encryption.rst | 41 +++++++++++++++++++ Resources/doc/index.rst | 1 + Resources/doc/setup.rst | 37 +++++------------ .../PaymentWorkflow/PaymentWorkflowTest.php | 20 +++++++++ .../TestBundle/Controller/OrderController.php | 14 +++++++ 7 files changed, 91 insertions(+), 28 deletions(-) create mode 100644 Resources/doc/encryption.rst diff --git a/CHANGELOG.md b/CHANGELOG.md index ed3db181..83838225 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project are documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.3.1] - Unreleased +### Added +- Added encryption [documentation](http://jmspaymentcorebundle.readthedocs.io/en/stable/encryption.html) + ## [1.3.0] - 2017-01-22 ### Changed - `JMS\Payment\CoreBundle\Model\ExtendedDataInterface` has changed. If any of your classes implement this interface, you need to update them accordingly: diff --git a/Resources/doc/backends.rst b/Resources/doc/backends.rst index c8c69393..59676863 100755 --- a/Resources/doc/backends.rst +++ b/Resources/doc/backends.rst @@ -16,7 +16,7 @@ This is the list of currently supported payment backends, through community-crea - `Merchant e-Solutions (Trident) `_ - `Mollie `_ - `Multisafepay `_ -- `Paymill `_ +- `Paymill `_ - `Paypal `_ - `Qiwi `_ - `Robokassa `_ diff --git a/Resources/doc/encryption.rst b/Resources/doc/encryption.rst new file mode 100644 index 00000000..943c5220 --- /dev/null +++ b/Resources/doc/encryption.rst @@ -0,0 +1,41 @@ +Encryption +========== + +- What is encrypted +- Migrating from mcrypt to defuse + + +Enabling encryption +------------------- +The only thing you need to do to enable encryption is to configure an encryption key. You can generate a key with the following command: + +.. code-block :: bash + + bin/console jms_payment_core:generate-key + +And then use it in your configuration: + +.. code-block :: yaml + + # app/config/config.yml + jms_payment_core: + encryption: + secret: output_of_above_command + +.. warning :: + + If you change ``encryption.secret`` and/or ``encryption.provider``, all encrypted data will become unreadable. See :ref:`encryption-reencrypt` for instructions on how to properly change the encryption key or provider. + +Selectively encrypting data +--------------------------- +TODO - Usage (form) + +Using a custom encryption provider +---------------------------------- +TODO (Not recommended) + +.. _encryption-reencrypt: + +Re-encrypting data +------------------ +Coming soon diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index b97b4ea6..4f8090ea 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -32,6 +32,7 @@ License setup payment_form + encryption events plugins model diff --git a/Resources/doc/setup.rst b/Resources/doc/setup.rst index e09d2b0d..64c0f741 100644 --- a/Resources/doc/setup.rst +++ b/Resources/doc/setup.rst @@ -1,8 +1,8 @@ Setup ===== -Installation -------------- +Installing +---------- Install with composer: .. code-block :: bash @@ -23,29 +23,8 @@ And register the bundle in your ``AppKernel.php``: ); } -Configuration -------------- -The configuration is as simple as setting an encryption key which will be used for encrypting data. You can generate a random key with the following command: - -.. code-block :: bash - - bin/console jms_payment_core:generate-key - -And then use it in your configuration: - -.. code-block :: yaml - - # app/config/config.yml - jms_payment_core: - encryption: - secret: output_of_above_command - -.. warning :: - - If you change the ``secret`` or the ``crypto`` provider, all encrypted data will become unreadable. - -Create database tables ----------------------- +Creating database tables +------------------------ This bundle requires a few database tables, which you can create as follows. If you're not using database migrations: @@ -84,8 +63,8 @@ Or, if you're using migrations: .. _setup-configure-plugin: -Configure a payment backend ---------------------------- +Configuring a payment backend +----------------------------- In addition to setting up this bundle, you will also need to install a *plugin* for each payment backend you intend to support. Plugins are simply bundles you add to your application, as you would with any other Symfony bundle. .. tip :: @@ -128,6 +107,10 @@ And configure it: :doc:`Other plugins ` will require different configuration. Take a look at their documentation for complete instructions. +Encrypting sensitive data +------------------------- +This bundle can encrypt sensitive data before storing it in the database. However, this feature is disabled by default. See :doc:`encryption` for instructions on how to enable it. + Next steps ---------- If you have no prior experience with this bundle or payment processing in general, you should follow the :doc:`guides/accepting_payments` guide. Otherwise, proceed to the :doc:`payment_form` chapter. diff --git a/Tests/Functional/PaymentWorkflow/PaymentWorkflowTest.php b/Tests/Functional/PaymentWorkflow/PaymentWorkflowTest.php index 01bd50ff..e0d0faaf 100755 --- a/Tests/Functional/PaymentWorkflow/PaymentWorkflowTest.php +++ b/Tests/Functional/PaymentWorkflow/PaymentWorkflowTest.php @@ -26,4 +26,24 @@ public function testPayment() $this->assertArrayHasKey('foo', $extendedData); $this->assertNotEquals('bar', $extendedData['foo'][0]); } + + /** + * @runInSeparateProcess + */ + public function testPaymentNoEncryption() + { + $amount = 123.45; + $order = new Order($amount); + + $response = parent::doRequest($order, 'payment_no_encryption'); + $order = $this->refreshOrder($order); + + $this->assertSame(201, $response->getStatusCode(), substr($response, 0, 2000)); + $this->assertTrue(Number::compare($amount, $order->getPaymentInstruction()->getAmount(), '==')); + $this->assertEquals('bar', $order->getPaymentInstruction()->getExtendedData()->get('foo')); + + $extendedData = $this->getRawExtendedData($order); + $this->assertArrayHasKey('foo', $extendedData); + $this->assertNotEquals('bar', $extendedData['foo'][0]); + } } diff --git a/Tests/Functional/TestBundle/Controller/OrderController.php b/Tests/Functional/TestBundle/Controller/OrderController.php index 82178062..6b5e7f50 100755 --- a/Tests/Functional/TestBundle/Controller/OrderController.php +++ b/Tests/Functional/TestBundle/Controller/OrderController.php @@ -31,6 +31,20 @@ public function paymentAction(Order $order) )); } + /** + * @Route("/{id}/payment-no-encryption", name="payment_no_encryption") + * + * @param Order $order + */ + public function paymentNoEncryptionAction(Order $order) + { + return $this->handleRequest($order, array( + 'paypal_express_checkout' => array( + 'foo' => 'bar', + ), + )); + } + private function handleRequest($order, array $predefinedData) { $formData = array(