git-svn-id: https://svn.salfter.gotdns.org/svn/compmgmt/trunk@170 1b90f75b-8b96-4784-87c0-14078182fce6

This commit is contained in:
(no author)
2008-10-21 03:21:28 +00:00
parent 90c1e0aadc
commit 57988e792a
19 changed files with 590 additions and 4 deletions

57
protected/BlogUser.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
// Include TDbUserManager.php file which defines TDbUser
Prado::using('System.Security.TDbUserManager');
/**
* BlogUser Class.
* BlogUser represents the user data that needs to be kept in session.
* Default implementation keeps username and role information.
*/
class BlogUser extends TDbUser
{
/**
* Creates a BlogUser object based on the specified username.
* This method is required by TDbUser. It checks the database
* to see if the specified username is there. If so, a BlogUser
* object is created and initialized.
* @param string the specified username
* @return BlogUser the user object, null if username is invalid.
*/
public function createUser($username)
{
// use UserRecord Active Record to look for the specified username
$userRecord=UserRecord::finder()->findByPk($username);
if($userRecord instanceof UserRecord) // if found
{
$user=new BlogUser($this->Manager);
$user->Name=$username; // set username
$user->Roles=($userRecord->role==1?'admin':'user'); // set role
$user->IsGuest=false; // the user is not a guest
return $user;
}
else
return null;
}
/**
* Checks if the specified (username, password) is valid.
* This method is required by TDbUser.
* @param string username
* @param string password
* @return boolean whether the username and password are valid.
*/
public function validateUser($username,$password)
{
// use UserRecord Active Record to look for the (username, password) pair.
return UserRecord::finder()->findBy_username_AND_password($username,$password)!==null;
}
/**
* @return boolean whether this user is an administrator.
*/
public function getIsAdmin()
{
return $this->isInRole('admin');
}
}
?>

View File

@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<application id="compmgmt" mode="Debug">
<!-- alias definitions and namespace usings
<paths>
<alias id="myalias" path="./lib" />
<using namespace="Application.common.*" />
<using namespace="Application.database.*" />
</paths>
-->
<!-- configurations for modules -->
<modules>
@@ -23,11 +21,25 @@
<route class="TBrowserLogRoute" Categories="System" />
</module>
-->
<module id="db" class="System.Data.TDataSourceConfig">
<database ConnectionString="sqlite:protected/data/blog.db" />
</module>
<module class="System.Data.ActiveRecord.TActiveRecordConfig" ConnectionID="db" />
<module id="auth"
class="System.Security.TAuthManager"
UserManager="users"
LoginPage="users.LoginUser" />
<module id="users"
class="System.Security.TDbUserManager"
UserClass="Application.BlogUser" />
</modules>
<!-- configuration for available services -->
<services>
<service id="page" class="TPageService" DefaultPage="Home">
<service id="page" class="TPageService" DefaultPage="posts.ListPost">
<pages MasterClass="Application.layouts.MainLayout" />
</service>
</services>

BIN
protected/data/blog.db Normal file
View File

Binary file not shown.

View File

@@ -0,0 +1,28 @@
<?php
/**
* Auto generated by prado-cli.php on 2008-10-20 06:25:37.
*/
class PostRecord extends TActiveRecord
{
const TABLE='posts';
public $post_id;
public $author_id;
public $create_time;
public $title;
public $content;
public $status;
public static function finder($className=__CLASS__)
{
return parent::finder($className);
}
public $author; //holds an UserRecord
public static $RELATIONS=array
(
'author' => array(self::BELONGS_TO, 'UserRecord'),
);
}
?>

View File

@@ -0,0 +1,28 @@
<?php
/**
* Auto generated by prado-cli.php on 2008-10-20 06:25:30.
*/
class UserRecord extends TActiveRecord
{
const TABLE='users';
public $username;
public $email;
public $password;
public $role;
public $first_name;
public $last_name;
public static function finder($className=__CLASS__)
{
return parent::finder($className);
}
public $posts=array(); //holds an array of PostRecord
public static $RELATIONS=array
(
'posts' => array(self::HAS_MANY, 'PostRecord'),
);
}
?>

View File

