Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
/*
3
 * Copyright 2010 Google Inc.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
 
18
if (!class_exists('Google_Client')) {
19
  require_once dirname(__FILE__) . '/autoload.php';
20
}
21
 
22
/**
23
 * The Google API Client
24
 * https://github.com/google/google-api-php-client
25
 */
26
#[AllowDynamicProperties]
27
class Google_Client
28
{
29
  const LIBVER = "1.1.5";
30
  const USER_AGENT_SUFFIX = "google-api-php-client/";
31
  /**
32
   * @var Google_Auth_Abstract $auth
33
   */
34
  private $auth;
35
 
36
  /**
37
   * @var Google_IO_Abstract $io
38
   */
39
  private $io;
40
 
41
  /**
42
   * @var Google_Cache_Abstract $cache
43
   */
44
  private $cache;
45
 
46
  /**
47
   * @var Google_Config $config
48
   */
49
  private $config;
50
 
51
  /**
52
   * @var Google_Logger_Abstract $logger
53
   */
54
  private $logger;
55
 
56
  /**
57
   * @var boolean $deferExecution
58
   */
59
  private $deferExecution = false;
60
 
61
  /** @var array $scopes */
62
  // Scopes requested by the client
63
  protected $requestedScopes = array();
64
 
65
  // definitions of services that are discovered.
66
  protected $services = array();
67
 
68
  // Used to track authenticated state, can't discover services after doing authenticate()
69
  private $authenticated = false;
70
 
71
  /**
72
   * Construct the Google Client.
73
   *
74
   * @param $config Google_Config or string for the ini file to load
75
   */
76
  public function __construct($config = null)
77
  {
78
    if (is_string($config) && strlen($config)) {
79
      $config = new Google_Config($config);
80
    } else if ( !($config instanceof Google_Config)) {
81
      $config = new Google_Config();
82
 
83
      if ($this->isAppEngine()) {
84
        // Automatically use Memcache if we're in AppEngine.
85
        $config->setCacheClass('Google_Cache_Memcache');
86
      }
87
 
88
      if (version_compare(phpversion(), "5.3.4", "<=") || $this->isAppEngine()) {
89
        // Automatically disable compress.zlib, as currently unsupported.
90
        $config->setClassConfig('Google_Http_Request', 'disable_gzip', true);
91
      }
92
    }
93
 
94
    if ($config->getIoClass() == Google_Config::USE_AUTO_IO_SELECTION) {
95
      if (function_exists('curl_version') && function_exists('curl_exec')
96
          && !$this->isAppEngine()) {
97
        $config->setIoClass("Google_IO_Curl");
98
      } else {
99
        $config->setIoClass("Google_IO_Stream");
100
      }
101
    }
102
 
103
    $this->config = $config;
104
  }
105
 
106
  /**
107
   * Get a string containing the version of the library.
108
   *
109
   * @return string
110
   */
111
  public function getLibraryVersion()
112
  {
113
    return self::LIBVER;
114
  }
115
 
116
  /**
117
   * Attempt to exchange a code for an valid authentication token.
118
   * If $crossClient is set to true, the request body will not include
119
   * the request_uri argument
120
   * Helper wrapped around the OAuth 2.0 implementation.
121
   *
122
   * @param $code string code from accounts.google.com
123
   * @param $crossClient boolean, whether this is a cross-client authentication
124
   * @return string token
125
   */
126
  public function authenticate($code, $crossClient = false)
127
  {
128
    $this->authenticated = true;
129
    return $this->getAuth()->authenticate($code, $crossClient);
130
  }
131
 
132
  /**
133
   * Loads a service account key and parameters from a JSON
134
   * file from the Google Developer Console. Uses that and the
135
   * given array of scopes to return an assertion credential for
136
   * use with refreshTokenWithAssertionCredential.
137
   *
138
   * @param string $jsonLocation File location of the project-key.json.
139
   * @param array $scopes The scopes to assert.
140
   * @return Google_Auth_AssertionCredentials.
141
   * @
142
   */
143
  public function loadServiceAccountJson($jsonLocation, $scopes)
144
  {
145
    $data = json_decode(file_get_contents($jsonLocation));
146
    if (isset($data->type) && $data->type == 'service_account') {
147
      // Service Account format.
148
      $cred = new Google_Auth_AssertionCredentials(
149
          $data->client_email,
150
          $scopes,
151
          $data->private_key
152
      );
153
      return $cred;
154
    } else {
155
      throw new Google_Exception("Invalid service account JSON file.");
156
    }
157
  }
158
 
159
  /**
160
   * Set the auth config from the JSON string provided.
161
   * This structure should match the file downloaded from
162
   * the "Download JSON" button on in the Google Developer
163
   * Console.
164
   * @param string $json the configuration json
165
   * @throws Google_Exception
166
   */
167
  public function setAuthConfig($json)
168
  {
169
    $data = json_decode($json);
170
    $key = isset($data->installed) ? 'installed' : 'web';
171
    if (!isset($data->$key)) {
172
      throw new Google_Exception("Invalid client secret JSON file.");
173
    }
174
    $this->setClientId($data->$key->client_id);
175
    $this->setClientSecret($data->$key->client_secret);
176
    if (isset($data->$key->redirect_uris)) {
177
      $this->setRedirectUri($data->$key->redirect_uris[0]);
178
    }
179
  }
180
 
181
  /**
182
   * Set the auth config from the JSON file in the path
183
   * provided. This should match the file downloaded from
184
   * the "Download JSON" button on in the Google Developer
185
   * Console.
186
   * @param string $file the file location of the client json
187
   */
188
  public function setAuthConfigFile($file)
189
  {
190
    $this->setAuthConfig(file_get_contents($file));
191
  }
192
 
193
  /**
194
   * @throws Google_Auth_Exception
195
   * @return array
196
   * @visible For Testing
197
   */
198
  public function prepareScopes()
199
  {
200
    if (empty($this->requestedScopes)) {
201
      throw new Google_Auth_Exception("No scopes specified");
202
    }
203
    $scopes = implode(' ', $this->requestedScopes);
204
    return $scopes;
205
  }
206
 
207
  /**
208
   * Set the OAuth 2.0 access token using the string that resulted from calling createAuthUrl()
209
   * or Google_Client#getAccessToken().
210
   * @param string $accessToken JSON encoded string containing in the following format:
211
   * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
212
   *  "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
213
   */
214
  public function setAccessToken($accessToken)
215
  {
216
    if ($accessToken == 'null') {
217
      $accessToken = null;
218
    }
219
    $this->getAuth()->setAccessToken($accessToken);
220
  }
221
 
222
 
223
 
224
  /**
225
   * Set the authenticator object
226
   * @param Google_Auth_Abstract $auth
227
   */
228
  public function setAuth(Google_Auth_Abstract $auth)
229
  {
230
    $this->config->setAuthClass(get_class($auth));
231
    $this->auth = $auth;
232
  }
233
 
234
  /**
235
   * Set the IO object
236
   * @param Google_IO_Abstract $io
237
   */
238
  public function setIo(Google_IO_Abstract $io)
239
  {
240
    $this->config->setIoClass(get_class($io));
241
    $this->io = $io;
242
  }
243
 
244
  /**
245
   * Set the Cache object
246
   * @param Google_Cache_Abstract $cache
247
   */
248
  public function setCache(Google_Cache_Abstract $cache)
249
  {
250
    $this->config->setCacheClass(get_class($cache));
251
    $this->cache = $cache;
252
  }
253
 
254
  /**
255
   * Set the Logger object
256
   * @param Google_Logger_Abstract $logger
257
   */
258
  public function setLogger(Google_Logger_Abstract $logger)
259
  {
260
    $this->config->setLoggerClass(get_class($logger));
261
    $this->logger = $logger;
262
  }
263
 
264
  /**
265
   * Construct the OAuth 2.0 authorization request URI.
266
   * @return string
267
   */
268
  public function createAuthUrl()
269
  {
270
    $scopes = $this->prepareScopes();
271
    return $this->getAuth()->createAuthUrl($scopes);
272
  }
273
 
274
  /**
275
   * Get the OAuth 2.0 access token.
276
   * @return string $accessToken JSON encoded string in the following format:
277
   * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
278
   *  "expires_in":3600,"id_token":"TOKEN", "created":1320790426}
279
   */
280
  public function getAccessToken()
281
  {
282
    $token = $this->getAuth()->getAccessToken();
283
    // The response is json encoded, so could be the string null.
284
    // It is arguable whether this check should be here or lower
285
    // in the library.
286
    return (null == $token || 'null' == $token || '[]' == $token) ? null : $token;
287
  }
288
 
289
  /**
290
   * Get the OAuth 2.0 refresh token.
291
   * @return string $refreshToken refresh token or null if not available
292
   */
293
  public function getRefreshToken()
294
  {
295
    return $this->getAuth()->getRefreshToken();
296
  }
297
 
298
  /**
299
   * Returns if the access_token is expired.
300
   * @return bool Returns True if the access_token is expired.
301
   */
302
  public function isAccessTokenExpired()
303
  {
304
    return $this->getAuth()->isAccessTokenExpired();
305
  }
306
 
307
  /**
308
   * Set OAuth 2.0 "state" parameter to achieve per-request customization.
309
   * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
310
   * @param string $state
311
   */
312
  public function setState($state)
313
  {
314
    $this->getAuth()->setState($state);
315
  }
316
 
317
  /**
318
   * @param string $accessType Possible values for access_type include:
319
   *  {@code "offline"} to request offline access from the user.
320
   *  {@code "online"} to request online access from the user.
321
   */
322
  public function setAccessType($accessType)
323
  {
324
    $this->config->setAccessType($accessType);
325
  }
326
 
327
  /**
328
   * @param string $approvalPrompt Possible values for approval_prompt include:
329
   *  {@code "force"} to force the approval UI to appear. (This is the default value)
330
   *  {@code "auto"} to request auto-approval when possible.
331
   */
332
  public function setApprovalPrompt($approvalPrompt)
333
  {
334
    $this->config->setApprovalPrompt($approvalPrompt);
335
  }
336
 
337
  /**
338
   * Set the login hint, email address or sub id.
339
   * @param string $loginHint
340
   */
341
  public function setLoginHint($loginHint)
342
  {
343
      $this->config->setLoginHint($loginHint);
344
  }
345
 
346
  /**
347
   * Set the application name, this is included in the User-Agent HTTP header.
348
   * @param string $applicationName
349
   */
350
  public function setApplicationName($applicationName)
351
  {
352
    $this->config->setApplicationName($applicationName);
353
  }
354
 
355
  /**
356
   * Set the OAuth 2.0 Client ID.
357
   * @param string $clientId
358
   */
359
  public function setClientId($clientId)
360
  {
361
    $this->config->setClientId($clientId);
362
  }
363
 
364
  /**
365
   * Set the OAuth 2.0 Client Secret.
366
   * @param string $clientSecret
367
   */
368
  public function setClientSecret($clientSecret)
369
  {
370
    $this->config->setClientSecret($clientSecret);
371
  }
372
 
373
  /**
374
   * Set the OAuth 2.0 Redirect URI.
375
   * @param string $redirectUri
376
   */
377
  public function setRedirectUri($redirectUri)
378
  {
379
    $this->config->setRedirectUri($redirectUri);
380
  }
381
 
382
  /**
383
   * If 'plus.login' is included in the list of requested scopes, you can use
384
   * this method to define types of app activities that your app will write.
385
   * You can find a list of available types here:
386
   * @link https://developers.google.com/+/api/moment-types
387
   *
388
   * @param array $requestVisibleActions Array of app activity types
389
   */
390
  public function setRequestVisibleActions($requestVisibleActions)
391
  {
392
    if (is_array($requestVisibleActions)) {
393
      $requestVisibleActions = join(" ", $requestVisibleActions);
394
    }
395
    $this->config->setRequestVisibleActions($requestVisibleActions);
396
  }
397
 
398
  /**
399
   * Set the developer key to use, these are obtained through the API Console.
400
   * @see http://code.google.com/apis/console-help/#generatingdevkeys
401
   * @param string $developerKey
402
   */
403
  public function setDeveloperKey($developerKey)
404
  {
405
    $this->config->setDeveloperKey($developerKey);
406
  }
407
 
408
  /**
409
   * Set the hd (hosted domain) parameter streamlines the login process for
410
   * Google Apps hosted accounts. By including the domain of the user, you
411
   * restrict sign-in to accounts at that domain.
412
   * @param $hd string - the domain to use.
413
   */
414
  public function setHostedDomain($hd)
415
  {
416
    $this->config->setHostedDomain($hd);
417
  }
418
 
419
  /**
420
   * Set the prompt hint. Valid values are none, consent and select_account.
421
   * If no value is specified and the user has not previously authorized
422
   * access, then the user is shown a consent screen.
423
   * @param $prompt string
424
   */
425
  public function setPrompt($prompt)
426
  {
427
    $this->config->setPrompt($prompt);
428
  }
429
 
430
  /**
431
   * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth
432
   * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which
433
   * an authentication request is valid.
434
   * @param $realm string - the URL-space to use.
435
   */
436
  public function setOpenidRealm($realm)
437
  {
438
    $this->config->setOpenidRealm($realm);
439
  }
440
 
441
  /**
442
   * If this is provided with the value true, and the authorization request is
443
   * granted, the authorization will include any previous authorizations
444
   * granted to this user/application combination for other scopes.
445
   * @param $include boolean - the URL-space to use.
446
   */
447
  public function setIncludeGrantedScopes($include)
448
  {
449
    $this->config->setIncludeGrantedScopes($include);
450
  }
451
 
452
  /**
453
   * Fetches a fresh OAuth 2.0 access token with the given refresh token.
454
   * @param string $refreshToken
455
   */
456
  public function refreshToken($refreshToken)
457
  {
458
    $this->getAuth()->refreshToken($refreshToken);
459
  }
460
 
461
  /**
462
   * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
463
   * token, if a token isn't provided.
464
   * @throws Google_Auth_Exception
465
   * @param string|null $token The token (access token or a refresh token) that should be revoked.
466
   * @return boolean Returns True if the revocation was successful, otherwise False.
467
   */
468
  public function revokeToken($token = null)
469
  {
470
    return $this->getAuth()->revokeToken($token);
471
  }
472
 
473
  /**
474
   * Verify an id_token. This method will verify the current id_token, if one
475
   * isn't provided.
476
   * @throws Google_Auth_Exception
477
   * @param string|null $token The token (id_token) that should be verified.
478
   * @return Google_Auth_LoginTicket Returns an apiLoginTicket if the verification was
479
   * successful.
480
   */
481
  public function verifyIdToken($token = null)
482
  {
483
    return $this->getAuth()->verifyIdToken($token);
484
  }
485
 
486
  /**
487
   * Verify a JWT that was signed with your own certificates.
488
   *
489
   * @param $id_token string The JWT token
490
   * @param $cert_location array of certificates
491
   * @param $audience string the expected consumer of the token
492
   * @param $issuer string the expected issuer, defaults to Google
493
   * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS
494
   * @return mixed token information if valid, false if not
495
   */
496
  public function verifySignedJwt($id_token, $cert_location, $audience, $issuer, $max_expiry = null)
497
  {
498
    $auth = new Google_Auth_OAuth2($this);
499
    $certs = $auth->retrieveCertsFromLocation($cert_location);
500
    return $auth->verifySignedJwtWithCerts($id_token, $certs, $audience, $issuer, $max_expiry);
501
  }
502
 
503
  /**
504
   * @param $creds Google_Auth_AssertionCredentials
505
   */
506
  public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds)
