Class RowLevelSecurityServiceImpl
- All Implemented Interfaces:
ExceptionAwareRowLevelSecurityProvider
,RowLevelSecurityProvider
,RowLevelSecurityService
- Author:
- Phillip Verheyden (phillipuniverse), Jeff Fischer
- See Also:
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoid
addFetchRestrictions
(AdminUser currentUser, String ceilingEntity, List<jakarta.persistence.criteria.Predicate> restrictions, List<jakarta.persistence.criteria.Order> sorts, jakarta.persistence.criteria.Root entityRoot, jakarta.persistence.criteria.CriteriaQuery criteria, jakarta.persistence.criteria.CriteriaBuilder criteriaBuilder) Used to further restrict a result set in the admin for a particular admin user.boolean
canAdd
(AdminUser currentUser, String sectionClassName, ClassMetadata cmd) Hook to determine if the given entity can be added by a user.boolean
Hook to determine if the given entity can be deleted by a user.boolean
Hook to determine if the given entity can be updated or not.getFetchRestrictionRoot
(AdminUser currentUser, Class<Serializable> ceilingEntity, List<FilterMapping> filterMappings) Contributes toRoot
determination forRowLevelSecurityProvider.addFetchRestrictions(AdminUser, String, List, List, Root, CriteriaQuery, CriteriaBuilder)
.Gets all of the registered providersProvide a modifier capable of manipulating anEntityForm
that has been marked as readonly and modify its state, presumably to set one or more aspects of the form as editable.void
setProviders
(List<RowLevelSecurityProvider> providers) validateAddRequest
(AdminUser currentUser, Entity entity, PersistencePackage persistencePackage) Validates whether a user has permissions to actually perform the record addition.validateRemoveRequest
(AdminUser currentUser, Entity entity, PersistencePackage persistencePackage) Validates whether a user has permissions to actually perform the record deletion.validateUpdateRequest
(AdminUser currentUser, Entity entity, PersistencePackage persistencePackage) Validates whether a user has permissions to actually perform the update.
-
Field Details
-
providers
-
-
Constructor Details
-
RowLevelSecurityServiceImpl
public RowLevelSecurityServiceImpl()
-
-
Method Details
-
addFetchRestrictions
public void addFetchRestrictions(AdminUser currentUser, String ceilingEntity, List<jakarta.persistence.criteria.Predicate> restrictions, List<jakarta.persistence.criteria.Order> sorts, jakarta.persistence.criteria.Root entityRoot, jakarta.persistence.criteria.CriteriaQuery criteria, jakarta.persistence.criteria.CriteriaBuilder criteriaBuilder) Description copied from interface:RowLevelSecurityProvider
Used to further restrict a result set in the admin for a particular admin user. This can be done by adding additional
Predicate
s to the given list of restrictions. You can also attach additional sorting from the given list of sorts.You should not attach any of these
Predicate
s to the given criteria, you should instead modify the given lists. These lists will be automatically attached to the criteria after execution.Existing
Predicate
s and sorts will already be added into the given restrictions and sorts lists.If you are filtering on a property that exists only in a subclass of an OOB framework entity (like if you extended ProductImpl and you need to add a restriction targeting MyProductImpl) then you need to override
RowLevelSecurityProvider.getFetchRestrictionRoot(AdminUser, Class, List)
to return the class that you are adding criteria to. Otherwise, the entityRoot will be wrong and if you try to get aPath
from it then you will run intoIllegalArgumentException
s.This method is executed prior to any
CriteriaTranslatorEventHandler
.- Specified by:
addFetchRestrictions
in interfaceRowLevelSecurityProvider
- Parameters:
currentUser
- the currently logged inAdminUser
ceilingEntity
- the entity currently being queried fromrestrictions
- the restrictions that will be applied to the criteria but have not been yet. AdditionalPredicate
s to further filter the query should be added to this listsorts
- the sorts that will be applied to the criteria. Additional sorts should be added to this listentityRoot
- the JPA root for ceilingEntitycriteria
- the criteria that will be executed. NoPredicate
s orOrder
s have been applied to this criteria, and nor should they be. All modifications should instead be to the given restrictions and/or sortscriteriaBuilder
- used to create additionalPredicate
s orOrder
s to add to restrictions and/or sorts
-
getFetchRestrictionRoot
public Class<Serializable> getFetchRestrictionRoot(AdminUser currentUser, Class<Serializable> ceilingEntity, List<FilterMapping> filterMappings) Description copied from interface:RowLevelSecurityProvider
Contributes to
Root
determination forRowLevelSecurityProvider.addFetchRestrictions(AdminUser, String, List, List, Root, CriteriaQuery, CriteriaBuilder)
. Normally, the queryRoot
is determined in the admin via the given filterMappings. Since row security deals with aCriteriaBuilder
directly, if you want to be able to target subclasses then a newRoot
must be established for that specific subclass.Note that depending on how you have your filters in the admin frontend (the list grids) set up, you might have to take into account the given filterMappings. The admin will not be able to find a correct root if there is an active filter set on a sibling class that you are attempting to also add more criteria to. For instance, if a class hierarchy exists for A -> B and also A -> C, if there is an active
FilterMapping
for a property from B and you attempt to add a fetch restriction on a property from C that will not work.It is acceptable to return null from this method if
RowLevelSecurityProvider.addFetchRestrictions(AdminUser, String, List, List, Root, CriteriaQuery, CriteriaBuilder)
does not rely on any properties from a child class.- Specified by:
getFetchRestrictionRoot
in interfaceRowLevelSecurityProvider
ceilingEntity
- the entity being queried forfilterMappings
- the existing filters passed from the admin frontend- Returns:
- the root class that is going to be used for
RowLevelSecurityProvider.addFetchRestrictions(AdminUser, String, List, List, Root, CriteriaQuery, CriteriaBuilder)
or null if no specific root needs to be used
-
canUpdate
Description copied from interface:RowLevelSecurityProvider
Hook to determine if the given entity can be updated or not. This is used to drive the form displayed in the admin frontend to remove modifier actions and set the entire
EntityForm
as readonly.If the entity cannot be updated, then by default it can also not be removed. You can change this by explicitly overriding
RowLevelSecurityProvider.canRemove(AdminUser, Entity)
- Specified by:
canUpdate
in interfaceRowLevelSecurityProvider
- Parameters:
currentUser
- the currently logged inAdminUser
entity
- theEntity
DTO that is attempting to be updated- Returns:
- true if the given entity can be updated, false otherwise
-
getUpdateDenialExceptions
Description copied from interface:ExceptionAwareRowLevelSecurityProvider
Provide a modifier capable of manipulating anEntityForm
that has been marked as readonly and modify its state, presumably to set one or more aspects of the form as editable.- Specified by:
getUpdateDenialExceptions
in interfaceExceptionAwareRowLevelSecurityProvider
- Returns:
- package containing the modifier implementations and any configurations for those modifiers
- See Also:
-
canRemove
Description copied from interface:RowLevelSecurityProvider
Hook to determine if the given entity can be deleted by a user. This is used to drive the
DefaultEntityFormActions.DELETE
button from appearing on the admin frontend.You might consider tying the remove to
RowLevelSecurityProvider.canUpdate(AdminUser, Entity)
and explicitly invoking that action yourself.- Specified by:
canRemove
in interfaceRowLevelSecurityProvider
- Parameters:
currentUser
- the currently logged inAdminUser
- Returns:
- true if the given entity can be deleted, false otherwise
-
canAdd
Description copied from interface:RowLevelSecurityProvider
Hook to determine if the given entity can be added by a user.
- Specified by:
canAdd
in interfaceRowLevelSecurityProvider
- Parameters:
currentUser
- the currently logged inAdminUser
- Returns:
- true if the given entity can be added, false otherwise
-
validateUpdateRequest
public GlobalValidationResult validateUpdateRequest(AdminUser currentUser, Entity entity, PersistencePackage persistencePackage) Description copied from interface:RowLevelSecurityProvider
Validates whether a user has permissions to actually perform the update. The result of this method is a validation result that indicates if something in the entire entity is in error. The message key from the resulting
GlobalValidationResult
will be automatically added to the given entityEntity.getGlobalValidationErrors()
.If you would like to add individual property errors, you can do that with the given entity by using
Entity.addValidationError(String, String)
. Even if you attach errors to specific properties you should still return an appropriateGlobalValidationResult
. In that case however, it might be more suitable to use aPropertyValidator
instead.For convenience, this is usually a simple invocation to
RowLevelSecurityProvider.canUpdate(AdminUser, Entity)
. However, it might be that you want to allow the user to see certain update fields but not allow the user to save certain fields for update.- Specified by:
validateUpdateRequest
in interfaceRowLevelSecurityProvider
- Parameters:
currentUser
- the currently logged inAdminUser
entity
- the DTO representation that is attempting to be deleted. Comes fromPersistencePackage.getEntity()
persistencePackage
- the full persiste- Returns:
- a
GlobalValidationResult
withGlobalValidationResult.isValid()
set to denote if the given entity failed row-level security validation or not.
-
validateRemoveRequest
public GlobalValidationResult validateRemoveRequest(AdminUser currentUser, Entity entity, PersistencePackage persistencePackage) Description copied from interface:RowLevelSecurityProvider
Validates whether a user has permissions to actually perform the record deletion. The result of this method is a validation result that indicates if something in the entire entity is in error. The message key from the resulting
GlobalValidationResult
will be automatically added to the given entityEntity.getGlobalValidationErrors()
.If you would like to add individual property errors, you can do that with the given entity by using
Entity.addValidationError(String, String)
. Even if you attach errors to specific properties you should still return an appropriateGlobalValidationResult
. In that case however, it might be more suitable to use aPropertyValidator
instead.This is usually a simple invocation to
#canDelete(AdminUser, Entity)
.- Specified by:
validateRemoveRequest
in interfaceRowLevelSecurityProvider
- Parameters:
currentUser
- the currently logged inAdminUser
entity
- the DTO representation that is attempting to be deleted. Comes fromPersistencePackage.getEntity()
persistencePackage
- the full request sent from the frontend through the admin pipeline- Returns:
- a
GlobalValidationResult
withGlobalValidationResult.isValid()
set to denote if the given entity failed row-level security validation or not.
-
validateAddRequest
public GlobalValidationResult validateAddRequest(AdminUser currentUser, Entity entity, PersistencePackage persistencePackage) Description copied from interface:RowLevelSecurityProvider
Validates whether a user has permissions to actually perform the record addition. The result of this method is a validation result that indicates if something in the entire entity is in error. The message key from the resulting
GlobalValidationResult
will be automatically added to the given entityEntity.getGlobalValidationErrors()
.If you would like to add individual property errors, you can do that with the given entity by using
Entity.addValidationError(String, String)
. Even if you attach errors to specific properties you should still return an appropriateGlobalValidationResult
. In that case however, it might be more suitable to use aPropertyValidator
instead.This is usually a simple invocation to
#canAdd(AdminUser, Entity)
.- Specified by:
validateAddRequest
in interfaceRowLevelSecurityProvider
- Parameters:
currentUser
- the currently logged inAdminUser
entity
- the DTO representation that is attempting to be deleted. Comes fromPersistencePackage.getEntity()
persistencePackage
- the full request sent from the frontend through the admin pipeline- Returns:
- a
GlobalValidationResult
withGlobalValidationResult.isValid()
set to denote if the given entity failed row-level security validation or not.
-
getProviders
Description copied from interface:RowLevelSecurityService
Gets all of the registered providers- Specified by:
getProviders
in interfaceRowLevelSecurityService
- Returns:
- the providers configured for this service
-
setProviders
-