11 class ApiUtilsTest
extends \PHPUnit_Framework_TestCase
14 * Force the timezone for ISO datetimes.
16 public static function setUpBeforeClass()
18 date_default_timezone_set('UTC');
22 * Generate a valid JWT token.
24 * @param string $secret API secret used to generate the signature.
26 * @return string Generated token.
28 public static function generateValidJwtToken($secret)
30 $header = Base64Url
::encode('{
34 $payload = Base64Url
::encode('{
37 $signature = Base64Url
::encode(hash_hmac('sha512', $header .'.'. $payload , $secret, true));
38 return $header .'.'. $payload .'.'. $signature;
42 * Generate a JWT token from given header and payload.
44 * @param string $header Header in JSON format.
45 * @param string $payload Payload in JSON format.
46 * @param string $secret API secret used to hash the signature.
48 * @return string JWT token.
50 public static function generateCustomJwtToken($header, $payload, $secret)
52 $header = Base64Url
::encode($header);
53 $payload = Base64Url
::encode($payload);
54 $signature = Base64Url
::encode(hash_hmac('sha512', $header . '.' . $payload, $secret, true));
55 return $header . '.' . $payload . '.' . $signature;
59 * Test validateJwtToken() with a valid JWT token.
61 public function testValidateJwtTokenValid()
63 $secret = 'WarIsPeace';
64 ApiUtils
::validateJwtToken(self
::generateValidJwtToken($secret), $secret);
68 * Test validateJwtToken() with a malformed JWT token.
70 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
71 * @expectedExceptionMessage Malformed JWT token
73 public function testValidateJwtTokenMalformed()
76 ApiUtils
::validateJwtToken($token, 'foo');
80 * Test validateJwtToken() with an empty JWT token.
82 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
83 * @expectedExceptionMessage Malformed JWT token
85 public function testValidateJwtTokenMalformedEmpty()
88 ApiUtils
::validateJwtToken($token, 'foo');
92 * Test validateJwtToken() with a JWT token without header.
94 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
95 * @expectedExceptionMessage Malformed JWT token
97 public function testValidateJwtTokenMalformedEmptyHeader()
99 $token = '.payload.signature';
100 ApiUtils
::validateJwtToken($token, 'foo');
104 * Test validateJwtToken() with a JWT token without payload
106 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
107 * @expectedExceptionMessage Malformed JWT token
109 public function testValidateJwtTokenMalformedEmptyPayload()
111 $token = 'header..signature';
112 ApiUtils
::validateJwtToken($token, 'foo');
116 * Test validateJwtToken() with a JWT token with an empty signature.
118 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
119 * @expectedExceptionMessage Invalid JWT signature
121 public function testValidateJwtTokenInvalidSignatureEmpty()
123 $token = 'header.payload.';
124 ApiUtils
::validateJwtToken($token, 'foo');
128 * Test validateJwtToken() with a JWT token with an invalid signature.
130 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
131 * @expectedExceptionMessage Invalid JWT signature
133 public function testValidateJwtTokenInvalidSignature()
135 $token = 'header.payload.nope';
136 ApiUtils
::validateJwtToken($token, 'foo');
140 * Test validateJwtToken() with a JWT token with a signature generated with the wrong API secret.
142 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
143 * @expectedExceptionMessage Invalid JWT signature
145 public function testValidateJwtTokenInvalidSignatureSecret()
147 ApiUtils
::validateJwtToken(self
::generateValidJwtToken('foo'), 'bar');
151 * Test validateJwtToken() with a JWT token with a an invalid header (not JSON).
153 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
154 * @expectedExceptionMessage Invalid JWT header
156 public function testValidateJwtTokenInvalidHeader()
158 $token = $this->generateCustomJwtToken('notJSON', '{"JSON":1}', 'secret');
159 ApiUtils
::validateJwtToken($token, 'secret');
163 * Test validateJwtToken() with a JWT token with a an invalid payload (not JSON).
165 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
166 * @expectedExceptionMessage Invalid JWT payload
168 public function testValidateJwtTokenInvalidPayload()
170 $token = $this->generateCustomJwtToken('{"JSON":1}', 'notJSON', 'secret');
171 ApiUtils
::validateJwtToken($token, 'secret');
175 * Test validateJwtToken() with a JWT token without issued time.
177 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
178 * @expectedExceptionMessage Invalid JWT issued time
180 public function testValidateJwtTokenInvalidTimeEmpty()
182 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"JSON":1}', 'secret');
183 ApiUtils
::validateJwtToken($token, 'secret');
187 * Test validateJwtToken() with an expired JWT token.
189 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
190 * @expectedExceptionMessage Invalid JWT issued time
192 public function testValidateJwtTokenInvalidTimeExpired()
194 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"iat":' . (time() - 600) . '}', 'secret');
195 ApiUtils
::validateJwtToken($token, 'secret');
199 * Test validateJwtToken() with a JWT token issued in the future.
201 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
202 * @expectedExceptionMessage Invalid JWT issued time
204 public function testValidateJwtTokenInvalidTimeFuture()
206 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"iat":' . (time() + 60) . '}', 'secret');
207 ApiUtils
::validateJwtToken($token, 'secret');