ILIAS  release_8 Revision v8.24
ilWACTokenTest.php
Go to the documentation of this file.
1<?php
18// declare(strict_types=1);
19require_once('./libs/composer/vendor/autoload.php');
20
26use Mockery\Adapter\Phpunit\MockeryTestCase;
27use Mockery\MockInterface;
28use org\bovigo\vfs;
29use Psr\Http\Message\ResponseInterface;
31use Dflydev\FigCookies\SetCookie;
32
43class ilWACTokenTest extends MockeryTestCase
44{
45 public const ADDITIONAL_TIME = 1;
46 public const LIFETIME = 2;
47 public const SALT = 'SALT';
48 public const CLIENT_NAME = 'client_name';
52 protected $backupGlobals = false;
56 protected $file_one;
68 protected $file_two;
72 protected $file_three;
76 protected $file_four;
80 protected $root;
84 private $http;
89
90
94 protected function setUp(): void
95 {
96 parent::setUp();
97
98 $this->root = vfs\vfsStream::setup('ilias.de');
99 $this->file_one = vfs\vfsStream::newFile('data/client_name/mobs/mm_123/dummy.jpg')
100 ->at($this->root)->setContent('dummy');
101 $this->file_one_subfolder = vfs\vfsStream::newFile('data/client_name/mobs/mm_123/mobile/dummy.jpg')
102 ->at($this->root)->setContent('dummy');
103 $this->file_one_subfolder_two = vfs\vfsStream::newFile('data/client_name/mobs/mm_123/mobile/device/dummy.jpg')
104 ->at($this->root)->setContent('dummy');
105 $this->file_two = vfs\vfsStream::newFile('data/client_name/mobs/mm_123/dummy2.jpg')
106 ->at($this->root)->setContent('dummy2');
107 $this->file_three = vfs\vfsStream::newFile('data/client_name/mobs/mm_124/dummy.jpg')
108 ->at($this->root)->setContent('dummy');
109 $this->file_four = vfs\vfsStream::newFile('data/client_name/sec/ilBlog/mm_124/dummy.jpg')
110 ->at($this->root)->setContent('dummy');
111
112 //setup container for HttpServiceAware classes
113 $container = new \ILIAS\DI\Container();
114 $container['http'] = fn($c) => Mockery::mock(GlobalHttpState::class);
115
116 $this->http = $container['http'];
117
118
119 $GLOBALS["DIC"] = $container;
120
121 $this->cookieFactory = Mockery::mock(CookieFactoryImpl::class);
122
123 //because the cookie have no logic except cloning it self therefore it should be no problem to defer the function calls
124 $this->cookieFactory->shouldDeferMissing();
125
126 ilWACToken::setSALT(self::SALT);
127 }
128
129
130 public function testWithoutSigning(): void
131 {
132 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($this->file_one->url(), false), $this->http, $this->cookieFactory);
133
134 $cookieJar = Mockery::mock(CookieJar::class);
135
136 $cookieJar
137 ->shouldReceive('getAll')
138 ->times(2)
139 ->withAnyArgs()
140 ->andReturn([]);
141
142 $this->http->shouldReceive('cookieJar')
143 ->twice()
144 ->withNoArgs()
145 ->andReturn($cookieJar);
146
147 $request = Mockery::mock(Psr\Http\Message\RequestInterface::class);
148 $request->shouldReceive('getCookieParams')
149 ->andReturn([]);
150
151 $this->http->shouldReceive('request')
152 ->withNoArgs()
153 ->andReturn($request);
154
155 $this->assertFalse($ilWACSignedPath->isSignedPath());
156 $this->assertFalse($ilWACSignedPath->isSignedPathValid());
157 $this->assertFalse($ilWACSignedPath->isFolderSigned());
158 $this->assertFalse($ilWACSignedPath->isFolderTokenValid());
159 }
160
161
162 public function testSomeBasics(): void
163 {
164 $query = 'myparam=1234';
165 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($this->file_four->url() . '?'
166 . $query, false), $this->http, $this->cookieFactory);
167
168 $this->assertEquals('dummy.jpg', $ilWACSignedPath->getPathObject()->getFileName());
169 $this->assertEquals($query, $ilWACSignedPath->getPathObject()->getQuery());
170 $this->assertEquals('./data/' . self::CLIENT_NAME
171 . '/sec/ilBlog/mm_124/', $ilWACSignedPath->getPathObject()
172 ->getSecurePath());
173 $this->assertEquals('ilBlog', $ilWACSignedPath->getPathObject()->getSecurePathId());
174 $this->assertFalse($ilWACSignedPath->getPathObject()->isStreamable());
175 }
176
177
178 public function testTokenGeneration(): void
179 {
180 $ilWacPath = new ilWacPath($this->file_four->url(), false);
181 $ilWACToken = new ilWACToken($ilWacPath->getPath(), self::CLIENT_NAME, 123456, 20);
182 $ilWACToken->generateToken();
183 $this->assertEquals('SALT-client_name-123456-20', $ilWACToken->getRawToken());
184 $this->assertEquals('./data/client_name/sec/ilBlog/mm_124/dummy.jpg', $ilWACToken->getId());
185
186 $this->assertEquals(self::SALT, ilWACToken::getSALT());
187 $ilWACToken = new ilWACToken($ilWacPath->getPath(), self::CLIENT_NAME, 123456, 20);
188 $this->assertEquals('b541e2bae42ee222f9be959b7ad2ab8844cbb05b', $ilWACToken->getToken());
189 $this->assertEquals('e45b98f267dc891c8206c844f7df29ea', $ilWACToken->getHashedId());
190 }
191
192
193 public function testCookieGeneration(): void
194 {
195 $this->markTestSkipped('unable to use http cookies at this point');
196
197 $cookieJar = Mockery::mock(CookieJar::class);
198
199 $response = Mockery::mock(ResponseInterface::class);
200
201 $this->http
202 ->shouldReceive('response')
203 ->times(3)
204 ->withNoArgs()
205 ->andReturn($response)
206 ->getMock();
207
208 $cookieJar
209 ->shouldReceive('with')
210 ->times(3)
211 ->with(new CookieWrapper(SetCookie::create('')))
212 ->andReturnSelf()
213 ->getMock()
214
215 ->shouldReceive('with')
216 ->times(3)
217 ->with(new CookieWrapper(SetCookie::create('')))
218 ->andReturnSelf()
219 ->getMock()
220
221 ->shouldReceive('with')
222 ->times(3)
223 ->with(new CookieWrapper(SetCookie::create('')))
224 ->andReturnSelf()
225 ->getMock();
226
227 $this->http->shouldReceive('cookieJar')
228 ->withNoArgs()
229 ->andReturn($cookieJar);
230
231 ilWACSignedPath::signFolderOfStartFile($this->file_one->url());
232
233 // in subfolder
234 ilWACSignedPath::signFolderOfStartFile($this->file_one_subfolder->url());
235
236 // in sub-subfolder
237 ilWACSignedPath::signFolderOfStartFile($this->file_one_subfolder->url());
238 }
239
240
241 public function testFileToken(): void
242 {
245
246 // Request within lifetime
247 $signed_path = ilWACSignedPath::signFile($this->file_one->url());
248 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($signed_path, false), $this->http, $this->cookieFactory);
249
250 $this->assertTrue($ilWACSignedPath->isSignedPath());
251 $this->assertTrue($ilWACSignedPath->isSignedPathValid());
252 $this->assertEquals($ilWACSignedPath->getPathObject()->getClient(), self::CLIENT_NAME);
253 $this->assertFalse($ilWACSignedPath->getPathObject()->isInSecFolder());
254 $this->assertTrue($ilWACSignedPath->getPathObject()->isImage());
255 $this->assertFalse($ilWACSignedPath->getPathObject()->isAudio());
256 $this->assertFalse($ilWACSignedPath->getPathObject()->isVideo());
257 $this->assertTrue($ilWACSignedPath->getPathObject()->hasTimestamp());
258 $this->assertTrue($ilWACSignedPath->getPathObject()->hasToken());
259
260 // Request after lifetime
261 $signed_path = ilWACSignedPath::signFile($this->file_four->url());
262 sleep($lifetime + self::ADDITIONAL_TIME);
263 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($signed_path, false), $this->http, $this->cookieFactory);
264 $this->assertTrue($ilWACSignedPath->isSignedPath());
265 $this->assertFalse($ilWACSignedPath->isSignedPathValid());
266 }
267
268
269
273 public function testModifiedTimestampNoMod(): void
274 {
275 // self::markTestSkipped("WIP");
276 // return;
277 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($this->getModifiedSignedPath(0, 0), false), $this->http, $this->cookieFactory);
278 $this->assertTrue($ilWACSignedPath->isSignedPath());
279 $this->assertTrue($ilWACSignedPath->isSignedPathValid());
280 }
281
282
286 public function testModifiedTimestampAddTime(): void
287 {
288 // self::markTestSkipped("WIP");
289 // return;
290 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($this->getModifiedSignedPath(self::ADDITIONAL_TIME, 0), false), $this->http, $this->cookieFactory);
291 $this->assertTrue($ilWACSignedPath->isSignedPath());
292 $this->assertFalse($ilWACSignedPath->isSignedPathValid());
293 }
294
295
296 public function testModifiedTimestampSubTime(): void
297 {
298 // self::markTestSkipped("WIP");
299 // return;
300 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($this->getModifiedSignedPath(self::ADDITIONAL_TIME
301 * -1, 0), false), $this->http, $this->cookieFactory);
302 $this->assertTrue($ilWACSignedPath->isSignedPath());
303 $this->assertFalse($ilWACSignedPath->isSignedPathValid());
304 }
305
306
307 public function testModifiedTTL(): void
308 {
309 // self::markTestSkipped("WIP");
310 // return;
311 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($this->getModifiedSignedPath(0, 1), false), $this->http, $this->cookieFactory);
312 $this->assertTrue($ilWACSignedPath->isSignedPath());
313 $this->assertFalse($ilWACSignedPath->isSignedPathValid());
314 }
315
316
317 public function testModifiedTTLAndTimestamp(): void
318 {
319 // self::markTestSkipped("WIP");
320 // return;
321 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($this->getModifiedSignedPath(1, 1), false), $this->http, $this->cookieFactory);
322 $this->assertTrue($ilWACSignedPath->isSignedPath());
323 $this->assertFalse($ilWACSignedPath->isSignedPathValid());
324 }
325
326
327 public function testModifiedToken(): void
328 {
329 // self::markTestSkipped("WIP");
330 // return;
331 $ilWACSignedPath = new ilWACSignedPath(new ilWACPath($this->getModifiedSignedPath(0, 0, md5('LOREM')), false), $this->http, $this->cookieFactory);
332 $this->assertTrue($ilWACSignedPath->isSignedPath());
333 $this->assertFalse($ilWACSignedPath->isSignedPathValid());
334 }
335
336
340 protected function getModifiedSignedPath(int $add_ttl = 0, int $add_timestamp = 0, $override_token = null): string
341 {
343 $signed_path = ilWACSignedPath::signFile($this->file_one->url());
344
345 $parts = parse_url($signed_path);
346 $path = $parts['path'];
347 $query = $parts['query'];
348 parse_str($query, $query_array);
349 $token = $override_token ? $override_token : $query_array['il_wac_token'];
350 $ttl = (int) $query_array['il_wac_ttl'];
351 $ts = (int) $query_array['il_wac_ts'];
352 $path_with_token = $path . '?il_wac_token=' . $token;
353
354 $modified_ttl = $ttl + $add_ttl;
355 $modified_ts = $ts + $add_timestamp;
356
357 return $path_with_token . '&il_wac_ttl=' . $modified_ttl . '&il_wac_ts=' . $modified_ts;
358 }
359}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilWACSignedPath.
static setTokenMaxLifetimeInSeconds(int $token_max_lifetime_in_seconds)
static signFolderOfStartFile(string $start_file_path)
static signFile(string $path_to_file)
static getTokenMaxLifetimeInSeconds()
TestCase for the ilWACTokenTest.
testModifiedTimestampNoMod()
@Test
testModifiedTimestampAddTime()
@Test
getModifiedSignedPath(int $add_ttl=0, int $add_timestamp=0, $override_token=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getSALT()
static setSALT(string $salt)
$c
Definition: cli.php:38
const CLIENT_NAME
Definition: constants.php:42
Interface GlobalHttpState.
$path
Definition: ltiservices.php:32
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:64
static http()
Fetches the global http state from ILIAS.
$query
$response
$container
@noRector
Definition: wac.php:14
$token
Definition: xapitoken.php:70