org.sandev.basics.util
Class AuthFilterBase

java.lang.Object
  extended by org.sandev.basics.util.AuthFilterBase
All Implemented Interfaces:
AuthFilter

public abstract class AuthFilterBase
extends java.lang.Object
implements AuthFilter

A base class for AuthFilter implementations with some useful utility methods. This breaks out the standard message class, instance, field and value access out by message type rather than verb type to make things easier to maintain when fine grained access control at the field level is needed.

To extend from this base, override the required abstract methods and then write an access method and optional query restriction method for each authorized messaging class defined in your application.


Field Summary
static int ACCTYPE_CLASS
          message class access
static int ACCTYPE_FIELD
          field access
static int ACCTYPE_FIELDVAL
          field value access
static int ACCTYPE_INSTANCE
          message instance access
 
Fields inherited from interface org.sandev.basics.util.AuthFilter
AUTH_ARRAYACCESS, AUTH_ARRAYADD, AUTH_ARRAYDELETE, AUTH_ARRAYMOVE, AUTH_ARRAYNEW, AUTH_NOACCESS, AUTH_READONLY, AUTH_READONLYNODISP, AUTH_UNRESTRICTED, AUTH_UNRESTRICTEDNODISP, AUTH_UNRESTRICTEDREADONLY, AUTH_VALHIDDEN
 
Constructor Summary
AuthFilterBase()
           
 
Method Summary
protected  int accAggregateUpdate(int accType, AuthUser user, java.lang.String msgClass, SandMessage msg, java.lang.String fieldName)
          Return the level of authorization for AggregateUpdate access.
static java.lang.String accessType(int access)
          Given an AuthFilter access constant, return a debug print name.
protected  SandAttrVal[] addMatch(SandAttrVal[] matches, SandAttrVal newmatch)
          Add this SandAttrVal to the existing array and return the new array.
protected  int checkAccess(int accType, AuthUser user, java.lang.String msgClass, SandMessage msg, java.lang.String fieldName)
          Given the type of checking and other message information return the level of authorization.
protected abstract  void debug(java.lang.String text)
          Log trace level and general information about what the AuthFilter is doing.
protected  void debugDumpMatches(java.lang.String prefix, SandAttrVal[] matches)
          Dump out the given matches using the debug dump method.
protected  int generatedFieldAccess(AuthUser user, SandMessage msg, java.lang.String fieldName)
          Return the authorization level for the given generated field within the given message for the given user.
 java.lang.String getBaseMsgClass(java.lang.String msgClass)
          Given the name of a message, return the short struct message name.
 java.lang.String getMatchValue(SandAttrVal[] matches, java.lang.String attr)
          Return the value specified for the give attr from the given matches, or null if not found.
protected  SandAttrVal[] getRestrictions(AuthUser user, java.lang.String msgClass, SandAttrVal[] givenMatches)
          Given the user, the class name of a message, and the existing match restrictions, return the additional match restrictions to be added to the query.
protected  long[] getSpecifiedUniqueIDs(SandAttrVal[] matches)
          Return an array of the uniqueID values specified.
protected  java.lang.String getUserDump(AuthUser user)
          Return a text identification of this user for debug logging.
 boolean hasMatch(SandAttrVal[] matches, java.lang.String attr, java.lang.String val)
          Return true if the given matches contains the given attrval, false otherwise.
 boolean hasSingleValueMatch(SandAttrVal[] matches, java.lang.String attr)
          Return true if the given matches contains a single value with no operator for the given attr.
 boolean isAdminRestrictedClass(java.lang.String className)
          If a class is restricted even for an admin user, then return true for that class name to authorize manually.
protected abstract  boolean isAdminUser(long id)
          Return true if the given id is the uniqueID of an admin user.
 boolean isClassNameMatch(java.lang.String testName, java.lang.String matchName)
          Return true if the testname specified is a direct match or common derived form for the matchname.
 boolean isCompletelyUnrestrictedClass(java.lang.String className)
          Return true if the given class is completely unrestricted in terms of authorization.
