Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 400 and 402] [Versions 400 and 403]

   1  <?php
   2  /*
   3   * Copyright 2014 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  /*
  19   * WARNING - this class depends on the Google App Engine PHP library
  20   * which is 5.3 and above only, so if you include this in a PHP 5.2
  21   * setup or one without 5.3 things will blow up.
  22   */
  23  use google\appengine\api\app_identity\AppIdentityService;
  24  
  25  if (!class_exists('Google_Client')) {
  26    require_once dirname(__FILE__) . '/../autoload.php';
  27  }
  28  
  29  /**
  30   * Authentication via the Google App Engine App Identity service.
  31   */
  32  class Google_Auth_AppIdentity extends Google_Auth_Abstract
  33  {
  34    const CACHE_PREFIX = "Google_Auth_AppIdentity::";
  35    private $client;
  36    private $token = false;
  37    private $tokenScopes = false;
  38  
  39    public function __construct(Google_Client $client, $config = null)
  40    {
  41      $this->client = $client;
  42    }
  43  
  44    /**
  45     * Retrieve an access token for the scopes supplied.
  46     */
  47    public function authenticateForScope($scopes)
  48    {
  49      if ($this->token && $this->tokenScopes == $scopes) {
  50        return $this->token;
  51      }
  52  
  53      $cacheKey = self::CACHE_PREFIX;
  54      if (is_string($scopes)) {
  55        $cacheKey .= $scopes;
  56      } else if (is_array($scopes)) {
  57        $cacheKey .= implode(":", $scopes);
  58      }
  59  
  60      $this->token = $this->client->getCache()->get($cacheKey);
  61      if (!$this->token) {
  62        $this->retrieveToken($scopes, $cacheKey);
  63      } else if ($this->token['expiration_time'] < time()) {
  64        $this->client->getCache()->delete($cacheKey);
  65        $this->retrieveToken($scopes, $cacheKey);
  66      }
  67  
  68      $this->tokenScopes = $scopes;
  69      return $this->token;
  70    }
  71  
  72    /**
  73     * Retrieve a new access token and store it in cache
  74     * @param mixed $scopes
  75     * @param string $cacheKey
  76     */
  77    private function retrieveToken($scopes, $cacheKey)
  78    {
  79      $this->token = AppIdentityService::getAccessToken($scopes);
  80      if ($this->token) {
  81        $this->client->getCache()->set(
  82            $cacheKey,
  83            $this->token
  84        );
  85      }
  86    }
  87  
  88    /**
  89     * Perform an authenticated / signed apiHttpRequest.
  90     * This function takes the apiHttpRequest, calls apiAuth->sign on it
  91     * (which can modify the request in what ever way fits the auth mechanism)
  92     * and then calls apiCurlIO::makeRequest on the signed request
  93     *
  94     * @param Google_Http_Request $request
  95     * @return Google_Http_Request The resulting HTTP response including the
  96     * responseHttpCode, responseHeaders and responseBody.
  97     */
  98    public function authenticatedRequest(Google_Http_Request $request)
  99    {
 100      $request = $this->sign($request);
 101      return $this->client->getIo()->makeRequest($request);
 102    }
 103  
 104    public function sign(Google_Http_Request $request)
 105    {
 106      if (!$this->token) {
 107        // No token, so nothing to do.
 108        return $request;
 109      }
 110  
 111      $this->client->getLogger()->debug('App Identity authentication');
 112  
 113      // Add the OAuth2 header to the request
 114      $request->setRequestHeaders(
 115          array('Authorization' => 'Bearer ' . $this->token['access_token'])
 116      );
 117  
 118      return $request;
 119    }
 120  }