Skip to content

Commit

Permalink
Add PHP 8 support (#12)
Browse files Browse the repository at this point in the history
* Update project dependencies to allow package to run under PHP 8

* Add suggestion entry for password directory without suggestion, fix & add dutch translations

* Rework validator logic and update tests to match PHP Zxcvbn library version 1.2 changes

* Remove development ray package and references on tests

* Bump minimum required version to supported PHP version 7.2

* Add clover xml file path to test github action

* Remove code coverage report upload

Co-authored-by: José Hernández Heughes <[email protected]>
  • Loading branch information
jahhernandez and José Hernández Heughes authored Mar 14, 2021
1 parent d05d3ed commit 0c6bfc6
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 106 deletions.
11 changes: 3 additions & 8 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ jobs:
max-parallel: 15
fail-fast: false
matrix:
php: ['5.6', '7.0', '7.1', '7.2', '7.3']
php: ['7.2', '7.3', '7.4', '8.0']

steps:
- name: Checkout
uses: actions/checkout@master

- name: Setup PHP
uses: shivammathur/setup-php@2.1.4
uses: shivammathur/setup-php@2.9.0
with:
php-version: ${{ matrix.php }}
coverage: none
Expand Down Expand Up @@ -47,7 +47,7 @@ jobs:
max-parallel: 15
fail-fast: false
matrix:
php: ['7.4']
php: ['8.0']

steps:
- name: Checkout
Expand Down Expand Up @@ -76,8 +76,3 @@ jobs:

- name: Run Unit Tests
run: php vendor/bin/phpunit --coverage-clover=clover.xml

- name: Upload Coverage Report
uses: codecov/codecov-action@v1
with:
fail_ci_if_error: true
14 changes: 7 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@
}
],
"require": {
"php": ">=5.6",
"php": ">=7.2",
"illuminate/support": "^5.4||^6.0||^7.0||^8.0",
"bjeavons/zxcvbn-php": "^0.3"
"bjeavons/zxcvbn-php": "^0.3||1.2"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.1",
"jakub-onderka/php-console-highlighter": "^0.3.2",
"jakub-onderka/php-parallel-lint": "^0.9.2",
"orchestra/testbench": "^3.4.10",
"orchestra/testbench": "~3.4.10 || ~3.6.7 || ~3.7.8 || ~3.8.6 || ^4.8 || ^5.2 || ^6.0",
"php-parallel-lint/php-console-highlighter": "^0.3.2",
"php-parallel-lint/php-parallel-lint": "^0.9.2||^1.2",
"phpmd/phpmd": "^2.6",
"phpunit/phpunit": "^5.7",
"squizlabs/php_codesniffer": "^2.8"
"phpunit/phpunit": "^5.7||^9.5",
"squizlabs/php_codesniffer": "^2.8||^3.5.8"
},
"autoload": {
"psr-4": {
Expand Down
38 changes: 14 additions & 24 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
backupGlobals="false"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutTodoAnnotatedTests="true"
verbose="true"
>
<testsuites>
<testsuite name="Unit Tests">
<directory>tests/</directory>
</testsuite>
</testsuites>

<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src/</directory>
<exclude>
<directory>vendor/</directory>
</exclude>
</whitelist>
</filter>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd" bootstrap="vendor/autoload.php" backupGlobals="false" beStrictAboutCoversAnnotation="true" beStrictAboutOutputDuringTests="true" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutTodoAnnotatedTests="true" verbose="true">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">src/</directory>
</include>
<exclude>
<directory>vendor/</directory>
</exclude>
</coverage>
<testsuites>
<testsuite name="Unit Tests">
<directory>tests/</directory>
</testsuite>
</testsuites>
</phpunit>
2 changes: 1 addition & 1 deletion resources/lang/de/validation.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

return [

'suggestion' => 'Fügen Sie ein oder zwei weitere Wörter hinzu. Gelegentliche Wörter sind besser',
'bruteforce' => 'Das Passwort ist durch Probieren leicht zu erraten. Verwenden Sie Zeichenklassen (Buchstaben, Zahlen, Sonderzeichen).',
'predictable' => 'Vorhersagbare Ersetzungen wie "@" für "a" oder "$" für "s" sind leicht zu erraten.',
'sequence' => 'Sequenzen wie "ABC" oder "123" sind leicht zu erraten.',
Expand Down
3 changes: 1 addition & 2 deletions resources/lang/en/validation.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

return [

'suggestion' => 'Add another word or two. Uncommon words are better',
'bruteforce' => 'This password is easy to brute-force. Use different character classes (letters, numbers, special characters).',
'predictable' => 'Predictable substitutions such as "@" for "a" or "$" for "s" are easy to guess',
'sequence' => 'Sequences like "ABC" or "123" are easy to guess',
Expand All @@ -17,5 +17,4 @@
'top_100' => 'This is in the top-100 most common passwords',
'digits' => 'Adding a series of digits does not improve security',
'reused' => 'Re-using information such as your name, username or email in the password is not secure',

];
36 changes: 20 additions & 16 deletions resources/lang/nl/validation.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
[
'predictable' => 'Voorspelbare vervangende tekenens zoals "@" ipv "a" of "$" ipv "s" zijn makkerlijk te raden',
'sequence' => 'Zinnen zoals "ABC" of "123" zijn makkerlijk te raden',
'repeat' => 'Herhalende tekens zoals "AAA" of "111" zijn makkerlijk te raden',
'date' => 'Datums zijn meestal makkerlijk te raden',
'year' => 'Recente jaren zijn makkerlijk te raden',
'straight_spatial' => 'Korte toetsenbord patronen zijn makkerlijk te raden',
'spatial_with_turns' => 'Op een volgende tekens zijn makkerlijk te raden',
'names' => 'Namen zijn makkerlijk te raden',
'common' => 'Wachtwoord lijkt te veel op een veelgebruikt wachtwoord',
'very_common' => 'Wachtwoord komt voor in veelgebruikte wachtwoorden',
'top_10' => 'Wachtwoord komt voor in de top 10 meest gebruikte wachtwoorden',
'top_100' => 'Wachtwoord komt voor in de top 100 meest gebruikte wachtwoorden',
'digits' => 'Een serie getallen verbetert het wachtwoord niet',
'reused' => 'Gegevens zoals uw naam of wachtwoord gebruiken in het wachtwoord is niet toegestaan',
]
<?php

return [
'suggestion' => 'Voeg nog een paar woorden toe. Ongewone woorden zijn beter',
'bruteforce' => 'Dit wachtwoord is gemakkelijk bruut te forceren. Gebruik verschillende tekenklassen (letters, cijfers, speciale tekens).',
'predictable' => 'Voorspelbare vervangende tekenens zoals "@" ipv "a" of "$" ipv "s" zijn makkerlijk te raden',
'sequence' => 'Zinnen zoals "ABC" of "123" zijn makkerlijk te raden',
'repeat' => 'Herhalende tekens zoals "AAA" of "111" zijn makkerlijk te raden',
'date' => 'Datums zijn meestal makkerlijk te raden',
'year' => 'Recente jaren zijn makkerlijk te raden',
'straight_spatial' => 'Korte toetsenbord patronen zijn makkerlijk te raden',
'spatial_with_turns' => 'Op een volgende tekens zijn makkerlijk te raden',
'names' => 'Namen zijn makkerlijk te raden',
'common' => 'Wachtwoord lijkt te veel op een veelgebruikt wachtwoord',
'very_common' => 'Wachtwoord komt voor in veelgebruikte wachtwoorden',
'top_10' => 'Wachtwoord komt voor in de top 10 meest gebruikte wachtwoorden',
'top_100' => 'Wachtwoord komt voor in de top 100 meest gebruikte wachtwoorden',
'digits' => 'Een serie getallen verbetert het wachtwoord niet',
'reused' => 'Gegevens zoals uw naam of wachtwoord gebruiken in het wachtwoord is niet toegestaan',
];
72 changes: 47 additions & 25 deletions src/ZxcvbnValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,20 @@ public function validate(...$args)
$validator = $args[3];

$desiredScore = $this->getDesiredScore($parameters);
$otherInput = $this->getAdditionalInput($validator, $parameters);
$otherInput = $this->getAdditionalInput($validator, $parameters);

$zxcvbn = new Zxcvbn();
$zxcvbn = new Zxcvbn();
$strength = $zxcvbn->passwordStrength($value, $otherInput);

$this->strength = $strength['score'];
$this->result = $strength;
$this->result = $strength;

if ($strength['score'] >= $desiredScore) {
return true;
}

$validator->setCustomMessages([
'zxcvbn' => $this->translator->get('zxcvbn::validation.' . $this->getFeedbackTranslation())
'zxcvbn' => $this->translator->get('zxcvbn::validation.' . $this->getFeedbackTranslation()),
]);

return false;
Expand All @@ -72,8 +72,7 @@ private function getDesiredScore(array $parameters = [])

private function getAdditionalInput(Validator $validator, array $parameters = [])
{
$input = $validator->getData();

$input = $validator->getData();
$otherInput = [];
foreach (array_slice($parameters, 1) as $attribute) {
if (isset($input[$attribute])) {
Expand All @@ -86,12 +85,12 @@ private function getAdditionalInput(Validator $validator, array $parameters = []

private function getFeedbackTranslation()
{
$isOnlyMatch = count($this->result['match_sequence']) === 1;
$isOnlyMatch = count($this->result['sequence']) === 1;

$longestMatch = new \stdClass();
$longestMatch = new \stdClass();
$longestMatch->token = '';

foreach ($this->result['match_sequence'] as $match) {
foreach ($this->result['sequence'] as $match) {
if (strlen($match->token) > strlen($longestMatch->token)) {
$longestMatch = $match;
}
Expand All @@ -102,52 +101,75 @@ private function getFeedbackTranslation()

private function getMatchFeedback($match, $isOnlyMatch)
{
$pattern = strtolower($match->pattern);
$pattern = mb_strtolower($match->pattern);
$strategy = 'get' . ucfirst($pattern) . 'Warning';

if (method_exists($this, $strategy)) {
return $this->$strategy($match, $isOnlyMatch);
}

// ['digits', 'year', 'date', 'repeat', 'sequence']
return strtolower($pattern);
return mb_strtolower($pattern);
}

/**
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
* @param $match
* @param $isOnlyMatch
* @return string
*/
private function getDictionaryWarning($match, $isOnlyMatch)
{
$warning = 'common'; // $match->dictionaryName == 'english'
if ($match->dictionaryName === 'passwords') {
$warning = $this->getPasswordWarning($match, $isOnlyMatch);
} elseif (in_array($match->dictionaryName, ['surnames', 'male_names', 'female_names'])) {
} elseif (in_array($match->dictionaryName, ['surnames', 'male_names', 'female_names'], true)) {
$warning = 'names';
} elseif ($match->dictionaryName === 'user_inputs') {
$warning = 'reused';
}

if (isset($match->l33t)) {
$warning = 'predictable';
return $warning;
}

/**
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
* @noinspection PhpMissingReturnTypeInspection
* @param $match
* @return string
*/
private function getRegexWarning($match)
{
$warning = 'year';

if ($match->regexName === 'recent_year') {
return 'year';
}

return $warning;
}

private function getPasswordWarning($match, $isOnlyMatch)
{
$warning = 'common';
if ($isOnlyMatch && !isset($match->l33t) && !isset($match->reversed)) {
$warning = 'very_common';

if ($match->rank <= 10) {
$warning = 'top_10';
} elseif ($match->rank <= 100) {
$warning = 'top_100';
}
if (!$isOnlyMatch) {
return 'suggestion';
}
if ($match->l33t) {
return 'predictable';
}

return $warning;
if (isset($match->reversed) && $match->reversed === true && $match->rank <= 100) {
return 'very_common';
}

if ($match->rank <= 10) {
return 'top_10';
}

if ($match->rank <= 100) {
return 'top_100';
}

return 'common';
}

/**
Expand Down
Loading

0 comments on commit 0c6bfc6

Please sign in to comment.