diff options
-rw-r--r-- | .gitattributes | 1 | ||||
-rw-r--r-- | COPYRIGHT | 2 | ||||
-rw-r--r-- | HISTORY | 1 | ||||
-rw-r--r-- | demos/quickstart/protected/pages/Advanced/Auth.page | 28 | ||||
-rw-r--r-- | demos/quickstart/protected/pages/GettingStarted/Introduction.page | 7 | ||||
-rw-r--r-- | demos/quickstart/protected/pages/GettingStarted/NewFeatures.page | 2 | ||||
-rw-r--r-- | framework/Data/TDataSourceConfig.php | 8 | ||||
-rw-r--r-- | framework/Security/TDbUserManager.php | 255 |
8 files changed, 298 insertions, 6 deletions
diff --git a/.gitattributes b/.gitattributes index 35538c44..74d07fd3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1890,6 +1890,7 @@ framework/PradoBase.php -text framework/Security/IUserManager.php -text framework/Security/TAuthManager.php -text framework/Security/TAuthorizationRule.php -text +framework/Security/TDbUserManager.php -text framework/Security/TSecurityManager.php -text framework/Security/TUser.php -text framework/Security/TUserManager.php -text @@ -1,7 +1,7 @@ The PRADO framework and the included demos are freeware.
They are released under the terms of the following BSD License.
-Copyright 2004-2006, The PRADO Group (http://www.pradosoft.com)
+Copyright 2004-2007, The PRADO Group (http://www.pradosoft.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -22,6 +22,7 @@ ENH: Improved exception display with hyperlinked keywords (Qiang) ENH: Improved exception display about template syntax error (Qiang) NEW: TShellApplication (Qiang) NEW: TDbCache (Qiang) +NEW: TDbUserManager and TDbUser (Qiang) NEW: Active Record driver for IBM DB2 (Cesar Ramos) Version 3.1.0 alpha January 15, 2007 diff --git a/demos/quickstart/protected/pages/Advanced/Auth.page b/demos/quickstart/protected/pages/Advanced/Auth.page index 2c335f88..c8380901 100644 --- a/demos/quickstart/protected/pages/Advanced/Auth.page +++ b/demos/quickstart/protected/pages/Advanced/Auth.page @@ -89,4 +89,32 @@ We have seen in the above example that two users are specified in the applicatio <p id="720562" class="block-content">
where the <tt>roles</tt> attribute in <tt>user</tt> element is optional. User roles can be specified in either the <tt>user</tt> element or in a separate <tt>role</tt> element.
</p>
+
+<h2 id="5505">Using <tt>TDbUserManager</tt></h2>
+<p id="720563" class="block-content">
+<tt>TDbUserManager</tt> is introduced in v3.1.0. Its main purpose is to simplify the task of managing user accounts that are stored in a database. It requires developers to write a user class that represents the necessary information for a user account. The user class must extend from <tt>TDbUser</tt>.
+</p>
+<p id="720564" class="block-content">
+To use <tt>TDbUserManager</tt>, configure it in the application configuration like following:
+</p>
+<com:TTextHighlighter Language="xml" CssClass="source block-content" id="code4">
+<module id="db"
+ class="System.Data.TDataSourceConfig" ..../>
+<module id="users"
+ class="System.Security.TDbUserManager"
+ UserClass="Path.To.MyUserClass"
+ ConnectionID="db" />
+<module id="auth"
+ class="System.Security.TAuthManager"
+ UserManager="users" LoginPage="Path.To.LoginPage" />
+</com:TTextHighlighter>
+
+</p>
+<p id="720565" class="block-content">
+In the above, <tt>UserClass</tt> specifies what class will be used to create user instance. The class must extend from <tt>TDbUser</tt>. <tt>ConnectionID</tt> refers to the ID of a <tt>TDataSourceConfig</tt> module which specifies how to establish database connection to retrieve user information.
+</p>
+<p id="720566" class="block-content">
+The user class has to implement the two abstract methods in <tt>TDbUser</tt>: <tt>validateUser()</tt> and <tt>createUser()</tt>. Since user account information is stored in a database, the user class may make use of its <tt>DbConnection</tt> property to reach the database.
+</p>
+
<div class="last-modified">$Id$</div></com:TContent>
\ No newline at end of file diff --git a/demos/quickstart/protected/pages/GettingStarted/Introduction.page b/demos/quickstart/protected/pages/GettingStarted/Introduction.page index 0871921a..e48360d6 100644 --- a/demos/quickstart/protected/pages/GettingStarted/Introduction.page +++ b/demos/quickstart/protected/pages/GettingStarted/Introduction.page @@ -4,12 +4,15 @@ <p id="10001">
This Quickstart tutorial is provided to help you quickly start building your own Web applications based on PRADO version 3.x.
</p>
+<p>
+If you are an existing PRADO 3.x user and would like to learn what enhancements are available for each new version, please check out the <a href="?page=GettingStarted.NewFeatures">new features</a> page. Otherwise, the following sections are helpful for newbies.
+</p>
<div class="start-page">
<div class="concepts start-block">
- <h2>How Prado Works</h2>
+ <h2>How PRADO Works</h2>
<p>Concepts and fundamentals</p>
<ol>
- <li><a href="#">Building web applications with Prado</a></li>
+ <li><a href="#">Building web applications with PRADO</a></li>
<li><a href="#">Web controls and events</a></li>
<li><a href="#">Validating user input</a></li>
<li><a href="#">Connecting to your database</a></li>
diff --git a/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page b/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page index cfbb3e8e..4aff6d47 100644 --- a/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page +++ b/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page @@ -19,6 +19,8 @@ This page summarizes the main new features that are introduced in each PRADO rel <li>Added support to allow <a href="?page=Configurations.AppConfig">including external application configurations</a>. Enhanced template syntax to facilitate <a href="?page=Configurations.Templates1">subproperty configuration</a>.</li>
+<li>Added TDbUserManager and TDbUser to simplify <a href="?page=Advanced.Auth">authentication and authorization</a> with user accounts stored in a database.</li>
+
</ul>
<div class="last-modified">$Id$</div>
diff --git a/framework/Data/TDataSourceConfig.php b/framework/Data/TDataSourceConfig.php index 93857b16..df444e97 100644 --- a/framework/Data/TDataSourceConfig.php +++ b/framework/Data/TDataSourceConfig.php @@ -10,6 +10,8 @@ * @package System.Data
*/
+Prado::using('System.Data.TDbConnection');
+
/**
* TDataSourceConfig module class provides <module> configuration for database connections.
*
@@ -46,7 +48,7 @@ */
class TDataSourceConfig extends TModule
{
- private $_connID;
+ private $_connID='';
private $_conn;
private $_connClass='System.Data.TDbConnection';
@@ -91,9 +93,9 @@ class TDataSourceConfig extends TModule */
public function getDbConnection()
{
- if(is_null($this->_conn))
+ if($this->_conn===null)
{
- if(!is_null($this->_connID))
+ if($this->_connID!=='')
$this->_conn = $this->findConnectionByID($this->getConnectionID());
else
$this->_conn = Prado::createComponent($this->getConnectionClass());
diff --git a/framework/Security/TDbUserManager.php b/framework/Security/TDbUserManager.php new file mode 100644 index 00000000..587fe0db --- /dev/null +++ b/framework/Security/TDbUserManager.php @@ -0,0 +1,255 @@ +<?php
+/**
+ * TDbUserManager class
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright © 2005-2007 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id: $
+ * @package System.Security
+ */
+
+/**
+ * Using IUserManager interface
+ */
+Prado::using('System.Security.IUserManager');
+Prado::using('System.Data.TDataSourceConfig');
+Prado::using('System.Security.TUser');
+
+/**
+ * TDbUserManager class
+ *
+ * TDbUserManager manages user accounts that are stored in a database.
+ * TDbUserManager is mainly designed to be used together with {@link TAuthManager}
+ * which manages how users are authenticated and authorized in a Prado application.
+ *
+ * To use TDbUserManager together with TAuthManager, configure them in
+ * the application configuration like following:
+ * <code>
+ * <module id="db"
+ * class="System.Data.TDataSourceConfig" ..../>
+ * <module id="users"
+ * class="System.Security.TDbUserManager"
+ * UserClass="Path.To.MyUserClass"
+ * ConnectionID="db" />
+ * <module id="auth"
+ * class="System.Security.TAuthManager"
+ * UserManager="users" LoginPage="Path.To.LoginPage" />
+ * </code>
+ *
+ * In the above, {@link setUserClass UserClass} specifies what class will be used
+ * to create user instance. The class must extend from {@link TDbUser}.
+ * {@link setConnectionID ConnectionID} refers to the ID of a {@link TDataSourceConfig} module
+ * which specifies how to establish database connection to retrieve user information.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: $
+ * @package System.Security
+ * @since 3.1.0
+ */
+class TDbUserManager extends TModule implements IUserManager
+{
+ private $_connID='';
+ private $_conn;
+ private $_guestName='Guest';
+ private $_userClass='';
+ private $_userFactory;
+
+ /**
+ * Initializes the module.
+ * This method is required by IModule and is invoked by application.
+ * @param TXmlElement module configuration
+ */
+ public function init($config)
+ {
+ if($this->_userClass==='')
+ throw new TConfigurationException('dbusermanager_userclass_required');
+ $this->_userFactory=Prado::createComponent($this->_userClass,$this);
+ if(!($this->_userFactory instanceof TDbUser))
+ throw new TInvalidDataTypeException('dbusermanager_userclass_invalid',$this->_userClass);
+ }
+
+ /**
+ * @return string the user class name in namespace format. Defaults to empty string, meaning not set.
+ */
+ public function getUserClass()
+ {
+ return $this->_userClass;
+ }
+
+ /**
+ * @param string the user class name in namespace format. The user class must extend from {@link TDbUser}.
+ */
+ public function setUserClass($value)
+ {
+ $this->_userClass=$value;
+ }
+
+ /**
+ * @return string guest name, defaults to 'Guest'
+ */
+ public function getGuestName()
+ {
+ return $this->_guestName;
+ }
+
+ /**
+ * @param string name to be used for guest users.
+ */
+ public function setGuestName($value)
+ {
+ $this->_guestName=$value;
+ }
+
+ /**
+ * 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)
+ {
+ return $this->_userFactory->validateUser($username,$password);
+ }
+
+ /**
+ * 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)
+ {
+ if($username===null)
+ {
+ $user=Prado::createComponent($this->_userClass,$this);
+ $user->setIsGuest(true);
+ return $user;
+ }
+ else
+ return $this->_userFactory->createUser($username);
+ }
+
+ /**
+ * @return string the ID of a TDataSourceConfig module. Defaults to empty string, meaning not set.
+ */
+ public function getConnectionID()
+ {
+ return $this->_connID;
+ }
+
+ /**
+ * Sets the ID of a TDataSourceConfig module.
+ * The datasource module will be used to establish the DB connection
+ * that will be used by the user manager.
+ * @param string module ID.
+ */
+ public function setConnectionID($value)
+ {
+ $this->_connID=$value;
+ }
+
+ /**
+ * @return TDbConnection the database connection that may be used to retrieve user data.
+ */
+ public function getDbConnection()
+ {
+ if($this->_conn===null)
+ $this->_conn=$this->createDbConnection($this->_connID);
+ return $this->_conn;
+ }
+
+ /**
+ * Creates the DB connection.
+ * @param string the module ID for TDataSourceConfig
+ * @return TDbConnection the created DB connection
+ * @throws TConfigurationException if module ID is invalid or empty
+ */
+ protected function createDbConnection($connectionID)
+ {
+ if($connectionID!=='')
+ {
+ $conn=$this->getApplication()->getModule($connectionID);
+ if($conn instanceof TDataSourceConfig)
+ return $conn->getDbConnection();
+ else
+ throw new TConfigurationException('dbusermanager_connectionid_invalid',$connectionID);
+ }
+ else
+ throw new TConfigurationException('dbusermanager_connectionid_empty');
+ }
+}
+
+
+/**
+ * TDbUser class
+ *
+ * TDbUser is the base user class for using together with {@link TDbUserManager}.
+ * Two methods are declared and must be implemented in the descendant classes:
+ * - {@link validateUser()}: validates if username and password are correct entries.
+ * - {@link createUser()}: creates a new user instance given the username
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: $
+ * @package System.Security
+ * @since 3.1.0
+ */
+abstract class TDbUser extends TUser
+{
+ private $_connection;
+
+ /**
+ * Returns a database connection that may be used to retrieve data from database.
+ *
+ * @return TDbConnection database connection that may be used to retrieve data from database
+ */
+ public function getDbConnection()
+ {
+ if($this->_connection===null)
+ {
+ $userManager=$this->getManager();
+ if($userManager instanceof TDbUserManager)
+ {
+ $connection=$userManager->getDbConnection();
+ if($connection instanceof TDbConnection)
+ {
+ $connection->setActive(true);
+ $this->_connection=$connection;
+ }
+ }
+ if($this->_connection===null)
+ throw new TConfigurationException('dbuser_dbconnection_invalid');
+ }
+ return $this->_connection;
+ }
+
+ /**
+ * Validates if username and password are correct entries.
+ * Usually, this is accomplished by checking if the user database
+ * contains this (username, password) pair.
+ * You may use {@link getDbConnection DbConnection} to deal with database.
+ * @param string username (case-sensitive)
+ * @param string password
+ * @return boolean whether the validation succeeds
+ */
+ abstract public function validateUser($username,$password);
+
+ /**
+ * Creates a new user instance given the username.
+ * This method usually needs to retrieve necessary user information
+ * (e.g. role, name, rank, etc.) from the user database according to
+ * the specified username. The newly created user instance should be
+ * initialized with these information.
+ *
+ * If the username is invalid (not found in the user database), null
+ * should be returned.
+ *
+ * You may use {@link getDbConnection DbConnection} to deal with database.
+ *
+ * @param string username (case-sensitive)
+ * @return TDbUser the newly created and initialized user instance
+ */
+ abstract public function createUser($username);
+}
+
+?>
\ No newline at end of file |