Class AdminPrivilegeService
AdminPermissionRef
, AdminRoleRef
, AdminRestriction
,
AdminRestrictedRole
, and AdminRestrictedPermission
. These functions are most
useful for validation purposes to prevent flat permission, role, restriction, restricted role,
and restricted permission escalation. This service also considers permissions inherited from an
entity's roles and their ancestors.
The AdminUser
entity supports the concept of restrictions, flat permissions, flat roles,
restricted roles, and restricted permissions.
Restrictions are used to exclusively restrict entities to only the specific targets within each
specified restriction type. See AdminUser.getRestrictions()
.
An entity with no (empty) restrictions is not restricted in any way and can be considered "least restrictive" automatically.
However, if an entity has one or more restrictions, it is exclusively restricted to only the specific targets within each specified restriction type. For example, assume we have "entityX" with restrictions [{VENDOR: [vendorA, vendorB]}, {STORE: [storeA, storeB]}]. It is exclusively restricted to vendors vendorA and vendorB, and stores storeA and storeB. It is not allowed to access storeC or vendorC, nor is it allowed to access targets of any other arbitrary restriction type.
In order for an entity's restrictions to be less restrictive than another entity, it must have access to restriction targets that the other entity does not.
If we have another "entityY" with restrictions [{VENDOR: [vendorA]}], it is exclusively restricted to vendor vendorA. It is not allowed to access vendorB or any other vendor besides vendorA, nor is it allowed to access any stores, nor is it allowed to access to targets of any other arbitrary restriction type. In this case, we would say that "entityX" is less restrictive than "entityY", as "entityX" is able to access items that "entityY" cannot. "entityY" is not less restrictive than "entityX", because "entityX" has access to all the restriction targets that "entityY" can.
A permission enables access to some resource(s). Without the appropriate permission, the entity cannot access those resource(s).
"Flat permissions" is the term used for all permissions that come from
AdminUser.getPermissions()
and any permissions inherited from
AdminUser.getRoles()
) or their ancestors. If the entity has restrictions, then these
permissions are only granted in those restrictions (effectively becoming restricted permissions).
If the entity has no restrictions, then those permissions are granted everywhere.
"Flat roles" is the term used for all roles that come from AdminUser.getRoles()
and those
inherited from their parent roles. Similarly, if the entity has restrictions, these roles are
only granted in those restrictions (effectively becoming restricted roles). If the entity has no
restrictions, then those roles are granted everywhere.
"Restricted permissions" are specific to particular restrictions. These are effectively added to
whatever "flat permissions" the restriction already inherits, and thus are a way to give
additional access within certain restrictions. See AdminUser.getRestrictedPermissions()
.
For example, assume we have a "userA" with restrictions on [vendorA, vendorC] with READ_PRODUCT "flat permission", and "restricted permission" of UPDATE_PRODUCT on [vendorC]. In this case, the user effectively has READ_PRODUCT permission on both vendorA and vendorC, and also UPDATE_PRODUCT permission on only vendorC.
"Restricted roles" are similar to "restricted permissions." Except the roles basically serve as a group of permissions, and each of those permission is specific to particular restrictions, just like "restricted permissions."
In order for an entity's permissions to be less restrictive than another entity, it must have permissions (whether they come from flat permissions, flat roles, restricted roles, or restricted permissions) in a context/restriction that the other entity does not.
Assume we have another "userB" with restrictions on [vendorA] with READ_PRODUCT "flat permission", and "restricted permission" of UPDATE_PRODUCT on [vendorA]. we would say that "userA" is less restrictive than "userB" because "userA" has READ_PRODUCT and UPDATE_PRODUCT on vendorC, which "userB" does not. Likewise, "userB" is also less restrictive than "userA" because "userB" has UPDATE_PRODUCT on vendorA, which "userA" does not.
- Author:
- Sunny Yu
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
An intermediary data structure used internally byAdminPrivilegeService
to hold data for a user or role entity to prevent querying the data multiple times. -
Constructor Summary
ConstructorsConstructorDescriptionAdminPrivilegeService
(AdminUserService<AdminUser> adminUserService, AdminRoleHydrationService adminRoleHydrationService, com.broadleafcommerce.data.tracking.core.policy.PolicyUtils policyUtils, AuthProvider authProvider) -
Method Summary
Modifier and TypeMethodDescriptionprotected AdminRoleHydrationService
protected AdminUserService<AdminUser>
protected Set<AdminPermissionRef>
getAllFlatPermissions
(@NonNull AdminUser user, @NonNull Collection<AdminRoleRef> roles) Gets a Set of allAdminUser.getPermissions()
along withAdminRoleRef.getPermissions()
.protected Set<AdminPermissionRef>
getAllFlatPermissions
(@NonNull Collection<AdminRoleRef> roles) Gets a Set of allAdminRoleRef.getPermissions()
.getAllPermissionNames
(@NonNull Set<AdminPermissionRef> permissions) Get all permission names from a set ofAdminPermissionRef
.protected AuthProvider
getConsolidatedRestrictionTypeAndTargetsByPermissionName
(@NonNull AdminPrivilegeService.PrivilegeHydrationResult privilegeHydrationResult) Gets a consolidated map of restricted permissions with the combination of flat permissions and restrictions, restricted roles, and restricted permissions.If the current authentication exists and is an admin user, reads the user from the data store and returns them in an Optional.getHydratedPrivileges
(@NonNull AdminUser user) getMergedRestrictionTypeAndTargetsByPermissionName
(Map<String, Map<String, Set<String>>> restrictionTypeAndTargetsByPermissionName1, Map<String, Map<String, Set<String>>> restrictionTypeAndTargetsByPermissionName2) Gets a Map that is a combination of the two given restricted permissions maps.protected com.broadleafcommerce.data.tracking.core.policy.PolicyUtils
getRestrictionTargetsByRestrictionType
(@NonNull Set<AdminRestriction> restrictions) Converts the Set ofAdminRestriction
to a Map with the structure of: { restrictionType: [restrictionTargets] }.getRestrictionTypeAndTargetsByPermissionName
(@NonNull Set<AdminRestrictedPermission> restrictedPermissions) Converts the Set ofAdminRestrictedPermission
to a Map with the structure of: { permissionName: { restrictionType: [restrictionTargets] } }.getRestrictionTypeAndTargetsByPermissionName
(Set<AdminRestriction> restrictions, Set<AdminPermissionRef> flatPermissions) Maps eachAdminPermissionRef
with all ofAdminRestriction
.getRestrictionTypeAndTargetsByPermissionNameFromRestrictedRoles
(@NonNull AdminPrivilegeService.PrivilegeHydrationResult privilegeHydrationResult) getRoleIds
(@NonNull AdminUser user) getRoleIds
(@NonNull Set<AdminRestrictedRole> restrictedRoles) protected Map<String,
Collection<AdminRoleRef>> getRoleWithAncestorsByRoleId
(@NonNull Set<String> roleIds) Gets roles along with their ancestry roles mapped by given role id.boolean
isLessRestrictiveByPrivileges
(@NonNull AdminUser user1, @NonNull AdminUser user2) Checks if user1 is less restrictive than user2 based on all of their flat permissions, flat roles, restrictions, restricted roles, and restricted permissions as a whole, which also includes those that are inherited from their roles and ancestry roles.protected boolean
isLessRestrictiveByRestrictedPermissions
(@NonNull Map<String, Map<String, Set<String>>> aRestrictionsByPermissionName, @NonNull Map<String, Map<String, Set<String>>> bRestrictionsByPermissionName) Checks if aRestrictionsByPermissionName is less restrictive than bRestrictionsByPermissionName.boolean
isLessRestrictiveByRestrictions
(@NonNull AdminUser user1, @NonNull AdminUser user2) Checks if user1's restrictions is less restrictive than user2's restrictions.protected boolean
isLessRestrictiveByRestrictions
(@NonNull Map<String, Set<String>> aRestrictionTargetsByType, @NonNull Map<String, Set<String>> bRestrictionTargetsByType) Checks if aRestrictionTargetsByType is less restrictive than bRestrictionTargetsByType.boolean
Checks ifAdminUser.getRestrictedPermissions()
specified restrictions are less restrictive thanAdminUser.getRestrictions()
.protected boolean
restrictedPrivilegeRestrictionsAreLessRestrictiveThanFlatRestrictions
(Set<AdminRestriction> restrictions, Set<? extends AdminRestrictedPrivilege> restrictedPrivileges) boolean
Checks ifAdminUser.getRestrictedRoles()
specified restrictions are less restrictive thanAdminUser.getRestrictions()
.
-
Constructor Details
-
AdminPrivilegeService
public AdminPrivilegeService(@NonNull AdminUserService<AdminUser> adminUserService, @NonNull AdminRoleHydrationService adminRoleHydrationService, @Nullable com.broadleafcommerce.data.tracking.core.policy.PolicyUtils policyUtils, AuthProvider authProvider)
-
-
Method Details
-
isLessRestrictiveByRestrictions
public boolean isLessRestrictiveByRestrictions(@NonNull @NonNull AdminUser user1, @NonNull @NonNull AdminUser user2) Checks if user1's restrictions is less restrictive than user2's restrictions.See the class-level javadocs for the detailed explanations on what it means to be less restrictive.
-
isLessRestrictiveByPrivileges
public boolean isLessRestrictiveByPrivileges(@NonNull @NonNull AdminUser user1, @NonNull @NonNull AdminUser user2) Checks if user1 is less restrictive than user2 based on all of their flat permissions, flat roles, restrictions, restricted roles, and restricted permissions as a whole, which also includes those that are inherited from their roles and ancestry roles.See the class-level javadocs for the detailed explanations on what it means to be less restrictive.
-
restrictedRolesRestrictionsAreLessRestrictiveThanFlatRestrictions
Checks ifAdminUser.getRestrictedRoles()
specified restrictions are less restrictive thanAdminUser.getRestrictions()
.- Parameters:
user
- theAdminUser
to check against- Returns:
- true if user's specified restrictions for restricted roles are less restrictive than user's flat restrictions, else false
-
restrictedPermissionsRestrictionsAreLessRestrictiveThanFlatRestrictions
public boolean restrictedPermissionsRestrictionsAreLessRestrictiveThanFlatRestrictions(AdminUser user) Checks ifAdminUser.getRestrictedPermissions()
specified restrictions are less restrictive thanAdminUser.getRestrictions()
.- Parameters:
user
- theAdminUser
to check against- Returns:
- true if user's specified restrictions for restricted permissions are less restrictive than user's flat restrictions, else false
-
restrictedPrivilegeRestrictionsAreLessRestrictiveThanFlatRestrictions
protected boolean restrictedPrivilegeRestrictionsAreLessRestrictiveThanFlatRestrictions(Set<AdminRestriction> restrictions, Set<? extends AdminRestrictedPrivilege> restrictedPrivileges) -
getConsolidatedRestrictionTypeAndTargetsByPermissionName
protected Map<String,Map<String, getConsolidatedRestrictionTypeAndTargetsByPermissionNameSet<String>>> (@NonNull @NonNull AdminPrivilegeService.PrivilegeHydrationResult privilegeHydrationResult) Gets a consolidated map of restricted permissions with the combination of flat permissions and restrictions, restricted roles, and restricted permissions. Flat permissions and restrictions are converted into a map of equivalent restricted permissions. Similarly, restricted roles are also converted into equivalent restricted permissions.For example, if an entity has READ_PRODUCT as flat permission (that came either from its direct flat permissions or from a flat role) with a flat vendor restriction on vendorA, it is then converted into a restricted permission as such: {READ_PRODUCT: {VENDOR: [vendorA]}}. This helps with the process of comparing entities' restrictiveness.
Likewise, if an entity has a role that has READ_PRODUCT permission assigned, and has the role added as restricted role on vendorA, it is then converted into a restricted permission as well: {READ_PRODUCT: {VENDOR: [vendorA]}}. This also helps with the process of comparing entities' restrictiveness.
- Parameters:
privilegeHydrationResult
-AdminPrivilegeService.PrivilegeHydrationResult
to consolidate the permissions, restrictions, restricted roles, and restricted permissions for a user- Returns:
- a consolidated map of restricted permissions from flat permissions, restrictions, restricted roles, and restricted permissions
-
getHydratedPrivileges
protected AdminPrivilegeService.PrivilegeHydrationResult getHydratedPrivileges(@NonNull @NonNull AdminUser user) -
getRoleIds
-
getRoleIds
-
getRoleWithAncestorsByRoleId
protected Map<String,Collection<AdminRoleRef>> getRoleWithAncestorsByRoleId(@NonNull @NonNull Set<String> roleIds) Gets roles along with their ancestry roles mapped by given role id.- Parameters:
roleIds
- role ids to get the roles and ancestry roles for- Returns:
- a collection containing the given roles along with their ancestors mapped by given role id
-
getAllPermissionNames
Get all permission names from a set ofAdminPermissionRef
.Permissions would be expanded if it starts with ALL_*, such as ALL_PRODUCT.
- Parameters:
permissions
- a set of permissions to get the all the permission names from- Returns:
- a set of permission names
- See Also:
-
getAllFlatPermissions
protected Set<AdminPermissionRef> getAllFlatPermissions(@NonNull @NonNull AdminUser user, @NonNull @NonNull Collection<AdminRoleRef> roles) Gets a Set of allAdminUser.getPermissions()
along withAdminRoleRef.getPermissions()
.- Parameters:
user
-AdminUser
to get the permissions forroles
-Collection
of roles to get all the permissions from. This is typically a collection of user's roles and their ancestry roles to prevent the need of querying all ancestry roles every time- Returns:
- a set containing the flat permissions from the given user and roles
-
getAllFlatPermissions
protected Set<AdminPermissionRef> getAllFlatPermissions(@NonNull @NonNull Collection<AdminRoleRef> roles) Gets a Set of allAdminRoleRef.getPermissions()
.- Parameters:
roles
-Collection
of roles to get all the permissions from- Returns:
- a set containing the flat permissions from the given roles
-
getMergedRestrictionTypeAndTargetsByPermissionName
protected Map<String,Map<String, getMergedRestrictionTypeAndTargetsByPermissionNameSet<String>>> (Map<String, Map<String, Set<String>>> restrictionTypeAndTargetsByPermissionName1, Map<String, Map<String, Set<String>>> restrictionTypeAndTargetsByPermissionName2) Gets a Map that is a combination of the two given restricted permissions maps. -
isLessRestrictiveByRestrictions
protected boolean isLessRestrictiveByRestrictions(@NonNull @NonNull Map<String, Set<String>> aRestrictionTargetsByType, @NonNull @NonNull Map<String, Set<String>> bRestrictionTargetsByType) Checks if aRestrictionTargetsByType is less restrictive than bRestrictionTargetsByType. Both have the structure of { restrictionType: [restrictionTargets] }.- Parameters:
aRestrictionTargetsByType
- theMap
of restriction targets by restriction type to compare frombRestrictionTargetsByType
- theMap
of restriction targets by restriction type to compare to- Returns:
- true if aRestrictionTargetsByRestrictionType is less restrictive than bRestrictionTargetsByRestrictionType, else false.
-
isLessRestrictiveByRestrictedPermissions
protected boolean isLessRestrictiveByRestrictedPermissions(@NonNull @NonNull Map<String, Map<String, Set<String>>> aRestrictionsByPermissionName, @NonNull @NonNull Map<String, Map<String, Set<String>>> bRestrictionsByPermissionName) Checks if aRestrictionsByPermissionName is less restrictive than bRestrictionsByPermissionName. Both have the structure of { permissionName: { restrictionType: [restrictionTargets] } }.- Parameters:
aRestrictionsByPermissionName
- theMap
of restrictions by permission name to compare frombRestrictionsByPermissionName
- theMap
of restrictions by permission name to compare to- Returns:
- true if aRestrictionsByPermissionName is less restrictive than bRestrictionsByPermissionName, else false.
-
getRestrictionTargetsByRestrictionType
protected Map<String,Set<String>> getRestrictionTargetsByRestrictionType(@NonNull @NonNull Set<AdminRestriction> restrictions) Converts the Set ofAdminRestriction
to a Map with the structure of: { restrictionType: [restrictionTargets] }.- Parameters:
restrictions
-Set
ofAdminRestriction
- Returns:
- a map with restriction type as key and restriction targets as value converted from the given set of restrictions
-
getRestrictionTypeAndTargetsByPermissionName
protected Map<String,Map<String, getRestrictionTypeAndTargetsByPermissionNameSet<String>>> (Set<AdminRestriction> restrictions, Set<AdminPermissionRef> flatPermissions) Maps eachAdminPermissionRef
with all ofAdminRestriction
. Doing this to convert flat permissions and restrictions into the map structure of restricted permissions, which helps the comparisons of restrictiveness.However, when there's no flat permissions, the restrictions are not added.
Note: The ALL_* permissions are expanded into CRUD_* permissions before mapping with a restriction.
- Parameters:
restrictions
-Set
ofAdminRestriction
flatPermissions
-Set
ofAdminPermissionRef
- Returns:
- a map of restricted permissions converted from restrictions and flat permissions
-
getRestrictionTypeAndTargetsByPermissionNameFromRestrictedRoles
protected Map<String,Map<String, getRestrictionTypeAndTargetsByPermissionNameFromRestrictedRolesSet<String>>> (@NonNull @NonNull AdminPrivilegeService.PrivilegeHydrationResult privilegeHydrationResult) Maps eachAdminPermissionRef
from theAdminRestrictedRole
with the correspondingrestriction
. Doing this to convert permissions assigned to the restricted role and restricted role restrictions into the map structure of restricted permissions, which helps the comparisons of restrictiveness.The ALL_* permissions are expanded into CRUD_* permissions with the same restrictions.
- Parameters:
privilegeHydrationResult
-AdminPrivilegeService.PrivilegeHydrationResult
to get the restricted roles and their ancestors from- Returns:
- a map of restriction type and targets mapped by permission name converted from the
given set of restricted roles and ancestor roles from
AdminPrivilegeService.PrivilegeHydrationResult
-
getRestrictionTypeAndTargetsByPermissionName
protected Map<String,Map<String, getRestrictionTypeAndTargetsByPermissionNameSet<String>>> (@NonNull @NonNull Set<AdminRestrictedPermission> restrictedPermissions) Converts the Set ofAdminRestrictedPermission
to a Map with the structure of: { permissionName: { restrictionType: [restrictionTargets] } }.The ALL_* permissions are expanded into CRUD_* permissions with the same restrictions. For example, if the set contains only {ALL_PRODUCT: {VENDOR: [vendor1, vendor2}}, it will be expanded into: [ {CREATE_PRODUCT: {VENDOR: [vendor1, vendor2}}, {READ_PRODUCT: {VENDOR: [vendor1, vendor2}}, {UPDATE_PRODUCT: {VENDOR: [vendor1, vendor2}}, {DELETE_PRODUCT: {VENDOR: [vendor1, vendor2}} ]
- Parameters:
restrictedPermissions
-Set
of restricted permissions- Returns:
- a map converted from the given set of restricted permissions
-
getCurrentlyAuthenticatedAdminUser
If the current authentication exists and is an admin user, reads the user from the data store and returns them in an Optional. Otherwise, returns empty.- Returns:
- an
Optional
containing the currently authenticatedAdminUser
- Throws:
IllegalStateException
- if the authentication had an admin user ID but the user wasn't found in the data store
-
getAdminUserService
-
getAdminRoleHydrationService
-
getPolicyUtils
@Nullable protected com.broadleafcommerce.data.tracking.core.policy.PolicyUtils getPolicyUtils() -
getAuthProvider
-