From 4945d1fb9856d92ab4dd9a0f65a11928f65f9b28 Mon Sep 17 00:00:00 2001
From: xue <>
Date: Thu, 18 May 2006 18:12:39 +0000
Subject: Merge from 3.0 branch till 1079.

---
 .gitattributes                                    |   2 +
 HISTORY                                           |   2 +
 demos/quickstart/protected/controls/Layout.php    |   2 +-
 demos/quickstart/protected/controls/TopicList.tpl |   1 +
 framework/Security/IUserManager.php               |  46 ++++++
 framework/Security/TAuthManager.php               |  22 +--
 framework/Security/TUser.php                      | 169 ++++++++++++++++++++++
 framework/Security/TUserManager.php               | 158 +-------------------
 framework/Web/Javascripts/js/clientscripts.php    |  38 +++--
 framework/Web/UI/TClientScriptManager.php         |   2 +-
 10 files changed, 260 insertions(+), 182 deletions(-)
 create mode 100644 framework/Security/IUserManager.php
 create mode 100644 framework/Security/TUser.php

diff --git a/.gitattributes b/.gitattributes
index ac044898..0c224241 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -841,10 +841,12 @@ framework/I18N/schema/sqlite.sql -text
 framework/IO/TTarFileExtractor.php -text
 framework/IO/TTextWriter.php -text
 framework/PradoBase.php -text
+framework/Security/IUserManager.php -text
 framework/Security/TAuthManager.php -text
 framework/Security/TAuthorizationRule.php -text
 framework/Security/TMembershipManager.php -text
 framework/Security/TSecurityManager.php -text
+framework/Security/TUser.php -text
 framework/Security/TUserManager.php -text
 framework/TApplication.php -text
 framework/TApplicationComponent.php -text
diff --git a/HISTORY b/HISTORY
index 5e4bcd94..ce8eda36 100644
--- a/HISTORY
+++ b/HISTORY
@@ -11,6 +11,7 @@ Version 3.0.1 June 1, 2006
 ==========================
 BUG: Ticket#44 - THtmlArea (tiny_mce) not working on some systems (Qiang)
 BUG: Ticket#167 - TSecurityManager issues warning when trying to encrypt/decrypt strings (Qiang)
+BUG: Ticket#179 - CGI incompatibility causing clientscripts.php failure (Qiang)
 ENH: Ticket#150 - TDataGrid and TDataList now render table section tags (Qiang)
 ENH: Ticket#152 - constituent parts of TWizard are exposed (Qiang)
 ENH: added sanity check to calling event handlers (Qiang)
@@ -18,6 +19,7 @@ ENH: added search for quickstart tutorials (Wei)
 ENH: added support to property tags for template owner control (Qiang)
 ENH: added Bulgarian requirement checker messages (StanProg)
 ENH: added TTheme.BaseUrl and TTheme.BasePath property (Qiang)
+ENH: refactored TUserManager and TAuthManager so that they are easier to be extended (Qiang)
 CHG: Ticket#151 - URL format is modified to handle empty GET values (Qiang)
 CHG: Ticket#153 - TAssetManager now ignores .svn directories (Qiang)
 NEW: TTableHeaderRow, TTableFooterRow and table section support (Qiang)
diff --git a/demos/quickstart/protected/controls/Layout.php b/demos/quickstart/protected/controls/Layout.php
index d58cabfa..7c2cbd85 100644
--- a/demos/quickstart/protected/controls/Layout.php
+++ b/demos/quickstart/protected/controls/Layout.php
@@ -16,7 +16,7 @@ class Layout extends TTemplateControl
 		if(strpos($url,'?')===false)
 			$url.='?notheme=true';
 		else
-			$url.='&notheme=true';
+			$url.='&amp;notheme=true';
 		$this->PrinterLink->NavigateUrl=$url;
 
 		if(isset($this->Request['notheme']))
diff --git a/demos/quickstart/protected/controls/TopicList.tpl b/demos/quickstart/protected/controls/TopicList.tpl
index 5ffc7098..f26b75a6 100644
--- a/demos/quickstart/protected/controls/TopicList.tpl
+++ b/demos/quickstart/protected/controls/TopicList.tpl
@@ -64,6 +64,7 @@
 <div class="topic">
 <div>Avanced Topics</div>
 <ul>
