Getting the AclAspect to work for both Mono & Flux methods.
This is done by checking the return type of the function via the joinPoint method signature
This commit is contained in:
parent
bd1c390402
commit
d5ed147111
|
|
@ -15,6 +15,7 @@ import org.springframework.security.core.GrantedAuthority;
|
|||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
|
@ -26,46 +27,57 @@ import java.util.Set;
|
|||
@Slf4j
|
||||
public class AclAspect {
|
||||
|
||||
@Around("execution(reactor.core.publisher.Mono+ com.appsmith.server.services.CrudService.*(..))")
|
||||
public Mono<?> checkAuthorization(ProceedingJoinPoint joinPoint) {
|
||||
try {
|
||||
@Around("execution(* com.appsmith.server.services.CrudService.*(..))")
|
||||
public Object checkAuthorization(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
Class returnType = signature.getReturnType();
|
||||
|
||||
if (Mono.class.isAssignableFrom(returnType)) {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map(ctx -> ctx.getAuthentication())
|
||||
.map(auth -> auth.getPrincipal())
|
||||
.filter(principal -> {
|
||||
User user = (User) principal;
|
||||
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
log.debug("Checking the authorization for user: {} for function: {}", user.getEmail(), method.getName());
|
||||
|
||||
// Get the auth permission to be applied
|
||||
AclPermission aclPermissionAnnotation = AnnotationUtils.findAnnotation(method, AclPermission.class);
|
||||
if (aclPermissionAnnotation == null) {
|
||||
// There are no permission annotations on the method. Continue
|
||||
return true;
|
||||
}
|
||||
String[] authPermission = aclPermissionAnnotation.values();
|
||||
|
||||
// Get the entity on which permission needs to be applied
|
||||
String authEntity = joinPoint.getTarget().getClass().getAnnotation(AclEntity.class).value();
|
||||
|
||||
Set<GrantedAuthority> actualPermissions = new HashSet<>();
|
||||
if (authPermission != null && authPermission.length > 0) {
|
||||
for (int i = 0; i < authPermission.length; i++) {
|
||||
actualPermissions.add(new SimpleGrantedAuthority(authPermission[i] + ":" + authEntity));
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("Permissions required to execute function: {} are: {}", method.getName(), actualPermissions);
|
||||
return user.getAuthorities().containsAll(actualPermissions);
|
||||
})
|
||||
.filter(principal -> authorizeUser((User) principal, method, joinPoint))
|
||||
// If the user is not authorized, the filter will not emit. Hence, we return "Unauthorized"
|
||||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.UNAUTHORIZED_ACCESS)))
|
||||
// The user is authorized to proceed to function execution
|
||||
.then((Mono<?>) joinPoint.proceed());
|
||||
} catch (Throwable throwable) {
|
||||
return Mono.error(throwable);
|
||||
.then((Mono<Object>) joinPoint.proceed());
|
||||
|
||||
} else if (Flux.class.isAssignableFrom(returnType)) {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map(ctx -> ctx.getAuthentication())
|
||||
.map(auth -> auth.getPrincipal())
|
||||
.filter(principal -> authorizeUser((User) principal, method, joinPoint))
|
||||
// If the user is not authorized, the filter will not emit. Hence, we return "Unauthorized"
|
||||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.UNAUTHORIZED_ACCESS)))
|
||||
// The user is authorized to proceed to function execution
|
||||
.thenMany((Flux<Object>) joinPoint.proceed());
|
||||
}
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
|
||||
private boolean authorizeUser(User user, Method method, ProceedingJoinPoint joinPoint) {
|
||||
log.debug("Checking the authorization for user: {} for function: {}", user.getEmail(), method.getName());
|
||||
|
||||
// Get the auth permission to be applied
|
||||
AclPermission aclPermissionAnnotation = AnnotationUtils.findAnnotation(method, AclPermission.class);
|
||||
if (aclPermissionAnnotation == null) {
|
||||
// There are no permission annotations on the method. Continue
|
||||
return true;
|
||||
}
|
||||
String[] authPermission = aclPermissionAnnotation.values();
|
||||
|
||||
// Get the entity on which permission needs to be applied
|
||||
String authEntity = joinPoint.getTarget().getClass().getAnnotation(AclEntity.class).value();
|
||||
|
||||
Set<GrantedAuthority> actualPermissions = new HashSet<>();
|
||||
if (authPermission != null && authPermission.length > 0) {
|
||||
for (int i = 0; i < authPermission.length; i++) {
|
||||
actualPermissions.add(new SimpleGrantedAuthority(authPermission[i] + ":" + authEntity));
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("Permissions required to execute function: {} are: {}", method.getName(), actualPermissions);
|
||||
return user.getAuthorities().containsAll(actualPermissions);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import org.checkerframework.framework.qual.InheritedAnnotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user