/* * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.security.access.expression.method; import static org.assertj.core.api.Assertions.*; 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; /** * 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"); assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); } @Test public void isAnonymousReturnsTrueIfTrustResolverReportsAnonymous() { when(trustResolver.isAnonymous(user)).thenReturn(true); assertThat(root.isAnonymous()).isTrue(); } @Test public void isAnonymousReturnsFalseIfTrustResolverReportsNonAnonymous() { when(trustResolver.isAnonymous(user)).thenReturn(false); assertThat(root.isAnonymous()).isFalse(); } @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); assertThat(root.hasPermission(dummyDomainObject, "ignored")).isFalse(); } @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); assertThat(root.hasPermission(dummyDomainObject, "ignored")).isTrue(); } @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 assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); e = parser.parseExpression("hasPermission(#domainObject, 10)"); // evaluator returns true assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); e = parser.parseExpression("hasPermission(#domainObject, 0xFF)"); // evaluator returns false, make sure return value matches assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isFalse(); } @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)"); assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); e = parser.parseExpression("hasPermission(this, 2)"); assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isFalse(); e = parser.parseExpression("hasPermission(this.x, 2)"); assertThat(ExpressionUtils.evaluateAsBoolean(e, ctx)).isTrue(); } }