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

Add UUID to StoreCredit#generate_authorization_code #4060

Conversation

spaghetticode
Copy link
Member

Fixes #4041

The value returned by StoreCredit#generate_authorization_code depends on time, which means that it may not be unique when a store credit is saved more than once at the same moment. This is not very likely to happen, but not impossible at all.

By introducing a UUID into the code we can be sure that this code will end up being unique. The previous format of the code is retained, since there may be applications relying on it.

Checklist:

  • I have followed Pull Request guidelines
  • I have added a detailed description into each commit message
  • I have updated Guides and README accordingly to this change (if needed)
  • I have added tests to cover this change (if needed)
  • I have attached screenshots to this PR for visual changes (if needed)

@spaghetticode spaghetticode self-assigned this May 13, 2021
@spaghetticode spaghetticode force-pushed the spaghetticode/store-credit-authorization_code branch 2 times, most recently from b6008c7 to 563da62 Compare May 13, 2021 09:18
@@ -150,7 +150,7 @@ def can_void?(payment)
end

def generate_authorization_code
"#{id}-SC-#{Time.current.utc.strftime('%Y%m%d%H%M%S%6N')}"
"#{id}-SC-#{Time.current.utc.strftime('%Y%m%d%H%M%S%6N')}-#{SecureRandom.uuid}"
Copy link
Member

Choose a reason for hiding this comment

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

This has enough segments in it now that it might be nicer to write it more like this, but either way is fine by me.

Suggested change
"#{id}-SC-#{Time.current.utc.strftime('%Y%m%d%H%M%S%6N')}-#{SecureRandom.uuid}"
[
id,
"SC",
Time.current.utc.strftime('%Y%m%d%H%M%S%6N'),
SecureRandom.uuid
].join("-")

@spaghetticode spaghetticode force-pushed the spaghetticode/store-credit-authorization_code branch from 563da62 to 341bcdc Compare May 14, 2021 09:11

describe "#generate_authorization_code" do
it "doesn't rely on time for uniqueness" do
expect(Time).to receive(:current).twice { Time.zone.parse("2019/09/05 06:30:00") }
Copy link
Member

Choose a reason for hiding this comment

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

Should we use the Rails helpers for stubbing time here, so the test is not so closely coupled with the implementation?

Copy link
Member Author

Choose a reason for hiding this comment

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

I actually wanted to explicitly couple it with the implementation, because the problem is with it. The moment we stop using the timestamp, this specific spec implementation may not make much sense anymore (I mean the line after this one), surely it won't make sense its text description.

Copy link
Member

Choose a reason for hiding this comment

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

What I meant is that there's a ton of different ways to get the current time in Ruby/Rails: Time.current, Time.now, Time.zone.now, DateTime.current, etc. In the test, we shouldn't worry about what method is being called exactly in the implementation.

A quick way to solve the problem would be to use the helpers Rails provides for stubbing time.

Does that make sense?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, sure! I think I knew about those helpers at a certain point in my life, but I forgot about them since then.

core/app/models/spree/store_credit.rb Show resolved Hide resolved
The value returned by `StoreCredit#generate_authorization_code`
depends on time, which means that it may not be unique when a
store credit is saved more than once at the same moment. This
is not very likely to happen, but not impossible at all.

By introducing a UUID into the code we can be sure that this
code will end up being unique. The previous format of the code
is retained, since there may be applications relying on it.
@spaghetticode spaghetticode force-pushed the spaghetticode/store-credit-authorization_code branch from 341bcdc to a4a3b57 Compare May 14, 2021 15:22
@kennyadsl kennyadsl merged commit a39affe into solidusio:master May 21, 2021
@kennyadsl kennyadsl deleted the spaghetticode/store-credit-authorization_code branch May 21, 2021 07:57
@kennyadsl kennyadsl added the changelog:solidus_core Changes to the solidus_core gem label May 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog:solidus_core Changes to the solidus_core gem
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Prevent store credits authorization_code duplicates with UUID
5 participants