protected  boolean isGeneratedField(java.lang.String fieldName)
          Return true if the given field name is a framework generated field, false otherwise.
protected abstract  boolean isLoginMessageClass(java.lang.String className)
          Return true if the given class name is an AuthUser class that is used for login purposes.
protected abstract  boolean isSingletonInstance(SandUpdateMessage sum)
          Return true if the given message is an update of a singleton class that should not be deleted or have additional instances created, even by an admin.
 SandAttrVal[] matchRestrictions(AuthUser user, java.lang.String className, SandAttrVal[] savs)
          Return match criteria necessary to bound queries of this message class so that users can only access data they are allowed to see.
 int messageClassAccess(AuthUser user, java.lang.String className)
          Determine what users have access to what messages.
 int messageFieldAccess(AuthUser user, SandMessage msg, java.lang.String fieldName)
          Restrict access to some fields of the message data based on user ownership.
 int messageFieldValueAccess(AuthUser user, SandMessage msg, java.lang.String fieldName)
          Always returns AUTH_UNRESTRICTED.
 int messageInstanceAccess(AuthUser user, SandMessage msg)
          Determine if this user is allowed to view this instance of this message.
 java.lang.String shortenClassName(java.lang.String classname)
          Strip any preceding qualifications to return the short class name.
protected  long specifiedUniqueID(SandAttrVal[] matches)
          Return the uniqueID specified in the matches, or zero if no uniqueID is found.
 int tokenAccess(AuthUser user, java.lang.String token)
          The names of any screens, actions, or other tokens that should be hidden from the user.
protected  boolean uniqueIDSpecified(SandAttrVal[] matches)
          Return true if the uniqueID is specified as one of the match criteria, false otherwise.
 SandAttrVal[] verifyMatch(SandAttrVal[] newMatches, SandAttrVal[] oldMatches, java.lang.String attr, java.lang.String val)
          Walk the newMatches and the oldMatches checking for the given attr.
protected abstract  void warn(java.lang.String text)
          Log the given problem text for development reference.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ACCTYPE_CLASS

public static final int ACCTYPE_CLASS
message class access

See Also:
Constant Field Values

ACCTYPE_INSTANCE

public static final int ACCTYPE_INSTANCE
message instance access

See Also:
Constant Field Values

ACCTYPE_FIELD

public static final int ACCTYPE_FIELD
field access

See Also:
Constant Field Values

ACCTYPE_FIELDVAL

public static final int ACCTYPE_FIELDVAL
field value access

See Also:
Constant Field Values
Constructor Detail

AuthFilterBase

public AuthFilterBase()
Method Detail

isAdminUser

protected abstract boolean isAdminUser(long id)
Return true if the given id is the uniqueID of an admin user. The admin user is typically defined in the initial data and represents a user that is authorized for everything.


isLoginMessageClass

protected abstract boolean isLoginMessageClass(java.lang.String className)
Return true if the given class name is an AuthUser class that is used for login purposes. User login messages need to be let through for unqualified username/password queries in order to support authentication.


isSingletonInstance

protected abstract boolean isSingletonInstance(SandUpdateMessage sum)
Return true if the given message is an update of a singleton class that should not be deleted or have additional instances created, even by an admin. A typical example is the system status control record, but this can be anything. Note that the given update message may or may not contain the actual singleton instance.


debug

protected abstract void debug(java.lang.String text)
Log trace level and general information about what the AuthFilter is doing. For normal operations, it is recommended that the implementation of this method not actually produce output since the trace information can be quite verbose. However it may be useful for development to switch this on occasionally.


warn

protected abstract void warn(java.lang.String text)
Log the given problem text for development reference. This is used for problems that don't warrant an exception being thrown, but that should probably be looked into.


tokenAccess

public int tokenAccess(AuthUser user,
                       java.lang.String token)
                throws SandException