@@ -1,5 +1,17 @@
<?php
class MainLayout extends TTemplateControl
{
/**
* Logs out a user.
* This method responds to the "logout" button's OnClick event.
* @param mixed event sender
* @param mixed event parameter
*/
public function logoutButtonClicked($sender,$param)
{
$this->Application->getModule('auth')->logout();
$url=$this->Service->constructUrl($this->Service->DefaultPage);
$this->Response->redirect($url);
}
}
?>

View File

@@ -13,6 +13,15 @@
</div>
<div id="footer">
<com:THyperLink Text="Login"
NavigateUrl="<%= $this->Service->constructUrl('users.LoginUser') %>"
Visible="<%= $this->User->IsGuest %>" />
<com:TLinkButton Text="Logout"
OnClick="logoutButtonClicked"
Visible="<%= !$this->User->IsGuest %>"
CausesValidation="false" />
<%= PRADO::poweredByPrado() %>
</div>

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,3 @@
<?php
?>

View File

@@ -0,0 +1,40 @@
<%@ Title="My Blog - Manage User Accounts" %>
<com:TContent ID="Main">
<h1>Manage User Accounts</h1>
<a href="<%= $this->Service->constructUrl('users.NewUser')%>">Create New User</a>
<br/>
<com:TDataGrid ID="UserGrid"
DataKeyField="username"
AutoGenerateColumns="false"
OnDeleteCommand="deleteButtonClicked">
<com:THyperLinkColumn
HeaderText="Username"
DataTextField="username"
DataNavigateUrlField="username">
<prop:DataNavigateUrlFormatString>#
$this->Service->constructUrl('users.EditUser',array('username'=>{0}))
</prop:DataNavigateUrlFormatString>
</com:THyperLinkColumn>
<com:TBoundColumn
HeaderText="Email"
DataField="email" />
<com:TCheckBoxColumn
HeaderText="Administrator"
DataField="role" />
<com:TButtonColumn
HeaderText="Command"
Text="Delete"
ButtonType="PushButton"
CommandName="delete" />
</com:TDataGrid>
</com:TContent>

View File

@@ -0,0 +1,34 @@
<?php
class AdminUser extends TPage
{
/**
* Populates the datagrid with user lists.
* This method is invoked by the framework when initializing the page
* @param mixed event parameter
*/
public function onInit($param)
{
parent::onInit($param);
// fetches all data account information
$this->UserGrid->DataSource=UserRecord::finder()->findAll();
// binds the data to interface components
$this->UserGrid->dataBind();
}
/**
* Deletes a specified user record.
* This method responds to the datagrid's OnDeleteCommand event.
* @param TDataGrid the event sender
* @param TDataGridCommandEventParameter the event parameter
*/
public function deleteButtonClicked($sender,$param)
{
// obtains the datagrid item that contains the clicked delete button
$item=$param->Item;
// obtains the primary key corresponding to the datagrid item
$username=$this->UserGrid->DataKeys[$item->ItemIndex];
// deletes the user record with the specified username primary key
UserRecord::finder()->deleteByPk($username);
}
}
?>

View File

@@ -0,0 +1,61 @@
<%@ Title="My Blog - Edit User" %>
<com:TContent ID="Main">
<h1>Edit User</h1>
<span>Username:</span>
<com:TLabel ID="Username" />
<br/>
<span>Password:</span>
<br/>
<com:TTextBox ID="Password" TextMode="Password" />
<br/>
<span>Re-type Password:</span>
<com:TCompareValidator
ControlToValidate="Password"
ControlToCompare="Password2"
ErrorMessage="Your password entries did not match."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Password2" TextMode="Password" />
<br/>
<span>Email Address:</span>
<com:TRequiredFieldValidator
ControlToValidate="Email"
ErrorMessage="Please provide your email address."
Display="Dynamic" />
<com:TEmailAddressValidator
ControlToValidate="Email"
ErrorMessage="You entered an invalid email address."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Email" />
<com:TControl Visible="<%= $this->User->IsAdmin %>">
<br/>
<span>Role:</span>
<br/>
<com:TDropDownList ID="Role">
<com:TListItem Text="Normal User" Value="0" />
<com:TListItem Text="Administrator" Value="1" />
</com:TDropDownList>
</com:TControl>
<br/>
<span>First Name:</span>
<br/>
<com:TTextBox ID="FirstName" />
<br/>
<span>Last Name:</span>
<br/>
<com:TTextBox ID="LastName" />
<br/>
<com:TButton Text="Save" OnClick="saveButtonClicked" />
</com:TContent>

