Class DefaultAdminRoleContextValidator<P extends AdminRole>

java.lang.Object
com.broadleafcommerce.adminuser.user.service.DefaultAdminRoleContextValidator<P>
All Implemented Interfaces:
AdminRoleContextValidator<P>

public class DefaultAdminRoleContextValidator<P extends AdminRole> extends Object implements AdminRoleContextValidator<P>
Default validator for use on AdminRole creation/modification/deletion. Verifies the following:
  1. the current authentication is not application restricted (and can therefore modify these tenant-level entities)
  2. the current context is able to create/modify the role
  3. the permissions specified for a role exist and are accessible from the role's context - a global role can assign only global permissions, while a tenant-level role can assign global permissions or permissions from the same tenant
  4. the tenant ID of a role can never be changed
  5. the name of a role is non-empty and unique within its context
  6. the direct parent of a role exists and is accessible from the role's context - a global role can only assign a global parent, while a tenant-level role can assign a global parent or parents from the same tenant
Author:
Samarth Dhruva (samarthd)
  • Constructor Summary

    Constructors
    Constructor
    Description
    DefaultAdminRoleContextValidator(com.broadleafcommerce.common.extension.TypeFactory typeFactory, com.broadleafcommerce.data.tracking.core.policy.PolicyUtils policyUtils)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    protected com.broadleafcommerce.data.tracking.core.context.ContextRequest
    Builds a ContextRequest that has a ContextRequest.tenantId matching the AdminRole.tenantId.
    protected boolean
    Uses policyUtils to check if currently authenticated user has tenant access.
     
    protected AdminRoleService<P>
     
    protected Map<String,Object>
     
    protected String
     
    protected org.springframework.validation.Errors
    getErrors(P role)
     
    protected com.broadleafcommerce.data.tracking.core.policy.PolicyUtils
     
    protected com.broadleafcommerce.common.extension.TypeFactory
     
    boolean
    isMutableFromContext(P role, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Returns whether or not the given entity is mutable from the given context.
    protected boolean
    Given a role that has a non-empty AdminRole.parentRoleId, validates that the parent exists and is accessible from the child's context.
    protected String
     
    void
    Lazy injection since this validator is itself a service component.
    void
    Lazy injection since this validator is itself a service component.
    org.springframework.validation.Errors
    validateCreate(P role, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Validates a create operation is allowed in the current context.
    void
    validateCreate(P role, org.springframework.validation.Errors errors, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Validates a create operation is allowed in the current context.
    protected void
    Since roles are a tenant-level concept, only tenant access users can perform creation/modification operations on them.
    org.springframework.validation.Errors
    validateDelete(P role, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Validates a delete operation is allowed in the current context.
    void
    validateDelete(P role, org.springframework.validation.Errors errors, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Validates a delete operation is allowed in the current context.
    protected void
    validateDirectlyAssignedPermissions(P role, org.springframework.validation.Errors errors)
     
    protected void
    validateNameUniqueInRoleContext(String id, P role, org.springframework.validation.Errors errors)
    While it is perfectly valid for two tenant-level roles in different tenants to have the same name, we want to avoid having duplicate names from the perspective of a particular tenant context (to prevent confusion).
    protected void
    validateParentRole(P role, org.springframework.validation.Errors errors)
    If the AdminRole.parentRoleId is supplied, verifies that it exists and is accessible from the child's context.
    protected void
    validatePermissions(P role, String permissionsFieldNameOnParent, Set<AdminPermissionRef> permissions, org.springframework.validation.Errors errors)
     
    protected void
    validatePermissionsAssignableFromRoleContext(P role, String permissionsFieldNameOnParent, Set<AdminPermissionRef> permissions, org.springframework.validation.Errors errors)
    Validates that all of the role's assigned permission IDs belong to permissions that are accessible from the role's context.
    protected void
    validateRoleIsMutableFromCurrentContext(P role, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Validates that the role can be mutated by the current context.
    protected void
    validateTenantIdUnchanged(P existingRole, P role, org.springframework.validation.Errors errors)
    Regardless of what context this operation is being performed in, tenant ID can never be changed (as it would compromise accessibility to/from related entities).
    org.springframework.validation.Errors
    validateUpdate(String id, P role, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Validates an update operation is allowed in the current context.
    void
    validateUpdate(String id, P role, org.springframework.validation.Errors errors, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
    Validates an update operation is allowed in the current context.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • DefaultAdminRoleContextValidator

      public DefaultAdminRoleContextValidator(com.broadleafcommerce.common.extension.TypeFactory typeFactory, @Nullable com.broadleafcommerce.data.tracking.core.policy.PolicyUtils policyUtils)
  • Method Details

    • setAdminRoleService

      @Autowired @Lazy public void setAdminRoleService(AdminRoleService<P> adminRoleService)
      Lazy injection since this validator is itself a service component. This avoids circular dependency exceptions
      Parameters:
      adminRoleService - the role service
    • setAdminPermissionService

      @Autowired @Lazy public void setAdminPermissionService(AdminPermissionService<AdminPermission> adminPermissionService)
      Lazy injection since this validator is itself a service component. This avoids circular dependency exceptions
      Parameters:
      adminPermissionService - the permission service
    • validateCreate

      public org.springframework.validation.Errors validateCreate(P role, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: AdminRoleContextValidator
      Validates a create operation is allowed in the current context.
      Specified by:
      validateCreate in interface AdminRoleContextValidator<P extends AdminRole>
      Parameters:
      role - The role to validate
      contextInfo - The current context
      Returns:
      An Errors object bound to a {code role}
      See Also:
    • getErrors

      protected org.springframework.validation.Errors getErrors(P role)
    • validateUpdate

      public org.springframework.validation.Errors validateUpdate(String id, P role, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: AdminRoleContextValidator
      Validates an update operation is allowed in the current context.
      Specified by:
      validateUpdate in interface AdminRoleContextValidator<P extends AdminRole>
      Parameters:
      id - the id of the role being updated, explicitly provided such that it can be used to find the existing record even if AdminRole.id is unsupplied in role.
      role - The role to validate
      contextInfo - The current context
      Returns:
      An Errors object bound to a {code role}
      See Also:
    • validateDelete

      public org.springframework.validation.Errors validateDelete(P role, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: AdminRoleContextValidator
      Validates a delete operation is allowed in the current context.
      Specified by:
      validateDelete in interface AdminRoleContextValidator<P extends AdminRole>
      Parameters:
      role - the role being deleted to validate
      contextInfo - The current context
      Returns:
      An Errors object bound to a {code role}
      See Also:
    • validateCreate

      public void validateCreate(P role, org.springframework.validation.Errors errors, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: AdminRoleContextValidator
      Validates a create operation is allowed in the current context.
      Specified by:
      validateCreate in interface AdminRoleContextValidator<P extends AdminRole>
      Parameters:
      role - The role to validate
      errors - An errors object bound to the role to be validated
      contextInfo - The current context
    • validateCurrentAuthenticationHasTenantAccess

      protected void validateCurrentAuthenticationHasTenantAccess()
      Since roles are a tenant-level concept, only tenant access users can perform creation/modification operations on them.
      Throws:
      com.broadleafcommerce.data.tracking.core.exception.NotPermittedException - if the current authentication does not have tenant access
    • currentUserHasTenantAccess

      protected boolean currentUserHasTenantAccess()
      Uses policyUtils to check if currently authenticated user has tenant access.

      If policyUtils is null or it's not an instance of TrackablePolicyUtils, that means policy validation is turned off or trackable considerations should be ignored. Therefore it will automatically report the currently authenticated user has tenant access, since we want to allow everything in those cases.

      Returns:
      true if currently authenticated user has tenant access, otherwise false
      See Also:
      • TrackablePolicyUtils.isUserTenantLevelAccess()
    • getAuthenticationDetails

      @NonNull protected Map<String,Object> getAuthenticationDetails()
    • prefixWithEntityValidationMessageKey

      protected String prefixWithEntityValidationMessageKey(String errorCode)
    • getCurrentlyAuthenticatedUser

      protected String getCurrentlyAuthenticatedUser()
    • validateNameUniqueInRoleContext

      protected void validateNameUniqueInRoleContext(@Nullable String id, P role, org.springframework.validation.Errors errors)
      While it is perfectly valid for two tenant-level roles in different tenants to have the same name, we want to avoid having duplicate names from the perspective of a particular tenant context (to prevent confusion).

      This means that:

      • a tenant-level role's name must be unique among roles with the same tenant id and global roles (which would be accessible from any tenant-context)
      • a global role's name must be unique among all roles in all contexts
      This method first validates that the name is present, then validates its uniqueness.
      Parameters:
      id - the id of the role, explicitly provided as it may be null on the role. May be null as in the case of a create.
      role - the role whose name should be validated for uniqueness in its context
      errors - the errors object bound to the given role on which errors can be registered
    • validateDirectlyAssignedPermissions

      protected void validateDirectlyAssignedPermissions(P role, org.springframework.validation.Errors errors)
    • validatePermissions

      protected void validatePermissions(P role, String permissionsFieldNameOnParent, Set<AdminPermissionRef> permissions, org.springframework.validation.Errors errors)
    • validatePermissionsAssignableFromRoleContext

      protected void validatePermissionsAssignableFromRoleContext(P role, String permissionsFieldNameOnParent, Set<AdminPermissionRef> permissions, org.springframework.validation.Errors errors)
      Validates that all of the role's assigned permission IDs belong to permissions that are accessible from the role's context.

      This is important, because the create/update/delete operation itself may be occurring in a context different from that of the role itself and thus its context cannot be used. For example, if a role is being created in a specific tenant from a global context, the permissions accessible from the global context (ex: permissions from other tenants) do not reflect the permissions accessible by the role itself.

      A key element to note is that while a tenant-level role can be assigned either global permissions or permissions from that tenant, a global role can only be assigned global permissions. This is to avoid a situation where a tenant-user is assigned a global role and ends up getting access to permissions from other tenants.

      Parameters:
      role - the role whose permissions need to be checked for context accessibility. The AdminRole.getPermissions() should be pre-validated to not contain any null elements or empty IDs.
      errors - the errors object bound to the given role on which errors can be registered
    • buildContextMatchingRoleTenant

      protected com.broadleafcommerce.data.tracking.core.context.ContextRequest buildContextMatchingRoleTenant(P role)
      Builds a ContextRequest that has a ContextRequest.tenantId matching the AdminRole.tenantId. Useful in situations where it is necessary to make validations from the perspective of the entity's context rather than the context of the current request itself, which may have different accessibility.
      Parameters:
      role - the role for which to build a context request
      Returns:
      a ContextRequest matching the given role's tenant ID
    • validateParentRole

      protected void validateParentRole(P role, org.springframework.validation.Errors errors)
      If the AdminRole.parentRoleId is supplied, verifies that it exists and is accessible from the child's context.

      Validations on the full ancestry (ex: cycle validation) are done by AdminRoleValidator.

      Parameters:
      role - the role whose AdminRole.parentRoleId needs to be validated
      errors - the errors object bound to the given role on which errors can be registered
    • isParentRoleAccessible

      protected boolean isParentRoleAccessible(P role)
      Given a role that has a non-empty AdminRole.parentRoleId, validates that the parent exists and is accessible from the child's context.
      Parameters:
      role - the role whose AdminRole.parentRoleId needs to be validated
      Returns:
      true if the parent role exists and is accessible by the child, false otherwise
    • validateUpdate

      public void validateUpdate(String id, P role, org.springframework.validation.Errors errors, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: AdminRoleContextValidator
      Validates an update operation is allowed in the current context.
      Specified by:
      validateUpdate in interface AdminRoleContextValidator<P extends AdminRole>
      Parameters:
      id - the id of the role being updated, explicitly provided such that it can be used to find the existing record even if AdminRole.id is unsupplied in role.
      role - The role to validate
      errors - An errors object bound to the role to be validated
      contextInfo - The current context
    • validateTenantIdUnchanged

      protected void validateTenantIdUnchanged(P existingRole, P role, org.springframework.validation.Errors errors)
      Regardless of what context this operation is being performed in, tenant ID can never be changed (as it would compromise accessibility to/from related entities).
      Parameters:
      existingRole - the role as it exists in the data store currently
      role - the role after update
      errors - the errors object bound to the given role on which errors can be registered
    • validateRoleIsMutableFromCurrentContext

      protected void validateRoleIsMutableFromCurrentContext(P role, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Validates that the role can be mutated by the current context.

      This is important, because in some cases roles are accessible by a context but not mutable from that context. For example, a global role can be accessed by a tenant context but cannot be mutated by that tenant context.

      Parameters:
      role - the role to validate mutability for
      contextInfo - context information surrounding multitenant state
      Throws:
      com.broadleafcommerce.data.tracking.core.exception.InvalidContextRequestException - if the role is not mutable from the current context
    • validateDelete

      public void validateDelete(P role, org.springframework.validation.Errors errors, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: AdminRoleContextValidator
      Validates a delete operation is allowed in the current context.
      Specified by:
      validateDelete in interface AdminRoleContextValidator<P extends AdminRole>
      Parameters:
      role - The role being deleted to validate
      errors - An errors object bound to the role to be validated
      contextInfo - The current context
    • isMutableFromContext

      public boolean isMutableFromContext(P role, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: AdminRoleContextValidator
      Returns whether or not the given entity is mutable from the given context.
      Specified by:
      isMutableFromContext in interface AdminRoleContextValidator<P extends AdminRole>
      Parameters:
      role - the entity whose mutability should be checked
      contextInfo - the context in which mutability should be checked
      Returns:
      true if the entity is mutable from the given context, false otherwise
    • getTypeFactory

      protected com.broadleafcommerce.common.extension.TypeFactory getTypeFactory()
    • getPolicyUtils

      @Nullable protected com.broadleafcommerce.data.tracking.core.policy.PolicyUtils getPolicyUtils()
    • getAdminRoleService

      protected AdminRoleService<P> getAdminRoleService()
    • getAdminPermissionService

      protected AdminPermissionService<AdminPermission> getAdminPermissionService()