Tom Nunamaker's Fusebox Security Example Code

LICENSE
=======
See the license.txt file for the BSD-type license you agree to if you use this code.

NOTICE
======
The files in this example are not a complete working application.  They provide an example
for you to write your own security in your code.  


USAGE
=====
Permissions are like keys to a lock.  If you have the permission, you are granted access to
the resource.  Users can get permissions two ways.  One is by directly assigning a permission
to the user.  The second is through group membership.   Anti-permissions are applied after
the combined permissions are calculated and remove a permission from a user regardless of how
they may have been given it.  For example, you may give a "sys admin" group permission to
delete a user.  If you have a user in the "sys admin" group but they are new, you may wish to
remove that ability for them to delete a user.  Add the "delete user" permission to the user's
anti-permissions.  They will maintain group membership in "sys admin" but not be able to 
delete users.

Permissions are stored in the database as a number/string pair.  The session.user.myPermissions
stores a list of the numbers associated with allowed permissions, not the text of what each
permission is.  This keeps the list size small and fast to use.  The number of permissions you 
use can be large.

Permissions are the keys to let your users into entire circuits, fuseactions or page elements.  
To restrict an entire circuit to a specific permission, modify your circuit.xml like this:

<circuit access="public" permissions="#evaluate(sPermissions['Sys Admin'])#">
... protected fuseactions...
</circuit>

This would protect all fuseactions in this circuit.  Make sure you add a check to make sure the
user is logged in.

To restrict access for an individual fuse, do something like this:

  <fuseaction name="editUser" permissions="#evaluate(sPermissions['Edit Employee Records'])#">
    .. Protected Fuseaction ...
  </fuseaction>
  
This would limit the ability to the "editUser" fuseaction to only those people with "Edit Employee Records"
permission.

To restrict part of your page based on permissions, use a CFIF test like this:

<cfif listfind(session.user.permissions, sPermissions['Delete User']) GT 0> 
  DISPLAY PROTECTED CONTENT
<cfelse>
  DO NOT DISPLAY PROTECTED CONTENT
</cfif>

This would validate if you are have "Delete User" permission.  If you do, show the protected content.



THE FILES
=========

Users.sql
---------
This is a Microsoft SQL server SQL script to create the tables, contrainsts, user defined fuctions etc to support the fusebox security code. You will have to modify the users table to suit your needs.  


SecuritySchema.png
------------------
A graphic showing how the database tables are related.  All fields are shown, however, if
you are migrating this to another database, please examine the users.sql file for the
CREATE TABLE commands which describe data field types, etc.


PermissionsGroup.png
--------------------
A graphic showing a sample of the permissions and usergroup structures I created for a client.


SecurityException.cfm
---------------------
This goes in your fusebox /plugins directory.


ListBasedSecurity.cfm
---------------------
This goes in your fusebox /plugins directory.  Please change the administrator email address
in this file from admin@youremail.com to your email address.


fusebox.xml
-----------
DO NOT replace your fusebox.xml with this file!  This simply is included to illustrate how
I call the two files to initialize the permissions and usergroup structures.


act_permissionInit.cfm
----------------------
This creates the permissions structure.  Call it before attempting to use security elsewhere
in your code.


act_userGroupsInit.cfm
----------------------
This creates the userGroups structure.  Call it before attempting to use security elsewhere
in your code.


qury_getUser.cfm
----------------
Illustrates how to use the SQL server UDF's to set the permissions and structure lists in your
recordset.


circuit.xml
-----------
This illustrates how you can set circuit level permission security and fuseaction level security


act_Initialize.cfm
------------------
Illustrates how to set a session.user structure with the session.user.myPermissions variable.
You can change the name of this variable but you have to update the ListBasedSecurity.cfm file
to look for your new variable name.