507
  {
508
    $this->getAuth()->setAssertionCredentials($creds);
509
  }
510
 
511
  /**
512
   * Set the scopes to be requested. Must be called before createAuthUrl().
513
   * Will remove any previously configured scopes.
514
   * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.login',
515
   * 'https://www.googleapis.com/auth/moderator')
516
   */
517
  public function setScopes($scopes)
518
  {
519
    $this->requestedScopes = array();
520
    $this->addScope($scopes);
521
  }
522
 
523
  /**
524
   * This functions adds a scope to be requested as part of the OAuth2.0 flow.
525
   * Will append any scopes not previously requested to the scope parameter.
526
   * A single string will be treated as a scope to request. An array of strings
527
   * will each be appended.
528
   * @param $scope_or_scopes string|array e.g. "profile"
529
   */
530
  public function addScope($scope_or_scopes)
531
  {
532
    if (is_string($scope_or_scopes) && !in_array($scope_or_scopes, $this->requestedScopes)) {
533
      $this->requestedScopes[] = $scope_or_scopes;
534
    } else if (is_array($scope_or_scopes)) {
535
      foreach ($scope_or_scopes as $scope) {
536
        $this->addScope($scope);
537
      }
538
    }
539
  }
540
 
541
  /**
542
   * Returns the list of scopes requested by the client
543
   * @return array the list of scopes
544
   *
545
   */
