Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c3ac139

Browse files
committed
Use HttpClient
1 parent 49816c1 commit c3ac139

File tree

3 files changed

+35
-24
lines changed

3 files changed

+35
-24
lines changed

src/Symfony/Component/Validator/Constraints/NotPwned.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class NotPwned extends Constraint
2525
{
2626
const PWNED_ERROR = 'd9bcdbfe-a9d6-4bfa-a8ff-da5fd93e0f6d';
2727

28-
protected static $errorNames = array(self::PWNED_ERROR => 'PWNED_ERROR');
28+
protected static $errorNames = [self::PWNED_ERROR => 'PWNED_ERROR'];
2929

3030
public $message = 'This password has been leaked in a data breach, it must not be used. Please use another password.';
3131
public $threshold = 1;

src/Symfony/Component/Validator/Constraints/NotPwnedValidator.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313

1414
use Symfony\Component\Validator\Constraint;
1515
use Symfony\Component\Validator\ConstraintValidator;
16-
use Symfony\Component\Validator\Exception\RuntimeException;
1716
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
17+
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
18+
use Symfony\Contracts\HttpClient\HttpClientInterface;
1819

1920
/**
2021
* Checks if a password has been leaked in a data breach using haveibeenpwned.com's API.
@@ -32,13 +33,15 @@ class NotPwnedValidator extends ConstraintValidator
3233
/**
3334
* @param callable(string):string|null $httpClient
3435
*/
35-
public function __construct(?callable $httpClient = null)
36+
public function __construct(HttpClientInterface $httpClient)
3637
{
3738
$this->httpClient = $httpClient;
3839
}
3940

4041
/**
4142
* {@inheritdoc}
43+
*
44+
* @throws ExceptionInterface
4245
*/
4346
public function validate($value, Constraint $constraint)
4447
{
@@ -61,10 +64,7 @@ public function validate($value, Constraint $constraint)
6164
$hashPrefix = substr($hash, 0, 5);
6265
$url = sprintf(self::RANGE_API, $hashPrefix);
6366

64-
if (!$result = $httpClient ? $httpClient($url) : @file_get_contents($url)) {
65-
throw new RuntimeException('Problem contacting the Have I been Pwned API.');
66-
}
67-
67+
$result = $httpClient->request('GET', $url)->getContent();
6868
foreach (explode("\r\n", $result) as $line) {
6969
list($hashSuffix, $count) = explode(':', $line);
7070

src/Symfony/Component/Validator/Tests/Constraints/NotPwnedValidatorTest.php

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
use Symfony\Component\Validator\Constraints\NotPwned;
1616
use Symfony\Component\Validator\Constraints\NotPwnedValidator;
1717
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
18+
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
19+
use Symfony\Contracts\HttpClient\HttpClientInterface;
20+
use Symfony\Contracts\HttpClient\ResponseInterface;
1821

1922
/**
2023
* @author Kévin Dunglas <[email protected]>
@@ -26,27 +29,35 @@ class NotPwnedValidatorTest extends ConstraintValidatorTestCase
2629
private const PASSWORD_LEAKED = 'maman';
2730
private const PASSWORD_NOT_LEAKED = ']<0585"%sb^5aa$w6!b38",,72?dp3r4\45b28Hy';
2831

29-
private const RETURN = array(
32+
private const RETURN = [
3033
'35E033023A46402F94CFB4F654C5BFE44A1:1',
3134
'35F079CECCC31812288257CD770AA7968D7:53',
3235
'36039744C253F9B2A4E90CBEDB02EBFB82D:5', // this is the matching line, password: maman
3336
'3686792BBC66A72D40D928ED15621124CFE:7',
3437
'36EEC709091B810AA240179A44317ED415C:2',
35-
);
38+
];
3639

3740
protected function createValidator()
3841
{
39-
$httpClient = function (string $url) {
40-
if (self::PASSWORD_TRIGGERING_AN_ERROR_RANGE_URL === $url) {
41-
// Simulate a connection error
42-
return false;
43-
}
44-
45-
return implode("\r\n", self::RETURN);
46-
};
47-
48-
// Pass null instead of this mock to run the tests against the real API
49-
return new NotPwnedValidator($httpClient);
42+
$httpClientStub = $this->createMock(HttpClientInterface::class);
43+
$httpClientStub->method('request')->will(
44+
$this->returnCallback(function (string $method, string $url): ResponseInterface {
45+
if (self::PASSWORD_TRIGGERING_AN_ERROR_RANGE_URL === $url) {
46+
throw new class('Problem contacting the Have I been Pwned API.') extends \Exception implements ServerExceptionInterface {
47+
};
48+
}
49+
50+
$responseStub = $this->createMock(ResponseInterface::class);
51+
$responseStub
52+
->method('getContent')
53+
->willReturn(implode("\r\n", self::RETURN));
54+
55+
return $responseStub;
56+
})
57+
);
58+
59+
// Pass HttpClient::create() instead of this mock to run the tests against the real API
60+
return new NotPwnedValidator($httpClientStub);
5061
}
5162

5263
public function testNullIsValid()
@@ -75,7 +86,7 @@ public function testInvalidPassword()
7586

7687
public function testThresholdReached()
7788
{
78-
$constraint = new NotPwned(array('threshold' => 3));
89+
$constraint = new NotPwned(['threshold' => 3]);
7990
$this->validator->validate(self::PASSWORD_LEAKED, $constraint);
8091

8192
$this->buildViolation($constraint->message)
@@ -85,7 +96,7 @@ public function testThresholdReached()
8596

8697
public function testThresholdNotReached()
8798
{
88-
$constraint = new NotPwned(array('threshold' => 10));
99+
$constraint = new NotPwned(['threshold' => 10]);
89100
$this->validator->validate(self::PASSWORD_LEAKED, $constraint);
90101

91102
$this->assertNoViolation();
@@ -112,11 +123,11 @@ public function testInvalidConstraint()
112123
*/
113124
public function testInvalidValue()
114125
{
115-
$this->validator->validate(array(), new NotPwned());
126+
$this->validator->validate([], new NotPwned());
116127
}
117128

118129
/**
119-
* @expectedException \Symfony\Component\Validator\Exception\RuntimeException
130+
* @expectedException \Symfony\Contracts\HttpClient\Exception\ExceptionInterface
120131
* @expectedExceptionMessage Problem contacting the Have I been Pwned API.
121132
*/
122133
public function testApiError()

0 commit comments

Comments
 (0)