Expresso 5-6

com.jcorporate.expresso.core.dbobj
Class RowSecuredDBObject

java.lang.Object
  extended bycom.jcorporate.expresso.core.dataobjects.BaseDataObject
      extended bycom.jcorporate.expresso.core.dataobjects.jdbc.JDBCDataObject
          extended bycom.jcorporate.expresso.core.dbobj.DBObject
              extended bycom.jcorporate.expresso.core.dbobj.SecuredDBObject
                  extended bycom.jcorporate.expresso.core.dbobj.RowSecuredDBObject
All Implemented Interfaces:
Cacheable, ContextNested, DataObject, LookupInterface, Securable, Serializable

public class RowSecuredDBObject
extends SecuredDBObject

subclass this for support of row-level Authorization.

Typically, you construct RowSecuredDBObject passing in userId or the controller request to set the requesting identity. Or, after construction, call setRequestingUid() so that user of this DBObject is known. Otherwise, security checks will always return false (and access methods will throw SecurityException).

LIMITATION: the primary key for a given row is persisted, along with the name of the table, to identify the permissions for that row. In other words, the primary key for permissions is the row's table name plus the row's primary key: permissionPK = targetTable + targetPrimKey. Each database vendor (MySQL, Oracle, etc.) has its own limit for the longest field that can be indexed as a primary key. If a target row has a very long primary key, the database may not be able to accommodate the primary key for its permissions. In that case, a runtime exception is thrown when trying to persist the permissions. If (length(permissionPK) > MAXIMUM for database) { throw runtime exception} In most cases, the primary key is an integer or some other short field, so this limitation is not a problem.

LIMITATION: all permissions are stored in a two tables: RowPermissions & RowGroupPerms. If your application has many tables (dbobjects) which all subclass RowSecuredDBObject, and also has many rows in these tables, you could run into scaling issues first with permissions. Use RowSecuredDBObject subclasses for only the important objects. Roll your own security scheme if you expect a very large database... and tell us how you did it. :-)

Author:
larry hamel, CodeGuild, Inc.
See Also:
RowPermissions, RowGroupPerms, Serialized Form

Nested Class Summary
 
Nested classes inherited from class com.jcorporate.expresso.core.dbobj.DBObject
DBObject.FieldError, DBObject.FieldUpdate
 
Field Summary
 
Fields inherited from class com.jcorporate.expresso.core.dbobj.SecuredDBObject
ADD, ALL_FUNCTIONS, CACHE_NAME, CACHE_TTY, DELETE, SEARCH, SYSTEM_ACCOUNT, SYSTEM_ACCOUNT_NAME, UPDATE
 
Fields inherited from class com.jcorporate.expresso.core.dbobj.DBObject
ATTRIBUTE_ERROR, ATTRIBUTE_ERROR_MESSAGE, ATTRIBUTE_PAGE_LIMIT, BIG_DECIMAL_ZERO, EMAIL_MASK, EVENT_ADD, EVENT_DELETE, EVENT_UPDATE, FLOAT_MASK, INT_MASK, IS_CHECK_RELATIONAL_INTEGRITY, UPDATE_CHANGED_ONLY, WHERE_KEYWORD
 
Fields inherited from class com.jcorporate.expresso.core.dataobjects.jdbc.JDBCDataObject
anyFieldsDistinct, anyFieldsToRetrieve, appendCustomWhere, caseSensitiveQuery, customWhereClause, dbKey, distinctFields, localConnection, LONGBINARY_READ_DEFAULT_SIZE, maxRecords, myClassName, myUpdates, offsetRecord, recordSet, retrieveFields, sMetadataMap, sortKeys
 
Fields inherited from class com.jcorporate.expresso.core.dataobjects.BaseDataObject
currentStatus, globalMask
 
Fields inherited from interface com.jcorporate.expresso.core.dataobjects.DataObject
STATUS_CURRENT, STATUS_DELETED, STATUS_NEW, STATUS_UPDATED
 