+	<li><a href="?page=Advanced.Collections">Collections</a></li>
     <li><a href="?page=Advanced.Auth">Authentication and Authorization</a></li>
     <li><a href="?page=Advanced.Security">Security</a></li>
     <li><a href="?page=Advanced.Scripts">Client-side Scripting</a></li>
diff --git a/framework/Security/IUserManager.php b/framework/Security/IUserManager.php
new file mode 100644
index 00000000..b1a6b67c
--- /dev/null
+++ b/framework/Security/IUserManager.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * IUserManager interface file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $  $Date: $
+ * @package System.Security
+ */
+
+/**
+ * IUserManager interface
+ *
+ * IUserManager specifies the interface that must be implemented by
+ * a user manager class if it is to be used together with {@link TAuthManager}
+ * and {@link TUser}.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $  $Date: $
+ * @package System.Security
+ * @since 3.0
+ */
+interface IUserManager
+{
+	/**
+	 * @return string name for a guest user.
+	 */
+	public function getGuestName();
+	/**
+	 * Returns a user instance given the user name.
+	 * @param string user name, null if it is a guest.
+	 * @return TUser the user instance, null if the specified username is not in the user database.
+	 */
+	public function getUser($username=null);
+	/**
+	 * Validates if the username and password are correct.
+	 * @param string user name
+	 * @param string password
+	 * @return boolean true if validation is successful, false otherwise.
+	 */
+	public function validateUser($username,$password);
+}
+
+?>
\ No newline at end of file
diff --git a/framework/Security/TAuthManager.php b/framework/Security/TAuthManager.php
index b4856ee5..ee01d5f3 100644
--- a/framework/Security/TAuthManager.php
+++ b/framework/Security/TAuthManager.php
@@ -11,15 +11,15 @@
  */
 
 /**
- * Using TUserManager class
+ * Using IUserManager interface
  */
-Prado::using('System.Security.TUserManager');
+Prado::using('System.Security.IUserManager');
 
 /**
  * TAuthManager class
  *
  * TAuthManager performs user authentication and authorization for a Prado application.
- * TAuthManager works together with a {@link TUserManager} module that can be
+ * TAuthManager works together with a {@link IUserManager} module that can be
  * specified via the {@link setUserManager UserManager} property.
  * If an authorization fails, TAuthManager will try to redirect the client
  * browser to a login page that is specified via the {@link setLoginPage LoginPage}.
@@ -45,7 +45,7 @@ class TAuthManager extends TModule
 	 */
 	private $_initialized=false;
 	/**
-	 * @var TUserManager user manager instance
+	 * @var IUserManager user manager instance
 	 */
 	private $_userManager=null;
 	/**
@@ -61,7 +61,7 @@ class TAuthManager extends TModule
 	 * Initializes this module.
 	 * This method is required by the IModule interface.
 	 * @param TXmlElement configuration for this module, can be null
-	 * @throws TConfigurationException if user manager does not exist or is not TUserManager
+	 * @throws TConfigurationException if user manager does not exist or is not IUserManager
 	 */
 	public function init($config)
 	{
@@ -72,7 +72,7 @@ class TAuthManager extends TModule
 		{
 			if(($users=$application->getModule($this->_userManager))===null)
 				throw new TConfigurationException('authmanager_usermanager_inexistent',$this->_userManager);
-			if(!($users instanceof TUserManager))
+			if(!($users instanceof IUserManager))
 				throw new TConfigurationException('authmanager_usermanager_invalid',$this->_userManager);
 			$this->_userManager=$users;
 		}
@@ -83,7 +83,7 @@ class TAuthManager extends TModule
 	}
 
 	/**
-	 * @return TUserManager user manager instance
+	 * @return IUserManager user manager instance
 	 */
 	public function getUserManager()
 	{
@@ -91,14 +91,14 @@ class TAuthManager extends TModule
 	}
 
 	/**
-	 * @param string|TUserManager the user manager module ID or the user mananger object
-	 * @throws TInvalidOperationException if the module has been initialized or the user manager object is not TUserManager
+	 * @param string|IUserManager the user manager module ID or the user mananger object
+	 * @throws TInvalidOperationException if the module has been initialized or the user manager object is not IUserManager
 	 */
 	public function setUserManager($provider)
 	{
 		if($this->_initialized)
 			throw new TInvalidOperationException('authmanager_usermanager_unchangeable');
-		if(!is_string($provider) && !($provider instanceof TUserManager))
+		if(!is_string($provider) && !($provider instanceof IUserManager))
 			throw new TConfigurationException('authmanager_usermanager_invalid',$this->_userManager);
 		$this->_userManager=$provider;
 	}