View File

@@ -0,0 +1,81 @@
<?php
class EditUser extends TPage
{
/**
* Initializes the inputs with existing user data.
* This method is invoked by the framework when the page is being initialized.
* @param mixed event parameter
*/
public function onInit($param)
{
parent::onInit($param);
if(!$this->IsPostBack) // if the page is initially requested
{
// Retrieves the existing user data. This is equivalent to:
// $userRecord=$this->getUserRecord();
$userRecord=$this->UserRecord;
// Populates the input controls with the existing user data
$this->Username->Text=$userRecord->username;
$this->Email->Text=$userRecord->email;
$this->Role->SelectedValue=$userRecord->role;
$this->FirstName->Text=$userRecord->first_name;
$this->LastName->Text=$userRecord->last_name;
}
}
/**
* Saves the user account if all inputs are valid.
* This method responds to the OnClick event of the "save" button.
* @param mixed event sender
* @param mixed event parameter
*/
public function saveButtonClicked($sender,$param)
{
if($this->IsValid) // when all validations succeed
{
// Retrieves the existing user data. This is equivalent to:
$userRecord=$this->UserRecord;
// Fetches the input data
$userRecord->username=$this->Username->Text;
// update password when the input is not empty
if(!empty($this->Password->Text))
$userRecord->password=$this->Password->Text;
$userRecord->email=$this->Email->Text;
// update the role if the current user is an administrator
if($this->User->IsAdmin)
$userRecord->role=(int)$this->Role->SelectedValue;
$userRecord->first_name=$this->FirstName->Text;
$userRecord->last_name=$this->LastName->Text;
// saves to the database via Active Record mechanism
$userRecord->save();
// redirects the browser to the homepage
$this->Response->redirect($this->Service->DefaultPageUrl);
}
}
/**
* Returns the user data to be editted.
* @return UserRecord the user data to be editted.
* @throws THttpException if the user data is not found.
*/
protected function getUserRecord()
{
// the user to be editted is the currently logged-in user
$username=$this->User->Name;
// if the 'username' GET var is not empty and the current user
// is an administrator, we use the GET var value instead.
if($this->User->IsAdmin && $this->Request['username']!==null)
$username=$this->Request['username'];
// use Active Record to look for the specified username
$userRecord=UserRecord::finder()->findByPk($username);
if(!($userRecord instanceof UserRecord))
throw new THttpException(500,'Username is invalid.');
return $userRecord;
}
}
?>

View File

@@ -0,0 +1,28 @@
<%@ Title="My Blog - Login" %>
<com:TContent ID="Main">
<h1>Login</h1>
<span>Username:</span>
<com:TRequiredFieldValidator
ControlToValidate="Username"
ErrorMessage="Please provide your username."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Username" />
<br/>
<span>Password:</span>
<com:TCustomValidator
ControlToValidate="Password"
ErrorMessage="Your entered an invalid password."
Display="Dynamic"
OnServerValidate="validateUser" />
<br/>
<com:TTextBox ID="Password" TextMode="Password" />
<br/>
<com:TButton Text="Login" OnClick="loginButtonClicked" />
</com:TContent>

View File

@@ -0,0 +1,35 @@
<?php
class LoginUser extends TPage
{
/**
* Validates whether the username and password are correct.
* This method responds to the TCustomValidator's OnServerValidate event.
* @param mixed event sender
* @param mixed event parameter
*/
public function validateUser($sender,$param)
{
$authManager=$this->Application->getModule('auth');
if(!$authManager->login($this->Username->Text,$this->Password->Text))
$param->IsValid=false; // tell the validator that validation fails
}
/**
* Redirects the user's browser to appropriate URL if login succeeds.
* This method responds to the login button's OnClick event.
* @param mixed event sender
* @param mixed event parameter
*/
public function loginButtonClicked($sender,$param)
{
if($this->Page->IsValid) // all validations succeed
{
// obtain the URL of the privileged page that the user wanted to visit originally
$url=$this->Application->getModule('auth')->ReturnUrl;
if(empty($url)) // the user accesses the login page directly
$url=$this->Service->DefaultPageUrl;
$this->Response->redirect($url);
}
}
}
?>

View File

