-
Notifications
You must be signed in to change notification settings - Fork 169
Expand file tree
/
Copy pathclass-wc-api-client-authentication.php
More file actions
187 lines (147 loc) · 4.54 KB
/
class-wc-api-client-authentication.php
File metadata and controls
187 lines (147 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<?php
/**
* WC API Client Authentication
*
* Handles SSL/OAuth authentication for the API
*
* @since 2.0
*/
class WC_API_Client_Authentication {
/** @var string endpoint URL */
protected $url;
/** @var string consumer key */
protected $consumer_key;
/** @var string consumer secret */
protected $consumer_secret;
/** OAuth signature method algorithm */
const HASH_ALGORITHM = 'SHA256';
/**
* Setup class
*
* @since 2.0
* @param string $url endpoint URL, e.g. http://www.woothemes,com/wc-api/v2/orders/123
* @param string $consumer_key
* @param string $consumer_secret
*/
public function __construct( $url, $consumer_key, $consumer_secret ) {
$this->url = $url;
$this->consumer_key = $consumer_key;
$this->consumer_secret = $consumer_secret;
}
/**
* Generate the parameters required for OAuth 1.0a authentication
*
* @since 2.0
* @param $params
* @param $method
* @return array
*/
public function get_oauth_params( $params, $method ) {
$params = array_merge( $params, array(
'oauth_consumer_key' => $this->consumer_key,
'oauth_timestamp' => time(),
'oauth_nonce' => sha1( microtime() ),
'oauth_signature_method' => 'HMAC-' . self::HASH_ALGORITHM,
) );
// the params above must be included in the signature generation
$params['oauth_signature'] = $this->generate_oauth_signature( $params, $method );
return $params;
}
/**
* Generate OAuth signature, see server-side method here:
*
* @link https://github.com/woothemes/woocommerce/blob/master/includes/api/class-wc-api-authentication.php#L196-L252
*
* @since 2.0
*
* @param array $params query parameters (including oauth_*)
* @param string $http_method, e.g. GET
* @return string signature
*/
public function generate_oauth_signature( $params, $http_method ) {
$base_request_uri = rawurlencode( $this->url );
if ( isset( $params['filter'] ) ) {
$filters = $params['filter'];
unset( $params['filter'] );
foreach ( $filters as $filter => $filter_value ) {
$params['filter[' . $filter . ']'] = $filter_value;
}
}
// normalize parameter key/values and sort them
$params = $this->normalize_parameters( $params );
uksort( $params, 'strcmp' );
// form query string
$query_params = array();
foreach ( $params as $param_key => $param_value ) {
$query_params[] = $param_key . '%3D' . $param_value; // join with equals sign
}
$query_string = implode( '%26', $query_params ); // join with ampersand
// form string to sign (first key)
$string_to_sign = $http_method . '&' . $base_request_uri . '&' . $query_string;
// append '&' to consumer_secret to be compliant with v3 API
$secret = $this->consumer_secret . '&';
return base64_encode( hash_hmac( self::HASH_ALGORITHM, $string_to_sign, $secret, true ) );
}
/**
* Normalize each parameter by assuming each parameter may have already been
* encoded, so attempt to decode, and then re-encode according to RFC 3986
*
* Note both the key and value is normalized so a filter param like:
*
* 'filter[period]' => 'week'
*
* is encoded to:
*
* 'filter%5Bperiod%5D' => 'week'
*
* This conforms to the OAuth 1.0a spec which indicates the entire query string
* should be URL encoded
*
* Modeled after the core method here:
*
* @link https://github.com/woothemes/woocommerce/blob/master/includes/api/class-wc-api-authentication.php#L254-L288
*
* @since 2.0
* @see rawurlencode()
* @param array $parameters un-normalized pararmeters
* @return array normalized parameters
*/
private function normalize_parameters( $parameters ) {
$normalized_parameters = array();
foreach ( $parameters as $key => $value ) {
// percent symbols (%) must be double-encoded
$key = str_replace( '%', '%25', rawurlencode( rawurldecode( $key ) ) );
$value = str_replace( '%', '%25', rawurlencode( rawurldecode( $value ) ) );
$normalized_parameters[ $key ] = $value;
}
return $normalized_parameters;
}
/**
* Returns true if accessing the API over SSL, primarily used to determine
* which authentication mechanism should be used (HTTP Basic Auth or OAuth)
*
* @since 2.0
* @return bool
*/
public function is_ssl() {
return substr( $this->url, 0, 5 ) === 'https';
}
/**
* Return the consumer key
*
* @since 2.0
* @return string
*/
public function get_consumer_key() {
return $this->consumer_key;
}
/**
* Return the consumer secret
*
* @since 2.0
* @return string
*/
public function get_consumer_secret() {
return $this->consumer_secret;
}
}