From 5911e093108df35cd2ddb4f6763befda8eb42cc2 Mon Sep 17 00:00:00 2001 From: dinamiko Date: Tue, 10 May 2022 10:25:06 +0200 Subject: [PATCH 1/3] validate birth date (WIP) --- .../Gateway/PayUponInvoice/PayUponInvoice.php | 71 ++++++++++++++----- .../src/Helper/PayUponInvoiceHelper.php | 15 ++++ 2 files changed, 67 insertions(+), 19 deletions(-) create mode 100644 modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php index e2fbdc59e..6a3f556c5 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php @@ -9,6 +9,7 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice; +use DateTime; use Psr\Log\LoggerInterface; use WC_Order; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PayUponInvoiceOrderEndpoint; @@ -259,6 +260,11 @@ class PayUponInvoice { if ( 'DE' !== $fields['billing_country'] ) { $errors->add( 'validation', __( 'Billing country not available.', 'woocommerce-paypal-payments' ) ); } + + $birth_date = filter_input( INPUT_POST, 'billing_birth_date', FILTER_SANITIZE_STRING ); + if(! $this->validate_birth_date($birth_date)) { + $errors->add( 'validation', __( 'Invalid birth date.', 'woocommerce-paypal-payments' ) ); + } }, 10, 2 @@ -276,6 +282,28 @@ class PayUponInvoice { ); } + /** + * Registers PUI assets. + */ + public function register_assets(): void { + wp_enqueue_script( + 'ppcp-pay-upon-invoice', + trailingslashit( $this->module_url ) . 'assets/js/pay-upon-invoice.js', + array(), + $this->asset_version + ); + + wp_localize_script( + 'ppcp-pay-upon-invoice', + 'FraudNetConfig', + array( + 'f' => $this->fraud_net->session_id(), + 's' => $this->fraud_net->source_website_id(), + 'sandbox' => $this->environment->current_environment_is( Environment::SANDBOX ), + ) + ); + } + /** * Checks whether checkout is ready for PUI. * @@ -311,26 +339,31 @@ class PayUponInvoice { } /** - * Registers PUI assets. + * Ensures date is valid, at least 18 years back and in the last 100 years timeframe. + * + * @param string $date + * @param string $format + * @return bool */ - public function register_assets(): void { - wp_enqueue_script( - 'ppcp-pay-upon-invoice', - trailingslashit( $this->module_url ) . 'assets/js/pay-upon-invoice.js', - array(), - $this->asset_version - ); + private function validate_birth_date(string $date, string $format = 'Y-m-d'): bool + { + $d = DateTime::createFromFormat($format, $date); + if($d === false) { + return false; + } - wp_localize_script( - 'ppcp-pay-upon-invoice', - 'FraudNetConfig', - array( - 'f' => $this->fraud_net->session_id(), - 's' => $this->fraud_net->source_website_id(), - 'sandbox' => $this->environment->current_environment_is( Environment::SANDBOX ), - ) - ); + if($date !== $d->format($format)) { + return false; + } + + if (time() < strtotime('+18 years', strtotime($date))) { + return false; + } + +// if (time() > strtotime('-100 years', strtotime($date))) { +// return false; +// } + + return true; } - - } diff --git a/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php b/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php new file mode 100644 index 000000000..6d5029322 --- /dev/null +++ b/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php @@ -0,0 +1,15 @@ + Date: Tue, 10 May 2022 11:59:24 +0200 Subject: [PATCH 2/3] Validate birth date --- modules/ppcp-wc-gateway/services.php | 7 ++- .../Gateway/PayUponInvoice/PayUponInvoice.php | 45 ++++++------------- .../PayUponInvoice/PayUponInvoiceGateway.php | 1 + .../src/Helper/PayUponInvoiceHelper.php | 31 ++++++++++++- .../Helper/PayUponInvoiceHelperTest.php | 32 +++++++++++++ 5 files changed, 81 insertions(+), 35 deletions(-) create mode 100644 tests/PHPUnit/WcGateway/Helper/PayUponInvoiceHelperTest.php diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index dffca2df2..08d3fb69a 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -38,6 +38,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoice; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoiceGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\TransactionUrlProvider; use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus; +use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceHelper; use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus; use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice; use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice; @@ -2192,6 +2193,9 @@ return array( (string) $source_website_id() ); }, + 'wcgateway.pay-upon-invoice-helper' => static function( ContainerInterface $container ): PayUponInvoiceHelper { + return new PayUponInvoiceHelper(); + }, 'wcgateway.pay-upon-invoice' => static function ( ContainerInterface $container ): PayUponInvoice { return new PayUponInvoice( $container->get( 'wcgateway.url' ), @@ -2200,7 +2204,8 @@ return array( $container->get( 'woocommerce.logger.woocommerce' ), $container->get( 'wcgateway.settings' ), $container->get( 'onboarding.environment' ), - $container->get( 'ppcp.asset-version' ) + $container->get( 'ppcp.asset-version' ), + $container->get( 'wcgateway.pay-upon-invoice-helper' ) ); }, 'wcgateway.logging.is-enabled' => function ( ContainerInterface $container ) : bool { diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php index 6a3f556c5..355ef3f3b 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php @@ -9,12 +9,12 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice; -use DateTime; use Psr\Log\LoggerInterface; use WC_Order; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PayUponInvoiceOrderEndpoint; use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException; use WooCommerce\PayPalCommerce\Onboarding\Environment; +use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceHelper; use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; @@ -76,6 +76,13 @@ class PayUponInvoice { */ protected $asset_version; + /** + * The PUI helper. + * + * @var PayUponInvoiceHelper + */ + protected $pui_helper; + /** * PayUponInvoice constructor. * @@ -86,6 +93,7 @@ class PayUponInvoice { * @param Settings $settings The settings. * @param Environment $environment The environment. * @param string $asset_version The asset version. + * @param PayUponInvoiceHelper $pui_helper The PUI helper. */ public function __construct( string $module_url, @@ -94,7 +102,8 @@ class PayUponInvoice { LoggerInterface $logger, Settings $settings, Environment $environment, - string $asset_version + string $asset_version, + PayUponInvoiceHelper $pui_helper ) { $this->module_url = $module_url; $this->fraud_net = $fraud_net; @@ -103,6 +112,7 @@ class PayUponInvoice { $this->settings = $settings; $this->environment = $environment; $this->asset_version = $asset_version; + $this->pui_helper = $pui_helper; } /** @@ -262,7 +272,7 @@ class PayUponInvoice { } $birth_date = filter_input( INPUT_POST, 'billing_birth_date', FILTER_SANITIZE_STRING ); - if(! $this->validate_birth_date($birth_date)) { + if ( ! $this->pui_helper->validate_birth_date( $birth_date ) ) { $errors->add( 'validation', __( 'Invalid birth date.', 'woocommerce-paypal-payments' ) ); } }, @@ -337,33 +347,4 @@ class PayUponInvoice { return true; } - - /** - * Ensures date is valid, at least 18 years back and in the last 100 years timeframe. - * - * @param string $date - * @param string $format - * @return bool - */ - private function validate_birth_date(string $date, string $format = 'Y-m-d'): bool - { - $d = DateTime::createFromFormat($format, $date); - if($d === false) { - return false; - } - - if($date !== $d->format($format)) { - return false; - } - - if (time() < strtotime('+18 years', strtotime($date))) { - return false; - } - -// if (time() > strtotime('-100 years', strtotime($date))) { -// return false; -// } - - return true; - } } diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php index f26deaece..8afea94a1 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php @@ -78,6 +78,7 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { * @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory. * @param PaymentSourceFactory $payment_source_factory The payment source factory. * @param Environment $environment The environment. + * @param TransactionUrlProvider $transaction_url_provider The transaction URL provider. * @param LoggerInterface $logger The logger. */ public function __construct( diff --git a/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php b/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php index 6d5029322..cd7c6c491 100644 --- a/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php +++ b/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php @@ -9,7 +9,34 @@ declare( strict_types=1 ); namespace WooCommerce\PayPalCommerce\WcGateway\Helper; -class PayUponInvoiceHelper -{ +use DateTime; +/** + * Class PayUponInvoiceHelper + */ +class PayUponInvoiceHelper { + + /** + * Ensures date is valid and at least 18 years back. + * + * @param string $date The date. + * @param string $format The date format. + * @return bool + */ + public function validate_birth_date( string $date, string $format = 'Y-m-d' ): bool { + $d = DateTime::createFromFormat( $format, $date ); + if ( false === $d ) { + return false; + } + + if ( $date !== $d->format( $format ) ) { + return false; + } + + if ( time() < strtotime( '+18 years', strtotime( $date ) ) ) { + return false; + } + + return true; + } } diff --git a/tests/PHPUnit/WcGateway/Helper/PayUponInvoiceHelperTest.php b/tests/PHPUnit/WcGateway/Helper/PayUponInvoiceHelperTest.php new file mode 100644 index 000000000..5a073c95a --- /dev/null +++ b/tests/PHPUnit/WcGateway/Helper/PayUponInvoiceHelperTest.php @@ -0,0 +1,32 @@ +assertSame((new PayUponInvoiceHelper())->validate_birth_date($input), $output); + } + + public function datesProvider(): array{ + $format = 'Y-m-d'; + + return [ + ['', false], + [(new DateTime())->format($format), false], + [(new DateTime('-17 years'))->format($format), false], + ['31-02-1942', false], + ['01-01-1942', false], + ['1942-01-01', true], + ]; + } + +} From 235c9c8281c0b1474d9d0c318e717aca9e62e803 Mon Sep 17 00:00:00 2001 From: dinamiko Date: Tue, 10 May 2022 12:18:18 +0200 Subject: [PATCH 3/3] Fix psalm --- .../src/Gateway/PayUponInvoice/PayUponInvoice.php | 2 +- modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php | 3 ++- tests/PHPUnit/WcGateway/Helper/PayUponInvoiceHelperTest.php | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php index 355ef3f3b..1bc41c257 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php @@ -272,7 +272,7 @@ class PayUponInvoice { } $birth_date = filter_input( INPUT_POST, 'billing_birth_date', FILTER_SANITIZE_STRING ); - if ( ! $this->pui_helper->validate_birth_date( $birth_date ) ) { + if ( $birth_date && ! $this->pui_helper->validate_birth_date( $birth_date ) ) { $errors->add( 'validation', __( 'Invalid birth date.', 'woocommerce-paypal-payments' ) ); } }, diff --git a/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php b/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php index cd7c6c491..ce2dc1b8c 100644 --- a/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php +++ b/modules/ppcp-wc-gateway/src/Helper/PayUponInvoiceHelper.php @@ -33,7 +33,8 @@ class PayUponInvoiceHelper { return false; } - if ( time() < strtotime( '+18 years', strtotime( $date ) ) ) { + $date_time = strtotime( $date ); + if ( $date_time && time() < strtotime( '+18 years', $date_time ) ) { return false; } diff --git a/tests/PHPUnit/WcGateway/Helper/PayUponInvoiceHelperTest.php b/tests/PHPUnit/WcGateway/Helper/PayUponInvoiceHelperTest.php index 5a073c95a..3a1d9bdc0 100644 --- a/tests/PHPUnit/WcGateway/Helper/PayUponInvoiceHelperTest.php +++ b/tests/PHPUnit/WcGateway/Helper/PayUponInvoiceHelperTest.php @@ -23,7 +23,7 @@ class PayUponInvoiceHelperTest extends TestCase ['', false], [(new DateTime())->format($format), false], [(new DateTime('-17 years'))->format($format), false], - ['31-02-1942', false], + ['1942-02-31', false], ['01-01-1942', false], ['1942-01-01', true], ];