Class DefaultAdminUserContextValidator<P extends AdminUser>
- Type Parameters:
P
-
- All Implemented Interfaces:
AdminUserContextValidator<P>
- Addition/removal of applications. User must be in the correct context (tenant or global) to add/remove a user from an application.
- Username/email uniqueness per tenant. Usernames and emails must be unique for a particular tenant. This includes all applications that are members of a tenant.
- User context: User should be in the correct context to perform modifications (e.g. tenant/app admin cannot modify a user belonging to another application or tenant).
- Tenant modification: A tenant or application admin may not modify another user's tenant.
- all assigned
AdminUser.permissions
are accessible from the user's context - all assigned
AdminUser.roles
are accessible from the user's context - the existing state of the user being updated/deleted is not already less restrictive than the
currently authenticated user. The comparison is based on restrictions and the state of
AdminUser.isGrantAnyAuthorityAllowed()
at the very least. If the authenticated user is not allowed to grant any authority, then all of the users' privileges will be taken into consideration as well (seevalidateUserPrivileges(AdminUser, Errors, boolean)
). Note thatAdminUserValidator
is responsible for validating the restrictiveness of the end-state of the user
-
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionDefaultAdminUserContextValidator
(com.broadleafcommerce.common.extension.TypeFactory typeFactory, com.broadleafcommerce.data.tracking.core.policy.PolicyUtils policyUtils) -
Method Summary
Modifier and TypeMethodDescriptionprotected com.broadleafcommerce.data.tracking.core.context.ContextRequest
Builds aContextRequest
that has aContextRequest.tenantId
matching theAdminUser.tenantId
.protected String
checkContextMutabilityAndReturnIfError
(P user, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Checks whether the givenuser
is mutable in the givencontextInfo
.protected String
protected boolean
UsespolicyUtils
to check if currently authenticated user has application access.protected boolean
UsespolicyUtils
to check if currently authenticated user has tenant access.protected P
findByEmail
(String email, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected P
protected P
findByUsername
(String username, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected AdminPrivilegeService
protected AdminUserAccessLevelProperties
protected AdminUserService<P>
protected AuthProvider
protected Collection<String>
protected String
protected org.springframework.validation.Errors
protected com.broadleafcommerce.data.tracking.core.policy.PolicyUtils
protected String
getTenantId
(P user, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Returns the tenant ID to be validated against.protected com.broadleafcommerce.common.extension.TypeFactory
protected boolean
isEmailChange
(P updatedUser, P existingUser) boolean
isMutableByCurrentUser
(P user) Returns whether or not the given entity is mutable by the current authenticated user.boolean
isMutableFromContext
(P user, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Returns whether or not the given entity is mutable from the given context.protected boolean
isUsernameChange
(P updatedUser, P existingUser) protected static String
prefixWithEntityValidationMessageKey
(String errorCode) void
setAdminPrivilegeService
(AdminPrivilegeService adminPrivilegeService) Lazy injection since this validator is itself a service component.void
setAdminUserAccessLevelProperties
(AdminUserAccessLevelProperties adminUserAccessLevelProperties) void
setAdminUserService
(AdminUserService<P> adminUserService) Lazy injection since this validator is itself a service component.void
setAuthProvider
(AuthProvider authProvider) protected void
validateApplicationContextForCreation
(P user, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) protected void
validateApplications
(P existingUser, P updatedUser, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validate that any potential application modifications are allowed.void
validateContextForModification
(P user, org.springframework.validation.Errors errors, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validate that modification of a user is valid in the current context.org.springframework.validation.Errors
validateCreate
(P user, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validates a create operation is allowed in the current context.void
validateCreate
(P user, org.springframework.validation.Errors errors, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validates a create operation is allowed in the current context.void
validateCurrentUserForModification
(P user, org.springframework.validation.Errors errors) Validate that modification of a user is permitted for the current authenticated user.org.springframework.validation.Errors
validateDelete
(P user, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validates a delete operation is allowed in the current context.void
validateDelete
(P user, 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
validateDirectlyAssignedPermissions
(P user, org.springframework.validation.Errors errors) Deprecated.protected void
validateDirectlyAssignedRoles
(P user, org.springframework.validation.Errors errors) protected void
validateEmailNotInUse
(String email, org.springframework.validation.Errors errors, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validates if a particular e-mail address is already in use for a particular tenant.protected void
validateExternalAccessManagementForCreate
(P user, org.springframework.validation.Errors errors) Validate that tenantAccess, applicationAccess and applicationIds are not set if these are intended to be managed by a third-party authentication provider.protected void
validateExternalAccessManagementForUpdate
(P user, P existingUser, org.springframework.validation.Errors errors) Validate that tenantAccess, applicationAccess and applicationIds are not set if these are intended to be managed by a third-party authentication provider.protected void
validateExternalRoles
(P user, org.springframework.validation.Errors errors) Ensure that there are not internal and external roles with the same role id.protected void
validatePermissions
(P user, String permissionsFieldNameOnParent, Set<AdminPermissionRef> permissions, org.springframework.validation.Errors errors) Deprecated.since 1.7.0.protected void
validatePermissionsAccessibleFromUserContext
(P user, String permissionsFieldNameOnParent, Set<AdminPermissionRef> permissionRefs, org.springframework.validation.Errors errors) Deprecated.protected void
validateRestrictedPermissionsPermissionRefs
(P user, org.springframework.validation.Errors errors) protected void
validateRestrictedRoles
(P user, org.springframework.validation.Errors errors) protected void
validateRoles
(P user, String roleFieldNameOnParent, Set<AdminRoleRef> roles, org.springframework.validation.Errors errors) protected void
validateRolesAccessibleFromUserContext
(P user, String rolesFieldNameOnParent, Set<AdminRoleRef> roleRefs, org.springframework.validation.Errors errors) Validates that all of the user's assigned role IDs belong to roles that are accessible from the user's context.protected void
validateTenant
(P existingUser, P updatedUser, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validates that the tenant ID has not changed on a user.protected void
validateTenantContextForCreation
(P user, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) org.springframework.validation.Errors
validateUpdate
(P user, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validates an update operation is allowed in the current context.void
validateUpdate
(P user, 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
validateUserAssignedApplications
(P user, org.springframework.validation.Errors errors) If a user doesn't have application access (seeAdminUser.isApplicationAccess()
) this validates that they do not have any applications assigned to them.protected void
validateUsernameNotInUse
(String username, com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo, org.springframework.validation.Errors errors) Validates if a username is already in use for a particular context.protected void
validateUserPrivileges
(P existingUser, org.springframework.validation.Errors errors, boolean throwIfError) Validates that the user being updated/deleted is equally or more restrictive as the currently authenticatedAdminUser
based on their restrictions at the very least.
-
Field Details
-
ERROR_USERNAME_IN_USE
-
ERROR_EMAIL_IN_USE
-
ERROR_EMAIL_IN_USE_OTHER_APP
-
NO_APPLICATION_ACCESS_CANNOT_HAVE_APPLICATIONS
-
USER_MUST_HAVE_APPLICATIONS
-
-
Constructor Details
-
DefaultAdminUserContextValidator
public DefaultAdminUserContextValidator(com.broadleafcommerce.common.extension.TypeFactory typeFactory, @Nullable com.broadleafcommerce.data.tracking.core.policy.PolicyUtils policyUtils)
-
-
Method Details
-
setAdminUserService
Lazy injection since this validator is itself a service component. This avoids circular dependency exceptions- Parameters:
adminUserService
- the user service
-
setAuthProvider
-
setAdminPrivilegeService
Lazy injection since this validator is itself a service component. This avoids circular dependency exceptions- Parameters:
adminPrivilegeService
- the restriction service
-
validateCreate
public org.springframework.validation.Errors validateCreate(@NonNull P user, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Description copied from interface:AdminUserContextValidator
Validates a create operation is allowed in the current context.- Specified by:
validateCreate
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- The user to validatecontextInfo
- The current context- Returns:
- An
Errors
object bound to a {code user} - See Also:
-
validateUpdate
public org.springframework.validation.Errors validateUpdate(@NonNull P user, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Description copied from interface:AdminUserContextValidator
Validates an update operation is allowed in the current context.- Specified by:
validateUpdate
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- The user to validatecontextInfo
- The current context- Returns:
- An
Errors
object bound to a {code user} - See Also:
-
validateDelete
public org.springframework.validation.Errors validateDelete(@NonNull P user, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Description copied from interface:AdminUserContextValidator
Validates a delete operation is allowed in the current context.- Specified by:
validateDelete
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- The user to validatecontextInfo
- The current context- Returns:
- An
Errors
object bound to a {code user} - See Also:
-
validateCreate
public void validateCreate(@NonNull P user, org.springframework.validation.Errors errors, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Description copied from interface:AdminUserContextValidator
Validates a create operation is allowed in the current context.- Specified by:
validateCreate
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- The user to validateerrors
- An errors object bound to theuser
to be validatedcontextInfo
- The current context
-
validateTenantContextForCreation
protected void validateTenantContextForCreation(P user, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
validateApplicationContextForCreation
protected void validateApplicationContextForCreation(P user, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) -
validateRestrictedPermissionsPermissionRefs
protected void validateRestrictedPermissionsPermissionRefs(P user, org.springframework.validation.Errors errors) -
validateDirectlyAssignedPermissions
@Deprecated protected void validateDirectlyAssignedPermissions(P user, org.springframework.validation.Errors errors) Deprecated. -
validatePermissions
@Deprecated protected void validatePermissions(P user, String permissionsFieldNameOnParent, Set<AdminPermissionRef> permissions, org.springframework.validation.Errors errors) Deprecated.since 1.7.0. -
prefixWithEntityValidationMessageKey
-
validatePermissionsAccessibleFromUserContext
@Deprecated protected void validatePermissionsAccessibleFromUserContext(P user, String permissionsFieldNameOnParent, Set<AdminPermissionRef> permissionRefs, org.springframework.validation.Errors errors) Deprecated.Validates that all of the user's assigned permission IDs belong to permissions that are accessible from the user's context.This is important, because the create/update/delete operation itself may be occurring in a context different from that of the user itself and thus its context cannot be used. For example, if a user 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 user itself.
TODO when global users are supported, update this validation to disallow assigning tenant permissions to global users
- Parameters:
user
- the user whose permissions need to be checked for context accessibility. TheAdminUser.getPermissions()
should be pre-validated to not contain any null elements or empty IDs.permissionRefs
-errors
- the errors object bound to the givenuser
on which errors can be registered
-
buildContextMatchingUserTenant
protected com.broadleafcommerce.data.tracking.core.context.ContextRequest buildContextMatchingUserTenant(P user) Builds aContextRequest
that has aContextRequest.tenantId
matching theAdminUser.tenantId
. Useful in situations where it is necessary to determine what entities are accessible by this user.- Parameters:
user
- the user for which to build a context request- Returns:
- a
ContextRequest
matching the given user's tenant ID
-
validateDirectlyAssignedRoles
-
validateRestrictedRoles
-
validateRoles
protected void validateRoles(P user, String roleFieldNameOnParent, Set<AdminRoleRef> roles, org.springframework.validation.Errors errors) -
validateExternalRoles
Ensure that there are not internal and external roles with the same role id.- Parameters:
user
- The User whose roles should be checked.errors
- the errors object bound to the givenuser
on which errors can be registered
-
validateRolesAccessibleFromUserContext
protected void validateRolesAccessibleFromUserContext(P user, String rolesFieldNameOnParent, Set<AdminRoleRef> roleRefs, org.springframework.validation.Errors errors) Validates that all of the user's assigned role IDs belong to roles that are accessible from the user's context.This is important, because the create/update/delete operation itself may be occurring in a context different from that of the user itself and thus its context cannot be used. For example, if a user is being created in a specific tenant from a global context, the roles accessible from the global context (ex: roles from other tenants) do not reflect the roles accessible by the user itself.
TODO when global users are supported, update this validation to disallow assigning tenant roles to global users
- Parameters:
user
- the user whose roles need to be checked for context accessibility. TheAdminUser.getRoles()
should be pre-validated to not contain any null elements or empty IDs.errors
- the errors object bound to the givenuser
on which errors can be registered
-
validateUpdate
public void validateUpdate(@NonNull P user, org.springframework.validation.Errors errors, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Description copied from interface:AdminUserContextValidator
Validates a create operation is allowed in the current context.- Specified by:
validateUpdate
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- The user to validateerrors
- An errors object bound to theuser
to be validatedcontextInfo
- The current context
-
validateDelete
public void validateDelete(@NonNull P user, org.springframework.validation.Errors errors, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Description copied from interface:AdminUserContextValidator
Validates a create operation is allowed in the current context.- Specified by:
validateDelete
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- The user to validateerrors
- An errors object bound to theuser
to be validatedcontextInfo
- The current context
-
validateContextForModification
public void validateContextForModification(@NonNull P user, org.springframework.validation.Errors errors, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Description copied from interface:AdminUserContextValidator
Validate that modification of a user is valid in the current context. The default implementation immediately aborts by throwing a runtime exception, though custom implementations may use theerrors
object if desired.- Specified by:
validateContextForModification
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- The user to validate againsterrors
- An errors object bound to theuser
to be validatedcontextInfo
- The current context- Throws:
com.broadleafcommerce.data.tracking.core.exception.EntityMissingException
- If modification of the user in this context is not allowed.- See Also:
-
checkContextMutabilityAndReturnIfError
@Nullable protected String checkContextMutabilityAndReturnIfError(@NonNull P user, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Checks whether the givenuser
is mutable in the givencontextInfo
.- Parameters:
user
- the user whose mutability should be checkedcontextInfo
- the context in which mutability should be evaluated- Returns:
- an error message describing why the user is not mutable in the
contextInfo
, ornull
if the user is mutable in the context
-
isMutableFromContext
public boolean isMutableFromContext(@NonNull P user, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Description copied from interface:AdminUserContextValidator
Returns whether or not the given entity is mutable from the given context.- Specified by:
isMutableFromContext
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- the entity whose mutability should be checkedcontextInfo
- the context in which mutability should be checked- Returns:
- true if the entity is mutable from the given context, false otherwise
-
validateCurrentUserForModification
public void validateCurrentUserForModification(P user, org.springframework.validation.Errors errors) Description copied from interface:AdminUserContextValidator
Validate that modification of a user is permitted for the current authenticated user. The default implementation immediately aborts by throwing a runtime exception, though custom implementations may use theerrors
object if desired.- Specified by:
validateCurrentUserForModification
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- The user to validate againsterrors
- An errors object bound to theuser
to be validated- Throws:
com.broadleafcommerce.data.tracking.core.exception.EntityMissingException
- If modification of the user in this context is not allowed.
-
checkCurrentUserMutabilityAndReturnIfError
-
isMutableByCurrentUser
Description copied from interface:AdminUserContextValidator
Returns whether or not the given entity is mutable by the current authenticated user.- Specified by:
isMutableByCurrentUser
in interfaceAdminUserContextValidator<P extends AdminUser>
- Parameters:
user
- the entity whose mutability should be checked- Returns:
- true if the entity is mutable by the current user, false otherwise
-
validateTenant
protected void validateTenant(P existingUser, P updatedUser, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validates that the tenant ID has not changed on a user. Validation is skipped if in a global context.- Parameters:
existingUser
- The existing userupdatedUser
- The proposed user modificationcontextInfo
- The current context.
-
getTenantId
@Nullable protected String getTenantId(P user, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Returns the tenant ID to be validated against. If there is no tenant ID on the contextInfo or the context is null this is either a global request or a request not performed in a context (e.g. service call, persistence handler), so we must fall back to the tenant ID on the user.- Parameters:
user
- The user being validated.contextInfo
- The current context.- Returns:
- The tenant ID to validate against.
-
validateUserPrivileges
protected void validateUserPrivileges(P existingUser, org.springframework.validation.Errors errors, boolean throwIfError) Validates that the user being updated/deleted is equally or more restrictive as the currently authenticatedAdminUser
based on their restrictions at the very least. However, if the authenticated user cannot grant any authority, which is set by theAdminUser.isGrantAnyAuthorityAllowed()
flag, then it will validate the privileges based on flat permissions, roles, restrictions, restricted roles, and restricted permissions as well, making sure that the user being updated/deleted is not already less restrictive than the authenticated user. As a user can only be updated/deleted by another user that is already less restrictive overall prior the mutation.In addition, if the authenticated user's
grantAnyAuthorityAllowed
flag is false, it cannot modify another user whosegrantAnyAuthorityAllowed
flag is true.This protects against situations where, for example, a more restricted user can modify a more powerful user like "Global Master".
- Parameters:
existingUser
- the existing user prior the mutation from the update/delete operationthrowIfError
- flag to determine whether it should throwNotPermittedException
if there's any error. Reason for this is to have field-level error if needed, such as when performing an update operation.- Throws:
com.broadleafcommerce.data.tracking.core.exception.NotPermittedException
- if throwIfError is true and if the user being updated/deleted is already less restrictive than the currently authenticated user based on restrictions,grantAnyAuthorityAllowed
flag, and/or all privileges
-
isEmailChange
- Parameters:
updatedUser
- The requested update of an existing userexistingUser
- The existing user, as they currently exist in the database.- Returns:
- true if this is an e-mail address change, else false.
-
isUsernameChange
- Parameters:
updatedUser
- The requested update of an existing userexistingUser
- The existing user, as they current exist in the database.- Returns:
- true if this is a username change, else false.
-
validateApplications
protected void validateApplications(P existingUser, P updatedUser, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validate that any potential application modifications are allowed.- Parameters:
existingUser
- The user as they exist in the data store prior to modification.updatedUser
- The potential modifications of the existing user.
-
validateUserAssignedApplications
protected void validateUserAssignedApplications(P user, org.springframework.validation.Errors errors) If a user doesn't have application access (seeAdminUser.isApplicationAccess()
) this validates that they do not have any applications assigned to them. If a user only has application access, this validates that they have applications assigned.- Parameters:
user
- The user to validateerrors
- The errors object bound touser
-
getErrors
-
findByEmail
-
findByUsername
-
validateUsernameNotInUse
protected void validateUsernameNotInUse(String username, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo, org.springframework.validation.Errors errors) Validates if a username is already in use for a particular context.- Parameters:
username
- The username to checkcontextInfo
- The current context
-
validateEmailNotInUse
protected void validateEmailNotInUse(String email, org.springframework.validation.Errors errors, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo) Validates if a particular e-mail address is already in use for a particular tenant. If the e-mail is in use, but the user is a member of a different application, a more specific error is communicated.- Parameters:
email
- The e-mail address to check.contextInfo
- The current context
-
validateExternalAccessManagementForCreate
protected void validateExternalAccessManagementForCreate(P user, org.springframework.validation.Errors errors) Validate that tenantAccess, applicationAccess and applicationIds are not set if these are intended to be managed by a third-party authentication provider.- Parameters:
user
- The user to validateerrors
- The errors object bound touser
- See Also:
-
validateExternalAccessManagementForUpdate
protected void validateExternalAccessManagementForUpdate(P user, P existingUser, org.springframework.validation.Errors errors) Validate that tenantAccess, applicationAccess and applicationIds are not set if these are intended to be managed by a third-party authentication provider.- Parameters:
user
- The user object from the API being validated.existingUser
- The user object that already exists in the database being updated.- See Also:
-
findById
-
getCurrentUserPrincipal
-
currentUserHasTenantAccess
protected boolean currentUserHasTenantAccess()UsespolicyUtils
to check if currently authenticated user has tenant access.If
policyUtils
is null or it's not an instance ofTrackablePolicyUtils
, 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()
-
currentUserHasApplicationAccess
protected boolean currentUserHasApplicationAccess()UsespolicyUtils
to check if currently authenticated user has application access.If
policyUtils
is null or it's not an instance ofTrackablePolicyUtils
, that means policy validation is turned off or trackable considerations should be ignored. Therefore it will automatically report the currently authenticated user has application access, since we want to allow everything in those cases.- Returns:
- true if currently authenticated user has application access, otherwise false
- See Also:
-
TrackablePolicyUtils.isUserApplicationLevelAccess()
-
getCurrentUserApplicationIds
-
getAuthenticationDetails
-
getAdminUserService
-
getTypeFactory
protected com.broadleafcommerce.common.extension.TypeFactory getTypeFactory() -
getPolicyUtils
@Nullable protected com.broadleafcommerce.data.tracking.core.policy.PolicyUtils getPolicyUtils() -
getAuthProvider
-
getAdminPrivilegeService
-
getAdminUserAccessLevelProperties
-
setAdminUserAccessLevelProperties
@Autowired(required=false) public void setAdminUserAccessLevelProperties(AdminUserAccessLevelProperties adminUserAccessLevelProperties)
-