Constructor Summary
RowSecuredDBObject()
          Constructor without parameters.
RowSecuredDBObject(DBConnection theConnection, int theUser)
          Constructor: Specify a DB connection AND user id.
RowSecuredDBObject(int theUser)
          Creates a new RowSecuredDBObject object.
RowSecuredDBObject(RequestContext request)
          Creates a new RowSecuredDBObject object.
 
Method Summary
 void add()
          we override not to check permissions (which is done at the table level by superclass) but rather to add default permissions
 void add(String group, int permissions)
           
 void addGroupPerm(String group, int perm)
          add permissions for a group; will only ADD permissions, not replace will add row or update existing row (logical OR of bits) as necessary
 boolean canRequesterAdministrate()
           
 boolean canRequesterRead()
          determine if getRequestingUid has rights to read this row
 boolean canRequesterWrite()
           
protected  void checkDeleteDetailPerm(DBObject obj)
          check delete privilege for all detail records; different than superclass because we must set uid
protected  void checkKeyLength()
          // warn if key of this row may be too long
 String defaultGroup()
           
 int defaultPermissions()
          override this to change default
 void delete(boolean deleteDetails)
          delete row. always delete permission records too
 void deleteAll()
          check that all objects can be deleted; must retrieve all objects to check individually
 boolean find()
          find object on criteria provided in fields
 List getAdministrateGroups()
           
 List getGroups()
          find any existing permission groups for this object.
 RowPermissions getPermissions()
          finds row permissions for the target row of this DBObject. if no row permissions are already persisted, the returned permissions object will be constructed and keyed to generating object, but all permissions will be false
 List getReadGroups()
           
 List getWriteGroups()
           
 boolean isRowAllowed(String requestedFunction)
          determine if this function is allowed for this requesting user
 boolean isRowAllowed(String requestedFunction, Collection items)
          iterate through collection, testing each row's privileges remove any row which does not have privileges; (do not throw security exception, just remove row)
 int ownerID()
           
 void removeGroup(String group)
          remove a permissions group
 void retrieve()
          retrieve object on criteria provided in fields
 ArrayList searchAndRetrieveList()
          search on criteria provided in fields, and after search phase iterate through collection, testing each row's privileges remove any row which does not have privileges; (do not throw security exception, just remove row)
 ArrayList searchAndRetrieveList(String sortKeys)
          search on criteria provided in fields, and after search phase iterate through collection, testing each row's privileges remove any row which does not have privileges; (do not throw security exception, just remove row) sort results by sortKeys
 void setPermissions(int perm)
          set the permissions for this object; group bits are ignored; only owner & "other" permissions apply with this method owner id is taken from getRequestingUid()
 void setPermissions(String group, int perm)
          set the group and permissions for this object; owner id is taken from getRequestingUid() before permissions can be set, caller's permission to change permissions is tested
 void update()
          before allowing update, check permission
 
Methods inherited from class com.jcorporate.expresso.core.dbobj.SecuredDBObject
canRequesterAdd, canRequesterDelete, canRequesterUpdate, checkAllowed, copyAttributes, count, createSecurityCache, delete, getRequestingUid, getString, getString, getString, getString, getString, getString, getSystemUid, instantiate, isAllowed, search, setRequestingUid
 
