Twitter Feed

Xataface Maillist

Sign up to receive the Xataface news letter with weekly updates and development tips.

 
Previous: Triggers Up to Contents Next: Changing the Look and Feel

Getting Started with Xataface

Jump:

Web Lite is a simple framework for developing data-driven web applications in PHP and MySQL. This tutorial will show you how to get a dataface powered web application running in under 20 minutes.

Permissions

Use sessions and delegate classes to define permissions at the record and field level.

Xataface 0.6 adds a new,  fine-grained permissions model and support for user authentication using your own database tables.  This section includes a brief overview of the permissions framework and a small example of how you might use permissions in the FacultyOfWidgetry application.

Roles and Permissions

Permissions

Before we jump into an example it is important to understand a couple of definitions and concepts about Xataface's permissions model.  Every possible action in Xataface has an associated permission to indicate whether the current user has permission to perform the action.  Some examples of permissions include:

  • view - The user has permission to view the content of the page for a particular record or table.
  • edit - The user has permission to edit a record.
  • delete - The user has permission to delete a record.
  • add new related record - The user has permission to add a new record to a relationship.
  • ... more ...

Before allowing the user to perform an action, Xataface checks the permissions to see if the user has the appropriate permissions.  You can override the default permissions by defining a method called 'getPermissions()' in your delegate classes (more on that below).

Roles

There could be 50 or more permissions associated with an application, so it quickly becomes unfeasible to have configure each user's access on a permission-by-permission basis.  Roles provide a means of grouping permissions together into logical sets so that each user can be assigned a role, which has a set of permissions already associated with it. 

The concept of a Role is not new by any means.  We use roles on a daily basis to simplify things.  Consider the example of a sports car.  There are a number of functions that can be performed on a sports car:

  • People can drive the car.
  • People can ride in the car.
  • People can wash the car.
  • People can fix the car.

We would probably have permissions 'drive','ride','wash', and 'fix' associated with our sports car, then.  The roles, in this example, might be:

  • Owner
  • Friend of Owner
  • Mechanic
  • Thief

The owner role should be able to do everything except for fix the car.  The mechanic role should be able to fix the car, but not drive the car.  The friend role should be able to ride in the car and wash the car, but not drive or fix it.  And the thief should not be permitted to perform any of the functions.

In the internet world, we might use roles such as "Administrator", "Anonymous", or "Member", where the administrator would have all permissions, the "Member" would be able to leave comments, and the "Anonymous" user would have no access.  Later, we'll find out how to create your own roles and permissions, but Xataface includes some built-in roles to handle the most frequently-used cases.  Some of Xataface's roles are as follows:

 

NO ACCESS
Role does not have any permissions.
READ ONLY
This role can view, show all, find, and navigate - which boils down to: this role can look but not touch.
EDIT
This role can do everything that READ ONLY can do plus edit existing records, add and remove related records, import records, and translate records.  In essence, this role can look, and touch - but not necessarily delete.
DELETE
Can do everything that EDIT can do, plus it can delete records.
OWNER
Same access as DELETE, but by a more intuitive name.  In theory OWNER may have different permissions than DELETE if actions were introduced that made sense for the OWNER role but not the DELETE role.
USER
Includes all of READ ONLY's permissions, but also has the ability to create new records.
ADMIN
Same as owner.

The following diagram shows the relationship between Xataface's built-in roles and permissions (as of June 29, 2006 - subject to change):

roles-permissions-graph.png

 

 

Learning by example

Now consider the familiar example of the Faculty of Widgetry site.  Suppose we add the following requirements:

  1. Users have to log into the system to access it.
  2. There are two types of users:
    • Regular Users - have read-only access to the system
    • Administrators - have full access to the system

Now that we have defined our requirements, let's look at how to implement this using PHP and Xataface.  We will be performing the following modifications to our system:

  1. Add a "Users" table to store the user names, passwords, and user levels of the system users.
  2. Turn on authentication in the conf.ini file.
  3. Define permissions for each table in our application using delegate classes.

Adding the Users table:

The Users table doesn't need to store very much.  Only the user names, passwords, and user role.  The user role is optional but it will allow us to limit actions on a per-user basis.  In our system we will use the following roles:

  • NO ACCESS - Not allowed to access the site at all.
  • READ ONLY - Can view the site, but not edit anything.
  • ADMIN - Has full access to the site - can add and edit programs and courses.

.  This is just one way to implement permissions.  There are many ways that you can do it.
So our Users table will look something like this:

Users-erd.png
Figure 1: ERD (Entity Relationship Diagram) for Users Table

The SQL to create this table would be as follows:

