View source
<?php
namespace Drupal\tfa\Plugin\TfaLogin;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\encrypt\EncryptionProfileManagerInterface;
use Drupal\encrypt\EncryptServiceInterface;
use Drupal\tfa\Plugin\TfaBasePlugin;
use Drupal\tfa\Plugin\TfaLoginInterface;
use Drupal\tfa\Plugin\TfaValidationInterface;
use Drupal\user\UserDataInterface;
class TfaTrustedBrowser extends TfaBasePlugin implements TfaLoginInterface, TfaValidationInterface {
use StringTranslationTrait;
protected $trustBrowser;
protected $cookieName;
protected $expiration;
public function __construct(array $configuration, $plugin_id, $plugin_definition, UserDataInterface $user_data, EncryptionProfileManagerInterface $encryption_profile_manager, EncryptServiceInterface $encrypt_service) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $user_data, $encryption_profile_manager, $encrypt_service);
$config = \Drupal::config('tfa.settings');
$this->cookieName = $config
->get('cookie_name') ?: 'TFA';
$this->expiration = $config
->get('trust_cookie_expiration') ?: 86400 * 30;
$this->userData = $user_data;
}
public function loginAllowed() {
if (isset($_COOKIE[$this->cookieName]) && $this
->trustedBrowser($_COOKIE[$this->cookieName]) !== FALSE) {
$this
->setUsed($_COOKIE[$this->cookieName]);
return TRUE;
}
return FALSE;
}
public function getForm(array $form, FormStateInterface $form_state) {
$form['trust_browser'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Remember this browser?'),
'#description' => $this
->t('Not recommended if you are on a public or shared computer.'),
];
return $form;
}
public function validateForm(array $form, FormStateInterface $form_state) {
}
public function submitForm(array $form, FormStateInterface &$form_state) {
$trust_browser = $form_state
->getValue('trust_browser');
if (!empty($trust_browser)) {
$this
->setTrusted($this
->generateBrowserId(), $this
->getAgent());
}
}
public function finalize() {
if ($this->trustBrowser) {
$name = $this
->getAgent();
$this
->setTrusted($this
->generateBrowserId(), $name);
}
}
protected function generateBrowserId() {
$id = base64_encode(random_bytes(32));
return strtr($id, [
'+' => '-',
'/' => '_',
'=' => '',
]);
}
protected function setTrusted($id, $name = '') {
$records = $this
->getUserData('tfa', 'tfa_trusted_browser', $this->configuration['uid'], $this->userData) ?: [];
$request_time = \Drupal::time()
->getRequestTime();
$records[$id] = [
'created' => $request_time,
'ip' => \Drupal::request()
->getClientIp(),
'name' => $name,
];
$data = [
'tfa_trusted_browser' => $records,
];
$this
->setUserData('tfa', $data, $this->configuration['uid'], $this->userData);
$cookie_secure = ini_get('session.cookie_secure');
$expiration = $request_time + $this->expiration;
$domain = strpos($_SERVER['HTTP_HOST'], 'localhost') === FALSE ? $_SERVER['HTTP_HOST'] : FALSE;
setcookie($this->cookieName, $id, $expiration, '/', $domain, empty($cookie_secure) ? FALSE : TRUE, TRUE);
$name = empty($name) ? $this
->getAgent() : $name;
\Drupal::logger('tfa')
->info('Set trusted browser for user UID @uid, browser @name', [
'@name' => $name,
'@uid' => $this->uid,
]);
}
protected function setUsed($id) {
$result = $this
->getUserData('tfa', 'tfa_trusted_browser', $this->uid, $this->userData);
$result[$id]['last_used'] = \Drupal::time()
->getRequestTime();
$data = [
'tfa_trusted_browser' => $result,
];
$this
->setUserData('tfa', $data, $this->uid, $this->userData);
}
protected function trustedBrowser($id) {
$result = $this
->getUserData('tfa', 'tfa_trusted_browser', $this->uid, $this->userData);
if (isset($result[$id])) {
return TRUE;
}
return FALSE;
}
protected function deleteTrusted($id = '') {
$result = $this
->getUserData('tfa', 'tfa_trusted_browser', $this->uid, $this->userData);
if ($id) {
if (isset($result[$id])) {
unset($result[$id]);
$data = [
'tfa_trusted_browser' => $result,
];
$this
->setUserData('tfa', $data, $this->uid, $this->userData);
return TRUE;
}
}
else {
$this
->deleteUserData('tfa', 'tfa_trusted_browser', $this->uid, $this->userData);
return TRUE;
}
return FALSE;
}
protected function getAgent($name = '') {
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$agent = $_SERVER['HTTP_USER_AGENT'];
if (preg_match("/like\\sGecko\\)\\sChrome\\//", $agent)) {
$name = 'Chrome';
}
elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox') !== FALSE) {
$name = 'Firefox';
}
elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) {
$name = 'Internet Explorer';
}
elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== FALSE) {
$name = 'Safari';
}
else {
$name = substr($agent, 0, 255);
}
}
return $name;
}
public function ready() {
return TRUE;
}
}