<commit_before><?php
/*
 * Copyright 2014 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

require_once 'RpcHelper.php';
require_once 'DownloadIterator.php';

/**
 * Google Identity Toolkit PHP client library.
 * https://developers.google.com/identity-toolkit/v3/‎
 */
class Gitkit_Client {
  private static $GITKIT_API_BASE =
      'https://www.googleapis.com/identitytoolkit/v3/relyingparty/';
  private static $GTIKIT_TOKEN_ISSUER = 'https://identitytoolkit.google.com/';
  private static $DEFAULT_COOKIE_NAME = 'gtoken';
  private $oauth2Client;
  private $clientId;
  private $projectId;
  private $widgetUrl;
  private $cookieName;
  private $rpcHelper;

  /**
   * Constructs the Gitkit client.
   *
   * @param string $clientId Google OAuth2 web client id
   * @param string $projectId Google developer console project id
   * @param string $widgetUrl the url hosting the Gitkit widget
   * @param string $cookieName cookie name for Gitkit token
   * @param Gitkit_RpcHelper $rpcHelper the rpc helper
   */
  public function __construct($clientId, $projectId, $widgetUrl, $cookieName, $rpcHelper) {
    $this->clientId = $clientId;
    $this->projectId = $projectId;
    $this->widgetUrl = $widgetUrl;
    $this->cookieName = $cookieName;
    $this->oauth2Client = new Google_Auth_OAuth2(new Google_Client());
    $this->rpcHelper = $rpcHelper;
  }

  /**
   * Creates a Gitkit client from a config file (json format).
   *
   * @param string $file file name of the json config file
   * @return Gitkit_Client created Gitkit client
   */
  public static function createFromFile($file) {
    $jsonConfig = json_decode(file_get_contents($file), true);
    return self::createFromConfig($jsonConfig);
  }

  /**
   * Creates a Gitkit client from the config array.
   *
   * @param array $config config parameters
   * @param null|Gitkit_RpcHelper $rpcHelper Gitkit Rpc helper object
   * @return Gitkit_Client created Gitkit client
   * @throws Gitkit_ClientException if required config is missing
   */
  public static function createFromConfig($config, $rpcHelper = null) {
    $clientId = $config['clientId'];
    $projectId = $config['projectId'];
    if (!isset($clientId) && !isset($projectId)) {
      throw new Gitkit_ClientException("Missing projectId or clientId in server configuration.");
    }
    if (!isset($config['widgetUrl'])) {
      throw new Gitkit_ClientException("\"widgetUrl\" should be configured");
    }
    if (isset($config["cookieName"])) {
      $cookieName = $config['cookieName'];
    } else {
      $cookieName = self::$DEFAULT_COOKIE_NAME;
    }
    if (!$rpcHelper) {
      if (!isset($config['serviceAccountEmail'])) {
        throw new Gitkit_ClientException(
            "\"serviceAccountEmail\" should be configured");
      }
      if (!isset($config['serviceAccountPrivateKeyFile'])) {
        throw new Gitkit_ClientException(
            "\"serviceAccountPrivateKeyFile\" should be configured");
      }
      $p12Key = file_get_contents($config["serviceAccountPrivateKeyFile"]);
      if ($p12Key === false) {
        throw new Gitkit_ClientException(
            "Can not read file " . $config["serviceAccountPrivateKeyFile"]);
      }
      if (isset($config['serverApiKey'])) {
        $serverApiKey = $config['serverApiKey'];
      } else {
        $serverApiKey = null;
      }
      $rpcHelper = new Gitkit_RpcHelper(
          $config["serviceAccountEmail"],
          $p12Key,
          self::$GITKIT_API_BASE,
          new Google_Auth_OAuth2(new Google_Client()),
          $serverApiKey);
    }
    return new Gitkit_Client($clientId, $projectId,
        $config['widgetUrl'], $cookieName, $rpcHelper);
  }

