jenkins-bot has submitted this change and it was merged.

Change subject: Add firebase/php-jwt for ContentTranslation
......................................................................


Add firebase/php-jwt for ContentTranslation

Used in https://gerrit.wikimedia.org/r/#/c/219194/

Bug: T97113
Bug: T106762
Change-Id: I58af86204981a9f038b93df40e5c6c2f51fe06ae
---
M composer.json
M composer.lock
M composer/autoload_classmap.php
M composer/installed.json
A firebase/php-jwt/.gitignore
A firebase/php-jwt/.travis.yml
A firebase/php-jwt/Authentication/JWT.php
A firebase/php-jwt/Exceptions/BeforeValidException.php
A firebase/php-jwt/Exceptions/ExpiredException.php
A firebase/php-jwt/Exceptions/SignatureInvalidException.php
A firebase/php-jwt/LICENSE
A firebase/php-jwt/README.md
A firebase/php-jwt/composer.json
A firebase/php-jwt/package.xml
A firebase/php-jwt/phpunit.xml.dist
A firebase/php-jwt/run-tests.sh
A firebase/php-jwt/tests/JWTTest.php
A firebase/php-jwt/tests/autoload.php.dist
A firebase/php-jwt/tests/bootstrap.php
19 files changed, 1,001 insertions(+), 1 deletion(-)

Approvals:
  Legoktm: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/composer.json b/composer.json
index 723d42f..a5090d8 100644
--- a/composer.json
+++ b/composer.json
@@ -11,6 +11,7 @@
        "require": {
                "composer/semver": "0.1.0",
                "cssjanus/cssjanus": "1.1.1",
+               "firebase/php-jwt": "2.1.0",
                "kzykhys/pygments": "1.0",
                "leafo/lessphp": "0.5.0",
                "liuggio/statsd-php-client": "1.0.16",
diff --git a/composer.lock b/composer.lock
index 5623eb1..7dbbc98 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at 
https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file";,
         "This file is @generated automatically"
     ],
-    "hash": "7d6cf00035f6a21a54aa0f9ba8a9101e",
+    "hash": "4985b96fdac3d7b3c1327fdcb1bd491f",
     "packages": [
         {
             "name": "composer/semver",
@@ -103,6 +103,50 @@
             "time": "2014-11-14 20:00:50"
         },
         {
+            "name": "firebase/php-jwt",
+            "version": "v2.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/firebase/php-jwt.git";,
+                "reference": "fb219727e199dd80a72d5274ebb5c8b24d58dd9b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": 
"https://api.github.com/repos/firebase/php-jwt/zipball/fb219727e199dd80a72d5274ebb5c8b24d58dd9b";,
+                "reference": "fb219727e199dd80a72d5274ebb5c8b24d58dd9b",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.2.0"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "Authentication/",
+                    "Exceptions/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/";,
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Neuman Vong",
+                    "email": "[email protected]",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Anant Narayanan",
+                    "email": "[email protected]",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A simple library to encode and decode JSON Web 
Tokens (JWT) in PHP. Should conform to the current spec.",
+            "homepage": "https://github.com/firebase/php-jwt";,
+            "time": "2015-05-20 19:16:04"
+        },
+        {
             "name": "kzykhys/pygments",
             "version": "v1.0.0",
             "source": {
diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php
index 285464b..3d8de99 100644
--- a/composer/autoload_classmap.php
+++ b/composer/autoload_classmap.php
@@ -6,6 +6,7 @@
 $baseDir = $vendorDir;
 
 return array(
+    'BeforeValidException' => $vendorDir . 
'/firebase/php-jwt/Exceptions/BeforeValidException.php',
     'CSSJanus' => $vendorDir . '/cssjanus/cssjanus/src/CSSJanus.php',
     'CSSJanusTokenizer' => $vendorDir . '/cssjanus/cssjanus/src/CSSJanus.php',
     'Cdb\\Exception' => $vendorDir . '/wikimedia/cdb/src/Exception.php',
@@ -238,7 +239,9 @@
     'Elastica\\Type\\AbstractType' => $vendorDir . 
'/ruflin/elastica/lib/Elastica/Type/AbstractType.php',
     'Elastica\\Type\\Mapping' => $vendorDir . 
'/ruflin/elastica/lib/Elastica/Type/Mapping.php',
     'Elastica\\Util' => $vendorDir . '/ruflin/elastica/lib/Elastica/Util.php',
+    'ExpiredException' => $vendorDir . 
'/firebase/php-jwt/Exceptions/ExpiredException.php',
     'IPSet\\IPSet' => $vendorDir . '/wikimedia/ip-set/src/IPSet.php',
+    'JWT' => $vendorDir . '/firebase/php-jwt/Authentication/JWT.php',
     'KzykHys\\Pygments\\Pygments' => $vendorDir . 
'/kzykhys/pygments/src/KzykHys/Pygments/Pygments.php',
     'LCRun3' => $vendorDir . '/zordius/lightncandy/src/lightncandy.php',
     'LightnCandy' => $vendorDir . '/zordius/lightncandy/src/lightncandy.php',
@@ -379,6 +382,7 @@
     'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
     'Psr\\Log\\Test\\DummyTest' => $vendorDir . 
'/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
     'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . 
'/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
+    'SignatureInvalidException' => $vendorDir . 
'/firebase/php-jwt/Exceptions/SignatureInvalidException.php',
     'Symfony\\Component\\Process\\Exception\\ExceptionInterface' => $vendorDir 
. '/symfony/process/Exception/ExceptionInterface.php',
     'Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => 
$vendorDir . '/symfony/process/Exception/InvalidArgumentException.php',
     'Symfony\\Component\\Process\\Exception\\LogicException' => $vendorDir . 
'/symfony/process/Exception/LogicException.php',
diff --git a/composer/installed.json b/composer/installed.json
index 1386097..97f95f3 100644
--- a/composer/installed.json
+++ b/composer/installed.json
@@ -865,5 +865,51 @@
         ],
         "description": "Provides library of common widgets, layouts, and 
windows.",
         "homepage": "https://www.mediawiki.org/wiki/OOjs_UI";
+    },
+    {
+        "name": "firebase/php-jwt",
+        "version": "v2.1.0",
+        "version_normalized": "2.1.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/firebase/php-jwt.git";,
+            "reference": "fb219727e199dd80a72d5274ebb5c8b24d58dd9b"
+        },
+        "dist": {
+            "type": "zip",
+            "url": 
"https://api.github.com/repos/firebase/php-jwt/zipball/fb219727e199dd80a72d5274ebb5c8b24d58dd9b";,
+            "reference": "fb219727e199dd80a72d5274ebb5c8b24d58dd9b",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.2.0"
+        },
+        "time": "2015-05-20 19:16:04",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "classmap": [
+                "Authentication/",
+                "Exceptions/"
+            ]
+        },
+        "notification-url": "https://packagist.org/downloads/";,
+        "license": [
+            "BSD-3-Clause"
+        ],
+        "authors": [
+            {
+                "name": "Neuman Vong",
+                "email": "[email protected]",
+                "role": "Developer"
+            },
+            {
+                "name": "Anant Narayanan",
+                "email": "[email protected]",
+                "role": "Developer"
+            }
+        ],
+        "description": "A simple library to encode and decode JSON Web Tokens 
(JWT) in PHP. Should conform to the current spec.",
+        "homepage": "https://github.com/firebase/php-jwt";
     }
 ]
