<commit_before><?php

/**
 * @package         Billing
 * @copyright       Copyright (C) 2012-2020 BillRun Technologies Ltd. All rights reserved.
 * @license         GNU Affero General Public License Version 3; see LICENSE.txt
 */

/**
 * This class manages custom payment gateway actions.
 *
 * @package     Controllers
 * @subpackage  Action
 *
 */
class CustompaymentgatewayController extends ApiController {

	use Billrun_Traits_Api_UserPermissions;

	public function generateTransactionsRequestFileAction() {
		$this->allowed();
		$request = $this->getRequest();
		Billrun_Factory::log()->log('Custom payment gateway API call with params: ' . print_r($request->getRequest(), 1), Zend_Log::INFO);
		$options['gateway_name'] = $request->get('payment_gateway');
		$options['file_type'] = $request->get('file_type');
		$options['cpg_type'] = "transactions_request";
		$options['params'] = [];
		if (!empty($request->get('parameters'))) {
			$options['params'] = json_decode($request->get('parameters'), true);
			if (is_null($options['params'])) {
				return $this->setError("Wrong parameters structure, no file was generated");
			}
		}
		$options['params']['created_by'] = Billrun_Factory::user() ? Billrun_Factory::user()->getUsername() : null;

		$options['pay_mode'] = !empty($request->get('pay_mode')) ? $request->get('pay_mode') : null;

		if (!$this->validateOptions($options)) {
			return $this->setError("One or more of the input parameters are not valid. ");
		}
		$cmd = 'php ' . APPLICATION_PATH . '/public/index.php ' . Billrun_Util::getCmdEnvParams() . ' --generate --type ' . $options['cpg_type'] . ' payment_gateway=' . $options['gateway_name'] . ' file_type=' . $options['file_type'];
		if (!is_null($options['pay_mode'])) {
			$cmd .= " pay_mode=" . $options['pay_mode'];
		}
		if (!$this->validateApiParameters($options)) {
			return $this->setError("One or more of the gateway parameters are not valid. ");
		}
		foreach ($options['params'] as $name => $value) {
			$cmd .= " " . $name . "=" . $value;
		}
		try {
			$success = Billrun_Util::forkProcessCli($cmd);
		} catch (Exception $ex) {
			return $this->setError("Error: " . $ex->getMessage());
		}
		Billrun_Factory::log("Finished " . $options['cpg_type'] . " custom payment gateway request.", Zend_Log::DEBUG);
		$output = array(
			'status' => "Done",
			'details' => array(),
		);
		$this->setSuccess($output, $options);
	}

	protected function getPermissionLevel() {
		return Billrun_Traits_Api_IUserPermissions::PERMISSION_WRITE;
	}

	protected function validateOptions($options) {
		if (isset($options['pay_mode']) && !in_array($options['pay_mode'], ['one_payment', 'multiple_payments'])) {
			Billrun_Factory::log("pay_mode parameter's value isn't valid", Zend_Log::ERR);
			return false;
		}

		$paymentsGatewaysConfig = Billrun_Factory::config()->getConfigValue('payment_gateways', []);
		if (empty($paymentsGatewaysConfig)) {
			Billrun_Factory::log("Payment gateways configuration is empty", Zend_Log::ERR);
			return false;
		} else {
			$gatewaysOptions = array_column($paymentsGatewaysConfig, 'name');
			if (!in_array($options['gateway_name'], $gatewaysOptions)) {
				Billrun_Factory::log("gateway_name parameter's value isn't valid", Zend_Log::ERR);
				return false;
			}
		}
		return true;
	}
	
	protected function validateApiParameters($options) {
		if (!isset($options['params'])) {
			return true;
		}
		$paymentsGatewaysConfig = Billrun_Factory::config()->getConfigValue('payment_gateways', []);
		$gatewayConfig = current(array_filter($paymentsGatewaysConfig, function($gatewayConfig) use($options) {
			return $gatewayConfig['name'] === $options['gateway_name'];
		}));
		if (empty($gatewayConfig['transactions_request'][0]['parameters'])) {
			Billrun_Factory::log("No parameters were configured, so no parameters can be send through the API request", Zend_Log::ERR);
			return false;
		}
		$parameters_config = $gatewayConfig['transactions_request'][0]['parameters'];
		$parameters_names = array_column($parameters_config, 'name');
		foreach($options['params'] as $name => $value) {
			if (!in_array($name, $parameters_names)) {
				Billrun_Factory::log($name . " parameter wasn't configured", Zend_Log::ERR);
				return false;
			}
			$paramConfig = current(array_filter($parameters_config, function($param) use($name) {
				return $param['name'] === $name;
			}));
			if (isset($paramConfig['regex']) && !preg_match($paramConfig['regex'], $value)) {
				Billrun_Factory::log($name . " parameter's value isn't valid", Zend_Log::ERR);
				return false;
			}
		}
		return true;
	}
	
