Skip to content

Commit

Permalink
Upgrade to Pwned Passwords API v2 - https://www.troyhunt.com/ive-just…
Browse files Browse the repository at this point in the history
  • Loading branch information
DivineOmega committed Feb 25, 2018
1 parent cc19852 commit b9a8b24
Showing 1 changed file with 17 additions and 38 deletions.
55 changes: 17 additions & 38 deletions src/PasswordExposedChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ class PasswordExposedChecker
private $cache;

const CACHE_EXPIRY_SECONDS = 60 * 60 * 24 * 30;
const TIME_BETWEEN_REQUESTS_SECONDS = 2;
const WAIT_TIMEOUT_SECONDS = 60;

public function __construct()
{
$this->client = new Client([
'base_uri' => 'https://haveibeenpwned.com/api/v2/',
'base_uri' => 'https://api.pwnedpasswords.com/',
'timeout' => 3.0,
]);

Expand All @@ -41,13 +39,7 @@ public function passwordExposed($password)
return $cacheItem->get();
}

$proceed = $this->wait();

if (!$proceed) {
return PasswordStatus::UNKNOWN;
}

$status = $this->getPasswordStatus($this->makeRequest($hash));
$status = $this->getPasswordStatus($hash, $this->makeRequest($hash));

if (in_array($status, [PasswordStatus::EXPOSED, PasswordStatus::NOT_EXPOSED])) {
$cacheItem->set($status);
Expand All @@ -67,44 +59,31 @@ private function makeRequest($hash)
],
];

return $this->client->request('GET', 'pwnedpassword/'.$hash, $options);
return $this->client->request('GET', 'range/'.substr($hash, 0, 5), $options);
}

private function getPasswordStatus(Response $response)
private function getPasswordStatus($hash, Response $response)
{
switch ($response->getStatusCode()) {
case 200:
return PasswordStatus::EXPOSED;

case 404:
return PasswordStatus::NOT_EXPOSED;
if ($response->getStatusCode()!==200) {
return PasswordStatus::UNKNOWN;
}

return PasswordStatus::UNKNOWN;
}
$hash = strtoupper($hash);
$hashSuffix = substr($hash, 5);

/**
* The wait method waits until 2 seconds have passed since the last request, then returns true.
* If we have been waiting for greater than self::WAIT_TIMEOUT_SECONDS, give up and return false.
*/
private function wait()
{
$startTime = time();
$body = (string) $response->getBody();

while (true) {
$lastRequestCacheItem = $this->cache->getItem('last_request');
if (!$lastRequestCacheItem->isHit() || $lastRequestCacheItem->get() < time() - self::TIME_BETWEEN_REQUESTS_SECONDS) {
$lastRequestCacheItem->set(time());
$this->cache->save($lastRequestCacheItem);
$lines = explode("\r\n", $body);

return true;
foreach($lines as $line) {
list($exposedHashSuffix, $occurrences) = explode(':', $line);
if ($hashSuffix==$exposedHashSuffix) {
return PasswordStatus::EXPOSED;
}
}

if ($startTime < time() - self::WAIT_TIMEOUT_SECONDS) {
return false;
}
return PasswordStatus::NOT_EXPOSED;

sleep(1);
}
}

}

0 comments on commit b9a8b24

Please sign in to comment.