diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/messaging/MessageSecurityMetadataSourceRegistry.java b/config/src/main/java/org/springframework/security/config/annotation/web/messaging/MessageSecurityMetadataSourceRegistry.java deleted file mode 100644 index b9969d1bf5..0000000000 --- a/config/src/main/java/org/springframework/security/config/annotation/web/messaging/MessageSecurityMetadataSourceRegistry.java +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright 2002-2022 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 - * - * https://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.config.annotation.web.messaging; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.messaging.Message; -import org.springframework.messaging.simp.SimpMessageType; -import org.springframework.security.access.expression.SecurityExpressionHandler; -import org.springframework.security.config.annotation.web.configurers.RememberMeConfigurer; -import org.springframework.security.messaging.access.expression.DefaultMessageSecurityExpressionHandler; -import org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory; -import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager; -import org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource; -import org.springframework.security.messaging.util.matcher.MessageMatcher; -import org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher; -import org.springframework.security.messaging.util.matcher.SimpMessageTypeMatcher; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.Assert; -import org.springframework.util.PathMatcher; -import org.springframework.util.StringUtils; - -/** - * Allows mapping security constraints using {@link MessageMatcher} to the security - * expressions. - * - * @author Rob Winch - * @since 4.0 - * @deprecated Use {@link MessageMatcherDelegatingAuthorizationManager} instead - */ -@Deprecated -public class MessageSecurityMetadataSourceRegistry { - - private static final String permitAll = "permitAll"; - - private static final String denyAll = "denyAll"; - - private static final String anonymous = "anonymous"; - - private static final String authenticated = "authenticated"; - - private static final String fullyAuthenticated = "fullyAuthenticated"; - - private static final String rememberMe = "rememberMe"; - - private SecurityExpressionHandler> expressionHandler = new DefaultMessageSecurityExpressionHandler<>(); - - private final LinkedHashMap matcherToExpression = new LinkedHashMap<>(); - - private DelegatingPathMatcher pathMatcher = new DelegatingPathMatcher(); - - private boolean defaultPathMatcher = true; - - /** - * Maps any {@link Message} to a security expression. - * @return the Expression to associate - */ - public Constraint anyMessage() { - return matchers(MessageMatcher.ANY_MESSAGE); - } - - /** - * Maps any {@link Message} that has a null SimpMessageHeaderAccessor destination - * header (i.e. CONNECT, CONNECT_ACK, HEARTBEAT, UNSUBSCRIBE, DISCONNECT, - * DISCONNECT_ACK, OTHER) - * @return the Expression to associate - */ - public Constraint nullDestMatcher() { - return matchers(SimpDestinationMessageMatcher.NULL_DESTINATION_MATCHER); - } - - /** - * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances. - * @param typesToMatch the {@link SimpMessageType} instance to match on - * @return the {@link Constraint} associated to the matchers. - */ - public Constraint simpTypeMatchers(SimpMessageType... typesToMatch) { - MessageMatcher[] typeMatchers = new MessageMatcher[typesToMatch.length]; - for (int i = 0; i < typesToMatch.length; i++) { - SimpMessageType typeToMatch = typesToMatch[i]; - typeMatchers[i] = new SimpMessageTypeMatcher(typeToMatch); - } - return matchers(typeMatchers); - } - - /** - * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances without - * regard to the {@link SimpMessageType}. If no destination is found on the Message, - * then the Matcher returns false. - * @param patterns the patterns to create - * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher} - * from. Uses - * {@link MessageSecurityMetadataSourceRegistry#simpDestPathMatcher(PathMatcher)} . - * @return the {@link Constraint} that is associated to the {@link MessageMatcher} - * @see MessageSecurityMetadataSourceRegistry#simpDestPathMatcher(PathMatcher) - */ - public Constraint simpDestMatchers(String... patterns) { - return simpDestMatchers(null, patterns); - } - - /** - * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances that match - * on {@code SimpMessageType.MESSAGE}. If no destination is found on the Message, then - * the Matcher returns false. - * @param patterns the patterns to create - * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher} - * from. Uses - * {@link MessageSecurityMetadataSourceRegistry#simpDestPathMatcher(PathMatcher)}. - * @return the {@link Constraint} that is associated to the {@link MessageMatcher} - * @see MessageSecurityMetadataSourceRegistry#simpDestPathMatcher(PathMatcher) - */ - public Constraint simpMessageDestMatchers(String... patterns) { - return simpDestMatchers(SimpMessageType.MESSAGE, patterns); - } - - /** - * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances that match - * on {@code SimpMessageType.SUBSCRIBE}. If no destination is found on the Message, - * then the Matcher returns false. - * @param patterns the patterns to create - * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher} - * from. Uses - * {@link MessageSecurityMetadataSourceRegistry#simpDestPathMatcher(PathMatcher)}. - * @return the {@link Constraint} that is associated to the {@link MessageMatcher} - * @see MessageSecurityMetadataSourceRegistry#simpDestPathMatcher(PathMatcher) - */ - public Constraint simpSubscribeDestMatchers(String... patterns) { - return simpDestMatchers(SimpMessageType.SUBSCRIBE, patterns); - } - - /** - * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances. If no - * destination is found on the Message, then the Matcher returns false. - * @param type the {@link SimpMessageType} to match on. If null, the - * {@link SimpMessageType} is not considered for matching. - * @param patterns the patterns to create - * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher} - * from. Uses - * {@link MessageSecurityMetadataSourceRegistry#simpDestPathMatcher(PathMatcher)}. - * @return the {@link Constraint} that is associated to the {@link MessageMatcher} - * @see MessageSecurityMetadataSourceRegistry#simpDestPathMatcher(PathMatcher) - */ - private Constraint simpDestMatchers(SimpMessageType type, String... patterns) { - List matchers = new ArrayList<>(patterns.length); - for (String pattern : patterns) { - matchers.add(new PathMatcherMessageMatcherBuilder(pattern, type)); - } - return new Constraint(matchers); - } - - /** - * The {@link PathMatcher} to be used with the - * {@link MessageSecurityMetadataSourceRegistry#simpDestMatchers(String...)}. The - * default is to use the default constructor of {@link AntPathMatcher}. - * @param pathMatcher the {@link PathMatcher} to use. Cannot be null. - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization. - */ - public MessageSecurityMetadataSourceRegistry simpDestPathMatcher(PathMatcher pathMatcher) { - Assert.notNull(pathMatcher, "pathMatcher cannot be null"); - this.pathMatcher.setPathMatcher(pathMatcher); - this.defaultPathMatcher = false; - return this; - } - - /** - * Determines if the {@link #simpDestPathMatcher(PathMatcher)} has been explicitly - * set. - * @return true if {@link #simpDestPathMatcher(PathMatcher)} has been explicitly set, - * else false. - */ - protected boolean isSimpDestPathMatcherConfigured() { - return !this.defaultPathMatcher; - } - - /** - * Maps a {@link List} of {@link MessageMatcher} instances to a security expression. - * @param matchers the {@link MessageMatcher} instances to map. - * @return The {@link Constraint} that is associated to the {@link MessageMatcher} - * instances - */ - public Constraint matchers(MessageMatcher... matchers) { - List builders = new ArrayList<>(matchers.length); - for (MessageMatcher matcher : matchers) { - builders.add(new PreBuiltMatcherBuilder(matcher)); - } - return new Constraint(builders); - } - - /** - * The {@link SecurityExpressionHandler} to be used. The default is to use - * {@link DefaultMessageSecurityExpressionHandler}. - * @param expressionHandler the {@link SecurityExpressionHandler} to use. Cannot be - * null. - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization. - */ - public MessageSecurityMetadataSourceRegistry expressionHandler( - SecurityExpressionHandler> expressionHandler) { - Assert.notNull(expressionHandler, "expressionHandler cannot be null"); - this.expressionHandler = expressionHandler; - return this; - } - - /** - * Allows subclasses to create creating a {@link MessageSecurityMetadataSource}. - * - *