Methods inherited from class com.jcorporate.expresso.core.dbobj.DBObject
addDetail, addField, addField, addFieldError, addFoundKeys, addIfNeeded, addIndex, addKey, addOrUpdate, addSortKey, addTransition, addVirtualField, addVirtualField, addVirtualField, addVirtualField, average, basicAdd, cacheIsChangedComparison, checkAllReferredToBy, checkAllRefs, checkAllRefsPublic, checkField, checkRef, checkRef, clear, clearDistinctFields, clearError, clearFieldsToRetrieve, clearSortKeys, containsWildCards, deleteAll, deleteDetails, denotesRange, equals, forKey, formatDateTime, get, getAllAttributes, getAttribute, getAttributesIterator, getBooleanFieldValue, getCacheSize, getCacheStatsMap, getCacheUtil, getCheckZeroUpdate, getCustomWhereClause, getDataContext, getDataField, getDataTransferObject, getDBName, getDetails, getDistinctFieldCount, getDistinctFields, getField, getFieldBigDecimal, getFieldBoolean, getFieldByte, getFieldByteArray, getFieldData, getFieldDate, getFieldDecimalFormatted, getFieldDouble, getFieldErrorMessage, getFieldFloat, getFieldInt, getFieldLong, getFieldMetaData, getFieldShort, getFieldsToRetrieveCount, getFilterClass, getFoundCount, getFoundKeysArray, getIndexArray, getISOValuesDefault, getISOValuesDefault, getISOValuesDefault, getKey, getKeyFieldListIterator, getLength, getLengthInt, getLocalConnection, getLocale, getLogger, getLookupObject, getMax, getMax, getMaxRecords, getMyKeys, getMyUpdatesArray, getOffsetRecord, getPatternMatcher, getPrecision, getSerializedForm, getStringFilter, getThisDBbj, getThisDBObj, getValidValueDescrip, getValidValues, getValidValuesList, getValues, getValuesDefault, getValuesDefault, getValuesDefault, hasError, hasErrors, haveAllKeys, initialize, isCached, isChanged, isDistinct, isEmpty, isFieldDistinct, isFieldNull, isFieldsToRetrieve, isFieldToRetrieve, isMultiValued, isReadOnly, isSecret, isVirtual, loadFromConnection, logChange, max, min, newInstance, noNewLine, noQuotes, notifyListeners, populateDefaultValues, referredToBy, removeAttribute, removeFromCache, retrieveFromCache, saveBinaryField, search, set, setAttribute, setCacheSize, setCharset, setCheckZeroUpdate, setConnection, setConnection, setCustomWhereClause, setCustomWhereClause, setDataContext, setDataField, setDataTransferObject, setDefaultValue, setDescription, setField, setField, setField, setField, setField, setField, setField, setField, setField, setField, setFieldData, setFieldData, setFieldDistinct, setFieldsToRetrieve, setFilterClass, setFilterClass, setKeys, setLocale, setLookupField, setLookupObject, setMask, setMaxRecords, setMultiValued, setName, setOffsetRecord, setReadOnly, setSchema, setSecret, setSortKey, setStringFilter, setStringFiltersOnAll, setTargetDbSchema, setTargetTable, setupFields, sqlAggrFunction, sum, toDebugString, update, updateAll, updateAll, verify
 
Methods inherited from class com.jcorporate.expresso.core.dataobjects.jdbc.JDBCDataObject
addInParam, addOutParam, buildWhereClause, buildWhereClauseBuffer, checkZeroUpdate, constructNewMetaData, createAndExecuteSearch, createAndRunStoreProcedure, getConnectionPool, getCustomStringFieldValue, getDef, getDistinctFieldArrayList, getExecutor, getFieldsToRetrieveIterator, getJDBCMetaData, getJDBCUtil, getMappedDataContext, getMetaData, getQueryInterface, getSerialForm, loadFromConnection, makeLimitationStub, quoteIfNeeded, runStoredProcedure, runStoredProcedureAndRetrieveList, selectFieldString, setCaseSensitiveQuery, setDBConnectionPool, setDBName, setMappedDataContext, setOriginalDBName, setTargetStoreProcedure
 
Methods inherited from class com.jcorporate.expresso.core.dataobjects.BaseDataObject
getGlobalMask, getStatus, isGlobalMasked, setFieldsWithDefaults, setGlobalMask, setStatus
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

RowSecuredDBObject

public RowSecuredDBObject()
                   throws DBException
Constructor without parameters. This constructor will attempt to use servlet filter to set data context and user ID from expresso v.5.6. However, if you have not set up this filter in web.xml, be sure to set dbname and user id after constructing.

Throws:
DBException - upon database communication error

RowSecuredDBObject

public RowSecuredDBObject(DBConnection theConnection,
                          int theUser)
                   throws DBException
