summaryrefslogtreecommitdiffstats
path: root/vendor/ipl/validator
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/ipl/validator')
-rw-r--r--vendor/ipl/validator/LICENSE21
-rw-r--r--vendor/ipl/validator/composer.json23
-rw-r--r--vendor/ipl/validator/src/BaseValidator.php11
-rw-r--r--vendor/ipl/validator/src/CallbackValidator.php45
-rw-r--r--vendor/ipl/validator/src/DateTimeValidator.php65
-rw-r--r--vendor/ipl/validator/src/PrivateKeyValidator.php33
-rw-r--r--vendor/ipl/validator/src/ValidatorChain.php284
-rw-r--r--vendor/ipl/validator/src/X509CertValidator.php33
8 files changed, 515 insertions, 0 deletions
diff --git a/vendor/ipl/validator/LICENSE b/vendor/ipl/validator/LICENSE
new file mode 100644
index 0000000..b247ccf
--- /dev/null
+++ b/vendor/ipl/validator/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2020 Icinga GmbH https://www.icinga.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/ipl/validator/composer.json b/vendor/ipl/validator/composer.json
new file mode 100644
index 0000000..0d66bee
--- /dev/null
+++ b/vendor/ipl/validator/composer.json
@@ -0,0 +1,23 @@
+{
+ "name": "ipl/validator",
+ "type": "library",
+ "description": "Icinga PHP Library - Common validators and validator chaining",
+ "homepage": "https://github.com/Icinga/ipl-validator",
+ "license": "MIT",
+ "require": {
+ "php": ">=7.2",
+ "ext-openssl": "*",
+ "ipl/stdlib": ">=0.12.0",
+ "ipl/i18n": ">=0.2.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "ipl\\Validator\\": "src"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "ipl\\Tests\\Validator\\": "tests"
+ }
+ }
+}
diff --git a/vendor/ipl/validator/src/BaseValidator.php b/vendor/ipl/validator/src/BaseValidator.php
new file mode 100644
index 0000000..8faa79b
--- /dev/null
+++ b/vendor/ipl/validator/src/BaseValidator.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace ipl\Validator;
+
+use ipl\Stdlib\Contract\Validator;
+use ipl\Stdlib\Messages;
+
+abstract class BaseValidator implements Validator
+{
+ use Messages;
+}
diff --git a/vendor/ipl/validator/src/CallbackValidator.php b/vendor/ipl/validator/src/CallbackValidator.php
new file mode 100644
index 0000000..611a45e
--- /dev/null
+++ b/vendor/ipl/validator/src/CallbackValidator.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace ipl\Validator;
+
+/**
+ * Validator that uses a callback for the actual validation
+ *
+ * # Example Usage
+ * ```
+ * $dedup = new CallbackValidator(function ($value, CallbackValidator $validator) {
+ * if (already_exists_in_database($value)) {
+ * $validator->addMessage('Record already exists in database');
+ *
+ * return false;
+ * }
+ *
+ * return true;
+ * });
+ *
+ * $dedup->isValid($id);
+ * ```
+ */
+class CallbackValidator extends BaseValidator
+{
+ /** @var callable Validation callback */
+ protected $callback;
+
+ /**
+ * Create a new callback validator
+ *
+ * @param callable $callback Validation callback
+ */
+ public function __construct(callable $callback)
+ {
+ $this->callback = $callback;
+ }
+
+ public function isValid($value)
+ {
+ // Multiple isValid() calls must not stack validation messages
+ $this->clearMessages();
+
+ return call_user_func($this->callback, $value, $this);
+ }
+}
diff --git a/vendor/ipl/validator/src/DateTimeValidator.php b/vendor/ipl/validator/src/DateTimeValidator.php
new file mode 100644
index 0000000..1e35d61
--- /dev/null
+++ b/vendor/ipl/validator/src/DateTimeValidator.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace ipl\Validator;
+
+use DateTime;
+use ipl\I18n\Translation;
+
+/**
+ * Validator for date-and-time input controls
+ */
+class DateTimeValidator extends BaseValidator
+{
+ use Translation;
+
+ /** @var string Default date time format */
+ const FORMAT = 'Y-m-d\TH:i:s';
+
+ /** @var bool Whether to use the default date time format */
+ protected $local;
+
+ /**
+ * Create a new date-and-time input control validator
+ *
+ * @param bool $local
+ */
+ public function __construct($local = true)
+ {
+ $this->local = (bool) $local;
+ }
+
+ /**
+ * Check whether the given date time is valid
+ *
+ * @param string|DateTime $value
+ *
+ * @return bool
+ */
+ public function isValid($value)
+ {
+ // Multiple isValid() calls must not stack validation messages
+ $this->clearMessages();
+
+ if (! $value instanceof DateTime && ! is_string($value)) {
+ $this->addMessage($this->translate('Invalid date/time given.'));
+
+ return false;
+ }
+
+ if (! $value instanceof DateTime) {
+ $format = $this->local === true ? static::FORMAT : DateTime::RFC3339;
+ $dateTime = DateTime::createFromFormat($format, $value);
+
+ if ($dateTime === false || $dateTime->format($format) !== $value) {
+ $this->addMessage(sprintf(
+ $this->translate("Date/time string not in the expected format: %s"),
+ $format
+ ));
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/ipl/validator/src/PrivateKeyValidator.php b/vendor/ipl/validator/src/PrivateKeyValidator.php
new file mode 100644
index 0000000..b629398
--- /dev/null
+++ b/vendor/ipl/validator/src/PrivateKeyValidator.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace ipl\Validator;
+
+use ipl\I18n\Translation;
+
+/**
+ * Validates a private key
+ */
+class PrivateKeyValidator extends BaseValidator
+{
+ use Translation;
+
+ public function isValid($value)
+ {
+ // Multiple isValid() calls must not stack validation messages
+ $this->clearMessages();
+
+ if (preg_match('/\A\s*\w+:/', $value)) {
+ $this->addMessage($this->translate('URLs are not allowed'));
+
+ return false;
+ }
+
+ if (openssl_pkey_get_private($value) === false) {
+ $this->addMessage($this->translate('Not a valid PEM-encoded private key'));
+
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/ipl/validator/src/ValidatorChain.php b/vendor/ipl/validator/src/ValidatorChain.php
new file mode 100644
index 0000000..2860a12
--- /dev/null
+++ b/vendor/ipl/validator/src/ValidatorChain.php
@@ -0,0 +1,284 @@
+<?php
+
+namespace ipl\Validator;
+
+use Countable;
+use InvalidArgumentException;
+use ipl\Stdlib\Contract\Validator;
+use ipl\Stdlib\Messages;
+use ipl\Stdlib\Plugins;
+use ipl\Stdlib\PriorityQueue;
+use IteratorAggregate;
+use SplObjectStorage;
+use Traversable;
+use UnexpectedValueException;
+
+use function ipl\Stdlib\get_php_type;
+
+class ValidatorChain implements Countable, IteratorAggregate, Validator
+{
+ use Messages;
+ use Plugins;
+
+ /** Default priority at which validators are added */
+ const DEFAULT_PRIORITY = 1;
+
+ /** @var PriorityQueue Validator chain */
+ protected $validators;
+
+ /** @var SplObjectStorage Validators that break the chain on failure */
+ protected $validatorsThatBreakTheChain;
+
+ /**
+ * Create a new validator chain
+ */
+ public function __construct()
+ {
+ $this->validators = new PriorityQueue();
+ $this->validatorsThatBreakTheChain = new SplObjectStorage();
+
+ $this->addDefaultPluginLoader('validator', __NAMESPACE__, 'Validator');
+ }
+
+ /**
+ * Get the validators that break the chain
+ *
+ * @return SplObjectStorage
+ */
+ public function getValidatorsThatBreakTheChain()
+ {
+ return $this->validatorsThatBreakTheChain;
+ }
+
+ /**
+ * Add a validator to the chain
+ *
+ * If $breakChainOnFailure is true and the validator fails, subsequent validators won't be executed.
+ *
+ * @param Validator $validator
+ * @param bool $breakChainOnFailure
+ * @param int $priority Priority at which to add validator
+ *
+ * @return $this
+ *
+ */
+ public function add(Validator $validator, $breakChainOnFailure = false, $priority = self::DEFAULT_PRIORITY)
+ {
+ $this->validators->insert($validator, $priority);
+
+ if ($breakChainOnFailure) {
+ $this->validatorsThatBreakTheChain->attach($validator);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add the validators from the given validator specification to the chain
+ *
+ * @param iterable $validators
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException If $validators is not iterable or if the validator specification is invalid
+ */
+ public function addValidators($validators)
+ {
+ if ($validators instanceof static) {
+ return $this->merge($validators);
+ }
+
+ if (! is_iterable($validators)) {
+ throw new InvalidArgumentException(sprintf(
+ '%s expects parameter one to be iterable, got %s instead',
+ __METHOD__,
+ get_php_type($validators)
+ ));
+ }
+
+ foreach ($validators as $name => $validator) {
+ $breakChainOnFailure = false;
+
+ if (! $validator instanceof Validator) {
+ if (is_int($name)) {
+ if (! is_array($validator)) {
+ $name = $validator;
+ $validator = null;
+ } else {
+ if (! isset($validator['name'])) {
+ throw new InvalidArgumentException(
+ 'Invalid validator array specification: Key "name" is missing'
+ );
+ }
+
+ $name = $validator['name'];
+ unset($validator['name']);
+ }
+ }
+
+ if (is_array($validator)) {
+ if (isset($validator['options'])) {
+ $options = $validator['options'];
+
+ unset($validator['options']);
+
+ $validator = array_merge($validator, $options);
+ }
+
+ if (isset($validator['break_chain_on_failure'])) {
+ $breakChainOnFailure = $validator['break_chain_on_failure'];
+
+ unset($validator['break_chain_on_failure']);
+ }
+ }
+
+ $validator = $this->createValidator($name, $validator);
+ }
+
+ $this->add($validator, $breakChainOnFailure);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a validator loader
+ *
+ * @param string $namespace Namespace of the validators
+ * @param string $postfix Validator name postfix, if any
+ *
+ * @return $this
+ */
+ public function addValidatorLoader($namespace, $postfix = null)
+ {
+ $this->addPluginLoader('validator', $namespace, $postfix);
+
+ return $this;
+ }
+
+ /**
+ * Remove all validators from the chain
+ *
+ * @return $this
+ */
+ public function clearValidators()
+ {
+ $this->validators = new PriorityQueue();
+ $this->validatorsThatBreakTheChain = new SplObjectStorage();
+
+ return $this;
+ }
+
+ /**
+ * Create a validator from the given name and options
+ *
+ * @param string $name
+ * @param mixed $options
+ *
+ * @return Validator
+ *
+ * @throws InvalidArgumentException If the validator to load is unknown
+ * @throws UnexpectedValueException If a validator loader did not return an instance of {@link Validator}
+ */
+ public function createValidator($name, $options = null)
+ {
+ $class = $this->loadPlugin('validator', $name);
+
+ if (! $class) {
+ throw new InvalidArgumentException(sprintf(
+ "Can't load validator '%s'. Validator unknown",
+ $name
+ ));
+ }
+
+ if (empty($options)) {
+ $validator = new $class();
+ } else {
+ $validator = new $class($options);
+ }
+
+ if (! $validator instanceof Validator) {
+ throw new UnexpectedValueException(sprintf(
+ "%s expects loader to return an instance of %s for validator '%s', got %s instead",
+ __METHOD__,
+ Validator::class,
+ $name,
+ get_php_type($validator)
+ ));
+ }
+
+ return $validator;
+ }
+
+ /**
+ * Merge all validators from the given chain into this one
+ *
+ * @param ValidatorChain $validatorChain
+ *
+ * @return $this
+ */
+ public function merge(ValidatorChain $validatorChain)
+ {
+ $validatorsThatBreakTheChain = $validatorChain->getValidatorsThatBreakTheChain();
+
+ foreach ($validatorChain->validators->yieldAll() as $priority => $validator) {
+ $this->add($validator, $validatorsThatBreakTheChain->contains($validator), $priority);
+ }
+
+ return $this;
+ }
+
+ public function __clone()
+ {
+ $this->validators = clone $this->validators;
+ }
+
+ /**
+ * Export the chain as array
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return array_values(iterator_to_array($this));
+ }
+
+ public function count(): int
+ {
+ return count($this->validators);
+ }
+
+ /**
+ * Get an iterator for traversing the validators
+ *
+ * @return Validator[]|PriorityQueue
+ */
+ public function getIterator(): Traversable
+ {
+ // Clone validators because the PriorityQueue acts as a heap and thus items are removed upon iteration
+ return clone $this->validators;
+ }
+
+ public function isValid($value)
+ {
+ $this->clearMessages();
+
+ $valid = true;
+
+ foreach ($this as $validator) {
+ if ($validator->isValid($value)) {
+ continue;
+ }
+
+ $valid = false;
+
+ $this->addMessages($validator->getMessages());
+
+ if ($this->validatorsThatBreakTheChain->contains($validator)) {
+ break;
+ }
+ }
+
+ return $valid;
+ }
+}
diff --git a/vendor/ipl/validator/src/X509CertValidator.php b/vendor/ipl/validator/src/X509CertValidator.php
new file mode 100644
index 0000000..7dfc4f7
--- /dev/null
+++ b/vendor/ipl/validator/src/X509CertValidator.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace ipl\Validator;
+
+use ipl\I18n\Translation;
+
+/**
+ * Validates an X.509 certificate
+ */
+class X509CertValidator extends BaseValidator
+{
+ use Translation;
+
+ public function isValid($value)
+ {
+ // Multiple isValid() calls must not stack validation messages
+ $this->clearMessages();
+
+ if (preg_match('/\A\s*\w+:/', $value)) {
+ $this->addMessage($this->translate('URLs are not allowed'));
+
+ return false;
+ }
+
+ if (openssl_x509_parse($value) === false) {
+ $this->addMessage($this->translate('Not a valid PEM-encoded X.509 certificate'));
+
+ return false;
+ }
+
+ return true;
+ }
+}