Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
 
18
defined('MOODLE_INTERNAL') || die();
19
 
20
require_once($CFG->libdir.'/filelib.php');
21
 
22
/**
23
 * OAuth helper class
24
 *
25
 * 1. You can extends oauth_helper to add specific functions, such as twitter extends oauth_helper
26
 * 2. Call request_token method to get oauth_token and oauth_token_secret, and redirect user to authorize_url,
27
 *    developer needs to store oauth_token and oauth_token_secret somewhere, we will use them to request
28
 *    access token later on
29
 * 3. User approved the request, and get back to moodle
30
 * 4. Call get_access_token, it takes previous oauth_token and oauth_token_secret as arguments, oauth_token
31
 *    will be used in OAuth request, oauth_token_secret will be used to bulid signature, this method will
32
 *    return access_token and access_secret, store these two values in database or session
33
 * 5. Now you can access oauth protected resources by access_token and access_secret using oauth_helper::request
34
 *    method (or get() post())
35
 *
36
 * Note:
37
 * 1. This class only support HMAC-SHA1
38
 * 2. oauth_helper class don't store tokens and secrets, you must store them manually
39
 * 3. Some functions are based on http://code.google.com/p/oauth/
40
 *
41
 * @package    moodlecore
42
 * @copyright  2010 Dongsheng Cai <dongsheng@moodle.com>
43
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
44
 */
45
 