Constructor: Specify a DB connection AND user id.

Parameters:
theConnection - A DBConnection that this object should use to connect to the database
theUser - User name attempting to use this object. If this is "SYSTEM", then full permissions are granted. Note that you cannot log in as "SYSTEM", it can only be used from within a method.
Throws:
DBException - If the object cannot be created

RowSecuredDBObject

public RowSecuredDBObject(int theUser)
                   throws DBException
Creates a new RowSecuredDBObject object. This constructor will attempt to use servlet filter to set data context--from expresso v.5.6. However, if you have not set up this filter in web.xml, be sure to set dbname and user id after constructing.

Parameters:
theUser - requesting user
Throws:
DBException - upon database communication error

RowSecuredDBObject

public RowSecuredDBObject(RequestContext request)
                   throws DBException
Creates a new RowSecuredDBObject object.

Parameters:
request - context for using this object
Throws:
DBException - upon database communication error
Method Detail

getAdministrateGroups

public List getAdministrateGroups()
                           throws DBException
Returns:
list of a group names (strings) which have permission to change permission
Throws:
DBException - upon database communication error

getGroups

public List getGroups()
               throws DBException
find any existing permission groups for this object. Typically, subclasses will call getReadGroups and getWriteGroups instead of this method

Returns:
list of RowGroupPerms
Throws:
DBException - upon database communication error

setPermissions

public void setPermissions(String group,
                           int perm)
                    throws DBException
set the group and permissions for this object; owner id is taken from getRequestingUid() before permissions can be set, caller's permission to change permissions is tested

Parameters:
group - name of group
perm - value of permissions
Throws:
DBException - upon database communication error

setPermissions

public void setPermissions(int perm)
                    throws DBException
set the permissions for this object; group bits are ignored; only owner & "other" permissions apply with this method owner id is taken from getRequestingUid()

Parameters:
perm - permissions to set
Throws:
DBException - upon database communication error

getPermissions

public RowPermissions getPermissions()
                              throws DBException
finds row permissions for the target row of this DBObject. if no row permissions are already persisted, the returned permissions object will be constructed and keyed to generating object, but all permissions will be false

Returns:
RowPermissions of the current perms
Throws:
DBException - if keys are not set on this object

getReadGroups

public List getReadGroups()
                   throws DBException
Returns:
list of group names (strings) which have read permission
Throws:
DBException - upon database communication error

isRowAllowed

public boolean isRowAllowed(String requestedFunction)
                     throws DBException
determine if this function is allowed for this requesting user

Parameters:
requestedFunction - code for function -- Add, Update, Delete, Search (read)
Returns:
true if this function is allowed for this requesting user
Throws:
SecurityException - (unchecked) if not allowed
DBException - for other data-related errors.

isRowAllowed

public boolean isRowAllowed(String requestedFunction,
                            Collection items)
                     throws DBException
iterate through collection, testing each row's privileges remove any row which does not have privileges; (do not throw security exception, just remove row)

Parameters:
requestedFunction - code for function -- Add, Update, Delete, Search (read)
items - is a collection of RowSecuredDBObjects
Returns:
true if AT LEAST ONE item in collectino is allowed; also manipulates input list, removing unallowed items
Throws:
DBException - upon database communication error

getWriteGroups

public List getWriteGroups()
                    throws DBException
Returns:
list of group names (strings) which have write permission
Throws:
DBException - upon database communication error

add

public void add()
         throws DBException
we override not to check permissions (which is done at the table level by superclass) but rather to add default permissions

Specified by:
add in interface DataObject
Overrides:
add in class SecuredDBObject
Throws:
DBException - upon database communication error
See Also:
for a way to add() with more specific permissions

add

public void add(String group,
                int permissions)
         throws DBException
Throws:
DBException

addGroupPerm

public void addGroupPerm(String group,
                         int perm)
                  throws DBException
add permissions for a group; will only ADD permissions, not replace will add row or update existing row (logical OR of bits) as necessary

