├── .gitignore ├── .php_cs ├── Makefile ├── README.md ├── composer.json ├── composer.lock ├── lib └── PasswordPolicy │ ├── Constraint.php │ ├── Constraints │ └── Limit.php │ ├── Message.php │ ├── Policy.php │ ├── Rule.php │ └── Rules │ ├── Base.php │ ├── CharacterRange.php │ ├── Regex.php │ └── Size.php ├── phpunit.xml.dist └── test └── Unit └── Rules └── SizeTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | 7 | @copyright 2011 The Authors 8 | @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | @version Build @@version@@ 10 | EOF; 11 | 12 | Symfony\CS\Fixer\Contrib\HeaderCommentFixer::setHeader($header); 13 | 14 | return Symfony\CS\Config\Config::create() 15 | ->level(Symfony\CS\FixerInterface::PSR2_LEVEL) 16 | ->fixers([ 17 | 'align_double_arrow', 18 | 'array_element_no_space_before_comma', 19 | 'array_element_white_space_after_comma', 20 | 'declare_equal_normalize', 21 | 'extra_empty_lines', 22 | 'header_comment', 23 | 'list_commas', 24 | 'multiline_array_trailing_comma', 25 | 'new_with_braces', 26 | 'no_blank_lines_before_namespace', 27 | 'no_empty_comment', 28 | 'no_empty_lines_after_phpdocs', 29 | 'no_empty_phpdoc', 30 | 'no_empty_statement', 31 | 'object_operator', 32 | 'ordered_use', 33 | 'php_unit_dedicate_assert', 34 | 'phpdoc_indent', 35 | 'phpdoc_order', 36 | 'phpdoc_params', 37 | 'phpdoc_scalar', 38 | 'phpdoc_separation', 39 | 'remove_leading_slash_use', 40 | 'remove_lines_between_uses', 41 | 'return', 42 | 'self_accessor', 43 | 'short_bool_cast', 44 | 'short_scalar_cast', 45 | 'single_blank_line_before_namespace', 46 | 'spaces_before_semicolon', 47 | 'ternary_spaces', 48 | 'trim_array_spaces', 49 | 'unneeded_control_parentheses', 50 | 'unused_use', 51 | 'whitespacey_lines', 52 | ]) 53 | ->finder( 54 | Symfony\CS\Finder\DefaultFinder::create() 55 | ->in(__DIR__ . "/lib") 56 | ->in(__DIR__ . "/test") 57 | ) 58 | ; -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: build 3 | 4 | .PHONY: build 5 | build: lint cs test 6 | 7 | lintfiles := $(shell find lib test -type f -iname '*.php') 8 | 9 | .PHONY: ${lintfiles} 10 | ${lintfiles}: 11 | php -l $@ 12 | 13 | .PHONY: lint 14 | lint: $(lintfiles) 15 | 16 | .PHONY: cs 17 | cs: 18 | vendor/bin/php-cs-fixer --quiet --no-interaction fix; true 19 | 20 | 21 | .PHONY: test 22 | test: 23 | vendor/bin/phpunit 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PasswordPolicy 2 | ============== 3 | 4 | A tool for checking and creating password policies in PHP and JS. 5 | 6 | ## Installation 7 | 8 | Use composer to setup an autoloader 9 | 10 | php composer.phar install 11 | 12 | Require the composer autoload file: 13 | 14 | require_once 'vendor/autoload.php'; 15 | 16 | ## Usage: 17 | 18 | To use, first instantiate the core policy object: 19 | 20 | $policy = new \PasswordPolicy\Policy; 21 | 22 | Then, add rules: 23 | 24 | $policy->contains('lowercase', $policy->atLeast(2)); 25 | 26 | ### Supported rule helper methods are: 27 | 28 | * `contains($class, $constraint = null, $description = '')`: Checks to see if a password contains a class of chars 29 | 30 | Supported Short-Cut classes: 31 | 32 | * `letter` - `a-zA-Z` 33 | * `lowercase` - `a-z` 34 | * `uppercase` - `A-Z` 35 | * `digit` - `0-9` 36 | * `symbol` - `^a-zA-Z0-9` (in other words, non-alpha-numeric) 37 | * `null` - `\0` 38 | * `alnum` - `a-zA-Z0-9` 39 | 40 | The second param is a constraint (optional) 41 | 42 | * `length($constraint)`: Checks the length of the password matches a constraint 43 | 44 | * `endsWith($class, $description = '')`: Checks to see if the password ends with a character class. 45 | 46 | * `startsWith($class, $description = '')`: Checks to see if the password starts with a character class. 47 | 48 | * `notMatch($regex, $description)`: Checks if the password does not match a regex. 49 | 50 | * `match($regex, $description)`: Checks if the password matches the regex. 51 | 52 | ### Supported Constraints: 53 | 54 | The policy also has short-cut helpers for creating constraints: 55 | 56 | * `atLeast($n)`: At least the param matches 57 | 58 | Equivalent to `between($n, PHP_INT_MAX)` 59 | 60 | * `atMost($n)`: At most the param matches 61 | 62 | Equivalent to `between(0, $n)` 63 | 64 | * `between($min, $max)`: Between $min and $max number of matches 65 | 66 | * `never()`: No matches 67 | 68 | Equivalent to `between(0, 0)` 69 | 70 | ## Testing the policy 71 | 72 | Once you setup the policy, you can then test it in PHP using the `test($password)` method. 73 | 74 | $result = $policy->test($password); 75 | 76 | The result return is a stdclass object with two members, result and messages. 77 | 78 | * `$result->result` - A boolean if the password is valid. 79 | 80 | * `$result->messages` - An array of messages 81 | 82 | Each message is an object of two members: 83 | 84 | * `$message->result` - A boolean indicating if the rule passed 85 | 86 | * `$message->message` - A textual description of the rule 87 | 88 | ## Using JavaScript 89 | 90 | Once you've built the policy, you can call `toJavaScript()` to generate a JS anonymous function for injecting into JS code. 91 | 92 | $js = $policy->toJavaScript(); 93 | echo "var policy = $js;"; 94 | 95 | Then, the policy object in JS is basically a wrapper for `$policy->test($password)`, and behaves the same (same return values). 96 | 97 | var result = policy(password); 98 | if (!result.result) { 99 | /* Process Messages To Display Failure To User */ 100 | } 101 | 102 | One note for the JavaScript, any regular expressions that you write need to be deliminated by `/` and be valid JS regexes (no PREG specific functionality is allowed). 103 | 104 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ircmaxell/password-policy", 3 | "type": "library", 4 | "description": "A tool for managing password policies", 5 | "keywords": ["password", "policy"], 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Anthony Ferrara", 10 | "email": "ircmaxell@ircmaxell.com", 11 | "homepage": "http://blog.ircmaxell.com" 12 | } 13 | ], 14 | "require": { 15 | "ircmaxell/security-lib": "^1.1", 16 | "php": ">=5.3.0" 17 | }, 18 | "require-dev": { 19 | "friendsofphp/php-cs-fixer": "^1.11", 20 | "phpunit/phpunit": "^4.8|^5.0" 21 | }, 22 | "autoload": { 23 | "psr-0": { 24 | "PasswordPolicy": "lib" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "d80030193bb4dda1d8a3839af8b4452e", 8 | "content-hash": "31a5a1984e31ff24139119c4740db425", 9 | "packages": [ 10 | { 11 | "name": "ircmaxell/security-lib", 12 | "version": "v1.1.0", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/ircmaxell/SecurityLib.git", 16 | "reference": "f3db6de12c20c9bcd1aa3db4353a1bbe0e44e1b5" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/ircmaxell/SecurityLib/zipball/f3db6de12c20c9bcd1aa3db4353a1bbe0e44e1b5", 21 | "reference": "f3db6de12c20c9bcd1aa3db4353a1bbe0e44e1b5", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": ">=5.3.2" 26 | }, 27 | "require-dev": { 28 | "mikey179/vfsstream": "1.1.*" 29 | }, 30 | "type": "library", 31 | "extra": { 32 | "branch-alias": { 33 | "dev-master": "1.0.x-dev" 34 | } 35 | }, 36 | "autoload": { 37 | "psr-0": { 38 | "SecurityLib": "lib" 39 | } 40 | }, 41 | "notification-url": "https://packagist.org/downloads/", 42 | "license": [ 43 | "MIT" 44 | ], 45 | "authors": [ 46 | { 47 | "name": "Anthony Ferrara", 48 | "email": "ircmaxell@ircmaxell.com", 49 | "homepage": "http://blog.ircmaxell.com" 50 | } 51 | ], 52 | "description": "A Base Security Library", 53 | "homepage": "https://github.com/ircmaxell/SecurityLib", 54 | "time": "2015-03-20 14:31:23" 55 | } 56 | ], 57 | "packages-dev": [ 58 | { 59 | "name": "doctrine/instantiator", 60 | "version": "1.0.5", 61 | "source": { 62 | "type": "git", 63 | "url": "https://github.com/doctrine/instantiator.git", 64 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 65 | }, 66 | "dist": { 67 | "type": "zip", 68 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 69 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 70 | "shasum": "" 71 | }, 72 | "require": { 73 | "php": ">=5.3,<8.0-DEV" 74 | }, 75 | "require-dev": { 76 | "athletic/athletic": "~0.1.8", 77 | "ext-pdo": "*", 78 | "ext-phar": "*", 79 | "phpunit/phpunit": "~4.0", 80 | "squizlabs/php_codesniffer": "~2.0" 81 | }, 82 | "type": "library", 83 | "extra": { 84 | "branch-alias": { 85 | "dev-master": "1.0.x-dev" 86 | } 87 | }, 88 | "autoload": { 89 | "psr-4": { 90 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 91 | } 92 | }, 93 | "notification-url": "https://packagist.org/downloads/", 94 | "license": [ 95 | "MIT" 96 | ], 97 | "authors": [ 98 | { 99 | "name": "Marco Pivetta", 100 | "email": "ocramius@gmail.com", 101 | "homepage": "http://ocramius.github.com/" 102 | } 103 | ], 104 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 105 | "homepage": "https://github.com/doctrine/instantiator", 106 | "keywords": [ 107 | "constructor", 108 | "instantiate" 109 | ], 110 | "time": "2015-06-14 21:17:01" 111 | }, 112 | { 113 | "name": "friendsofphp/php-cs-fixer", 114 | "version": "v1.12.1", 115 | "source": { 116 | "type": "git", 117 | "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", 118 | "reference": "d33ee60f3d3e6152888b7f3a385f49e5c43bf1bf" 119 | }, 120 | "dist": { 121 | "type": "zip", 122 | "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/d33ee60f3d3e6152888b7f3a385f49e5c43bf1bf", 123 | "reference": "d33ee60f3d3e6152888b7f3a385f49e5c43bf1bf", 124 | "shasum": "" 125 | }, 126 | "require": { 127 | "ext-tokenizer": "*", 128 | "php": "^5.3.6 || >=7.0 <7.2", 129 | "sebastian/diff": "^1.1", 130 | "symfony/console": "^2.3 || ^3.0", 131 | "symfony/event-dispatcher": "^2.1 || ^3.0", 132 | "symfony/filesystem": "^2.1 || ^3.0", 133 | "symfony/finder": "^2.1 || ^3.0", 134 | "symfony/process": "^2.3 || ^3.0", 135 | "symfony/stopwatch": "^2.5 || ^3.0" 136 | }, 137 | "conflict": { 138 | "hhvm": "<3.9" 139 | }, 140 | "require-dev": { 141 | "phpunit/phpunit": "^4.5|^5", 142 | "satooshi/php-coveralls": "^1.0" 143 | }, 144 | "bin": [ 145 | "php-cs-fixer" 146 | ], 147 | "type": "application", 148 | "autoload": { 149 | "psr-4": { 150 | "Symfony\\CS\\": "Symfony/CS/" 151 | } 152 | }, 153 | "notification-url": "https://packagist.org/downloads/", 154 | "license": [ 155 | "MIT" 156 | ], 157 | "authors": [ 158 | { 159 | "name": "Dariusz Rumiński", 160 | "email": "dariusz.ruminski@gmail.com" 161 | }, 162 | { 163 | "name": "Fabien Potencier", 164 | "email": "fabien@symfony.com" 165 | } 166 | ], 167 | "description": "A tool to automatically fix PHP code style", 168 | "time": "2016-09-07 06:48:24" 169 | }, 170 | { 171 | "name": "myclabs/deep-copy", 172 | "version": "1.5.2", 173 | "source": { 174 | "type": "git", 175 | "url": "https://github.com/myclabs/DeepCopy.git", 176 | "reference": "da8529775f14f4fdae33f916eb0cf65f6afbddbc" 177 | }, 178 | "dist": { 179 | "type": "zip", 180 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/da8529775f14f4fdae33f916eb0cf65f6afbddbc", 181 | "reference": "da8529775f14f4fdae33f916eb0cf65f6afbddbc", 182 | "shasum": "" 183 | }, 184 | "require": { 185 | "php": ">=5.4.0" 186 | }, 187 | "require-dev": { 188 | "doctrine/collections": "1.*", 189 | "phpunit/phpunit": "~4.1" 190 | }, 191 | "type": "library", 192 | "autoload": { 193 | "psr-4": { 194 | "DeepCopy\\": "src/DeepCopy/" 195 | } 196 | }, 197 | "notification-url": "https://packagist.org/downloads/", 198 | "license": [ 199 | "MIT" 200 | ], 201 | "description": "Create deep copies (clones) of your objects", 202 | "homepage": "https://github.com/myclabs/DeepCopy", 203 | "keywords": [ 204 | "clone", 205 | "copy", 206 | "duplicate", 207 | "object", 208 | "object graph" 209 | ], 210 | "time": "2016-09-06 16:07:05" 211 | }, 212 | { 213 | "name": "phpdocumentor/reflection-common", 214 | "version": "1.0", 215 | "source": { 216 | "type": "git", 217 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 218 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" 219 | }, 220 | "dist": { 221 | "type": "zip", 222 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 223 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", 224 | "shasum": "" 225 | }, 226 | "require": { 227 | "php": ">=5.5" 228 | }, 229 | "require-dev": { 230 | "phpunit/phpunit": "^4.6" 231 | }, 232 | "type": "library", 233 | "extra": { 234 | "branch-alias": { 235 | "dev-master": "1.0.x-dev" 236 | } 237 | }, 238 | "autoload": { 239 | "psr-4": { 240 | "phpDocumentor\\Reflection\\": [ 241 | "src" 242 | ] 243 | } 244 | }, 245 | "notification-url": "https://packagist.org/downloads/", 246 | "license": [ 247 | "MIT" 248 | ], 249 | "authors": [ 250 | { 251 | "name": "Jaap van Otterdijk", 252 | "email": "opensource@ijaap.nl" 253 | } 254 | ], 255 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 256 | "homepage": "http://www.phpdoc.org", 257 | "keywords": [ 258 | "FQSEN", 259 | "phpDocumentor", 260 | "phpdoc", 261 | "reflection", 262 | "static analysis" 263 | ], 264 | "time": "2015-12-27 11:43:31" 265 | }, 266 | { 267 | "name": "phpdocumentor/reflection-docblock", 268 | "version": "3.1.0", 269 | "source": { 270 | "type": "git", 271 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 272 | "reference": "9270140b940ff02e58ec577c237274e92cd40cdd" 273 | }, 274 | "dist": { 275 | "type": "zip", 276 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd", 277 | "reference": "9270140b940ff02e58ec577c237274e92cd40cdd", 278 | "shasum": "" 279 | }, 280 | "require": { 281 | "php": ">=5.5", 282 | "phpdocumentor/reflection-common": "^1.0@dev", 283 | "phpdocumentor/type-resolver": "^0.2.0", 284 | "webmozart/assert": "^1.0" 285 | }, 286 | "require-dev": { 287 | "mockery/mockery": "^0.9.4", 288 | "phpunit/phpunit": "^4.4" 289 | }, 290 | "type": "library", 291 | "autoload": { 292 | "psr-4": { 293 | "phpDocumentor\\Reflection\\": [ 294 | "src/" 295 | ] 296 | } 297 | }, 298 | "notification-url": "https://packagist.org/downloads/", 299 | "license": [ 300 | "MIT" 301 | ], 302 | "authors": [ 303 | { 304 | "name": "Mike van Riel", 305 | "email": "me@mikevanriel.com" 306 | } 307 | ], 308 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 309 | "time": "2016-06-10 09:48:41" 310 | }, 311 | { 312 | "name": "phpdocumentor/type-resolver", 313 | "version": "0.2", 314 | "source": { 315 | "type": "git", 316 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 317 | "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" 318 | }, 319 | "dist": { 320 | "type": "zip", 321 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", 322 | "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", 323 | "shasum": "" 324 | }, 325 | "require": { 326 | "php": ">=5.5", 327 | "phpdocumentor/reflection-common": "^1.0" 328 | }, 329 | "require-dev": { 330 | "mockery/mockery": "^0.9.4", 331 | "phpunit/phpunit": "^5.2||^4.8.24" 332 | }, 333 | "type": "library", 334 | "extra": { 335 | "branch-alias": { 336 | "dev-master": "1.0.x-dev" 337 | } 338 | }, 339 | "autoload": { 340 | "psr-4": { 341 | "phpDocumentor\\Reflection\\": [ 342 | "src/" 343 | ] 344 | } 345 | }, 346 | "notification-url": "https://packagist.org/downloads/", 347 | "license": [ 348 | "MIT" 349 | ], 350 | "authors": [ 351 | { 352 | "name": "Mike van Riel", 353 | "email": "me@mikevanriel.com" 354 | } 355 | ], 356 | "time": "2016-06-10 07:14:17" 357 | }, 358 | { 359 | "name": "phpspec/prophecy", 360 | "version": "v1.6.1", 361 | "source": { 362 | "type": "git", 363 | "url": "https://github.com/phpspec/prophecy.git", 364 | "reference": "58a8137754bc24b25740d4281399a4a3596058e0" 365 | }, 366 | "dist": { 367 | "type": "zip", 368 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", 369 | "reference": "58a8137754bc24b25740d4281399a4a3596058e0", 370 | "shasum": "" 371 | }, 372 | "require": { 373 | "doctrine/instantiator": "^1.0.2", 374 | "php": "^5.3|^7.0", 375 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", 376 | "sebastian/comparator": "^1.1", 377 | "sebastian/recursion-context": "^1.0" 378 | }, 379 | "require-dev": { 380 | "phpspec/phpspec": "^2.0" 381 | }, 382 | "type": "library", 383 | "extra": { 384 | "branch-alias": { 385 | "dev-master": "1.6.x-dev" 386 | } 387 | }, 388 | "autoload": { 389 | "psr-0": { 390 | "Prophecy\\": "src/" 391 | } 392 | }, 393 | "notification-url": "https://packagist.org/downloads/", 394 | "license": [ 395 | "MIT" 396 | ], 397 | "authors": [ 398 | { 399 | "name": "Konstantin Kudryashov", 400 | "email": "ever.zet@gmail.com", 401 | "homepage": "http://everzet.com" 402 | }, 403 | { 404 | "name": "Marcello Duarte", 405 | "email": "marcello.duarte@gmail.com" 406 | } 407 | ], 408 | "description": "Highly opinionated mocking framework for PHP 5.3+", 409 | "homepage": "https://github.com/phpspec/prophecy", 410 | "keywords": [ 411 | "Double", 412 | "Dummy", 413 | "fake", 414 | "mock", 415 | "spy", 416 | "stub" 417 | ], 418 | "time": "2016-06-07 08:13:47" 419 | }, 420 | { 421 | "name": "phpunit/php-code-coverage", 422 | "version": "4.0.1", 423 | "source": { 424 | "type": "git", 425 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 426 | "reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3" 427 | }, 428 | "dist": { 429 | "type": "zip", 430 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5f3f7e736d6319d5f1fc402aff8b026da26709a3", 431 | "reference": "5f3f7e736d6319d5f1fc402aff8b026da26709a3", 432 | "shasum": "" 433 | }, 434 | "require": { 435 | "php": "^5.6 || ^7.0", 436 | "phpunit/php-file-iterator": "~1.3", 437 | "phpunit/php-text-template": "~1.2", 438 | "phpunit/php-token-stream": "^1.4.2", 439 | "sebastian/code-unit-reverse-lookup": "~1.0", 440 | "sebastian/environment": "^1.3.2 || ^2.0", 441 | "sebastian/version": "~1.0|~2.0" 442 | }, 443 | "require-dev": { 444 | "ext-xdebug": ">=2.1.4", 445 | "phpunit/phpunit": "^5.4" 446 | }, 447 | "suggest": { 448 | "ext-dom": "*", 449 | "ext-xdebug": ">=2.4.0", 450 | "ext-xmlwriter": "*" 451 | }, 452 | "type": "library", 453 | "extra": { 454 | "branch-alias": { 455 | "dev-master": "4.0.x-dev" 456 | } 457 | }, 458 | "autoload": { 459 | "classmap": [ 460 | "src/" 461 | ] 462 | }, 463 | "notification-url": "https://packagist.org/downloads/", 464 | "license": [ 465 | "BSD-3-Clause" 466 | ], 467 | "authors": [ 468 | { 469 | "name": "Sebastian Bergmann", 470 | "email": "sb@sebastian-bergmann.de", 471 | "role": "lead" 472 | } 473 | ], 474 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 475 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 476 | "keywords": [ 477 | "coverage", 478 | "testing", 479 | "xunit" 480 | ], 481 | "time": "2016-07-26 14:39:29" 482 | }, 483 | { 484 | "name": "phpunit/php-file-iterator", 485 | "version": "1.4.1", 486 | "source": { 487 | "type": "git", 488 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 489 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" 490 | }, 491 | "dist": { 492 | "type": "zip", 493 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 494 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 495 | "shasum": "" 496 | }, 497 | "require": { 498 | "php": ">=5.3.3" 499 | }, 500 | "type": "library", 501 | "extra": { 502 | "branch-alias": { 503 | "dev-master": "1.4.x-dev" 504 | } 505 | }, 506 | "autoload": { 507 | "classmap": [ 508 | "src/" 509 | ] 510 | }, 511 | "notification-url": "https://packagist.org/downloads/", 512 | "license": [ 513 | "BSD-3-Clause" 514 | ], 515 | "authors": [ 516 | { 517 | "name": "Sebastian Bergmann", 518 | "email": "sb@sebastian-bergmann.de", 519 | "role": "lead" 520 | } 521 | ], 522 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 523 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 524 | "keywords": [ 525 | "filesystem", 526 | "iterator" 527 | ], 528 | "time": "2015-06-21 13:08:43" 529 | }, 530 | { 531 | "name": "phpunit/php-text-template", 532 | "version": "1.2.1", 533 | "source": { 534 | "type": "git", 535 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 536 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 537 | }, 538 | "dist": { 539 | "type": "zip", 540 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 541 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 542 | "shasum": "" 543 | }, 544 | "require": { 545 | "php": ">=5.3.3" 546 | }, 547 | "type": "library", 548 | "autoload": { 549 | "classmap": [ 550 | "src/" 551 | ] 552 | }, 553 | "notification-url": "https://packagist.org/downloads/", 554 | "license": [ 555 | "BSD-3-Clause" 556 | ], 557 | "authors": [ 558 | { 559 | "name": "Sebastian Bergmann", 560 | "email": "sebastian@phpunit.de", 561 | "role": "lead" 562 | } 563 | ], 564 | "description": "Simple template engine.", 565 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 566 | "keywords": [ 567 | "template" 568 | ], 569 | "time": "2015-06-21 13:50:34" 570 | }, 571 | { 572 | "name": "phpunit/php-timer", 573 | "version": "1.0.8", 574 | "source": { 575 | "type": "git", 576 | "url": "https://github.com/sebastianbergmann/php-timer.git", 577 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" 578 | }, 579 | "dist": { 580 | "type": "zip", 581 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", 582 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", 583 | "shasum": "" 584 | }, 585 | "require": { 586 | "php": ">=5.3.3" 587 | }, 588 | "require-dev": { 589 | "phpunit/phpunit": "~4|~5" 590 | }, 591 | "type": "library", 592 | "autoload": { 593 | "classmap": [ 594 | "src/" 595 | ] 596 | }, 597 | "notification-url": "https://packagist.org/downloads/", 598 | "license": [ 599 | "BSD-3-Clause" 600 | ], 601 | "authors": [ 602 | { 603 | "name": "Sebastian Bergmann", 604 | "email": "sb@sebastian-bergmann.de", 605 | "role": "lead" 606 | } 607 | ], 608 | "description": "Utility class for timing", 609 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 610 | "keywords": [ 611 | "timer" 612 | ], 613 | "time": "2016-05-12 18:03:57" 614 | }, 615 | { 616 | "name": "phpunit/php-token-stream", 617 | "version": "1.4.8", 618 | "source": { 619 | "type": "git", 620 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 621 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" 622 | }, 623 | "dist": { 624 | "type": "zip", 625 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 626 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 627 | "shasum": "" 628 | }, 629 | "require": { 630 | "ext-tokenizer": "*", 631 | "php": ">=5.3.3" 632 | }, 633 | "require-dev": { 634 | "phpunit/phpunit": "~4.2" 635 | }, 636 | "type": "library", 637 | "extra": { 638 | "branch-alias": { 639 | "dev-master": "1.4-dev" 640 | } 641 | }, 642 | "autoload": { 643 | "classmap": [ 644 | "src/" 645 | ] 646 | }, 647 | "notification-url": "https://packagist.org/downloads/", 648 | "license": [ 649 | "BSD-3-Clause" 650 | ], 651 | "authors": [ 652 | { 653 | "name": "Sebastian Bergmann", 654 | "email": "sebastian@phpunit.de" 655 | } 656 | ], 657 | "description": "Wrapper around PHP's tokenizer extension.", 658 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 659 | "keywords": [ 660 | "tokenizer" 661 | ], 662 | "time": "2015-09-15 10:49:45" 663 | }, 664 | { 665 | "name": "phpunit/phpunit", 666 | "version": "5.5.4", 667 | "source": { 668 | "type": "git", 669 | "url": "https://github.com/sebastianbergmann/phpunit.git", 670 | "reference": "3e6e88e56c912133de6e99b87728cca7ed70c5f5" 671 | }, 672 | "dist": { 673 | "type": "zip", 674 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3e6e88e56c912133de6e99b87728cca7ed70c5f5", 675 | "reference": "3e6e88e56c912133de6e99b87728cca7ed70c5f5", 676 | "shasum": "" 677 | }, 678 | "require": { 679 | "ext-dom": "*", 680 | "ext-json": "*", 681 | "ext-pcre": "*", 682 | "ext-reflection": "*", 683 | "ext-spl": "*", 684 | "myclabs/deep-copy": "~1.3", 685 | "php": "^5.6 || ^7.0", 686 | "phpspec/prophecy": "^1.3.1", 687 | "phpunit/php-code-coverage": "^4.0.1", 688 | "phpunit/php-file-iterator": "~1.4", 689 | "phpunit/php-text-template": "~1.2", 690 | "phpunit/php-timer": "^1.0.6", 691 | "phpunit/phpunit-mock-objects": "^3.2", 692 | "sebastian/comparator": "~1.1", 693 | "sebastian/diff": "~1.2", 694 | "sebastian/environment": "^1.3 || ^2.0", 695 | "sebastian/exporter": "~1.2", 696 | "sebastian/global-state": "~1.0", 697 | "sebastian/object-enumerator": "~1.0", 698 | "sebastian/resource-operations": "~1.0", 699 | "sebastian/version": "~1.0|~2.0", 700 | "symfony/yaml": "~2.1|~3.0" 701 | }, 702 | "conflict": { 703 | "phpdocumentor/reflection-docblock": "3.0.2" 704 | }, 705 | "suggest": { 706 | "phpunit/php-invoker": "~1.1" 707 | }, 708 | "bin": [ 709 | "phpunit" 710 | ], 711 | "type": "library", 712 | "extra": { 713 | "branch-alias": { 714 | "dev-master": "5.5.x-dev" 715 | } 716 | }, 717 | "autoload": { 718 | "classmap": [ 719 | "src/" 720 | ] 721 | }, 722 | "notification-url": "https://packagist.org/downloads/", 723 | "license": [ 724 | "BSD-3-Clause" 725 | ], 726 | "authors": [ 727 | { 728 | "name": "Sebastian Bergmann", 729 | "email": "sebastian@phpunit.de", 730 | "role": "lead" 731 | } 732 | ], 733 | "description": "The PHP Unit Testing framework.", 734 | "homepage": "https://phpunit.de/", 735 | "keywords": [ 736 | "phpunit", 737 | "testing", 738 | "xunit" 739 | ], 740 | "time": "2016-08-26 07:11:44" 741 | }, 742 | { 743 | "name": "phpunit/phpunit-mock-objects", 744 | "version": "3.2.7", 745 | "source": { 746 | "type": "git", 747 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 748 | "reference": "546898a2c0c356ef2891b39dd7d07f5d82c8ed0a" 749 | }, 750 | "dist": { 751 | "type": "zip", 752 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/546898a2c0c356ef2891b39dd7d07f5d82c8ed0a", 753 | "reference": "546898a2c0c356ef2891b39dd7d07f5d82c8ed0a", 754 | "shasum": "" 755 | }, 756 | "require": { 757 | "doctrine/instantiator": "^1.0.2", 758 | "php": "^5.6 || ^7.0", 759 | "phpunit/php-text-template": "^1.2", 760 | "sebastian/exporter": "^1.2" 761 | }, 762 | "conflict": { 763 | "phpunit/phpunit": "<5.4.0" 764 | }, 765 | "require-dev": { 766 | "phpunit/phpunit": "^5.4" 767 | }, 768 | "suggest": { 769 | "ext-soap": "*" 770 | }, 771 | "type": "library", 772 | "extra": { 773 | "branch-alias": { 774 | "dev-master": "3.2.x-dev" 775 | } 776 | }, 777 | "autoload": { 778 | "classmap": [ 779 | "src/" 780 | ] 781 | }, 782 | "notification-url": "https://packagist.org/downloads/", 783 | "license": [ 784 | "BSD-3-Clause" 785 | ], 786 | "authors": [ 787 | { 788 | "name": "Sebastian Bergmann", 789 | "email": "sb@sebastian-bergmann.de", 790 | "role": "lead" 791 | } 792 | ], 793 | "description": "Mock Object library for PHPUnit", 794 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 795 | "keywords": [ 796 | "mock", 797 | "xunit" 798 | ], 799 | "time": "2016-09-06 16:07:45" 800 | }, 801 | { 802 | "name": "sebastian/code-unit-reverse-lookup", 803 | "version": "1.0.0", 804 | "source": { 805 | "type": "git", 806 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 807 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" 808 | }, 809 | "dist": { 810 | "type": "zip", 811 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 812 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", 813 | "shasum": "" 814 | }, 815 | "require": { 816 | "php": ">=5.6" 817 | }, 818 | "require-dev": { 819 | "phpunit/phpunit": "~5" 820 | }, 821 | "type": "library", 822 | "extra": { 823 | "branch-alias": { 824 | "dev-master": "1.0.x-dev" 825 | } 826 | }, 827 | "autoload": { 828 | "classmap": [ 829 | "src/" 830 | ] 831 | }, 832 | "notification-url": "https://packagist.org/downloads/", 833 | "license": [ 834 | "BSD-3-Clause" 835 | ], 836 | "authors": [ 837 | { 838 | "name": "Sebastian Bergmann", 839 | "email": "sebastian@phpunit.de" 840 | } 841 | ], 842 | "description": "Looks up which function or method a line of code belongs to", 843 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 844 | "time": "2016-02-13 06:45:14" 845 | }, 846 | { 847 | "name": "sebastian/comparator", 848 | "version": "1.2.0", 849 | "source": { 850 | "type": "git", 851 | "url": "https://github.com/sebastianbergmann/comparator.git", 852 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" 853 | }, 854 | "dist": { 855 | "type": "zip", 856 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", 857 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", 858 | "shasum": "" 859 | }, 860 | "require": { 861 | "php": ">=5.3.3", 862 | "sebastian/diff": "~1.2", 863 | "sebastian/exporter": "~1.2" 864 | }, 865 | "require-dev": { 866 | "phpunit/phpunit": "~4.4" 867 | }, 868 | "type": "library", 869 | "extra": { 870 | "branch-alias": { 871 | "dev-master": "1.2.x-dev" 872 | } 873 | }, 874 | "autoload": { 875 | "classmap": [ 876 | "src/" 877 | ] 878 | }, 879 | "notification-url": "https://packagist.org/downloads/", 880 | "license": [ 881 | "BSD-3-Clause" 882 | ], 883 | "authors": [ 884 | { 885 | "name": "Jeff Welch", 886 | "email": "whatthejeff@gmail.com" 887 | }, 888 | { 889 | "name": "Volker Dusch", 890 | "email": "github@wallbash.com" 891 | }, 892 | { 893 | "name": "Bernhard Schussek", 894 | "email": "bschussek@2bepublished.at" 895 | }, 896 | { 897 | "name": "Sebastian Bergmann", 898 | "email": "sebastian@phpunit.de" 899 | } 900 | ], 901 | "description": "Provides the functionality to compare PHP values for equality", 902 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 903 | "keywords": [ 904 | "comparator", 905 | "compare", 906 | "equality" 907 | ], 908 | "time": "2015-07-26 15:48:44" 909 | }, 910 | { 911 | "name": "sebastian/diff", 912 | "version": "1.4.1", 913 | "source": { 914 | "type": "git", 915 | "url": "https://github.com/sebastianbergmann/diff.git", 916 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 917 | }, 918 | "dist": { 919 | "type": "zip", 920 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 921 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 922 | "shasum": "" 923 | }, 924 | "require": { 925 | "php": ">=5.3.3" 926 | }, 927 | "require-dev": { 928 | "phpunit/phpunit": "~4.8" 929 | }, 930 | "type": "library", 931 | "extra": { 932 | "branch-alias": { 933 | "dev-master": "1.4-dev" 934 | } 935 | }, 936 | "autoload": { 937 | "classmap": [ 938 | "src/" 939 | ] 940 | }, 941 | "notification-url": "https://packagist.org/downloads/", 942 | "license": [ 943 | "BSD-3-Clause" 944 | ], 945 | "authors": [ 946 | { 947 | "name": "Kore Nordmann", 948 | "email": "mail@kore-nordmann.de" 949 | }, 950 | { 951 | "name": "Sebastian Bergmann", 952 | "email": "sebastian@phpunit.de" 953 | } 954 | ], 955 | "description": "Diff implementation", 956 | "homepage": "https://github.com/sebastianbergmann/diff", 957 | "keywords": [ 958 | "diff" 959 | ], 960 | "time": "2015-12-08 07:14:41" 961 | }, 962 | { 963 | "name": "sebastian/environment", 964 | "version": "1.3.8", 965 | "source": { 966 | "type": "git", 967 | "url": "https://github.com/sebastianbergmann/environment.git", 968 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" 969 | }, 970 | "dist": { 971 | "type": "zip", 972 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", 973 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", 974 | "shasum": "" 975 | }, 976 | "require": { 977 | "php": "^5.3.3 || ^7.0" 978 | }, 979 | "require-dev": { 980 | "phpunit/phpunit": "^4.8 || ^5.0" 981 | }, 982 | "type": "library", 983 | "extra": { 984 | "branch-alias": { 985 | "dev-master": "1.3.x-dev" 986 | } 987 | }, 988 | "autoload": { 989 | "classmap": [ 990 | "src/" 991 | ] 992 | }, 993 | "notification-url": "https://packagist.org/downloads/", 994 | "license": [ 995 | "BSD-3-Clause" 996 | ], 997 | "authors": [ 998 | { 999 | "name": "Sebastian Bergmann", 1000 | "email": "sebastian@phpunit.de" 1001 | } 1002 | ], 1003 | "description": "Provides functionality to handle HHVM/PHP environments", 1004 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1005 | "keywords": [ 1006 | "Xdebug", 1007 | "environment", 1008 | "hhvm" 1009 | ], 1010 | "time": "2016-08-18 05:49:44" 1011 | }, 1012 | { 1013 | "name": "sebastian/exporter", 1014 | "version": "1.2.2", 1015 | "source": { 1016 | "type": "git", 1017 | "url": "https://github.com/sebastianbergmann/exporter.git", 1018 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" 1019 | }, 1020 | "dist": { 1021 | "type": "zip", 1022 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", 1023 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", 1024 | "shasum": "" 1025 | }, 1026 | "require": { 1027 | "php": ">=5.3.3", 1028 | "sebastian/recursion-context": "~1.0" 1029 | }, 1030 | "require-dev": { 1031 | "ext-mbstring": "*", 1032 | "phpunit/phpunit": "~4.4" 1033 | }, 1034 | "type": "library", 1035 | "extra": { 1036 | "branch-alias": { 1037 | "dev-master": "1.3.x-dev" 1038 | } 1039 | }, 1040 | "autoload": { 1041 | "classmap": [ 1042 | "src/" 1043 | ] 1044 | }, 1045 | "notification-url": "https://packagist.org/downloads/", 1046 | "license": [ 1047 | "BSD-3-Clause" 1048 | ], 1049 | "authors": [ 1050 | { 1051 | "name": "Jeff Welch", 1052 | "email": "whatthejeff@gmail.com" 1053 | }, 1054 | { 1055 | "name": "Volker Dusch", 1056 | "email": "github@wallbash.com" 1057 | }, 1058 | { 1059 | "name": "Bernhard Schussek", 1060 | "email": "bschussek@2bepublished.at" 1061 | }, 1062 | { 1063 | "name": "Sebastian Bergmann", 1064 | "email": "sebastian@phpunit.de" 1065 | }, 1066 | { 1067 | "name": "Adam Harvey", 1068 | "email": "aharvey@php.net" 1069 | } 1070 | ], 1071 | "description": "Provides the functionality to export PHP variables for visualization", 1072 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1073 | "keywords": [ 1074 | "export", 1075 | "exporter" 1076 | ], 1077 | "time": "2016-06-17 09:04:28" 1078 | }, 1079 | { 1080 | "name": "sebastian/global-state", 1081 | "version": "1.1.1", 1082 | "source": { 1083 | "type": "git", 1084 | "url": "https://github.com/sebastianbergmann/global-state.git", 1085 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1086 | }, 1087 | "dist": { 1088 | "type": "zip", 1089 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1090 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1091 | "shasum": "" 1092 | }, 1093 | "require": { 1094 | "php": ">=5.3.3" 1095 | }, 1096 | "require-dev": { 1097 | "phpunit/phpunit": "~4.2" 1098 | }, 1099 | "suggest": { 1100 | "ext-uopz": "*" 1101 | }, 1102 | "type": "library", 1103 | "extra": { 1104 | "branch-alias": { 1105 | "dev-master": "1.0-dev" 1106 | } 1107 | }, 1108 | "autoload": { 1109 | "classmap": [ 1110 | "src/" 1111 | ] 1112 | }, 1113 | "notification-url": "https://packagist.org/downloads/", 1114 | "license": [ 1115 | "BSD-3-Clause" 1116 | ], 1117 | "authors": [ 1118 | { 1119 | "name": "Sebastian Bergmann", 1120 | "email": "sebastian@phpunit.de" 1121 | } 1122 | ], 1123 | "description": "Snapshotting of global state", 1124 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1125 | "keywords": [ 1126 | "global state" 1127 | ], 1128 | "time": "2015-10-12 03:26:01" 1129 | }, 1130 | { 1131 | "name": "sebastian/object-enumerator", 1132 | "version": "1.0.0", 1133 | "source": { 1134 | "type": "git", 1135 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1136 | "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" 1137 | }, 1138 | "dist": { 1139 | "type": "zip", 1140 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", 1141 | "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", 1142 | "shasum": "" 1143 | }, 1144 | "require": { 1145 | "php": ">=5.6", 1146 | "sebastian/recursion-context": "~1.0" 1147 | }, 1148 | "require-dev": { 1149 | "phpunit/phpunit": "~5" 1150 | }, 1151 | "type": "library", 1152 | "extra": { 1153 | "branch-alias": { 1154 | "dev-master": "1.0.x-dev" 1155 | } 1156 | }, 1157 | "autoload": { 1158 | "classmap": [ 1159 | "src/" 1160 | ] 1161 | }, 1162 | "notification-url": "https://packagist.org/downloads/", 1163 | "license": [ 1164 | "BSD-3-Clause" 1165 | ], 1166 | "authors": [ 1167 | { 1168 | "name": "Sebastian Bergmann", 1169 | "email": "sebastian@phpunit.de" 1170 | } 1171 | ], 1172 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1173 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1174 | "time": "2016-01-28 13:25:10" 1175 | }, 1176 | { 1177 | "name": "sebastian/recursion-context", 1178 | "version": "1.0.2", 1179 | "source": { 1180 | "type": "git", 1181 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1182 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791" 1183 | }, 1184 | "dist": { 1185 | "type": "zip", 1186 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", 1187 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791", 1188 | "shasum": "" 1189 | }, 1190 | "require": { 1191 | "php": ">=5.3.3" 1192 | }, 1193 | "require-dev": { 1194 | "phpunit/phpunit": "~4.4" 1195 | }, 1196 | "type": "library", 1197 | "extra": { 1198 | "branch-alias": { 1199 | "dev-master": "1.0.x-dev" 1200 | } 1201 | }, 1202 | "autoload": { 1203 | "classmap": [ 1204 | "src/" 1205 | ] 1206 | }, 1207 | "notification-url": "https://packagist.org/downloads/", 1208 | "license": [ 1209 | "BSD-3-Clause" 1210 | ], 1211 | "authors": [ 1212 | { 1213 | "name": "Jeff Welch", 1214 | "email": "whatthejeff@gmail.com" 1215 | }, 1216 | { 1217 | "name": "Sebastian Bergmann", 1218 | "email": "sebastian@phpunit.de" 1219 | }, 1220 | { 1221 | "name": "Adam Harvey", 1222 | "email": "aharvey@php.net" 1223 | } 1224 | ], 1225 | "description": "Provides functionality to recursively process PHP variables", 1226 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1227 | "time": "2015-11-11 19:50:13" 1228 | }, 1229 | { 1230 | "name": "sebastian/resource-operations", 1231 | "version": "1.0.0", 1232 | "source": { 1233 | "type": "git", 1234 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1235 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1236 | }, 1237 | "dist": { 1238 | "type": "zip", 1239 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1240 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1241 | "shasum": "" 1242 | }, 1243 | "require": { 1244 | "php": ">=5.6.0" 1245 | }, 1246 | "type": "library", 1247 | "extra": { 1248 | "branch-alias": { 1249 | "dev-master": "1.0.x-dev" 1250 | } 1251 | }, 1252 | "autoload": { 1253 | "classmap": [ 1254 | "src/" 1255 | ] 1256 | }, 1257 | "notification-url": "https://packagist.org/downloads/", 1258 | "license": [ 1259 | "BSD-3-Clause" 1260 | ], 1261 | "authors": [ 1262 | { 1263 | "name": "Sebastian Bergmann", 1264 | "email": "sebastian@phpunit.de" 1265 | } 1266 | ], 1267 | "description": "Provides a list of PHP built-in functions that operate on resources", 1268 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1269 | "time": "2015-07-28 20:34:47" 1270 | }, 1271 | { 1272 | "name": "sebastian/version", 1273 | "version": "2.0.0", 1274 | "source": { 1275 | "type": "git", 1276 | "url": "https://github.com/sebastianbergmann/version.git", 1277 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" 1278 | }, 1279 | "dist": { 1280 | "type": "zip", 1281 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", 1282 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", 1283 | "shasum": "" 1284 | }, 1285 | "require": { 1286 | "php": ">=5.6" 1287 | }, 1288 | "type": "library", 1289 | "extra": { 1290 | "branch-alias": { 1291 | "dev-master": "2.0.x-dev" 1292 | } 1293 | }, 1294 | "autoload": { 1295 | "classmap": [ 1296 | "src/" 1297 | ] 1298 | }, 1299 | "notification-url": "https://packagist.org/downloads/", 1300 | "license": [ 1301 | "BSD-3-Clause" 1302 | ], 1303 | "authors": [ 1304 | { 1305 | "name": "Sebastian Bergmann", 1306 | "email": "sebastian@phpunit.de", 1307 | "role": "lead" 1308 | } 1309 | ], 1310 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1311 | "homepage": "https://github.com/sebastianbergmann/version", 1312 | "time": "2016-02-04 12:56:52" 1313 | }, 1314 | { 1315 | "name": "symfony/console", 1316 | "version": "v3.1.4", 1317 | "source": { 1318 | "type": "git", 1319 | "url": "https://github.com/symfony/console.git", 1320 | "reference": "8ea494c34f0f772c3954b5fbe00bffc5a435e563" 1321 | }, 1322 | "dist": { 1323 | "type": "zip", 1324 | "url": "https://api.github.com/repos/symfony/console/zipball/8ea494c34f0f772c3954b5fbe00bffc5a435e563", 1325 | "reference": "8ea494c34f0f772c3954b5fbe00bffc5a435e563", 1326 | "shasum": "" 1327 | }, 1328 | "require": { 1329 | "php": ">=5.5.9", 1330 | "symfony/polyfill-mbstring": "~1.0" 1331 | }, 1332 | "require-dev": { 1333 | "psr/log": "~1.0", 1334 | "symfony/event-dispatcher": "~2.8|~3.0", 1335 | "symfony/process": "~2.8|~3.0" 1336 | }, 1337 | "suggest": { 1338 | "psr/log": "For using the console logger", 1339 | "symfony/event-dispatcher": "", 1340 | "symfony/process": "" 1341 | }, 1342 | "type": "library", 1343 | "extra": { 1344 | "branch-alias": { 1345 | "dev-master": "3.1-dev" 1346 | } 1347 | }, 1348 | "autoload": { 1349 | "psr-4": { 1350 | "Symfony\\Component\\Console\\": "" 1351 | }, 1352 | "exclude-from-classmap": [ 1353 | "/Tests/" 1354 | ] 1355 | }, 1356 | "notification-url": "https://packagist.org/downloads/", 1357 | "license": [ 1358 | "MIT" 1359 | ], 1360 | "authors": [ 1361 | { 1362 | "name": "Fabien Potencier", 1363 | "email": "fabien@symfony.com" 1364 | }, 1365 | { 1366 | "name": "Symfony Community", 1367 | "homepage": "https://symfony.com/contributors" 1368 | } 1369 | ], 1370 | "description": "Symfony Console Component", 1371 | "homepage": "https://symfony.com", 1372 | "time": "2016-08-19 06:48:39" 1373 | }, 1374 | { 1375 | "name": "symfony/event-dispatcher", 1376 | "version": "v3.1.4", 1377 | "source": { 1378 | "type": "git", 1379 | "url": "https://github.com/symfony/event-dispatcher.git", 1380 | "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5" 1381 | }, 1382 | "dist": { 1383 | "type": "zip", 1384 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c0c00c80b3a69132c4e55c3e7db32b4a387615e5", 1385 | "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5", 1386 | "shasum": "" 1387 | }, 1388 | "require": { 1389 | "php": ">=5.5.9" 1390 | }, 1391 | "require-dev": { 1392 | "psr/log": "~1.0", 1393 | "symfony/config": "~2.8|~3.0", 1394 | "symfony/dependency-injection": "~2.8|~3.0", 1395 | "symfony/expression-language": "~2.8|~3.0", 1396 | "symfony/stopwatch": "~2.8|~3.0" 1397 | }, 1398 | "suggest": { 1399 | "symfony/dependency-injection": "", 1400 | "symfony/http-kernel": "" 1401 | }, 1402 | "type": "library", 1403 | "extra": { 1404 | "branch-alias": { 1405 | "dev-master": "3.1-dev" 1406 | } 1407 | }, 1408 | "autoload": { 1409 | "psr-4": { 1410 | "Symfony\\Component\\EventDispatcher\\": "" 1411 | }, 1412 | "exclude-from-classmap": [ 1413 | "/Tests/" 1414 | ] 1415 | }, 1416 | "notification-url": "https://packagist.org/downloads/", 1417 | "license": [ 1418 | "MIT" 1419 | ], 1420 | "authors": [ 1421 | { 1422 | "name": "Fabien Potencier", 1423 | "email": "fabien@symfony.com" 1424 | }, 1425 | { 1426 | "name": "Symfony Community", 1427 | "homepage": "https://symfony.com/contributors" 1428 | } 1429 | ], 1430 | "description": "Symfony EventDispatcher Component", 1431 | "homepage": "https://symfony.com", 1432 | "time": "2016-07-19 10:45:57" 1433 | }, 1434 | { 1435 | "name": "symfony/filesystem", 1436 | "version": "v3.1.4", 1437 | "source": { 1438 | "type": "git", 1439 | "url": "https://github.com/symfony/filesystem.git", 1440 | "reference": "bb29adceb552d202b6416ede373529338136e84f" 1441 | }, 1442 | "dist": { 1443 | "type": "zip", 1444 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/bb29adceb552d202b6416ede373529338136e84f", 1445 | "reference": "bb29adceb552d202b6416ede373529338136e84f", 1446 | "shasum": "" 1447 | }, 1448 | "require": { 1449 | "php": ">=5.5.9" 1450 | }, 1451 | "type": "library", 1452 | "extra": { 1453 | "branch-alias": { 1454 | "dev-master": "3.1-dev" 1455 | } 1456 | }, 1457 | "autoload": { 1458 | "psr-4": { 1459 | "Symfony\\Component\\Filesystem\\": "" 1460 | }, 1461 | "exclude-from-classmap": [ 1462 | "/Tests/" 1463 | ] 1464 | }, 1465 | "notification-url": "https://packagist.org/downloads/", 1466 | "license": [ 1467 | "MIT" 1468 | ], 1469 | "authors": [ 1470 | { 1471 | "name": "Fabien Potencier", 1472 | "email": "fabien@symfony.com" 1473 | }, 1474 | { 1475 | "name": "Symfony Community", 1476 | "homepage": "https://symfony.com/contributors" 1477 | } 1478 | ], 1479 | "description": "Symfony Filesystem Component", 1480 | "homepage": "https://symfony.com", 1481 | "time": "2016-07-20 05:44:26" 1482 | }, 1483 | { 1484 | "name": "symfony/finder", 1485 | "version": "v3.1.4", 1486 | "source": { 1487 | "type": "git", 1488 | "url": "https://github.com/symfony/finder.git", 1489 | "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577" 1490 | }, 1491 | "dist": { 1492 | "type": "zip", 1493 | "url": "https://api.github.com/repos/symfony/finder/zipball/e568ef1784f447a0e54dcb6f6de30b9747b0f577", 1494 | "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577", 1495 | "shasum": "" 1496 | }, 1497 | "require": { 1498 | "php": ">=5.5.9" 1499 | }, 1500 | "type": "library", 1501 | "extra": { 1502 | "branch-alias": { 1503 | "dev-master": "3.1-dev" 1504 | } 1505 | }, 1506 | "autoload": { 1507 | "psr-4": { 1508 | "Symfony\\Component\\Finder\\": "" 1509 | }, 1510 | "exclude-from-classmap": [ 1511 | "/Tests/" 1512 | ] 1513 | }, 1514 | "notification-url": "https://packagist.org/downloads/", 1515 | "license": [ 1516 | "MIT" 1517 | ], 1518 | "authors": [ 1519 | { 1520 | "name": "Fabien Potencier", 1521 | "email": "fabien@symfony.com" 1522 | }, 1523 | { 1524 | "name": "Symfony Community", 1525 | "homepage": "https://symfony.com/contributors" 1526 | } 1527 | ], 1528 | "description": "Symfony Finder Component", 1529 | "homepage": "https://symfony.com", 1530 | "time": "2016-08-26 12:04:02" 1531 | }, 1532 | { 1533 | "name": "symfony/polyfill-mbstring", 1534 | "version": "v1.2.0", 1535 | "source": { 1536 | "type": "git", 1537 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1538 | "reference": "dff51f72b0706335131b00a7f49606168c582594" 1539 | }, 1540 | "dist": { 1541 | "type": "zip", 1542 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", 1543 | "reference": "dff51f72b0706335131b00a7f49606168c582594", 1544 | "shasum": "" 1545 | }, 1546 | "require": { 1547 | "php": ">=5.3.3" 1548 | }, 1549 | "suggest": { 1550 | "ext-mbstring": "For best performance" 1551 | }, 1552 | "type": "library", 1553 | "extra": { 1554 | "branch-alias": { 1555 | "dev-master": "1.2-dev" 1556 | } 1557 | }, 1558 | "autoload": { 1559 | "psr-4": { 1560 | "Symfony\\Polyfill\\Mbstring\\": "" 1561 | }, 1562 | "files": [ 1563 | "bootstrap.php" 1564 | ] 1565 | }, 1566 | "notification-url": "https://packagist.org/downloads/", 1567 | "license": [ 1568 | "MIT" 1569 | ], 1570 | "authors": [ 1571 | { 1572 | "name": "Nicolas Grekas", 1573 | "email": "p@tchwork.com" 1574 | }, 1575 | { 1576 | "name": "Symfony Community", 1577 | "homepage": "https://symfony.com/contributors" 1578 | } 1579 | ], 1580 | "description": "Symfony polyfill for the Mbstring extension", 1581 | "homepage": "https://symfony.com", 1582 | "keywords": [ 1583 | "compatibility", 1584 | "mbstring", 1585 | "polyfill", 1586 | "portable", 1587 | "shim" 1588 | ], 1589 | "time": "2016-05-18 14:26:46" 1590 | }, 1591 | { 1592 | "name": "symfony/process", 1593 | "version": "v3.1.4", 1594 | "source": { 1595 | "type": "git", 1596 | "url": "https://github.com/symfony/process.git", 1597 | "reference": "e64e93041c80e77197ace5ab9385dedb5a143697" 1598 | }, 1599 | "dist": { 1600 | "type": "zip", 1601 | "url": "https://api.github.com/repos/symfony/process/zipball/e64e93041c80e77197ace5ab9385dedb5a143697", 1602 | "reference": "e64e93041c80e77197ace5ab9385dedb5a143697", 1603 | "shasum": "" 1604 | }, 1605 | "require": { 1606 | "php": ">=5.5.9" 1607 | }, 1608 | "type": "library", 1609 | "extra": { 1610 | "branch-alias": { 1611 | "dev-master": "3.1-dev" 1612 | } 1613 | }, 1614 | "autoload": { 1615 | "psr-4": { 1616 | "Symfony\\Component\\Process\\": "" 1617 | }, 1618 | "exclude-from-classmap": [ 1619 | "/Tests/" 1620 | ] 1621 | }, 1622 | "notification-url": "https://packagist.org/downloads/", 1623 | "license": [ 1624 | "MIT" 1625 | ], 1626 | "authors": [ 1627 | { 1628 | "name": "Fabien Potencier", 1629 | "email": "fabien@symfony.com" 1630 | }, 1631 | { 1632 | "name": "Symfony Community", 1633 | "homepage": "https://symfony.com/contributors" 1634 | } 1635 | ], 1636 | "description": "Symfony Process Component", 1637 | "homepage": "https://symfony.com", 1638 | "time": "2016-08-16 14:58:24" 1639 | }, 1640 | { 1641 | "name": "symfony/stopwatch", 1642 | "version": "v3.1.4", 1643 | "source": { 1644 | "type": "git", 1645 | "url": "https://github.com/symfony/stopwatch.git", 1646 | "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1" 1647 | }, 1648 | "dist": { 1649 | "type": "zip", 1650 | "url": "https://api.github.com/repos/symfony/stopwatch/zipball/bb42806b12c5f89db4ebf64af6741afe6d8457e1", 1651 | "reference": "bb42806b12c5f89db4ebf64af6741afe6d8457e1", 1652 | "shasum": "" 1653 | }, 1654 | "require": { 1655 | "php": ">=5.5.9" 1656 | }, 1657 | "type": "library", 1658 | "extra": { 1659 | "branch-alias": { 1660 | "dev-master": "3.1-dev" 1661 | } 1662 | }, 1663 | "autoload": { 1664 | "psr-4": { 1665 | "Symfony\\Component\\Stopwatch\\": "" 1666 | }, 1667 | "exclude-from-classmap": [ 1668 | "/Tests/" 1669 | ] 1670 | }, 1671 | "notification-url": "https://packagist.org/downloads/", 1672 | "license": [ 1673 | "MIT" 1674 | ], 1675 | "authors": [ 1676 | { 1677 | "name": "Fabien Potencier", 1678 | "email": "fabien@symfony.com" 1679 | }, 1680 | { 1681 | "name": "Symfony Community", 1682 | "homepage": "https://symfony.com/contributors" 1683 | } 1684 | ], 1685 | "description": "Symfony Stopwatch Component", 1686 | "homepage": "https://symfony.com", 1687 | "time": "2016-06-29 05:41:56" 1688 | }, 1689 | { 1690 | "name": "symfony/yaml", 1691 | "version": "v3.1.4", 1692 | "source": { 1693 | "type": "git", 1694 | "url": "https://github.com/symfony/yaml.git", 1695 | "reference": "f291ed25eb1435bddbe8a96caaef16469c2a092d" 1696 | }, 1697 | "dist": { 1698 | "type": "zip", 1699 | "url": "https://api.github.com/repos/symfony/yaml/zipball/f291ed25eb1435bddbe8a96caaef16469c2a092d", 1700 | "reference": "f291ed25eb1435bddbe8a96caaef16469c2a092d", 1701 | "shasum": "" 1702 | }, 1703 | "require": { 1704 | "php": ">=5.5.9" 1705 | }, 1706 | "type": "library", 1707 | "extra": { 1708 | "branch-alias": { 1709 | "dev-master": "3.1-dev" 1710 | } 1711 | }, 1712 | "autoload": { 1713 | "psr-4": { 1714 | "Symfony\\Component\\Yaml\\": "" 1715 | }, 1716 | "exclude-from-classmap": [ 1717 | "/Tests/" 1718 | ] 1719 | }, 1720 | "notification-url": "https://packagist.org/downloads/", 1721 | "license": [ 1722 | "MIT" 1723 | ], 1724 | "authors": [ 1725 | { 1726 | "name": "Fabien Potencier", 1727 | "email": "fabien@symfony.com" 1728 | }, 1729 | { 1730 | "name": "Symfony Community", 1731 | "homepage": "https://symfony.com/contributors" 1732 | } 1733 | ], 1734 | "description": "Symfony Yaml Component", 1735 | "homepage": "https://symfony.com", 1736 | "time": "2016-09-02 02:12:52" 1737 | }, 1738 | { 1739 | "name": "webmozart/assert", 1740 | "version": "1.1.0", 1741 | "source": { 1742 | "type": "git", 1743 | "url": "https://github.com/webmozart/assert.git", 1744 | "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" 1745 | }, 1746 | "dist": { 1747 | "type": "zip", 1748 | "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", 1749 | "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", 1750 | "shasum": "" 1751 | }, 1752 | "require": { 1753 | "php": "^5.3.3|^7.0" 1754 | }, 1755 | "require-dev": { 1756 | "phpunit/phpunit": "^4.6", 1757 | "sebastian/version": "^1.0.1" 1758 | }, 1759 | "type": "library", 1760 | "extra": { 1761 | "branch-alias": { 1762 | "dev-master": "1.2-dev" 1763 | } 1764 | }, 1765 | "autoload": { 1766 | "psr-4": { 1767 | "Webmozart\\Assert\\": "src/" 1768 | } 1769 | }, 1770 | "notification-url": "https://packagist.org/downloads/", 1771 | "license": [ 1772 | "MIT" 1773 | ], 1774 | "authors": [ 1775 | { 1776 | "name": "Bernhard Schussek", 1777 | "email": "bschussek@gmail.com" 1778 | } 1779 | ], 1780 | "description": "Assertions to validate method input/output with nice error messages.", 1781 | "keywords": [ 1782 | "assert", 1783 | "check", 1784 | "validate" 1785 | ], 1786 | "time": "2016-08-09 15:02:57" 1787 | } 1788 | ], 1789 | "aliases": [], 1790 | "minimum-stability": "stable", 1791 | "stability-flags": [], 1792 | "prefer-stable": false, 1793 | "prefer-lowest": false, 1794 | "platform": { 1795 | "php": ">=5.3.0" 1796 | }, 1797 | "platform-dev": [] 1798 | } 1799 | -------------------------------------------------------------------------------- /lib/PasswordPolicy/Constraint.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy; 12 | 13 | interface Constraint 14 | { 15 | public function check($number); 16 | public function getMessage(); 17 | public function toJavaScript(); 18 | } 19 | -------------------------------------------------------------------------------- /lib/PasswordPolicy/Constraints/Limit.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy\Constraints; 12 | 13 | class Limit implements \PasswordPolicy\Constraint 14 | { 15 | protected $min = 0; 16 | protected $max = 0; 17 | 18 | public function __construct($min, $max) 19 | { 20 | $this->min = (int) $min; 21 | $this->max = (int) $max; 22 | } 23 | 24 | public function check($number) 25 | { 26 | if ($number < $this->min) { 27 | return false; 28 | } 29 | if ($number > $this->max) { 30 | return false; 31 | } 32 | 33 | return true; 34 | } 35 | 36 | public function getMessage() 37 | { 38 | if ($this->max == 0) { 39 | return "no"; 40 | } elseif ($this->min == 0) { 41 | return "at most {$this->max}"; 42 | } elseif ($this->max == PHP_INT_MAX) { 43 | return "at least {$this->min}"; 44 | } 45 | 46 | return "at least {$this->min} and at most {$this->max}"; 47 | } 48 | 49 | public function toJavaScript() 50 | { 51 | $msg = $this->getMessage(); 52 | 53 | return "function(num) { 54 | if (num < {$this->min}) { 55 | return false; 56 | } else if (num > {$this->max}) { 57 | return false; 58 | } 59 | return true; 60 | }"; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/PasswordPolicy/Message.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy; 12 | 13 | class Message 14 | { 15 | protected $result = true; 16 | protected $message = ''; 17 | 18 | public function __construct($result, $text) 19 | { 20 | $this->result = (bool) $result; 21 | $this->message = $text; 22 | } 23 | 24 | public function getMessage() 25 | { 26 | return $this->message; 27 | } 28 | 29 | public function isFailed() 30 | { 31 | return !$this->result; 32 | } 33 | 34 | public function isSuccess() 35 | { 36 | return $this->result; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/PasswordPolicy/Policy.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy; 12 | 13 | class Policy 14 | { 15 | protected $rules = array(); 16 | 17 | public function atLeast($n) 18 | { 19 | return new Constraints\Limit($n, PHP_INT_MAX); 20 | } 21 | 22 | public function atMost($n) 23 | { 24 | return new Constraints\Limit(0, $n); 25 | } 26 | 27 | public function between($min, $max) 28 | { 29 | return new Constraints\Limit($min, $max); 30 | } 31 | 32 | public function never() 33 | { 34 | return new Constraints\Limit(0, 0); 35 | } 36 | 37 | public function contains( 38 | $chars, 39 | Constraint $constraint = null, 40 | $description = '' 41 | ) { 42 | list($chars, $desc) = Rules\Regex::toCharClass($chars); 43 | if ($desc && !$description) { 44 | $description = $desc; 45 | } 46 | $rule = new Rules\CharacterRange($chars, $description); 47 | if ($constraint) { 48 | $rule->setConstraint($constraint); 49 | } 50 | $this->rules[] = $rule; 51 | 52 | return $this; 53 | } 54 | 55 | public function length(Constraint $constraint) 56 | { 57 | $rule = new Rules\Size(); 58 | $rule->setConstraint($constraint); 59 | $this->rules[] = $rule; 60 | 61 | return $this; 62 | } 63 | 64 | public function endsWith($chars, $description = '') 65 | { 66 | list($chars, $desc) = Rules\Regex::toCharClass($chars); 67 | if ($desc && !$description) { 68 | $description = $desc; 69 | } 70 | $description = 'Ends with ' . $description; 71 | $rule = new Rules\Regex('/[' . $chars . ']$/', $description); 72 | $this->rules[] = $rule; 73 | 74 | return $this; 75 | } 76 | 77 | public function startsWith($chars, $description = '') 78 | { 79 | list($chars, $desc) = Rules\Regex::toCharClass($chars); 80 | if ($desc && !$description) { 81 | $description = $desc; 82 | } 83 | $description = 'Starts with ' . $description; 84 | $rule = new Rules\Regex('/^[' . $chars . ']/', $description); 85 | $this->rules[] = $rule; 86 | 87 | return $this; 88 | } 89 | 90 | public function notMatch($regex, $description) 91 | { 92 | $rule = new Rules\Regex($regex, $description); 93 | $rule->setConstraint($this->never()); 94 | $this->rules[] = $rule; 95 | 96 | return $this; 97 | } 98 | 99 | public function match($regex, $description) 100 | { 101 | $rule = new Rules\Regex($regex, $description); 102 | $this->rules[] = $rule; 103 | 104 | return $this; 105 | } 106 | 107 | public function addRule(Rule $rule) 108 | { 109 | $this->rules[] = $rule; 110 | } 111 | 112 | public function toJavaScript() 113 | { 114 | $rules = array(); 115 | foreach ($this->rules as $rule) { 116 | $rules[] = "\n" . $rule->toJavaScript(); 117 | } 118 | $stub = "(function(p) { 119 | var rules = [" . implode(', ', $rules) . " 120 | ], 121 | ruleLen = rules.length, 122 | messages = [], 123 | result = true, 124 | tmp; 125 | for (var i = 0; i < ruleLen; i++) { 126 | tmp = rules[i].check(p); 127 | messages.push({success: tmp, message: rules[i].message}); 128 | result = result && tmp; 129 | } 130 | return { 131 | result: result, 132 | messages: messages 133 | }; 134 | })"; 135 | 136 | return preg_replace('/\s\s+/', ' ', $stub); 137 | } 138 | 139 | public function test($password) 140 | { 141 | $messages = array(); 142 | $result = true; 143 | foreach ($this->rules as $rule) { 144 | $tmp = $rule->test($password); 145 | $msg = new \StdClass(); 146 | $msg->result = $tmp; 147 | $msg->message = $rule->getMessage(); 148 | $messages[] = $msg; 149 | $result = $result && $tmp; 150 | } 151 | $return = new \StdClass(); 152 | $return->result = $result; 153 | $return->messages = $messages; 154 | 155 | return $return; 156 | } 157 | 158 | public function getMessages($password) 159 | { 160 | $messages = array(); 161 | foreach ($this->rules as $rule) { 162 | $message = $rule->getMessage($password); 163 | if (!$rule->test($password)) { 164 | $messages[] = array('failed', $message); 165 | } else { 166 | $messages[] = array('passed', $message); 167 | } 168 | } 169 | 170 | return $messages; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /lib/PasswordPolicy/Rule.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy; 12 | 13 | interface Rule 14 | { 15 | public function getMessage(); 16 | public function setConstraint(\PasswordPolicy\Constraint $constraint); 17 | public function test($password); 18 | public function toJavaScript(); 19 | } 20 | -------------------------------------------------------------------------------- /lib/PasswordPolicy/Rules/Base.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy\Rules; 12 | 13 | abstract class Base implements \PasswordPolicy\Rule 14 | { 15 | protected $constraint = null; 16 | 17 | public function getMessage() 18 | { 19 | if ($this->constraint) { 20 | return $this->constraint->getMessage(); 21 | } 22 | 23 | return ''; 24 | } 25 | 26 | public function setConstraint(\PasswordPolicy\Constraint $constraint) 27 | { 28 | $this->constraint = $constraint; 29 | } 30 | 31 | public function toJavaScript() 32 | { 33 | return '{ 34 | message: "Not Implemented", 35 | check: function(p) { return false; } 36 | }'; 37 | } 38 | 39 | protected function testConstraint($num, $password) 40 | { 41 | if (empty($this->constraint)) { 42 | return (bool) $num; 43 | } 44 | 45 | return $this->constraint->check($num, $password); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/PasswordPolicy/Rules/CharacterRange.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy\Rules; 12 | 13 | class CharacterRange extends Regex 14 | { 15 | public function __construct($range, $textDescription) 16 | { 17 | $this->description = "Expecting %s $textDescription characters"; 18 | $this->regex = '/[' . $range . ']/'; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/PasswordPolicy/Rules/Regex.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy\Rules; 12 | 13 | class Regex extends Base 14 | { 15 | protected $description = ''; 16 | protected $regex = ''; 17 | 18 | public function __construct($regex, $textDescription) 19 | { 20 | $this->description = $textDescription; 21 | $this->regex = $regex; 22 | } 23 | 24 | public function getMessage() 25 | { 26 | $constraint = parent::getMessage(); 27 | 28 | return sprintf($this->description, $constraint); 29 | } 30 | 31 | public function test($password) 32 | { 33 | $matches = array(); 34 | $num = preg_match_all($this->regex, $password, $matches); 35 | 36 | return $this->testConstraint($num, $password); 37 | } 38 | 39 | public function toJavaScript() 40 | { 41 | $ret = "{ 42 | message: " . json_encode($this->getMessage()) . ", 43 | check: function(p) { 44 | var r = {$this->regex}g;"; 45 | if ($this->constraint) { 46 | $ret .= " 47 | var c = " . $this->constraint->toJavaScript() . "; 48 | var l = p.match(r); 49 | l = l ? l.length : 0; 50 | return c(l);"; 51 | } else { 52 | $ret .= " 53 | return r.test(p);"; 54 | } 55 | $ret .= " 56 | } 57 | }"; 58 | 59 | return $ret; 60 | } 61 | 62 | public static function toCharClass($desc) 63 | { 64 | switch ($desc) { 65 | case 'letter': 66 | return array('a-zA-Z', 'letter'); 67 | case 'lowercase': 68 | return array('a-z', 'lowercase'); 69 | case 'uppercase': 70 | return array('A-Z', 'uppercase'); 71 | case 'alnum': 72 | return array('a-zA-Z0-9', 'alpha numeric'); 73 | case 'digit': 74 | return array('0-9', 'digit'); 75 | case 'symbol': 76 | return array('^a-zA-Z0-9', 'symbol'); 77 | case 'null': 78 | return array('\0', 'null'); 79 | } 80 | 81 | return array($desc, ''); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lib/PasswordPolicy/Rules/Size.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy\Rules; 12 | 13 | use SecurityLib\Util; 14 | 15 | class Size extends Base 16 | { 17 | public function getMessage() 18 | { 19 | $constraint = parent::getMessage(); 20 | 21 | return "Expecting a password length of $constraint characters"; 22 | } 23 | 24 | public function test($password) 25 | { 26 | return $this->testConstraint(Util::safeStrlen($password), $password); 27 | } 28 | 29 | public function toJavaScript() 30 | { 31 | $ret = "{ 32 | message: " . json_encode($this->getMessage()) . ", 33 | check: function(p) { 34 | return (" . $this->constraint->toJavaScript() . ")(p.length); 35 | } 36 | }"; 37 | 38 | return $ret; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | test/Unit 22 | 23 | 24 | 25 | 26 | lib/ 27 | 28 | 29 | -------------------------------------------------------------------------------- /test/Unit/Rules/SizeTest.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2011 The Authors 8 | * @license http://www.opensource.org/licenses/mit-license.html MIT License 9 | * @version Build @@version@@ 10 | */ 11 | namespace PasswordPolicy\Rules; 12 | 13 | class SizeTest extends \PHPUnit_Framework_TestCase 14 | { 15 | public function testNoConstraint() 16 | { 17 | $rule = new Size(); 18 | $this->assertTrue($rule->test("abc")); 19 | } 20 | 21 | public function testNoConstraintFail() 22 | { 23 | $rule = new Size(); 24 | $this->assertFalse($rule->test("")); 25 | } 26 | } 27 | --------------------------------------------------------------------------------