public function JwtPathAuthTest::testPathAdmin in JSON Web Token Authentication (JWT) 8
Test admin form updates and actual path auth.
File
- tests/
src/ Functional/ JwtPathAuthTest.php, line 83
Class
- JwtPathAuthTest
- Tests path-based authentication.
Namespace
Drupal\Tests\jwt\FunctionalCode
public function testPathAdmin() {
$this
->drupalLogin($this->adminUser);
$url = Url::fromRoute('jwt_path_auth.config_form');
$this
->drupalGet($url);
$edit = [
'allowed_path_prefixes' => "/system/files/\nzzz",
];
$this
->drupalPostForm(NULL, $edit, 'Save configuration');
$this
->assertText('Paths must start with a slash.');
$edit = [
'allowed_path_prefixes' => "/system/files/\r\n/foo/zzz/ \r\n/entity/file/",
];
$this
->drupalPostForm(NULL, $edit, 'Save configuration');
$config = $this
->config('jwt_path_auth.config');
$expected = [
'/system/files/',
'/foo/zzz/',
'/entity/file/',
];
$this
->assertSame($expected, $config
->get('allowed_path_prefixes'));
/** @var \Drupal\Core\File\FileSystemInterface $file_system */
$file_system = $this->container
->get('file_system');
// A temporary private file can be access by the creator.
// @see file_file_download().
$file = $this
->createPrivateFile('drupal.txt', $this->adminUser
->id(), 0);
// Make sure the logged-in user can access the file.
$file_real_path = $file_system
->realpath($file
->getFileUri());
$this
->assertFileExists($file_real_path);
$this
->drupalGet($file
->createFileUrl());
$this
->assertResponse(200);
$this
->assertText($this
->getFileContent($file));
// Make sure the logged-in user can access the REST resource. The path
// should be '/entity/file/' . $file->id().
$options = [
'query' => [
'_format' => 'json',
],
];
$file_rest_url = Url::fromRoute('rest.entity.file.GET', [
'file' => $file
->id(),
], $options);
$this
->drupalGet($file_rest_url);
$this
->assertResponse(200);
$this
->drupalLogout();
// Expect a 403 when not authenticated.
$this
->drupalGet($file
->createFileUrl());
$this
->assertResponse(403);
// When Drupal is in a subdirectory (such as drupal.org testbot) any
// path in the JWT other than a "/" must bre prefixed with the base
// path - the system does not expect the client to know where Drupal
// is actually installed in terms of path hierarchy.
$base_url = $this->container
->get('router.request_context')
->getBaseUrl();
/** @var \Drupal\jwt\Transcoder\JwtTranscoderInterface $transcoder */
$transcoder = $this->container
->get('jwt.transcoder');
$jwt = new JsonWebToken();
$jwt
->setClaim([
'drupal',
'path_auth',
'uid',
], $this->adminUser
->id());
$jwt
->setClaim([
'drupal',
'path_auth',
'path',
], '/');
$token = $transcoder
->encode($jwt);
$this
->assertSame('private://drupal.txt', $file
->getFileUri());
$options = [
'query' => [
'jwt' => $token,
],
];
// Make a real request with the token in the query string.
$this
->drupalGet($file
->createFileUrl(), $options);
$this
->assertResponse(200);
$this
->assertText($this
->getFileContent($file));
// If the path claim on the JWT doesn't match, access should be denied.
$jwt = new JsonWebToken();
$jwt
->setClaim([
'drupal',
'path_auth',
'uid',
], $this->adminUser
->id());
$jwt
->setClaim([
'drupal',
'path_auth',
'path',
], $base_url . '/foo/');
$token = $transcoder
->encode($jwt);
$options = [
'query' => [
'jwt' => $token,
],
];
$this
->drupalGet($file
->createFileUrl(), $options);
$this
->assertResponse(403);
// Making a REST api request with no JWT should be denied.
$options = [
'query' => [
'_format' => 'json',
],
];
$file_rest_url = Url::fromRoute('rest.entity.file.GET', [
'file' => $file
->id(),
], $options);
$this
->drupalGet($file_rest_url);
$this
->assertResponse(403);
// Token path does not match, should still be 403.
$options = [
'query' => [
'_format' => 'json',
'jwt' => $token,
],
];
$file_rest_url = Url::fromRoute('rest.entity.file.GET', [
'file' => $file
->id(),
], $options);
$this
->drupalGet($file_rest_url);
$this
->assertResponse(403);
// Create a new token matching the request path prefix.
$jwt = new JsonWebToken();
$jwt
->setClaim([
'drupal',
'path_auth',
'uid',
], $this->adminUser
->id());
$jwt
->setClaim([
'drupal',
'path_auth',
'path',
], $base_url . '/entity/');
$token = $transcoder
->encode($jwt);
$options = [
'query' => [
'_format' => 'json',
'jwt' => $token,
],
];
$file_rest_url = Url::fromRoute('rest.entity.file.GET', [
'file' => $file
->id(),
], $options);
$this
->drupalGet($file_rest_url);
$this
->assertResponse(200);
$json = $this
->getSession()
->getPage()
->getContent();
$data = json_decode($json, TRUE);
$this
->assertEquals($file
->uuid(), $data['uuid'][0]['value']);
// If the user is blocked, the JWT should stop working.
$this->adminUser
->block();
$this->adminUser
->save();
$this
->drupalGet($file_rest_url);
$this
->assertResponse(403);
}