Authentication System
updated as of: March 30, 2015
last author: Andy Theuninck
original author: Andy Theuninck
The latest documentation can be found on the
Project Wiki.
The information below may be out of date.
The backend eventually needs access controls.
In my opinion, the "backendsecurity" column
in the employees table isn't going to work. There's
enough going on that tiered access just doesn't
make sense. For example, the front end manager
should be able to edit cashiers but probably not
products. Buyers or scanning should be able to
edit products but probably not cashiers.
We need something more nuanced (mandatory access
controls if you're into terminology). The system
described here is included with fannie. It isn't
perfect (frankly, the table structure is just
bone-headed) but it works and is reasonably
flexible.
Authenticating Users
The auth package is primarily SQL based. The UI lets
you add and remove users, change passwords, etc.
The system can be run entirely this way with usernames
and (encrypted) passwords right in the database.
Users generally don't like keeping track of lots
of passwords, so I've added a couple alternatives.
You can authenticate against an /etc/shadow file.
A small utility, shadowread, is included to
let apache pull password hashes out without
making /etc/shadow readable for all users
(PHP-PAM integration was in rough shape when I wrote
this). This is just for name & password matching;
the user still exists in SQL.
You can authenticate against an LDAP server. I use
it with openldap. It could probably be done with
Active Directory in a Windows environment.
Again this is just for name & password matching.
Both LDAP and shadow logins will automatically
create users in the database if needed.
Permissions
The auth package is structured around the notion
of authorization classes. An authorization class
is simply something a user is allowed to do -
for instance "edit_prices" could be an authorization class.
For finer granularity, there are optional sub-class limits.
These are pretty flexible. These don't have to mean the same
thing in all contexts, and can be anything that works in a SQL
BETWEEN statements. For example, you could use these to give
someone permission to edit prices, but only for products in
departments 10 through 15. Or you could give someone permission
to edit members, but only if their member type is 1.
Groups
You can put users in groups and then assign authorization classes
to the group. The table structure for this is idiotic but functional.
It saves some headaches rolling out a new tool
or trying to remember all the authorizations a new employee needs.
Tying it all together
There are really only two functions that get used a lot to access
user information from Fannie:
- checkLogin() returns the name of the user, or false
if the user has not logged in.
- validateUserQuiet(string $auth_class [,string $sub_start, string $sub_end])
returns the name of the user if they are logged in and have the
requested authorization. Otherwise it returns false.
The login page (auth/ui/loginform.php) accepts an optional GET argument
in the URL, redirect. So a fannie tool that uses authentication will
have a little section like this:
include($FANNIE_ROOT."auth/login.php");
if (!validateUserQuiet("edit_prices")){
$redirect = $FANNIE_URL."item/itemMaint.php";
$loginpage = $FANNIE_URL."auth/ui/loginform.php";
header("Location: $loginpage?redirect=$redirect");
exit;
}
This sends the user to a login form, if needed, and once they
enter a valid username and password brings them right
back to what they were doing.
Installation
- In the Authentication section ("tab") of the Fannie Install page
select "Yes" for Authentican Enabled and click "Re-run".
- After that, if no Users have been entered yet there will be input boxes for
Username and Password for an initial one with "admin" authorization. Click "Re-run".
- These credentials will let you log in to the Authentication interface at FANNIE/auth/ui/
However other protected pages may still be closed to a user who only has "admin" authorization.
10Nov12 EL This procedure may have been superseded by the above:
The auth packages uses itself to check who can edit users,
permissions, etc so there's a little backdoor for initial
installation.
- Create a file in auth/ named init.php. It can be empty.
- Go to auth/ui/menu.php in a browser.
- Create a user for yourself. Remember your password.
- Give your user the authorization "admin". This provides
access to manage the auth package.
- Delete the init.php file created in step one.
Drawbacks and/or Gotchas
Just stuff to be aware of. Some can probably be fixed, some are inherent.
- You will not remember the names of all the authorization
classes. It's easy enough to go look in the code, but it's an
annoying extra step. A drop down list of existing authorizations
would help some. Groups help some.
- Groups must have at least one user. groups.php could be
re-written around a new schema, but it's not a priority for me.
- The example code above, which is used throughout fannie, is kind
of sloppy. If someone has a valid username & password but not
that particular authorization, the redirect loops. It works -
anyone who should have access will call IT to ask what's going on -
but could be handled more gracefully.
- All three name & password systems are enabled. Turning one
off involves editing either auth/ui/loginform.php or auth/login.php.
This should probably be configurable.
- LDAP configuration is hard coded in auth/login.php. Probably not
a big deal until it's been tested with several different LDAP servers
to get an idea just how many config options will be needed.