Skip to content

Commit

Permalink
Merge pull request #8 from adhocore/develop
Browse files Browse the repository at this point in the history
Support php5.5
  • Loading branch information
adhocore authored Jul 14, 2018
2 parents 3cbbf06 + 7eb47d9 commit c2e6c8b
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@ git:

language: php
php:
- 5.5
- 5.6
- 7.0
- 7.1
- 7.2

install:
- composer install --prefer-dist

before_script:
- for P in src tests; do find $P -type f -name '*.php' -exec php -l {} \;; done

script:
- vendor/bin/phpunit --coverage-text --coverage-clover=coverage.xml

Expand Down
9 changes: 5 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "adhocore/jwt",
"description": "Ultra lightweight JSON web token (JWT) library for PHP7.",
"description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.",
"type": "library",
"keywords": [
"jwt", "jwt-php", "auth", "json-web-token", "token"
Expand All @@ -15,17 +15,18 @@
"autoload": {
"psr-4": {
"Ahc\\Jwt\\": "src/"
}
},
"files": ["src/functions.php"]
},
"autoload-dev": {
"psr-4": {
"Ahc\\Jwt\\Test\\": "tests/"
}
},
"require": {
"php": ">=7.0"
"php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "^6.0.0"
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5"
}
}
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)


- Lightweight JSON Web Token (JWT) library for PHP7.
- Lightweight JSON Web Token (JWT) library for PHP5.5 or newer.

