Auth Plugin

DAViCal has a simple architecture which is intended to support external authentication through some form of "plugin" approach.

Required Functionality
The needed functions of any authentication method are:
 * 1) Test the provided username & password against the external authentication system;
 * 2) Return any failure, otherwise;
 * 3) Update the internal DAViCal data with any changes, or create it if required;
 * 4) Return the 'usr' record as an object

The 'usr' record object will need only to contain the 'user_no' field (indicating the user_no of the internal DAViCal data which was created / updated during the login).

Configuration
In order to provide maximum flexibility, each authentication plugin may define it's own configuration settings. At some future point when configuration of DAViCal can be done other than through editing a text file, the plugin will also likely be asked to define these data structures, but at present they need only be documented.

The root of the configuration data for any plugin will start at $c->authenticate_hook['call'] which will refer to a function accepting two parameters (the username and password entered by the user), and returning on failure. The actions of this function could, of course, be defined in whatever manner it's author wished. The preferred method for controlling it's operation is to hold all needec configuration data within an associative array stored at $c->authenticate_hook['config'].

Here is an example of the configuration of the auth_other_awl proof-of-concept function: // Using a different authentication method require_once('AuthPlugins.php'); $c->authenticate_hook = array(       'call'   => 'auth_other_awl',        'config' => array( 'connection' => 'dbname=other_awl port=5433 user=general', 'columns'   => "user_no, active, current_timestamp AS email_ok, joined, " + "last_update AS updated, last_used, username, password, fullname, email" ) );

Operation
The authentication hook is called early in the session setup, and the returned $usr->user_no of the (successful) call is used as the key for the construction of the session data, including group memberships and relationships.

The session data itself is used in many parts of the system, and within further SQL calls into the DAViCal database, so having the authentication hook operate by constructing these simple records in the DAViCal database where necessary is the simplest method of guaranteeing minimal change will be required as other enhancements are added to DAViCal in the future.

Helper Function
A helper function is provided which to assist with creating the internal DAViCal data.

This is not yet written at 2007-04-10 (function name also subject to change) boolean DAViCalSession::ConstructUserData( $usr, $groups [, $calendars="" [, $user_no=false ]] );

The arguments are as follows:

Function Operation
The following pseudo code describes the approximate planned operation of this function:

IF existing user record IF out of date user record UPDATE user record ELSE INSERT user record

initialise group_id list FOR EACH $group IF relationship_type does not exist THEN LOG the error CONTINUE to the next $group

IF group exists IF out of date group record UPDATE group record ELSE INSERT group record IF relationship does not exist INSERT relationship append group_id to group_id list

DELETE FROM relationship WHERE from_user = user_no AND to_user NOT IN ( group_id list )

IF $calendar is a text string IF user does not have a collection of that name INSERT collection record of type calendar ELSE IF $calendar is an array FOR EACH $calendar IF user does not have a collection of that name INSERT collection record of type calendar

Authentication against another AWL-based system
In the AWL libraries, the inc/AuthPlugins.php contains the function auth_other_awl($username,$password) which provides an almost trivial proof of concept example of using a different database (with the same structure) as the authentication source.

Cookie Login Not Supported
The "forget me not" functionality is not currently supported against external authentication sources, though it could work in some cases. For this to work in the general case there would need to be (potentially insecure) storage of the person's actual password, which would be a security risk. In general DAViCal uses salted MD5 hashes for one-way encryption of passwords, and the 'forget-me-not' feature uses a double-hashing comparison in order to provide some security without exposing passwords.

Efficiency Considerations
This code will usually be called for each request.

When logging into the DAViCal administration pages the code is called when the user's username / password are submitted and at no other time (after login a session cookie is used to maintain the authentication status).

Unfortunately, when accessing DAViCal through CalDAV, HTTP basic authentication will be used. This involves providing authentication tokens along with each request.

But we can put a timestamp store in db to avoid to pass through this process each time but only each X seconds ?

Information on tables

 * Database/Tables/Collection
 * Database/Tables/Session
 * Database/Tables/Usr