Failed Conditions
Push — develop ( 9cc0c5...5590ec )
by Reüel
03:35
created

Security   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Test Coverage

Coverage 63.64%

Importance

Changes 0
Metric Value
eloc 41
dl 0
loc 116
ccs 28
cts 44
cp 0.6364
rs 10
c 0
b 0
f 0
wmc 15

6 Methods

Rating   Name   Duplication   Size   Complexity  
A get_request_data() 0 19 4
A sign_data() 0 8 1
A get_calculations_parameters_out() 0 11 3
A get_calculations_parameters_in() 0 11 3
A get_calculation_fields() 0 4 1
A get_signature() 0 27 3
1
<?php
2
3
namespace Pronamic\WordPress\Pay\Gateways\Ingenico;
4
5
/**
6
 * Title: Ingenico security class
7
 * Description:
8
 * Copyright: Copyright (c) 2005 - 2016
9
 * Company: Pronamic
10
 *
11
 * @author  Remco Tolsma
12
 * @version 2.0.0
13
 */
14
class Security {
15
	/**
16
	 * The Ogone calculations parameters in
17
	 *
18
	 * @var array
19
	 */
20
	private static $calculations_parameters_in;
21
22
	/**
23
	 * The Ogone calucations parameters out
24
	 *
25
	 * @var array
26
	 */
27
	private static $calculations_parameters_out;
28
29
	/**
30
	 * Get calculations parameters in
31
	 */
32 3
	public static function get_calculations_parameters_in() {
33 3
		if ( ! isset( self::$calculations_parameters_in ) ) {
34 1
			self::$calculations_parameters_in = array();
35
36 1
			$file = dirname( __FILE__ ) . '/../data/calculations-parameters-sha-in.txt';
37 1
			if ( is_readable( $file ) ) {
38 1
				self::$calculations_parameters_in = file( $file, FILE_IGNORE_NEW_LINES );
0 ignored issues
show
Documentation Bug introduced by
It seems like file($file, Pronamic\Wor...\FILE_IGNORE_NEW_LINES) can also be of type false. However, the property $calculations_parameters_in is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
39
			}
40
		}
41
42 3
		return self::$calculations_parameters_in;
43
	}
44
45
	/**
46
	 * Get calculations parameters in
47
	 */
48 2
	public static function get_calculations_parameters_out() {
49 2
		if ( ! isset( self::$calculations_parameters_out ) ) {
50 1
			self::$calculations_parameters_out = array();
51
52 1
			$file = dirname( __FILE__ ) . '/../data/calculations-parameters-sha-out.txt';
53 1
			if ( is_readable( $file ) ) {
54 1
				self::$calculations_parameters_out = file( $file, FILE_IGNORE_NEW_LINES );
0 ignored issues
show
Documentation Bug introduced by
It seems like file($file, Pronamic\Wor...\FILE_IGNORE_NEW_LINES) can also be of type false. However, the property $calculations_parameters_out is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
55
			}
56
		}
57
58 2
		return self::$calculations_parameters_out;
59
	}
60
61
	/**
62
	 * Get request data
63
	 *
64
	 * @return array
65
	 */
66
	public static function get_request_data() {
67
		$data = array();
68
69
		if ( isset( $_SERVER['REQUEST_METHOD'] ) ) { // WPCS: input var okay
70
			switch ( $_SERVER['REQUEST_METHOD'] ) { // WPCS: input var okay
71
				case 'GET':
72
					// @todo see how we can improve security around this
73
					$data = $_GET; // WPCS: input var okay
74
75
					break;
76
				case 'POST':
77
					// @todo see how we can improve security around this
78
					$data = $_POST; // WPCS: input var okay // WPCS: CSRF OK
79
80
					break;
81
			}
82
		}
83
84
		return $data;
85
	}
86
87 3
	public static function get_calculation_fields( $calculation_fields, $fields ) {
88 3
		$calculation_fields = array_flip( $calculation_fields );
89
90 3
		return array_intersect_key( $fields, $calculation_fields );
91
	}
92
93 3
	public static function get_signature( $fields, $passphrase, $hash_algorithm ) {
94
		// This string is constructed by concatenating the values of the fields sent with the order (sorted
95
		// alphabetically, in the format ‘parameter=value’), separated by a passphrase.
96 3
		$string = '';
97
98
		// All parameters need to be put alphabetically
99 3
		ksort( $fields );
100
101
		// Loop
102 3
		foreach ( $fields as $name => $value ) {
103 3
			$value = (string) $value;
104
105
			// Use of empty will fail, value can be string '0'
106 3
			if ( strlen( $value ) > 0 ) {
107 2
				$name = strtoupper( $name );
108
109 3
				$string .= $name . '=' . $value . $passphrase;
110
			}
111
		}
112
113
		// Hash
114 3
		$result = hash( $hash_algorithm, $string );
115
116
		// String to uppercase
117 3
		$result = strtoupper( $result );
118
119 3
		return $result;
120
	}
121
122
	public static function sign_data( Data $data, $pass_phrase, $hash_algorithm ) {
123
		$calculation_fields = Security::get_calculations_parameters_in();
124
125
		$fields = Security::get_calculation_fields( $calculation_fields, $data->get_fields() );
126
127
		$signature = Security::get_signature( $fields, $pass_phrase, $hash_algorithm );
128
129
		$data->set_field( 'SHASign', $signature );
130
	}
131
}
132