Search moodle.org's
Developer Documentation

See Release Notes

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

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

   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  /**
  19   * A class to contain the library configuration for the Google API client.
  20   */
  21  #[AllowDynamicProperties]
  22  class Google_Config
  23  {
  24    const GZIP_DISABLED = true;
  25    const GZIP_ENABLED = false;
  26    const GZIP_UPLOADS_ENABLED = true;
  27    const GZIP_UPLOADS_DISABLED = false;
  28    const USE_AUTO_IO_SELECTION = "auto";
  29    const TASK_RETRY_NEVER = 0;
  30    const TASK_RETRY_ONCE = 1;
  31    const TASK_RETRY_ALWAYS = -1;
  32    protected $configuration;
  33  
  34    /**
  35     * Create a new Google_Config. Can accept an ini file location with the
  36     * local configuration. For example:
  37     *     application_name="My App"
  38     *
  39     * @param [$ini_file_location] - optional - The location of the ini file to load
  40     */
  41    public function __construct($ini_file_location = null)
  42    {
  43      $this->configuration = array(
  44        // The application_name is included in the User-Agent HTTP header.
  45        'application_name' => '',
  46  
  47        // Which Authentication, Storage and HTTP IO classes to use.
  48        'auth_class'    => 'Google_Auth_OAuth2',
  49        'io_class'      => self::USE_AUTO_IO_SELECTION,
  50        'cache_class'   => 'Google_Cache_File',
  51        'logger_class'  => 'Google_Logger_Null',
  52  
  53        // Don't change these unless you're working against a special development
  54        // or testing environment.
  55        'base_path' => 'https://www.googleapis.com',
  56  
  57        // Definition of class specific values, like file paths and so on.
  58        'classes' => array(
  59          'Google_IO_Abstract' => array(
  60            'request_timeout_seconds' => 100,
  61          ),
  62          'Google_IO_Curl' => array(
  63            'disable_proxy_workaround' => false,
  64            'options' => null,
  65          ),
  66          'Google_Logger_Abstract' => array(
  67            'level' => 'debug',
  68            'log_format' => "[%datetime%] %level%: %message% %context%\n",
  69            'date_format' => 'd/M/Y:H:i:s O',
  70            'allow_newlines' => true
  71          ),
  72          'Google_Logger_File' => array(
  73            'file' => 'php://stdout',
  74            'mode' => 0640,
  75            'lock' => false,
  76          ),
  77          'Google_Http_Request' => array(
  78            // Disable the use of gzip on calls if set to true. Defaults to false.
  79            'disable_gzip' => self::GZIP_ENABLED,
  80  
  81            // We default gzip to disabled on uploads even if gzip is otherwise
  82            // enabled, due to some issues seen with small packet sizes for uploads.
  83            // Please test with this option before enabling gzip for uploads in
  84            // a production environment.
  85            'enable_gzip_for_uploads' => self::GZIP_UPLOADS_DISABLED,
  86          ),
  87          // If you want to pass in OAuth 2.0 settings, they will need to be
  88          // structured like this.
  89          'Google_Auth_OAuth2' => array(
  90            // Keys for OAuth 2.0 access, see the API console at
  91            // https://developers.google.com/console
  92            'client_id' => '',
  93            'client_secret' => '',
  94            'redirect_uri' => '',
  95  
  96            // Simple API access key, also from the API console. Ensure you get
  97            // a Server key, and not a Browser key.
  98            'developer_key' => '',
  99  
 100            // Other parameters.
 101            'hd' => '',
 102            'prompt' => '',
 103            'openid.realm' => '',
 104            'include_granted_scopes' => '',
 105            'login_hint' => '',
 106            'request_visible_actions' => '',
 107            'access_type' => 'online',
 108            'approval_prompt' => 'auto',
 109            'federated_signon_certs_url' =>
 110                'https://www.googleapis.com/oauth2/v1/certs',
 111          ),
 112          'Google_Task_Runner' => array(
 113            // Delays are specified in seconds
 114            'initial_delay' => 1,
 115            'max_delay' => 60,
 116            // Base number for exponential backoff
 117            'factor' => 2,
 118            // A random number between -jitter and jitter will be added to the
 119            // factor on each iteration to allow for better distribution of
 120            // retries.
 121            'jitter' => .5,
 122            // Maximum number of retries allowed
 123            'retries' => 0
 124          ),
 125          'Google_Service_Exception' => array(
 126            'retry_map' => array(
 127              '500' => self::TASK_RETRY_ALWAYS,
 128              '503' => self::TASK_RETRY_ALWAYS,
 129              'rateLimitExceeded' => self::TASK_RETRY_ALWAYS,
 130              'userRateLimitExceeded' => self::TASK_RETRY_ALWAYS
 131            )
 132          ),
 133          'Google_IO_Exception' => array(
 134            'retry_map' => !extension_loaded('curl') ? array() : array(
 135              CURLE_COULDNT_RESOLVE_HOST => self::TASK_RETRY_ALWAYS,
 136              CURLE_COULDNT_CONNECT => self::TASK_RETRY_ALWAYS,
 137              CURLE_OPERATION_TIMEOUTED => self::TASK_RETRY_ALWAYS,
 138              CURLE_SSL_CONNECT_ERROR => self::TASK_RETRY_ALWAYS,
 139              CURLE_GOT_NOTHING => self::TASK_RETRY_ALWAYS
 140            )
 141          ),
 142          // Set a default directory for the file cache.
 143          'Google_Cache_File' => array(
 144            'directory' => sys_get_temp_dir() . '/Google_Client'
 145          )
 146        ),
 147      );
 148      if ($ini_file_location) {
 149        $ini = parse_ini_file($ini_file_location, true);
 150        if (is_array($ini) && count($ini)) {
 151          $merged_configuration = $ini + $this->configuration;
 152          if (isset($ini['classes']) && isset($this->configuration['classes'])) {
 153            $merged_configuration['classes'] = $ini['classes'] + $this->configuration['classes'];
 154          }
 155          $this->configuration = $merged_configuration;
 156        }
 157      }
 158    }
 159  
 160    /**
 161     * Set configuration specific to a given class.
 162     * $config->setClassConfig('Google_Cache_File',
 163     *   array('directory' => '/tmp/cache'));
 164     * @param $class string The class name for the configuration
 165     * @param $config string key or an array of configuration values
 166     * @param $value string optional - if $config is a key, the value
 167     */
 168    public function setClassConfig($class, $config, $value = null)
 169    {
 170      if (!is_array($config)) {
 171        if (!isset($this->configuration['classes'][$class])) {
 172          $this->configuration['classes'][$class] = array();
 173        }
 174        $this->configuration['classes'][$class][$config] = $value;
 175      } else {
 176        $this->configuration['classes'][$class] = $config;
 177      }
 178    }
 179  
 180    public function getClassConfig($class, $key = null)
 181    {
 182      if (!isset($this->configuration['classes'][$class])) {
 183        return null;
 184      }
 185      if ($key === null) {
 186        return $this->configuration['classes'][$class];
 187      } else {
 188        return $this->configuration['classes'][$class][$key];
 189      }
 190    }
 191  
 192    /**
 193     * Return the configured cache class.
 194     * @return string
 195     */
 196    public function getCacheClass()
 197    {
 198      return $this->configuration['cache_class'];
 199    }
 200  
 201    /**
 202     * Return the configured logger class.
 203     * @return string
 204     */
 205    public function getLoggerClass()
 206    {
 207      return $this->configuration['logger_class'];
 208    }
 209  
 210    /**
 211     * Return the configured Auth class.
 212     * @return string
 213     */
 214    public function getAuthClass()
 215    {
 216      return $this->configuration['auth_class'];
 217    }
 218  
 219    /**
 220     * Set the auth class.
 221     *
 222     * @param $class string the class name to set
 223     */
 224    public function setAuthClass($class)
 225    {
 226      $prev = $this->configuration['auth_class'];
 227      if (!isset($this->configuration['classes'][$class]) &&
 228          isset($this->configuration['classes'][$prev])) {
 229        $this->configuration['classes'][$class] =
 230            $this->configuration['classes'][$prev];
 231      }
 232      $this->configuration['auth_class'] = $class;
 233    }
 234  
 235    /**
 236     * Set the IO class.
 237     *
 238     * @param $class string the class name to set
 239     */
 240    public function setIoClass($class)
 241    {
 242      $prev = $this->configuration['io_class'];
 243      if (!isset($this->configuration['classes'][$class]) &&
 244          isset($this->configuration['classes'][$prev])) {
 245        $this->configuration['classes'][$class] =
 246            $this->configuration['classes'][$prev];
 247      }
 248      $this->configuration['io_class'] = $class;
 249    }
 250  
 251    /**
 252     * Set the cache class.
 253     *
 254     * @param $class string the class name to set
 255     */
 256    public function setCacheClass($class)
 257    {
 258      $prev = $this->configuration['cache_class'];
 259      if (!isset($this->configuration['classes'][$class]) &&
 260          isset($this->configuration['classes'][$prev])) {
 261        $this->configuration['classes'][$class] =
 262            $this->configuration['classes'][$prev];
 263      }
 264      $this->configuration['cache_class'] = $class;
 265    }
 266  
 267    /**
 268     * Set the logger class.
 269     *
 270     * @param $class string the class name to set
 271     */
 272    public function setLoggerClass($class)
 273    {
 274      $prev = $this->configuration['logger_class'];
 275      if (!isset($this->configuration['classes'][$class]) &&
 276          isset($this->configuration['classes'][$prev])) {
 277        $this->configuration['classes'][$class] =
 278            $this->configuration['classes'][$prev];
 279      }
 280      $this->configuration['logger_class'] = $class;
 281    }
 282  
 283    /**
 284     * Return the configured IO class.
 285     *
 286     * @return string
 287     */
 288    public function getIoClass()
 289    {
 290      return $this->configuration['io_class'];
 291    }
 292  
 293    /**
 294     * Set the application name, this is included in the User-Agent HTTP header.
 295     * @param string $name
 296     */
 297    public function setApplicationName($name)
 298    {
 299      $this->configuration['application_name'] = $name;
 300    }
 301  
 302    /**
 303     * @return string the name of the application
 304     */
 305    public function getApplicationName()
 306    {
 307      return $this->configuration['application_name'];
 308    }
 309  
 310    /**
 311     * Set the client ID for the auth class.
 312     * @param $clientId string - the API console client ID
 313     */
 314    public function setClientId($clientId)
 315    {
 316      $this->setAuthConfig('client_id', $clientId);
 317    }
 318  
 319    /**
 320     * Set the client secret for the auth class.
 321     * @param $secret string - the API console client secret
 322     */
 323    public function setClientSecret($secret)
 324    {
 325      $this->setAuthConfig('client_secret', $secret);
 326    }
 327  
 328    /**
 329     * Set the redirect uri for the auth class. Note that if using the
 330     * Javascript based sign in flow, this should be the string 'postmessage'.
 331     *
 332     * @param $uri string - the URI that users should be redirected to
 333     */
 334    public function setRedirectUri($uri)
 335    {
 336      $this->setAuthConfig('redirect_uri', $uri);
 337    }
 338  
 339    /**
 340     * Set the app activities for the auth class.
 341     * @param $rva string a space separated list of app activity types
 342     */
 343    public function setRequestVisibleActions($rva)
 344    {
 345      $this->setAuthConfig('request_visible_actions', $rva);
 346    }
 347  
 348    /**
 349     * Set the the access type requested (offline or online.)
 350     * @param $access string - the access type
 351     */
 352    public function setAccessType($access)
 353    {
 354      $this->setAuthConfig('access_type', $access);
 355    }
 356  
 357    /**
 358     * Set when to show the approval prompt (auto or force)
 359     * @param $approval string - the approval request
 360     */
 361    public function setApprovalPrompt($approval)
 362    {
 363      $this->setAuthConfig('approval_prompt', $approval);
 364    }
 365  
 366    /**
 367     * Set the login hint (email address or sub identifier)
 368     * @param $hint string
 369     */
 370    public function setLoginHint($hint)
 371    {
 372      $this->setAuthConfig('login_hint', $hint);
 373    }
 374  
 375    /**
 376     * Set the developer key for the auth class. Note that this is separate value
 377     * from the client ID - if it looks like a URL, its a client ID!
 378     * @param $key string - the API console developer key
 379     */
 380    public function setDeveloperKey($key)
 381    {
 382      $this->setAuthConfig('developer_key', $key);
 383    }
 384  
 385    /**
 386     * Set the hd (hosted domain) parameter streamlines the login process for
 387     * Google Apps hosted accounts. By including the domain of the user, you
 388     * restrict sign-in to accounts at that domain.
 389     *
 390     * This should not be used to ensure security on your application - check
 391     * the hd values within an id token (@see Google_Auth_LoginTicket) after sign
 392     * in to ensure that the user is from the domain you were expecting.
 393     *
 394     * @param $hd string - the domain to use.
 395     */
 396    public function setHostedDomain($hd)
 397    {
 398      $this->setAuthConfig('hd', $hd);
 399    }
 400  
 401    /**
 402     * Set the prompt hint. Valid values are none, consent and select_account.
 403     * If no value is specified and the user has not previously authorized
 404     * access, then the user is shown a consent screen.
 405     * @param $prompt string
 406     */
 407    public function setPrompt($prompt)
 408    {
 409      $this->setAuthConfig('prompt', $prompt);
 410    }
 411  
 412    /**
 413     * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth
 414     * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which
 415     * an authentication request is valid.
 416     * @param $realm string - the URL-space to use.
 417     */
 418    public function setOpenidRealm($realm)
 419    {
 420      $this->setAuthConfig('openid.realm', $realm);
 421    }
 422  
 423    /**
 424     * If this is provided with the value true, and the authorization request is
 425     * granted, the authorization will include any previous authorizations
 426     * granted to this user/application combination for other scopes.
 427     * @param $include boolean - the URL-space to use.
 428     */
 429    public function setIncludeGrantedScopes($include)
 430    {
 431      $this->setAuthConfig(
 432          'include_granted_scopes',
 433          $include ? "true" : "false"
 434      );
 435    }
 436  
 437    /**
 438     * @return string the base URL to use for API calls
 439     */
 440    public function getBasePath()
 441    {
 442      return $this->configuration['base_path'];
 443    }
 444  
 445    /**
 446     * Set the auth configuration for the current auth class.
 447     * @param $key - the key to set
 448     * @param $value - the parameter value
 449     */
 450    private function setAuthConfig($key, $value)
 451    {
 452      if (!isset($this->configuration['classes'][$this->getAuthClass()])) {
 453        $this->configuration['classes'][$this->getAuthClass()] = array();
 454      }
 455      $this->configuration['classes'][$this->getAuthClass()][$key] = $value;
 456    }
 457  }