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

Convert signature verification specs to request specs #28443

Merged
merged 2 commits into from
Dec 22, 2023

Conversation

ClearlyClaire
Copy link
Contributor

Prerequisite for fixing #18474

I decided to hardcode the signature headers so that:

  • the tests are more robust
  • other implementers can have a look at examples Mastodon will take as input, together with a keypair to test things with

@ClearlyClaire
Copy link
Contributor Author

cc @mjankowski since you're working a lot on specs and code style lately, I'd like your feedback on it, especially the long lines, and the routing issues (I used your pattern, but it clears the existing routes)

Copy link

codecov bot commented Dec 20, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (c7c7279) 84.28% compared to head (1c569c1) 84.31%.
Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #28443      +/-   ##
==========================================
+ Coverage   84.28%   84.31%   +0.02%     
==========================================
  Files        1039     1039              
  Lines       28226    28226              
  Branches     4550     4550              
==========================================
+ Hits        23790    23798       +8     
+ Misses       3287     3281       -6     
+ Partials     1149     1147       -2     

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

@mjankowski
Copy link
Contributor

cc @mjankowski since you're working a lot on specs and code style lately, I'd like your feedback on it, especially the long lines, and the routing issues (I used your pattern, but it clears the existing routes)

On the routes/controller - I think what you are doing here is the least bad way to do this. It's just not as smooth in request specs as controller specs where it's more expected to do this. If we find a better way we can update, but at least for now this method matches what's done elsewhere (a CSP spec, maybe?)

On the long lines with the signature values ... the only things I can think of here both from readability and linting perspective would be to put the whole signature value into a heredoc assigned variable, and then do string interpolation when using the value. If the value is purposefully wrong, then just using the raw value makes sense. If the value is calculated from the headers, it might be nice to actually do the calculation here, and/or leave a comment line showing how it was built -- especially if as noted in the PR description, there's some side benefit here to potentially showing others what's being done and what's right/wrong approaches, etc.

@ClearlyClaire ClearlyClaire force-pushed the tests/signature-verification-tests branch 2 times, most recently from 341b2e7 to e8618d2 Compare December 20, 2023 14:45
@ClearlyClaire
Copy link
Contributor Author

On the routes/controller - I think what you are doing here is the least bad way to do this. It's just not as smooth in request specs as controller specs where it's more expected to do this. If we find a better way we can update, but at least for now this method matches what's done elsewhere (a CSP spec, maybe?)

It's similar to what you did with the CSP spec, yeah. We could also private send to eval_block instead of draw, but this wouldn't work because of the catch-all unmatched_route fallback we have in config/routes.rb. Instead, I re-added the one route the code uses.

On the long lines with the signature values ... the only things I can think of here both from readability and linting perspective would be to put the whole signature value into a heredoc assigned variable, and then do string interpolation when using the value. If the value is purposefully wrong, then just using the raw value makes sense. If the value is calculated from the headers, it might be nice to actually do the calculation here, and/or leave a comment line showing how it was built -- especially if as noted in the PR description, there's some side benefit here to potentially showing others what's being done and what's right/wrong approaches, etc.

Do you have an example on how you'd do it? I'm not sure how a heredoc would help, these values do not have linebreaks.

The idea is that implementers would have values to play with without having to run Mastodon itself.

@mjankowski
Copy link
Contributor

... but this wouldn't work because of the catch-all unmatched_route fallback we have in config/routes.rb

That rings a bell from the CSP one -- I recall having to work around that as well.

Do you have an example on how you'd do it? I'm not sure how a heredoc would help, these values do not have linebreaks.

You'd have to massage it a little bit ... something like this would work:

irb(main):001> original = 'Z8ilar3J7bOwqZkMp7sL8sRs4B1FT+UorbmvWoE+A5UeoOJ3KBcUmbsh+k3wQwbP5gMNUrra9rEWabpasZGphLsbDxfbsWL3Cf0PllAc7c1c7AFEwnewtExI83/qqgEkfWc2z7UDutXc2NfgAx89Ox8
DXU/fA2GG0jILjB6UpFyNugkY9rg6oI31UnvfVi3R7sr3/x8Ea3I9thPvqI2byF6cojknSpDAwYzeKdngX3TAQEGzFHz3SDWwyp3jeMWfwvVVbM38FxhvAnSumw7YwWW4L7M7h4M68isLimoT3yfCn2ucBVL5Dz8koBpYf/40w7QidClAw
CafZQFC29yDOg=='
=> "Z8ilar3J7bOwqZkMp7sL8sRs4B1FT+UorbmvWoE+A5UeoOJ3KBcUmbsh+k3wQwbP5gMNUrra9rEWabpasZGphLsbDxfbsWL3Cf0PllAc7c1c7AFEwnewtExI83/qqgEkfWc2z7UDutXc2NfgAx89Ox8DXU/fA2GG0jILjB6Up...
irb(main):002> 
irb(main):003" http_signature_value = <<-SIGNATURE.squish.tr(' ', '')
irb(main):004"   Z8ilar3J7bOwqZkMp7sL8sRs4B1FT+UorbmvWoE+A5UeoOJ3KBcUmbsh+k3wQwbP5gMNUrra9rEWabpa
irb(main):005"   sZGphLsbDxfbsWL3Cf0PllAc7c1c7AFEwnewtExI83/qqgEkfWc2z7UDutXc2NfgAx89Ox8DXU/fA2GG
irb(main):006"   0jILjB6UpFyNugkY9rg6oI31UnvfVi3R7sr3/x8Ea3I9thPvqI2byF6cojknSpDAwYzeKdngX3TAQEGz
irb(main):007"   FHz3SDWwyp3jeMWfwvVVbM38FxhvAnSumw7YwWW4L7M7h4M68isLimoT3yfCn2ucBVL5Dz8koBpYf/40
irb(main):008"   w7QidClAwCafZQFC29yDOg==
irb(main):009> SIGNATURE
=> "Z8ilar3J7bOwqZkMp7sL8sRs4B1FT+UorbmvWoE+A5UeoOJ3KBcUmbsh+k3wQwbP5gMNUrra9rEWabpasZGphLsbDxfbsWL3Cf0PllAc7c1c7AFEwnewtExI83/qqgEkfWc2z7UDutXc2NfgAx89Ox8DXU/fA2GG0jILjB6Up...
irb(main):010> 
irb(main):011> http_signature_value == original
=> true
irb(main):012> 

There may be more elegant way there, but that would work.

@ClearlyClaire
Copy link
Contributor Author

That rings a bell from the CSP one -- I recall having to work around that as well.

There's no such thing in the API CSP test, there's the reloading at teardown, though, which I do here too.

squish.tr(' ', '')

Right, I guess I can do that… this is a little awkward though, especially since it's embedded in a header value that are in a similar situation (too long, no newlines) but for which spaces matter.

@ClearlyClaire ClearlyClaire force-pushed the tests/signature-verification-tests branch from e8618d2 to a488d6a Compare December 20, 2023 15:38
@ClearlyClaire ClearlyClaire marked this pull request as ready for review December 20, 2023 15:39
@renchap renchap added testing Automated lint and test suites ruby Pull requests that update Ruby code labels Dec 20, 2023
@nightpool
Copy link
Member

I wouldn't worry too much about the long lines, but it might be nice to include a simple dev Ruby file or rake task or whatever that shows how you generated the spec values for future maintainability if the Signature headers need to change (e.g. if we change the requests or add a new request type we want to spec)

@ClearlyClaire
Copy link
Contributor Author

I added some methods and assertions on the specs to demonstrate how the signature strings are built. It's not exhaustive because that's not the point of the specs, but this should be enough to illustrate how this works and quickly build specs.

Copy link
Member

@renchap renchap left a comment

Choose a reason for hiding this comment

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

Looks good to me and I like having more explicit values everywhere.

If you get an approval from @mjankowski (as he is much knowledgable than myself on specs) then go for merge :)

Copy link
Contributor

@mjankowski mjankowski left a comment

Choose a reason for hiding this comment

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

Looks solid as move from controller->request spec.

If we get feedback from people on the educational uses, we can always revise style/naming on that front later.

@ClearlyClaire ClearlyClaire added this pull request to the merge queue Dec 22, 2023
Merged via the queue into main with commit a2624ff Dec 22, 2023
47 checks passed
@ClearlyClaire ClearlyClaire deleted the tests/signature-verification-tests branch December 22, 2023 19:01
smiba pushed a commit to smiba/mastodon that referenced this pull request Jan 3, 2024
vmstan pushed a commit to vmstan/mastodon that referenced this pull request Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ruby Pull requests that update Ruby code testing Automated lint and test suites
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants