Support Path Variables in Message Expressions

Extract path variables expressed in SimpDestinationMessageMatcher's pattern.

Issue: gh-4469
This commit is contained in:
Daniel Bustamante Ospina
2018-11-17 18:42:40 -05:00
committed by Rob Winch
parent fcd8a38f0b
commit f97ac4daa6
8 changed files with 160 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 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.
@@ -20,26 +20,40 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.messaging.Message;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.security.messaging.util.matcher.MessageMatcher;
import org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class MessageExpressionConfigAttributeTests {
@Mock
Expression expression;
@Mock
MessageMatcher<?> matcher;
MessageExpressionConfigAttribute attribute;
@Before
public void setup() {
attribute = new MessageExpressionConfigAttribute(expression);
attribute = new MessageExpressionConfigAttribute(expression, matcher);
}
@Test(expected = IllegalArgumentException.class)
public void constructorNullExpression() {
new MessageExpressionConfigAttribute(null);
new MessageExpressionConfigAttribute(null, matcher);
}
@Test(expected = IllegalArgumentException.class)
public void constructorNullMatcher() {
new MessageExpressionConfigAttribute(expression, null);
}
@Test
@@ -58,4 +72,16 @@ public class MessageExpressionConfigAttributeTests {
assertThat(attribute.toString()).isEqualTo(expression.getExpressionString());
}
@Test
public void postProcessContext() {
SimpDestinationMessageMatcher matcher = new SimpDestinationMessageMatcher("/topics/{topic}/**");
Message<?> message = MessageBuilder.withPayload("M").setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "/topics/someTopic/sub1").build();
EvaluationContext context = mock(EvaluationContext.class);
attribute = new MessageExpressionConfigAttribute(expression, matcher);
attribute.postProcess(context, message);
verify(context).setVariable("topic", "someTopic");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 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.
@@ -27,6 +27,7 @@ import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.core.Authentication;
import org.springframework.security.messaging.util.matcher.MessageMatcher;
import java.util.Arrays;
import java.util.Collection;
@@ -45,6 +46,8 @@ public class MessageExpressionVoterTests {
@Mock
Expression expression;
@Mock
MessageMatcher<?> matcher;
@Mock
SecurityExpressionHandler<Message> expressionHandler;
@Mock
EvaluationContext evaluationContext;
@@ -54,7 +57,7 @@ public class MessageExpressionVoterTests {
@Before
public void setup() {
attributes = Arrays
.<ConfigAttribute> asList(new MessageExpressionConfigAttribute(expression));
.<ConfigAttribute> asList(new MessageExpressionConfigAttribute(expression, matcher));
voter = new MessageExpressionVoter();
}
@@ -99,7 +102,7 @@ public class MessageExpressionVoterTests {
@Test
public void supportsMessageExpressionConfigAttributeTrue() {
assertThat(voter.supports(new MessageExpressionConfigAttribute(expression)))
assertThat(voter.supports(new MessageExpressionConfigAttribute(expression, matcher)))
.isTrue();
}
@@ -120,4 +123,20 @@ public class MessageExpressionVoterTests {
verify(expressionHandler).createEvaluationContext(authentication, message);
}
@Test
public void postProcessEvaluationContext(){
final MessageExpressionConfigAttribute configAttribute = mock(MessageExpressionConfigAttribute.class);
voter.setExpressionHandler(expressionHandler);
when(expressionHandler.createEvaluationContext(authentication, message)).thenReturn(evaluationContext);
when(configAttribute.getAuthorizeExpression()).thenReturn(expression);
attributes = Arrays.<ConfigAttribute> asList(configAttribute);
when(configAttribute.postProcess(evaluationContext, message)).thenReturn(evaluationContext);
when(expression.getValue(any(EvaluationContext.class), eq(Boolean.class)))
.thenReturn(true);
assertThat(voter.vote(authentication, message, attributes)).isEqualTo(
ACCESS_GRANTED);
verify(configAttribute).postProcess(evaluationContext, message);
}
}

View File

@@ -127,6 +127,23 @@ public class SimpDestinationMessageMatcherTests {
assertThat(matcher.matches(messageBuilder.build())).isTrue();
}
@Test
public void extractPathVariablesFromDestination() throws Exception {
matcher = new SimpDestinationMessageMatcher("/topics/{topic}/**");
messageBuilder.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "/topics/someTopic/sub1");
messageBuilder.setHeader(SimpMessageHeaderAccessor.MESSAGE_TYPE_HEADER,
SimpMessageType.MESSAGE);
assertThat(matcher.extractPathVariables(messageBuilder.build()).get("topic")).isEqualTo("someTopic");
}
@Test
public void extractedVariablesAreEmptyInNullDestination() throws Exception {
matcher = new SimpDestinationMessageMatcher("/topics/{topic}/**");
assertThat(matcher.extractPathVariables(messageBuilder.build())).isEmpty();
}
@Test
public void typeConstructorParameterIsTransmitted() throws Exception {
matcher = SimpDestinationMessageMatcher.createMessageMatcher("/match",
@@ -139,4 +156,4 @@ public class SimpDestinationMessageMatcherTests {
}
}
}