helper = $data;
$this->escaper = $escaper;
$this->timezone = $timezone;
$this->storeManager = $storeManager;
$this->configHelper = $configHelper;
$this->failedAuthFactory = $failedAuthFactory;
$this->failedAuthResource = $failedAuthResource;
parent::__construct($context);
}
/**
* Auth.
*/
public function authenticate()
{
//in locked state
if ($this->isAuthLocked()) {
$this->sendUnauthorizedResponse();
return false;
}
//passcode not valid.
if (!$this->helper->auth($this->getRequest()->getParam('code'))) {
$this->processFailedRequest();
$this->sendUnauthorizedResponse();
return false;
}
//ip is not allowed
if (!$this->helper->isIpAllowed()) {
$this->sendNoContentResponse();
return false;
}
return true;
}
/**
*
*/
public function execute()
{
}
/**
* @return \Zend\Http\PhpEnvironment\Response
*/
public function sendUnauthorizedResponse()
{
$this->getResponse()
->setHttpResponseCode(401)
->setHeader('Pragma', 'public', true)
->setHeader(
'Cache-Control',
'must-revalidate, post-check=0, pre-check=0',
true
)
->setHeader('Content-type', 'text/html; charset=UTF-8', true)
->setBody('
401 Unauthorized
');
return $this->getResponse()->sendHeaders();
}
/**
* @return \Zend\Http\PhpEnvironment\Response
*/
public function sendNoContentResponse()
{
try {
$this->getResponse()
->setHttpResponseCode(204)
->setHeader('Pragma', 'public', true)
->setHeader(
'Cache-Control',
'must-revalidate, post-check=0, pre-check=0',
true
)
->setHeader('Content-type', 'text/html; charset=UTF-8', true);
return $this->getResponse()->sendHeaders();
} catch (\Exception $e) {
$this->helper->log($e);
}
}
/**
* Register the failed attempt and set a lock with a 5min window if more then 5 request failed.
*/
private function processFailedRequest()
{
$url = $this->_url->getCurrentUrl();
$storeId = $this->storeManager->getStore()->getId();
$failedAuth = $this->failedAuthFactory->create();
$this->failedAuthResource->load($failedAuth, $storeId, 'store_id');
$numOfFails = $failedAuth->getFailuresNum();
$lastAttemptDate = $failedAuth->getLastAttemptDate();
//set the first failed attempt
if (!$failedAuth->getId()) {
$failedAuth->setFirstAttemptDate(time());
}
//check the time for the last fail and update the records
if ($numOfFails == \Dotdigitalgroup\Email\Model\FailedAuth::NUMBER_MAX_FAILS_LIMIT) {
//ignore the resource is in a locked state
if ($failedAuth->isLocked()) {
$this->helper->log(sprintf('Resource locked time : %s ,store : %s', $lastAttemptDate, $storeId));
return;
} else {
//reset with the first lock after the the lock expired
$numOfFails = 0;
$failedAuth->setFirstAttemptDate(time());
}
}
try {
$failedAuth->setFailuresNum(++$numOfFails)
->setStoreId($storeId)
->setUrl($url)
->setLastAttemptDate(time());
$this->failedAuthResource->save($failedAuth);
} catch (\Exception $e) {
$this->helper->log($e);
}
}
/**
* @return bool
*/
private function isAuthLocked()
{
$failedAuth = $this->failedAuthFactory->create();
$storeId = $this->storeManager->getStore()->getId();
$this->failedAuthResource->load($failedAuth, $storeId, 'store_id');
return $failedAuth->isLocked();
}
}