From 0326773df468d0261f45f5df7a44e551a924fca6 Mon Sep 17 00:00:00 2001 From: bizmate Date: Fri, 15 Oct 2021 15:28:22 +0100 Subject: [PATCH] Add validation for the Url value object and refactor its tests, remove obsolete security checker, add dockerised setup to ensure you can run a consistent development environment. --- Makefile | 31 ++++++++++++++++++++++++ README.md | 27 ++++++++++++++++++++- composer.json | 5 ++-- docker-compose.yml | 18 ++++++++++++++ docker/php/Dockerfile | 11 +++++++++ src/Web/Url.php | 7 +++++- tests/Web/UrlTest.php | 55 +++++++++++++++++++++++++------------------ 7 files changed, 126 insertions(+), 28 deletions(-) create mode 100644 Makefile create mode 100644 docker-compose.yml create mode 100644 docker/php/Dockerfile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..66e90cf --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +SHELL := /usr/bin/env bash + +up: + export UID && docker-compose up -d + bin/wait_for_docker.bash "Generating autoload files" + +down: + docker-compose down -v + +build: + docker-compose build + +bash: + export UID && docker-compose run php bash + +tests: + export UID && docker-compose run --rm php bash -c "vendor/bin/phpunit --coverage-clover tests/logs/clover.xml" +.PHONY: tests + +phpcs: + docker-compose run --rm php bash -c "vendor/bin/phpcs --ignore=vendor -n src" + +phpcbf: + docker-compose run --rm php bash -c "vendor/bin/phpcbf --ignore=vendor -n src" + +securitychecker: + docker-compose run --rm php bash -c "symfony local:check:security" + +docker_clean: + docker rm $(docker ps -a -q) || true + docker rmi < echo $(docker images -q | tr "\n" " ") diff --git a/README.md b/README.md index 4dec4fe..5c9e531 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,33 @@ This is fork of the educational package nicolopignatelli/valueobjects that aims # Install -required >= PHP 7.0 +Supports >= PHP 7.0 ```bash $ composer require ytake/valueobjects ``` + +# Develop + +To run tests, checks and get a shell to the development environment you need `docker`, `docker-compose` and `make`. + +## Run composer and docker + +Running `make up` will build the php docker image and run composer install as part of it. + +You can also open a shell inside the container, for instance to perform some commands like composer changes and updates +by running `make bash` + +## Run tests + +You can run unit + +`make tests` + +code style checks and fixes + +`make phpcs` and `make phpcbf + +or the security checker with + +`make securitychecker` diff --git a/composer.json b/composer.json index 322bca3..db8993d 100644 --- a/composer.json +++ b/composer.json @@ -22,14 +22,13 @@ "laminas/laminas-validator": "^2.0" }, "require-dev": { - "phpunit/phpunit": "^7.0.0 || ^6.0.0 ", + "phpunit/phpunit": "^6.0.0 ", "php-coveralls/php-coveralls": "^2.1.0", "phpmd/phpmd": "@stable", "squizlabs/php_codesniffer": "~2.7", "sebastian/phpcpd": "*", "phploc/phploc": "*", - "pdepend/pdepend" : "^2.2.4", - "sensiolabs/security-checker": "^4.0.0" + "pdepend/pdepend" : "^2.2.4" }, "autoload": { "psr-4": { diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..188ba0f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: '2' +services: + php: + build: + context: docker/php + volumes: + - websrc:/var/www/html + user: $UID + working_dir: /var/www/html + command: composer install --ignore-platform-reqs + +volumes: + websrc: + driver: local + driver_opts: + o: bind + type: none + device: $PWD \ No newline at end of file diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile new file mode 100644 index 0000000..d9f3fe3 --- /dev/null +++ b/docker/php/Dockerfile @@ -0,0 +1,11 @@ +FROM php:7.0.22-cli +MAINTAINER Diego Gullo + +RUN apt-get update && apt-get install -y ssh git zip locales locales-all wget\ + && pecl install xdebug-2.9.0 && docker-php-ext-enable xdebug && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* + +COPY --from=composer /usr/bin/composer /usr/bin/composer + +RUN mkdir -p /home/composer && chmod 777 /home/composer && cd /usr/local/bin \ + && bash -c "$(wget -qO - 'https://get.symfony.com/cli/installer')" '' --install-dir=/usr/local/bin diff --git a/src/Web/Url.php b/src/Web/Url.php index f51adc4..689d2c0 100644 --- a/src/Web/Url.php +++ b/src/Web/Url.php @@ -121,7 +121,12 @@ public function __toString(): string */ public static function fromNative(): ValueObjectInterface { - $urlString = \strval(\func_get_arg(0)); + $unsanitisedUrl = \strval(\func_get_arg(0)); + $urlString = filter_var($unsanitisedUrl, FILTER_VALIDATE_URL); + + if (false === $urlString) { + throw new \InvalidArgumentException("Invalid URL : " . $unsanitisedUrl); + } $user = \parse_url($urlString, PHP_URL_USER); $pass = \parse_url($urlString, PHP_URL_PASS); diff --git a/tests/Web/UrlTest.php b/tests/Web/UrlTest.php index 25a8460..a3d4a91 100644 --- a/tests/Web/UrlTest.php +++ b/tests/Web/UrlTest.php @@ -32,34 +32,43 @@ public function setup() new FragmentIdentifier('#fragmentidentifier') ); } - - public function testFromNative() + + public function fromNativeProviderValidUrls(){ + return [ + [ 'http://user:pass@foo.com:80/bar?querystring#fragmentidentifier' ], + [ 'http://www.test.com' ], + [ 'http://www.test.com/bar' ], + [ 'http://www.test.com/?querystring' ], + [ 'http://www.test.com/#fragmentidentifier' ] + ]; + } + + /** + * @dataProvider fromNativeProviderValidUrls + */ + public function testFromNativeWithValidUrl($nativeUrlString) { - $nativeUrlString = 'http://user:pass@foo.com:80/bar?querystring#fragmentidentifier'; - $fromNativeUrl = Url::fromNative($nativeUrlString); - - $this->assertTrue($this->url->sameValueAs($fromNativeUrl)); - - $nativeUrlString = 'http://www.test.com'; - $fromNativeUrl = Url::fromNative($nativeUrlString); - - $this->assertSame($nativeUrlString, $fromNativeUrl->__toString()); - - $nativeUrlString = 'http://www.test.com/bar'; - $fromNativeUrl = Url::fromNative($nativeUrlString); - - $this->assertSame($nativeUrlString, $fromNativeUrl->__toString()); - - $nativeUrlString = 'http://www.test.com/?querystring'; - $fromNativeUrl = Url::fromNative($nativeUrlString); - - $this->assertSame($nativeUrlString, $fromNativeUrl->__toString()); - - $nativeUrlString = 'http://www.test.com/#fragmentidentifier'; $fromNativeUrl = Url::fromNative($nativeUrlString); $this->assertSame($nativeUrlString, $fromNativeUrl->__toString()); } + + public function fromNativeProviderInvalidUrls(){ + return [ + [ 'foo.com:80/bar?querystring#fragmentidentifier' ], + [ 'www.test.com' ], + [ 'notAUrl' ] + ]; + } + + /** + * @dataProvider fromNativeProviderInvalidUrls + * @expectedException \InvalidArgumentException + */ + public function testFromNativeWithInvalidUrl($nativeUrlString) + { + Url::fromNative($nativeUrlString); + } public function testSameValueAs() {