package com.sequenceiq.periscope.service.security;
import java.io.Serializable;
import java.lang.reflect.Field;
import javax.inject.Inject;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import com.sequenceiq.periscope.domain.Cluster;
import com.sequenceiq.periscope.domain.PeriscopeUser;
import com.sequenceiq.periscope.service.NotFoundException;
@Component
public class OwnerBasedPermissionEvaluator implements PermissionEvaluator {
@Inject
private UserDetailsService userDetailsService;
@Override
public boolean hasPermission(Authentication authentication, final Object targetDomainObject, Object permission) {
if (targetDomainObject == null) {
throw new NotFoundException("Resource not found.");
}
try {
PeriscopeUser user = userDetailsService.getDetails((String) authentication.getPrincipal(), UserFilterField.USERNAME);
if (getUserId(targetDomainObject).equals(user.getId())) {
return true;
}
} catch (IllegalAccessException e) {
return false;
}
return false;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
return false;
}
private String getUserId(Object targetDomainObject) throws IllegalAccessException {
Field clusterField = ReflectionUtils.findField(targetDomainObject.getClass(), "cluster");
if (clusterField != null) {
clusterField.setAccessible(true);
Cluster cluster = (Cluster) clusterField.get(targetDomainObject);
return getUserId(cluster);
} else {
Field userIdField = ReflectionUtils.findField(targetDomainObject.getClass(), "userId");
if (userIdField != null) {
userIdField.setAccessible(true);
return (String) userIdField.get(targetDomainObject);
}
return getUserIdFromCluster(targetDomainObject);
}
}
private String getUserIdFromCluster(Object targetDomainObject) throws IllegalAccessException {
Field owner = ReflectionUtils.findField(targetDomainObject.getClass(), "user");
owner.setAccessible(true);
PeriscopeUser user = (PeriscopeUser) owner.get(targetDomainObject);
return user.getId();
}
}