/** * @param $type * @param $headers * @param $server * @param $params * @param $files * @param $userId * @param $envId int optional Could be null, when we check headers (for UI) * @return Scalr_UI_Request * @throws Scalr_Exception_Core * @throws Exception */ public static function initializeInstance($type, $headers, $server, $params, $files, $userId, $envId = null) { if (self::$_instance) { self::$_instance = null; } $class = get_called_class(); /* @var $instance Scalr_UI_Request */ $instance = new $class($type, $headers, $server, $params, $files); $container = Scalr::getContainer(); if ($userId) { try { $user = Scalr_Account_User::init(); $user->loadById($userId); } catch (Exception $e) { throw new Exception('User account is no longer available.'); } if ($user->status != Scalr_Account_User::STATUS_ACTIVE) { throw new Exception('User account has been deactivated. Please contact your account owner.'); } $scope = $instance->getHeaderVar('Scope'); // ajax file upload, download files if (empty($scope)) { $scope = $instance->getParam('X-Scalr-Scope'); } if (empty($envId)) { $envId = $instance->getParam('X-Scalr-Envid'); } if ($user->isAdmin()) { if ($scope != 'scalr') { $scope = 'scalr'; } } else { if (!in_array($scope, ['account', 'environment'])) { $scope = 'environment'; } } if (!$user->isAdmin()) { if ($envId || $scope == 'environment') { if (!$envId) { $envId = $instance->getHeaderVar('Envid'); } $environment = $user->getDefaultEnvironment($envId); $user->getPermissions()->setEnvironmentId($environment->id); $scope = 'environment'; } } if ($user->getAccountId()) { if ($user->getAccount()->status == Scalr_Account::STATUS_INACIVE) { if ($user->getType() == Scalr_Account_User::TYPE_TEAM_USER) { throw new Exception('Scalr account has been deactivated. Please contact scalr team.'); } } else { if ($user->getAccount()->status == Scalr_Account::STATUS_SUSPENDED) { if ($user->getType() == Scalr_Account_User::TYPE_TEAM_USER) { throw new Exception('Account was suspended. Please contact your account owner to solve this situation.'); } } } } $ipWhitelist = $user->getVar(Scalr_Account_User::VAR_SECURITY_IP_WHITELIST); if ($ipWhitelist) { $ipWhitelist = unserialize($ipWhitelist); if (!Scalr_Util_Network::isIpInSubnets($instance->getRemoteAddr(), $ipWhitelist)) { throw new Exception('The IP address isn\'t authorized.'); } } // check header's variables $headerUserId = !is_null($instance->getHeaderVar('Userid')) ? intval($instance->getHeaderVar('Userid')) : null; if (!empty($headerUserId) && $headerUserId != $user->getId()) { throw new Scalr_Exception_Core('Session expired. Please refresh page.', 1); } $instance->user = $user; $instance->environment = isset($environment) ? $environment : null; $instance->scope = $scope; } $container->request = $instance; $container->environment = isset($instance->environment) ? $instance->environment : null; self::$_instance = $instance; $container->set('auditlogger.request', function () { return self::$_instance; }); return $instance; }
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 $password * @param $cpassword * @param $securityIpWhitelist */ public function xSecuritySaveAction($password, $cpassword, $securityIpWhitelist) { $validator = new Validator(); $validator->validate($password, 'password', Validator::NOEMPTY); $validator->validate($cpassword, 'cpassword', Validator::NOEMPTY); $validator->addErrorIf($password && $cpassword && $password != $cpassword, ['password', 'cpassword'], 'Two passwords are not equal'); $subnets = array(); $securityIpWhitelist = trim($securityIpWhitelist); if ($securityIpWhitelist) { $whitelist = explode(',', $securityIpWhitelist); foreach ($whitelist as $mask) { $sub = Scalr_Util_Network::convertMaskToSubnet($mask); if ($sub) { $subnets[] = $sub; } else { $validator->addError('securityIpWhitelist', sprintf('Not valid mask: %s', $mask)); } } } if (count($subnets) && !Scalr_Util_Network::isIpInSubnets($this->request->getRemoteAddr(), $subnets)) { $validator->addError('securityIpWhitelist', 'New IP access whitelist doesn\'t correspond your current IP address'); } if ($validator->isValid($this->response)) { $updateSession = false; if ($password != '******') { $this->user->updatePassword($password); $updateSession = true; } $this->user->setVar(Scalr_Account_User::VAR_SECURITY_IP_WHITELIST, count($subnets) ? serialize($subnets) : ''); $this->user->save(); if ($updateSession) { Scalr_Session::create($this->user->getId()); } $this->response->success('Security settings successfully updated'); } }
/** * @param RawData $password * @param RawData $cpassword * @param $securityIpWhitelist * @param RawData $currentPassword optional */ public function xSecuritySaveAction(RawData $password, RawData $cpassword, $securityIpWhitelist, RawData $currentPassword = null) { $validator = new Validator(); if ($password != '******') { $validator->addErrorIf(!$this->user->checkPassword($currentPassword), ['currentPassword'], 'Invalid password'); } $validator->validate($password, 'password', Validator::NOEMPTY); $validator->validate($cpassword, 'cpassword', Validator::NOEMPTY); $validator->addErrorIf($password && $cpassword && $password != $cpassword, ['password', 'cpassword'], 'Two passwords are not equal'); $subnets = array(); $securityIpWhitelist = trim($securityIpWhitelist); if ($securityIpWhitelist) { $whitelist = explode(',', $securityIpWhitelist); foreach ($whitelist as $mask) { $sub = Scalr_Util_Network::convertMaskToSubnet($mask); if ($sub) { $subnets[] = $sub; } else { $validator->addError('securityIpWhitelist', sprintf('Not valid mask: %s', $mask)); } } } if (count($subnets) && !Scalr_Util_Network::isIpInSubnets($this->request->getRemoteAddr(), $subnets)) { $validator->addError('securityIpWhitelist', 'New IP access whitelist doesn\'t correspond your current IP address'); } if ($validator->isValid($this->response)) { $updateSession = false; if ($password != '******') { $this->user->updatePassword($password); $updateSession = true; // Send notification E-mail $this->getContainer()->mailer->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/password_change_notification.eml', array('{{fullname}}' => $this->user->fullname ? $this->user->fullname : $this->user->getEmail()), $this->user->getEmail(), $this->user->fullname); } $this->user->setVar(Scalr_Account_User::VAR_SECURITY_IP_WHITELIST, count($subnets) ? serialize($subnets) : ''); $this->user->save(); if ($updateSession) { Scalr_Session::create($this->user->getId()); $this->response->data(['specialToken' => Scalr_Session::getInstance()->getToken()]); } $this->response->success('Security settings successfully updated'); } }
/** * @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)'); } }
public function xSecuritySaveAction() { $this->request->defineParams(array('password' => array('type' => 'string', 'validator' => array(Scalr_Validator::NOEMPTY => true)), 'cpassword' => array('type' => 'string', 'validator' => array(Scalr_Validator::NOEMPTY => true)))); $this->request->validate(); if ($this->getParam('password') != $this->getParam('cpassword')) { $this->request->addValidationErrors('cpassword', 'Two passwords are not equal'); } $subnets = array(); $whitelist = trim($this->getParam('security_ip_whitelist')); if ($whitelist) { $whitelist = explode(',', $whitelist); foreach ($whitelist as $mask) { $sub = Scalr_Util_Network::convertMaskToSubnet($mask); if ($sub) { $subnets[] = $sub; } else { $this->request->addValidationErrors('security_ip_whitelist', sprintf('Not valid mask: %s', $mask)); } } } if (count($subnets) && !Scalr_Util_Network::isIpInSubnets($this->request->getRemoteAddr(), $subnets)) { $this->request->addValidationErrors('security_ip_whitelist', 'New IP access whitelist doesn\'t correspond your current IP address'); } if ($this->request->isValid()) { $updateSession = false; if ($this->getParam('password') != '******') { $this->user->updatePassword($this->getParam('password')); $updateSession = true; } $this->user->setVar(Scalr_Account_User::VAR_SECURITY_IP_WHITELIST, count($subnets) ? serialize($subnets) : ''); $this->user->save(); if ($updateSession) { Scalr_Session::create($this->user->getId()); } $this->response->success('Secuity settings successfully updated'); } else { $this->response->failure(); $this->response->data($this->request->getValidationErrors()); } }