46
class oauth_helper {
47
    /** @var string consumer key, issued by oauth provider*/
48
    protected $consumer_key;
49
    /** @var string consumer secret, issued by oauth provider*/
50
    protected $consumer_secret;
51
    /** @var string oauth root*/
52
    protected $api_root;
53
    /** @var string request token url*/
54
    protected $request_token_api;
55
    /** @var string authorize url*/
56
    protected $authorize_url;
57
    protected $http_method;
58
    /** @var string */
59
    protected $access_token_api;
60
    /** @var curl */
61
    protected $http;
62
    /** @var array options to pass to the next curl request */
63
    protected $http_options;
64
    /** @var moodle_url oauth callback URL. */
65
    protected $oauth_callback;
66
     /** @var string access token. */
67
    protected $access_token;
68
    /** @var  string access secret token. */
69
    protected $access_token_secret;
70
    /** @var  string sign secret. */
71
    protected $sign_secret;
72
    /** @var  string nonce. */
73
    protected $nonce;
74
    /** @var  int timestamp. */
75
    protected $timestamp;
76
 
77
 
78
    /**
79
     * Contructor for oauth_helper.
80
     * Subclass can override construct to build its own $this->http
81
     *
82
     * @param array $args requires at least three keys, oauth_consumer_key
83
     *                    oauth_consumer_secret and api_root, oauth_helper will
84
     *                    guess request_token_api, authrize_url and access_token_api
85
     *                    based on api_root, but it not always works
86
     */
87
    function __construct($args) {
88
        if (!empty($args['api_root'])) {
89
            $this->api_root = $args['api_root'];
90
        } else {
91
            $this->api_root = '';
92
        }
93
        $this->consumer_key = $args['oauth_consumer_key'];
94
        $this->consumer_secret = $args['oauth_consumer_secret'];
95
 
96
        if (empty($args['request_token_api'])) {
97
            $this->request_token_api = $this->api_root . '/request_token';
98
        } else {
99
            $this->request_token_api = $args['request_token_api'];
100
        }
101
 
102
        if (empty($args['authorize_url'])) {
103
            $this->authorize_url = $this->api_root . '/authorize';
104
        } else {
105
            $this->authorize_url = $args['authorize_url'];
106
        }
107
 
108
        if (empty($args['access_token_api'])) {
109
            $this->access_token_api = $this->api_root . '/access_token';
110
        } else {
111
            $this->access_token_api = $args['access_token_api'];
112
        }
113
 
114
        if (!empty($args['oauth_callback'])) {
115
            $this->oauth_callback = new moodle_url($args['oauth_callback']);
116
        }
117
        if (!empty($args['access_token'])) {
118
            $this->access_token = $args['access_token'];
119
        }
120
        if (!empty($args['access_token_secret'])) {
121
            $this->access_token_secret = $args['access_token_secret'];
122
        }
123
        $this->http = new curl(array('debug'=>false));
124
        if (!empty($args['http_options'])) {
125
            $this->http_options = $args['http_options'];
126
        } else {
127
            $this->http_options = array();
128
        }
129
    }
130
 
131
    /**
132
     * Build parameters list:
133
     *    oauth_consumer_key="0685bd9184jfhq22",
134
     *    oauth_nonce="4572616e48616d6d65724c61686176",
135
     *    oauth_token="ad180jjd733klru7",
136
     *    oauth_signature_method="HMAC-SHA1",
137
     *    oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",
138
     *    oauth_timestamp="137131200",
139
     *    oauth_version="1.0"
140
     *    oauth_verifier="1.0"
141
     * @param array $param
142
     * @return string
143
     */
144
    function get_signable_parameters($params){
145
        $sorted = $params;
146
        ksort($sorted);
147
 
148
        $total = array();
149
        foreach ($sorted as $k => $v) {
150
            if ($k == 'oauth_signature') {
151
                continue;
152
            }
153
 
154
            $total[] = rawurlencode($k) . '=' . rawurlencode($v);
155
        }
156
        return implode('&', $total);
157
    }
158
 
159
    /**
160
     * Create signature for oauth request
161
     * @param string $url
162
     * @param string $secret
163
     * @param array $params
164
     * @return string
165
     */
166
    public function sign($http_method, $url, $params, $secret) {
167
        $sig = array(
168
            strtoupper($http_method),
169
            preg_replace('/%7E/', '~', rawurlencode($url)),
170
            rawurlencode($this->get_signable_parameters($params)),
171
        );
172
 
173
        $base_string = implode('&', $sig);
174
        $sig = base64_encode(hash_hmac('sha1', $base_string, $secret, true));
175
        return $sig;
176
    }
177
 
178
    /**
179
     * Initilize oauth request parameters, including:
180
     *    oauth_consumer_key="0685bd9184jfhq22",
181
     *    oauth_token="ad180jjd733klru7",
182
     *    oauth_signature_method="HMAC-SHA1",
183
     *    oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",
184
     *    oauth_timestamp="137131200",
185
     *    oauth_nonce="4572616e48616d6d65724c61686176",
186
     *    oauth_version="1.0"
187
     * To access protected resources, oauth_token should be defined
188
     *
189
     * @param string $url
190
     * @param string $token
191
     * @param string $http_method
192
     * @return array
193
     */
194
    public function prepare_oauth_parameters($url, $params, $http_method = 'POST') {
195
        if (is_array($params)) {
196
            $oauth_params = $params;
197
        } else {
198
            $oauth_params = array();
199
        }
200
        $oauth_params['oauth_version']	    = '1.0';
201
        $oauth_params['oauth_nonce']	    = $this->get_nonce();
202
        $oauth_params['oauth_timestamp']    = $this->get_timestamp();
203
        $oauth_params['oauth_consumer_key'] = $this->consumer_key;
204
        $oauth_params['oauth_signature_method']	= 'HMAC-SHA1';
205
        $oauth_params['oauth_signature']	= $this->sign($http_method, $url, $oauth_params, $this->sign_secret);
206
        return $oauth_params;
207
    }
208
 
209
    public function setup_oauth_http_header($params) {
210
 
211
        $total = array();
212
        ksort($params);
213
        foreach ($params as $k => $v) {
214
            $total[] = rawurlencode($k) . '="' . rawurlencode($v).'"';
215
        }
216
        $str = implode(', ', $total);
217
        $str = 'Authorization: OAuth '.$str;
218
        $this->http->setHeader('Expect:');
219
        $this->http->setHeader($str);
220
    }
221
 
222
    /**
223
     * Sets the options for the next curl request
224
     *
225
     * @param array $options
226
     */
227
    public function setup_oauth_http_options($options) {
228
        $this->http_options = $options;
229
    }
230
 
231
    /**
232
     * Request token for authentication
233
     * This is the first step to use OAuth, it will return oauth_token and oauth_token_secret
234
     * @return array
235
     */
236
    public function request_token() {
237
        $this->sign_secret = $this->consumer_secret.'&';
238
 
239
        if (empty($this->oauth_callback)) {
240
            $params = [];
241
        } else {
242
            $params = ['oauth_callback' => $this->oauth_callback->out(false)];
243
        }
244
 
245
        $params = $this->prepare_oauth_parameters($this->request_token_api, $params, 'GET');
246
        $content = $this->http->get($this->request_token_api, $params, $this->http_options);
247
        // Including:
248
        //     oauth_token
249
        //     oauth_token_secret
250
        $result = $this->parse_result($content);
251
        if (empty($result['oauth_token'])) {
252
            throw new moodle_exception('oauth1requesttoken', 'core_error', '', null, $content);
253
        }
254
        // Build oauth authorize url.
255
        $result['authorize_url'] = $this->authorize_url . '?oauth_token='.$result['oauth_token'];
256
 
257
        return $result;
258
    }
259
 
260
    /**
261
     * Set oauth access token for oauth request
262
     * @param string $token
263
     * @param string $secret
264
     */
265
    public function set_access_token($token, $secret) {
266
        $this->access_token = $token;
267
        $this->access_token_secret = $secret;
268
    }
269
 
270
    /**
271
     * Request oauth access token from server
272
     * @param string $method
273
     * @param string $url
274
     * @param string $token
275
     * @param string $secret
276
     */
277
    public function get_access_token($token, $secret, $verifier='') {
278
        $this->sign_secret = $this->consumer_secret.'&'.$secret;
279
        $params = $this->prepare_oauth_parameters($this->access_token_api, array('oauth_token'=>$token, 'oauth_verifier'=>$verifier), 'POST');
280
        $this->setup_oauth_http_header($params);
281
        // Should never send the callback in this request.
282
        unset($params['oauth_callback']);
283
        $content = $this->http->post($this->access_token_api, $params, $this->http_options);
284
        $keys = $this->parse_result($content);
285
 
286
        if (empty($keys['oauth_token']) || empty($keys['oauth_token_secret'])) {
287
            throw new moodle_exception('oauth1accesstoken', 'core_error', '', null, $content);
288
        }
289
 
290
        $this->set_access_token($keys['oauth_token'], $keys['oauth_token_secret']);
291
        return $keys;
292
    }
293
 
294
    /**
295
     * Request oauth protected resources
296
     * @param string $method
297
     * @param string $url
298
     * @param string $token
299
     * @param string $secret
300
     */
301
    public function request($method, $url, $params=array(), $token='', $secret='') {
302
        if (empty($token)) {
303
            $token = $this->access_token;
304
        }
305
        if (empty($secret)) {
306
            $secret = $this->access_token_secret;
307
        }
308
        // to access protected resource, sign_secret will alwasy be consumer_secret+token_secret
309
        $this->sign_secret = $this->consumer_secret.'&'.$secret;
310
        if (strtolower($method) === 'post' && !empty($params)) {
311
            $oauth_params = $this->prepare_oauth_parameters($url, array('oauth_token'=>$token) + $params, $method);
312
        } else {
313
            $oauth_params = $this->prepare_oauth_parameters($url, array('oauth_token'=>$token), $method);
314
        }
315
        $this->setup_oauth_http_header($oauth_params);
316
        $content = call_user_func_array(array($this->http, strtolower($method)), array($url, $params, $this->http_options));
317
        // reset http header and options to prepare for the next request
318
        $this->http->resetHeader();
319
        // return request return value
320
        return $content;
321
    }
322
 
323
    /**
324
     * shortcut to start http get request
325
     */
326
    public function get($url, $params=array(), $token='', $secret='') {
327
        return $this->request('GET', $url, $params, $token, $secret);
328
    }
329
 
330
    /**
331
     * shortcut to start http post request
332
     */
333
    public function post($url, $params=array(), $token='', $secret='') {
334
        return $this->request('POST', $url, $params, $token, $secret);
335
    }
336
 
337
    /**
338
     * A method to parse oauth response to get oauth_token and oauth_token_secret
339
     * @param string $str
340
     * @return array
341
     */
342
    public function parse_result($str) {
343
        if (empty($str)) {
344
            throw new moodle_exception('error');
345
        }
346
        $parts = explode('&', $str);
347
        $result = array();
348
        foreach ($parts as $part){
349
            list($k, $v) = explode('=', $part, 2);
350
            $result[urldecode($k)] = urldecode($v);
351
        }
352
        if (empty($result)) {
353
            throw new moodle_exception('error');
354
        }
355
        return $result;
356
    }
357
 
358
    /**
359
     * Set nonce
360
     */
361
    function set_nonce($str) {
362
        $this->nonce = $str;
363
    }
364
    /**
365
     * Set timestamp
366
     */
367
    function set_timestamp($time) {
368
        $this->timestamp = $time;
369
    }
370
    /**
371
     * Generate timestamp
372
     */
373
    function get_timestamp() {
374
        if (!empty($this->timestamp)) {
375
            $timestamp = $this->timestamp;
376
            unset($this->timestamp);
377
            return $timestamp;
378
        }
379
        return time();
380
    }
381
    /**
382
     * Generate nonce for oauth request
383
     */
384
    function get_nonce() {
385
        if (!empty($this->nonce)) {
386
            $nonce = $this->nonce;
387
            unset($this->nonce);
388
            return $nonce;
389
        }
390
        $mt = microtime();
391
        $rand = mt_rand();
392
 
393
        return md5($mt . $rand);
394
    }
395
}
396
 
