diff options
| author | brettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2009-10-08 21:48:14 +0000 | 
|---|---|---|
| committer | brettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2009-10-08 21:48:14 +0000 | 
| commit | b291acfd03be87038a1804d454a2f0f84412e17f (patch) | |
| tree | a82bae2c6ea7917875f9fec6561fb62d1d852613 /engine | |
| parent | 993ccb6d2433c6316e45dda23387f161c1f70e03 (diff) | |
| download | elgg-b291acfd03be87038a1804d454a2f0f84412e17f.tar.gz elgg-b291acfd03be87038a1804d454a2f0f84412e17f.tar.bz2  | |
Brought access.php and sesssion.php up to code standards.
git-svn-id: http://code.elgg.org/elgg/trunk@3517 36083f99-b078-4883-b0ff-0f9b5a30f544
Diffstat (limited to 'engine')
| -rw-r--r-- | engine/lib/access.php | 1435 | ||||
| -rw-r--r-- | engine/lib/sessions.php | 1301 | 
2 files changed, 1401 insertions, 1335 deletions
diff --git a/engine/lib/access.php b/engine/lib/access.php index 80348a692..b39cb1455 100644 --- a/engine/lib/access.php +++ b/engine/lib/access.php @@ -1,739 +1,758 @@  <?php +/** + * Elgg access permissions + * For users, objects, collections and all metadata + * + * @package Elgg + * @subpackage Core -	/** -	 * Elgg access permissions -	 * For users, objects, collections and all metadata -	 *  -	 * @package Elgg -	 * @subpackage Core - -	 * @author Curverider Ltd - -	 * @link http://elgg.org/ -	 */ - -	/** -	 * Get the list of access restrictions the given user is allowed to see on this site -	 * -	 * @uses get_access_array -	 * @param int $user_id User ID; defaults to currently logged in user -	 * @param int $site_id Site ID; defaults to current site  -	 * @param boolean $flush If set to true, will refresh the access list from the database -	 * @return string A list of access collections suitable for injection in an SQL call -	 */ -		function get_access_list($user_id = 0, $site_id = 0, $flush = false) { -			 -			global $CONFIG, $init_finished, $SESSION; -			static $access_list; -			 -			if (!isset($access_list) || !$init_finished) -				$access_list = array(); -				 -			if ($user_id == 0) $user_id = $SESSION['id']; -			if (($site_id == 0) && (isset($CONFIG->site_id))) $site_id = $CONFIG->site_id; -			$user_id = (int) $user_id; -			$site_id = (int) $site_id; -			 -			if (isset($access_list[$user_id])) return $access_list[$user_id]; -			 -			$access_list[$user_id] = "(" . implode(",",get_access_array($user_id, $site_id, $flush)) . ")"; -			 -			return $access_list[$user_id]; -			 -		} -		 -	/** -	 * Gets an array of access restrictions the given user is allowed to see on this site -	 * -	 * @param int $user_id User ID; defaults to currently logged in user -	 * @param int $site_id Site ID; defaults to current site  -	 * @param boolean $flush If set to true, will refresh the access list from the database -	 * @return array An array of access collections suitable for injection in an SQL call -	 */ -		function get_access_array($user_id = 0, $site_id = 0, $flush = false) { -			 -			global $CONFIG, $init_finished; -			static $access_array, $acm, $ac; // Caches. $ac* flag whether we have executed a query previously, and stop it being run again if no data is returned. -			 -			if (!isset($access_array) || (!isset($init_finished)) || (!$init_finished)) -				$access_array = array();  -				 -			if ($user_id == 0) $user_id = get_loggedin_userid(); -			 -			if (($site_id == 0) && (isset($CONFIG->site_guid))) $site_id = $CONFIG->site_guid; -			$user_id = (int) $user_id; -			$site_id = (int) $site_id; -			 -			if (empty($access_array[$user_id]) || $flush == true) { -				 -				$query = "SELECT am.access_collection_id FROM {$CONFIG->dbprefix}access_collection_membership am "; -				$query .= " LEFT JOIN {$CONFIG->dbprefix}access_collections ag ON ag.id = am.access_collection_id "; -				$query .= " WHERE am.user_guid = {$user_id} AND (ag.site_guid = {$site_id} OR ag.site_guid = 0)"; -				 -				$tmp_access_array = array(ACCESS_PUBLIC);  -				if (isloggedin()) { -					$tmp_access_array[] = ACCESS_LOGGED_IN; -					 -					// The following can only return sensible data if the user is logged in. -					 -					if ($collections = get_data($query)) { -						foreach($collections as $collection) -							if (!empty($collection->access_collection_id)) $tmp_access_array[] = $collection->access_collection_id; -							 -					} -						 -					$query = "SELECT ag.id FROM {$CONFIG->dbprefix}access_collections ag  "; -					$query .= " WHERE ag.owner_guid = {$user_id} AND (ag.site_guid = {$site_id} OR ag.site_guid = 0)"; -					 -					if ($collections = get_data($query)) { -						foreach($collections as $collection) -							if (!empty($collection->id)) $tmp_access_array[] = $collection->id; -					} -					  -					 -					global $is_admin; -					 -					if (isset($is_admin) && $is_admin == true) { -						$tmp_access_array[] = ACCESS_PRIVATE; -					} + * @author Curverider Ltd + + * @link http://elgg.org/ + */ + +/** + * Return a string of access_ids for $user_id appropriate for inserting into an SQL IN clause. + * + * @uses get_access_array + * @param int $user_id User ID; defaults to currently logged in user + * @param int $site_id Site ID; defaults to current site + * @param boolean $flush If set to true, will refresh the access list from the database + * @return string A list of access collections suitable for injection in an SQL call + */ +function get_access_list($user_id = 0, $site_id = 0, $flush = false) { +	global $CONFIG, $init_finished, $SESSION; +	static $access_list; + +	if (!isset($access_list) || !$init_finished) { +		$access_list = array(); +	} + +	if ($user_id == 0) { +		$user_id = $SESSION['id']; +	} + +	if (($site_id == 0) && (isset($CONFIG->site_id))) { +		$site_id = $CONFIG->site_id; +	} +	$user_id = (int) $user_id; +	$site_id = (int) $site_id; + +	if (isset($access_list[$user_id])) { +		return $access_list[$user_id]; +	} + +	$access_list[$user_id] = "(" . implode(",", get_access_array($user_id, $site_id, $flush)) . ")"; + +	return $access_list[$user_id]; +} + +/** + * Gets an array of access restrictions the given user is allowed to see on this site + * + * @param int $user_id User ID; defaults to currently logged in user + * @param int $site_id Site ID; defaults to current site + * @param boolean $flush If set to true, will refresh the access list from the database + * @return array An array of access collections suitable for injection in an SQL call + */ +function get_access_array($user_id = 0, $site_id = 0, $flush = false) { +	global $CONFIG, $init_finished; + +	// @todo everything from the db is cached. +	// this cache might be redundant. +	static $access_array; + +	if (!isset($access_array) || (!isset($init_finished)) || (!$init_finished)) { +		$access_array = array(); +	} + +	if ($user_id == 0) { +		$user_id = get_loggedin_userid(); +	} + +	if (($site_id == 0) && (isset($CONFIG->site_guid))) { +		$site_id = $CONFIG->site_guid; +	} + +	$user_id = (int) $user_id; +	$site_id = (int) $site_id; + +	if (empty($access_array[$user_id]) || $flush == true) { +		$tmp_access_array = array(ACCESS_PUBLIC); +		if (isloggedin()) { +			$tmp_access_array[] = ACCESS_LOGGED_IN; + +			// The following can only return sensible data if the user is logged in. + +			// Get ACL memberships +			$query = "SELECT am.access_collection_id FROM {$CONFIG->dbprefix}access_collection_membership am "; +			$query .= " LEFT JOIN {$CONFIG->dbprefix}access_collections ag ON ag.id = am.access_collection_id "; +			$query .= " WHERE am.user_guid = {$user_id} AND (ag.site_guid = {$site_id} OR ag.site_guid = 0)"; -					$access_array[$user_id] = $tmp_access_array; +			if ($collections = get_data($query)) { +				foreach($collections as $collection) { +					if (!empty($collection->access_collection_id)) { +						$tmp_access_array[] = $collection->access_collection_id; +					}  				} -				else -					$tmp_return = $tmp_access_array; // No user id logged in so we can only access public info -				 -				 -			} else { -				$tmp_access_array = $access_array[$user_id]; -			} -			 -			$tmp_return = $access_array[$user_id]; -			 -			return trigger_plugin_hook('access:collections:read','user',array('user_id' => $user_id, 'site_id' => $site_id),$tmp_access_array); -		} -		 -	/** -	 * Gets the default access permission for new content -	 * -	 * @return int default access id (see ACCESS defines in elgglib.php)   -	 */ -		function get_default_access($user=null) -		{ -			global $CONFIG; -			 -			if (!$CONFIG->allow_user_default_access) { -				return $CONFIG->default_access;  			} -			 -			if (!$user) { -				if (isloggedin()) { -					$user = $_SESSION['user']; -				} else { -					return $CONFIG->default_access; + +			// Get ACLs owned. +			$query = "SELECT ag.id FROM {$CONFIG->dbprefix}access_collections ag  "; +			$query .= " WHERE ag.owner_guid = {$user_id} AND (ag.site_guid = {$site_id} OR ag.site_guid = 0)"; + +			if ($collections = get_data($query)) { +				foreach($collections as $collection) { +					if (!empty($collection->id)) { +						$tmp_access_array[] = $collection->id; +					}  				}  			} -			 -			if (false !== ($default_access = $user->getPrivateSetting('elgg_default_access'))) { -				return $default_access; -			} else {			 -				return $CONFIG->default_access; + +			$is_admin = is_admin_user($user_id); + +			if ($is_admin == true) { +				$tmp_access_array[] = ACCESS_PRIVATE;  			} + +			$access_array[$user_id] = $tmp_access_array; +		} else { +			// No user id logged in so we can only access public info +			$tmp_return = $tmp_access_array;  		} -		 -		/** -		 * Override the default behaviour and allow results to show hidden entities as well. -		 * THIS IS A HACK. -		 *  -		 * TODO: Replace this with query object! -		 */ -		$ENTITY_SHOW_HIDDEN_OVERRIDE = false; -		 -		/** -		 * This will be replaced. Do not use in plugins! -		 * -		 * @param bool $show -		 */ -		function access_show_hidden_entities($show_hidden) -		{ -			global $ENTITY_SHOW_HIDDEN_OVERRIDE;   -			$ENTITY_SHOW_HIDDEN_OVERRIDE = $show_hidden;   -		} -		 -		/** -		 * This will be replaced. Do not use in plugins! -		 */ -		function access_get_show_hidden_status() -		{ -			global $ENTITY_SHOW_HIDDEN_OVERRIDE;   -			return $ENTITY_SHOW_HIDDEN_OVERRIDE; -		} -		 -		/** -		 * Add annotation restriction -		 *  -		 * Returns an SQL fragment that is true (or optionally false) if the given user has  -		 * added an annotation with the given name to the given entity. -		 *  -		 * TODO: This is fairly generic so perhaps it could be moved to annotations.php -		 *  -		 * @param string $annotation_name name of the annotation -	 	 * @param string $entity_guid SQL string that evaluates to the GUID of the entity the annotation should be attached to -	 	 * @param string $owner_guid SQL string that evaluates to the GUID of the owner of the annotation	 	 *  -	 	 * @param boolean $exists If set to true, will return true if the annotation exists, otherwise returns false -	 	 * @return string An SQL fragment suitable for inserting into a WHERE clause -		 */ -		 -		function get_annotation_sql($annotation_name,$entity_guid,$owner_guid,$exists) { -			global $CONFIG; -			 -			if ($exists) { -				$not = ''; -			} else { -				$not = 'NOT'; -			} -			 -			$sql = <<<END -$not EXISTS (SELECT * FROM {$CONFIG->dbprefix}annotations a  + +	} else { + +		$tmp_access_array = $access_array[$user_id]; +	} + +	$tmp_return = $access_array[$user_id]; + +	return trigger_plugin_hook('access:collections:read','user',array('user_id' => $user_id, 'site_id' => $site_id),$tmp_access_array); +} + +/** + * Gets the default access permission for new content + * + * @return int default access id (see ACCESS defines in elgglib.php) + */ +function get_default_access(ElggUser $user = null) { +	global $CONFIG; + +	if (!$CONFIG->allow_user_default_access) { +		return $CONFIG->default_access; +	} + +	if (!($user) || (!$user = get_loggedin_user())) { +		return $CONFIG->default_access; +	} + +	if (false !== ($default_access = $user->getPrivateSetting('elgg_default_access'))) { +		return $default_access; +	} else { +		return $CONFIG->default_access; +	} +} + +/** + * Override the default behaviour and allow results to show hidden entities as well. + * THIS IS A HACK. + * + * TODO: Replace this with query object! + */ +$ENTITY_SHOW_HIDDEN_OVERRIDE = false; + +/** + * This will be replaced. Do not use in plugins! + * + * @param bool $show + */ +function access_show_hidden_entities($show_hidden) { +	global $ENTITY_SHOW_HIDDEN_OVERRIDE; +	$ENTITY_SHOW_HIDDEN_OVERRIDE = $show_hidden; +} + +/** + * This will be replaced. Do not use in plugins! + */ +function access_get_show_hidden_status() { +	global $ENTITY_SHOW_HIDDEN_OVERRIDE; +	return $ENTITY_SHOW_HIDDEN_OVERRIDE; +} + +/** + * Add annotation restriction + * + * Returns an SQL fragment that is true (or optionally false) if the given user has + * added an annotation with the given name to the given entity. + * + * TODO: This is fairly generic so perhaps it could be moved to annotations.php + * + * @param string $annotation_name name of the annotation +	* @param string $entity_guid SQL string that evaluates to the GUID of the entity the annotation should be attached to +	* @param string $owner_guid SQL string that evaluates to the GUID of the owner of the annotation	 	 * +	* @param boolean $exists If set to true, will return true if the annotation exists, otherwise returns false +	* @return string An SQL fragment suitable for inserting into a WHERE clause + */ +function get_annotation_sql($annotation_name, $entity_guid, $owner_guid, $exists) { +	global $CONFIG; + +	if ($exists) { +		$not = ''; +	} else { +		$not = 'NOT'; +	} + +	$sql = <<<END +$not EXISTS (SELECT * FROM {$CONFIG->dbprefix}annotations a  INNER JOIN {$CONFIG->dbprefix}metastrings ms ON (a.name_id = ms.id)  WHERE ms.string = '$annotation_name'  AND a.entity_guid = $entity_guid  AND a.owner_guid = $owner_guid)  END; -			return $sql; -		} -		 -		/** -		 * Add access restriction sql code to a given query. -		 *  -		 * Note that if this code is executed in privileged mode it will return blank. -		 *  -		 * TODO: DELETE once Query classes are fully integrated -		 *  -		 * @param string $table_prefix Optional xxx. prefix for the access code. -		 */ -		function get_access_sql_suffix($table_prefix = "",$owner=null) -		{ -			global $ENTITY_SHOW_HIDDEN_OVERRIDE, $CONFIG;   -			 -			$sql = ""; -			$friends_bit = ""; -			$enemies_bit = ""; -			 -			if ($table_prefix) -					$table_prefix = sanitise_string($table_prefix) . "."; -			 -			if (!isset($owner)) { -				$owner = get_loggedin_userid(); -			} -			 -			// do NOT use $is_admin global here, since that only checks against -			// the current logged in user. -			// Can't use metadata here because because of recursion. -			// (get_entity, get_*() calls this function.) -			if (!$owner) {  -				$owner = -1; -				$admin = false; -			} else { -				$admin = is_admin_user($owner); -			} -			 -			$access = get_access_list($owner); -			 -			if ($admin) { -				$sql = " (1 = 1) "; -			} else if ($owner != -1) {				 -				$friends_bit = $table_prefix.'access_id = '.ACCESS_FRIENDS.' AND '; -				$friends_bit .= "{$table_prefix}owner_guid IN (SELECT guid_one FROM {$CONFIG->dbprefix}entity_relationships WHERE relationship='friend' AND guid_two=$owner)"; -				$friends_bit = '('.$friends_bit.') OR '; -				 -				if ((isset($CONFIG->user_block_and_filter_enabled)) && ($CONFIG->user_block_and_filter_enabled)) { -					// check to see if the user is in the entity owner's block list -					// or if the entity owner is in the user's filter list -					// if so, disallow access -					 -					$enemies_bit = get_annotation_sql('elgg_block_list',"{$table_prefix}owner_guid",$owner,false); -					$enemies_bit = '('.$enemies_bit. ' AND '.get_annotation_sql('elgg_filter_list',$owner,"{$table_prefix}owner_guid",false).')'; -				} -			} +	return $sql; +} -			if (empty($sql)) -				$sql = " $friends_bit ({$table_prefix}access_id in {$access} or ({$table_prefix}owner_guid = {$owner}) or ({$table_prefix}access_id = " . ACCESS_PRIVATE . " and {$table_prefix}owner_guid = $owner))"; -			 -			if ($enemies_bit) { -				$sql = "$enemies_bit AND ($sql)"; -			} -				 -			if (!$ENTITY_SHOW_HIDDEN_OVERRIDE) -				$sql .= " and {$table_prefix}enabled='yes'"; -			return '('.$sql.')'; +/** + * Add access restriction sql code to a given query. + * Note that if this code is executed in privileged mode it will return blank. + * @TODO: DELETE once Query classes are fully integrated + * + * @param string $table_prefix Optional table. prefix for the access code. + * @param int $owner + */ +function get_access_sql_suffix($table_prefix = "", $owner = null) { +	global $ENTITY_SHOW_HIDDEN_OVERRIDE, $CONFIG; + +	$sql = ""; +	$friends_bit = ""; +	$enemies_bit = ""; + +	if ($table_prefix) +			$table_prefix = sanitise_string($table_prefix) . "."; + +	if (!isset($owner)) { +		$owner = get_loggedin_userid(); +	} + +	if (!$owner) { +		$owner = -1; +	} + +	$is_admin = is_admin_user($owner); +	$access = get_access_list($owner); + +	if ($is_admin) { +		$sql = " (1 = 1) "; +	} else if ($owner != -1) { +		$friends_bit = "{$table_prefix}access_id = " . ACCESS_FRIENDS . " +			AND {$table_prefix}owner_guid IN ( +				SELECT guid_one FROM {$CONFIG->dbprefix}entity_relationships +				WHERE relationship='friend' AND guid_two=$owner +			)"; + +		$friends_bit = '('.$friends_bit.') OR '; + +		if ((isset($CONFIG->user_block_and_filter_enabled)) && ($CONFIG->user_block_and_filter_enabled)) { +			// check to see if the user is in the entity owner's block list +			// or if the entity owner is in the user's filter list +			// if so, disallow access +			$enemies_bit = get_annotation_sql('elgg_block_list', "{$table_prefix}owner_guid", $owner, false); +			$enemies_bit = '(' +				. $enemies_bit +				. '	AND ' . get_annotation_sql('elgg_filter_list', $owner, "{$table_prefix}owner_guid", false) +			. ')';  		} -		 -		/** -		 * Determines whether the given user has access to the given entity -		 *  -		 * @param ElggEntity $entity The entity to check access for. -		 * @param ElggUser $user Optionally the user to check access for. -		 *  -		 * @return boolean True if the user can access the entity -		 */ -		 -		function has_access_to_entity($entity,$user = null) { -			global $CONFIG; -			 -			if (!isset($user)) { -				$access_bit = get_access_sql_suffix("e"); -			} else { -				$access_bit = get_access_sql_suffix("e",$user->getGUID()); +	} + +	if (empty($sql)) { +		$sql = " $friends_bit ({$table_prefix}access_id IN {$access} +			OR ({$table_prefix}owner_guid = {$owner}) +			OR ( +				{$table_prefix}access_id = " . ACCESS_PRIVATE . " +				AND {$table_prefix}owner_guid = $owner +			) +		)"; +	} + +	if ($enemies_bit) { +		$sql = "$enemies_bit AND ($sql)"; +	} + +	if (!$ENTITY_SHOW_HIDDEN_OVERRIDE) +		$sql .= " and {$table_prefix}enabled='yes'"; +	return '('.$sql.')'; +} + +/** + * Determines whether the given user has access to the given entity + * + * @param ElggEntity $entity The entity to check access for. + * @param ElggUser $user Optionally the user to check access for. + * + * @return boolean True if the user can access the entity + */ +function has_access_to_entity($entity, $user = null) { +	global $CONFIG; + +	if (!isset($user)) { +		$access_bit = get_access_sql_suffix("e"); +	} else { +		$access_bit = get_access_sql_suffix("e", $user->getGUID()); +	} + +	$query = "SELECT guid from {$CONFIG->dbprefix}entities e WHERE e.guid = " . $entity->getGUID(); +	$query .= " AND " . $access_bit; // Add access controls +	if (get_data($query)) { +		return true; +	} else { +		return false; +	} +} + +/** + * Returns an array of access permissions that the specified user is allowed to save objects with. + * Permissions are of the form ('id' => 'Description') + * + * @param int $user_id The user's GUID. + * @param int $site_id The current site. + * @param true|false $flush If this is set to true, this will shun any cached version + * + * @return array List of access permissions + */ +function get_write_access_array($user_id = 0, $site_id = 0, $flush = false) { +	global $CONFIG; +	//@todo this is probably not needed since caching happens at the DB level. +	static $access_array; + +	if ($user_id == 0) { +		$user_id = get_loggedin_userid(); +	} + +	if (($site_id == 0) && (isset($CONFIG->site_id))) { +		$site_id = $CONFIG->site_id; +	} + +	$user_id = (int) $user_id; +	$site_id = (int) $site_id; + +	if (empty($access_array[$user_id]) || $flush == true) { +		$query = "SELECT ag.* FROM {$CONFIG->dbprefix}access_collections ag "; +		$query .= " WHERE (ag.site_guid = {$site_id} OR ag.site_guid = 0)"; +		$query .= " AND (ag.owner_guid = {$user_id})"; +		$query .= " AND ag.id >= 3"; + +		$tmp_access_array = array(0 => elgg_echo("PRIVATE"), ACCESS_FRIENDS => elgg_echo("access:friends:label"), 1 => elgg_echo("LOGGED_IN"), 2 => elgg_echo("PUBLIC")); +		if ($collections = get_data($query)) { +			foreach($collections as $collection) { +				$tmp_access_array[$collection->id] = $collection->name;  			} -			 -			$query = "SELECT guid from {$CONFIG->dbprefix}entities e WHERE e.guid = ".$entity->getGUID(); -			$query .= " AND ".$access_bit; // Add access controls -			if (get_data($query)) { -				return true; -			} else { -				return false; -			}			  		} -		 -		/** -		 * Returns an array of access permissions that the specified user is allowed to save objects with. -		 * Permissions are of the form ('id' => 'Description') -		 * -		 * @param int $user_id The user's GUID. -		 * @param int $site_id The current site. -		 * @param true|false $flush If this is set to true, this will shun any cached version -		 * @return array List of access permissions= -		 */ -		function get_write_access_array($user_id = 0, $site_id = 0, $flush = false) { -			 -			global $CONFIG; -			static $access_array; -			 -			if ($user_id == 0) $user_id = get_loggedin_userid(); -			if (($site_id == 0) && (isset($CONFIG->site_id))) $site_id = $CONFIG->site_id; -			$user_id = (int) $user_id; -			$site_id = (int) $site_id; -			 -			if (empty($access_array[$user_id]) || $flush == true) { -				 -				$query = "SELECT ag.* FROM {$CONFIG->dbprefix}access_collections ag "; -				$query .= " WHERE (ag.site_guid = {$site_id} OR ag.site_guid = 0)"; -				$query .= " AND (ag.owner_guid = {$user_id})"; -				$query .= " AND ag.id >= 3"; -				 -				$tmp_access_array = array(0 => elgg_echo("PRIVATE"), ACCESS_FRIENDS => elgg_echo("access:friends:label"), 1 => elgg_echo("LOGGED_IN"), 2 => elgg_echo("PUBLIC")); -				if ($collections = get_data($query)) { -					foreach($collections as $collection) -						$tmp_access_array[$collection->id] = $collection->name; -				} -				 -				$access_array[$user_id] = $tmp_access_array; -				 -			} else { -				$tmp_access_array = $access_array[$user_id]; -			} -			 -			$tmp_access_array = trigger_plugin_hook('access:collections:write','user',array('user_id' => $user_id, 'site_id' => $site_id),$tmp_access_array); -			 -			return $tmp_access_array; -			 + +		$access_array[$user_id] = $tmp_access_array; +	} else { +		$tmp_access_array = $access_array[$user_id]; +	} + +	$tmp_access_array = trigger_plugin_hook('access:collections:write','user',array('user_id' => $user_id, 'site_id' => $site_id),$tmp_access_array); + +	return $tmp_access_array; +} + +/** + * Creates a new access control collection owned by the specified user. + * + * @param string $name The name of the collection. + * @param int $owner_guid The GUID of the owner (default: currently logged in user). + * @param int $site_guid The GUID of the site (default: current site). + * + * @return int|false Depending on success (the collection ID if successful). + */ +function create_access_collection($name, $owner_guid = 0, $site_guid = 0) { +	global $CONFIG; + +	$name = trim($name); +	if (empty($name)) { +		return false; +	} + +	if ($owner_guid == 0) { +		$owner_guid = get_loggedin_userid(); +	} +	if (($site_id == 0) && (isset($CONFIG->site_guid))) { +		$site_id = $CONFIG->site_guid; +	} +	$name = sanitise_string($name); + +	$q = "INSERT INTO {$CONFIG->dbprefix}access_collections +		SET name = '{$name}', +			owner_guid = {$owner_guid}, +			site_guid = {$site_id}"; +	if (!$id = insert_data($q)) { +		return false; +	} + +	$params = array( +		'collection_id' => $id +	); + +	if (!trigger_plugin_hook('access:collections:addcollection', 'collection', $params, true)) { +		return false; +	} + +	return $id; +} + +/** + * Updates the membership in an access collection. + * + * @param int $collection_id The ID of the collection. + * @param array $members Array of member GUIDs + * @return true|false Depending on success + */ +function update_access_collection($collection_id, $members) { +	global $CONFIG; + +	$collection_id = (int) $collection_id; +	$members = (is_array($members)) ? $members : array(); + +	$collections = get_write_access_array(); + +	if (array_key_exists($collection_id, $collections)) { +		$cur_members = get_members_of_access_collection($collection_id, true); +		$cur_members = (is_array($cur_members)) ? $cur_members : array(); + +		$remove_members = array_diff($cur_members, $members); +		$add_members = array_diff($members, $cur_members); + +		$params = array( +			'collection_id' => $collection_id, +			'members' => $members, +			'add_members' => $add_members, +			'remove_members' => $remove_members +		); + +		foreach ($add_members as $guid) { +			add_user_to_access_collection($guid, $collection_id);  		} -		/** -		 * Creates a new access control collection owned by the specified user. -		 * -		 * @param string $name The name of the collection. -		 * @param int $owner_guid The GUID of the owner (default: currently logged in user). -		 * @param int $site_guid The GUID of the site (default: current site). -		 * @return int|false Depending on success (the collection ID if successful). -		 */ -		function create_access_collection($name, $owner_guid = 0, $site_guid = 0) { -			 -			global $CONFIG; -			 -			$name = trim($name); -			if (empty($name)) return false; -			 -			if ($owner_guid == 0) $owner_guid = get_loggedin_userid(); -			if (($site_id == 0) && (isset($CONFIG->site_guid))) $site_id = $CONFIG->site_guid; -			$name = sanitise_string($name); -			 -			if (!$id = insert_data("insert into {$CONFIG->dbprefix}access_collections set name = '{$name}', owner_guid = {$owner_guid}, site_guid = {$site_id}")) { -				return false; -			} -			 -			$params = array( -				'collection_id' => $id -			); -			 -			if (!trigger_plugin_hook('access:collections:addcollection', 'collection', $params, true)) { -				return false; -			} -			 -			return $id; +		foreach ($remove_members as $guid) { +			remove_user_from_access_collection($guid, $collection_id);  		} -		 -		/** -		 * Updates the membership in an access collection. -		 * -		 * @param int $collection_id The ID of the collection. -		 * @param array $members Array of member GUIDs -		 * @return true|false Depending on success -		 */ -		function update_access_collection($collection_id, $members) { -			 -			global $CONFIG; -			$collection_id = (int) $collection_id; -			$members = (is_array($members)) ? $members : array(); -			 -			$collections = get_write_access_array(); -			 -			if (array_key_exists($collection_id, $collections)) { -				$cur_members = get_members_of_access_collection($collection_id, true); -				$cur_members = (is_array($cur_members)) ? $cur_members : array(); -				  -				$remove_members = array_diff($cur_members, $members); -				$add_members = array_diff($members, $cur_members); -				 -				$params = array( -					'collection_id' => $collection_id, -					'members' => $members, -					'add_members' => $add_members, -					'remove_members' => $remove_members -				); -				 -				foreach ($add_members as $guid) { -					add_user_to_access_collection($guid, $collection_id); -				} -				 -				foreach ($remove_members as $guid) { -					remove_user_from_access_collection($guid, $collection_id); -				} -				 -				return true; -			} -			 + +		return true; +	} + +	return false; +} + +/** + * Deletes a specified access collection + * + * @param int $collection_id The collection ID + * @return true|false Depending on success + */ +function delete_access_collection($collection_id) { + +	$collection_id = (int) $collection_id; +	$collections = get_write_access_array(); +	$params = array('collection_id' => $collection_id); + +	if (!trigger_plugin_hook('access:collections:deletecollection', 'collection', $params, true)) { +		return false; +	} + +	if (array_key_exists($collection_id, $collections)) { +		global $CONFIG; +		delete_data("delete from {$CONFIG->dbprefix}access_collection_membership where access_collection_id = {$collection_id}"); +		delete_data("delete from {$CONFIG->dbprefix}access_collections where id = {$collection_id}"); +		return true; +	} else { +		return false; +	} + +} + +/** + * Get a specified access collection + * + * @param int $collection_id The collection ID + * @return array|false Depending on success + */ +function get_access_collection($collection_id) { +	global $CONFIG; +	$collection_id = (int) $collection_id; + +	$get_collection = get_data_row("SELECT * FROM {$CONFIG->dbprefix}access_collections WHERE id = {$collection_id}"); + +	return $get_collection; +} + +/** + * Adds a user to the specified user collection + * + * @param int $user_guid The GUID of the user to add + * @param int $collection_id The ID of the collection to add them to + * @return true|false Depending on success + */ +function add_user_to_access_collection($user_guid, $collection_id) { +	$collection_id = (int) $collection_id; +	$user_guid = (int) $user_guid; +	$collections = get_write_access_array(); + +	if (!($collection = get_access_collection($collection_id))) +		return false; + +	if ((array_key_exists($collection_id, $collections) || $collection->owner_guid == 0) +			&& $user = get_user($user_guid)) { +		global $CONFIG; + +		$params = array( +			'collection_id' => $collection_id, +			'user_guid' => $user_guid +		); + +		if (!trigger_plugin_hook('access:collections:add_user', 'collection', $params, true)) {  			return false;  		} -		 -		/** -		 * Deletes a specified access collection -		 * -		 * @param int $collection_id The collection ID -		 * @return true|false Depending on success -		 */ -		function delete_access_collection($collection_id) { -			 -			$collection_id = (int) $collection_id; -			$collections = get_write_access_array(); -			$params = array('collection_id' => $collection_id); -			 -			if (!trigger_plugin_hook('access:collections:deletecollection', 'collection', $params, true)) { -				return false; -			} -			 -			if (array_key_exists($collection_id, $collections)) { -				global $CONFIG; -				delete_data("delete from {$CONFIG->dbprefix}access_collection_membership where access_collection_id = {$collection_id}"); -				delete_data("delete from {$CONFIG->dbprefix}access_collections where id = {$collection_id}"); -				return true; -			} else { -				return false; -			} -			 -		} -		 -		/** -		 * Get a specified access collection -		 * -		 * @param int $collection_id The collection ID -		 * @return array|false Depending on success -		 */ -		function get_access_collection($collection_id) { -    		 -    		$collection_id = (int) $collection_id; -    		global $CONFIG; -    		$get_collection = get_data_row("SELECT * FROM {$CONFIG->dbprefix}access_collections WHERE id = {$collection_id}"); -    		 -    		return $get_collection; -    		 -		} -		 -		/** -		 * Adds a user to the specified user collection -		 * -		 * @param int $user_guid The GUID of the user to add -		 * @param int $collection_id The ID of the collection to add them to -		 * @return true|false Depending on success -		 */ -		function add_user_to_access_collection($user_guid, $collection_id) { -			 -			$collection_id = (int) $collection_id; -			$user_guid = (int) $user_guid; -			$collections = get_write_access_array(); -			 -			if (!($collection = get_access_collection($collection_id))) -				return false; -				 -			if ((array_key_exists($collection_id, $collections) || $collection->owner_guid == 0) -					&& $user = get_user($user_guid)) { -				global $CONFIG; - -				$params = array( -					'collection_id' => $collection_id, -					'user_guid' => $user_guid -				); -			 -				if (!trigger_plugin_hook('access:collections:add_user', 'collection', $params, true)) { -					return false; -				} -				 -				try { -					insert_data("insert into {$CONFIG->dbprefix}access_collection_membership set access_collection_id = {$collection_id}, user_guid = {$user_guid}"); -				} catch (DatabaseException $e) {} -				return true; -				 -			} -			 -			return false; -			 + +		try { +			insert_data("insert into {$CONFIG->dbprefix}access_collection_membership set access_collection_id = {$collection_id}, user_guid = {$user_guid}"); +		} catch (DatabaseException $e) { +			// nothing.  		} +		return true; -		/** -		 * Removes a user from an access collection -		 * -		 * @param int $user_guid The user GUID -		 * @param int $collection_id The access collection ID -		 * @return true|false Depending on success -		 */ -		function remove_user_from_access_collection($user_guid, $collection_id) { -			 -			$collection_id = (int) $collection_id; -			$user_guid = (int) $user_guid; -			$collections = get_write_access_array(); -			 -			if (!($collection = get_access_collection($collection_id))) -				return false; -			 -			if ((array_key_exists($collection_id, $collections) || $collection->owner_guid == 0) && $user = get_user($user_guid)) { -				global $CONFIG; -				$params = array( -					'collection_id' => $collection_id, -					'user_guid' => $user_guid -				); -			 -				if (!trigger_plugin_hook('access:collections:remove_user', 'collection', $params, true)) { -					return false; -				} -				 -				delete_data("delete from {$CONFIG->dbprefix}access_collection_membership where access_collection_id = {$collection_id} and user_guid = {$user_guid}"); -				return true; -				 -			} -			 +	} + +	return false; +} + +/** + * Removes a user from an access collection + * + * @param int $user_guid The user GUID + * @param int $collection_id The access collection ID + * @return true|false Depending on success + */ +function remove_user_from_access_collection($user_guid, $collection_id) { +	$collection_id = (int) $collection_id; +	$user_guid = (int) $user_guid; +	$collections = get_write_access_array(); + +	if (!($collection = get_access_collection($collection_id))) +		return false; + +	if ((array_key_exists($collection_id, $collections) || $collection->owner_guid == 0) && $user = get_user($user_guid)) { +		global $CONFIG; +		$params = array( +			'collection_id' => $collection_id, +			'user_guid' => $user_guid +		); + +		if (!trigger_plugin_hook('access:collections:remove_user', 'collection', $params, true)) {  			return false; -			 -		} -		 -		/** -		 * Get all of a users collections -		 * -		 * @param int $owner_guid The user ID -		 * @return true|false Depending on success -		 */ -		function get_user_access_collections($owner_guid) { -			 -			$owner_guid = (int) $owner_guid; -			 -			global $CONFIG; -			 -			$collections = get_data("SELECT * FROM {$CONFIG->dbprefix}access_collections WHERE owner_guid = {$owner_guid}"); -			 -			return $collections; -			  		} -		 -		/** -		 * Get all of members of a friend collection -		 * -		 * @param int $collection The collection's ID -		 * @param true|false $idonly If set to true, will only return the members' IDs (default: false) -		 * @return ElggUser entities if successful, false if not -		 */ -		function get_members_of_access_collection($collection, $idonly = false) { -    		 -    		$collection = (int)$collection; -    		 -    		global $CONFIG; -		 -    		if (!$idonly) { -		    	$query = "SELECT e.* FROM {$CONFIG->dbprefix}access_collection_membership m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.user_guid WHERE m.access_collection_id = {$collection}";	     -				$collection_members = get_data($query, "entity_row_to_elggstar"); -    		} else { -    			$query = "SELECT e.guid FROM {$CONFIG->dbprefix}access_collection_membership m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.user_guid WHERE m.access_collection_id = {$collection}"; -    			$collection_members = get_data($query); -    			foreach($collection_members as $key => $val) -    				$collection_members[$key] = $val->guid; -    		} -			 -			return $collection_members; -			 -		} -		 -		/** -		 * Displays a user's access collections, using the friends/collections view -		 * -		 * @param int $owner_guid The GUID of the owning user -		 * @return string A formatted rendition of the collections -		 */ -		function elgg_view_access_collections($owner_guid) { -			 -			if ($collections = get_user_access_collections($owner_guid)) { -				 -				foreach($collections as $key => $collection) { -					$collections[$key]->members = get_members_of_access_collection($collection->id, true); -					$collections[$key]->entities = get_user_friends($owner_guid,"",9999); -				} -				 -			} -			 -			return elgg_view('friends/collections',array('collections' => $collections)); -			 -		} -		 -		/** -		 * Get entities with the specified access collection id. -		 *  -		 * @param $collection_id -		 * @param $entity_type -		 * @param $entity_subtype -		 * @param $owner_guid -		 * @param $limit -		 * @param $offset -		 * @param $order_by -		 * @param $site_guid -		 * @param $count -		 * @return unknown_type -		 */ -		function get_entities_from_access_id($collection_id, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) { -			global $CONFIG; -			 -			if (!$collection_id) -				return false; -				 -			$entity_type = sanitise_string($entity_type); -			$entity_subtype = get_subtype_id($entity_type, $entity_subtype); -			$limit = (int)$limit; -			$offset = (int)$offset; -			if ($order_by == "")  -				$order_by = "e.time_created desc"; -			else -				$order_by = "e.time_created, {$order_by}"; -			$order_by = sanitise_string($order_by); -			$site_guid = (int) $site_guid; -			if ((is_array($owner_guid) && (count($owner_guid)))) { -				foreach($owner_guid as $key => $guid) { -					$owner_guid[$key] = (int) $guid; -				} -			} else { -				$owner_guid = (int) $owner_guid; -			} -			if ($site_guid == 0) -				$site_guid = $CONFIG->site_guid; -				 -			//$access = get_access_list(); -				 -			$where = array("e.access_id = $collection_id"); -			 -			if ($entity_type!=="") -				$where[] = "e.type='$entity_type'"; -			if ($entity_subtype) -				$where[] = "e.subtype=$entity_subtype"; -			if ($site_guid > 0) -				$where[] = "e.site_guid = {$site_guid}"; -			if (is_array($owner_guid)) { -				$where[] = "e.container_guid in (".implode(",",$owner_guid).")"; -			} else if ($owner_guid > 0) -				$where[] = "e.container_guid = {$owner_guid}"; -			 -			if (!$count) { -				$query = "SELECT distinct e.* ";  -			} else { -				$query = "SELECT count(distinct e.guid) as total "; -			} -				 -			$query .= "from {$CONFIG->dbprefix}entities e where"; -			foreach ($where as $w) -				$query .= " $w and "; -			$query .= get_access_sql_suffix("e"); // Add access controls -			//$query .= ' and ' . get_access_sql_suffix("m"); // Add access controls -			 -			if (!$count) { -				$query .= " order by $order_by limit $offset, $limit"; // Add order and limit -				return get_data($query, "entity_row_to_elggstar"); -			} else { -				if ($row = get_data_row($query)) -					return $row->total; -			} -			return false; + +		delete_data("delete from {$CONFIG->dbprefix}access_collection_membership where access_collection_id = {$collection_id} and user_guid = {$user_guid}"); +		return true; + +	} + +	return false; +} + +/** + * Get all of a users collections + * + * @param int $owner_guid The user ID + * @return true|false Depending on success + */ +function get_user_access_collections($owner_guid) { +	global $CONFIG; +	$owner_guid = (int) $owner_guid; + +	$collections = get_data("SELECT * FROM {$CONFIG->dbprefix}access_collections WHERE owner_guid = {$owner_guid}"); + +	return $collections; +} + +/** + * Get all of members of a friend collection + * + * @param int $collection The collection's ID + * @param true|false $idonly If set to true, will only return the members' IDs (default: false) + * @return ElggUser entities if successful, false if not + */ +function get_members_of_access_collection($collection, $idonly = false) { +	global $CONFIG; +	$collection = (int)$collection; + +	if (!$idonly) { +		$query = "SELECT e.* FROM {$CONFIG->dbprefix}access_collection_membership m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.user_guid WHERE m.access_collection_id = {$collection}"; +		$collection_members = get_data($query, "entity_row_to_elggstar"); +	} else { +		$query = "SELECT e.guid FROM {$CONFIG->dbprefix}access_collection_membership m JOIN {$CONFIG->dbprefix}entities e ON e.guid = m.user_guid WHERE m.access_collection_id = {$collection}"; +		$collection_members = get_data($query); +		foreach($collection_members as $key => $val) { +			$collection_members[$key] = $val->guid;  		} -		 -		/** -		 * Lists entities from an access collection -		 *  -		 * @param $collection_id -		 * @param $entity_type -		 * @param $entity_subtype -		 * @param $owner_guid -		 * @param $limit -		 * @param $fullview -		 * @param $viewtypetoggle -		 * @param $pagination -		 * @return str -		 */ -		function list_entities_from_access_id($collection_id, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) { -			$offset = (int) get_input('offset'); -			$limit = (int) $limit; -			$count = get_entities_from_access_id($collection_id, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, true); -			$entities = get_entities_from_access_id($collection_id, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, false); -			 -			return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); +	} + +	return $collection_members; +} + +/** + * Displays a user's access collections, using the friends/collections view + * + * @param int $owner_guid The GUID of the owning user + * @return string A formatted rendition of the collections + */ +function elgg_view_access_collections($owner_guid) { +	if ($collections = get_user_access_collections($owner_guid)) { +		foreach($collections as $key => $collection) { +			$collections[$key]->members = get_members_of_access_collection($collection->id, true); +			$collections[$key]->entities = get_user_friends($owner_guid,"",9999);  		} -		 -	/** -	 * Return a humanreadable version of an entity's access level -	 * -	 * @param $entity_accessid (int) The entity's access id -	 * @return string e.g. Public, Private etc -	 **/ -		  -		function get_readable_access_level($entity_accessid){	 -			$access = (int) $entity_accessid; -			//get the access level for object in readable string -			$options = get_write_access_array(); -			foreach($options as $key => $option) { -				if($key == $access){ -					$entity_acl = htmlentities($option, ENT_QUOTES, 'UTF-8'); -					return $entity_acl; -					break; -				} -	 		} -	 		return false; +	} + +	return elgg_view('friends/collections',array('collections' => $collections)); +} + +/** + * Get entities with the specified access collection id. + * + * @param $collection_id + * @param $entity_type + * @param $entity_subtype + * @param $owner_guid + * @param $limit + * @param $offset + * @param $order_by + * @param $site_guid + * @param $count + * @return unknown_type + */ +function get_entities_from_access_id($collection_id, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $offset = 0, $order_by = "", $site_guid = 0, $count = false) { +	global $CONFIG; + +	if (!$collection_id) { +		return false; +	} + +	$entity_type = sanitise_string($entity_type); +	$entity_subtype = get_subtype_id($entity_type, $entity_subtype); +	$limit = (int)$limit; +	$offset = (int)$offset; + +	if ($order_by == "") { +		$order_by = "e.time_created desc"; +	} else { +		$order_by = "e.time_created, {$order_by}"; +	} + +	$order_by = sanitise_string($order_by); +	$site_guid = (int) $site_guid; +	if ((is_array($owner_guid) && (count($owner_guid)))) { +		foreach($owner_guid as $key => $guid) { +			$owner_guid[$key] = (int) $guid;  		} -		 -		global $init_finished; -		$init_finished = false; -		 -	/** -	 * A quick and dirty way to make sure the access permissions have been correctly set up -	 * -	 */ -		function access_init() { -			global $init_finished; -			$init_finished = true; +	} else { +		$owner_guid = (int) $owner_guid; +	} +	if ($site_guid == 0) +		$site_guid = $CONFIG->site_guid; + +	//$access = get_access_list(); + +	$where = array("e.access_id = $collection_id"); + +	if ($entity_type!=="") +		$where[] = "e.type='$entity_type'"; +	if ($entity_subtype) +		$where[] = "e.subtype=$entity_subtype"; +	if ($site_guid > 0) +		$where[] = "e.site_guid = {$site_guid}"; +	if (is_array($owner_guid)) { +		$where[] = "e.container_guid in (".implode(",",$owner_guid).")"; +	} else if ($owner_guid > 0) +		$where[] = "e.container_guid = {$owner_guid}"; + +	if (!$count) { +		$query = "SELECT distinct e.* "; +	} else { +		$query = "SELECT count(distinct e.guid) as total "; +	} + +	$query .= "from {$CONFIG->dbprefix}entities e where"; +	foreach ($where as $w) +		$query .= " $w and "; +	$query .= get_access_sql_suffix("e"); // Add access controls +	//$query .= ' and ' . get_access_sql_suffix("m"); // Add access controls + +	if (!$count) { +		$query .= " order by $order_by limit $offset, $limit"; // Add order and limit +		return get_data($query, "entity_row_to_elggstar"); +	} else { +		if ($row = get_data_row($query)) +			return $row->total; +	} +	return false; +} + +/** + * Lists entities from an access collection + * + * @param $collection_id + * @param $entity_type + * @param $entity_subtype + * @param $owner_guid + * @param $limit + * @param $fullview + * @param $viewtypetoggle + * @param $pagination + * @return str + */ +function list_entities_from_access_id($collection_id, $entity_type = "", $entity_subtype = "", $owner_guid = 0, $limit = 10, $fullview = true, $viewtypetoggle = true, $pagination = true) { +	$offset = (int) get_input('offset'); +	$limit = (int) $limit; +	$count = get_entities_from_access_id($collection_id, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, true); +	$entities = get_entities_from_access_id($collection_id, $entity_type, $entity_subtype, $owner_guid, $limit, $offset, "", 0, false); + +	return elgg_view_entity_list($entities, $count, $offset, $limit, $fullview, $viewtypetoggle, $pagination); +} + +/** + * Return a humanreadable version of an entity's access level + * + * @param $entity_accessid (int) The entity's access id + * @return string e.g. Public, Private etc + **/ +function get_readable_access_level($entity_accessid){ +	$access = (int) $entity_accessid; +	//get the access level for object in readable string +	$options = get_write_access_array(); +	foreach($options as $key => $option) { +		if($key == $access){ +			$entity_acl = htmlentities($option, ENT_QUOTES, 'UTF-8'); +			return $entity_acl; +			break;  		} -		 -	// This function will let us know when 'init' has finished -		register_elgg_event_handler('init','system','access_init',9999); -		 -?> +	} +	return false; +} + +global $init_finished; +$init_finished = false; + +/** + * A quick and dirty way to make sure the access permissions have been correctly set up + * + */ +function access_init() { +	global $init_finished; +	$init_finished = true; +} + +// This function will let us know when 'init' has finished +register_elgg_event_handler('init','system','access_init',9999);
\ No newline at end of file diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php index b34f07725..d3e4a499d 100644 --- a/engine/lib/sessions.php +++ b/engine/lib/sessions.php @@ -1,669 +1,716 @@  <?php -	/** -	 * Elgg session management -	 * Functions to manage logins -	 *  -	 * @package Elgg -	 * @subpackage Core +/** + * Elgg session management + * Functions to manage logins + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + */ -	 * @author Curverider Ltd +/** Elgg magic session */ +global $SESSION; -	 * @link http://elgg.org/ -	 */ +/** + * Magic session class. + * This class is intended to extend the $_SESSION magic variable by providing an API hook + * to plug in other values. + * + * Primarily this is intended to provide a way of supplying "logged in user" details without touching the session + * (which can cause problems when accessed server side). + * + * If a value is present in the session then that value is returned, otherwise a plugin hook 'session:get', '$var' is called, + * where $var is the variable being requested. + * + * Setting values will store variables in the session in the normal way. + * + * LIMITATIONS: You can not access multidimensional arrays + * + * This is EXPERIMENTAL. + */ +class ElggSession implements ArrayAccess { +	/** Local cache of trigger retrieved variables */ +	private static $__localcache; -	/** Elgg magic session */ -	global $SESSION; +	function __isset($key) { +		return $this->offsetExists($key); +	} + +	/** Set a value, go straight to session. */ +	function offsetSet($key, $value) { +		$_SESSION[$key] = $value; +	}  	/** -	 * Magic session class. -	 * This class is intended to extend the $_SESSION magic variable by providing an API hook -	 * to plug in other values. -	 * -	 * Primarily this is intended to provide a way of supplying "logged in user" details without touching the session  -	 * (which can cause problems when accessed server side). -	 *  -	 * If a value is present in the session then that value is returned, otherwise a plugin hook 'session:get', '$var' is called, -	 * where $var is the variable being requested. -	 *  -	 * Setting values will store variables in the session in the normal way. -	 *  -	 * LIMITATIONS: You can not access multidimensional arrays -	 *  -	 * This is EXPERIMENTAL. +	 * Get a variable from either the session, or if its not in the session attempt to get it from +	 * an api call.  	 */ -	class ElggSession implements ArrayAccess -	{ -		/** Local cache of trigger retrieved variables */ -		private static $__localcache;  -		 -		function __isset($key) { return $this->offsetExists($key); } -				 -		/** Set a value, go straight to session. */ -		function offsetSet($key, $value) { $_SESSION[$key] = $value; }  - 		 -		/** -		 * Get a variable from either the session, or if its not in the session attempt to get it from -		 * an api call. -		 */ - 		function offsetGet($key)  - 		{  - 			if (!ElggSession::$__localcache) - 				ElggSession::$__localcache = array(); - 				 - 			if (isset($_SESSION[$key])) - 				return $_SESSION[$key]; - 				 - 			if (isset(ElggSession::$__localcache[$key])) - 				return ElggSession::$__localcache[$key]; - 			 - 			$value = null; - 			$value = trigger_plugin_hook('session:get', $key, null, $value); - 			 - 			ElggSession::$__localcache[$key] = $value; - 			 -   			return ElggSession::$__localcache[$key]; - 		}  - 		 - 		/** - 		 * Unset a value from the cache and the session. - 		 */ - 		function offsetUnset($key)  - 		{ -   			unset(ElggSession::$__localcache[$key]); -			unset($_SESSION[$key]);  - 		}  - 		 - 		/** - 		 * Return whether the value is set in either the session or the cache. - 		 */ - 		function offsetExists($offset) {  -			if (isset(ElggSession::$__localcache[$offset])) -				return true; -				 -			if (isset($_SESSION[$offset])) -				return true; +	function offsetGet($key) { +		if (!ElggSession::$__localcache) { +			ElggSession::$__localcache = array(); +		} + +		if (isset($_SESSION[$key])) { +			return $_SESSION[$key]; +		} -			if ($this->offsetGet($offset)) return true; +		if (isset(ElggSession::$__localcache[$key])) { +			return ElggSession::$__localcache[$key];  		} + +		$value = null; +		$value = trigger_plugin_hook('session:get', $key, null, $value); + +		ElggSession::$__localcache[$key] = $value; + +		return ElggSession::$__localcache[$key];  	} -	 -		 +  	/** -	 * Return the current logged in user, or null if no user is logged in. -	 * -	 * If no user can be found in the current session, a plugin hook - 'session:get' 'user' to give plugin  -	 * authors another way to provide user details to the ACL system without touching the session. -	 */ -		function get_loggedin_user() -		{ -			global $SESSION; -		 -			if (isset($SESSION)) -				return $SESSION['user']; -				 -			return false; -		} -		 +	* Unset a value from the cache and the session. +	*/ +	function offsetUnset($key) { +		unset(ElggSession::$__localcache[$key]); +		unset($_SESSION[$key]); +	} +  	/** -	 * Return the current logged in user by id. -	 *  -	 * @see get_loggedin_user() -	 * @return int -	 */ -		function get_loggedin_userid() -		{ -			$user = get_loggedin_user(); -			if ($user) -				return $user->guid; -				 -			return 0; +	* Return whether the value is set in either the session or the cache. +	*/ +	function offsetExists($offset) { +		if (isset(ElggSession::$__localcache[$offset])) { +			return true;  		} -	/** -	 * Returns whether or not the user is currently logged in -	 * -	 * @return true|false -	 */ -		function isloggedin() { -						 -			if (!is_installed()) return false;  -			 -			$user = get_loggedin_user(); -		 -			if ((isset($user)) && ($user instanceof ElggUser) && ($user->guid > 0)) -				return true; -				 -			return false; -			 +		if (isset($_SESSION[$offset])) { +			return true;  		} -	/** -	 * Returns whether or not the user is currently logged in and that they are an admin user. -	 * -	 * @uses isloggedin() -	 * @return true|false -	 */ -		function isadminloggedin() -		{ -			if (!is_installed()) return false;  -			 -			$user = get_loggedin_user(); -			 -			if ((isloggedin()) && (($user->admin || $user->siteadmin))) -				return true; -				 -			return false; +		if ($this->offsetGet($offset)){ +			return true;  		} -		 -		/** -		 * Check if the given user is an admin. -		 *  -		 * @param $user_guid -		 * @return bool -		 */ -		function is_admin_user($user_guid) { -			global $CONFIG; -			 -			// caching is done at the db level so no need to here. -			$query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as e, {$CONFIG->dbprefix}metastrings as ms1, {$CONFIG->dbprefix}metastrings as ms2, {$CONFIG->dbprefix}metadata as md -				WHERE ( -					ms1.string = 'admin' AND ms2.string = 'yes' -					AND md.name_id = ms1.id	AND md.value_id = ms2.id -					AND e.guid = md.entity_guid -					AND e.guid = {$user_guid} -					AND e.banned = 'no' -					) -				OR ( -					ms1.string = 'admin' AND ms2.string = '1' -					AND md.name_id = ms1.id	AND md.value_id = ms2.id -					AND e.guid = md.entity_guid -					AND e.guid = {$user_guid} -					AND e.banned = 'no' -					)"; - -			// normalizing the results from get_data() -			// See #1242 -			$info = get_data($query); -			if (!((is_array($info) && count($info) < 1) || $info === false)) { -				return true; +	} +} + + +/** + * Return the current logged in user, or null if no user is logged in. + * + * If no user can be found in the current session, a plugin hook - 'session:get' 'user' to give plugin + * authors another way to provide user details to the ACL system without touching the session. + */ +function get_loggedin_user() { +	global $SESSION; + +	if (isset($SESSION)) { +		return $SESSION['user']; +	} + +	return false; +} + +/** + * Return the current logged in user by id. + * + * @see get_loggedin_user() + * @return int + */ +function get_loggedin_userid() { +	$user = get_loggedin_user(); +	if ($user) +		return $user->guid; + +	return 0; +} + +/** + * Returns whether or not the user is currently logged in + * + * @return true|false + */ +function isloggedin() { +	if (!is_installed()) { +		return false; +	} + +	$user = get_loggedin_user(); + +	if ((isset($user)) && ($user instanceof ElggUser) && ($user->guid > 0)) { +		return true; +	} + +	return false; +} + +/** + * Returns whether or not the user is currently logged in and that they are an admin user. + * + * @uses isloggedin() + * @return true|false + */ +function isadminloggedin() { +	if (!is_installed()) { +		return false; +	} + +	$user = get_loggedin_user(); + +	if ((isloggedin()) && (($user->admin || $user->siteadmin))) { +		return true; +	} + +	return false; +} + +/** + * Check if the given user has full access. + * @todo: Will always return full access if the user is an admin. + * + * @param $user_guid + * @return bool + */ +function is_admin_user($user_guid) { +	global $CONFIG; + +	// cannot use metadata here because +	// caching is done at the db level so no need to here. +	$query = "SELECT * FROM {$CONFIG->dbprefix}users_entity as e, {$CONFIG->dbprefix}metastrings as ms1, {$CONFIG->dbprefix}metastrings as ms2, {$CONFIG->dbprefix}metadata as md +		WHERE ( +			ms1.string = 'admin' AND ms2.string = 'yes' +			AND md.name_id = ms1.id	AND md.value_id = ms2.id +			AND e.guid = md.entity_guid +			AND e.guid = {$user_guid} +			AND e.banned = 'no' +			) +		OR ( +			ms1.string = 'admin' AND ms2.string = '1' +			AND md.name_id = ms1.id	AND md.value_id = ms2.id +			AND e.guid = md.entity_guid +			AND e.guid = {$user_guid} +			AND e.banned = 'no' +			)"; + +	// normalizing the results from get_data() +	// See #1242 +	$info = get_data($query); +	if (!((is_array($info) && count($info) < 1) || $info === false)) { +		return true; +	} +	return false; +} + +/** + * Perform standard authentication with a given username and password. + * Returns an ElggUser object for use with login. + * + * @see login + * @param string $username The username, optionally (for standard logins) + * @param string $password The password, optionally (for standard logins) + * @return ElggUser|false The authenticated user object, or false on failure. + */ + +function authenticate($username, $password) { +	if (pam_authenticate(array('username' => $username, 'password' => $password))) { +		return get_user_by_username($username); +	} + +	return false; +} + +/** + * Hook into the PAM system which accepts a username and password and attempts to authenticate + * it against a known user. + * + * @param array $credentials Associated array of credentials passed to pam_authenticate. This function expects + * 		'username' and 'password' (cleartext). + */ +function pam_auth_userpass($credentials = NULL) { +	$max_in_period = 3; // max 3 login attempts in +	$period_length = 5; // 5 minutes +	$periods = array(); + +	if (is_array($credentials) && ($credentials['username']) && ($credentials['password'])) { +		if ($user = get_user_by_username($credentials['username'])) { + +			// Let admins log in without validating their email, but normal users must have validated their email or been admin created +			if ((!$user->admin) && (!$user->validated) && (!$user->admin_created)) { +				return false;  			} -			return false; -		} -		 -	/** -	 * Perform standard authentication with a given username and password. -	 * Returns an ElggUser object for use with login. -	 * -	 * @see login -	 * @param string $username The username, optionally (for standard logins) -	 * @param string $password The password, optionally (for standard logins) -	 * @return ElggUser|false The authenticated user object, or false on failure. -	 */ -		 -		function authenticate($username, $password) { -             -			if (pam_authenticate(array('username' => $username, 'password' => $password))) -				return get_user_by_username($username); -             -            return false; -			 -		} -		 -		/** -		 * Hook into the PAM system which accepts a username and password and attempts to authenticate -		 * it against a known user. -		 * -		 * @param array $credentials Associated array of credentials passed to pam_authenticate. This function expects -		 * 		'username' and 'password' (cleartext). -		 */ -		function pam_auth_userpass($credentials = NULL) -		{ -			$max_in_period = 3; // max 3 login attempts in -			$period_length = 5; // 5 minutes -			$periods = array(); -			 -			if (is_array($credentials) && ($credentials['username']) && ($credentials['password'])) -			{ -				//$dbpassword = md5($credentials['password']); -             -				 -	            if ($user = get_user_by_username($credentials['username'])) { -	            		            	 -	            	// Let admins log in without validating their email, but normal users must have validated their email or been admin created -					if ((!$user->admin) && (!$user->validated) && (!$user->admin_created)) -						return false; -	          	 -					 // User has been banned, so bin them. -					 if ($user->isBanned()) return false; -						 -	                 if ($user->password == generate_user_password($user, $credentials['password']))  -	                 	 -	                 	return true; -	                 else  -	                 	// Password failed, log. -	                 	log_login_failure($user->guid); -	                 	 -	            } + +			// User has been banned, so bin them. +			if ($user->isBanned()) { +				return false;  			} -			 -			return false; -		} -		 -		function log_login_failure($user_guid) -		{ -			$user_guid = (int)$user_guid; -			$user = get_entity($user_guid); -			 -			if (($user_guid) && ($user) && ($user instanceof ElggUser)) -			{ -				$fails = (int)$user->getPrivateSetting("login_failures"); -				$fails++; -				 -				$user->setPrivateSetting("login_failures", $fails); -				$user->setPrivateSetting("login_failure_$fails", time()); + +			if ($user->password == generate_user_password($user, $credentials['password'])) { +				return true; +			} else { +				// Password failed, log. +				log_login_failure($user->guid);  			} +  		} -		 -		function reset_login_failure_count($user_guid) -		{ -			$user_guid = (int)$user_guid; -			$user = get_entity($user_guid); -			 -			if (($user_guid) && ($user) && ($user instanceof ElggUser)) -			{ -				$fails = (int)$user->getPrivateSetting("login_failures"); -				 -				if ($fails) { -					for ($n=1; $n <= $fails; $n++)  -						$user->removePrivateSetting("login_failure_$n"); -						 -					$user->removePrivateSetting("login_failures"); -				} +	} + +	return false; +} + +/** + * Log a failed login for $user_guid + * + * @param $user_guid + * @return bool on success + */ +function log_login_failure($user_guid) { +	$user_guid = (int)$user_guid; +	$user = get_entity($user_guid); + +	if (($user_guid) && ($user) && ($user instanceof ElggUser)) { +		$fails = (int)$user->getPrivateSetting("login_failures"); +		$fails++; + +		$user->setPrivateSetting("login_failures", $fails); +		$user->setPrivateSetting("login_failure_$fails", time()); +		return true; +	} + +	return false; +} + +/** + * Resets the fail login count for $user_guid + * + * @param $user_guid + * @return bool on success (success = user has no logged failed attempts) + */ +function reset_login_failure_count($user_guid) { +	$user_guid = (int)$user_guid; +	$user = get_entity($user_guid); + +	if (($user_guid) && ($user) && ($user instanceof ElggUser)) { +		$fails = (int)$user->getPrivateSetting("login_failures"); + +		if ($fails) { +			for ($n=1; $n <= $fails; $n++) { +				$user->removePrivateSetting("login_failure_$n");  			} + +			$user->removePrivateSetting("login_failures"); + +			return true;  		} -		 -		function check_rate_limit_exceeded($user_guid) -		{ -			$limit = 5; -			$user_guid = (int)$user_guid; -			$user = get_entity($user_guid); -			 -			if (($user_guid) && ($user) && ($user instanceof ElggUser)) -			{ -				$fails = (int)$user->getPrivateSetting("login_failures"); -				if ($fails >= $limit) -				{ -					$cnt = 0; -					$time = time(); -					for ($n=$fails; $n>0; $n--) -					{ -						$f = $user->getPrivateSetting("login_failure_$n"); -						if ($f > $time - (60*5)) -							$cnt++; -							 -						if ($cnt==$limit) return true; // Limit reached -					} + +		// nothing to reset +		return true; +	} + +	return false; +} + +/** + * Checks if the rate limit of failed logins has been exceeded for $user_guid. + * + * @param $user_guid + * @return bool on exceeded limit. + */ +function check_rate_limit_exceeded($user_guid) { +	$limit = 5; +	$user_guid = (int)$user_guid; +	$user = get_entity($user_guid); + +	if (($user_guid) && ($user) && ($user instanceof ElggUser)) { +		$fails = (int)$user->getPrivateSetting("login_failures"); +		if ($fails >= $limit) { +			$cnt = 0; +			$time = time(); +			for ($n=$fails; $n>0; $n--) { +				$f = $user->getPrivateSetting("login_failure_$n"); +				if ($f > $time - (60*5)) { +					$cnt++; +				} + +				if ($cnt==$limit) { +					// Limit reached +					return true;  				} -				  			} -			 -			return false;  		} -		 -	/** -	 * Logs in a specified ElggUser. For standard registration, use in conjunction -	 * with authenticate. -	 *  -	 * @see authenticate -	 * @param ElggUser $user A valid Elgg user object -	 * @param boolean $persistent Should this be a persistent login? -	 * @return true|false Whether login was successful -	 */ -		function login(ElggUser $user, $persistent = false) { -             -            global $CONFIG; -             -            if ($user->isBanned()) return false; // User is banned, return false. -            if (check_rate_limit_exceeded($user->guid)) return false; // Check rate limit -           -            $_SESSION['user'] = $user; -            $_SESSION['guid'] = $user->getGUID(); -            $_SESSION['id'] = $_SESSION['guid']; -            $_SESSION['username'] = $user->username; -            $_SESSION['name'] = $user->name; -                      -            $code = (md5($user->name . $user->username . time() . rand())); - -            $user->code = md5($code); -             -            $_SESSION['code'] = $code; -             -            if (($persistent)) -				setcookie("elggperm", $code, (time()+(86400 * 30)),"/"); -          -            if (!$user->save() || !trigger_elgg_event('login','user',$user)) { -            	unset($_SESSION['username']); -	            unset($_SESSION['name']); -	            unset($_SESSION['code']); -	            unset($_SESSION['guid']); -	            unset($_SESSION['id']); -	            unset($_SESSION['user']); -	            setcookie("elggperm", "", (time()-(86400 * 30)),"/"); -            	return false; -            } -             -            // Users privilege has been elevated, so change the session id (help prevent session hijacking) -	        session_regenerate_id();  - -	        // Update statistics -	        set_last_login($_SESSION['guid']); -	        reset_login_failure_count($user->guid); // Reset any previous failed login attempts -	         -	        // Set admin shortcut flag if this is an admin -			if (isadminloggedin()) { -				global $is_admin; -				$is_admin = true; -			} -	         -			return true; -				 +	} + +	return false; +} + +/** + * Logs in a specified ElggUser. For standard registration, use in conjunction + * with authenticate. + * + * @see authenticate + * @param ElggUser $user A valid Elgg user object + * @param boolean $persistent Should this be a persistent login? + * @return true|false Whether login was successful + */ +function login(ElggUser $user, $persistent = false) { +	global $CONFIG; + +	// User is banned, return false. +	if ($user->isBanned()) { +		return false; +	} + +	// Check rate limit +	if (check_rate_limit_exceeded($user->guid)) { +		return false; +	} + +	$_SESSION['user'] = $user; +	$_SESSION['guid'] = $user->getGUID(); +	$_SESSION['id'] = $_SESSION['guid']; +	$_SESSION['username'] = $user->username; +	$_SESSION['name'] = $user->name; + +	$code = (md5($user->name . $user->username . time() . rand())); + +	$user->code = md5($code); + +	$_SESSION['code'] = $code; + +	if (($persistent)) { +		setcookie("elggperm", $code, (time()+(86400 * 30)),"/"); +	} + +	if (!$user->save() || !trigger_elgg_event('login','user',$user)) { +		unset($_SESSION['username']); +		unset($_SESSION['name']); +		unset($_SESSION['code']); +		unset($_SESSION['guid']); +		unset($_SESSION['id']); +		unset($_SESSION['user']); +		setcookie("elggperm", "", (time()-(86400 * 30)),"/"); +		return false; +	} + +	// Users privilege has been elevated, so change the session id (help prevent session hijacking) +	session_regenerate_id(); + +	// Update statistics +	set_last_login($_SESSION['guid']); +	reset_login_failure_count($user->guid); // Reset any previous failed login attempts + +	// Set admin shortcut flag if this is an admin +	if (isadminloggedin()) { +		//@todo REMOVE THIS. +		global $is_admin; +		$is_admin = true; +	} + +	return true; +} + +/** + * Log the current user out + * + * @return true|false + */ +function logout() { +	global $CONFIG; + +	if (isset($_SESSION['user'])) { +		if (!trigger_elgg_event('logout','user',$_SESSION['user'])) { +			return false;  		} -         -	/** -	 * Log the current user out -	 * -	 * @return true|false -	 */ -		function logout() { -            global $CONFIG; - -            if (isset($_SESSION['user'])) { -            	if (!trigger_elgg_event('logout','user',$_SESSION['user'])) return false; -            	$_SESSION['user']->code = ""; -            	$_SESSION['user']->save(); -            } -             -            unset($_SESSION['username']); -            unset($_SESSION['name']); -            unset($_SESSION['code']); -            unset($_SESSION['guid']); -            unset($_SESSION['id']); -            unset($_SESSION['user']); -             -            setcookie("elggperm", "", (time()-(86400 * 30)),"/"); -             -            session_destroy(); -             -            return true; -        } -         -        function get_session_fingerprint() -        { -        	global $CONFIG; -        	 -        	return md5($_SERVER['HTTP_USER_AGENT'] . get_site_secret()); -        } -		 -	/** -	 * Initialises the system session and potentially logs the user in -	 *  -	 * This function looks for: -	 *  -	 * 1. $_SESSION['id'] - if not present, we're logged out, and this is set to 0 -	 * 2. The cookie 'elggperm' - if present, checks it for an authentication token, validates it, and potentially logs the user in  -	 * -	 * @uses $_SESSION -	 * @param unknown_type $event -	 * @param unknown_type $object_type -	 * @param unknown_type $object -	 */ -		function session_init($event, $object_type, $object) { -			 -			global $DB_PREFIX, $CONFIG; -			 -			if (!is_db_installed()) return false; -			 -			// Use database for sessions -			$DB_PREFIX = $CONFIG->dbprefix; // HACK to allow access to prefix after object distruction -			if ((!isset($CONFIG->use_file_sessions))) -				session_set_save_handler("__elgg_session_open", "__elgg_session_close", "__elgg_session_read", "__elgg_session_write", "__elgg_session_destroy", "__elgg_session_gc"); -				 -			session_name('Elgg'); -	        session_start(); -	         -	        // Do some sanity checking by generating a fingerprint (makes some XSS attacks harder) -	        if (isset($_SESSION['__elgg_fingerprint'])) -			{ -			    if ($_SESSION['__elgg_fingerprint'] != get_session_fingerprint()) -			    { -			    	session_destroy(); -			    	return false; -			    } -			} -			else -			{ -			    $_SESSION['__elgg_fingerprint'] = get_session_fingerprint(); -			} -			 -			// Generate a simple token (private from potentially public session id) -			if (!isset($_SESSION['__elgg_session'])) $_SESSION['__elgg_session'] = md5(microtime().rand()); -	         -	        if (empty($_SESSION['guid'])) { -	            if (isset($_COOKIE['elggperm'])) {             -	                $code = $_COOKIE['elggperm']; -	                $code = md5($code); -	                unset($_SESSION['guid']);//$_SESSION['guid'] = 0; -	                unset($_SESSION['id']);//$_SESSION['id'] = 0; -	                if ($user = get_user_by_code($code)) { -                    	$_SESSION['user'] = $user; -                        $_SESSION['id'] = $user->getGUID(); -                        $_SESSION['guid'] = $_SESSION['id']; -                        $_SESSION['code'] = $_COOKIE['elggperm']; -	                } -	            } else { -	            	unset($_SESSION['id']); //$_SESSION['id'] = 0; -	                unset($_SESSION['guid']);//$_SESSION['guid'] = 0; -	                unset($_SESSION['code']);//$_SESSION['code'] = ""; -	            } -	        } else { -	            if (!empty($_SESSION['code'])) { -	                $code = md5($_SESSION['code']); -	                if ($user = get_user_by_code($code)) { -	                	$_SESSION['user'] = $user; -	                	$_SESSION['id'] = $user->getGUID(); -                        $_SESSION['guid'] = $_SESSION['id']; -	                } else { -	                	unset($_SESSION['user']); -	                	unset($_SESSION['id']); //$_SESSION['id'] = 0; -		                unset($_SESSION['guid']);//$_SESSION['guid'] = 0; -		                unset($_SESSION['code']);//$_SESSION['code'] = ""; -	                } -	            } else { -	            	//$_SESSION['user'] = new ElggDummy(); -	            	unset($_SESSION['id']); //$_SESSION['id'] = 0; -	                unset($_SESSION['guid']);//$_SESSION['guid'] = 0; -	                unset($_SESSION['code']);//$_SESSION['code'] = ""; -	            } -	        } -	        if ($_SESSION['id'] > 0) { -	            set_last_action($_SESSION['id']); -	        } -	         -	        register_action("login",true); -    		register_action("logout"); -    		 -    		// Register a default PAM handler -    		register_pam_handler('pam_auth_userpass'); -    		 -    		// Initialise the magic session -    		global $SESSION; -    		$SESSION = new ElggSession(); -    		 -    		// Finally we ensure that a user who has been banned with an open session is kicked. -    		if ((isset($_SESSION['user'])) && ($_SESSION['user']->isBanned())) -    		{ -    			session_destroy(); -			    return false; -    		} -    		 -    		// Since we have loaded a new user, this user may have different language preferences -    		register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/"); -    		 -    		return true; -	         +		$_SESSION['user']->code = ""; +		$_SESSION['user']->save(); +	} + +	unset($_SESSION['username']); +	unset($_SESSION['name']); +	unset($_SESSION['code']); +	unset($_SESSION['guid']); +	unset($_SESSION['id']); +	unset($_SESSION['user']); + +	setcookie("elggperm", "", (time()-(86400 * 30)),"/"); + +	session_destroy(); + +	return true; +} + +/** + * Returns a fingerprint for an elgg session. + * + * @return string + */ +function get_session_fingerprint() { +	global $CONFIG; + +	return md5($_SERVER['HTTP_USER_AGENT'] . get_site_secret()); +} + +/** + * Initialises the system session and potentially logs the user in + * + * This function looks for: + * + * 1. $_SESSION['id'] - if not present, we're logged out, and this is set to 0 + * 2. The cookie 'elggperm' - if present, checks it for an authentication token, validates it, and potentially logs the user in + * + * @uses $_SESSION + * @param unknown_type $event + * @param unknown_type $object_type + * @param unknown_type $object + */ +function session_init($event, $object_type, $object) { +	global $DB_PREFIX, $CONFIG; + +	if (!is_db_installed()) { +		return false; +	} + +	// Use database for sessions +	// HACK to allow access to prefix after object destruction +	$DB_PREFIX = $CONFIG->dbprefix; +	if ((!isset($CONFIG->use_file_sessions))) { +		session_set_save_handler("__elgg_session_open", +			"__elgg_session_close", +			"__elgg_session_read", +			"__elgg_session_write", +			"__elgg_session_destroy", +			"__elgg_session_gc"); +	} + +	session_name('Elgg'); +	session_start(); + +	// Do some sanity checking by generating a fingerprint (makes some XSS attacks harder) +	if (isset($_SESSION['__elgg_fingerprint'])) { +		if ($_SESSION['__elgg_fingerprint'] != get_session_fingerprint()) { +			session_destroy(); +			return false;  		} -		 -	/** -	 * Used at the top of a page to mark it as logged in users only. -	 * -	 */ -		function gatekeeper() { -			if (!isloggedin()) { -				$_SESSION['last_forward_from'] = current_page_url(); -				forward(); +	} else { +		$_SESSION['__elgg_fingerprint'] = get_session_fingerprint(); +	} + +	// Generate a simple token (private from potentially public session id) +	if (!isset($_SESSION['__elgg_session'])) { +		$_SESSION['__elgg_session'] = md5(microtime().rand()); +	} + +	if (empty($_SESSION['guid'])) { +		if (isset($_COOKIE['elggperm'])) { +			$code = $_COOKIE['elggperm']; +			$code = md5($code); +			unset($_SESSION['guid']);//$_SESSION['guid'] = 0; +			unset($_SESSION['id']);//$_SESSION['id'] = 0; +			if ($user = get_user_by_code($code)) { +				$_SESSION['user'] = $user; +				$_SESSION['id'] = $user->getGUID(); +				$_SESSION['guid'] = $_SESSION['id']; +				$_SESSION['code'] = $_COOKIE['elggperm'];  			} +		} else { +			unset($_SESSION['id']); //$_SESSION['id'] = 0; +			unset($_SESSION['guid']);//$_SESSION['guid'] = 0; +			unset($_SESSION['code']);//$_SESSION['code'] = "";  		} -		 -		/** -		 * Used at the top of a page to mark it as logged in admin or siteadmin only. -		 * -		 */ -		function admin_gatekeeper() -		{ -			gatekeeper(); -			if (!isadminloggedin()) { -				$_SESSION['last_forward_from'] = current_page_url(); -				forward(); +	} else { +		if (!empty($_SESSION['code'])) { +			$code = md5($_SESSION['code']); +			if ($user = get_user_by_code($code)) { +				$_SESSION['user'] = $user; +				$_SESSION['id'] = $user->getGUID(); +						$_SESSION['guid'] = $_SESSION['id']; +			} else { +				unset($_SESSION['user']); +				unset($_SESSION['id']); //$_SESSION['id'] = 0; +				unset($_SESSION['guid']);//$_SESSION['guid'] = 0; +				unset($_SESSION['code']);//$_SESSION['code'] = "";  			} +		} else { +			//$_SESSION['user'] = new ElggDummy(); +			unset($_SESSION['id']); //$_SESSION['id'] = 0; +			unset($_SESSION['guid']);//$_SESSION['guid'] = 0; +			unset($_SESSION['code']);//$_SESSION['code'] = "";  		} -		 -		/** -		 * DB Based session handling code. -		 */ -		function __elgg_session_open($save_path, $session_name) -		{ -			global $sess_save_path; -			$sess_save_path = $save_path; -			 -			return true; +	} + +	if ($_SESSION['id'] > 0) { +		set_last_action($_SESSION['id']); +	} + +	register_action("login",true); +	register_action("logout"); + +	// Register a default PAM handler +	register_pam_handler('pam_auth_userpass'); + +	// Initialise the magic session +	global $SESSION; +	$SESSION = new ElggSession(); + +	// Finally we ensure that a user who has been banned with an open session is kicked. +	if ((isset($_SESSION['user'])) && ($_SESSION['user']->isBanned())) { +		session_destroy(); +		return false; +	} + +	// Since we have loaded a new user, this user may have different language preferences +	register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/"); + +	return true; +} + +/** + * Used at the top of a page to mark it as logged in users only. + * + */ +function gatekeeper() { +	if (!isloggedin()) { +		$_SESSION['last_forward_from'] = current_page_url(); +		forward(); +	} +} + +/** + * Used at the top of a page to mark it as logged in admin or siteadmin only. + * + */ +function admin_gatekeeper() { +	gatekeeper(); + +	if (!isadminloggedin()) { +		$_SESSION['last_forward_from'] = current_page_url(); +		forward(); +	} +} + +/** + * DB Based session handling code. + */ +function __elgg_session_open($save_path, $session_name) { +	global $sess_save_path; +	$sess_save_path = $save_path; + +	return true; +} + +/** + * DB Based session handling code. + */ +function __elgg_session_close() { +	return true; +} + +/** + * DB Based session handling code. + */ +function __elgg_session_read($id) { +	global $DB_PREFIX; + +	$id = sanitise_string($id); + +	try { +		$result = get_data_row("SELECT * from {$DB_PREFIX}users_sessions where session='$id'"); + +		if ($result) { +			return (string)$result->data;  		} -		 -		/** -		 * DB Based session handling code. -		 */ -		function __elgg_session_close() -		{ + +	} catch (DatabaseException $e) { + +		// Fall back to file store in this case, since this likely means +		// that the database hasn't been upgraded +		global $sess_save_path; + +		$sess_file = "$sess_save_path/sess_$id"; +		return (string) @file_get_contents($sess_file); +	} + +	return ''; +} + +/** + * DB Based session handling code. + */ +function __elgg_session_write($id, $sess_data) { +	global $DB_PREFIX; + +	$id = sanitise_string($id); +	$time = time(); + +	try { +		$sess_data_sanitised = sanitise_string($sess_data); + +		$q = "REPLACE INTO {$DB_PREFIX}users_sessions +			(session, ts, data) VALUES +			('$id', '$time', '$sess_data_sanitised')"; + +		if (insert_data($q)!==false) {  			return true;  		} -		 -		/** -		 * DB Based session handling code. -		 */ -		function __elgg_session_read($id) -		{ -			global $DB_PREFIX; -			 -			$id = sanitise_string($id); -			 -			try {		 -				$result = get_data_row("SELECT * from {$DB_PREFIX}users_sessions where session='$id'");			 -				 -				if ($result) -					return (string)$result->data; -					 -			} catch (DatabaseException $e) { -				 -				// Fall back to file store in this case, since this likely means that the database hasn't been upgraded -				global $sess_save_path; - -				$sess_file = "$sess_save_path/sess_$id";			 -				return (string) @file_get_contents($sess_file); -			} -				 -			return ''; -		} -		 -		/** -		 * DB Based session handling code. -		 */ -		function __elgg_session_write($id, $sess_data) -		{ -			global $DB_PREFIX; -			 -			$id = sanitise_string($id);			 -			$time = time(); -			 -			try { -				$sess_data_sanitised = sanitise_string($sess_data); +	} catch (DatabaseException $e) { +		// Fall back to file store in this case, since this likely means +		// that the database hasn't been upgraded +		global $sess_save_path; -				if (insert_data("REPLACE INTO {$DB_PREFIX}users_sessions (session, ts, data) VALUES ('$id', '$time', '$sess_data_sanitised')")!==false) -					return true; -					 -			} catch (DatabaseException $e) { -				// Fall back to file store in this case, since this likely means that the database hasn't been upgraded -				global $sess_save_path; - -  				$sess_file = "$sess_save_path/sess_$id"; -  				if ($fp = @fopen($sess_file, "w")) { -    				$return = fwrite($fp, $sess_data); -    				fclose($fp); -    				return $return; -  				} -  				 -			} -			 -			return false; -		} -		 -		/** -		 * DB Based session handling code. -		 */ -		function __elgg_session_destroy($id) -		{ -			global $DB_PREFIX; -			 -			$id = sanitise_string($id); - -			try {		 -				return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where session='$id'"); -			} catch (DatabaseException $e) { -				// Fall back to file store in this case, since this likely means that the database hasn't been upgraded -				global $sess_save_path; - -				$sess_file = "$sess_save_path/sess_$id"; -				return(@unlink($sess_file)); -			} -			 -			return false; +		$sess_file = "$sess_save_path/sess_$id"; +		if ($fp = @fopen($sess_file, "w")) { +			$return = fwrite($fp, $sess_data); +			fclose($fp); +			return $return;  		} -		 -		/** -		 * DB Based session handling code. -		 */ -		function __elgg_session_gc($maxlifetime) -		{ -			global $DB_PREFIX; -			 -			$life = time()-$maxlifetime; - -			try { -				return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where ts<'$life'"); -			} catch (DatabaseException $e) { -				// Fall back to file store in this case, since this likely means that the database hasn't been upgraded -				global $sess_save_path; - -				foreach (glob("$sess_save_path/sess_*") as $filename) { -					if (filemtime($filename) < $life) { -						@unlink($filename); -					} -				} +	} + +	return false; +} + +/** + * DB Based session handling code. + */ +function __elgg_session_destroy($id) { +	global $DB_PREFIX; + +	$id = sanitise_string($id); + +	try { +		return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where session='$id'"); +	} catch (DatabaseException $e) { +		// Fall back to file store in this case, since this likely means that +		// the database hasn't been upgraded +		global $sess_save_path; + +		$sess_file = "$sess_save_path/sess_$id"; +		return(@unlink($sess_file)); +	} + +	return false; +} + +/** + * DB Based session handling code. + */ +function __elgg_session_gc($maxlifetime) { +	global $DB_PREFIX; + +	$life = time()-$maxlifetime; + +	try { +		return (bool)delete_data("DELETE from {$DB_PREFIX}users_sessions where ts<'$life'"); +	} catch (DatabaseException $e) { +		// Fall back to file store in this case, since this likely means that the database hasn't been upgraded +		global $sess_save_path; + +		foreach (glob("$sess_save_path/sess_*") as $filename) { +			if (filemtime($filename) < $life) { +				@unlink($filename);  			} -			 -			return true;  		} -		 -		register_elgg_event_handler("boot","system","session_init",20); +	} +	return true; +} -?>
\ No newline at end of file +register_elgg_event_handler("boot","system","session_init",20);
\ No newline at end of file  | 