546
  public function getScopes()
547
  {
548
     return $this->requestedScopes;
549
  }
550
 
551
  /**
552
   * Declare whether batch calls should be used. This may increase throughput
553
   * by making multiple requests in one connection.
554
   *
555
   * @param boolean $useBatch True if the batch support should
556
   * be enabled. Defaults to False.
557
   */
558
  public function setUseBatch($useBatch)
559
  {
560
    // This is actually an alias for setDefer.
561
    $this->setDefer($useBatch);
562
  }
563
 
564
  /**
565
   * Declare whether making API calls should make the call immediately, or
566
   * return a request which can be called with ->execute();
567
   *
568
   * @param boolean $defer True if calls should not be executed right away.
569
   */
570
  public function setDefer($defer)
571
  {
572
    $this->deferExecution = $defer;
573
  }
574
 
575
  /**
576
   * Helper method to execute deferred HTTP requests.
577
   *
578
   * @param $request Google_Http_Request|Google_Http_Batch
579
   * @throws Google_Exception
580
   * @return object of the type of the expected class or array.
581
   */
582
  public function execute($request)
583
  {
584
    if ($request instanceof Google_Http_Request) {
585
      $request->setUserAgent(
586
          $this->getApplicationName()
587
          . " " . self::USER_AGENT_SUFFIX
588
          . $this->getLibraryVersion()
589
      );
590
      if (!$this->getClassConfig("Google_Http_Request", "disable_gzip")) {
591
        $request->enableGzip();
592
      }
593
      $request->maybeMoveParametersToBody();
594
      return Google_Http_REST::execute($this, $request);
595
    } else if ($request instanceof Google_Http_Batch) {
596
      return $request->execute();
597
    } else {
598
      throw new Google_Exception("Do not know how to execute this type of object.");
599
    }
600
  }
