Skip to content
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

Core: Fix BaseResponse.uri_to_regexp #8193

Merged
merged 4 commits into from
Oct 6, 2024
Merged

Conversation

MSSputnik
Copy link
Contributor

Found an issue on how the URIs send by the boto3 client converted into function names.

I have 2 URI:

  1. /accounts/{AwsAccountId}/namespaces/{Namespace}/groups
  2. /accounts/{AwsAccountId}/namespaces/{Namespace}/users/{UserName}/groups

These URIs were converted into these regular expressions:

  1. /accounts/(?P<AwsAccountId>.*)/namespaces/(?P<Namespace>.*)/groups
  2. /accounts/(?P<AwsAccountId>.*)/namespaces/(?P<Namespace>.*)/users/(?P<UserName>.*)/groups

Unfortunately both request URIs match regular expression 1:

  1. /accounts/1235/namespaces/default/groups
  2. /accounts/123456789012/namespaces/default/users/authoremail%40example.com/groups

Investigating on how AWS defines the requestUri in the service.json files I found that there are 2 types of parameters.

  1. e.g. quicksight: /accounts/{AwsAccountId}/namespaces/{Namespace}/users/{UserName}/groups
  2. e.g. workspaceweb: /portals/{portalArn+}/trustStores

As you can see in the requestUri from workspaceweb there is a + at the end of the parameter. Checking the code this means, that the parameter can contain a / as it is a Arn. The same I found in the S3 API.

To fix this issue I changed the function BaseResponse.uri_to_regexp to replace the parameter without the + at the end with (?P<{name}>[^/]+) to allow any text but no /. For the parameter with a + I used (?P<{name}>.+) to allow any character with minimum length of 1.
I found the usage of .* is not recommended as this causes issues with URIs form the mediastoredata API where ^/$ is ListItems and ^/{Path+}$ is GetObject.

On my development machine most of the test ran successfully. In local mode 2 tests fail and in server mode 3 tests fail. Checking this failuers, I think they are unrelated to this change and therefore I created this pull request.

Copy link

codecov bot commented Oct 3, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 94.53%. Comparing base (caf67cc) to head (24e55ad).
Report is 19 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #8193   +/-   ##
=======================================
  Coverage   94.53%   94.53%           
=======================================
  Files        1155     1155           
  Lines       99714    99707    -7     
=======================================
- Hits        94266    94261    -5     
+ Misses       5448     5446    -2     
Flag Coverage Δ
servertests 28.84% <100.00%> (+0.06%) ⬆️
unittests 94.50% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@bblommers bblommers added the moto-core PR's that touch the core functionality. This will trigger additional tests. label Oct 5, 2024
@MSSputnik
Copy link
Contributor Author

Hello @bblommers ,

I checked the failing tests and they are also failing without my changes. (Using the current moto main branch).

The first 9 tests have in common that they use the old requests library 0.15. The tests using 0.17.0 succeed.
The 10th test fails due to some docker problems.

Can you please check?
I think I can not do anything about the failing tests.
Thanks

if not re.match("^{.*}$", elem):
# URL-parts sometimes contain a $
# Like Greengrass: /../deployments/$reset
# We don't want to our regex to think this marks an end-of-line, so let's escape it
return elem.replace("$", r"\$")

# When the element ends with +} the parameter can contain a / otherwise not.
no_slash_allowed = False if "+" == elem[-2:-1] else True
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any objections to making the naming positive, and having a more direct check? Something like this is more readable IMO:

slash_allowed = elem.endswith("+}")
if slash_allowed:
    return ...
return ...

@bblommers
Copy link
Collaborator

Don't worry about the tests @MSSputnik. I've restarted them a few times to check the performance, as regex changes can make quite a big impact. But that all looks good as far as I'm concerned - the tests just happen to be particularly flaky today.

It is a good change though! I did look into this recently as well, because some ARN's weren't being matched properly, but I didn't notice the difference in behaviour between {param} and {param+}.
I have a feeling that this could simplify a lot of URL matching logic in various services.

The only question I had was around variable naming essentially - having a negative variable isn't always easy to read, and having a double negative (not_x = False if..) is even more difficult to wrap your head around IMO.

@MSSputnik
Copy link
Contributor Author

I updated the condition.
The reason for using the negative clause were historical. In first I just replaced the is_last condition. No technical cause.

Copy link
Collaborator

@bblommers bblommers left a comment

Choose a reason for hiding this comment

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

Great - thank you so much @MSSputnik!

@bblommers bblommers added this to the 5.0.17 milestone Oct 6, 2024
@bblommers bblommers merged commit 43410b9 into getmoto:master Oct 6, 2024
53 checks passed
@bblommers bblommers changed the title Fix BaseResponse.uri_to_regexp Core: Fix BaseResponse.uri_to_regexp Oct 6, 2024
Copy link
Contributor

github-actions bot commented Oct 6, 2024

This is now part of moto >= 5.0.17.dev16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
moto-core PR's that touch the core functionality. This will trigger additional tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants