array(
'name' => 'Order by',
'type' => 'list',
'values' => array(
'Breach date' => 'breachDate',
'Date added to HIBP' => 'dateAdded',
),
'defaultValue' => 'dateAdded',
),
'item_limit' => array(
'name' => 'Limit number of returned items',
'type' => 'number',
'required' => true,
'defaultValue' => 20,
)
));
const API_URI = 'https://haveibeenpwned.com/api/v3';
const CACHE_TIMEOUT = 3600;
private $breaches = array();
public function collectData() {
$data = json_decode(getContents(self::API_URI . '/breaches'), true);
$breaches = array();
foreach($data as $breach) {
$item = array();
$pwnCount = number_format($breach['PwnCount']);
$item['title'] = $breach['Title'] . ' - '
. $pwnCount . ' breached accounts';
$item['dateAdded'] = $breach['AddedDate'];
$item['breachDate'] = $breach['BreachDate'];
$item['uri'] = self::URI . '/PwnedWebsites' . $breach['Name'];
$item['content'] = '
' . $breach['Description'] . '
';
$item['content'] .= '' . $this->breachType($breach) . '
';
$breachDate = date('j F Y', strtotime($breach['BreachDate']));
$addedDate = date('j F Y', strtotime($breach['AddedDate']));
$compData = implode(', ', $breach['DataClasses']);
$item['content'] .= <<
Breach date: {$breachDate}
Date added to HIBP: {$addedDate}
Compromised accounts: {$pwnCount}
Compromised data: {$compData}
EOD;
$item['uid'] = $breach['Name'];
$this->breaches[] = $item;
}
$this->orderBreaches();
$this->createItems();
}
private const BREACH_TYPES = array(
'IsVerified' => array(
false => 'Unverified breach, may be sourced from elsewhere'
),
'IsFabricated' => array(
true => 'Fabricated breach, likely not legitimate'
),
'IsSensitive' => array(
true => 'Sensitive breach, not publicly searchable'
),
'IsRetired' => array(
true => 'Retired breach, removed from system'
),
'IsSpamList' => array(
true => 'Spam list, used for spam marketing'
),
'IsMalware' => array(
true => 'Malware breach'
),
);
/**
* Extract data breach type(s)
*/
private function breachType($breach) {
$content = '';
foreach (self::BREACH_TYPES as $type => $message) {
if (isset($message[$breach[$type]])) {
$content .= $message[$breach[$type]] . '.
';
}
}
return $content;
}
/**
* Order Breaches by date added or date breached
*/
private function orderBreaches() {
$sortBy = $this->getInput('order');
$sort = array();
foreach ($this->breaches as $key => $item) {
$sort[$key] = $item[$sortBy];
}
array_multisort($sort, SORT_DESC, $this->breaches);
}
/**
* Create items from breaches array
*/
private function createItems() {
$limit = $this->getInput('item_limit');
if ($limit < 1) {
$limit = 20;
}
foreach ($this->breaches as $breach) {
$item = array();
$item['title'] = $breach['title'];
$item['timestamp'] = $breach[$this->getInput('order')];
$item['uri'] = $breach['uri'];
$item['content'] = $breach['content'];
$item['uid'] = $breach['uid'];
$this->items[] = $item;
if (count($this->items) >= $limit) {
break;
}
}
}
}