Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]

   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  #[AllowDynamicProperties]
  33  class Google_Auth_AppIdentity extends Google_Auth_Abstract
  34  {
  35    const CACHE_PREFIX = "Google_Auth_AppIdentity::";
  36    private $client;
  37    private $token = false;
  38    private $tokenScopes = false;
  39  
  40    public function __construct(Google_Client $client, $config = null)
  41    {
  42      $this->client = $client;
  43    }
  44  
  45    /**
  46     * Retrieve an access token for the scopes supplied.
  47     */
  48    public function authenticateForScope($scopes)
  49    {
  50      if ($this->token && $this->tokenScopes == $scopes) {
  51        return $this->token;
  52      }
  53  
  54      $cacheKey = self::CACHE_PREFIX;
  55      if (is_string($scopes)) {
  56        $cacheKey .= $scopes;
  57      } else if (is_array($scopes)) {
  58        $cacheKey .= implode(":", $scopes);
  59      }
  60  
  61      $this->token = $this->client->getCache()->get($cacheKey);
  62      if (!$this->token) {
  63        $this->retrieveToken($scopes, $cacheKey);
  64      } else if ($this->token['expiration_time'] < time()) {
  65        $this->client->getCache()->delete($cacheKey);
  66        $this->retrieveToken($scopes, $cacheKey);
  67      }
  68  
  69      $this->tokenScopes = $scopes;
  70      return $this->token;
  71    }
  72  
  73    /**
  74     * Retrieve a new access token and store it in cache
  75     * @param mixed $scopes
  76     * @param string $cacheKey
  77     */
  78    private function retrieveToken($scopes, $cacheKey)
  79    {
  80      $this->token = AppIdentityService::getAccessToken($scopes);
  81      if ($this->token) {
  82        $this->client->getCache()->set(
  83            $cacheKey,
  84            $this->token
  85        );
  86      }
  87    }
  88  
  89    /**
  90     * Perform an authenticated / signed apiHttpRequest.
  91     * This function takes the apiHttpRequest, calls apiAuth->sign on it
  92     * (which can modify the request in what ever way fits the auth mechanism)
  93     * and then calls apiCurlIO::makeRequest on the signed request
  94     *
  95     * @param Google_Http_Request $request
  96     * @return Google_Http_Request The resulting HTTP response including the
  97     * responseHttpCode, responseHeaders and responseBody.
  98     */
  99    public function authenticatedRequest(Google_Http_Request $request)
 100    {
 101      $request = $this->sign($request);
 102      return $this->client->getIo()->makeRequest($request);
 103    }
 104  
 105    public function sign(Google_Http_Request $request)
 106    {
 107      if (!$this->token) {
 108        // No token, so nothing to do.
 109        return $request;
 110      }
 111  
 112      $this->client->getLogger()->debug('App Identity authentication');
 113  
 114      // Add the OAuth2 header to the request
 115      $request->setRequestHeaders(
 116          array('Authorization' => 'Bearer ' . $this->token['access_token'])
 117      );
 118  
 119      return $request;
 120    }
 121  }