forked from rasa/opauth-paypal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PayPalStrategy.php
212 lines (198 loc) · 5.57 KB
/
PayPalStrategy.php
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
<?php
/**
* PayPal strategy for Opauth
*
* More information on Opauth: http://opauth.org
*
* @copyright Original © 2012 U-Zyn Chua (http://uzyn.com)
* @copyright Modified © 2013 Will Morgan (https://github.com/willmorgan)
* @link http://opauth.org
* @package Opauth.PayPalStrategy
* @license MIT License
*
* @author U-Zyn Chua <@uzyn>
* @author Will Morgan <@willmorgan>
*/
class PayPalStrategy extends OpauthStrategy{
/**
* Compulsory config keys, listed as unassociative arrays
* eg. array('app_id', 'app_secret');
*/
public $expects = array('app_id', 'app_secret');
/**
* Optional config keys with respective default values, listed as associative arrays
* eg. array('scope' => 'email');
*/
public $defaults = array(
'redirect_uri' => '{complete_url_to_strategy}int_callback',
/**
* @config boolean If true, use the PayPal sandbox
*/
'sandbox' => false,
/**
* @config string The scopes to ask for separated by spaces
*/
'scope' => 'openid email profile',
);
/**
* CLIENT BROWSER facing URL
* @return string the URL to redirect the client to to start OAuth
*/
public function getClientAuthURL() {
$domain = 'www.paypal.com';
if($this->isSandboxMode()) {
$domain = 'www.sandbox.paypal.com';
}
return sprintf(
'https://%s/webapps/auth/protocol/openidconnect/v1/authorize',
$domain
);
}
/**
* SERVER facing URL
* @return string the URL to obtain an OAuth access_token from
*/
public function getTokenServiceURL() {
$domain = 'api.paypal.com';
if($this->isSandboxMode()) {
$domain = 'api.sandbox.paypal.com';
}
return sprintf(
'https://%s/v1/identity/openidconnect/tokenservice',
$domain
);
}
/**
* SERVER facing URL
* @return string the URL to get the user's OpenID info from
*/
public function getUserInfoURL() {
$domain = 'api.paypal.com';
if($this->isSandboxMode()) {
$domain = 'api.sandbox.paypal.com';
}
return sprintf(
'https://%s/v1/identity/openidconnect/userinfo',
$domain
);
}
/**
* @return boolean If we're in sandbox mode
*/
public function isSandboxMode() {
return !empty($this->strategy['sandbox']);
}
/**
* Auth request
* Redirects the client to the authorise page where they are asked to enter
* their credentials and accept the information that this application asks
* for.
* @return void
*/
public function request(){
$url = $this->getClientAuthURL();
$params = array(
'client_id' => $this->strategy['app_id'],
'response_type' => 'code',
'nonce' => time() + base64_encode(rand(0x00, 0xff)),
'redirect_uri' => $this->strategy['redirect_uri'],
);
if (!empty($this->strategy['scope'])) $params['scope'] = $this->strategy['scope'];
if (!empty($this->strategy['state'])) $params['state'] = $this->strategy['state'];
if (!empty($this->strategy['response_type'])) $params['response_type'] = $this->strategy['response_type'];
if (!empty($this->strategy['display'])) $params['display'] = $this->strategy['display'];
$this->clientGet($url, $params);
}
/**
* Internal callback, after PayPal's OAuth
* After the user accepts the terms on the client authentication page
* (see ->request), we are returned a code that is used to exchange for an
* access_token. This code can be used only once.
*/
public function int_callback(){
if (array_key_exists('code', $_GET) && !empty($_GET['code'])){
$url = $this->getTokenServiceURL();
$params = array(
'client_id' =>$this->strategy['app_id'],
'client_secret' => $this->strategy['app_secret'],
'redirect_uri'=> $this->strategy['redirect_uri'],
'code' => trim($_GET['code']),
'grant_type' => 'authorization_code'
);
$response = $this->serverPost($url, $params, null, $headers);
$results = json_decode($response, true);
if (!empty($results) && !empty($results['access_token'])){
$me = $this->me($results['access_token']);
$this->auth = array(
'provider' => 'PayPal',
'uid' => $me['user_id'],
'info' => array(),
'credentials' => array(
'token' => $results['access_token'],
'expires' => date('c', time() + $results['expires_in'])
),
'token' => $results,
'raw' => $me
);
$this->callback();
}
else{
$error = array(
'provider' => 'PayPal',
'code' => 'access_token_error',
'message' => 'Failed when attempting to obtain access token',
'raw' => $headers
);
$this->errorCallback($error);
}
}
else{
$error = array(
'provider' => 'PayPal',
'code' => $_GET['error'],
'message' => $_GET['error_description'],
'raw' => $_GET
);
$this->errorCallback($error);
}
}
/**
* Queries PayPal's Identity resource for OpenID user info.
* At this point, the server must hold a valid access_token.
*
* @param string $access_token
* @return array Parsed JSON results in OpenID format
*/
protected function me($access_token){
$url = $this->getUserInfoURL();
$data = array(
'schema' => 'openid',
);
$headers = array(
'Authorization: Bearer ' . $access_token,
'Accept: application/json',
'Content-Type: application/json',
);
$options = array(
'http' => array(
'header' => implode("\r\n", $headers),
),
);
$me = $this->serverGet($url, $data, $options, $headers);
if (!empty($me)){
return json_decode($me, true);
}
else{
$error = array(
'provider' => 'PayPal',
'code' => 'me_error',
'message' => 'Failed when attempting to query for user information',
'raw' => array(
'response' => $me,
'headers' => $headers
)
);
$this->errorCallback($error);
}
}
}