diff --git a/firebase/php-jwt/.gitignore b/firebase/php-jwt/.gitignore
new file mode 100644
index 0000000..96e2f2e
--- /dev/null
+++ b/firebase/php-jwt/.gitignore
@@ -0,0 +1,3 @@
+vendor
+phpunit.phar
+phpunit.phar.asc
diff --git a/firebase/php-jwt/.travis.yml b/firebase/php-jwt/.travis.yml
new file mode 100644
index 0000000..0bd12c5
--- /dev/null
+++ b/firebase/php-jwt/.travis.yml
@@ -0,0 +1,13 @@
+language: php
+
+php:
+  - 5.3
+  - 5.4
+  - 5.5
+  - hhvm
+
+before_script:
+  - wget -nc http://getcomposer.org/composer.phar
+  - php composer.phar install
+
+script: phpunit --configuration phpunit.xml.dist
diff --git a/firebase/php-jwt/Authentication/JWT.php 
b/firebase/php-jwt/Authentication/JWT.php
new file mode 100644
index 0000000..7d6665b
--- /dev/null
+++ b/firebase/php-jwt/Authentication/JWT.php
@@ -0,0 +1,334 @@
+<?php
+
+/**
+ * JSON Web Token implementation, based on this spec:
+ * http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
+ *
+ * PHP version 5
+ *
+ * @category Authentication
+ * @package  Authentication_JWT
+ * @author   Neuman Vong <[email protected]>
+ * @author   Anant Narayanan <[email protected]>
+ * @license  http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
+ * @link     https://github.com/firebase/php-jwt
+ */
+class JWT
+{
+
+    /**
+     * When checking nbf, iat or expiration times,
+     * we want to provide some extra leeway time to
+     * account for clock skew.
+     */
+    public static $leeway = 0;
+
+    public static $supported_algs = array(
+        'HS256' => array('hash_hmac', 'SHA256'),
+        'HS512' => array('hash_hmac', 'SHA512'),
+        'HS384' => array('hash_hmac', 'SHA384'),
+        'RS256' => array('openssl', 'SHA256'),
+    );
+
+    /**
+     * Decodes a JWT string into a PHP object.
+     *
+     * @param string      $jwt           The JWT
+     * @param string|Array|null $key     The secret key, or map of keys
+     * @param Array       $allowed_algs  List of supported verification 
algorithms
+     *
+     * @return object      The JWT's payload as a PHP object
+     *
+     * @throws DomainException              Algorithm was not provided
+     * @throws UnexpectedValueException     Provided JWT was invalid
+     * @throws SignatureInvalidException    Provided JWT was invalid because 
the signature verification failed
+     * @throws BeforeValidException         Provided JWT is trying to be used 
before it's eligible as defined by 'nbf'
+     * @throws BeforeValidException         Provided JWT is trying to be used 
before it's been created as defined by 'iat'
+     * @throws ExpiredException             Provided JWT has since expired, as 
defined by the 'exp' claim
+     *
+     * @uses jsonDecode
+     * @uses urlsafeB64Decode
+     */
+    public static function decode($jwt, $key = null, $allowed_algs = array())
+    {
+        $tks = explode('.', $jwt);
+        if (count($tks) != 3) {
+            throw new UnexpectedValueException('Wrong number of segments');
+        }
+        list($headb64, $bodyb64, $cryptob64) = $tks;
+        if (null === ($header = 
JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) {
+            throw new UnexpectedValueException('Invalid header encoding');
+        }
+        if (null === $payload = 
JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64))) {
+            throw new UnexpectedValueException('Invalid claims encoding');
+        }
+        $sig = JWT::urlsafeB64Decode($cryptob64);
+        if (isset($key)) {
+            if (empty($header->alg)) {
+                throw new DomainException('Empty algorithm');
+            }
+            if (empty(self::$supported_algs[$header->alg])) {
+                throw new DomainException('Algorithm not supported');
+            }
+            if (!is_array($allowed_algs) || !in_array($header->alg, 
$allowed_algs)) {
+                throw new DomainException('Algorithm not allowed');
+            }
+            if (is_array($key) || $key instanceof \ArrayAccess) {
+                if (isset($header->kid)) {
+                    $key = $key[$header->kid];
+                } else {
+                    throw new DomainException('"kid" empty, unable to lookup 
correct key');
+                }
+            }
+
+            // Check the signature
+            if (!JWT::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
+                throw new SignatureInvalidException('Signature verification 
failed');
+            }
+
+            // Check if the nbf if it is defined. This is the time that the
+            // token can actually be used. If it's not yet that time, abort.
+            if (isset($payload->nbf) && $payload->nbf > (time() + 
self::$leeway)) {
+                throw new BeforeValidException(
+                    'Cannot handle token prior to ' . date(DateTime::ISO8601, 
$payload->nbf)
+                );
+            }
+
+            // Check that this token has been created before 'now'. This 
prevents
+            // using tokens that have been created for later use (and haven't
+            // correctly used the nbf claim).
+            if (isset($payload->iat) && $payload->iat > (time() + 
self::$leeway)) {
+                throw new BeforeValidException(
+                    'Cannot handle token prior to ' . date(DateTime::ISO8601, 
$payload->iat)
+                );
+            }
+
+            // Check if this token has expired.
+            if (isset($payload->exp) && (time() - self::$leeway) >= 
$payload->exp) {
+                throw new ExpiredException('Expired token');
+            }
+        }
+
+        return $payload;
+    }
+
+    /**
+     * Converts and signs a PHP object or array into a JWT string.
+     *
+     * @param object|array $payload PHP object or array
+     * @param string       $key     The secret key
+     * @param string       $alg     The signing algorithm. Supported
+     *                              algorithms are 'HS256', 'HS384' and 'HS512'
+     *
+     * @return string      A signed JWT
+     * @uses jsonEncode
+     * @uses urlsafeB64Encode
+     */
+    public static function encode($payload, $key, $alg = 'HS256', $keyId = 
null)
+    {
+        $header = array('typ' => 'JWT', 'alg' => $alg);
+        if ($keyId !== null) {
+            $header['kid'] = $keyId;
+        }
+        $segments = array();
+        $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($header));
+        $segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($payload));
+        $signing_input = implode('.', $segments);
+
+        $signature = JWT::sign($signing_input, $key, $alg);
+        $segments[] = JWT::urlsafeB64Encode($signature);
+
+        return implode('.', $segments);
+    }
+
+    /**
+     * Sign a string with a given key and algorithm.
+     *
+     * @param string $msg          The message to sign
+     * @param string|resource $key The secret key
+     * @param string $alg       The signing algorithm. Supported algorithms
+     *                               are 'HS256', 'HS384', 'HS512' and 'RS256'
+     *
+     * @return string          An encrypted message
+     * @throws DomainException Unsupported algorithm was specified
+     */
+    public static function sign($msg, $key, $alg = 'HS256')
+    {
+        if (empty(self::$supported_algs[$alg])) {
+            throw new DomainException('Algorithm not supported');
+        }
+        list($function, $algorithm) = self::$supported_algs[$alg];
+        switch($function) {
+            case 'hash_hmac':
+                return hash_hmac($algorithm, $msg, $key, true);
+            case 'openssl':
+                $signature = '';
+                $success = openssl_sign($msg, $signature, $key, $algorithm);
+                if (!$success) {
+                    throw new DomainException("OpenSSL unable to sign data");
+                } else {
+                    return $signature;
+                }
+        }
+    }
+
+    /**
+     * Verify a signature with the mesage, key and method. Not all methods
+     * are symmetric, so we must have a separate verify and sign method.
+     * @param string $msg the original message
+     * @param string $signature
+     * @param string|resource $key for HS*, a string key works. for RS*, must 
be a resource of an openssl public key
+     * @param string $alg
+     * @return bool
+     * @throws DomainException Invalid Algorithm or OpenSSL failure
+     */
+    private static function verify($msg, $signature, $key, $alg)
+    {
+        if (empty(self::$supported_algs[$alg])) {
+            throw new DomainException('Algorithm not supported');
+        }
+
+        list($function, $algorithm) = self::$supported_algs[$alg];
+        switch($function) {
+            case 'openssl':
+                $success = openssl_verify($msg, $signature, $key, $algorithm);
+                if (!$success) {
+                    throw new DomainException("OpenSSL unable to verify data: 
" . openssl_error_string());
+                } else {
+                    return $signature;
+                }
+            case 'hash_hmac':
+            default:
+                $hash = hash_hmac($algorithm, $msg, $key, true);
+                if (function_exists('hash_equals')) {
+                    return hash_equals($signature, $hash);
+                }
+                $len = min(self::safeStrlen($signature), 
self::safeStrlen($hash));
+
+                $status = 0;
+                for ($i = 0; $i < $len; $i++) {
+                    $status |= (ord($signature[$i]) ^ ord($hash[$i]));
+                }
+                $status |= (self::safeStrlen($signature) ^ 
self::safeStrlen($hash));
+
+                return ($status === 0);
+        }
+    }
+
+    /**
+     * Decode a JSON string into a PHP object.
+     *
+     * @param string $input JSON string
+     *
+     * @return object          Object representation of JSON string
+     * @throws DomainException Provided string was invalid JSON
+     */
+    public static function jsonDecode($input)
+    {
+        if (version_compare(PHP_VERSION, '5.4.0', '>=') && 
!(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
+            /** In PHP >=5.4.0, json_decode() accepts an options parameter, 
that allows you
+             * to specify that large ints (like Steam Transaction IDs) should 
be treated as
+             * strings, rather than the PHP default behaviour of converting 
them to floats.
+             */
+            $obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
+        } else {
+            /** Not all servers will support that, however, so for older 
versions we must
+             * manually detect large ints in the JSON string and quote them 
(thus converting
+             *them to strings) before decoding, hence the preg_replace() call.
+             */
+            $max_int_length = strlen((string) PHP_INT_MAX) - 1;
+            $json_without_bigints = 
preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);
+            $obj = json_decode($json_without_bigints);
+        }
+
+        if (function_exists('json_last_error') && $errno = json_last_error()) {
+            JWT::handleJsonError($errno);
+        } elseif ($obj === null && $input !== 'null') {
+            throw new DomainException('Null result with non-null input');
+        }
+        return $obj;
+    }
+
+    /**
+     * Encode a PHP object into a JSON string.
+     *
+     * @param object|array $input A PHP object or array
+     *
+     * @return string          JSON representation of the PHP object or array
+     * @throws DomainException Provided object could not be encoded to valid 
JSON
+     */
+    public static function jsonEncode($input)
+    {
+        $json = json_encode($input);
+        if (function_exists('json_last_error') && $errno = json_last_error()) {
+            JWT::handleJsonError($errno);
+        } elseif ($json === 'null' && $input !== null) {
+            throw new DomainException('Null result with non-null input');
+        }
+        return $json;
+    }
+
+    /**
+     * Decode a string with URL-safe Base64.
+     *
+     * @param string $input A Base64 encoded string
+     *
+     * @return string A decoded string
+     */
+    public static function urlsafeB64Decode($input)
+    {
+        $remainder = strlen($input) % 4;
+        if ($remainder) {
+            $padlen = 4 - $remainder;
+            $input .= str_repeat('=', $padlen);
+        }
+        return base64_decode(strtr($input, '-_', '+/'));
+    }
+
+    /**
+     * Encode a string with URL-safe Base64.
+     *
+     * @param string $input The string you want encoded
+     *
+     * @return string The base64 encode of what you passed in
+     */
+    public static function urlsafeB64Encode($input)
+    {
+        return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
+    }
+
+    /**
+     * Helper method to create a JSON error.
+     *
+     * @param int $errno An error number from json_last_error()
+     *
+     * @return void
+     */
+    private static function handleJsonError($errno)
+    {
+        $messages = array(
+            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
+            JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
+            JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON'
+        );
+        throw new DomainException(
+            isset($messages[$errno])
+            ? $messages[$errno]
+            : 'Unknown JSON error: ' . $errno
+        );
+    }
+
+    /**
+     * Get the number of bytes in cryptographic strings.
+     *
+     * @param string
+     * @return int
+     */
+    private static function safeStrlen($str)
+    {
+        if (function_exists('mb_strlen')) {
+            return mb_strlen($str, '8bit');
+        }
+        return strlen($str);
+    }
+}
diff --git a/firebase/php-jwt/Exceptions/BeforeValidException.php 
b/firebase/php-jwt/Exceptions/BeforeValidException.php
new file mode 100644
index 0000000..5a84975
--- /dev/null
+++ b/firebase/php-jwt/Exceptions/BeforeValidException.php
@@ -0,0 +1,6 @@
+<?php
+
+class BeforeValidException extends UnexpectedValueException
+{
+
+}
diff --git a/firebase/php-jwt/Exceptions/ExpiredException.php 
b/firebase/php-jwt/Exceptions/ExpiredException.php
new file mode 100644
index 0000000..bd80468
--- /dev/null
+++ b/firebase/php-jwt/Exceptions/ExpiredException.php
@@ -0,0 +1,6 @@
+<?php
+
+class ExpiredException extends UnexpectedValueException
+{
+
+}
diff --git a/firebase/php-jwt/Exceptions/SignatureInvalidException.php 
b/firebase/php-jwt/Exceptions/SignatureInvalidException.php
new file mode 100644
index 0000000..d122232
--- /dev/null
+++ b/firebase/php-jwt/Exceptions/SignatureInvalidException.php
@@ -0,0 +1,6 @@
+<?php
+
+class SignatureInvalidException extends UnexpectedValueException
+{
+
+}
diff --git a/firebase/php-jwt/LICENSE b/firebase/php-jwt/LICENSE
new file mode 100644
index 0000000..cb0c49b
--- /dev/null
+++ b/firebase/php-jwt/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2011, Neuman Vong
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Neuman Vong nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/firebase/php-jwt/README.md b/firebase/php-jwt/README.md
new file mode 100644
index 0000000..00bad2e
--- /dev/null
+++ b/firebase/php-jwt/README.md
@@ -0,0 +1,93 @@
+[![Build 
Status](https://travis-ci.org/firebase/php-jwt.png?branch=master)](https://travis-ci.org/firebase/php-jwt)
+
+PHP-JWT
+=======
+A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should
+conform to the [current 
spec](http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06)
+
+Installation
+------------
+
+Use composer to manage your dependencies and download PHP-JWT:
+
+```bash
+composer require firebase/php-jwt
+```
+
+Example
+-------
+```php
+<?php
+
+$key = "example_key";
+$token = array(
+    "iss" => "http://example.org";,
+    "aud" => "http://example.com";,
+    "iat" => 1356999524,
+    "nbf" => 1357000000
+);
+
+/**
+ * IMPORTANT:
+ * You must specify supported algorithms for your application. See
+ * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40
+ * for a list of spec-compliant algorithms.
+ */
+$jwt = JWT::encode($token, $key);
+$decoded = JWT::decode($jwt, $key, array('HS256'));
+
+print_r($decoded);
+
+/*
+ NOTE: This will now be an object instead of an associative array. To get
+ an associative array, you will need to cast it as such:
+*/
+
+$decoded_array = (array) $decoded;
+
+/**
+ * You can add a leeway to account for when there is a clock skew times between
+ * the signing and verifying servers. It is recommended that this leeway should
+ * not be bigger than a few minutes.
+ *
+ * Source: 
http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef
+ */
+JWT::$leeway = 60; // $leeway in seconds
+$decoded = JWT::decode($jwt, $key, array('HS256'));
+
+?>
+```
+
+Changelog
+---------
+
+#### 2.1.0 / 2015-05-20
+- Add support for adding a leeway to `JWT:decode()` that accounts for clock 
skew
+between signing and verifying entities. Thanks to 
[@lcabral](https://github.com/lcabral)!
+- Add support for passing an object implementing the `ArrayAccess` interface 
for
+`$keys` argument in `JWT::decode()`. Thanks to 
[@aztech-dev](https://github.com/aztech-dev)!
+
+#### 2.0.0 / 2015-04-01
+- **Note**: It is strongly recommended that you update to > v2.0.0 to address
+  known security vulnerabilities in prior versions when both symmetric and
+  asymmetric keys are used together.
+- Update signature for `JWT::decode(...)` to require an array of supported
+  algorithms to use when verifying token signatures.
+
+
+Tests
+-----
+Run the tests using phpunit:
+
+```bash
+$ pear install PHPUnit
+$ phpunit --configuration phpunit.xml.dist
+PHPUnit 3.7.10 by Sebastian Bergmann.
+.....
+Time: 0 seconds, Memory: 2.50Mb
+OK (5 tests, 5 assertions)
+```
+
+License
+-------
+[3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause).
diff --git a/firebase/php-jwt/composer.json b/firebase/php-jwt/composer.json
new file mode 100644
index 0000000..95560af
--- /dev/null
+++ b/firebase/php-jwt/composer.json
@@ -0,0 +1,25 @@
+{
+    "name": "firebase/php-jwt",
+    "description": "A simple library to encode and decode JSON Web Tokens 
(JWT) in PHP. Should conform to the current spec.",
+    "homepage": "https://github.com/firebase/php-jwt";,
+    "authors": [
+        {
+            "name": "Neuman Vong",
+            "email": "[email protected]",
+            "role": "Developer"
+        },
+        {
+            "name": "Anant Narayanan",
+            "email": "[email protected]",
+            "role": "Developer"
+        }
+    ],
+    "license": "BSD-3-Clause",
+    "require": {
+        "php": ">=5.2.0"
+    },
+    "autoload": {
+        "classmap": ["Authentication/", "Exceptions/"]
+    },
+    "minimum-stability": "dev"
+}
diff --git a/firebase/php-jwt/package.xml b/firebase/php-jwt/package.xml
new file mode 100644
index 0000000..b40da26
--- /dev/null
+++ b/firebase/php-jwt/package.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.9.2" version="2.0" 
xmlns="http://pear.php.net/dtd/package-2.0"; 
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+    http://pear.php.net/dtd/tasks-1.0.xsd
+    http://pear.php.net/dtd/package-2.0
+    http://pear.php.net/dtd/package-2.0.xsd";>
+ <name>JWT</name>
+ <channel>pear.php.net</channel>
+ <summary>A JWT encoder/decoder.</summary>
+ <description>A JWT encoder/decoder library for PHP.</description>
+ <lead>
+  <name>Neuman Vong</name>
+  <user>lcfrs</user>
+  <email>[email protected]</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Firebase Operations</name>
+  <user>firebase</user>
+  <email>[email protected]</email>
+  <active>yes</active>
+ </lead>
+ <date>2015-05-20</date>
+ <version>
+  <release>2.1.0</release>
+  <api>2.1.0</api>
+ </version>
+ <stability>
+  <release>beta</release>
+  <api>beta</api>
+ </stability>
+ <license uri="http://opensource.org/licenses/BSD-3-Clause";>BSD 3-Clause 
License</license>
+ <notes>
+Initial release with basic support for JWT encoding, decoding and signature 
verification.
+ </notes>
+ <contents>
+  <dir baseinstalldir="/" name="/">
+   <dir name="tests">
+    <file name="JWTTest.php" role="test" />
+   </dir>
+   <file name="Authentication/JWT.php" role="php" />
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.1</min>
+   </php>
+   <pearinstaller>
+    <min>1.7.0</min>
+   </pearinstaller>
+   <extension>
+    <name>json</name>
+   </extension>
+   <extension>
+    <name>hash</name>
+   </extension>
+  </required>
+ </dependencies>
+ <phprelease />
+ <changelog>
+  <release>
+   <version>
+    <release>0.1.0</release>
+    <api>0.1.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2015-04-01</date>
+   <license uri="http://opensource.org/licenses/BSD-3-Clause";>BSD 3-Clause 
License</license>
+   <notes>
+Initial release with basic support for JWT encoding, decoding and signature 
verification.
+   </notes>
+  </release>
+ </changelog>
+</package>
diff --git a/firebase/php-jwt/phpunit.xml.dist 
b/firebase/php-jwt/phpunit.xml.dist
new file mode 100644
index 0000000..9f85f5b
--- /dev/null
+++ b/firebase/php-jwt/phpunit.xml.dist
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+         backupStaticAttributes="false"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false"
+         syntaxCheck="false"
+         bootstrap="tests/bootstrap.php"
+>
+    <testsuites>
+        <testsuite name="PHP JSON Web Token Test Suite">
+            <directory>./tests</directory>
+        </testsuite>
+    </testsuites>
+</phpunit>
diff --git a/firebase/php-jwt/run-tests.sh b/firebase/php-jwt/run-tests.sh
new file mode 100755
index 0000000..d37c30f
--- /dev/null
+++ b/firebase/php-jwt/run-tests.sh
@@ -0,0 +1,38 @@
+
+#!/usr/bin/env bash
+gpg --fingerprint D8406D0D82947747293778314AA394086372C20A
+if [ $? -ne 0 ]; then
+    echo -e "\033[33mDownloading PGP Public Key...\033[0m"
+    gpg --recv-keys D8406D0D82947747293778314AA394086372C20A
+    # Sebastian Bergmann <[email protected]>
+    gpg --fingerprint D8406D0D82947747293778314AA394086372C20A
+    if [ $? -ne 0 ]; then
+        echo -e "\033[31mCould not download PGP public key for 
verification\033[0m"
+        exit
+    fi
+fi
+
+# Let's grab the latest release and its signature
+if [ ! -f phpunit.phar ]; then
+    wget https://phar.phpunit.de/phpunit.phar
+fi
+if [ ! -f phpunit.phar.asc ]; then
+    wget https://phar.phpunit.de/phpunit.phar.asc
+fi
+
+# Verify before running
+gpg --verify phpunit.phar.asc phpunit.phar
+if [ $? -eq 0 ]; then
+    echo
+    echo -e "\033[33mBegin Unit Testing\033[0m"
+    # Run the testing suite
+    php --version
+    php phpunit.phar --configuration phpunit.xml.dist
+else
+    echo
+    chmod -x phpunit.phar
+    mv phpunit.phar /tmp/bad-phpunit.phar
+    mv phpunit.phar.asc /tmp/bad-phpunit.phar.asc
+    echo -e "\033[31mSignature did not match! PHPUnit has been moved to 
/tmp/bad-phpunit.phar\033[0m"
+    exit 1
+fi
diff --git a/firebase/php-jwt/tests/JWTTest.php 
b/firebase/php-jwt/tests/JWTTest.php
new file mode 100644
index 0000000..0605e4c
--- /dev/null
+++ b/firebase/php-jwt/tests/JWTTest.php
@@ -0,0 +1,231 @@
+<?php
+
+class JWTTest extends PHPUnit_Framework_TestCase
+{
+    public function testEncodeDecode()
+    {
+        $msg = JWT::encode('abc', 'my_key');
+        $this->assertEquals(JWT::decode($msg, 'my_key', array('HS256')), 
'abc');
+    }
+
+    public function testDecodeFromPython()
+    {
+        $msg = 
'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.Iio6aHR0cDovL2FwcGxpY2F0aW9uL2NsaWNreT9ibGFoPTEuMjMmZi5vbz00NTYgQUMwMDAgMTIzIg.E_U8X2YpMT5K1cEiT_3-IvBYfrdIFIeVYeOqre_Z5Cg';
+        $this->assertEquals(
+            JWT::decode($msg, 'my_key', array('HS256')),
+            '*:http://application/clicky?blah=1.23&f.oo=456 AC000 123'
+        );
+    }
+
+    public function testUrlSafeCharacters()
+    {
+        $encoded = JWT::encode('f?', 'a');
+        $this->assertEquals('f?', JWT::decode($encoded, 'a', array('HS256')));
+    }
+
+    public function testMalformedUtf8StringsFail()
+    {
+        $this->setExpectedException('DomainException');
+        JWT::encode(pack('c', 128), 'a');
+    }
+
+    public function testMalformedJsonThrowsException()
+    {
+        $this->setExpectedException('DomainException');
+        JWT::jsonDecode('this is not valid JSON string');
+    }
+
+    public function testExpiredToken()
+    {
+        $this->setExpectedException('ExpiredException');
+        $payload = array(
+            "message" => "abc",
+            "exp" => time() - 20); // time in the past
+        $encoded = JWT::encode($payload, 'my_key');
+        JWT::decode($encoded, 'my_key', array('HS256'));
+    }
+
+    public function testBeforeValidTokenWithNbf()
+    {
+        $this->setExpectedException('BeforeValidException');
+        $payload = array(
+            "message" => "abc",
+            "nbf" => time() + 20); // time in the future
+        $encoded = JWT::encode($payload, 'my_key');
+        JWT::decode($encoded, 'my_key', array('HS256'));
+    }
+
+    public function testBeforeValidTokenWithIat()
+    {
+        $this->setExpectedException('BeforeValidException');
+        $payload = array(
+            "message" => "abc",
+            "iat" => time() + 20); // time in the future
+        $encoded = JWT::encode($payload, 'my_key');
+        JWT::decode($encoded, 'my_key', array('HS256'));
+    }
+
+    public function testValidToken()
+    {
+        $payload = array(
+            "message" => "abc",
+            "exp" => time() + JWT::$leeway + 20); // time in the future
+        $encoded = JWT::encode($payload, 'my_key');
+        $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
+        $this->assertEquals($decoded->message, 'abc');
+    }
+
+    public function testValidTokenWithLeeway()
+    {
+        JWT::$leeway = 60;
+        $payload = array(
+            "message" => "abc",
+            "exp" => time() - 20); // time in the past
+        $encoded = JWT::encode($payload, 'my_key');
+        $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
+        $this->assertEquals($decoded->message, 'abc');
+        JWT::$leeway = 0;
+    }
+
+    public function testExpiredTokenWithLeeway()
+    {
+        JWT::$leeway = 60;
+        $payload = array(
+            "message" => "abc",
+            "exp" => time() - 70); // time far in the past
+        $this->setExpectedException('ExpiredException');
+        $encoded = JWT::encode($payload, 'my_key');
+        $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
+        $this->assertEquals($decoded->message, 'abc');
+        JWT::$leeway = 0;
+    }
+
+    public function testValidTokenWithList()
+    {
+        $payload = array(
+            "message" => "abc",
+            "exp" => time() + 20); // time in the future
+        $encoded = JWT::encode($payload, 'my_key');
+        $decoded = JWT::decode($encoded, 'my_key', array('HS256', 'HS512'));
+        $this->assertEquals($decoded->message, 'abc');
+    }
+
+    public function testValidTokenWithNbf()
+    {
+        $payload = array(
+            "message" => "abc",
+            "iat" => time(),
+            "exp" => time() + 20, // time in the future
+            "nbf" => time() - 20);
+        $encoded = JWT::encode($payload, 'my_key');
+        $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
+        $this->assertEquals($decoded->message, 'abc');
+    }
+
+    public function testValidTokenWithNbfLeeway()
+    {
+        JWT::$leeway = 60;
+        $payload = array(
+            "message" => "abc",
+            "nbf"     => time() + 20); // not before in near (leeway) future
+        $encoded = JWT::encode($payload, 'my_key');
+        $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
+        $this->assertEquals($decoded->message, 'abc');
+        JWT::$leeway = 0;
+    }
+
+    public function testInvalidTokenWithNbfLeeway()
+    {
+        JWT::$leeway = 60;
+        $payload = array(
+            "message" => "abc",
+            "nbf"     => time() + 65); // not before too far in future
+        $encoded = JWT::encode($payload, 'my_key');
+        $this->setExpectedException('BeforeValidException');
+        $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
+        JWT::$leeway = 0;
+    }
+
+    public function testValidTokenWithIatLeeway()
+    {
+        JWT::$leeway = 60;
+        $payload = array(
+            "message" => "abc",
+            "iat"     => time() + 20); // issued in near (leeway) future
+        $encoded = JWT::encode($payload, 'my_key');
+        $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
+        $this->assertEquals($decoded->message, 'abc');
+        JWT::$leeway = 0;
+    }
+
+    public function testInvalidTokenWithIatLeeway()
+    {
+        JWT::$leeway = 60;
+        $payload = array(
+            "message" => "abc",
+            "iat"     => time() + 65); // issued too far in future
+        $encoded = JWT::encode($payload, 'my_key');
+        $this->setExpectedException('BeforeValidException');
+        $decoded = JWT::decode($encoded, 'my_key', array('HS256'));
+        JWT::$leeway = 0;
+    }
+
+    public function testInvalidToken()
+    {
+        $payload = array(
+            "message" => "abc",
+            "exp" => time() + 20); // time in the future
+        $encoded = JWT::encode($payload, 'my_key');
+        $this->setExpectedException('SignatureInvalidException');
+        $decoded = JWT::decode($encoded, 'my_key2', array('HS256'));
+    }
+
+    public function testRSEncodeDecode()
+    {
+        $privKey = openssl_pkey_new(array('digest_alg' => 'sha256',
+            'private_key_bits' => 1024,
+            'private_key_type' => OPENSSL_KEYTYPE_RSA));
+        $msg = JWT::encode('abc', $privKey, 'RS256');
+        $pubKey = openssl_pkey_get_details($privKey);
+        $pubKey = $pubKey['key'];
+        $decoded = JWT::decode($msg, $pubKey, array('RS256'));
+        $this->assertEquals($decoded, 'abc');
+    }
+
+    public function testKIDChooser()
+    {
+        $keys = array('1' => 'my_key', '2' => 'my_key2');
+        $msg = JWT::encode('abc', $keys['1'], 'HS256', '1');
+        $decoded = JWT::decode($msg, $keys, array('HS256'));
+        $this->assertEquals($decoded, 'abc');
+    }
+
+    public function testArrayAccessKIDChooser()
+    {
+        $keys = new ArrayObject(array('1' => 'my_key', '2' => 'my_key2'));
+        $msg = JWT::encode('abc', $keys['1'], 'HS256', '1');
+        $decoded = JWT::decode($msg, $keys, array('HS256'));
+        $this->assertEquals($decoded, 'abc');
+    }
+
+    public function testNoneAlgorithm()
+    {
+        $msg = JWT::encode('abc', 'my_key');
+        $this->setExpectedException('DomainException');
+        JWT::decode($msg, 'my_key', array('none'));
+    }
+
+    public function testIncorrectAlgorithm()
+    {
+        $msg = JWT::encode('abc', 'my_key');
+        $this->setExpectedException('DomainException');
+        JWT::decode($msg, 'my_key', array('RS256'));
+    }
+
+    public function testMissingAlgorithm()
+    {
+        $msg = JWT::encode('abc', 'my_key');
+        $this->setExpectedException('DomainException');
+        JWT::decode($msg, 'my_key');
+    }
+}
diff --git a/firebase/php-jwt/tests/autoload.php.dist 
b/firebase/php-jwt/tests/autoload.php.dist
new file mode 100644
index 0000000..2e4310a
--- /dev/null
+++ b/firebase/php-jwt/tests/autoload.php.dist
@@ -0,0 +1,17 @@
+<?php
+
+// if the library is the project, try to use the composer's autoload for the 
tests
+$composerAutoload = __DIR__ . '/../vendor/autoload.php';
+
+if (is_file($composerAutoload)) {
+    include $composerAutoload;
+} else {
+    die('Unable to find autoload.php file, please use composer to load 
dependencies:
+
+wget http://getcomposer.org/composer.phar
+php composer.phar install
+
+Visit http://getcomposer.org/ for more information.
+
+');
+}
diff --git a/firebase/php-jwt/tests/bootstrap.php 
b/firebase/php-jwt/tests/bootstrap.php
new file mode 100644
index 0000000..326c216
--- /dev/null
+++ b/firebase/php-jwt/tests/bootstrap.php
@@ -0,0 +1,7 @@
+<?php
+
+if (file_exists($file = __DIR__ . '/autoload.php')) {
+    require_once $file;
+} elseif (file_exists($file = __DIR__ . '/autoload.php.dist')) {
+    require_once $file;
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/226616
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I58af86204981a9f038b93df40e5c6c2f51fe06ae
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/vendor
Gerrit-Branch: master
Gerrit-Owner: Nikerabbit <[email protected]>
Gerrit-Reviewer: CSteipp <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: Nikerabbit <[email protected]>
Gerrit-Reviewer: Santhosh <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to