From d4a8821157287e95a6de8cdb77a6055d73ab5f14 Mon Sep 17 00:00:00 2001 From: Benjamin Renard Date: Mon, 13 Mar 2023 02:13:21 +0100 Subject: [PATCH] Initial commit --- .gitignore | 4 + .pre-commit-config.yaml | 13 + composer.json | 21 + phpstan.neon | 10 + phpunit.xml | 27 + src/Filter.php | 645 ++++++++++++++++++++++ src/Filter/CombineException.php | 5 + src/Filter/FilterException.php | 5 + src/Filter/ParserException.php | 5 + tests/FilterTest.php | 934 ++++++++++++++++++++++++++++++++ 10 files changed, 1669 insertions(+) create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 composer.json create mode 100644 phpstan.neon create mode 100644 phpunit.xml create mode 100644 src/Filter.php create mode 100644 src/Filter/CombineException.php create mode 100644 src/Filter/FilterException.php create mode 100644 src/Filter/ParserException.php create mode 100644 tests/FilterTest.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..179a6a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/composer.lock +/vendor +/.phpunit.cache +/coverage* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..751d6f8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +# Pre-commit hooks to run tests and ensure code is cleaned. +# See https://pre-commit.com for more information +repos: +- repo: https://github.com/digitalpulp/pre-commit-php.git + rev: 1.4.0 + hooks: + - id: php-stan + files: \.(php)$ + args: ['--configuration=phpstan.neon', '--xdebug'] +- repo: https://github.com/digitalpulp/pre-commit-php.git + rev: 1.4.0 + hooks: + - id: php-unit diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..4dce187 --- /dev/null +++ b/composer.json @@ -0,0 +1,21 @@ +{ + "name": "brenard/eesyldap", + "type": "library", + "description": "Object oriented interface for searching and manipulating LDAP entries & filters", + "require-dev": { + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9" + }, + "authors": [ + { + "name": "Benjamin Renard", + "email": "brenard@zionetrix.net" + } + ], + "license": "LGPL-3.0-or-later", + "autoload": { + "psr-4": { + "EesyLDAP\\": "src/" + } + } +} diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..3c80b36 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,10 @@ +parameters: + level: 9 + paths: + - src + - tests + treatPhpDocTypesAsCertain: false + ignoreErrors: + - + message: "#Method .*::test.*\\(\\) has no return type specified\\.#" + path: tests/* diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..766495c --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,27 @@ + + + + + tests + + + + + + src + + + diff --git a/src/Filter.php b/src/Filter.php new file mode 100644 index 0000000..cbd2c78 --- /dev/null +++ b/src/Filter.php @@ -0,0 +1,645 @@ + $sub_filters + */ +class Filter { + + /* + ************************************************************************************************* + * Leaf mode + ************************************************************************************************* + */ + + /** + * The attribute name + * @var string|null + */ + private $attr_name; + + /** + * The operator + * @var string|null + */ + private $op; + + /** + * The attribute value pattern + * @var string|null + */ + private $pattern; + + + /* + ************************************************************************************************* + * Combine mode + ************************************************************************************************* + */ + + /** + * The logical operator + * @var string|null + */ + private $log_op; + + /** + * The LDAP sub-filters objects + * @var array|null + */ + private $sub_filters; + + + /* + ************************************************************************************************* + * Some constants + ************************************************************************************************* + */ + + /** + * List of possible logical operators + * @var array + */ + private static $log_ops = array('&', '|', '!'); + + /** + * List of logical operators aliases + * @var array + */ + private static $log_op_aliases = array('and' => '&', 'or' => '|', 'not' => '!'); + + /** + * The NOT logical operator + * @var string + */ + private static $not_op = '!'; + + /** + * List of possible operators + * @var array + */ + private static $ops = array('=', '<', '>', '<=', '>=', '~='); + + /** + * List of operators aliases + * @var array + */ + private static $op_aliases = array( + 'equals' => '=', + '==' => '=', + 'lower' => '<', + 'greater' => '>', + 'lower_or_equals' => '<=', + 'greater_or_equals' => '>=', + 'approx' => '~=', + ); + + /** + * Characters to escape in a LDAP filter string + * @var array + */ + private static $espace_chars = array ( + '\\' => '\5c', // \ + '(' => '\28', // ( + ')' => '\29', // ) + '*' => '\2a', // * + "\u{0000}" => '\00', // NUL + ); + + /** + * Regex to match on OID + * @var string + */ + private static $oid_regex = '/^[0-9]+(\.[0-9]+)+$/'; + + /** + * Regex to match attribute name + * @var string + */ + private static $attr_name_regex = '/^(?P[a-zA-Z][a-zA-Z0-9\-]*)(;(?P