http_signatures 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/lib/http_signatures/context.rb +14 -3
- data/lib/http_signatures/key_store.rb +8 -0
- data/lib/http_signatures/version.rb +1 -1
- data/spec/context_spec.rb +45 -17
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f089f43abace9a9b86c3d19ba394ca4029260c2
|
4
|
+
data.tar.gz: d3f055bf4eb80034756d585770be2bffd778b798
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d8a718a78fed672fb5c61b1a43f9d01fc983abf08f5fa97f7156f1d14ceaba5bcd95413f2b47dec8bc154880a7cfa4530b68ffa52cb63a48866a67309249065
|
7
|
+
data.tar.gz: 00be41245a855a9441a0414c1a2c10c5523df24b879f32c3b9c55d2327bb9dfe56b7382304a8e36818e870e0e4479e78830446bcef84daf2b79a410d69639671
|
data/README.md
CHANGED
@@ -15,10 +15,13 @@ require "http_signatures"
|
|
15
15
|
$context = HttpSignatures::Context.new(
|
16
16
|
keys: {"examplekey" => "secret-key-here"},
|
17
17
|
algorithm: "hmac-sha256",
|
18
|
-
headers:
|
18
|
+
headers: ["(request-target)", "Date", "Content-Length"],
|
19
19
|
)
|
20
20
|
```
|
21
21
|
|
22
|
+
If there's only one key in the `keys` hash, that will be used for signing.
|
23
|
+
Otherwise, specify one via `signing_key_id: "examplekey"`.
|
24
|
+
|
22
25
|
### Messages
|
23
26
|
|
24
27
|
A message is an HTTP request or response. A subset of the interface of
|
@@ -29,6 +32,7 @@ of `message#method` and `message#path` for `(request-target)` support.
|
|
29
32
|
```rb
|
30
33
|
require "net/http"
|
31
34
|
require "time"
|
35
|
+
|
32
36
|
message = Net::HTTP::Get.new(
|
33
37
|
"/path?query=123",
|
34
38
|
"Date" => Time.now.rfc822,
|
@@ -39,7 +43,7 @@ message = Net::HTTP::Get.new(
|
|
39
43
|
### Signing a message
|
40
44
|
|
41
45
|
```rb
|
42
|
-
$context.signer
|
46
|
+
$context.signer.sign(message)
|
43
47
|
```
|
44
48
|
|
45
49
|
Now `message` contains the signature headers:
|
@@ -1,19 +1,30 @@
|
|
1
1
|
module HttpSignatures
|
2
2
|
class Context
|
3
3
|
|
4
|
-
def initialize(keys: {}, algorithm: nil, headers: nil)
|
4
|
+
def initialize(keys: {}, signing_key_id: nil, algorithm: nil, headers: nil)
|
5
5
|
@key_store = KeyStore.new(keys)
|
6
|
+
@signing_key_id = signing_key_id
|
6
7
|
@algorithm_name = algorithm
|
7
8
|
@headers = headers
|
8
9
|
end
|
9
10
|
|
10
|
-
def signer
|
11
|
+
def signer
|
11
12
|
Signer.new(
|
12
|
-
key:
|
13
|
+
key: signing_key,
|
13
14
|
algorithm: Algorithm.create(@algorithm_name),
|
14
15
|
header_list: HeaderList.new(@headers),
|
15
16
|
)
|
16
17
|
end
|
17
18
|
|
19
|
+
private
|
20
|
+
|
21
|
+
def signing_key
|
22
|
+
if @signing_key_id
|
23
|
+
@key_store.fetch(@signing_key_id)
|
24
|
+
else
|
25
|
+
@key_store.only_key
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
18
29
|
end
|
19
30
|
end
|
data/spec/context_spec.rb
CHANGED
@@ -2,28 +2,56 @@ require "net/http"
|
|
2
2
|
|
3
3
|
RSpec.describe HttpSignatures::Context do
|
4
4
|
|
5
|
-
subject(:context) do
|
6
|
-
HttpSignatures::Context.new(
|
7
|
-
keys: {"hello" => "world"},
|
8
|
-
algorithm: "null",
|
9
|
-
headers: %w{(request-target) date content-length},
|
10
|
-
)
|
11
|
-
end
|
12
|
-
|
13
5
|
let(:message) { Net::HTTP::Get.new("/", "date" => "x", "content-length" => "0") }
|
14
6
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
7
|
+
context "with one key in KeyStore, no signing_key_id specified" do
|
8
|
+
subject(:context) do
|
9
|
+
HttpSignatures::Context.new(
|
10
|
+
keys: {"hello" => "world"},
|
11
|
+
algorithm: "null",
|
12
|
+
headers: %w{(request-target) date content-length},
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#signer" do
|
17
|
+
it "instantiates Signer with key, algorithm, headers" do
|
18
|
+
expect(HttpSignatures::Signer).to receive(:new) do |args|
|
19
|
+
expect(args[:key]).to eq(HttpSignatures::Key.new(id: "hello", secret: "world"))
|
20
|
+
expect(args[:algorithm].name).to eq("null")
|
21
|
+
expect(args[:header_list].to_a).to eq(%w{(request-target) date content-length})
|
22
|
+
end
|
23
|
+
context.signer
|
24
|
+
end
|
25
|
+
|
26
|
+
it "signs without errors" do
|
27
|
+
context.signer.sign(message)
|
21
28
|
end
|
22
|
-
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "with two keys in KeyStore, signing_key_id specified" do
|
33
|
+
subject(:context) do
|
34
|
+
HttpSignatures::Context.new(
|
35
|
+
keys: {"hello" => "world", "another" => "key"},
|
36
|
+
signing_key_id: "another",
|
37
|
+
algorithm: "null",
|
38
|
+
headers: %w{(request-target) date content-length},
|
39
|
+
)
|
23
40
|
end
|
24
41
|
|
25
|
-
|
26
|
-
|
42
|
+
describe "#signer" do
|
43
|
+
it "instantiates Signer with key, algorithm, headers" do
|
44
|
+
expect(HttpSignatures::Signer).to receive(:new) do |args|
|
45
|
+
expect(args[:key]).to eq(HttpSignatures::Key.new(id: "another", secret: "key"))
|
46
|
+
expect(args[:algorithm].name).to eq("null")
|
47
|
+
expect(args[:header_list].to_a).to eq(%w{(request-target) date content-length})
|
48
|
+
end
|
49
|
+
context.signer
|
50
|
+
end
|
51
|
+
|
52
|
+
it "signs without errors" do
|
53
|
+
context.signer.sign(message)
|
54
|
+
end
|
27
55
|
end
|
28
56
|
end
|
29
57
|
|