601
 
602
  /**
603
   * Whether or not to return raw requests
604
   * @return boolean
605
   */
606
  public function shouldDefer()
607
  {
608
    return $this->deferExecution;
609
  }
610
 
611
  /**
612
   * @return Google_Auth_Abstract Authentication implementation
613
   */
614
  public function getAuth()
615
  {
616
    if (!isset($this->auth)) {
617
      $class = $this->config->getAuthClass();
618
      $this->auth = new $class($this);
619
    }
620
    return $this->auth;
621
  }
622
 
623
  /**
624
   * @return Google_IO_Abstract IO implementation
625
   */
626
  public function getIo()
627
  {
628
    if (!isset($this->io)) {
629
      $class = $this->config->getIoClass();
630
      $this->io = new $class($this);
631
    }
632
    return $this->io;
633
  }
634
 
635
  /**
636
   * @return Google_Cache_Abstract Cache implementation
637
   */
638
  public function getCache()
639
  {
640
    if (!isset($this->cache)) {
641
      $class = $this->config->getCacheClass();
642
      $this->cache = new $class($this);
643
    }
644
    return $this->cache;
645
  }
646
 
647
  /**
648
   * @return Google_Logger_Abstract Logger implementation
649
   */
650
  public function getLogger()
651
  {
652
    if (!isset($this->logger)) {
653
      $class = $this->config->getLoggerClass();
654
      $this->logger = new $class($this);
655
    }
656
    return $this->logger;
657
  }