Parameters:
group - to be added
perm - to be added
Throws:
DBException - upon database communication error

canRequesterAdministrate

public boolean canRequesterAdministrate()
                                 throws DBException
Returns:
true if requesting id has permission to administrate (change permissions)
Throws:
DBException - upon database communication error

canRequesterRead

public boolean canRequesterRead()
                         throws DBException
determine if getRequestingUid has rights to read this row

Overrides:
canRequesterRead in class SecuredDBObject
Returns:
true if getRequestingUid has rights to read this row
Throws:
DBException - upon database communication error

canRequesterWrite

public boolean canRequesterWrite()
                          throws DBException
Returns:
true if requesting id has permission to write
Throws:
DBException - upon database communication error

defaultGroup

public String defaultGroup()
                    throws DBException
Returns:
the default group for this requesting user; null if user has no groups
Throws:
DBException - upon database communication error

defaultPermissions

public int defaultPermissions()
override this to change default

Returns:
the default permissions

delete

public void delete(boolean deleteDetails)
            throws DBException
delete row. always delete permission records too

Overrides:
delete in class DBObject
Parameters:
deleteDetails - set to true if related details should be deleted also
Throws:
DBException - upon database communication error
See Also:
to delete objects identified by non-key fields

deleteAll

public void deleteAll()
               throws DBException
check that all objects can be deleted; must retrieve all objects to check individually

Overrides:
deleteAll in class SecuredDBObject
Throws:
DBException - upon database communication error

find

public boolean find()
             throws DBException
find object on criteria provided in fields

Specified by:
find in interface DataObject
Overrides:
find in class SecuredDBObject
Returns:
true if found AND allowed
Throws:
DBException - if user does not have rights to read found item

ownerID

public int ownerID()
            throws DBException
Returns:
uid of owner of this object
Throws:
DBException - upon database communication error

removeGroup

public void removeGroup(String group)
                 throws DBException
remove a permissions group

Parameters:
group - to be removed
Throws:
DBException - upon database communication error

retrieve

public void retrieve()
              throws DBException
retrieve object on criteria provided in fields

Overrides:
retrieve in class SecuredDBObject
Throws:
DBException - upon database communication error

searchAndRetrieveList

public ArrayList searchAndRetrieveList()
                                throws DBException
search on criteria provided in fields, and after search phase iterate through collection, testing each row's privileges remove any row which does not have privileges; (do not throw security exception, just remove row)

Specified by:
searchAndRetrieveList in interface DataObject
Overrides:
searchAndRetrieveList in class SecuredDBObject
Returns:
list of RowSecuredDBObject's which are both found AND allowed for this requester
Throws:
DBException - upon database communication error

searchAndRetrieveList

public ArrayList searchAndRetrieveList(String sortKeys)
                                throws DBException
search on criteria provided in fields, and after search phase iterate through collection, testing each row's privileges remove any row which does not have privileges; (do not throw security exception, just remove row) sort results by sortKeys

Specified by:
searchAndRetrieveList in interface DataObject
Overrides:
searchAndRetrieveList in class SecuredDBObject
Parameters:
sortKeys - sort field(s)
Returns:
list of RowSecuredDBObject's which are both found AND allowed for this requester
Throws:
DBException - upon database communication error

update

public void update()
            throws DBException
before allowing update, check permission

Specified by:
update in interface DataObject
Overrides:
update in class SecuredDBObject
Throws:
DBException - upon database communication error

checkDeleteDetailPerm

protected void checkDeleteDetailPerm(DBObject obj)
                              throws DBException
check delete privilege for all detail records; different than superclass because we must set uid

Overrides:
checkDeleteDetailPerm in class DBObject
Parameters:
obj - Object to be checked for deletion of detail records
Throws:
DBException - upon database communication error

checkKeyLength

protected void checkKeyLength()
                       throws DBException
// warn if key of this row may be too long

Throws:
DBException - upon error

Expresso 5-6

Please see www.jcorporate.com for information about new Expresso releases.