CREATE TABLE  `Users` (
`UserID` INT( 11 ) NOT NULL AUTO_INCREMENT ,
`UserName` VARCHAR( 32 ) NOT NULL ,
`Password` VARCHAR( 32 ) NOT NULL ,
`Role` ENUM('READ ONLY','NO ACCESS','ADMIN') DEFAULT 'READ ONLY',
PRIMARY KEY ( `UserID` ) ,
UNIQUE (`UserName`)
)

The reason we have a UserID field in addition to a UserName field is so that we can change the UserName without destroying relationships. (It is important to note that you can use any table to store your user information, as long as it has a field for the user name and password used to log in).

Setting up authentication

Now that we have a table to store our users, we can turn on authentication for our application.  Setting up authentication is a two-step process:

  1. We need to enable authentication for our application so that users can log in and out.  This is done by adding a section to the conf.ini file as follows:
    [_auth]
    users_table = Users
    username_column = UserName
    password_column = Password

    The 'users_table' directive indicates the name of the table that stores the users for the application.
    The 'username_column' is the name of the column of the users table that contains the login user name.
    The 'password_column' is (obviously) the name of the password column of the users table.  There are some other directives that can be added to this section to customize the login scenario, but these 3 basic ones will get us started.

  2. We need to define the permissions that are granted to each user for each record.  This is done by implementing the getPermissions() method in our delegate classes.  We can define an application-wide permissions scheme by implementing the getPermissions() method in the application delegate class, or we can specify the permissions on a table-by-table basis by implementing the method in the tables' delegate classes; or you can do both.  The getPermissions() method returns an array of permissions that are granted to the currently logged-in user for a particular record.  We'll begin with the application's delegate class so that we can secure all tables equally to begin.  If you haven't added an application delegate class to your application yet, just create a directory named conf in your application's directory, and add a file named ApplicationDelegate.php to this newly made conf directory with the following content:
    <?php
    /**
    * A delegate class for the entire application to handle custom handling of
    * some functions such as permissions and preferences.
    */
    class conf_ApplicationDelegate {
    /**
    * Returns permissions array. This method is called every time an action is
    * performed to make sure that the user has permission to perform the action.
    * @param record A Dataface_Record object (may be null) against which we check
    * permissions.
    * @see Dataface_PermissionsTool
    * @see Dataface_AuthenticationTool
    */
    function getPermissions(&$record){
    $auth =& Dataface_AuthenticationTool::getInstance();
    $user =& $auth->getLoggedInUser();
    if ( !isset($user) ) return Dataface_PermissionsTool::NO_ACCESS();
    // if the user is null then nobody is logged in... no access.
    // This will force a login prompt.
    $role = $user->val('Role');
    return Dataface_PermissionsTool::getRolePermissions($role);
    // Returns all of the permissions for the user's current role.
    }
    }
    ?>

Testing our application

In order to test our application, we will add a couple of users to the Users table with the available roles.  The SQL for these additions is as follows (though you can use your favorite SQL tool:

INSERT INTO `Users` (`UserName`,`Password`,`Role`) 
VALUES ('readOnlyUser','password','READ ONLY'),
('adminUser','password','ADMIN')

Now we load up the application in a web browser:

 

loginform-0.6.gif

When we log in as 'readOnlyUser' we see:

 

loggedIn-ReadOnly.gif

Now it looks basically the same as before we added authentication, except there is now a "logout" link in the upper right corner, and a link to view/edit the profile of the currently logged-in user (by way of the "My Profile" link in the upper right).  Notice, that the "New record", and "Delete record" options are no longer available in the "actions" menu.  Only "show all" remains.  This is because the current user (readOnlyUser) only has READ ONLY permissions which does not include creating new records or deleting records.  This limitation becomes even more evident when we click on the "details" tab to see record details:


loggedin-ReadOnly-details.gif

Notice that the "Edit" tab is no longer visible - only the "View" tab. 

If we log out and then log back in as 'adminUser', the edit tab re-appears along with options to create new records and delete records.

Source files download

Download the source files for this application as a tar.gz archive

(Note: These PHP sources are out of date, and include deprecated code such as short open tags.   You will need to change all PHP open tags from "<?" to "<?php" in order for these samples to work in most modern PHP installations).

And from here...


This section gives you a basic understanding of Dataface's permissions and authentication model.  You should now be able to add authentication and permissions to your dataface applications.   Some more advanced features, such as creating your own roles and permissions will be covered in later tutorials and reference manuals.  Later sections will also look at custom actions which can use the permissions model to limit who can perform them.

 

 

Previous: Triggers Up to Contents Next: Changing the Look and Feel
blog comments powered by Disqus
Powered by Xataface
(c) 2005-2017 All rights reserved