397
/**
398
 * OAuth 2.0 Client for using web access tokens.
399
 *
400
 * http://tools.ietf.org/html/draft-ietf-oauth-v2-22
401
 *
402
 * @package   core
403
 * @copyright Dan Poltawski <talktodan@gmail.com>
404
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
405
 */
406
abstract class oauth2_client extends curl {
407
    /** @var string $clientid client identifier issued to the client */
408
    private $clientid = '';
409
    /** @var string $clientsecret The client secret. */
410
    private $clientsecret = '';
411
    /** @var moodle_url $returnurl URL to return to after authenticating */
412
    private $returnurl = null;
413
    /** @var string $scope of the authentication request */
414
    protected $scope = '';
415
    /** @var stdClass $accesstoken access token object */
416
    protected $accesstoken = null;
417
    /** @var string $refreshtoken refresh token string */
418
    protected $refreshtoken = '';
419
    /** @var string $mocknextresponse string */
420
    private $mocknextresponse = '';
421
    /** @var array $upgradedcodes list of upgraded codes in this request */
422
    private static $upgradedcodes = [];
423
    /** @var bool basicauth */
424
    protected $basicauth = false;
425
 
426
    /**
427
     * Returns the auth url for OAuth 2.0 request
428
     * @return string the auth url
429
     */
430
    abstract protected function auth_url();
431
 
432
    /**
433
     * Returns the token url for OAuth 2.0 request
434
     * @return string the auth url
435
     */
436
    abstract protected function token_url();
437
 
438
    /**
439
     * Constructor.
440
     *
441
     * @param string $clientid
442
     * @param string $clientsecret
443
     * @param moodle_url $returnurl
444
     * @param string $scope
445
     */
446
    public function __construct($clientid, $clientsecret, moodle_url $returnurl, $scope) {
447
        parent::__construct();
448
        $this->clientid = $clientid;
449
        $this->clientsecret = $clientsecret;
450
        $this->returnurl = $returnurl;
451
        $this->scope = $scope;
452
        $this->accesstoken = $this->get_stored_token();
453
    }
454
 
455
    /**
456
     * Is the user logged in? Note that if this is called
457
     * after the first part of the authorisation flow the token
458
     * is upgraded to an accesstoken.
459
     *
460
     * @return boolean true if logged in
461
     */
462
    public function is_logged_in() {
463
        // Has the token expired?
464
        if (isset($this->accesstoken->expires) && time() >= $this->accesstoken->expires) {
465
            $this->store_token(null);
466
            return false;
467
        }
468
 
469
        // We have a token so we are logged in.
470
        if (isset($this->accesstoken->token)) {
471
            // Check that the access token has all the requested scopes.
472
            $scopemissing = false;
473
            $scopecheck = ' ' . $this->accesstoken->scope . ' ';
474
 
475
            $requiredscopes = explode(' ', $this->scope);
476
            foreach ($requiredscopes as $requiredscope) {
477
                if (strpos($scopecheck, ' ' . $requiredscope . ' ') === false) {
478
                    $scopemissing = true;
479
                    break;
480
                }
481
            }
482
            if (!$scopemissing) {
483
                return true;
484
            }
485
        }
486
 
487
        // If we've been passed then authorization code generated by the
488
        // authorization server try and upgrade the token to an access token.
489
        $code = optional_param('oauth2code', null, PARAM_RAW);
490
        // Note - sometimes we may call is_logged_in twice in the same request - we don't want to attempt
491
        // to upgrade the same token twice.
492
        if ($code && !in_array($code, self::$upgradedcodes) && $this->upgrade_token($code)) {
493
            return true;
494
        }
495
 
496
        return false;
497
    }
498
 
499
    /**
500
     * Callback url where the request is returned to.
501
     *
502
     * @return moodle_url url of callback
503
     */
504
    public static function callback_url() {
505
        global $CFG;
506
 
507
        return new moodle_url('/admin/oauth2callback.php');
508
    }
509
 
510
    /**
511
     * An additional array of url params to pass with a login request.
512
     *
513
     * @return array of name value pairs.
514
     */
515
    public function get_additional_login_parameters() {
516
        return [];
517
    }
518
 
519
    /**
520
     * Returns the login link for this oauth request
521
     *
522
     * @return moodle_url login url
523
     */
524
    public function get_login_url() {
525
 
526
        $callbackurl = self::callback_url();
527
        $defaultparams = [
528
            'client_id' => $this->clientid,
529
            'response_type' => 'code',
530
            'redirect_uri' => $callbackurl->out(false),
531
            'state' => $this->returnurl->out_as_local_url(false),
532
 
533
        ];
534
        if (!empty($this->scope)) {
535
            // The scope should only be included if a value is set.
536
            // If none provided, the server MUST process the request and provide an appropriate documented response.
537
            // See spec https://tools.ietf.org/html/rfc6749#section-3.3
538
            $defaultparams['scope'] = $this->scope;
539
        }
540
 
541
        $params = array_merge(
542
            $defaultparams,
543
            $this->get_additional_login_parameters()
544
        );
545
 
546
        return new moodle_url($this->auth_url(), $params);
547
    }
548
 
549
    /**
550
     * Given an array of name value pairs - build a valid HTTP POST application/x-www-form-urlencoded string.
551
     *
552
     * @param array $params Name / value pairs.
553
     * @return string POST data.
554
     */
555
    public function build_post_data($params) {
556
        $result = [];
557
        foreach ($params as $name => $value) {
558
            $result[] = urlencode($name) . '=' . urlencode($value);
559
        }
560
        return implode('&', $result);
561
    }
562
 
563
    /**
564
     * Upgrade a authorization token from oauth 2.0 to an access token
565
     *
566
     * @param string $code the code returned from the oauth authenticaiton
567
     * @return boolean true if token is upgraded succesfully
568
     */
569
    public function upgrade_token($code) {
570
        $callbackurl = self::callback_url();
571
        $params = array('code' => $code,
572
            'grant_type' => 'authorization_code',
573
            'redirect_uri' => $callbackurl->out(false),
574
        );
575
 
576
        if ($this->basicauth) {
577
            $idsecret = urlencode($this->clientid) . ':' . urlencode($this->clientsecret);
578
            $this->setHeader('Authorization: Basic ' . base64_encode($idsecret));
579
        } else {
580
            $params['client_id'] = $this->clientid;
581
            $params['client_secret'] = $this->clientsecret;
582
        }
583
 
584
        // Requests can either use http GET or POST.
585
        if ($this->use_http_get()) {
586
            $response = $this->get($this->token_url(), $params);
587
        } else {
588
            $response = $this->post($this->token_url(), $this->build_post_data($params));
589
        }
590
 
591
        if ($this->info['http_code'] !== 200) {
592
            $debuginfo = !empty($this->error) ? $this->error : $response;
593
            throw new moodle_exception('oauth2upgradetokenerror', 'core_error', '', $this->info['http_code'], $debuginfo);
594
        }
595
 
596
        $r = json_decode($response);
597
 
598
        if (is_null($r)) {
599
            throw new moodle_exception("Could not decode JSON token response");
600
        }
601
 
602
        if (!empty($r->error)) {
603
            throw new moodle_exception($r->error . ' ' . $r->error_description);
604
        }
605
 
606
        if (!isset($r->access_token)) {
607
            return false;
608
        }
609
 
610
        if (isset($r->refresh_token)) {
611
            $this->refreshtoken = $r->refresh_token;
612
        }
613
 
614
        // Store the token an expiry time.
615
        $accesstoken = new stdClass;
616
        $accesstoken->token = $r->access_token;
617
        if (isset($r->expires_in)) {
618
            // Expires 10 seconds before actual expiry.
619
            $accesstoken->expires = (time() + ($r->expires_in - 10));
620
        }
621
        $accesstoken->scope = $this->scope;
622
        // Also add the scopes.
623
        self::$upgradedcodes[] = $code;
624
        $this->store_token($accesstoken);
625
 
626
        return true;
627
    }
628
 
629
    /**
630
     * Logs out of a oauth request, clearing any stored tokens
631
     */
632
    public function log_out() {
633
        $this->store_token(null);
634
    }
635
 
636
    /**
637
     * Make a HTTP request, adding the access token we have
638
     *
639
     * @param string $url The URL to request
640
     * @param array $options
641
     * @param mixed $acceptheader mimetype (as string) or false to skip sending an accept header.
642
     * @return string
643
     */
644
    protected function request($url, $options = array(), $acceptheader = 'application/json') {
645
        $murl = new moodle_url($url);
646
 
647
        if ($this->accesstoken) {
648
            if ($this->use_http_get()) {
649
                // If using HTTP GET add as a parameter.
650
                $murl->param('access_token', $this->accesstoken->token);
651
            } else {
652
                $this->setHeader('Authorization: Bearer '.$this->accesstoken->token);
653
            }
654
        }
655
 
656
        if ($acceptheader) {
657
            $this->setHeader('Accept: ' . $acceptheader);
658
        }
659
 
660
        $response = parent::request($murl->out(false), $options);
661
 
662
        $this->resetHeader();
663
 
664
        return $response;
665
    }
666
 
667
    /**
668
     * Multiple HTTP Requests
669
     * This function could run multi-requests in parallel.
670
     *
671
     * @param array $requests An array of files to request
672
     * @param array $options An array of options to set
673
     * @return array An array of results
674
     */
675
    protected function multi($requests, $options = array()) {
676
        if ($this->accesstoken) {
677
            $this->setHeader('Authorization: Bearer '.$this->accesstoken->token);
678
        }
679
        return parent::multi($requests, $options);
680
    }
681
 
682
    /**
683
     * Returns the tokenname for the access_token to be stored
684
     * through multiple requests.
685
     *
686
     * The default implentation is to use the classname combiend
687
     * with the scope.
688
     *
689
     * @return string tokenname for prefernce storage
690
     */
691
    protected function get_tokenname() {
692
        // This is unusual but should work for most purposes.
693
        return get_class($this).'-'.md5($this->scope);
694
    }
695
 
696
    /**
697
     * Store a token between requests. Currently uses
698
     * session named by get_tokenname
699
     *
700
     * @param stdClass|null $token token object to store or null to clear
701
     */
702
    protected function store_token($token) {
703
        global $SESSION;
704
 
705
        $this->accesstoken = $token;
706
        $name = $this->get_tokenname();
707
 
708
        if ($token !== null) {
709
            $SESSION->{$name} = $token;
710
        } else {
711
            unset($SESSION->{$name});
712
        }
713
    }
714
 
715
    /**
716
     * Get a refresh token!!!
717
     *
718
     * @return string
719
     */
720
    public function get_refresh_token() {
721
        return $this->refreshtoken;
722
    }
723
 
724
    /**
725
     * Retrieve a token stored.
726
     *
727
     * @return stdClass|null token object
728
     */
729
    protected function get_stored_token() {
730
        global $SESSION;
731
 
732
        $name = $this->get_tokenname();
733
 
734
        if (isset($SESSION->{$name})) {
735
            return $SESSION->{$name};
736
        }
737
 
738
        return null;
739
    }
740
 
741
    /**
742
     * Get access token object.
743
     *
744
     * This is just a getter to read the private property.
745
     *
746
     * @return stdClass
747
     */
748
    public function get_accesstoken() {
749
        return $this->accesstoken;
750
    }
751
 
752
    /**
753
     * Get the client ID.
754
     *
755
     * This is just a getter to read the private property.
756
     *
757
     * @return string
758
     */
759
    public function get_clientid() {
760
        return $this->clientid;
761
    }
762
 
763
    /**
764
     * Get the client secret.
765
     *
766
     * This is just a getter to read the private property.
767
     *
768
     * @return string
769
     */
770
    public function get_clientsecret() {
771
        return $this->clientsecret;
772
    }
773
 
774
    /**
775
     * Should HTTP GET be used instead of POST?
776
     * Some APIs do not support POST and want oauth to use
777
     * GET instead (with the auth_token passed as a GET param).
778
     *
779
     * @return bool true if GET should be used
780
     */
781
    protected function use_http_get() {
782
        return false;
783
    }
784
}