	protected function render($tpl, array $parameters = null) {
		return parent::render('index', $parameters);
	}

}<commit_msg>BRCD-2643:Added general validation check for the input parameters in cpg API, and removed duplication of the validation function from the model.<commit_after><?php

/**
 * @package         Billing
 * @copyright       Copyright (C) 2012-2020 BillRun Technologies Ltd. All rights reserved.
 * @license         GNU Affero General Public License Version 3; see LICENSE.txt
 */

/**
 * This class manages custom payment gateway actions.
 *
 * @package     Controllers
 * @subpackage  Action
 *
 */
class CustompaymentgatewayController extends ApiController {

	use Billrun_Traits_Api_UserPermissions;

	public function generateTransactionsRequestFileAction() {
		$this->allowed();
		$request = $this->getRequest();
		Billrun_Factory::log()->log('Custom payment gateway API call with params: ' . print_r($request->getRequest(), 1), Zend_Log::INFO);
		$options['gateway_name'] = $request->get('payment_gateway');
		$options['file_type'] = $request->get('file_type');
		$options['cpg_type'] = "transactions_request";
		$options['params'] = [];
		if (!empty($request->get('parameters'))) {
			$options['params'] = json_decode($request->get('parameters'), true);
			if (is_null($options['params'])) {
				return $this->setError("Wrong parameters structure, no file was generated");
			}
		}
		$options['params']['created_by'] = Billrun_Factory::user() ? Billrun_Factory::user()->getUsername() : null;

		$options['pay_mode'] = !empty($request->get('pay_mode')) ? $request->get('pay_mode') : null;

		if (!$this->validateOptions($options)) {
			return $this->setError("One or more of the input parameters are not valid. ");
		}
		$cmd = 'php ' . APPLICATION_PATH . '/public/index.php ' . Billrun_Util::getCmdEnvParams() . ' --generate --type ' . $options['cpg_type'] . ' payment_gateway=' . $options['gateway_name'] . ' file_type=' . $options['file_type'];
		if (!is_null($options['pay_mode'])) {
			$cmd .= " pay_mode=" . $options['pay_mode'];
		}
		foreach ($options['params'] as $name => $value) {
			$cmd .= " " . $name . "=" . $value;
		}
		try {
			$success = Billrun_Util::forkProcessCli($cmd);
		} catch (Exception $ex) {
			return $this->setError("Error: " . $ex->getMessage());
		}
		Billrun_Factory::log("Finished " . $options['cpg_type'] . " custom payment gateway request.", Zend_Log::DEBUG);
		$output = array(
			'status' => "Done",
			'details' => array(),
		);
		$this->setSuccess($output, $options);
	}

	protected function getPermissionLevel() {
		return Billrun_Traits_Api_IUserPermissions::PERMISSION_WRITE;
	}

	protected function validateOptions($options) {
		if (isset($options['pay_mode']) && !in_array($options['pay_mode'], ['one_payment', 'multiple_payments'])) {
			Billrun_Factory::log("pay_mode parameter's value isn't valid", Zend_Log::ERR);
			return false;
		}

		$paymentsGatewaysConfig = Billrun_Factory::config()->getConfigValue('payment_gateways', []);
		if (empty($paymentsGatewaysConfig)) {
			Billrun_Factory::log("Payment gateways configuration is empty", Zend_Log::ERR);
			return false;
		} else {
			$gatewaysOptions = array_column($paymentsGatewaysConfig, 'name');
			if (!in_array($options['gateway_name'], $gatewaysOptions)) {
				Billrun_Factory::log("gateway_name parameter's value isn't valid", Zend_Log::ERR);
				return false;
			}
		}
		if (!empty($options['params'])) {
			$available_characters = array_merge_recursive(['-', ',', '/', '_', '&', '(', ')', '\'', '|', '+', '.'] , range('0', '9'));
			$parameters_string = str_replace($available_characters, '', implode("", $options['params']));
			if (!preg_match( '/^[a-zA-Z]+/', $parameters_string)) {
				return false;
			}
		}

		return true;
	}

	protected function render($tpl, array $parameters = null) {
		return parent::render('index', $parameters);
	}

}
{'fraction_non_alphanumeric': 0.1771793054571226, 'fraction_numerical': 0.003307347035199622, 'mean_word_length': 5.034925160370634, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3218806', 'n_tokens_mistral': 2892, 'n_tokens_neox': 2610, 'n_words': 538}