Apache Notes
============
This package allows you to create a complex site authorization system where
specific actions on resources are given custom rules. It extends
Apache::AuthCookie to track sessions. It has been tested with Apache 1 and 2,
and seems to work well. There are sample sites in the samples directory. The
differences in the two apache environments require slightly different setups,
so be sure to use the proper sample for your configuration.

If you are using this module with Apache2 and mod_perl2, you must use 
the mod_perl 1 compatibility settings.

Description
===========

There are two levels of control in SiteControl. 

The first is managed by AccessController, and determines if a valid user
has logged in. If so, it makes a user object available to the request
processor. This is done using SiteControl::UserFactory (a good base
implementation is already written).  The underlying code associates this user
with a session, and manages the browser interaction.

The second level of control is supplied by an application level
PermissionManager. The user objects are passed to this object, along
with the requested action and an opaque resource (of any type). Rules are
installed in the PM that determine if a specific action is allowed for a given
user and resource.

   if($manager->can($currentUser, "change", $dnsrecord)) {
      ...
   }

where the PM applies the various installed rules (user-defined) and returns
true if the action is allowed, false otherwise. In this example, one of the 
rules might detect that the resource (dnsrecord) is a row from a DNS tracking
table. It might then check to see if the currentUser is associated with 
DNS management and return true if they are, false otherwise. The top level 
application could then use this in a pretty abstract way. For example, if there
is a generic section of code that allows users to modify a row from a table,
the same code could be used:

   if($manager->can($currentUser, "change", $thisRecord)) {
      ...
   }

The application doesn't have to figure out what thisRecord is...the rules can
sense them. This allows the top-level application to be written in very
generic terms, and rules to be written based on the actual logic involved.

A rule might include code like this:

   sub grants
   {
      $this = shift;
      $user = shift;
      $action = shift;
      $resource = shift;

      if($action eq "change") {
         if($resource->isa("DNS::Record")) 
         {
            if($resource->getContactEMail() eq $user->getAttribute("email"))
            {
               return "permission granted by DNSRule";
            }
         }
      }
      return 0;
   }

which would detect the proper types that it knows how to handle, and do a check
that would indicate if permission is to be granted.

Comments on Rules

How would you make a system that allows everything, unless something is
specifically denied?
   Have a GrantAll rule that always grants permission.
   Add rules that never grant, but deny on specific cases.

How to make a system that denies everything except things that have been
checked out:
   Write rules that grant on your specific cases. The default is to deny
   permission if no rules have anything else to say about the request.

A rule can take several approaches:

Relative rule: It grants but never denies. Or it denies, but never grants.

Absolute rule: If it grants, then it does not deny. If it does not grant, then
it denies.

Read the manual pages for more information.
