Authentication and Authorization

Before we set off to implement the user pages, we need to do some work to enable authentication and authorization.

We add two new modules to the application configuration as follows:

<modules>
    ...TDataSourceConfig and TActiveRecordConfig modules...

    <module id="auth"
      class="System.Security.TAuthManager"
      UserManager="users"
      LoginPage="users.LoginUser" />

    <module id="users"
      class="System.Security.TDbUserManager"
      UserClass="Application.BlogUser" />
</modules>

The TAuthManager module manages the whole authentication and authorization workflow. It uses the users module as its user manager (see below). By specifying the LoginPage property, we inform the auth manager to redirect user's browser to the LoginUser page when an authorization fails. We will describe how to create LoginUser in the next subsection.

The user module is of class TDbUserManager which is responsible to verify the validity of a user and keep basic user data in the PHP session. The UserClass property is initialized as Application.BlogUser, which indicates the user manager would look for a BlogUser class under the directory protected (remember the alias Application refers to the protected directory) and use it to keep user's session data.

As we will see in later sections, in controls and pages, we can use $this->User to obtain the BlogUser object which contains the information of the user currently accessing the system.

Below is the implementation detail of BlogUser. Notice Active Record is used to perform DB query. For example, we use UserRecord::finder()->findByPk($username) to look for the primary key specified by $username in the users table.

// 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');
    }
}