Auth Plugin

From Davical
Jump to: navigation, search


Template:TableOfContents

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

Basic Components

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 {{{false}}} 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:

$usr A usr object, containing at least username, fullname and email fields and may contain ???
$groups An array of group objects. Each group object should contain at least a groupshort field and may contain groupname, groupemail and relationship_type.
$calendars A single calendar name, or an array of one or more calendar objects. If an array of calendar objects, each one must contain a name field, and may contain a displayname field. If no value is supplied then no default calendar(s) will be created.
$user_no An integer ID used to identify the usr record to be created / updated. If this is not present, or false, the $usr->username field will be used as the unique user identifier.

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

Examples

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.

Notes

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