The names of any screens, actions, or other tokens that should be hidden from the user. This default implementation restricts the "Admin" token representing the Admin screen, to only users for whom isAdminUser returns true. Extend as needed.

Specified by:
tokenAccess in interface AuthFilter
Throws:
SandException

generatedFieldAccess

protected int generatedFieldAccess(AuthUser user,
                                   SandMessage msg,
                                   java.lang.String fieldName)
Return the authorization level for the given generated field within the given message for the given user. The given field name will be one of the names for which isGeneratedField returns true. By default this method returns the same value for a given field regardless of the message or user.

Persistency fields are maintained by the persistence processing and should never be modified directly by any user. Runtime and transient fields used for caching and message transmission are generally not part of editing a form.


isCompletelyUnrestrictedClass

public boolean isCompletelyUnrestrictedClass(java.lang.String className)
Return true if the given class is completely unrestricted in terms of authorization. For example this may be true for completely dependent (aggregated) class instances or some UI form classes.

A cache action is triggered in response to an update, and uses the SandTransmitAuthID of the update that caused it for transmission across an authorization boundary. The assumption is that cache information is not available outside the system, so there is no reason to restrict access to it.


isAdminRestrictedClass

public boolean isAdminRestrictedClass(java.lang.String className)
If a class is restricted even for an admin user, then return true for that class name to authorize manually. This method is primarily useful for restricting display classes like reports.


messageClassAccess

public int messageClassAccess(AuthUser user,
                              java.lang.String className)
                       throws SandException
Determine what users have access to what messages. This is set up so that access is generally denied, and then granted for known situations.

Specified by:
messageClassAccess in interface AuthFilter
Throws:
SandException

messageInstanceAccess

public int messageInstanceAccess(AuthUser user,
                                 SandMessage msg)
                          throws SandException
Determine if this user is allowed to view this instance of this message. At best, they will have the access allowed by the message class level access.

While this method will be called to filter a collection of instances, we don't want to be in a situation where we are pulling instances out of a collection because it has the potential for causing paging problems in the UI. Restricting collections is best done through matchRestrictions.

Specified by:
messageInstanceAccess in interface AuthFilter
Throws:
SandException

messageFieldAccess

public int messageFieldAccess(AuthUser user,
                              SandMessage msg,
                              java.lang.String fieldName)
                       throws SandException
Restrict access to some fields of the message data based on user ownership.

Specified by:
messageFieldAccess in interface AuthFilter
Throws:
SandException

messageFieldValueAccess

public int messageFieldValueAccess(AuthUser user,
                                   SandMessage msg,
                                   java.lang.String fieldName)
                            throws SandException
Always returns AUTH_UNRESTRICTED. We have yet to find a real use case where this level of authorization is worth it so this method is essentially stubbed out. The most typical case of a perceived need is for dynamic value selection of an enumerated type based on workflow parameters. This has more to do with appropriate value displays and business logic, not just authorization, so it is typically handled through the dynamic value selection and update validation mechanisms.

Specified by:
messageFieldValueAccess in interface AuthFilter
Throws:
SandException

matchRestrictions

public SandAttrVal[] matchRestrictions(AuthUser user,
                                       java.lang.String className,
                                       SandAttrVal[] savs)
                                throws SandException
Return match criteria necessary to bound queries of this message class so that users can only access data they are allowed to see. The returned data will still be subject to filtering, but the best security is to never to retrieve the data in the first place at any level.

Specified by:
matchRestrictions in interface AuthFilter
Throws:
SandException

checkAccess

protected int checkAccess(int accType,
                          AuthUser user,
                          java.lang.String msgClass,
                          SandMessage msg,
                          java.lang.String fieldName)
                   throws SandException
Given the type of checking and other message information return the level of authorization. The accType, user, and msgClass must always be specified. The msg must be specified for all access other than ACCTYPE_CLASS. The fieldName must be specified for ACCTYPE_FIELD or ACCTYPE_FIELDVAL access.

Throws:
SandException

accAggregateUpdate

