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 classAn intermediary data structure used internally byAdminPrivilegeServiceto 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 AdminRoleHydrationServiceprotected 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 AuthProvidergetConsolidatedRestrictionTypeAndTargetsByPermissionName(@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.PolicyUtilsgetRestrictionTargetsByRestrictionType(@NonNull Set<AdminRestriction> restrictions) Converts the Set ofAdminRestrictionto a Map with the structure of: { restrictionType: [restrictionTargets] }.getRestrictionTypeAndTargetsByPermissionName(@NonNull Set<AdminRestrictedPermission> restrictedPermissions) Converts the Set ofAdminRestrictedPermissionto a Map with the structure of: { permissionName: { restrictionType: [restrictionTargets] } }.getRestrictionTypeAndTargetsByPermissionName(Set<AdminRestriction> restrictions, Set<AdminPermissionRef> flatPermissions) Maps eachAdminPermissionRefwith 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.booleanisLessRestrictiveByPrivileges(@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 booleanisLessRestrictiveByRestrictedPermissions(@NonNull Map<String, Map<String, Set<String>>> aRestrictionsByPermissionName, @NonNull Map<String, Map<String, Set<String>>> bRestrictionsByPermissionName) Checks if aRestrictionsByPermissionName is less restrictive than bRestrictionsByPermissionName.booleanisLessRestrictiveByRestrictions(@NonNull AdminUser user1, @NonNull AdminUser user2) Checks if user1's restrictions is less restrictive than user2's restrictions.protected booleanisLessRestrictiveByRestrictions(@NonNull Map<String, Set<String>> aRestrictionTargetsByType, @NonNull Map<String, Set<String>> bRestrictionTargetsByType) Checks if aRestrictionTargetsByType is less restrictive than bRestrictionTargetsByType.booleanChecks ifAdminUser.getRestrictedPermissions()specified restrictions are less restrictive thanAdminUser.getRestrictions().protected booleanrestrictedPrivilegeRestrictionsAreLessRestrictiveThanFlatRestrictions(Set<AdminRestriction> restrictions, Set<? extends AdminRestrictedPrivilege> restrictedPrivileges) booleanChecks 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- theAdminUserto 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- theAdminUserto 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.PrivilegeHydrationResultto 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-AdminUserto get the permissions forroles-Collectionof 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-Collectionof 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- theMapof restriction targets by restriction type to compare frombRestrictionTargetsByType- theMapof 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- theMapof restrictions by permission name to compare frombRestrictionsByPermissionName- theMapof 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 ofAdminRestrictionto a Map with the structure of: { restrictionType: [restrictionTargets] }.- Parameters:
restrictions-SetofAdminRestriction- 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 eachAdminPermissionRefwith 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-SetofAdminRestrictionflatPermissions-SetofAdminPermissionRef- 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 eachAdminPermissionReffrom theAdminRestrictedRolewith 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.PrivilegeHydrationResultto 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 ofAdminRestrictedPermissionto 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-Setof 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
Optionalcontaining 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
-