@@ -0,0 +1,73 @@
<%@ Title="My Blog - New User" %>
<com:TContent ID="Main">
<h1>Create New User</h1>
<span>Username:</span>
<com:TRequiredFieldValidator
ControlToValidate="Username"
ErrorMessage="Please provide a username."
Display="Dynamic" />
<com:TCustomValidator
ControlToValidate="Username"
ErrorMessage="Sorry, your username is taken by someone else. Please choose another username."
OnServerValidate="checkUsername"
Display="Dynamic" />
<br/>
<com:TTextBox ID="Username" />
<br/>
<span>Password:</span>
<com:TRequiredFieldValidator
ControlToValidate="Password"
ErrorMessage="Please provide a password."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Password" TextMode="Password" />
<br/>
<span>Re-type Password:</span>
<com:TCompareValidator
ControlToValidate="Password"
ControlToCompare="Password2"
ErrorMessage="Your password entries did not match."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Password2" TextMode="Password" />
<br/>
<span>Email Address:</span>
<com:TRequiredFieldValidator
ControlToValidate="Email"
ErrorMessage="Please provide your email address."
Display="Dynamic" />
<com:TEmailAddressValidator
ControlToValidate="Email"
ErrorMessage="You entered an invalid email address."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Email" />
<br/>
<span>Role:</span>
<br/>
<com:TDropDownList ID="Role">
<com:TListItem Text="Normal User" Value="0" />
<com:TListItem Text="Administrator" Value="1" />
</com:TDropDownList>
<br/>
<span>First Name:</span>
<br/>
<com:TTextBox ID="FirstName" />
<br/>
<span>Last Name:</span>
<br/>
<com:TTextBox ID="LastName" />
<br/>
<com:TButton Text="Create" OnClick="createButtonClicked" />
</com:TContent>

View File

@@ -0,0 +1,43 @@
<?php
class NewUser extends TPage
{
/**
* Checks whether the username exists in the database.
* This method responds to the OnServerValidate event of username's custom validator.
* @param mixed event sender
* @param mixed event parameter
*/
public function checkUsername($sender,$param)
{
// valid if the username is not found in the database
$param->IsValid=UserRecord::finder()->findByPk($this->Username->Text)===null;
}
/**
* Creates a new user account if all inputs are valid.
* This method responds to the OnClick event of the "create" button.
* @param mixed event sender
* @param mixed event parameter
*/
public function createButtonClicked($sender,$param)
{
if($this->IsValid) // when all validations succeed
{
// populates a UserRecord object with user inputs
$userRecord=new UserRecord;
$userRecord->username=$this->Username->Text;
$userRecord->password=$this->Password->Text;
$userRecord->email=$this->Email->Text;
$userRecord->role=(int)$this->Role->SelectedValue;
$userRecord->first_name=$this->FirstName->Text;
$userRecord->last_name=$this->LastName->Text;
// saves to the database via Active Record mechanism
$userRecord->save();
// redirects the browser to the homepage
$this->Response->redirect($this->Service->DefaultPageUrl);
}
}
}
?>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<authorization>
<allow pages="NewUser,AdminUser" roles="admin" />
<deny users="?" />
</authorization>
</configuration>

25
protected/schema.sql Normal file
View File

@@ -0,0 +1,25 @@
/* create users table */
CREATE TABLE users (
username VARCHAR(128) NOT NULL PRIMARY KEY,
email VARCHAR(128) NOT NULL,
password VARCHAR(128) NOT NULL, /* in plain text */
role INTEGER NOT NULL, /* 0: normal user, 1: administrator */
first_name VARCHAR(128),
last_name VARCHAR(128)
);
/* create posts table */
CREATE TABLE posts (
post_id INTEGER NOT NULL PRIMARY KEY,
author_id VARCHAR(128) NOT NULL
CONSTRAINT fk_author REFERENCES users(username),
create_time INTEGER NOT NULL, /* UNIX timestamp */
title VARCHAR(256) NOT NULL, /* title of the post */
content TEXT, /* post body */
status INTEGER NOT NULL /* 0: published; 1: draft; 2: pending; 2: denied */
);
/* insert some initial data records for testing */
INSERT INTO users VALUES ('admin', 'admin@example.com', 'demo', 1, 'Scott', 'Alfter');
INSERT INTO users VALUES ('demo', 'demo@example.com', 'demo', 0, 'Foo', 'Bar');
INSERT INTO posts VALUES (NULL, 'admin', 1175708482, 'first post', 'this is my first post', 0);