@@ -283,7 +283,7 @@ class TAuthManager extends TModule
 			throw new TConfigurationException('authmanager_session_required');
 		else
 		{
-			$this->_userManager->switchToGuest($this->getUser());
+			$this->getUser()->setIsGuest(true);
 			$session->destroy();
 		}
 	}
diff --git a/framework/Security/TUser.php b/framework/Security/TUser.php
new file mode 100644
index 00000000..7b785add
--- /dev/null
+++ b/framework/Security/TUser.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * TUser class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $  $Date: $
+ * @package System.Security
+ */
+
+/**
+ * Using IUserManager interface
+ */
+Prado::using('System.Security.IUserManager');
+
+/**
+ * TUser class
+ *
+ * TUser implements basic user functionality for a prado application.
+ * To get the name of the user, use {@link getName Name} property.
+ * The property {@link getIsGuest IsGuest} tells if the user a guest/anonymous user.
+ * To obtain or test the roles that the user is in, use property
+ * {@link getRoles Roles} and call {@link isInRole()}, respectively.
+ *
+ * TUser is meant to be used together with {@link IUserManager}.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $  $Date: $
+ * @package System.Security
+ * @since 3.0
+ */
+class TUser extends TComponent implements IUser
+{
+	/**
+	 * @var IUserManager user manager
+	 */
+	private $_manager;
+	/**
+	 * @var boolean if the user is a guest
+	 */
+	private $_isGuest=true;
+	/**
+	 * @var string username
+	 */
+	private $_name='';
+	/**
+	 * @var array user roles
+	 */
+	private $_roles=array();
+
+	/**
+	 * Constructor.
+	 * @param IUserManager user manager
+	 */
+	public function __construct(IUserManager $manager)
+	{
+		$this->_manager=$manager;
+	}
+
+	/**
+	 * @return IUserManager user manager
+	 */
+	public function getManager()
+	{
+		return $this->_manager;
+	}
+
+	/**
+	 * @return string username
+	 */
+	public function getName()
+	{
+		return $this->_name;
+	}
+
+	/**
+	 * @param string username
+	 */
+	public function setName($value)
+	{
+		$this->_name=$value;
+	}
+
+	/**
+	 * @return boolean if the user is a guest
+	 */
+	public function getIsGuest()
+	{
+		return $this->_isGuest;
+	}
+
+	/**
+	 * @param boolean if the user is a guest
+	 */
+	public function setIsGuest($value)
+	{
+		if($this->_isGuest=TPropertyValue::ensureBoolean($value))
+		{
+			$this->_name=$this->_manager->getGuestName();
+			$this->_roles=array();
+		}
+	}
+
+	/**
+	 * @return array list of roles that the user is of
+	 */
+	public function getRoles()
+	{
+		return $this->_roles;
+	}
+
+	/**
+	 * @return array|string list of roles that the user is of. If it is a string, roles are assumed by separated by comma
+	 */
+	public function setRoles($value)
+	{
+		if(is_array($value))
+			$this->_roles=$value;
+		else
+		{
+			$this->_roles=array();
+			foreach(explode(',',$value) as $role)
+			{
+				if(($role=trim($role))!=='')
+					$this->_roles[]=$role;
+			}
+		}
+	}
+
+	/**
+	 * @param string role to be tested. Note, role is case-insensitive.
+	 * @return boolean whether the user is of this role
+	 */
+	public function isInRole($role)
+	{
+		foreach($this->_roles as $r)
+			if(strcasecmp($role,$r)===0)
+				return true;
+		return false;
+	}
+
+	/**
+	 * @return string user data that is serialized and will be stored in session
+	 */
+	public function saveToString()
+	{
+		return serialize(array($this->_name,$this->_roles,$this->_isGuest));
+	}
+
+	/**
+	 * @param string user data that is serialized and restored from session
+	 * @return IUser the user object
+	 */
+	public function loadFromString($data)
+	{
+		if(!empty($data))
+		{
+			$array=unserialize($data);
+			$this->_name=$array[0];
+			$this->_roles=$array[1];
+			$this->_isGuest=$array[2];
+		}
+		return $this;
+	}
+}
+
+?>
\ No newline at end of file
diff --git a/framework/Security/TUserManager.php b/framework/Security/TUserManager.php
index 5bd18d0c..45e55bd7 100644
--- a/framework/Security/TUserManager.php
+++ b/framework/Security/TUserManager.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * TUser, TUserManager class
+ * TUserManager class
  *
  * @author Qiang Xue <qiang.xue@gmail.com>
  * @link http://www.pradosoft.com/
