I have my own permissionEvaluator with takes List<Long> ids as parameter and is able to preAuthorize such case for example:
@PreAuthorize("isUserAssignedToDepartment(#case.departmentId)")
public void storeCase(Case case);
And I have dozens of different operations to secure including list of objects in parameter but all of those objects have departmentId. The question is how to map those objects to collection od ids that i need ?
The hardest one would be something like this:
@PreAuthorize("isUserAssignedToDepartment(#xObjects.stream().map(XObjects::getDepartmentId).collect(Collectors.toSet()))")
public void migrateXObjects(List<XObjects> xObjects, boolean sendEmails);
My isUserAssignedToDepartment evaluator could take a list of ids but the above example throws spel exception:
Caused by: org.springframework.expression.spel.SpelParseException: Expression [#oauth2.throwOnError(isUserAssignedToDepartment(#xObjects.stream().map(XObjects::getDepartmentId).collect(Collectors.toSet())))] @200: EL1043E: Unexpected token. Expected 'rparen())' but was 'colon(:)'
I see some spell projections that are able to map one collection to another: https://docs.spring.io/spring-framework/docs/4.3.0.RELEASE/spring-framework-reference/html/expressions.html#expressions-collection-projection
// returns ['Smiljan', 'Idvor' ]
List placesOfBirth = (List)parser.parseExpression("Members.![placeOfBirth.city]");
But would it be possible to combine PreAuthorize with it somehow ? My method has two parameters:
@PreAuthorize("isUserAssignedToDepartment(#xObjects.stream().map(XObjects::getDepartmentId).collect(Collectors.toSet()))")
public void migrateXObjects(List<XObjects> xObjects, boolean sendEmail);
My permission evaluator:
public class UserAssignedToDepartmentimplementsEvaluator TargetedPermissionEvaluator {
@Getter
private final String name;
private final SomeService someService;
public UserAssignedToDepartmentimplementsEvaluator (String name,
SomeService someService) {
this.name = name;
this.someService= someService;
}
@Override
public boolean hasPermission(Authentication authentication, Object o, Object o1) {
return false;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable id (or list of ids), String targetType, Object permission) {
if (id == null) {
log.warn("id is null!");
return false;
}
(...) // do business checks..
}