Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

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