· 6 years ago · Oct 20, 2018, 10:12 AM
1class OAuthServer
2{
3
4 function __construct ( $uri = null, $method = null, $params = null, $store = 'SESSION',
5 $store_options = array(), $options = array() )
6 {
7 $this->session = OAuthSession::instance($store, $store_options);
8
9 if (array_key_exists('allowed_uri_schemes', $options) && is_array($options['allowed_uri_schemes'])) {
10 $this->allowed_uri_schemes = $options['allowed_uri_schemes'];
11 }
12 if (array_key_exists('disallowed_uri_schemes', $options) && is_array($options['disallowed_uri_schemes'])) {
13 $this->disallowed_uri_schemes = $options['disallowed_uri_schemes'];
14 }
15 }
16
17 /**
18 * Handle the request_token request.
19 * Returns the new request token and request token secret.
20 *
21 * TODO: add correct result code to exception
22 *
23 * @return string returned request token, false on an error
24 */
25 public function requestToken ()
26 {
27 OAuthRequestLogger::start($this);
28 try
29 {
30 $this->verify(false);
31
32 $options = array();
33 $ttl = $this->getParam('xoauth_token_ttl', false);
34 if ($ttl)
35 {
36 $options['token_ttl'] = $ttl;
37 }
38
39 // 1.0a Compatibility : associate callback url to the request token
40 $cbUrl = $this->getParam('oauth_callback', true);
41 if ($cbUrl) {
42 $options['oauth_callback'] = $cbUrl;
43 }
44
45 // Create a request token
46 $store = OAuthStore::instance();
47 $token = $store->addConsumerRequestToken($this->getParam('oauth_consumer_key', true), $options);
48 $result = 'oauth_callback_confirmed=1&oauth_token='.$this->urlencode($token['token'])
49 .'&oauth_token_secret='.$this->urlencode($token['token_secret']);
50
51 if (!empty($token['token_ttl']))
52 {
53 $result .= '&xoauth_token_ttl='.$this->urlencode($token['token_ttl']);
54 }
55
56 $request_token = $token['token'];
57
58 header('HTTP/1.1 200 OK');
59 header('Content-Length: '.strlen($result));
60 header('Content-Type: application/x-www-form-urlencoded');
61
62 echo $result;
63 }
64 catch (OAuthException2 $e)
65 {
66 $request_token = false;
67
68 header('HTTP/1.1 401 Unauthorized');
69 header('Content-Type: text/plain');
70
71 echo "OAuth Verification Failed: " . $e->getMessage();
72 }
73
74 OAuthRequestLogger::flush();
75 return $request_token;
76 }
77
78
79 /**
80 * Verify the start of an authorization request. Verifies if the request token is valid.
81 * Next step is the method authorizeFinish()
82 *
83 * Nota bene: this stores the current token, consumer key and callback in the _SESSION
84 *
85 * @exception OAuthException2 thrown when not a valid request
86 * @return array token description
87 */
88 public function authorizeVerify ()
89 {
90 OAuthRequestLogger::start($this);
91
92 $store = OAuthStore::instance();
93 $token = $this->getParam('oauth_token', true);
94 $rs = $store->getConsumerRequestToken($token);
95 if (empty($rs))
96 {
97 throw new OAuthException2('Unknown request token "'.$token.'"');
98 }
99
100 // We need to remember the callback
101 $verify_oauth_token = $this->session->get('verify_oauth_token');
102 if ( empty($verify_oauth_token)
103 || strcmp($verify_oauth_token, $rs['token']))
104 {
105 $this->session->set('verify_oauth_token', $rs['token']);
106 $this->session->set('verify_oauth_consumer_key', $rs['consumer_key']);
107 $cb = $this->getParam('oauth_callback', true);
108 if ($cb)
109 $this->session->set('verify_oauth_callback', $cb);
110 else
111 $this->session->set('verify_oauth_callback', $rs['callback_url']);
112 }
113 OAuthRequestLogger::flush();
114 return $rs;
115 }
116
117
118 /**
119 * Overrule this method when you want to display a nice page when
120 * the authorization is finished. This function does not know if the authorization was
121 * succesfull, you need to check the token in the database.
122 *
123 * @param boolean authorized if the current token (oauth_token param) is authorized or not
124 * @param int user_id user for which the token was authorized (or denied)
125 * @return string verifier For 1.0a Compatibility
126 */
127 public function authorizeFinish ( $authorized, $user_id )
128 {
129 OAuthRequestLogger::start($this);
130
131 $token = $this->getParam('oauth_token', true);
132 $verifier = null;
133 if ($this->session->get('verify_oauth_token') == $token)
134 {
135 // Flag the token as authorized, or remove the token when not authorized
136 $store = OAuthStore::instance();
137
138 // Fetch the referrer host from the oauth callback parameter
139 $referrer_host = '';
140 $oauth_callback = false;
141 $verify_oauth_callback = $this->session->get('verify_oauth_callback');
142 if (!empty($verify_oauth_callback) && $verify_oauth_callback != 'oob') // OUT OF BAND
143 {
144 $oauth_callback = $this->session->get('verify_oauth_callback');
145 $ps = parse_url($oauth_callback);
146 if (isset($ps['host']))
147 {
148 $referrer_host = $ps['host'];
149 }
150 }
151
152 if ($authorized)
153 {
154 OAuthRequestLogger::addNote('Authorized token "'.$token.'" for user '.$user_id.' with referrer "'.$referrer_host.'"');
155 // 1.0a Compatibility : create a verifier code
156 $verifier = $store->authorizeConsumerRequestToken($token, $user_id, $referrer_host);
157 }
158 else
159 {
160 OAuthRequestLogger::addNote('Authorization rejected for token "'.$token.'" for user '.$user_id."\nToken has been deleted");
161 $store->deleteConsumerRequestToken($token);
162 }
163
164 if (!empty($oauth_callback))
165 {
166 $params = array('oauth_token' => rawurlencode($token));
167 // 1.0a Compatibility : if verifier code has been generated, add it to the URL
168 if ($verifier) {
169 $params['oauth_verifier'] = $verifier;
170 }
171
172 $uri = preg_replace('/\s/', '%20', $oauth_callback);
173 if (!empty($this->allowed_uri_schemes))
174 {
175 if (!in_array(substr($uri, 0, strpos($uri, '://')), $this->allowed_uri_schemes))
176 {
177 throw new OAuthException2('Illegal protocol in redirect uri '.$uri);
178 }
179 }
180 else if (!empty($this->disallowed_uri_schemes))
181 {
182 if (in_array(substr($uri, 0, strpos($uri, '://')), $this->disallowed_uri_schemes))
183 {
184 throw new OAuthException2('Illegal protocol in redirect uri '.$uri);
185 }
186 }
187
188 $this->redirect($oauth_callback, $params);
189 }
190 }
191 OAuthRequestLogger::flush();
192 return $verifier;
193 }
194
195
196 /**
197 * Exchange a request token for an access token.
198 * The exchange is only succesful iff the request token has been authorized.
199 *
200 * Never returns, calls exit() when token is exchanged or when error is returned.
201 */
202 public function accessToken ()
203 {
204 OAuthRequestLogger::start($this);
205
206 try
207 {
208 $this->verify('request');
209
210 $options = array();
211 $ttl = $this->getParam('xoauth_token_ttl', false);
212 if ($ttl)
213 {
214 $options['token_ttl'] = $ttl;
215 }
216
217 $verifier = $this->getParam('oauth_verifier', false);
218 if ($verifier) {
219 $options['verifier'] = $verifier;
220 }
221
222 $store = OAuthStore::instance();
223 $token = $store->exchangeConsumerRequestForAccessToken($this->getParam('oauth_token', true), $options);
224 $result = 'oauth_token='.$this->urlencode($token['token'])
225 .'&oauth_token_secret='.$this->urlencode($token['token_secret']);
226
227 if (!empty($token['token_ttl']))
228 {
229 $result .= '&xoauth_token_ttl='.$this->urlencode($token['token_ttl']);
230 }
231
232 header('HTTP/1.1 200 OK');
233 header('Content-Length: '.strlen($result));
234 header('Content-Type: application/x-www-form-urlencoded');
235
236 echo $result;
237 }
238 catch (OAuthException2 $e)
239 {
240 header('HTTP/1.1 401 Access Denied');
241 header('Content-Type: text/plain');
242
243 echo "OAuth Verification Failed: " . $e->getMessage();
244 }
245
246 OAuthRequestLogger::flush();
247 exit();
248 }
249}