Skip to content

16635 initial commit #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

GuusArts
Copy link
Owner

@GuusArts GuusArts commented Apr 7, 2025

User description

Closes spring-projectsgh-16500


PR Type

Enhancement, Tests


Description

  • Introduced DestinationPathPatternMessageMatcher for enhanced message matching.

    • Supports matching message destinations using patterns and message types.
    • Replaces the deprecated SimpDestinationMessageMatcher.
  • Deprecated SimpDestinationMessageMatcher and related methods in favor of the new matcher.

  • Added new test cases for DestinationPathPatternMessageMatcher to validate functionality.

    • Includes tests for matching patterns, extracting path variables, and handling edge cases.
  • Updated existing tests to use the new DestinationPathPatternMessageMatcher.


Changes walkthrough 📝

Relevant files
Miscellaneous
2 files
WebSocketMessageBrokerSecurityConfigurationDocTests.java
Updated copyright year to 2025                                                     
+1/-1     
WebSocketMessageBrokerSecurityConfigurationTests.java
Updated copyright year to 2025                                                     
+1/-1     
Enhancement
3 files
MessageMatcherDelegatingAuthorizationManager.java
Integrated DestinationPathPatternMessageMatcher and deprecated old
matchers
+144/-12
DestinationPathPatternMessageMatcher.java
Added new `DestinationPathPatternMessageMatcher` implementation
+155/-0 
SimpDestinationMessageMatcher.java
Deprecated `SimpDestinationMessageMatcher` in favor of new matcher
+2/-0     
Tests
3 files
MessageMatcherDelegatingAuthorizationManagerTests.java
Updated tests to use `DestinationPathPatternMessageMatcher`
+63/-21 
DestinationPathPatternMessageMatcherTests.java
Added tests for `DestinationPathPatternMessageMatcher`     
+146/-0 
SimpDestinationMessageMatcherTests.java
Added edge case tests for deprecated `SimpDestinationMessageMatcher`
+10/-1   

Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • Copy link

    sourcery-ai bot commented Apr 7, 2025

    Reviewer's Guide by Sourcery

    This pull request introduces DestinationPathPatternMessageMatcher to provide more flexible message destination matching using path patterns. It also adds configuration options for customizing the path separator used during matching and deprecates the old SimpDestinationMessageMatcher.

    No diagrams generated as the changes look simple and do not need a visual representation.

    File-Level Changes

    Change Details Files
    Introduces DestinationPathPatternMessageMatcher to match messages based on destination path patterns, offering more flexible matching capabilities.
    • Added DestinationPathPatternMessageMatcher class.
    • Added DestinationPathPatternMessageMatcherTests class.
    • Deprecated SimpDestinationMessageMatcher class.
    • Updated MessageMatcherDelegatingAuthorizationManager to use DestinationPathPatternMessageMatcher.
    • Added builder methods for destination path patterns in MessageMatcherDelegatingAuthorizationManager.Builder.
    messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageMatcherDelegatingAuthorizationManager.java
    messaging/src/test/java/org/springframework/security/messaging/access/intercept/MessageMatcherDelegatingAuthorizationManagerTests.java
    messaging/src/main/java/org/springframework/security/messaging/util/matcher/SimpDestinationMessageMatcher.java
    messaging/src/main/java/org/springframework/security/messaging/util/matcher/DestinationPathPatternMessageMatcher.java
    messaging/src/test/java/org/springframework/security/messaging/util/matcher/DestinationPathPatternMessageMatcherTests.java
    Adds configuration options to MessageMatcherDelegatingAuthorizationManager.Builder to configure the path separator used for matching.
    • Added messageRouteSeparator() method to use the message route separator.
    • Deprecated simpDestPathMatcher() methods in favor of messageRouteSeparator().
    messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageMatcherDelegatingAuthorizationManager.java
    Updates tests to use the new destinationPathPatterns and messageRouteSeparator methods.
    • Replaced simpDestMatchers with destinationPathPatterns in tests.
    • Added tests for messageRouteSeparator.
    messaging/src/test/java/org/springframework/security/messaging/access/intercept/MessageMatcherDelegatingAuthorizationManagerTests.java

    Tips and commands

    Interacting with Sourcery

    • Trigger a new review: Comment @sourcery-ai review on the pull request.
    • Continue discussions: Reply directly to Sourcery's review comments.
    • Generate a GitHub issue from a review comment: Ask Sourcery to create an
      issue from a review comment by replying to it. You can also reply to a
      review comment with @sourcery-ai issue to create an issue from it.
    • Generate a pull request title: Write @sourcery-ai anywhere in the pull
      request title to generate a title at any time. You can also comment
      @sourcery-ai title on the pull request to (re-)generate the title at any time.
    • Generate a pull request summary: Write @sourcery-ai summary anywhere in
      the pull request body to generate a PR summary at any time exactly where you
      want it. You can also comment @sourcery-ai summary on the pull request to
      (re-)generate the summary at any time.
    • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
      request to (re-)generate the reviewer's guide at any time.
    • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
      pull request to resolve all Sourcery comments. Useful if you've already
      addressed all the comments and don't want to see them anymore.
    • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
      request to dismiss all existing Sourcery reviews. Especially useful if you
      want to start fresh with a new review - don't forget to comment
      @sourcery-ai review to trigger a new review!
    • Generate a plan of action for an issue: Comment @sourcery-ai plan on
      an issue to generate a plan of action for it.

    Customizing Your Experience

    Access your dashboard to:

    • Enable or disable review features such as the Sourcery-generated pull request
      summary, the reviewer's guide, and others.
    • Change the review language.
    • Add, remove or edit custom review instructions.
    • Adjust other review settings.

    Getting Help

    Copy link

    qodo-merge-pro bot commented Apr 7, 2025

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 PR contains tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Redundant Condition

    The authorizationContext method contains two consecutive closing braces without any code between them, which appears to be a mistake in the code structure.

    if (matcher instanceof Builder.LazySimpDestinationMessageMatcher pathMatcher) {
    	return new MessageAuthorizationContext<>(message, pathMatcher.extractPathVariables(message));
    }
    Incorrect Test

    The test matchesFalseWithDotSeparatorAndAdditionalWildcardPathSegment is asserting that a path matches when it shouldn't, which contradicts the test name and expected behavior.

    void matchesFalseWithDotSeparatorAndAdditionalWildcardPathSegment() {
    	this.matcher = DestinationPathPatternMessageMatcher.messageRoute().matcher("/destination/a.*");
    	this.messageBuilder.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "/destination/a.b");
    	assertThat(this.matcher.matches(this.messageBuilder.build())).isTrue();
    	this.messageBuilder.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "/destination/a.b.c");
    	assertThat(this.matcher.matches(this.messageBuilder.build())).isFalse();

    @GuusArts GuusArts changed the title Add DestinationPathPatternMessageMatcher 16635 initial commit Apr 7, 2025
    Copy link

    qodo-merge-pro bot commented Apr 7, 2025

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    General
    Simplify duplicate conditional logic

    The code is duplicating the same logic for both matcher types. Since both
    matchers have the same extractPathVariables method with the same signature, you
    can simplify this code by combining the conditions.

    messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageMatcherDelegatingAuthorizationManager.java [92-97]

    -if (matcher instanceof Builder.LazySimpDestinationMessageMatcher pathMatcher) {
    -    return new MessageAuthorizationContext<>(message, pathMatcher.extractPathVariables(message));
    -}
    -if (matcher instanceof Builder.LazySimpDestinationPatternMessageMatcher pathMatcher) {
    +if (matcher instanceof Builder.LazySimpDestinationMessageMatcher pathMatcher || 
    +    matcher instanceof Builder.LazySimpDestinationPatternMessageMatcher pathMatcher) {
         return new MessageAuthorizationContext<>(message, pathMatcher.extractPathVariables(message));
     }
    • Apply this suggestion
    Suggestion importance[1-10]: 5

    __

    Why: The suggestion correctly identifies redundant code that performs the same operation for two different matcher types. Combining the conditions would reduce duplication and improve maintainability. This is a valid code style improvement, though not critical for functionality.

    Low
    • More

    Copy link

    @sourcery-ai sourcery-ai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Hey @GuusArts - I've reviewed your changes - here's some feedback:

    Overall Comments:

    • Consider removing the LazySimpDestinationMessageMatcher and LazySimpDestinationPatternMessageMatcher classes and instead creating the matchers directly.
    • It might be helpful to provide a usage example in the javadoc for the new destinationPathPatterns method.
    Here's what I looked at during the review
    • 🟢 General issues: all looks good
    • 🟢 Security: all looks good
    • 🟢 Testing: all looks good
    • 🟡 Complexity: 2 issues found
    • 🟢 Documentation: all looks good

    Sourcery is free for open source - if you like our reviews please consider sharing them ✨
    Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

    @@ -87,12 +89,11 @@ private MessageAuthorizationContext<?> authorizationContext(MessageMatcher<?> ma
    if (!matcher.matches((Message) message)) {
    return null;
    }
    if (matcher instanceof SimpDestinationMessageMatcher simp) {
    Copy link

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    issue (complexity): Consider introducing a common interface for matchers that extract path variables to reduce duplicated instance-of checks in the authorizationContext method and simplify code navigation by checking the interface instead of concrete types..

    Consider introducing a common abstraction for matchers that extract path variables. Currently, you have duplicated instance‑of checks in the authorizationContext method for both lazy matcher types. You can reduce branching by defining an interface (e.g. HasPathVariables) and letting both lazy matcher classes implement it. Then update authorizationContext to check this interface rather than multiple concrete types.

    For example:

    // 1. Define the common interface
    public interface HasPathVariables {
        Map<String, String> extractPathVariables(Message<?> message);
    }
    // 2. Have your lazy matcher classes implement it
    private static final class LazySimpDestinationMessageMatcher implements MessageMatcher<Object>, HasPathVariables {
        // existing code
        @Override
        public Map<String, String> extractPathVariables(Message<?> message) {
            return this.delegate.get().extractPathVariables(message);
        }
        // ...
    }
    
    private static final class LazySimpDestinationPatternMessageMatcher implements MessageMatcher<Object>, HasPathVariables {
        // existing code
        @Override
        public Map<String, String> extractPathVariables(Message<?> message) {
            return this.delegate.get().extractPathVariables(message);
        }
        // ...
    }
    // 3. Simplify the authorizationContext method with a single check:
    private MessageAuthorizationContext<?> authorizationContext(MessageMatcher<?> matcher, Message<?> message) {
        if (!matcher.matches(message)) {
            return null;
        }
        if (matcher instanceof HasPathVariables hv) {
            return new MessageAuthorizationContext<>(message, hv.extractPathVariables(message));
        }
        return new MessageAuthorizationContext<>(message);
    }

    By applying these changes you reduce duplicated logic, simplify navigation in the code, and maintain all current functionality.

    * Initialize this builder with a {@link PathPatternRouteMatcher} configured with the
    * {@link org.springframework.http.server.PathContainer.Options#HTTP_PATH} separator
    */
    public static Builder withDefaults() {
    Copy link

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    issue (complexity): Consider consolidating the two static builder methods into a single parameterized builder method using an enum to specify the route matcher type, simplifying the API and reducing duplication while maintaining functionality

    You could simplify the API by reducing the dual static builder methods and abstracting the route matcher choice into a single parameterized builder. For example, define an enum to clarify the matcher type and consolidate builder creation:

    public enum RouteMatcherType {
        SLASH, DOT
    }

    Then replace the two static methods with one unified builder method:

    public static Builder builder(RouteMatcherType type) {
        PathPatternRouteMatcher matcher = (type == RouteMatcherType.DOT)
                ? DOT_SEPARATED_ROUTE_MATCHER
                : SLASH_SEPARATED_ROUTE_MATCHER;
        return new Builder(matcher);
    }

    This change removes duplicative entry points while keeping all functionality intact. The rest of your Builder and matching logic remains the same.

    Copy link

    sonarqubecloud bot commented Apr 7, 2025

    @GuusArts GuusArts requested a review from Copilot May 15, 2025 09:31
    Copy link

    @Copilot Copilot AI left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Pull Request Overview

    This PR introduces a new DestinationPathPatternMessageMatcher to enhance message destination matching while deprecating the old SimpDestinationMessageMatcher. Key changes include new matcher implementation with support for path variable extraction, updated tests to verify the new behaviors, and minor documentation updates (e.g. copyright year).

    Reviewed Changes

    Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

    Show a summary per file
    File Description
    SimpDestinationMessageMatcherTests.java Added tests to ensure extraction method throws an exception when no match is found.
    DestinationPathPatternMessageMatcherTests.java Added comprehensive tests for the new matcher covering various route patterns and message types.
    MessageMatcherDelegatingAuthorizationManagerTests.java Updated tests to use destinationPathPatterns and messageRouteSeparator, replacing deprecated methods.
    SimpDestinationMessageMatcher.java Marked the class as deprecated and updated the Javadoc to refer to the new matcher.
    DestinationPathPatternMessageMatcher.java Introduced the new implementation leveraging PathPatternRouteMatcher for both slash- and dot-separated routes.
    MessageMatcherDelegatingAuthorizationManager.java Integrated the new matcher into the authorization context and replaced deprecated lazy matcher usage.
    WebSocketMessageBrokerSecurityConfigurationTests.java, WebSocketMessageBrokerSecurityConfigurationDocTests.java Updated copyright statements.
    Comments suppressed due to low confidence (1)

    messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageMatcherDelegatingAuthorizationManager.java:516

    • [nitpick] Consider renaming 'LazySimpDestinationPatternMessageMatcher' to 'LazyDestinationPathPatternMessageMatcher' to maintain clear consistency with the new 'DestinationPathPatternMessageMatcher' naming in the codebase.
    private static final class LazySimpDestinationPatternMessageMatcher implements MessageMatcher<Object> {
    

    @GuusArts GuusArts closed this May 15, 2025
    @GuusArts GuusArts reopened this May 15, 2025
    Copy link

    snyk-io bot commented May 15, 2025

    🎉 Snyk checks have passed. No issues have been found so far.

    security/snyk check is complete. No issues have been found. (View Details)

    code/snyk check is complete. No issues have been found. (View Details)

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    Deprecate usages of PathMatcher in Web Socket support
    2 participants