<commit_before><?php
/**
 * OpenEyes
 *
 * (C) Moorfields Eye Hospital NHS Foundation Trust, 2008-2011
 * (C) OpenEyes Foundation, 2011-2013
 * This file is part of OpenEyes.
 * OpenEyes is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 * OpenEyes is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along with OpenEyes in a file titled COPYING. If not, see <http://www.gnu.org/licenses/>.
 *
 * @package OpenEyes
 * @link http://www.openeyes.org.uk
 * @author OpenEyes <<EMAIL>>
 * @copyright Copyright (c) 2008-2011, Moorfields Eye Hospital NHS Foundation Trust
 * @copyright Copyright (c) 2011-2013, OpenEyes Foundation
 * @license http://www.gnu.org/licenses/gpl-3.0.html The GNU General Public License V3.0
 */

/**
 * UserIdentity represents the data needed to identity a user.
 * It contains the authentication method that checks if the provided
 * data can identity the user.
 */

class UserIdentity extends CUserIdentity
{
	private $_id;

	/*
	 * New error code for users with active set to 0
	 */
	const ERROR_USER_INACTIVE = 3;

	/**
	 * Authenticates a user.
	 *
	 * Uses either BASIC or LDAP authentication. BASIC authenticates against
	 * the openeyes DB. LDAP uses whichever LDAP is specified in the params.php
	 * config file.
	 *
	 * @return boolean whether authentication succeeds.
	 * @throws
	 */
	public function authenticate($force=false)
	{
		if (!in_array(Yii::app()->params['ldap_method'],array('native','zend','native-search'))) {
			throw new Exception('Unsupported LDAP authentication method: '.Yii::app()->params['ldap_method'].', please use native or zend.');
		}

		Yii::app()->event->dispatch('user_before_login', array('username' => $this->username));

		/**
		 * Usernames are case sensitive
		 */
		$user = User::model()->find('username = ?', array($this->username));
		if ($user === null) {
			Audit::add('login','login-failed',null,"User not found in local database: $this->username");
			$this->errorCode = self::ERROR_USERNAME_INVALID;
			return false;
		} elseif (!$force && $user->active != 1) {
			$user->audit('login','login-failed',null,"User not active and so cannot login: $this->username");
			$this->errorCode = self::ERROR_USER_INACTIVE;
			return false;
		} elseif (!$force && !Yii::app()->getAuthManager()->checkAccess('OprnLogin', $user->id)) {
			$user->audit('login', 'login-failed', "User has not been assigned OprnLogin and so cannot login: $this->username", true);
			$this->errorCode = self::ERROR_USER_INACTIVE;
			return false;
		}

		if (in_array($user->username,Yii::app()->params['local_users'])) {
			Yii::app()->params['auth_source'] = 'BASIC';
		}

		$this->password = <PASSWORD>($<PASSWORD>);

		/**
		 * Here we diverge depending on the authentication source.
		 */
        if (Yii::app()->params['auth_source'] == 'LDAP') {
			/**
			 * Required for LDAP authentication
			 */
			if (Yii::app()->params['ldap_method'] == 'zend') {
                Yii::import('application.vendors.*');
				require_once('Zend/Ldap.php');

				/**
				 * Check with LDAP for authentication
				 */
				$options = array(
					'host'				=> Yii::app()->params['ldap_server'],
					'port'				=> Yii::app()->params['ldap_port'],
					'username'			=> Yii::app()->params['ldap_admin_dn'],
					'password'			=> Yii::app()->params['ldap_password'],
					'baseDn'			=> Yii::app()->params['ldap_admin_dn'],
					'useStartTls'		=> false,
				);

				$ldap = $this->getLdap($options);

				/**
				 * Try and bind to the login details provided. This indicates if
				 * the user is in LDAP.
				 */

				try {
					$ldap->bind(
						"cn=" . $this->username . "," . Yii::app()->params['ldap_dn'],
						$this->password
					);
				} catch (Exception $e) {
					/**
					 * User not authenticated via LDAP
					 */
					$audit = new Audit;
					$audit->action = "login-failed";
					$audit->target_type = "login";
					$audit->user_id = $user->id;
					$audit->data = "Login failed for user {$this->username}: LDAP authentication failed: ".$e->getMessage().": ".$this->username;
					$audit->save();
					OELog::log("Login failed for user {$this->username}: LDAP authentication failed: ".$e->getMessage(),$this->username);

					$this->errorCode = self::ERROR_USERNAME_INVALID;
					return false;
				}

				/**
				 * User is in LDAP, get their details.
				 */
				$info = $ldap->getEntry(
					"cn=" . $this->username . "," . Yii::app()->params['ldap_dn'],
					array('givenname', 'sn', 'mail')
				);

			} elseif (Yii::app()->params['ldap_method'] == 'native-search') {
				// verify we can reach the server, as ldap_connect doesn't timeout correctly
				if ($fp = @fsockopen(Yii::app()->params['ldap_server'], Yii::app()->params['ldap_port'], $errno, $errstr, 5)) {
					if (!$link = ldap_connect(Yii::app()->params['ldap_server'], Yii::app()->params['ldap_port'])) {
						throw new Exception("Unable to connect to LDAP server: " . Yii::app()->params['ldap_server'] . ":" . Yii::app()->params['ldap_port']);
					}
				} else {
					throw new Exception("Unable to reach LDAP server: " . Yii::app()->params['ldap_server'] . ":" . Yii::app()->params['ldap_port'] . " : " . $errstr);
				}

				ldap_set_option($link, LDAP_OPT_REFERRALS, 0);
				ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, 3);
				ldap_set_option($link, LDAP_OPT_NETWORK_TIMEOUT, Yii::app()->params['ldap_native_timeout']);

				// Bind as the LDAP admin user. Set parameters ldap_admin_dn and ldap_password in local config for this.
<commit_msg>OE-6070 removed socket check for native-search method, to account for when ldap_server specified with a protocol.<commit_after><?php
/**
 * OpenEyes
 *
 * (C) Moorfields Eye Hospital NHS Foundation Trust, 2008-2011
 * (C) OpenEyes Foundation, 2011-2013
 * This file is part of OpenEyes.
 * OpenEyes is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 * OpenEyes is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along with OpenEyes in a file titled COPYING. If not, see <http://www.gnu.org/licenses/>.
 *
 * @package OpenEyes
 * @link http://www.openeyes.org.uk
 * @author OpenEyes <<EMAIL>>
 * @copyright Copyright (c) 2008-2011, Moorfields Eye Hospital NHS Foundation Trust
 * @copyright Copyright (c) 2011-2013, OpenEyes Foundation
 * @license http://www.gnu.org/licenses/gpl-3.0.html The GNU General Public License V3.0
 */

/**
 * UserIdentity represents the data needed to identity a user.
 * It contains the authentication method that checks if the provided
 * data can identity the user.
 */

class UserIdentity extends CUserIdentity
{
	private $_id;

	/*
	 * New error code for users with active set to 0
	 */
	const ERROR_USER_INACTIVE = 3;

	/**
	 * Authenticates a user.
	 *
	 * Uses either BASIC or LDAP authentication. BASIC authenticates against
	 * the openeyes DB. LDAP uses whichever LDAP is specified in the params.php
	 * config file.
	 *
	 * @return boolean whether authentication succeeds.
	 * @throws
	 */
	public function authenticate($force=false)
	{
		if (!in_array(Yii::app()->params['ldap_method'],array('native','zend','native-search'))) {
			throw new Exception('Unsupported LDAP authentication method: '.Yii::app()->params['ldap_method'].', please use native or zend.');
		}

		Yii::app()->event->dispatch('user_before_login', array('username' => $this->username));

		/**
		 * Usernames are case sensitive
		 */
		$user = User::model()->find('username = ?', array($this->username));
		if ($user === null) {
			Audit::add('login','login-failed',null,"User not found in local database: $this->username");
			$this->errorCode = self::ERROR_USERNAME_INVALID;
			return false;
		} elseif (!$force && $user->active != 1) {
			$user->audit('login','login-failed',null,"User not active and so cannot login: $this->username");
			$this->errorCode = self::ERROR_USER_INACTIVE;
			return false;
		} elseif (!$force && !Yii::app()->getAuthManager()->checkAccess('OprnLogin', $user->id)) {
			$user->audit('login', 'login-failed', "User has not been assigned OprnLogin and so cannot login: $this->username", true);
			$this->errorCode = self::ERROR_USER_INACTIVE;
			return false;
		}

		if (in_array($user->username,Yii::app()->params['local_users'])) {
			Yii::app()->params['auth_source'] = 'BASIC';
		}

		$this->password = <PASSWORD>_decode($this->password);

		/**
		 * Here we diverge depending on the authentication source.
		 */
        if (Yii::app()->params['auth_source'] == 'LDAP') {
			/**
			 * Required for LDAP authentication
			 */
			if (Yii::app()->params['ldap_method'] == 'zend') {
                Yii::import('application.vendors.*');
				require_once('Zend/Ldap.php');

				/**
				 * Check with LDAP for authentication
				 */
				$options = array(
					'host'				=> Yii::app()->params['ldap_server'],
					'port'				=> Yii::app()->params['ldap_port'],
					'username'			=> Yii::app()->params['ldap_admin_dn'],
					'password'			=> Yii::app()->params['ldap_password'],
					'baseDn'			=> Yii::app()->params['ldap_admin_dn'],
					'useStartTls'		=> false,
				);

				$ldap = $this->getLdap($options);

				/**
				 * Try and bind to the login details provided. This indicates if
				 * the user is in LDAP.
				 */

				try {
					$ldap->bind(
						"cn=" . $this->username . "," . Yii::app()->params['ldap_dn'],
						$this->password
					);
				} catch (Exception $e) {
					/**
					 * User not authenticated via LDAP
					 */
					$audit = new Audit;
					$audit->action = "login-failed";
					$audit->target_type = "login";
					$audit->user_id = $user->id;
					$audit->data = "Login failed for user {$this->username}: LDAP authentication failed: ".$e->getMessage().": ".$this->username;
					$audit->save();
					OELog::log("Login failed for user {$this->username}: LDAP authentication failed: ".$e->getMessage(),$this->username);

					$this->errorCode = self::ERROR_USERNAME_INVALID;
					return false;
				}

				/**
				 * User is in LDAP, get their details.
				 */
				$info = $ldap->getEntry(
					"cn=" . $this->username . "," . Yii::app()->params['ldap_dn'],
					array('givenname', 'sn', 'mail')
				);

			} elseif (Yii::app()->params['ldap_method'] == 'native-search') {
				if (!$link = ldap_connect(Yii::app()->params['ldap_server'], Yii::app()->params['ldap_port'])) {
					throw new Exception("Unable to connect to LDAP server: " . Yii::app()->params['ldap_server'] . " " . Yii::app()->params['ldap_port']);
				}

				ldap_set_option($link, LDAP_OPT_REFERRALS, 0);
				ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, 3);
				ldap_set_option($link, LDAP_OPT_NETWORK_TIMEOUT, Yii::app()->params['ldap_native_timeout']);

				// Bind as the LDAP admin user. Set parameters ldap_admin_dn and ldap_password in local config for this.

{'fraction_non_alphanumeric': 0.16174806302777053, 'fraction_numerical': 0.0077478889179071996, 'mean_word_length': 3.6566680178354276, 'pattern_counts': {'":': 4, '<': 14, '<?xml version=': 0, '>': 145, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1441754', 'n_tokens_mistral': 4174, 'n_tokens_neox': 3541, 'n_words': 996}