Skip to content

Commit 364939c

Browse files
shouichibyroot
authored andcommitted
Add expires_at option to signed_id
Problem: Though, the `MessageVerifier` that powers `signed_id` supports both `expires_in` and `expires_at`, `signed_id` only supports `expires_in`. Because of this, generating signed_id that expires at a certain time is somewhat tedious. Imagine issuing a coupon that is valid only for a day. Solution: Add `expires_at` option to `signed_id` to generate signed ids that expire at the given time.
1 parent 93b2a2c commit 364939c

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

activerecord/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Add `expires_in` option to `signed_id`.
2+
3+
*Shouichi Kamiya*
4+
15
* Allow applications to set retry deadline for query retries.
26

37
Building on the work done in #44576 and #44591, we extend the logic that automatically

activerecord/lib/active_record/signed_id.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ def combine_signed_id_purposes(purpose)
109109
#
110110
# And you then change your +find_signed+ calls to require this new purpose. Any old signed ids that were not
111111
# created with the purpose will no longer find the record.
112-
def signed_id(expires_in: nil, purpose: nil)
113-
self.class.signed_id_verifier.generate id, expires_in: expires_in, purpose: self.class.combine_signed_id_purposes(purpose)
112+
def signed_id(expires_in: nil, expires_at: nil, purpose: nil)
113+
self.class.signed_id_verifier.generate id, expires_in: expires_in, expires_at: expires_at, purpose: self.class.combine_signed_id_purposes(purpose)
114114
end
115115
end
116116
end

activerecord/test/cases/signed_id_test.rb

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ class SignedIdTest < ActiveRecord::TestCase
6767
assert_nil Account.find_signed("this won't find anything")
6868
end
6969

70-
test "find signed record within expiration date" do
70+
test "find signed record within expiration duration" do
7171
assert_equal @account, Account.find_signed(@account.signed_id(expires_in: 1.minute))
7272
end
7373

74-
test "fail to find signed record within expiration date" do
74+
test "fail to find signed record within expiration duration" do
7575
signed_id = @account.signed_id(expires_in: 1.minute)
7676
travel 2.minutes
7777
assert_nil Account.find_signed(signed_id)
@@ -83,6 +83,16 @@ class SignedIdTest < ActiveRecord::TestCase
8383
assert_nil Account.find_signed signed_id
8484
end
8585

86+
test "find signed record within expiration time" do
87+
assert_equal @account, Account.find_signed(@account.signed_id(expires_at: 1.minute.from_now))
88+
end
89+
90+
test "fail to find signed record within expiration time" do
91+
signed_id = @account.signed_id(expires_at: 1.minute.from_now)
92+
travel 2.minutes
93+
assert_nil Account.find_signed(signed_id)
94+
end
95+
8696
test "find signed record with purpose" do
8797
assert_equal @account, Account.find_signed(@account.signed_id(purpose: :v1), purpose: :v1)
8898
end
@@ -99,11 +109,11 @@ class SignedIdTest < ActiveRecord::TestCase
99109
end
100110
end
101111

102-
test "find signed record with a bang within expiration date" do
112+
test "find signed record with a bang within expiration duration" do
103113
assert_equal @account, Account.find_signed!(@account.signed_id(expires_in: 1.minute))
104114
end
105115

106-
test "finding signed record outside expiration date raises on the bang" do
116+
test "finding signed record outside expiration duration raises on the bang" do
107117
signed_id = @account.signed_id(expires_in: 1.minute)
108118
travel 2.minutes
109119

0 commit comments

Comments
 (0)