Skip to content
Snippets Groups Projects
Commit c6507357 authored by Adam G-H's avatar Adam G-H
Browse files

Use config schema validation

parent 479a5429
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !992. Comments created here will be created in the context of that merge request.
......@@ -34,3 +34,6 @@ package_manager.settings:
sequence:
type: string
label: 'A relative path'
constraints:
NotBlank: []
RelativePath: []
......@@ -9,7 +9,6 @@ use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\package_manager\ComposerInspector;
use Drupal\package_manager\Event\CollectPathsToExcludeEvent;
use Drupal\package_manager\PathLocator;
use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
......@@ -41,14 +40,11 @@ final class UnknownPathExcluder implements EventSubscriberInterface {
* The path locator service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
* @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $pathFactory
* The path factory service.
*/
public function __construct(
private readonly ComposerInspector $composerInspector,
private readonly PathLocator $pathLocator,
private readonly ConfigFactoryInterface $configFactory,
private readonly PathFactoryInterface $pathFactory,
) {}
/**
......@@ -106,16 +102,15 @@ final class UnknownPathExcluder implements EventSubscriberInterface {
$known_paths[] = ltrim($scaffold_file_path, '/');
}
// Accept any relative paths that the administrator has explicitly marked as
// safe.
$safe_paths = $this->configFactory->get('package_manager.settings')
->get('known_paths') ?: [];
foreach ($safe_paths as $path) {
if ($this->pathFactory->create($path)->isAbsolute()) {
throw new \InvalidArgumentException("'$path' must be relative to the project root.");
}
$known_paths[] = $path;
}
// Accept any known paths that the administrator has explicitly identified.
// These are validated by config schema.
// @see package_manager.schema.yml
// @see \Drupal\package_manager\Plugin\Validation\Constraint\RelativePathConstraint
// @see \Drupal\package_manager\Plugin\Validation\Constraint\RelativePathConstraintValidator
$known_paths = array_merge(
$known_paths,
$this->configFactory->get('package_manager.settings')->get('known_paths') ?: [],
);
// Search for all files (including hidden ones) in the project root. We need
// to use readdir() and friends here, rather than glob(), since certain
......
<?php
namespace Drupal\package_manager\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Checks if a path is relative, regardless of whether it actually exists.
*
* @Constraint(
* id = "RelativePath",
* label = @Translation("Is relative path", context = "Validation"),
* )
*/
final class RelativePathConstraint extends Constraint {
/**
* {@inheritdoc}
*/
public string $message = '{{ value }} must be a relative path.';
}
<?php
namespace Drupal\package_manager\Plugin\Validation\Constraint;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
/**
* Validates that a value is a relative path that may or may not exist.
*/
final class RelativePathConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
/**
* Constructs a RelativePathConstraintValidator object.
*
* @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $pathFactory
* The path factory service.
*/
public function __construct(
private readonly PathFactoryInterface $pathFactory,
) {}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get(PathFactoryInterface::class),
);
}
/**
* {@inheritdoc}
*/
public function validate(mixed $value, Constraint $constraint): void {
assert($constraint instanceof RelativePathConstraint);
if (is_string($value)) {
if ($this->pathFactory->create($value)->isAbsolute()) {
$this->context->addViolation($constraint->message, ['value' => $value]);
}
$value = $this->pathFactory->create($value);
}
throw new UnexpectedTypeException($value, 'string');
}
}
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