@@ -11,157 +11,9 @@
  */
 
 /**
- * TUser class
- *
- * TUser implements basic user functionality for a prado application.
- * To get the name of the user, use {@link getName Name} property.
- * The property {@link getIsGuest IsGuest} tells if the user a guest/anonymous user.
- * To obtain or test the roles that the user is in, use property
- * {@link getRoles Roles} and call {@link isInRole()}, respectively.
- *
- * TUser is meant to be used together with {@link TUserManager} and
- * {@link TAuthManager}.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Revision: $  $Date: $
- * @package System.Security
- * @since 3.0
+ * Using TUser class
  */
-class TUser extends TComponent implements IUser
-{
-	/**
-	 * @var TUserManager user manager
-	 */
-	private $_manager;
-	/**
-	 * @var boolean if the user is a guest
-	 */
-	private $_isGuest=true;
-	/**
-	 * @var string username
-	 */
-	private $_name='';
-	/**
-	 * @var array user roles
-	 */
-	private $_roles=array();
-
-	/**
-	 * Constructor.
-	 * @param TUserManager user manager
-	 */
-	public function __construct($manager=null)
-	{
-		$this->_manager=$manager;
-	}
-
-	/**
-	 * @return TUserManager user manager
-	 */
-	public function getManager()
-	{
-		return $this->_manager;
-	}
-
-	/**
-	 * @return string username
-	 */
-	public function getName()
-	{
-		return $this->_name;
-	}
-
-	/**
-	 * @param string username
-	 */
-	public function setName($value)
-	{
-		$this->_name=$value;
-	}
-
-	/**
-	 * @return boolean if the user is a guest
-	 */
-	public function getIsGuest()
-	{
-		return $this->_isGuest;
-	}
-
-	/**
-	 * @param boolean if the user is a guest
-	 */
-	public function setIsGuest($value)
-	{
-		$this->_isGuest=TPropertyValue::ensureBoolean($value);
-		if($this->_isGuest)
-		{
-			$this->_name=$this->_manager->getGuestName();
-			$this->_roles=array();
-		}
-	}
-
-	/**
-	 * @return array list of roles that the user is of
-	 */
-	public function getRoles()
-	{
-		return $this->_roles;
-	}
-
-	/**
-	 * @return array|string list of roles that the user is of. If it is a string, roles are assumed by separated by comma
-	 */
-	public function setRoles($value)
-	{
-		if(is_array($value))
-			$this->_roles=$value;
-		else
-		{
-			$this->_roles=array();
-			foreach(explode(',',$value) as $role)
-			{
-				if(($role=trim($role))!=='')
-					$this->_roles[]=$role;
-			}
-		}
-	}
-
-	/**
-	 * @param string role to be tested. Note, role is case-insensitive.
-	 * @return boolean whether the user is of this role
-	 */
-	public function isInRole($role)
-	{
-		foreach($this->_roles as $r)
-			if(strcasecmp($role,$r)===0)
-				return true;
-		return false;
-	}
-
-	/**
-	 * @return string user data that is serialized and will be stored in session
-	 */
-	public function saveToString()
-	{
-		return serialize(array($this->_name,$this->_roles,$this->_isGuest));
-	}
-
-	/**
-	 * @param string user data that is serialized and restored from session
-	 * @return IUser the user object
-	 */
-	public function loadFromString($data)
-	{
-		if(!empty($data))
-		{
-			$array=unserialize($data);
-			$this->_name=$array[0];
-			$this->_roles=$array[1];
-			$this->_isGuest=$array[2];
-		}
-		return $this;
-	}
-}
+Prado::using('System.Security.TUser');
 
 /**
  * TUserManager class
@@ -195,7 +47,7 @@ class TUser extends TComponent implements IUser
  * @package System.Security
  * @since 3.0
  */