protected int accAggregateUpdate(int accType,
                                 AuthUser user,
                                 java.lang.String msgClass,
                                 SandMessage msg,
                                 java.lang.String fieldName)
                          throws SandException
Return the level of authorization for AggregateUpdate access. The authorization for an AggregateUpdate is the minimum level of authorization available for each update instance.

Throws:
SandException

getRestrictions

protected SandAttrVal[] getRestrictions(AuthUser user,
                                        java.lang.String msgClass,
                                        SandAttrVal[] givenMatches)
                                 throws SandException
Given the user, the class name of a message, and the existing match restrictions, return the additional match restrictions to be added to the query.

Throws:
SandException

shortenClassName

public java.lang.String shortenClassName(java.lang.String classname)
Strip any preceding qualifications to return the short class name. This is for times when we want to check how the classname starts, and we aren't worried about name collisions.


accessType

public static java.lang.String accessType(int access)
Given an AuthFilter access constant, return a debug print name.


isGeneratedField

protected boolean isGeneratedField(java.lang.String fieldName)
Return true if the given field name is a framework generated field, false otherwise.


getUserDump

protected java.lang.String getUserDump(AuthUser user)
Return a text identification of this user for debug logging.


addMatch

protected SandAttrVal[] addMatch(SandAttrVal[] matches,
                                 SandAttrVal newmatch)
Add this SandAttrVal to the existing array and return the new array.


debugDumpMatches

protected void debugDumpMatches(java.lang.String prefix,
                                SandAttrVal[] matches)
Dump out the given matches using the debug dump method.


uniqueIDSpecified

protected boolean uniqueIDSpecified(SandAttrVal[] matches)
Return true if the uniqueID is specified as one of the match criteria, false otherwise.


getSpecifiedUniqueIDs

protected long[] getSpecifiedUniqueIDs(SandAttrVal[] matches)
Return an array of the uniqueID values specified. If no uniqueID attribute was specified then this returns a zero length array. If there are several uniqueID matches specified, then we want the last one only. That's how the queries are ultimately processed against the DB (byproduct of using a SortedMap) so that's what we do here also.


specifiedUniqueID

protected long specifiedUniqueID(SandAttrVal[] matches)
Return the uniqueID specified in the matches, or zero if no uniqueID is found. This assumes a single uniqueID spec.


getBaseMsgClass

public java.lang.String getBaseMsgClass(java.lang.String msgClass)
Given the name of a message, return the short struct message name.


isClassNameMatch

public boolean isClassNameMatch(java.lang.String testName,
                                java.lang.String matchName)
Return true if the testname specified is a direct match or common derived form for the matchname. So for example a matchname of "SystemStatus" would return true against testnames of "SystemStatus", "SystemStatusUpdate", "SystemStatusQuery", "SystemStatusCollection", "org.sandev.TaskHeap.sandmessages.SystemStatus" etc.


verifyMatch

public SandAttrVal[] verifyMatch(SandAttrVal[] newMatches,
                                 SandAttrVal[] oldMatches,
                                 java.lang.String attr,
                                 java.lang.String val)
Walk the newMatches and the oldMatches checking for the given attr. If found, set the value as specified and return newMatches. Otherwise append the new attr val to newMatches and return the result.


hasMatch

public boolean hasMatch(SandAttrVal[] matches,
                        java.lang.String attr,
                        java.lang.String val)
Return true if the given matches contains the given attrval, false otherwise. This utility method does not trap if any of the given values are null, since that's an invalid call and having a crash at that point makes it easier to identify errors in the calling code.


hasSingleValueMatch

public boolean hasSingleValueMatch(SandAttrVal[] matches,
                                   java.lang.String attr)
Return true if the given matches contains a single value with no operator for the given attr. Used to test that the matches are querying for a specific value only.


getMatchValue

public java.lang.String getMatchValue(SandAttrVal[] matches,
                                      java.lang.String attr)
Return the value specified for the give attr from the given matches, or null if not found.