- * This is not exposed so as not to confuse users of the API, which should never - * invoke this method. - *

- * @return the {@link MessageSecurityMetadataSource} to use - */ - protected MessageSecurityMetadataSource createMetadataSource() { - LinkedHashMap, String> matcherToExpression = new LinkedHashMap<>(); - for (Map.Entry entry : this.matcherToExpression.entrySet()) { - matcherToExpression.put(entry.getKey().build(), entry.getValue()); - } - return ExpressionBasedMessageSecurityMetadataSourceFactory - .createExpressionMessageMetadataSource(matcherToExpression, this.expressionHandler); - } - - /** - * Allows determining if a mapping was added. - * - *

- * This is not exposed so as not to confuse users of the API, which should never need - * to invoke this method. - *

- * @return true if a mapping was added, else false - */ - protected boolean containsMapping() { - return !this.matcherToExpression.isEmpty(); - } - - private static String hasAnyRole(String... authorities) { - String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','ROLE_"); - return "hasAnyRole('ROLE_" + anyAuthorities + "')"; - } - - private static String hasRole(String role) { - Assert.notNull(role, "role cannot be null"); - if (role.startsWith("ROLE_")) { - throw new IllegalArgumentException( - "role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'"); - } - return "hasRole('ROLE_" + role + "')"; - } - - private static String hasAuthority(String authority) { - return "hasAuthority('" + authority + "')"; - } - - private static String hasAnyAuthority(String... authorities) { - String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','"); - return "hasAnyAuthority('" + anyAuthorities + "')"; - } - - /** - * Represents the security constraint to be applied to the {@link MessageMatcher} - * instances. - */ - public final class Constraint { - - private final List messageMatchers; - - /** - * Creates a new instance - * @param messageMatchers the {@link MessageMatcher} instances to map to this - * constraint - */ - private Constraint(List messageMatchers) { - Assert.notEmpty(messageMatchers, "messageMatchers cannot be null or empty"); - this.messageMatchers = messageMatchers; - } - - /** - * Shortcut for specifying {@link Message} instances require a particular role. If - * you do not want to have "ROLE_" automatically inserted see - * {@link #hasAuthority(String)}. - * @param role the role to require (i.e. USER, ADMIN, etc). Note, it should not - * start with "ROLE_" as this is automatically inserted. - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - */ - public MessageSecurityMetadataSourceRegistry hasRole(String role) { - return access(MessageSecurityMetadataSourceRegistry.hasRole(role)); - } - - /** - * Shortcut for specifying {@link Message} instances require any of a number of - * roles. If you do not want to have "ROLE_" automatically inserted see - * {@link #hasAnyAuthority(String...)} - * @param roles the roles to require (i.e. USER, ADMIN, etc). Note, it should not - * start with "ROLE_" as this is automatically inserted. - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - */ - public MessageSecurityMetadataSourceRegistry hasAnyRole(String... roles) { - return access(MessageSecurityMetadataSourceRegistry.hasAnyRole(roles)); - } - - /** - * Specify that {@link Message} instances require a particular authority. - * @param authority the authority to require (i.e. ROLE_USER, ROLE_ADMIN, etc). - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - */ - public MessageSecurityMetadataSourceRegistry hasAuthority(String authority) { - return access(MessageSecurityMetadataSourceRegistry.hasAuthority(authority)); - } - - /** - * Specify that {@link Message} instances requires any of a number authorities. - * @param authorities the requests require at least one of the authorities (i.e. - * "ROLE_USER","ROLE_ADMIN" would mean either "ROLE_USER" or "ROLE_ADMIN" is - * required). - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - */ - public MessageSecurityMetadataSourceRegistry hasAnyAuthority(String... authorities) { - return access(MessageSecurityMetadataSourceRegistry.hasAnyAuthority(authorities)); - } - - /** - * Specify that Messages are allowed by anyone. - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - */ - public MessageSecurityMetadataSourceRegistry permitAll() { - return access(permitAll); - } - - /** - * Specify that Messages are allowed by anonymous users. - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - */ - public MessageSecurityMetadataSourceRegistry anonymous() { - return access(anonymous); - } - - /** - * Specify that Messages are allowed by users that have been remembered. - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - * @see RememberMeConfigurer - */ - public MessageSecurityMetadataSourceRegistry rememberMe() { - return access(rememberMe); - } - - /** - * Specify that Messages are not allowed by anyone. - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - */ - public MessageSecurityMetadataSourceRegistry denyAll() { - return access(denyAll); - } - - /** - * Specify that Messages are allowed by any authenticated user. - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - */ - public MessageSecurityMetadataSourceRegistry authenticated() { - return access(authenticated); - } - - /** - * Specify that Messages are allowed by users who have authenticated and were not - * "remembered". - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - * @see RememberMeConfigurer - */ - public MessageSecurityMetadataSourceRegistry fullyAuthenticated() { - return access(fullyAuthenticated); - } - - /** - * Allows specifying that Messages are secured by an arbitrary expression - * @param attribute the expression to secure the URLs (i.e. "hasRole('ROLE_USER') - * and hasRole('ROLE_SUPER')") - * @return the {@link MessageSecurityMetadataSourceRegistry} for further - * customization - */ - public MessageSecurityMetadataSourceRegistry access(String attribute) { - for (MatcherBuilder messageMatcher : this.messageMatchers) { - MessageSecurityMetadataSourceRegistry.this.matcherToExpression.put(messageMatcher, attribute); - } - return MessageSecurityMetadataSourceRegistry.this; - } - - } - - private static final class PreBuiltMatcherBuilder implements MatcherBuilder { - - private MessageMatcher matcher; - - private PreBuiltMatcherBuilder(MessageMatcher matcher) { - this.matcher = matcher; - } - - @Override - public MessageMatcher build() { - return this.matcher; - } - - } - - private final class PathMatcherMessageMatcherBuilder implements MatcherBuilder { - - private final String pattern; - - private final SimpMessageType type; - - private PathMatcherMessageMatcherBuilder(String pattern, SimpMessageType type) { - this.pattern = pattern; - this.type = type; - } - - @Override - public MessageMatcher build() { - if (this.type == null) { - return new SimpDestinationMessageMatcher(this.pattern, - MessageSecurityMetadataSourceRegistry.this.pathMatcher); - } - if (SimpMessageType.MESSAGE == this.type) { - return SimpDestinationMessageMatcher.createMessageMatcher(this.pattern, - MessageSecurityMetadataSourceRegistry.this.pathMatcher); - } - if (SimpMessageType.SUBSCRIBE == this.type) { - return SimpDestinationMessageMatcher.createSubscribeMatcher(this.pattern, - MessageSecurityMetadataSourceRegistry.this.pathMatcher); - } - throw new IllegalStateException(this.type + " is not supported since it does not have a destination"); - } - - } - - private interface MatcherBuilder { - - MessageMatcher build(); - - } - - static class DelegatingPathMatcher implements PathMatcher { - - private PathMatcher delegate = new AntPathMatcher(); - - @Override - public boolean isPattern(String path) { - return this.delegate.isPattern(path); - } - - @Override - public boolean match(String pattern, String path) { - return this.delegate.match(pattern, path); - } - - @Override - public boolean matchStart(String pattern, String path) { - return this.delegate.matchStart(pattern, path); - } - - @Override - public String extractPathWithinPattern(String pattern, String path) { - return this.delegate.extractPathWithinPattern(pattern, path); - } - - @Override - public Map extractUriTemplateVariables(String pattern, String path) { - return this.delegate.extractUriTemplateVariables(pattern, path); - } - - @Override - public Comparator getPatternComparator(String path) { - return this.delegate.getPatternComparator(path); - } - - @Override - public String combine(String pattern1, String pattern2) { - return this.delegate.combine(pattern1, pattern2); - } - - void setPathMatcher(PathMatcher pathMatcher) { - this.delegate = pathMatcher; - } - - } - -} diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/messaging/MessageSecurityMetadataSourceRegistryTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/messaging/MessageSecurityMetadataSourceRegistryTests.java deleted file mode 100644 index 7070547813..0000000000 --- a/config/src/test/java/org/springframework/security/config/annotation/web/messaging/MessageSecurityMetadataSourceRegistryTests.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright 2002-2017 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 - * - * https://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.config.annotation.web.messaging; - -import java.util.Collection; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.messaging.Message; -import org.springframework.messaging.simp.SimpMessageHeaderAccessor; -import org.springframework.messaging.simp.SimpMessageType; -import org.springframework.messaging.support.MessageBuilder; -import org.springframework.security.access.ConfigAttribute; -import org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource; -import org.springframework.security.messaging.util.matcher.MessageMatcher; -import org.springframework.util.AntPathMatcher; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.BDDMockito.given; - -@ExtendWith(MockitoExtension.class) -public class MessageSecurityMetadataSourceRegistryTests { - - @Mock - private MessageMatcher matcher; - - private MessageSecurityMetadataSourceRegistry messages; - - private Message message; - - @BeforeEach - public void setup() { - this.messages = new MessageSecurityMetadataSourceRegistry(); - // @formatter:off - this.message = MessageBuilder.withPayload("Hi") - .setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "location") - .setHeader(SimpMessageHeaderAccessor.MESSAGE_TYPE_HEADER, SimpMessageType.MESSAGE) - .build(); - // @formatter:on - } - - // See - // https://github.com/spring-projects/spring-security/commit/3f30529039c76facf335d6ca69d18d8ae287f3f9#commitcomment-7412712 - // https://jira.spring.io/browse/SPR-11660 - @Test - public void simpDestMatchersCustom() { - // @formatter:off - this.message = MessageBuilder.withPayload("Hi") - .setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "price.stock.1.2") - .build(); - // @formatter:on - this.messages.simpDestPathMatcher(new AntPathMatcher(".")).simpDestMatchers("price.stock.*").permitAll(); - assertThat(getAttribute()).isNull(); - // @formatter:off - this.message = MessageBuilder.withPayload("Hi") - .setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "price.stock.1.2") - .build(); - // @formatter:on - this.messages.simpDestPathMatcher(new AntPathMatcher(".")).simpDestMatchers("price.stock.**").permitAll(); - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - @Test - public void simpDestMatchersCustomSetAfterMatchersDoesNotMatter() { - // @formatter:off - this.message = MessageBuilder.withPayload("Hi") - .setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "price.stock.1.2") - .build(); - // @formatter:on - this.messages.simpDestMatchers("price.stock.*").permitAll().simpDestPathMatcher(new AntPathMatcher(".")); - assertThat(getAttribute()).isNull(); - // @formatter:off - this.message = MessageBuilder.withPayload("Hi") - .setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "price.stock.1.2") - .build(); - // @formatter:on - this.messages.simpDestMatchers("price.stock.**").permitAll().simpDestPathMatcher(new AntPathMatcher(".")); - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - @Test - public void pathMatcherNull() { - assertThatIllegalArgumentException().isThrownBy(() -> this.messages.simpDestPathMatcher(null)); - } - - @Test - public void matchersFalse() { - this.messages.matchers(this.matcher).permitAll(); - assertThat(getAttribute()).isNull(); - } - - @Test - public void matchersTrue() { - given(this.matcher.matches(this.message)).willReturn(true); - this.messages.matchers(this.matcher).permitAll(); - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - @Test - public void simpDestMatchersExact() { - this.messages.simpDestMatchers("location").permitAll(); - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - @Test - public void simpDestMatchersMulti() { - // @formatter:off - this.messages - .simpDestMatchers("admin/**", "api/**").hasRole("ADMIN") - .simpDestMatchers("location").permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - @Test - public void simpDestMatchersRole() { - // @formatter:off - this.messages - .simpDestMatchers("admin/**", "location/**").hasRole("ADMIN") - .anyMessage().denyAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("hasRole('ROLE_ADMIN')"); - } - - @Test - public void simpDestMatchersAnyRole() { - // @formatter:off - this.messages - .simpDestMatchers("admin/**", "location/**").hasAnyRole("ADMIN", "ROOT") - .anyMessage().denyAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("hasAnyRole('ROLE_ADMIN','ROLE_ROOT')"); - } - - @Test - public void simpDestMatchersAuthority() { - // @formatter:off - this.messages - .simpDestMatchers("admin/**", "location/**").hasAuthority("ROLE_ADMIN") - .anyMessage().fullyAuthenticated(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("hasAuthority('ROLE_ADMIN')"); - } - - @Test - public void simpDestMatchersAccess() { - String expected = "hasRole('ROLE_ADMIN') and fullyAuthenticated"; - this.messages.simpDestMatchers("admin/**", "location/**").access(expected).anyMessage().denyAll(); - assertThat(getAttribute()).isEqualTo(expected); - } - - @Test - public void simpDestMatchersAnyAuthority() { - // @formatter:off - this.messages - .simpDestMatchers("admin/**", "location/**").hasAnyAuthority("ROLE_ADMIN", "ROLE_ROOT") - .anyMessage().denyAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("hasAnyAuthority('ROLE_ADMIN','ROLE_ROOT')"); - } - - @Test - public void simpDestMatchersRememberMe() { - // @formatter:off - this.messages - .simpDestMatchers("admin/**", "location/**").rememberMe() - .anyMessage().denyAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("rememberMe"); - } - - @Test - public void simpDestMatchersAnonymous() { - // @formatter:off - this.messages - .simpDestMatchers("admin/**", "location/**").anonymous() - .anyMessage().denyAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("anonymous"); - } - - @Test - public void simpDestMatchersFullyAuthenticated() { - // @formatter:off - this.messages - .simpDestMatchers("admin/**", "location/**").fullyAuthenticated() - .anyMessage().denyAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("fullyAuthenticated"); - } - - @Test - public void simpDestMatchersDenyAll() { - // @formatter:off - this.messages - .simpDestMatchers("admin/**", "location/**").denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("denyAll"); - } - - @Test - public void simpDestMessageMatchersNotMatch() { - // @formatter:off - this.messages. - simpMessageDestMatchers("admin/**").denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - @Test - public void simpDestMessageMatchersMatch() { - // @formatter:off - this.messages - .simpMessageDestMatchers("location/**").denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("denyAll"); - } - - @Test - public void simpDestSubscribeMatchersNotMatch() { - // @formatter:off - this.messages - .simpSubscribeDestMatchers("location/**").denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - @Test - public void simpDestSubscribeMatchersMatch() { - // @formatter:off - this.message = MessageBuilder.fromMessage(this.message) - .setHeader(SimpMessageHeaderAccessor.MESSAGE_TYPE_HEADER, SimpMessageType.SUBSCRIBE) - .build(); - this.messages - .simpSubscribeDestMatchers("location/**").denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("denyAll"); - } - - @Test - public void nullDestMatcherNotMatches() { - // @formatter:off - this.messages - .nullDestMatcher().denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - @Test - public void nullDestMatcherMatch() { - // @formatter:off - this.message = MessageBuilder.withPayload("Hi") - .setHeader(SimpMessageHeaderAccessor.MESSAGE_TYPE_HEADER, SimpMessageType.CONNECT) - .build(); - this.messages - .nullDestMatcher().denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("denyAll"); - } - - @Test - public void simpTypeMatchersMatch() { - // @formatter:off - this.messages - .simpTypeMatchers(SimpMessageType.MESSAGE).denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("denyAll"); - } - - @Test - public void simpTypeMatchersMatchMulti() { - // @formatter:off - this.messages - .simpTypeMatchers(SimpMessageType.CONNECT, SimpMessageType.MESSAGE).denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("denyAll"); - } - - @Test - public void simpTypeMatchersNotMatch() { - // @formatter:off - this.messages - .simpTypeMatchers(SimpMessageType.CONNECT).denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - @Test - public void simpTypeMatchersNotMatchMulti() { - // @formatter:off - this.messages - .simpTypeMatchers(SimpMessageType.CONNECT, SimpMessageType.DISCONNECT).denyAll() - .anyMessage().permitAll(); - // @formatter:on - assertThat(getAttribute()).isEqualTo("permitAll"); - } - - private String getAttribute() { - MessageSecurityMetadataSource source = this.messages.createMetadataSource(); - Collection attrs = source.getAttributes(this.message); - if (attrs == null) { - return null; - } - assertThat(attrs).hasSize(1); - return attrs.iterator().next().toString(); - } - -}