Designing for a reusable Access-Level Constraint library

From: Ryan Kinderman (ryan_at_kinderman.net)
Date: 10/31/03


Date: Thu, 30 Oct 2003 22:47:01 -0600


--- The Introduction ---

I've been working on a design project for quite some time, to come up
with a reusable library which provides a general-purpose, reusable set
of components by which client applications may define their own
access-level constraints (ALCs) based on the problem domain of the
specific application. The library will force a consistent design for
implementing ALCs, thus creating a standard design protocol that every
application can follow to simplify this process. It will also take care
of a number of common access-level tasks, such as obtaining access
levels from a persistant store, performing user authentication (against
a database, say), and abstracting certain access-level considerations,
such as whether one thing has more or less access than another thing.

--- The Problem ---

Having relatively little experience in software engineering, while still
understanding object-oriented programming concepts, I'm having trouble
deciding whether this library will have to be too generalized to be
useful. That is to say, I'm afraid that developers using the library
will end up having to create customized classes for everything they want
access-level constraints for, or they will have to manually compare the
access levels of the current user and some object they wish to access,
so that the library is really nothing more than a glorified
data-retrieval/abstraction system.

-- The Details --

I've decided that all access levels will be integer-based. I've created
an interface called IAuthAccess, which is used to seperate the access
comparison rules from the application. It defines 3 operations:
IsLessThan(IAuthAccess authAccess), IsGreaterThan(IAuthAccess ...),
IsEqualTo(...). I then have an IntLowerAuthAccess class which
implements the IAuthAccess interface in the case of an integer
access-level of lower value representing a higher access level (example:
  Access Level 1 == Super User, Access Level 2 == Domain Admin, Level 3
== Normal User, etc.). I could also define an IntHigherAuthAccess class
to represent the inverse case, or some other class which has specific
meanings for each number. In any case, I will be using
IntLowerAuthAccess for the time-being.

I've defined 4 different *types* of access-level constraints. They are
as follows:

1. User
        A user of a piece of software may have an access level which describes
the level of access that they have in the software. The access level
would determine which parts of the software’s data, UI, and logical
operations that the user would be authorized to use or gain access to.
2. Command
        A Command is a logical operation within a piece of software. Examples
of a Command include: opening a persistent object (file, data field,
etc.), deleting a persistent object, and performing a certain
decision-making process.
3. Data
        There is sometimes the need to restrict access to certain kinds of
data. Specifically, the results of a database query may differ
depending on the access level of the object requesting the results.
Alternatively, the results returned from a database query may have an
access level attached to them, which may then be compared against an
object to determine whether it has access to each result.
4. User Interface (UI)
        This is the only type of ALC that has two words (laugh). This is also
the only ALC which interacts exclusively with a User ALC. A UI ALC is a
graphical component of a piece of software which may be represented
differently depending on the access-level of the user interacting with
it. Examples include menu items in a main application window which may
or may not be visible, or a TextBox object within a form that is enabled
or disabled depending on the user logged into the application.

A User access level always defines the level of access that a user has
within a piece of software. The exact effects of this access depends on
the type of ALC that the user is interacting with, and the object that
it's attached to.

In my first iteration of the library, I have the IAuthAccess classes
I've mentioned previously, as well as the following classes:

1. IAuthManager
        Responsible for authenticating user credentials against an authority.
An AuthManager must be implemented for each seperate, unrelated authority.
        Operations:
                IAuthUser Authenticate(String userName, String password)
                IAuthAccess GetRequiredCommandAccess(String commandId)

2. DbAuthManager
        An abstract base class that implements the IAuthManager interface for
the general case of a database being the source of authority for
authentication and command access retrieval.

3. SqlAuthManager
        A derived class of DbAuthManager for the SQL Server RDBMS.

I'm still trying to decide how to handle Data and UI ALCs.

--- The Cry for Help ---

So, what I was wondering is if any of you seasoned veterans out there
can spot flaws in this idea right from the start, or if you can think of
a direction in which I can go with this as far as how I may wish to
organize or design the classes/layers.

Any advice/feedback would be greatly appreciated.

Thanks,

Ryan Kinderman