8 class ApiUtilsTest
extends \PHPUnit_Framework_TestCase
11 * Force the timezone for ISO datetimes.
13 public static function setUpBeforeClass()
15 date_default_timezone_set('UTC');
19 * Generate a valid JWT token.
21 * @param string $secret API secret used to generate the signature.
23 * @return string Generated token.
25 public static function generateValidJwtToken($secret)
27 $header = base64_encode('{
31 $payload = base64_encode('{
34 $signature = hash_hmac('sha512', $header .'.'. $payload , $secret);
35 return $header .'.'. $payload .'.'. $signature;
39 * Generate a JWT token from given header and payload.
41 * @param string $header Header in JSON format.
42 * @param string $payload Payload in JSON format.
43 * @param string $secret API secret used to hash the signature.
45 * @return string JWT token.
47 public static function generateCustomJwtToken($header, $payload, $secret)
49 $header = base64_encode($header);
50 $payload = base64_encode($payload);
51 $signature = hash_hmac('sha512', $header . '.' . $payload, $secret);
52 return $header . '.' . $payload . '.' . $signature;
56 * Test validateJwtToken() with a valid JWT token.
58 public function testValidateJwtTokenValid()
60 $secret = 'WarIsPeace';
61 ApiUtils
::validateJwtToken(self
::generateValidJwtToken($secret), $secret);
65 * Test validateJwtToken() with a malformed JWT token.
67 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
68 * @expectedExceptionMessage Malformed JWT token
70 public function testValidateJwtTokenMalformed()
73 ApiUtils
::validateJwtToken($token, 'foo');
77 * Test validateJwtToken() with an empty JWT token.
79 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
80 * @expectedExceptionMessage Malformed JWT token
82 public function testValidateJwtTokenMalformedEmpty()
85 ApiUtils
::validateJwtToken($token, 'foo');
89 * Test validateJwtToken() with a JWT token without header.
91 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
92 * @expectedExceptionMessage Malformed JWT token
94 public function testValidateJwtTokenMalformedEmptyHeader()
96 $token = '.payload.signature';
97 ApiUtils
::validateJwtToken($token, 'foo');
101 * Test validateJwtToken() with a JWT token without payload
103 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
104 * @expectedExceptionMessage Malformed JWT token
106 public function testValidateJwtTokenMalformedEmptyPayload()
108 $token = 'header..signature';
109 ApiUtils
::validateJwtToken($token, 'foo');
113 * Test validateJwtToken() with a JWT token with an empty signature.
115 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
116 * @expectedExceptionMessage Invalid JWT signature
118 public function testValidateJwtTokenInvalidSignatureEmpty()
120 $token = 'header.payload.';
121 ApiUtils
::validateJwtToken($token, 'foo');
125 * Test validateJwtToken() with a JWT token with an invalid signature.
127 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
128 * @expectedExceptionMessage Invalid JWT signature
130 public function testValidateJwtTokenInvalidSignature()
132 $token = 'header.payload.nope';
133 ApiUtils
::validateJwtToken($token, 'foo');
137 * Test validateJwtToken() with a JWT token with a signature generated with the wrong API secret.
139 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
140 * @expectedExceptionMessage Invalid JWT signature
142 public function testValidateJwtTokenInvalidSignatureSecret()
144 ApiUtils
::validateJwtToken(self
::generateValidJwtToken('foo'), 'bar');
148 * Test validateJwtToken() with a JWT token with a an invalid header (not JSON).
150 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
151 * @expectedExceptionMessage Invalid JWT header
153 public function testValidateJwtTokenInvalidHeader()
155 $token = $this->generateCustomJwtToken('notJSON', '{"JSON":1}', 'secret');
156 ApiUtils
::validateJwtToken($token, 'secret');
160 * Test validateJwtToken() with a JWT token with a an invalid payload (not JSON).
162 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
163 * @expectedExceptionMessage Invalid JWT payload
165 public function testValidateJwtTokenInvalidPayload()
167 $token = $this->generateCustomJwtToken('{"JSON":1}', 'notJSON', 'secret');
168 ApiUtils
::validateJwtToken($token, 'secret');
172 * Test validateJwtToken() with a JWT token without issued time.
174 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
175 * @expectedExceptionMessage Invalid JWT issued time
177 public function testValidateJwtTokenInvalidTimeEmpty()
179 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"JSON":1}', 'secret');
180 ApiUtils
::validateJwtToken($token, 'secret');
184 * Test validateJwtToken() with an expired JWT token.
186 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
187 * @expectedExceptionMessage Invalid JWT issued time
189 public function testValidateJwtTokenInvalidTimeExpired()
191 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"iat":' . (time() - 600) . '}', 'secret');
192 ApiUtils
::validateJwtToken($token, 'secret');
196 * Test validateJwtToken() with a JWT token issued in the future.
198 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
199 * @expectedExceptionMessage Invalid JWT issued time
201 public function testValidateJwtTokenInvalidTimeFuture()
203 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"iat":' . (time() + 60) . '}', 'secret');
204 ApiUtils
::validateJwtToken($token, 'secret');