Skip to content

Commit 2c27032

Browse files
CopilotGrantBirki
andcommitted
Complete HMAC test coverage by implementing missing test cases
Co-authored-by: GrantBirki <[email protected]>
1 parent 8b023b4 commit 2c27032

File tree

3 files changed

+355
-8
lines changed

3 files changed

+355
-8
lines changed

for grouping

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
diff --git a/spec/unit/lib/hooks/plugins/auth/hmac_spec.rb b/spec/unit/lib/hooks/plugins/auth/hmac_spec.rb
2+
index 9e8b01c..fa12174 100644
3+
--- a/spec/unit/lib/hooks/plugins/auth/hmac_spec.rb
4+
+++ b/spec/unit/lib/hooks/plugins/auth/hmac_spec.rb
5+
@@ -70,7 +70,8 @@ describe Hooks::Plugins::Auth::HMAC do
6+
auth: {
7+
header: header,
8+
algorithm: "sha256",
9+
- format: "signature_only"
10+
+ format: "signature_only",
11+
+ secret_env_key: "HMAC_TEST_SECRET"
12+
}
13+
}
14+
end
15+
@@ -78,7 +79,7 @@ describe Hooks::Plugins::Auth::HMAC do
16+
let(:headers) { { header => signature } }
17+

18+
it "returns true for a valid hash-only signature" do
19+
- # TODO
20+
+ expect(valid_with(headers:, config:)).to be true
21+
end
22+

23+
it "returns false for an invalid hash-only signature" do
24+
@@ -104,13 +105,14 @@ describe Hooks::Plugins::Auth::HMAC do
25+
format: "version=signature",
26+
version_prefix: "v0",
27+
payload_template: payload_template,
28+
- timestamp_tolerance: 300
29+
+ timestamp_tolerance: 300,
30+
+ secret_env_key: "HMAC_TEST_SECRET"
31+
}
32+
}
33+
end
34+

35+
it "returns true for a valid versioned signature with valid timestamp" do
36+
- # TODO
37+
+ expect(valid_with(headers:, config:)).to be true
38+
end
39+

40+
it "returns false for an expired timestamp" do
41+
@@ -153,10 +155,10 @@ describe Hooks::Plugins::Auth::HMAC do
42+

43+
context "with missing config values" do
44+
let(:headers) { { "X-Signature" => "sha256=" + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, payload) } }
45+
- let(:config) { {} }
46+
+ let(:config) { { auth: { secret_env_key: "HMAC_TEST_SECRET" } } }
47+

48+
it "uses defaults and validates correctly" do
49+
- # TODO
50+
+ expect(valid_with(headers:, config:)).to be true
51+
end
52+
end
53+

54+
@@ -404,7 +406,8 @@ describe Hooks::Plugins::Auth::HMAC do
55+
format: "version=signature",
56+
version_prefix: "v0",
57+
payload_template: "v0:{timestamp}:{body}",
58+
- timestamp_tolerance: 300
59+
+ timestamp_tolerance: 300,
60+
+ secret_env_key: "HMAC_TEST_SECRET"
61+
}
62+
}
63+
end
64+
@@ -464,7 +467,14 @@ describe Hooks::Plugins::Auth::HMAC do
65+
end
66+

67+
it "returns true when timestamp header name case differs due to normalization" do
68+
- # TODO
69+
+ timestamp = Time.now.to_i.to_s
70+
+ signing_payload = "v0:#{timestamp}:#{payload}"
71+
+ signature = "v0=" + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, signing_payload)
72+
+
73+
+ # Use uppercase timestamp header name in the request headers
74+
+ headers = { header => signature, timestamp_header.upcase => timestamp }
75+
+
76+
+ expect(valid_with(headers:, config: base_config)).to be true
77+
end
78+
end
79+


spec/unit/lib/hooks/plugins/auth/hmac_spec.rb

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,16 @@ def valid_with(args = {})
7070
auth: {
7171
header: header,
7272
algorithm: "sha256",
73-
format: "signature_only"
73+
format: "signature_only",
74+
secret_env_key: "HMAC_TEST_SECRET"
7475
}
7576
}
7677
end
7778
let(:signature) { OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, payload) }
7879
let(:headers) { { header => signature } }
7980

8081
it "returns true for a valid hash-only signature" do
81-
# TODO
82+
expect(valid_with(headers:, config:)).to be true
8283
end
8384

8485
it "returns false for an invalid hash-only signature" do
@@ -104,13 +105,14 @@ def valid_with(args = {})
104105
format: "version=signature",
105106
version_prefix: "v0",
106107
payload_template: payload_template,
107-
timestamp_tolerance: 300
108+
timestamp_tolerance: 300,
109+
secret_env_key: "HMAC_TEST_SECRET"
108110
}
109111
}
110112
end
111113

112114
it "returns true for a valid versioned signature with valid timestamp" do
113-
# TODO
115+
expect(valid_with(headers:, config:)).to be true
114116
end
115117

116118
it "returns false for an expired timestamp" do
@@ -153,10 +155,10 @@ def valid_with(args = {})
153155

154156
context "with missing config values" do
155157
let(:headers) { { "X-Signature" => "sha256=" + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, payload) } }
156-
let(:config) { {} }
158+
let(:config) { { auth: { secret_env_key: "HMAC_TEST_SECRET" } } }
157159

158160
it "uses defaults and validates correctly" do
159-
# TODO
161+
expect(valid_with(headers:, config:)).to be true
160162
end
161163
end
162164

@@ -404,7 +406,8 @@ def valid_with(args = {})
404406
format: "version=signature",
405407
version_prefix: "v0",
406408
payload_template: "v0:{timestamp}:{body}",
407-
timestamp_tolerance: 300
409+
timestamp_tolerance: 300,
410+
secret_env_key: "HMAC_TEST_SECRET"
408411
}
409412
}
410413
end
@@ -464,7 +467,14 @@ def valid_with(args = {})
464467
end
465468

466469
it "returns true when timestamp header name case differs due to normalization" do
467-
# TODO
470+
timestamp = Time.now.to_i.to_s
471+
signing_payload = "v0:#{timestamp}:#{payload}"
472+
signature = "v0=" + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, signing_payload)
473+
474+
# Use uppercase timestamp header name in the request headers
475+
headers = { header => signature, timestamp_header.upcase => timestamp }
476+
477+
expect(valid_with(headers:, config: base_config)).to be true
468478
end
469479
end
470480

0 commit comments

Comments
 (0)