userManager = $userManager; $this->em = $em; $this->mailer = $mailer; $this->eb = $eb; $this->ii = $ii; $this->requestStack = $requestStack; $this->router = $router; $this->tmpName = ""; $this->sm = $sm; $this->cookieName = "Phoenix_Machine_Name"; $this->cookieName_tmp_device = "Phoenix_tmp_device_state"; } /** * Generate a new authentication code an send it to the user * @param CustomUserInterface $user * @todo handle errors on $state = false */ public function generateAndSend(CustomUserInterface $user) { $code = mt_rand(10000, 99999); $user->setTwoFactorEmailCode($code); $user->resetFailedAttempt(); $state = $this->userManager->quickUpdate($user); $this->sendCode($user); } /** * Send email with code to user * @param CustomUserInterface $user */ protected function sendCode(CustomUserInterface $user) { $message = new \Swift_Message(); $title = $this->sm->get('twoauth_email_title','default title'); $infoArray = $this->ii->getInfo(); $ipInfo = $infoArray['ip']; $device = "Unknown-Device"; $geo = $infoArray['geolocalisation']; $geoString = ""; if (isset($geo['city']) && isset($geo['country']) && isset($geo['countryCode']) && isset($geo['isp'])) { $geoString = '(' . $geo['isp'] . ') - ' . $geo['city'] . ', ' . $geo['country'] . ' (' . $geo['countryCode'] . ')'; }elseif (isset($geo['country_code'])){ $geoString = '('.$geo['country_code'].')'; } if ($this->getMachineName() != "NaN") $device = $this->getMachineName(); if (!empty($geoString)) $geoString = " " . $geoString; $url_help = ""; //todo request url to help in any hack attempt $args = array( 'code' => $user->getTwoFactorEmailCode(), 'new_ip' => $device . " : " . $ipInfo . $geoString, 'title_email' => $title, 'url_help' => $url_help, ); $body = $this->eb->buildEmail('@UserBasis/Default/Email/newDevice.email.html.twig', $args); $message ->setTo($user->getEmail()) ->setSubject($title) ->setFrom($this->sm->get('mailing_sender','admin@default.com')) ->setContentType('text/html') ->setBody($body); $this->mailer->send($message); } /** * Get machine name from cookies or set a new one if $generate is set tot TRUE * * @param bool $generate * @param string $default * @return mixed|string */ public function getMachineName($generate = false, $default = "NaN") { if (!empty($this->tmpName)) return $this->tmpName; $cookies = $this->requestStack->getCurrentRequest()->cookies; if (isset($cookies) && $cookies->has($this->cookieName)) { $name = $cookies->get($this->cookieName); } else { $name = $default; } $this->tmpName = $name; return $name; } /** * Generate a new random name * * @return string */ public function getNewName() { $basename = "DEVICE-"; $hash = substr(md5((string)$this->ii->getIp() . (string)mt_rand(10, 99)), 0, 5); return $basename . $hash; } public function setTempDevice($bool) { $cookie = new Cookie($this->cookieName_tmp_device, $bool, strtotime('now + 2 years')); $response = new Response(); $response->headers->setCookie($cookie); $response->sendHeaders(); } public function isTempDevice($default = false) { $cookies = $this->requestStack->getCurrentRequest()->cookies; if ($cookies->has($this->cookieName_tmp_device)) { $state = $cookies->get($this->cookieName_tmp_device); } else { $state = $default; } return $state; } /** * Set a new name for the device * @todo handle errors on $state = false * * @param CustomUserInterface $user * @param $name * @param null $oldName * @return bool */ public function setNewName(CustomUserInterface $user, $name, $oldName = null) { if (empty($name)) return false; $return = false; if (is_null($oldName)) $oldName = $this->getMachineName(); $allAuthorization = $user->getAuthorizedIps(); foreach ($allAuthorization as $key => $cred) { if (is_array($cred) && isset($cred['ip']) && isset($cred['computer'])) { if ($cred['ip'] == $this->ii->getIp()) { if ($cred['computer'] == $oldName) { //device alrdy authorized $cookie = new Cookie($this->cookieName, $name, strtotime('now + 2 years')); $response = new Response(); $response->headers->setCookie($cookie); $response->sendHeaders(); $this->tmpName = $name; $allAuthorization[$key]['computer'] = $name; $return = true; } } } } $user->setAuthorizedIps($allAuthorization); $state = $this->userManager->quickUpdate($user); return $return; } /** * Validates the code, which was entered by the user * * @todo handle errors on $state = false * * @param CustomUserInterface $user * @param $code * @param bool $addIp * @return bool */ public function checkCode(CustomUserInterface $user, $code, $addIp = false) { $bool = $user->getTwoFactorEmailCode() == $code; if ($bool && $addIp) { $user->addAuthorizedIp($this->ii->getIp(), $this->getMachineName(true)); $state = $this->userManager->quickUpdate($user); } if (!$bool) { $user->incrementFailedAttempt(); $state = $this->userManager->quickUpdate($user); if ($user->getFailedAttempt() >= 4) { $user->resetFailedAttempt(); $state = $this->userManager->quickUpdate($user); } } return $bool; } /** * Generates the attribute key for the session * @param TokenInterface $token * @return string */ public function getSessionKey(TokenInterface $token) { return sprintf('two_factor_%s_%s', $token->getProviderKey(), $token->getUsername()); } }