private function loginUserGet($login, $password, $accountId, $scalrCaptcha, $scalrCaptchaChallenge) { if ($login != '' && $password != '') { $isAdminLogin = $this->db->GetOne('SELECT * FROM account_users WHERE email = ? AND account_id = 0', array($login)); if ($this->getContainer()->config->get('scalr.auth_mode') == 'ldap' && !$isAdminLogin) { $ldap = $this->getContainer()->ldap($login, $password); $this->response->setHeader('X-Scalr-LDAP-Login', $login); $tldap = 0; $start = microtime(true); $result = $ldap->isValidUser(); $tldap = microtime(true) - $start; if ($result) { try { //Tries to retrieve user's email address from LDAP or provides that login is always with domain suffix if (($pos = strpos($login, '@')) === false) { $login = $ldap->getEmail(); } $start = microtime(true); $groups = $ldap->getUserGroups(); $gtime = microtime(true) - $start; $tldap += $gtime; $this->response->setHeader('X-Scalr-LDAP-G-Query-Time', sprintf('%0.4f sec', $gtime)); $this->response->setHeader('X-Scalr-LDAP-Query-Time', sprintf('%0.4f sec', $tldap)); $this->response->setHeader('X-Scalr-LDAP-CLogin', $login); $this->ldapGroups = $groups; } catch (Exception $e) { throw new Exception($e->getMessage() . $ldap->getLog()); } foreach ($groups as $key => $name) { $groups[$key] = $this->db->qstr($name); } $userAvailableAccounts = array(); if ($ldap->getConfig()->debug) { $this->response->varDump($groups); $this->response->setHeader('X-Scalr-LDAP-Debug', json_encode($ldap->getLog())); } // System users are not members of any group so if there is no groups then skip this. if (count($groups) > 0) { foreach ($this->db->GetAll(' SELECT clients.id, clients.name FROM clients JOIN client_environments ON client_environments.client_id = clients.id JOIN account_team_envs ON account_team_envs.env_id = client_environments.id JOIN account_teams ON account_teams.id = account_team_envs.team_id WHERE account_teams.name IN(' . join(',', $groups) . ')') as $value) { $userAvailableAccounts[$value['id']] = $value; } } foreach ($this->db->GetAll("\n SELECT clients.id, clients.name, clients.org, clients.dtadded\n FROM clients\n JOIN account_users ON account_users.account_id = clients.id\n WHERE account_users.email = ? AND account_users.type = ?", array($login, Scalr_Account_User::TYPE_ACCOUNT_OWNER)) as $value) { $value['dtadded'] = Scalr_Util_DateTime::convertTz($value['dtadded'], 'M j, Y'); $userAvailableAccounts[$value['id']] = $value; } $userAvailableAccounts = array_values($userAvailableAccounts); if (count($userAvailableAccounts) == 0) { throw new Scalr_Exception_Core('You don\'t have access to any account. ' . $ldap->getLog()); } if (count($userAvailableAccounts) == 1) { $accountId = $userAvailableAccounts[0]['id']; } else { $ids = array(); foreach ($userAvailableAccounts as $value) { $ids[] = $value['id']; } if (!$accountId && !in_array($accountId, $ids)) { $this->response->data(array('accounts' => $userAvailableAccounts)); throw new Exception(); } } $user = new Scalr_Account_User(); $user = $user->loadByEmail($login, $accountId); if (!$user) { $user = new Scalr_Account_User(); $user->type = Scalr_Account_User::TYPE_TEAM_USER; $user->status = Scalr_Account_User::STATUS_ACTIVE; $user->create($login, $accountId); } if (!$user->fullname) { $user->fullname = $ldap->getFullName(); $user->save(); } if ($ldap->getUsername() != $ldap->getEmail()) { $user->setSetting(Scalr_Account_User::SETTING_LDAP_EMAIL, $ldap->getEmail()); } else { $user->setSetting(Scalr_Account_User::SETTING_LDAP_EMAIL, ''); } } else { throw new Exception("Incorrect login or password (1) " . $ldap->getLog()); } } else { $userAvailableAccounts = $this->db->GetAll(' SELECT account_users.id AS userId, clients.id, clients.name, clients.org, clients.dtadded, au.email AS `owner` FROM account_users LEFT JOIN clients ON clients.id = account_users.account_id LEFT JOIN account_users au ON account_users.account_id = au.account_id WHERE account_users.email = ? AND (au.type = ? OR account_users.type = ? OR account_users.type = ?) GROUP BY userId ', array($login, Scalr_Account_User::TYPE_ACCOUNT_OWNER, Scalr_Account_User::TYPE_SCALR_ADMIN, Scalr_Account_User::TYPE_FIN_ADMIN)); foreach ($userAvailableAccounts as &$ac) { $ac['dtadded'] = Scalr_Util_DateTime::convertTz($ac['dtadded'], 'M j, Y'); } if (count($userAvailableAccounts) == 1) { $user = new Scalr_Account_User(); $user->loadById($userAvailableAccounts[0]['userId']); } else { if (count($userAvailableAccounts) > 1) { if ($accountId) { foreach ($userAvailableAccounts as $acc) { if ($acc['id'] == $accountId) { $user = new Scalr_Account_User(); $user->loadById($acc['userId']); break; } } } else { $this->response->data(array('accounts' => $userAvailableAccounts)); throw new Exception(); } } else { throw new Exception("Incorrect login or password (3)"); } } if ($user) { // kaptcha if ($user->loginattempts > 2 && $this->getContainer()->config->get('scalr.ui.recaptcha.private_key')) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'http://www.google.com/recaptcha/api/verify'); curl_setopt($curl, CURLOPT_POST, true); $post = 'privatekey=' . urlencode($this->getContainer()->config->get('scalr.ui.recaptcha.private_key')) . '&remoteip=' . urlencode($this->request->getRemoteAddr()) . '&challenge=' . urlencode($scalrCaptchaChallenge) . '&response=' . urlencode($scalrCaptcha); curl_setopt($curl, CURLOPT_POSTFIELDS, $post); curl_setopt($curl, CURLOPT_TIMEOUT, 10); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLINFO_HEADER_OUT, true); $response = curl_exec($curl); curl_close($curl); $responseStrings = explode("\n", $response); if ($responseStrings[0] !== 'true') { $this->response->data(array('loginattempts' => $user->loginattempts, 'kaptchaError' => $response)); throw new Exception(); } } if (!$user->checkPassword($password)) { if ($this->getContainer()->config->get('scalr.ui.recaptcha.private_key')) { $this->response->data(array('loginattempts' => $user->loginattempts)); } throw new Exception("Incorrect login or password (1)"); } } else { throw new Exception("Incorrect login or password (2)"); } } // valid user, other checks $whitelist = $user->getVar(Scalr_Account_User::VAR_SECURITY_IP_WHITELIST); if ($whitelist) { $subnets = unserialize($whitelist); if (!Scalr_Util_Network::isIpInSubnets($this->request->getRemoteAddr(), $subnets)) { throw new Exception('The IP address you are attempting to log in from isn\'t authorized'); } } return $user; } else { throw new Exception('Incorrect login or password (0)'); } }
/** * @param string $login * @param string $password * @param int $accountId * @param string $scalrCaptcha * @return Scalr_Account_User * @throws Exception * @throws Scalr_Exception_Core * @throws \Scalr\System\Config\Exception\YamlException */ private function loginUserGet($login, $password, $accountId, $scalrCaptcha) { if ($login != '' && $password != '') { $isAdminLogin = $this->db->GetOne('SELECT * FROM account_users WHERE email = ? AND account_id = 0', array($login)); if ($this->getContainer()->config->get('scalr.auth_mode') == 'ldap' && !$isAdminLogin) { $ldap = $this->getContainer()->ldap($login, $password); $this->response->setHeader('X-Scalr-LDAP-Login', $login); $tldap = 0; $start = microtime(true); $result = $ldap->isValidUser(); $tldap = microtime(true) - $start; if ($result) { try { //Tries to retrieve user's email address from LDAP or provides that login is always with domain suffix if (($pos = strpos($login, '@')) === false) { $login = $ldap->getEmail(); } $start = microtime(true); $groups = $ldap->getUserGroups(); $gtime = microtime(true) - $start; $tldap += $gtime; $this->response->setHeader('X-Scalr-LDAP-G-Query-Time', sprintf('%0.4f sec', $gtime)); $this->response->setHeader('X-Scalr-LDAP-Query-Time', sprintf('%0.4f sec', $tldap)); $this->response->setHeader('X-Scalr-LDAP-CLogin', $login); $this->ldapGroups = $groups; } catch (Exception $e) { throw new Exception($e->getMessage() . $ldap->getLog()); } foreach ($groups as $key => $name) { $groups[$key] = $this->db->qstr($name); } $userAvailableAccounts = array(); if ($ldap->getConfig()->debug) { $this->response->setHeader('X-Scalr-LDAP-Debug', json_encode($ldap->getLog())); } // System users are not members of any group so if there is no groups then skip this. if (count($groups) > 0) { foreach ($this->db->GetAll(' SELECT clients.id, clients.name FROM clients JOIN client_environments ON client_environments.client_id = clients.id JOIN account_team_envs ON account_team_envs.env_id = client_environments.id JOIN account_teams ON account_teams.id = account_team_envs.team_id WHERE account_teams.name IN(' . join(',', $groups) . ')') as $value) { $userAvailableAccounts[$value['id']] = $value; } } foreach ($this->db->GetAll("\n SELECT clients.id, clients.name, clients.org, clients.dtadded\n FROM clients\n JOIN account_users ON account_users.account_id = clients.id\n WHERE account_users.email = ? AND account_users.type = ?", array($login, Scalr_Account_User::TYPE_ACCOUNT_OWNER)) as $value) { $value['dtadded'] = Scalr_Util_DateTime::convertTz($value['dtadded'], 'M j, Y'); $userAvailableAccounts[$value['id']] = $value; } $userAvailableAccounts = array_values($userAvailableAccounts); if (empty($userAvailableAccounts)) { throw new Scalr_Exception_Core('You don\'t have access to any account. ' . $ldap->getLog()); } elseif (count($userAvailableAccounts) == 1) { $accountId = $userAvailableAccounts[0]['id']; } else { $ids = array(); foreach ($userAvailableAccounts as $value) { $ids[] = $value['id']; } if (!$accountId && !in_array($accountId, $ids)) { $this->response->data(array('accounts' => $userAvailableAccounts)); throw new Exception(); } } $user = new Scalr_Account_User(); $user = $user->loadByEmail($login, $accountId); if (!$user) { $user = new Scalr_Account_User(); $user->type = Scalr_Account_User::TYPE_TEAM_USER; $user->status = Scalr_Account_User::STATUS_ACTIVE; $user->create($login, $accountId); } if (!$user->fullname) { $user->fullname = $ldap->getFullName(); $user->save(); } if ($ldap->getUsername() != $ldap->getEmail()) { $user->setSetting(Scalr_Account_User::SETTING_LDAP_EMAIL, $ldap->getEmail()); $user->setSetting(Scalr_Account_User::SETTING_LDAP_USERNAME, $ldap->getUsername()); } else { $user->setSetting(Scalr_Account_User::SETTING_LDAP_EMAIL, ''); } } else { throw new Exception("Incorrect login or password (1) " . $ldap->getLog()); } } else { $userAvailableAccounts = $this->db->GetAll(' SELECT account_users.id AS userId, clients.id, clients.name, clients.org, clients.dtadded, au.email AS `owner` FROM account_users LEFT JOIN clients ON clients.id = account_users.account_id LEFT JOIN account_users au ON account_users.account_id = au.account_id WHERE account_users.email = ? AND (au.type = ? OR account_users.type = ? OR account_users.type = ?) GROUP BY userId ', array($login, Scalr_Account_User::TYPE_ACCOUNT_OWNER, Scalr_Account_User::TYPE_SCALR_ADMIN, Scalr_Account_User::TYPE_FIN_ADMIN)); foreach ($userAvailableAccounts as &$ac) { $ac['dtadded'] = Scalr_Util_DateTime::convertTz($ac['dtadded'], 'M j, Y'); } if (count($userAvailableAccounts) == 1) { $user = new Scalr_Account_User(); $user->loadById($userAvailableAccounts[0]['userId']); } elseif (count($userAvailableAccounts) > 1) { if ($accountId) { foreach ($userAvailableAccounts as $acc) { if ($acc['id'] == $accountId) { $user = new Scalr_Account_User(); $user->loadById($acc['userId']); break; } } } else { $this->response->data(array('accounts' => $userAvailableAccounts)); throw new Exception(); } } else { throw new Exception("Incorrect login or password (3)"); } if ($user) { if ($user->status != User::STATUS_ACTIVE) { throw new Exception('User account has been deactivated. Please contact your account owner.'); } // kaptcha if ($user->loginattempts > 3 && $this->getContainer()->config->get('scalr.ui.recaptcha.private_key')) { if (!$scalrCaptcha || ($r = $this->validateReCaptcha($scalrCaptcha)) !== true) { $this->response->data(array('loginattempts' => $user->loginattempts, 'scalrCaptchaError' => isset($r) ? $r : 'empty-value')); throw new Exception(); } } if (!$user->checkPassword($password)) { $attempts = (int) $this->getContainer()->config->get('scalr.security.user.suspension.failed_login_attempts'); if ($attempts > 0 && $user->loginattempts >= $attempts && $user->getEmail() != 'admin') { $user->status = User::STATUS_INACTIVE; $user->loginattempts = 0; $user->save(); throw new Exception('User account has been deactivated. Please contact your account owner.'); } if ($this->getContainer()->config->get('scalr.ui.recaptcha.private_key')) { $this->response->data(array('loginattempts' => $user->loginattempts)); } throw new Exception("Incorrect login or password (1)"); } } else { throw new Exception("Incorrect login or password (2)"); } } // valid user, other checks $whitelist = $user->getVar(Scalr_Account_User::VAR_SECURITY_IP_WHITELIST); if ($whitelist) { $subnets = unserialize($whitelist); if (!Scalr_Util_Network::isIpInSubnets($this->request->getRemoteAddr(), $subnets)) { throw new Exception('The IP address you are attempting to log in from isn\'t authorized'); } } return $user; } else { throw new Exception('Incorrect login or password (0)'); } }