aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/api/ApiUtilsTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'tests/api/ApiUtilsTest.php')
-rw-r--r--tests/api/ApiUtilsTest.php206
1 files changed, 206 insertions, 0 deletions
diff --git a/tests/api/ApiUtilsTest.php b/tests/api/ApiUtilsTest.php
new file mode 100644
index 00000000..10da1459
--- /dev/null
+++ b/tests/api/ApiUtilsTest.php
@@ -0,0 +1,206 @@
1<?php
2
3namespace Shaarli\Api;
4
5/**
6 * Class ApiUtilsTest
7 */
8class ApiUtilsTest extends \PHPUnit_Framework_TestCase
9{
10 /**
11 * Force the timezone for ISO datetimes.
12 */
13 public static function setUpBeforeClass()
14 {
15 date_default_timezone_set('UTC');
16 }
17
18 /**
19 * Generate a valid JWT token.
20 *
21 * @param string $secret API secret used to generate the signature.
22 *
23 * @return string Generated token.
24 */
25 public static function generateValidJwtToken($secret)
26 {
27 $header = base64_encode('{
28 "typ": "JWT",
29 "alg": "HS512"
30 }');
31 $payload = base64_encode('{
32 "iat": '. time() .'
33 }');
34 $signature = hash_hmac('sha512', $header .'.'. $payload , $secret);
35 return $header .'.'. $payload .'.'. $signature;
36 }
37
38 /**
39 * Generate a JWT token from given header and payload.
40 *
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.
44 *
45 * @return string JWT token.
46 */
47 public static function generateCustomJwtToken($header, $payload, $secret)
48 {
49 $header = base64_encode($header);
50 $payload = base64_encode($payload);
51 $signature = hash_hmac('sha512', $header . '.' . $payload, $secret);
52 return $header . '.' . $payload . '.' . $signature;
53 }
54
55 /**
56 * Test validateJwtToken() with a valid JWT token.
57 */
58 public function testValidateJwtTokenValid()
59 {
60 $secret = 'WarIsPeace';
61 ApiUtils::validateJwtToken(self::generateValidJwtToken($secret), $secret);
62 }
63
64 /**
65 * Test validateJwtToken() with a malformed JWT token.
66 *
67 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
68 * @expectedExceptionMessage Malformed JWT token
69 */
70 public function testValidateJwtTokenMalformed()
71 {
72 $token = 'ABC.DEF';
73 ApiUtils::validateJwtToken($token, 'foo');
74 }
75
76 /**
77 * Test validateJwtToken() with an empty JWT token.
78 *
79 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
80 * @expectedExceptionMessage Malformed JWT token
81 */
82 public function testValidateJwtTokenMalformedEmpty()
83 {
84 $token = false;
85 ApiUtils::validateJwtToken($token, 'foo');
86 }
87
88 /**
89 * Test validateJwtToken() with a JWT token without header.
90 *
91 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
92 * @expectedExceptionMessage Malformed JWT token
93 */
94 public function testValidateJwtTokenMalformedEmptyHeader()
95 {
96 $token = '.payload.signature';
97 ApiUtils::validateJwtToken($token, 'foo');
98 }
99
100 /**
101 * Test validateJwtToken() with a JWT token without payload
102 *
103 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
104 * @expectedExceptionMessage Malformed JWT token
105 */
106 public function testValidateJwtTokenMalformedEmptyPayload()
107 {
108 $token = 'header..signature';
109 ApiUtils::validateJwtToken($token, 'foo');
110 }
111
112 /**
113 * Test validateJwtToken() with a JWT token with an empty signature.
114 *
115 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
116 * @expectedExceptionMessage Invalid JWT signature
117 */
118 public function testValidateJwtTokenInvalidSignatureEmpty()
119 {
120 $token = 'header.payload.';
121 ApiUtils::validateJwtToken($token, 'foo');
122 }
123
124 /**
125 * Test validateJwtToken() with a JWT token with an invalid signature.
126 *
127 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
128 * @expectedExceptionMessage Invalid JWT signature
129 */
130 public function testValidateJwtTokenInvalidSignature()
131 {
132 $token = 'header.payload.nope';
133 ApiUtils::validateJwtToken($token, 'foo');
134 }
135
136 /**
137 * Test validateJwtToken() with a JWT token with a signature generated with the wrong API secret.
138 *
139 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
140 * @expectedExceptionMessage Invalid JWT signature
141 */
142 public function testValidateJwtTokenInvalidSignatureSecret()
143 {
144 ApiUtils::validateJwtToken(self::generateValidJwtToken('foo'), 'bar');
145 }
146
147 /**
148 * Test validateJwtToken() with a JWT token with a an invalid header (not JSON).
149 *
150 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
151 * @expectedExceptionMessage Invalid JWT header
152 */
153 public function testValidateJwtTokenInvalidHeader()
154 {
155 $token = $this->generateCustomJwtToken('notJSON', '{"JSON":1}', 'secret');
156 ApiUtils::validateJwtToken($token, 'secret');
157 }
158
159 /**
160 * Test validateJwtToken() with a JWT token with a an invalid payload (not JSON).
161 *
162 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
163 * @expectedExceptionMessage Invalid JWT payload
164 */
165 public function testValidateJwtTokenInvalidPayload()
166 {
167 $token = $this->generateCustomJwtToken('{"JSON":1}', 'notJSON', 'secret');
168 ApiUtils::validateJwtToken($token, 'secret');
169 }
170
171 /**
172 * Test validateJwtToken() with a JWT token without issued time.
173 *
174 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
175 * @expectedExceptionMessage Invalid JWT issued time
176 */
177 public function testValidateJwtTokenInvalidTimeEmpty()
178 {
179 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"JSON":1}', 'secret');
180 ApiUtils::validateJwtToken($token, 'secret');
181 }
182
183 /**
184 * Test validateJwtToken() with an expired JWT token.
185 *
186 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
187 * @expectedExceptionMessage Invalid JWT issued time
188 */
189 public function testValidateJwtTokenInvalidTimeExpired()
190 {
191 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"iat":' . (time() - 600) . '}', 'secret');
192 ApiUtils::validateJwtToken($token, 'secret');
193 }
194
195 /**
196 * Test validateJwtToken() with a JWT token issued in the future.
197 *
198 * @expectedException \Shaarli\Api\Exceptions\ApiAuthorizationException
199 * @expectedExceptionMessage Invalid JWT issued time
200 */
201 public function testValidateJwtTokenInvalidTimeFuture()
202 {
203 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"iat":' . (time() + 60) . '}', 'secret');
204 ApiUtils::validateJwtToken($token, 'secret');
205 }
206}