658
 
659
  /**
660
   * Retrieve custom configuration for a specific class.
661
   * @param $class string|object - class or instance of class to retrieve
662
   * @param $key string optional - key to retrieve
663
   * @return array
664
   */
665
  public function getClassConfig($class, $key = null)
666
  {
667
    if (!is_string($class)) {
668
      $class = get_class($class);
669
    }
670
    return $this->config->getClassConfig($class, $key);
671
  }
672
 
673
  /**
674
   * Set configuration specific to a given class.
675
   * $config->setClassConfig('Google_Cache_File',
676
   *   array('directory' => '/tmp/cache'));
677
   * @param $class string|object - The class name for the configuration
678
   * @param $config string key or an array of configuration values
679
   * @param $value string optional - if $config is a key, the value
680
   *
681
   */
682
  public function setClassConfig($class, $config, $value = null)
683
  {
684
    if (!is_string($class)) {
685
      $class = get_class($class);
686
    }
687
    $this->config->setClassConfig($class, $config, $value);
688
 
689
  }
690
 
691
  /**
692
   * @return string the base URL to use for calls to the APIs
693
   */
694
  public function getBasePath()
695
  {
696
    return $this->config->getBasePath();
697
  }
698
 
699
  /**
700
   * @return string the name of the application
701
   */
702
  public function getApplicationName()
703
  {
704
    return $this->config->getApplicationName();
705
  }
706
 
707
  /**
708
   * Are we running in Google AppEngine?
709
   * return bool
710
   */
711
  public function isAppEngine()
712
  {
713
    return (isset($_SERVER['SERVER_SOFTWARE']) &&
714
        strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false);
715
  }
716
}