<?php
namespace App\FHI360\Access\Portal\Controller;
//use http\Env\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use \Curl\Curl;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpFoundation\Cookie;
class SecurityController extends Controller
{
protected $authorizationChecker;
/**
* @Route("/login", name="login")
*/
public function loginAction(Request $request)
{
$this->authorizationChecker = $this->get('security.authorization_checker');
// if user is logged in already, redirect to portal dashboard
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
return new RedirectResponse($this->generateUrl('portal'));
}
$authenticationUtils = $this->get('security.authentication_utils');
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$check_if_javascript_is_enabled = $this->getParameter("check_if_javascript_is_enabled");
$check_if_cookie_is_enabled = $this->getParameter("check_if_cookie_is_enabled");
//Check Browser compatibility
$suiteUtils = $this->container->get('suite_utils');
$browser_details = $suiteUtils->getBrowserDetails();
$browserName = $browser_details['name'];
$acceptableBrowser = array('Mozilla Firefox','Apple Safari','Google Chrome', 'Microsoft Edge');
if(in_array($browserName,$acceptableBrowser)){
$check_browser_compatible = "yes";
}else{
$check_browser_compatible = "no";
}
return $this->render('Portal/Security/login.html.twig', array(
'lastUserName' => $lastUsername,
'check_browser_compatible' => $check_browser_compatible,
'check_if_javascript_is_enabled' => $check_if_javascript_is_enabled,
'check_if_cookie_is_enabled' => $check_if_cookie_is_enabled
));
}
/**
* @Route("/login_check", name="login_check")
*/
public function loginCheckAction(Request $request)
{
return $this->render('Portal/Security/login.html.twig');
}
/**
* @Route("/logout", name="logout")
*/
public function logoutAction(){
throw new \Exception('This should not be reached!');
}
/**
* @Route("/extend_session", name="extend_session")
*/
public function extendSessionAction(Request $request)
{
if ($request->hasSession()) {
$session = $request->getSession();
if (isset($_COOKIE["PHPSESSID"])) {
$session_created = $session->getMetadataBag()->getCreated();
$session_lifetime = $session->getMetadataBag()->getLifetime();
$session_expire_time = $session_created + $session_lifetime;
$time_to_expire = $session_expire_time - time();
//only ask user to extend the session when we have less than 15 minutes left
$minutes_before_prompt = $this->getParameter("session_timeout_timer_minutes");
if ($time_to_expire > 0 && $time_to_expire < $minutes_before_prompt * 60) {
$request->getSession()->migrate(true); //keep session active but generate new session id
//set same session/cookie for suitecrm
setcookie("PHPSESSID", $session->get('suite_session'), time()+$session_lifetime, "/crm");
}
}
}
$redirectUrl = "https://{$this->getParameter('portal_domain')}";
return new RedirectResponse($redirectUrl);
}
/**
* @Route("/check_session", name="check_session")
*/
public function checkSessionAction(Request $request)
{
$display_timeout_modal = "false";
$this->authorizationChecker = $this->get('security.authorization_checker');
// if user is logged in already, redirect to portal dashboard
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
if ($request->hasSession()) {
$session = $request->getSession();
if (isset($_COOKIE["PHPSESSID"])) {
$session_created = $session->getMetadataBag()->getCreated();
$session_lifetime = $session->getMetadataBag()->getLifetime();
$session_expire_time = $session_created + $session_lifetime;
$time_to_expire = $session_expire_time - time();
//only ask user to extend the session when we have less than 15 minutes left
$minutes_before_prompt = $this->getParameter("session_timeout_timer_minutes");
if ($time_to_expire > 0 && $time_to_expire < $minutes_before_prompt * 60) {
$display_timeout_modal = $time_to_expire;
}
}
}
}
return new Response($display_timeout_modal);
}
/**
* @Route("/reset-password", name="reset-password")
*/
public function forgotPasswordAction(Request $request)
{
return $this->render('Portal/Security/reset-password.html.twig', array(
'recaptcha_site_key' => $this->getParameter('recaptcha_site_key'),
'forgot_password_url' => $this->getParameter('forgot_password_url'),
'lastEmail' => "",
));
}
/**
* @Route("/changenewpassword", name="Changenewpassword")
*/
public function changenewpasswordAction(Request $request)
{
$suiteUtils = $this->container->get('suite_utils');
$password_link_id = $request->query->get('guid');
$password_link_details = $suiteUtils->getPasswordLinkDetails($password_link_id);
$linkexpiration = 24;
$expired='0';
if(sizeof($password_link_details)==0){
// Set success error message
$this->addFlash(
'error',
'The reset password link has been expired. Please create a new one using forgot password'
);
// Redirect to login page
return $this->redirectToRoute('login');
}
$password_link_details = $password_link_details[0];
if($linkexpiration){
$delay=$linkexpiration*60*60;
$stim = strtotime($password_link_details['date_generated']) + date('Z');
$expiretime =$stim+$delay;
$timenow = time();
if ($timenow > $expiretime){
// Set success error message
$this->addFlash(
'error',
'The reset password link has been expired. Please create a new one using forgot password'
);
// Redirect to login page
return $this->redirectToRoute('login');
}
}
$file = $this->get('kernel')->getProjectDir().'/password-requirements.json';
$password_settings = json_decode(file_get_contents($file),true);
$data = array(
'tools' => '',
'username' => $password_link_details['username'],
'guid' => $password_link_id,
'first_name' => $password_link_details['first_name'],
'last_name' => $password_link_details['last_name'],
'email' => $password_link_details['email'],
'password_settings'=>$password_settings,
);
return $this->render('Portal/Security/generate-password.html.twig',$data);
}
/**
* @Route("/changenewpassword/submit", name="changenewpassword-submit")
*/
public function changenewpasswordSubmitAction(Request $request){
// FHI360\Access\SuiteBundle\Service\SuiteUtils
$suiteUtils = $this->container->get('suite_utils');
// Get the fields from request
$form_user_name = $request->request->get('user_name');
$form_new_password = $request->request->get('new_password');
$form_confirm_password = $request->request->get('confirm_password');
$form_guid = $request->request->get('guid');
$firstName = $request->request->get('first_name');
$lastName = $request->request->get('last_name');
$email = $request->request->get('email');
$file = $this->get('kernel')->getProjectDir().'/password-requirements.json';
$password_settings = json_decode(file_get_contents($file),true);
$password_ok = true;
if(!empty($form_new_password)) {
if(empty($form_confirm_password)) {
$this->addFlash(
'error',
"Please enter Confirmation Password"
);
$password_ok = false;
return $this->redirect('/changenewpassword?guid='.$form_guid);
} else if($form_new_password !== $form_confirm_password) {
$this->addFlash(
'error',
"New and Confirmation Passwords don't match"
);
$password_ok = false;
return $this->redirect('/changenewpassword?guid='.$form_guid);
}
$password_requirements = $suiteUtils->validatePasswordRequirements($file,$form_new_password,strtolower($form_user_name),strtolower($firstName),strtolower($lastName),strtolower($email));
if(!$password_requirements['valid']){
$this->addFlash(
'error',
$password_requirements['message']
);
$password_ok = false;
return $this->redirect('/changenewpassword?guid='.$form_guid);
}
}
if($password_ok && !empty($form_new_password) && !empty($form_confirm_password) && !empty($form_user_name)){
$sugarURL = $this->getParameter('suitecrml_url');
$url = $sugarURL . "/index.php?entryPoint=change_new_password";
$curl = new Curl($url);
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
$curl->setOpt(CURLOPT_RETURNTRANSFER, true);
$curl->setOpt(CURLOPT_FOLLOWLOCATION, false);
$post_param = array(
'user_name' => $form_user_name,
'new_password' => trim($form_new_password),
'guid' => $form_guid,
'previous_passwords' => $password_settings['previous_passwords']['required'],
'previous_passwords_count' => $password_settings['previous_passwords']['min'],
);
$curl->post($url, $post_param);
$response_data = json_decode(json_encode($curl->response), true);
if(isset($response_data) && $response_data==false) {
$this->addFlash('error', "There was an error when trying to change your password.");
return $this->redirect('/changenewpassword?guid='.$form_guid);
}else if(isset($response_data) && $response_data=='password_used'){
$this->addFlash('error', $password_settings['previous_passwords']['message']);
return $this->redirect('/changenewpassword?guid='.$form_guid);
}
else {
$this->addFlash('notice', "Your password has been reset.");
return $this->redirectToRoute('login');
}
}else{
return $this->redirect('/changenewpassword?guid='.$form_guid);
}
}
/**
* @Route("/send-forgot-password", name="send-forgot-password")
*/
public function sendForgotPasswordAction(Request $request)
{
// FHI360\Access\SuiteBundle\Service\SuiteUtils
$suiteUtils = $this->container->get('suite_utils');
$lastEmail = !empty($request->request->get('fp_user_mail')) ? $request->request->get('fp_user_mail') : "";
// Set URL to verify user captcha before calling SuiteCRM reset password endpoint
$recaptcha_verify_url = $this->getParameter('recaptcha_verify_url');
$curl = new Curl($recaptcha_verify_url);
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
$curl->setOpt(CURLOPT_RETURNTRANSFER, true);
$curl->setOpt(CURLOPT_FOLLOWLOCATION, false);
// Setting the values defined at
// https://www.google.com/recaptcha/admin#site/338881496?setup
$post = array(
'secret' => $this->getParameter('recaptcha_secret_key'),
'response' => $request->request->get('g-recaptcha-response'),
);
$curl->post($recaptcha_verify_url, $post);
$response_data = json_decode(json_encode($curl->response), true);
// If captcha verified send forgot password
// email and redirect to login page
if($response_data['success']){
$userName = $request->request->get('fp_user_name');
//Check Restrict user before sending any email
$userRestrictCheck = $suiteUtils->getUserRestrictCheck($userName);
if($userRestrictCheck == 1){
$this->addFlash('error', 'Invalid User Login');
// Redirect to login page
return $this->redirectToRoute('login');
}
// Call SuiteCRM to send reset password email
$post = array(
'user_name' => $request->request->get('fp_user_name'),
'user_email' => $request->request->get('fp_user_mail'),
'link' => '1',
);
$sugarURL = "https://{$this->getParameter('suite_domain')}";
$curl->post("$sugarURL/index.php?entryPoint=GeneratePassword", $post);
$response_data = json_decode(json_encode($curl->response), true);
if($response_data == "1"){
// Set success error message
$this->addFlash(
'notice',
'The email was sent! Please check your inbox to reset your password.'
);
// Redirect to login page
return $this->redirectToRoute('login');
} else {
// Set email address
// Show error
$this->addFlash(
'error',
"The email couldn't be sent, please check your email address or contact the Access Tech Team."
);
}
} else {
// Show error
$this->addFlash(
'error',
"Please complete the reCaptcha challenge before submitting your request."
);
}
return $this->render('Portal/Security/reset-password.html.twig', array(
'recaptcha_site_key' => $this->getParameter('recaptcha_site_key'),
'forgot_password_url' => $this->getParameter('forgot_password_url'),
'lastEmail' => $lastEmail
));
}
/**
* @Route("/changepassword", name="Changepassword")
*/
public function changepasswordAction(Request $request)
{
$suiteUtils = $this->container->get('suite_utils');
$password_link_id = $request->query->get('guid');
$password_link_details = $suiteUtils->getPasswordLinkDetails($password_link_id);
if(sizeof($password_link_details)==0){
// Set success error message
$this->addFlash(
'error',
'The reset password link has been expired. Please create a new one using forgot password'
);
// Redirect to login page
return $this->redirectToRoute('login');
}
$password_link_details = $password_link_details[0];
$file = $this->get('kernel')->getProjectDir().'/password-requirements.json';
$password_settings = json_decode(file_get_contents($file),true);
$data = array(
'tools' => '',
'username' => $password_link_details['username'],
'guid' => $password_link_id,
'first_name' => $password_link_details['first_name'],
'last_name' => $password_link_details['last_name'],
'email' => $password_link_details['email'],
'password_settings'=>$password_settings,
);
return $this->render('Portal/Security/change-old-password.html.twig',$data);
}
/**
* @Route("/changepassword/submit", name="changepassword-submit")
*/
public function changepasswordSubmitAction(Request $request){
// FHI360\Access\SuiteBundle\Service\SuiteUtils
$suiteUtils = $this->container->get('suite_utils');
// Get the fields from request
$form_user_name = $request->request->get('user_name');
$form_old_password = $request->request->get('old_password');
$form_new_password = $request->request->get('new_password');
$form_confirm_password = $request->request->get('confirm_password');
$form_guid = $request->request->get('guid');
$firstName = $request->request->get('first_name');
$lastName = $request->request->get('last_name');
$email = $request->request->get('email');
$file = $this->get('kernel')->getProjectDir().'/password-requirements.json';
$password_settings = json_decode(file_get_contents($file),true);
$password_ok = true;
if(!empty($form_new_password)) {
if(empty($form_old_password)) {
$this->addFlash(
'error',
"Please enter Current Password"
);
$password_ok = false;
return $this->redirect('/changepassword?guid='.$form_guid);
}
else if(empty($form_confirm_password)) {
$this->addFlash(
'error',
"Please enter Confirmation Password"
);
$password_ok = false;
return $this->redirect('/changepassword?guid='.$form_guid);
} else if($form_new_password !== $form_confirm_password) {
$this->addFlash(
'error',
"New and Confirmation Passwords don't match"
);
$password_ok = false;
return $this->redirect('/changepassword?guid='.$form_guid);
}
$password_requirements = $suiteUtils->validatePasswordRequirements($file,$form_new_password,strtolower($form_user_name),strtolower($firstName),strtolower($lastName),strtolower($email));
if(!$password_requirements['valid']){
$this->addFlash(
'error',
$password_requirements['message']
);
$password_ok = false;
return $this->redirect('/changepassword?guid='.$form_guid);
}
}
if($password_ok && !empty($form_new_password) && !empty($form_confirm_password) && !empty($form_user_name)){
$sugarURL = $this->getParameter('suitecrml_url');
$url = $sugarURL . "/index.php?entryPoint=change_new_password";
$curl = new Curl($url);
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
$curl->setOpt(CURLOPT_RETURNTRANSFER, true);
$curl->setOpt(CURLOPT_FOLLOWLOCATION, false);
$post_param = array(
'user_name' => $form_user_name,
'old_password' => trim($form_old_password),
'new_password' => trim($form_new_password),
'guid' => $form_guid,
'previous_passwords' => $password_settings['previous_passwords']['required'],
'previous_passwords_count' => $password_settings['previous_passwords']['min'],
);
$curl->post($url, $post_param);
$response_data = json_decode(json_encode($curl->response), true);
$this->container->get('session')->getFlashBag()->clear();
if(isset($response_data) && $response_data==false) {
$this->addFlash('error', "There was an error when trying to change your password.");
return $this->redirect('/changepassword?guid='.$form_guid);
}else if(isset($response_data) && $response_data=='password_failed'){
$this->addFlash('error', 'There was an error when trying to change your password, make sure the current password is correct.');
return $this->redirect('/changepassword?guid='.$form_guid);
}else if(isset($response_data) && $response_data=='password_used'){
$this->addFlash('error', $password_settings['previous_passwords']['message']);
return $this->redirect('/changepassword?guid='.$form_guid);
}
else {
$this->addFlash('notice', "Your password has been reset.");
return $this->redirectToRoute('login');
}
}else{
return $this->redirect('/changepassword?guid='.$form_guid);
}
}
/**
* @Route("/policies", name="policies")
*/
public function policies(Request $request)
{
if($this->getParameter("enable_disclaimer")=='no'){
return $this->redirect('/');
}
$suiteUtils = $this->container->get('suite_utils');
$gid = $request->query->get('guid');
if(isset($gid) && $gid!=""){
$password_link_details = $suiteUtils->getPasswordLinkDetails($gid);
if(sizeof($password_link_details)==0){
// Set success error message
$this->addFlash(
'error',
'The link has been expired.'
);
// Redirect to login page
return $this->redirectToRoute('login');
}
}
$file = $this->get('kernel')->getProjectDir().'/policy-document.txt';
$policy_content = file_get_contents($file,FILE_IGNORE_NEW_LINES);
$data = array(
'tools' => '',
'policy_content' => nl2br($policy_content,true),
'guid' => $gid
);
return $this->render('Portal/Security/policies.html.twig',$data);
}
/**
* @Route("/policies-submit", name="policies-submit")
*/
public function policiesSubmitAction(Request $request)
{
$suiteUtils = $this->container->get('suite_utils');
if($this->get('security.token_storage')->getToken() != null && $this->get('security.token_storage')->getToken()->getUsername() != 'anon.'){
$user = $this->get('security.token_storage')->getToken()->getUser();
$user_id = $user->getID();
$user_name = $user->getUsername();
$suiteUtils->saveUserAcceptedTerms($user_id,$user_name);
$request->getSession()->set("user_accepted_terms",'yes');
return $this->redirect('/');
}else{
$gid = $request->request->get('guid');
if(isset($gid) && $gid!=""){
$password_link_details = $suiteUtils->getPasswordLinkDetails($gid);
if(sizeof($password_link_details)==0){
// Set success error message
$this->addFlash(
'error',
'The link has been expired.'
);
// Redirect to login page
return $this->redirectToRoute('login');
}
$suiteUtils->saveUserAcceptedTerms($password_link_details[0]['user_id'],$password_link_details[0]['username']);
return $this->redirect('/changepassword?guid='.$gid);
}
}
}
/**
* @Route("/set-user-consent", name="set-user-consent")
*/
public function setUserConsentAction(Request $request){
$user = $this->get('security.token_storage')->getToken()->getUser();
$suiteUtils = $this->container->get('suite_utils');
$user_id = $user->getID();
$suiteUtils->saveUserConsent($user_id);
return $this->redirectToRoute('login');
}
/**
* @Route("/masquerade", name="masquerade")
* @author Mahesh
* Check if the logged in user is admin and rewrite
* the session to make the logged in user as requested user.
*/
public function masqueradeAction(Request $request)
{
$this->authorizationChecker = $this->get('security.authorization_checker');
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
if ($request->hasSession()) {
$user = $this->get('security.token_storage')->getToken()->getUser();
$suiteUtils = $this->container->get('suite_utils');
$user_has_switch_permission = $suiteUtils->getUserPermissionForSwitchUser($user->getID());
if($user_has_switch_permission){
setcookie("masquerade", "true");
return $this->redirect("/?_swtich_user=".$request->query->get('username'));
}else{
return new RedirectResponse($this->generateUrl('portal'));
}
}
}
}
}