  /**
   * Validates a Gitkit token. User info is extracted from the token only.
   *
   * @param string $gitToken token to be checked
   * @return Gitkit_Account|null Gitkit user corresponding to the token, null
   * for invalid token
   */
  public function validateToken($gitToken) {
    if ($gitToken) {
      $loginTicket = null;
      if (isset($this->projectId)) {
        try {
          $loginTicket = $this->oauth2Client->verifySignedJwtWithCerts(
              $gitToken,
              $this->getCerts(),
              $this->projectId,
              self::$GTIKIT_TOKEN_ISSUER,
              180 * 86400)->getAttributes();
        } catch (Google_Auth_Exception $e) {
          if (strpos($e->getMessage(), "Wrong recipient") === false) {
            throw $e;
          }
        }
      }
      if (!isset($loginTicket) and isset($this->clientId)) {
        try {
          $loginTicket = $this->oauth2Client->verifySignedJwtWithCerts(
              $gitToken,
              $this->getCerts(),
              $this->clientId,
              self::$GTIKIT_TOKEN_ISSUER,
              180 * 86400)->getAttributes();
        } catch (Google_Auth_Exception $e) {
          if (strpos($e->getMessage(), "Wrong recipient") === false) {
            throw $e;
          }
        }
      }
      if (!isset($loginTicket)) {
        throw new Google_Auth_Exception(
          "Gitkit token audience doesn't match projectId or clientId in server configuration.");
      }
      $jwt = $loginTicket["payload"];
      if ($jwt) {
        $user = new Gitkit_Account();
        $user->setUserId($jwt["user_id"]);
        $user->setEmail($jwt["email"]);
        if (isset($jwt["provider_id"])) {
          $user->setProviderId($jwt["provider_id"]);<commit_msg>1. fix backward compatibility; 2. code refactoring.<commit_after><?php
/*
 * Copyright 2014 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

require_once 'RpcHelper.php';
require_once 'DownloadIterator.php';

/**
 * Google Identity Toolkit PHP client library.
 * https://developers.google.com/identity-toolkit/v3/‎
 */
class Gitkit_Client {
  private static $GITKIT_API_BASE =
      'https://www.googleapis.com/identitytoolkit/v3/relyingparty/';
  private static $GTIKIT_TOKEN_ISSUER = 'https://identitytoolkit.google.com/';
  private static $DEFAULT_COOKIE_NAME = 'gtoken';
  private $oauth2Client;
  private $clientId;
  private $projectId;
  private $widgetUrl;
  private $cookieName;
  private $rpcHelper;

  /**
   * Constructs the Gitkit client.
   *
   * @param string $clientId Google OAuth2 web client id
   * @param string $projectId Google developer console project id
   * @param string $widgetUrl the url hosting the Gitkit widget
   * @param string $cookieName cookie name for Gitkit token
   * @param Gitkit_RpcHelper $rpcHelper the rpc helper
   */
  public function __construct($clientId, $widgetUrl, $cookieName, $rpcHelper, $projectId) {
    $this->clientId = $clientId;
    $this->widgetUrl = $widgetUrl;
    $this->cookieName = $cookieName;
    $this->oauth2Client = new Google_Auth_OAuth2(new Google_Client());
    $this->rpcHelper = $rpcHelper;
    $this->projectId = $projectId;
  }

  /**
   * Creates a Gitkit client from a config file (json format).
   *
   * @param string $file file name of the json config file
   * @return Gitkit_Client created Gitkit client
   */
  public static function createFromFile($file) {
    $jsonConfig = json_decode(file_get_contents($file), true);
    return self::createFromConfig($jsonConfig);
  }

  /**
   * Creates a Gitkit client from the config array.
   *
   * @param array $config config parameters
   * @param null|Gitkit_RpcHelper $rpcHelper Gitkit Rpc helper object
   * @return Gitkit_Client created Gitkit client
   * @throws Gitkit_ClientException if required config is missing
   */
  public static function createFromConfig($config, $rpcHelper = null) {
    $clientId = $config['clientId'];
    $projectId = $config['projectId'];
    if (!isset($clientId) && !isset($projectId)) {
      throw new Gitkit_ClientException("Missing projectId or clientId in server configuration.");
    }
    if (!isset($config['widgetUrl'])) {
      throw new Gitkit_ClientException("\"widgetUrl\" should be configured");
    }
    if (isset($config["cookieName"])) {
      $cookieName = $config['cookieName'];
    } else {
      $cookieName = self::$DEFAULT_COOKIE_NAME;
    }
    if (!$rpcHelper) {
      if (!isset($config['serviceAccountEmail'])) {
        throw new Gitkit_ClientException(
            "\"serviceAccountEmail\" should be configured");
      }
      if (!isset($config['serviceAccountPrivateKeyFile'])) {
        throw new Gitkit_ClientException(
            "\"serviceAccountPrivateKeyFile\" should be configured");
      }
      $p12Key = file_get_contents($config["serviceAccountPrivateKeyFile"]);
      if ($p12Key === false) {
        throw new Gitkit_ClientException(
            "Can not read file " . $config["serviceAccountPrivateKeyFile"]);
      }
      if (isset($config['serverApiKey'])) {
        $serverApiKey = $config['serverApiKey'];
      } else {
        $serverApiKey = null;
      }
      $rpcHelper = new Gitkit_RpcHelper(
          $config["serviceAccountEmail"],
          $p12Key,
          self::$GITKIT_API_BASE,
          new Google_Auth_OAuth2(new Google_Client()),
          $serverApiKey);
    }
    return new Gitkit_Client($clientId, $config['widgetUrl'],
        $cookieName, $rpcHelper, $projectId);
  }

  /**
   * Validates a Gitkit token. User info is extracted from the token only.
   *
   * @param string $gitToken token to be checked
   * @return Gitkit_Account|null Gitkit user corresponding to the token, null
   * for invalid token
   */
  public function validateToken($gitToken) {
    if ($gitToken) {
      $loginTicket = null;
      $auds = array_filter(
          array($this->projectId, $this->clientId),
          function($x) {
            return isset($x);
          });
      foreach ($auds as $aud) {
        try {
          $loginTicket = $this->oauth2Client->verifySignedJwtWithCerts(
              $gitToken,
              $this->getCerts(),
              $aud,
              self::$GTIKIT_TOKEN_ISSUER,
              180 * 86400)->getAttributes();
          break;
        } catch (Google_Auth_Exception $e) {
          if (strpos($e->getMessage(), "Wrong recipient") === false) {
            throw $e;
          }
        }
      }
      if (!isset($loginTicket)) {
        throw new Google_Auth_Exception(
          "Gitkit token audience doesn't match projectId or clientId in server configuration.");
      }
      $jwt = $loginTicket["payload"];
      if ($jwt) {
        $user = new Gitkit_Account();
        $user->setUserId($jwt["user_id"]);
        $user->setEmail($jwt["email"]);
        if (isset($jwt["provider_id"])) {
          $user->setProviderId($jwt["provider_id"]);
{'fraction_non_alphanumeric': 0.11948275862068966, 'fraction_numerical': 0.006120689655172414, 'mean_word_length': 2.972945205479452, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 42, 'https://': 6, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1737432', 'n_tokens_mistral': 3389, 'n_tokens_neox': 3358, 'n_words': 900}