Skip to content
Snippets Groups Projects
Commit 848c9a27 authored by omkar podey's avatar omkar podey Committed by Adam G-H
Browse files

Issue #3364735 by omkar.podey, phenaproxima, Wim Leers:...

Issue #3364735 by omkar.podey, phenaproxima, Wim Leers: WritableFileSystemValidator does not check if the project root is writable
parent cb221304
No related branches found
No related tags found
2 merge requests!989Issue #3356804 by phenaproxima: Flag a warning during status check if the...,!903Issue #3364735: WritableFileSystemValidator does not check if the project root is writable
...@@ -41,14 +41,23 @@ class WritableFileSystemValidator implements EventSubscriberInterface { ...@@ -41,14 +41,23 @@ class WritableFileSystemValidator implements EventSubscriberInterface {
public function validate(PreOperationStageEvent $event): void { public function validate(PreOperationStageEvent $event): void {
$messages = []; $messages = [];
$drupal_root = $this->pathLocator->getProjectRoot(); $project_root = $this->pathLocator->getProjectRoot();
// If the web (Drupal) root and project root are different, validate the
// web root separately.
$web_root = $this->pathLocator->getWebRoot(); $web_root = $this->pathLocator->getWebRoot();
if ($web_root) { if ($web_root) {
$drupal_root .= DIRECTORY_SEPARATOR . $web_root; $drupal_root = $project_root . DIRECTORY_SEPARATOR . $web_root;
if (!is_writable($drupal_root)) {
$messages[] = $this->t('The Drupal directory "@dir" is not writable.', [
'@dir' => $drupal_root,
]);
}
} }
if (!is_writable($drupal_root)) {
$messages[] = $this->t('The Drupal directory "@dir" is not writable.', [ if (!is_writable($project_root)) {
'@dir' => $drupal_root, $messages[] = $this->t('The project root directory "@dir" is not writable.', [
'@dir' => $project_root,
]); ]);
} }
......
...@@ -32,37 +32,80 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase { ...@@ -32,37 +32,80 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase {
*/ */
public function providerWritable(): array { public function providerWritable(): array {
// @see \Drupal\Tests\package_manager\Traits\ValidationTestTrait::resolvePlaceholdersInArrayValuesWithRealPaths() // @see \Drupal\Tests\package_manager\Traits\ValidationTestTrait::resolvePlaceholdersInArrayValuesWithRealPaths()
$root_error = t('The Drupal directory "<PROJECT_ROOT>" is not writable.'); $drupal_root_error = t('The Drupal directory "<PROJECT_ROOT>/web" is not writable.');
$vendor_error = t('The vendor directory "<VENDOR_DIR>" is not writable.'); $vendor_error = t('The vendor directory "<VENDOR_DIR>" is not writable.');
$project_root_error = t('The project root directory "<PROJECT_ROOT>" is not writable.');
$summary = t('The file system is not writable.'); $summary = t('The file system is not writable.');
$writable_permission = 0777; $writable_permission = 0777;
$non_writable_permission = 0550; $non_writable_permission = 0550;
return [ return [
'root and vendor are writable' => [ 'root and vendor are writable, nested web root' => [
$writable_permission, $writable_permission,
$writable_permission, $writable_permission,
$writable_permission,
'web',
[], [],
], ],
'root writable, vendor not writable' => [ 'root writable, vendor not writable, nested web root' => [
$writable_permission,
$writable_permission, $writable_permission,
$non_writable_permission, $non_writable_permission,
'web',
[ [
ValidationResult::createError([$vendor_error], $summary), ValidationResult::createError([$vendor_error], $summary),
], ],
], ],
'root not writable, vendor writable' => [ 'root not writable, vendor writable, nested web root' => [
$non_writable_permission,
$non_writable_permission,
$writable_permission,
'web',
[
ValidationResult::createError([$drupal_root_error, $project_root_error], $summary),
],
],
'nothing writable, nested web root' => [
$non_writable_permission,
$non_writable_permission, $non_writable_permission,
$non_writable_permission,
'web',
[
ValidationResult::createError([$drupal_root_error, $project_root_error, $vendor_error], $summary),
],
],
'root and vendor are writable, non-nested web root' => [
$writable_permission,
$writable_permission,
$writable_permission,
'',
[],
],
'root writable, vendor not writable, non-nested web root' => [
$writable_permission, $writable_permission,
$writable_permission,
$non_writable_permission,
'',
[ [
ValidationResult::createError([$root_error], $summary), ValidationResult::createError([$vendor_error], $summary),
], ],
], ],
'nothing writable' => [ 'root not writable, vendor writable, non-nested web root' => [
$non_writable_permission, $non_writable_permission,
$non_writable_permission, $non_writable_permission,
$writable_permission,
'',
[ [
ValidationResult::createError([$root_error, $vendor_error], $summary), ValidationResult::createError([$project_root_error], $summary),
],
],
'nothing writable, non-nested web root' => [
$non_writable_permission,
$non_writable_permission,
$non_writable_permission,
'',
[
ValidationResult::createError([$project_root_error, $vendor_error], $summary),
], ],
], ],
]; ];
...@@ -73,20 +116,20 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase { ...@@ -73,20 +116,20 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase {
* *
* @param int $root_permissions * @param int $root_permissions
* The file permissions for the root folder. * The file permissions for the root folder.
* @param int $webroot_permissions
* The file permissions for the web root folder.
* @param int $vendor_permissions * @param int $vendor_permissions
* The file permissions for the vendor folder. * The file permissions for the vendor folder.
* @param array $expected_results * @param string $webroot_relative_directory
* The web root path, relative to the project root, or an empty string if
* the web root and project root are the same.
* @param \Drupal\package_manager\ValidationResult[] $expected_results
* The expected validation results. * The expected validation results.
* *
* @dataProvider providerWritable * @dataProvider providerWritable
*/ */
public function testWritable(int $root_permissions, int $vendor_permissions, array $expected_results): void { public function testWritable(int $root_permissions, int $webroot_permissions, int $vendor_permissions, string $webroot_relative_directory, array $expected_results): void {
$path_locator = $this->container->get(PathLocator::class); $this->setUpPermissions($root_permissions, $webroot_permissions, $vendor_permissions, $webroot_relative_directory);
// We need to set the vendor directory's permissions first because, in the
// test project, it's located inside the project root.
$this->assertTrue(chmod($path_locator->getVendorDirectory(), $vendor_permissions));
$this->assertTrue(chmod($path_locator->getProjectRoot(), $root_permissions));
$this->assertStatusCheckResults($expected_results); $this->assertStatusCheckResults($expected_results);
$this->assertResults($expected_results, PreCreateEvent::class); $this->assertResults($expected_results, PreCreateEvent::class);
...@@ -97,24 +140,26 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase { ...@@ -97,24 +140,26 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase {
* *
* @param int $root_permissions * @param int $root_permissions
* The file permissions for the root folder. * The file permissions for the root folder.
* @param int $webroot_permissions
* The file permissions for the web root folder.
* @param int $vendor_permissions * @param int $vendor_permissions
* The file permissions for the vendor folder. * The file permissions for the vendor folder.
* @param array $expected_results * @param string $webroot_relative_directory
* The web root path, relative to the project root, or an empty string if
* the web root and project root are the same.
* @param \Drupal\package_manager\ValidationResult[] $expected_results
* The expected validation results. * The expected validation results.
* *
* @dataProvider providerWritable * @dataProvider providerWritable
*/ */
public function testWritableDuringPreApply(int $root_permissions, int $vendor_permissions, array $expected_results): void { public function testWritableDuringPreApply(int $root_permissions, int $webroot_permissions, int $vendor_permissions, string $webroot_relative_directory, array $expected_results): void {
$this->addEventTestListener( $this->addEventTestListener(
function () use ($root_permissions, $vendor_permissions): void { function () use ($webroot_permissions, $root_permissions, $vendor_permissions, $webroot_relative_directory): void {
$path_locator = $this->container->get(PathLocator::class); $this->setUpPermissions($root_permissions, $webroot_permissions, $vendor_permissions, $webroot_relative_directory);
// We need to set the vendor directory's permissions first because, in
// the test project, it's located inside the project root.
$this->assertTrue(chmod($path_locator->getVendorDirectory(), $vendor_permissions));
$this->assertTrue(chmod($path_locator->getProjectRoot(), $root_permissions));
// During pre-apply we don't care whether the staging root is writable. // During pre-apply we don't care whether the staging root is writable.
/** @var \Drupal\package_manager_bypass\MockPathLocator $path_locator */
$path_locator = $this->container->get(PathLocator::class);
$this->assertTrue(chmod($path_locator->getStagingRoot(), 0550)); $this->assertTrue(chmod($path_locator->getStagingRoot(), 0550));
}, },
); );
...@@ -122,6 +167,41 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase { ...@@ -122,6 +167,41 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase {
$this->assertResults($expected_results, PreApplyEvent::class); $this->assertResults($expected_results, PreApplyEvent::class);
} }
/**
* Sets the permissions of the test project's directories.
*
* @param int $root_permissions
* The permissions for the project root.
* @param int $web_root_permissions
* The permissions for the web root.
* @param int $vendor_permissions
* The permissions for the vendor directory.
* @param string $relative_web_root
* The web root path, relative to the project root, or an empty string if
* the web root and project root are the same.
*/
private function setUpPermissions(int $root_permissions, int $web_root_permissions, int $vendor_permissions, string $relative_web_root): void {
/** @var \Drupal\package_manager_bypass\MockPathLocator $path_locator */
$path_locator = $this->container->get(PathLocator::class);
$project_root = $web_root = $path_locator->getProjectRoot();
$vendor_dir = $path_locator->getVendorDirectory();
// Create the web root directory, if necessary.
if (!empty($relative_web_root)) {
$web_root .= '/' . $relative_web_root;
mkdir($web_root);
}
$path_locator->setPaths($project_root, $vendor_dir, $relative_web_root, $path_locator->getStagingRoot());
// We need to set the vendor directory and web root permissions first
// because they may be located inside the project root.
$this->assertTrue(chmod($vendor_dir, $vendor_permissions));
if ($project_root !== $web_root) {
$this->assertTrue(chmod($web_root, $web_root_permissions));
}
$this->assertTrue(chmod($project_root, $root_permissions));
}
/** /**
* Data provider for ::testStagingRootPermissions(). * Data provider for ::testStagingRootPermissions().
* *
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment