package org.springframework.security.access.expression.method;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.core.Authentication;
import java.util.*;
/**
* Tests for {@link MethodSecurityExpressionRoot}
*
* @author Luke Taylor
*/
public class MethodSecurityExpressionRootTests {
SpelExpressionParser parser = new SpelExpressionParser();
MethodSecurityExpressionRoot root;
StandardEvaluationContext ctx;
private AuthenticationTrustResolver trustResolver;
private Authentication user;
@Before
public void createContext() {
user = mock(Authentication.class);
root = new MethodSecurityExpressionRoot(user);
ctx = new StandardEvaluationContext();
ctx.setRootObject(root);
trustResolver = mock(AuthenticationTrustResolver.class);
root.setTrustResolver(trustResolver);
}
@Test
public void canCallMethodsOnVariables() throws Exception {
ctx.setVariable("var", "somestring");
Expression e = parser.parseExpression("#var.length() == 10");
assertTrue(ExpressionUtils.evaluateAsBoolean(e, ctx));
}
@Test
public void isAnonymousReturnsTrueIfTrustResolverReportsAnonymous() {
when(trustResolver.isAnonymous(user)).thenReturn(true);
assertTrue(root.isAnonymous());
}
@Test
public void isAnonymousReturnsFalseIfTrustResolverReportsNonAnonymous() {
when(trustResolver.isAnonymous(user)).thenReturn(false);
assertFalse(root.isAnonymous());
}
@Test
public void hasPermissionOnDomainObjectReturnsFalseIfPermissionEvaluatorDoes() throws Exception {
final Object dummyDomainObject = new Object();
final PermissionEvaluator pe = mock(PermissionEvaluator.class);
ctx.setVariable("domainObject", dummyDomainObject);
root.setPermissionEvaluator(pe);
when(pe.hasPermission(user, dummyDomainObject, "ignored")).thenReturn(false);
assertFalse(root.hasPermission(dummyDomainObject, "ignored"));
}
@Test
public void hasPermissionOnDomainObjectReturnsTrueIfPermissionEvaluatorDoes() throws Exception {
final Object dummyDomainObject = new Object();
final PermissionEvaluator pe = mock(PermissionEvaluator.class);
ctx.setVariable("domainObject", dummyDomainObject);
root.setPermissionEvaluator(pe);
when(pe.hasPermission(user, dummyDomainObject, "ignored")).thenReturn(true);
assertTrue(root.hasPermission(dummyDomainObject, "ignored"));
}
@Test
public void hasPermissionOnDomainObjectWorksWithIntegerExpressions() throws Exception {
final Object dummyDomainObject = new Object();
ctx.setVariable("domainObject", dummyDomainObject);
final PermissionEvaluator pe = mock(PermissionEvaluator.class);
root.setPermissionEvaluator(pe);
when(pe.hasPermission(eq(user), eq(dummyDomainObject), any(Integer.class))).thenReturn(true)
.thenReturn(true)
.thenReturn(false);
Expression e = parser.parseExpression("hasPermission(#domainObject, 0xA)");
// evaluator returns true
assertTrue(ExpressionUtils.evaluateAsBoolean(e, ctx));
e = parser.parseExpression("hasPermission(#domainObject, 10)");
// evaluator returns true
assertTrue(ExpressionUtils.evaluateAsBoolean(e, ctx));
e = parser.parseExpression("hasPermission(#domainObject, 0xFF)");
// evaluator returns false, make sure return value matches
assertFalse(ExpressionUtils.evaluateAsBoolean(e, ctx));
}
@Test
public void hasPermissionWorksWithThisObject() throws Exception {
Object targetObject = new Object() {
public String getX() {
return "x";
}
};
root.setThis(targetObject);
Integer i = 2;
PermissionEvaluator pe = mock(PermissionEvaluator.class);
root.setPermissionEvaluator(pe);
when(pe.hasPermission(user, targetObject, i)).thenReturn(true)
.thenReturn(false);
when(pe.hasPermission(user, "x", i)).thenReturn(true);
Expression e = parser.parseExpression("hasPermission(this, 2)");
assertTrue(ExpressionUtils.evaluateAsBoolean(e, ctx));
e = parser.parseExpression("hasPermission(this, 2)");
assertFalse(ExpressionUtils.evaluateAsBoolean(e, ctx));
e = parser.parseExpression("hasPermission(this.x, 2)");
assertTrue(ExpressionUtils.evaluateAsBoolean(e, ctx));
}
}