-class TUserManager extends TModule
+class TUserManager extends TModule implements IUserManager
 {
 	/**
 	 * extension name to the user file
@@ -379,8 +231,6 @@ class TUserManager extends TModule
 	public function switchToGuest($user)
 	{
 		$user->setIsGuest(true);
-		$user->setName($this->getGuestName());
-		$user->setRoles(array());
 	}
 }
 
diff --git a/framework/Web/Javascripts/js/clientscripts.php b/framework/Web/Javascripts/js/clientscripts.php
index 1fb14003..3ac3b062 100644
--- a/framework/Web/Javascripts/js/clientscripts.php
+++ b/framework/Web/Javascripts/js/clientscripts.php
@@ -1,15 +1,15 @@
 <?php
 /**
- * This file compresses the javascript files using GZip 
+ * This file compresses the javascript files using GZip
  *
  * Todo:
  *  - Add local file cache for the GZip:ed version.
  */
 
-if(is_int(strpos($_SERVER['REQUEST_URI'], '__nocache')))
-	$expiresOffset = -10000; //no cache
-else
-	$expiresOffset = 3600 * 24 * 10;		// 10 days util client cache expires
+$debugMode=(isset($_GET['mode']) && $_GET['mode']==='debug');
+
+// if debug mode, js is not cached; otherwise cached for 10 days.
+$expiresOffset = $debugMode ? -10000 : 3600 * 24 * 10; //no cache
 
 //allowed libraries
 $library = array('prado', 'effects', 'ajax', 'validator', 'logger', 'datepicker', 'rico', 'colorpicker');
@@ -18,7 +18,7 @@ $param = isset($_GET['js']) ? $_GET['js'] : '';
 
 //check for proper matching parameters, otherwise exit;
 if(preg_match('/(\w)+(,\w+)*/', $param)) $js = explode(',', $param); else exit();
-foreach($js as $lib) if(!in_array($lib, $library)) exit(); 
+foreach($js as $lib) if(!in_array($lib, $library)) exit();
 
 // Only gzip the contents if clients and server support it
 if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
@@ -27,8 +27,8 @@ else
 	$encodings = array();
 
 // Check for gzip header or northon internet securities
-if ((in_array('gzip', $encodings) || isset($_SERVER['---------------'])) 
-		&& function_exists('ob_gzhandler') && !ini_get('zlib.output_compression') 
+if ((in_array('gzip', $encodings) || isset($_SERVER['---------------']))
+		&& function_exists('ob_gzhandler') && !ini_get('zlib.output_compression')
 		&& ini_get('output_handler') != 'ob_gzhandler')
 	ob_start("ob_gzhandler");
 
@@ -38,16 +38,24 @@ header('Content-type: text/javascript; charset: UTF-8');
 header('Vary: Accept-Encoding'); // Handle proxies
 header('Expires: ' . @gmdate('D, d M Y H:i:s', @time() + $expiresOffset) . ' GMT');
 
-foreach($js as $lib)
+if ($debugMode)
 {
-	$file = realpath($lib.'.js');
-	if(is_file($file))
-		echo file_get_contents($file);
-	else //log missings files to console logger
+	foreach($js as $lib)
 	{
-		echo 'setTimeout(function(){ if(Logger) Logger.error("Missing file", "'.$lib.'.js"); }, 1000);';
-		error_log("Unable to find asset file {$lib}.js");
+		$file = realpath($lib.'.js');
+		if(is_file($file))
+			echo file_get_contents($file);
+		else //log missings files to console logger
+		{
+			echo 'setTimeout(function(){ if(Logger) Logger.error("Missing file", "'.$lib.'.js"); }, 1000);';
+			error_log("Unable to find asset file {$lib}.js");
+		}
 	}
 }
+else
+{
+	foreach($js as $lib)
+		echo file_get_contents($lib.'.js');
+}
 
 ?>
\ No newline at end of file
diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php
index 160ed055..3926d166 100644
--- a/framework/Web/UI/TClientScriptManager.php
+++ b/framework/Web/UI/TClientScriptManager.php
@@ -159,7 +159,7 @@ class TClientScriptManager extends TApplicationComponent
 			$scriptLoader=$basePath.'/'.self::SCRIPT_LOADER;
 			$url=$this->publishFilePath($scriptLoader).'?js='.trim($files,',');
 			if($this->getApplication()->getMode()===TApplication::STATE_DEBUG)
-				$url.='&__nocache';
+				$url.='&amp;mode=debug';
 			$writer->write(TJavaScript::renderScriptFile($url));
 		}
 	}
-- 
cgit v1.2.3