## Installation
```
Expand Down
22 changes: 11 additions & 11 deletions src/JWT.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Ahc\Jwt;

/**
* JSON Web Token (JWT) implementation in PHP7.
* JSON Web Token (JWT) implementation in PHP5.5+.
*
* @author Jitendra Adhikari <jiten.adhikary@gmail.com>
* @license MIT
Expand Down Expand Up @@ -68,7 +68,7 @@ class JWT
* @param int $leeway Leeway for clock skew. Shouldnot be more than 2 minutes (120s).
* @param string $pass The passphrase (only for RS* algos).
*/
public function __construct($key, string $algo = 'HS256', int $maxAge = 3600, int $leeway = 0, string $pass = null)
public function __construct($key, $algo = 'HS256', $maxAge = 3600, $leeway = 0, $pass = null)
{
$this->validateConfig($key, $algo, $maxAge, $leeway);

Expand All @@ -91,7 +91,7 @@ public function __construct($key, string $algo = 'HS256', int $maxAge = 3600, in
*
* @return self
*/
public function registerKeys(array $keys): self
public function registerKeys(array $keys)
{
$this->keys = \array_merge($this->keys, $keys);

Expand All @@ -106,14 +106,14 @@ public function registerKeys(array $keys): self
*
* @return string URL safe JWT token.
*/
public function encode(array $payload, array $header = []) : string
public function encode(array $payload, array $header = [])
{
$header = ['typ' => 'JWT', 'alg' => $this->algo] + $header;

$this->validateKid($header);

if (!isset($payload['iat']) && !isset($payload['exp'])) {
$payload['exp'] = ($this->timestamp ?? \time()) + $this->maxAge;
$payload['exp'] = ($this->timestamp ?: \time()) + $this->maxAge;
}

$header = $this->urlSafeEncode($header);
Expand All @@ -130,7 +130,7 @@ public function encode(array $payload, array $header = []) : string
*
* @return array
*/
public function decode(string $token) : array
public function decode($token)
{
if (\substr_count($token, '.') < 2) {
throw new JWTException('Invalid token: Incomplete segments', static::ERROR_TOKEN_INVALID);
Expand All @@ -156,7 +156,7 @@ public function decode(string $token) : array
*
* @param int|null $timestamp
*/
public function setTestTimestamp(int $timestamp = null) : JWT
public function setTestTimestamp($timestamp = null)
{
$this->timestamp = $timestamp;

Expand All @@ -170,7 +170,7 @@ public function setTestTimestamp(int $timestamp = null) : JWT
*
* @return string
*/
protected function sign(string $input) : string
protected function sign($input)
{
// HMAC SHA.
if (\substr($this->algo, 0, 2) === 'HS') {
Expand All @@ -194,7 +194,7 @@ protected function sign(string $input) : string
*
* @return bool
*/
protected function verify(string $input, string $signature) : bool
protected function verify($input, $signature)
{
$algo = $this->algos[$this->algo];

Expand All @@ -221,7 +221,7 @@ protected function verify(string $input, string $signature) : bool
*
* @return string
*/
protected function urlSafeEncode($data) : string
protected function urlSafeEncode($data)
{
if (\is_array($data)) {
$data = \json_encode($data, JSON_UNESCAPED_SLASHES);
Expand All @@ -241,7 +241,7 @@ protected function urlSafeEncode($data) : string
*
* @return array|\stdClass|string
*/
protected function urlSafeDecode(string $data, bool $asJson = true)
protected function urlSafeDecode($data, $asJson = true)
{
if (!$asJson) {
return \base64_decode(\strtr($data, '-_', '+/'));
Expand Down
6 changes: 3 additions & 3 deletions src/ValidatesJWT.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ trait ValidatesJWT
*
* @codeCoverageIgnore
*/
protected function validateConfig($key, string $algo, int $maxAge, int $leeway)
protected function validateConfig($key, $algo, $maxAge, $leeway)
{
if (empty($key)) {
throw new JWTException('Signing key cannot be empty', static::ERROR_KEY_EMPTY);
Expand Down Expand Up @@ -71,7 +71,7 @@ protected function validateKid(array $header)
*/
protected function validateTimestamps(array $payload)
{
$timestamp = $this->timestamp ?? \time();
$timestamp = $this->timestamp ?: \time();
$checks = [
['exp', $this->leeway /* */ , static::ERROR_TOKEN_EXPIRED, 'Expired'],
['iat', $this->maxAge - $this->leeway, static::ERROR_TOKEN_EXPIRED, 'Expired'],
Expand Down Expand Up @@ -100,7 +100,7 @@ protected function validateKey()
$key = 'file://' . $key;
}

$this->key = \openssl_get_privatekey($key, $this->passphrase ?? '');
$this->key = \openssl_get_privatekey($key, $this->passphrase ?: '');
}

if (!\is_resource($this->key)) {
Expand Down
23 changes: 23 additions & 0 deletions src/functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

// @codeCoverageIgnoreStart
if (!\function_exists('hash_equals')) {
// PHP5.5 compat.
// @see http://php.net/manual/en/function.hash-equals.php#115635
function hash_equals($str1, $str2)
{
if (\strlen($str1) !== \strlen($str2)) {
return false;
}

$ret = 0;
$res = $str1 ^ $str2;

for ($i = \strlen($res) - 1; $i >= 0; $i--) {
$ret |= ord($res[$i]);
}

return !$ret;
}
}
// @codeCoverageIgnoreEnd
41 changes: 22 additions & 19 deletions tests/JWTTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
namespace Ahc\Jwt\Test;

use Ahc\Jwt\JWT;
use Ahc\Jwt\JWTException;

/** @coversDefaultClass \Ahc\Jwt\JWT */
class JWTTest extends \PHPUnit\Framework\TestCase
{
/** @dataProvider data1 */
public function test_decode_encoded_token(string $key, string $algo, int $age, int $leeway, array $payload, array $header = [])
public function test_decode_encoded_token($key, $algo, $age, $leeway, array $payload, array $header = [])
{
$jwt = new JWT($key, $algo, $age, $leeway);
$token = $jwt->encode($payload, $header);
Expand All @@ -26,26 +25,28 @@ public function test_decode_encoded_token(string $key, string $algo, int $age, i
$this->assertSame($payload, $decoded);
}

/**
* @expectedException \Ahc\Jwt\JWTException
*/
public function test_json_fail()
{
$this->expectException(JWTException::class);

$jwt = new JWT('very^secre7');

try {
$jwt->encode([random_bytes(10)]);
$jwt->encode([base64_decode('mF6u28o4K2cD3w==')]);
} catch (\Exception $e) {
$this->assertSame($e->getCode(), JWT::ERROR_JSON_FAILED, $e->getMessage());

throw $e;
}
}

/** @dataProvider data2 */
public function test_decode_fail(string $key, string $algo, int $age, int $leeway, int $offset, int $error, $token)
/**
* @dataProvider data2
* @expectedException \Ahc\Jwt\JWTException
*/
public function test_decode_fail($key, $algo, $age, $leeway, $offset, $error, $token)
{
$this->expectException(JWTException::class);

$jwt = new JWT($key, $algo, $age, $leeway);
$token = is_string($token) ? $token : $jwt->encode($token);

Expand All @@ -63,7 +64,7 @@ public function test_decode_fail(string $key, string $algo, int $age, int $leewa
}

/** @dataProvider data1 */
public function test_rs_decode_encoded(string $key, string $algo, int $age, int $leeway, array $payload, array $header = [])
public function test_rs_decode_encoded($key, $algo, $age, $leeway, array $payload, array $header = [])
{
$key = __DIR__ . '/stubs/priv.key';
$jwt = new JWT($key, str_replace('HS', 'RS', $algo), $age, $leeway);
Expand All @@ -81,11 +82,12 @@ public function test_rs_decode_encoded(string $key, string $algo, int $age, int
$this->assertSame($payload, $decoded);
}

/** @dataProvider data3 */
public function test_rs_invalid_key(string $method, string $key, $arg)
/**
* @dataProvider data3
* @expectedException \Ahc\Jwt\JWTException
*/
public function test_rs_invalid_key($method, $key, $arg)
{
$this->expectException(JWTException::class);

$jwt = new JWT($key, 'RS256');

try {
Expand All @@ -109,19 +111,20 @@ public function test_kid()
return $jwt;
}

/**
* @expectedException \Ahc\Jwt\JWTException
* @expectedExceptionMessage Invalid token: Unknown key ID
*/
public function test_kid_invalid()
{
// keys can be sent as array too
$jwt = new JWT(['key1' => 'secret1', 'key2' => 'secret2'], 'HS256');

$this->expectException(JWTException::class);
$this->expectExceptionMessage('Invalid token: Unknown key ID');

// Use key3
$jwt->encode(['a' => 1, 'exp' => time() + 1000], ['kid' => 'key3']);
}

public function data1() : array
public function data1()
{
return [
['secret', 'HS256', rand(10, 1000), rand(1, 10), [
Expand Down Expand Up @@ -152,7 +155,7 @@ public function data1() : array
];
}

public function data2() : array
public function data2()
{
return [
['topsecret', 'HS256', 5, 0, 0, JWT::ERROR_TOKEN_INVALID, 'a.b'],
Expand Down

0 comments on commit c2e6c8b

Please sign in to comment.