fernet-rack 0.6 → 0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/fernet-rack.gemspec +3 -3
- data/lib/rack/fernet.rb +48 -10
- data/test/test_fernet.rb +38 -18
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6aa8111be46b666e1b3103cde898fa7af875ddb9
|
|
4
|
+
data.tar.gz: be4873a4df9f0c809c0a9be556c18e5e72ef7261
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 568a2b5c57eb398519c690fb4113ad84908e984d020341a3243557ecba3b7af3006ae3812a554ca84fd6db6aac0d64c9386b36806fabf22dcfbc0564ff8093e5
|
|
7
|
+
data.tar.gz: febb00068b464b7000c6d7f23cb13bd16dd164cce50328ef4e891f4adb6aa6dc4a781216ae19d866471fa850f9effbf4230da746651b760a107a5f36315d37be
|
data/fernet-rack.gemspec
CHANGED
|
@@ -13,8 +13,8 @@ Gem::Specification.new do |gem|
|
|
|
13
13
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
14
14
|
gem.name = "fernet-rack"
|
|
15
15
|
gem.require_paths = ["lib"]
|
|
16
|
-
gem.version = '0.
|
|
16
|
+
gem.version = '0.7'
|
|
17
17
|
|
|
18
|
-
gem.add_runtime_dependency "fernet", '~> 2.
|
|
18
|
+
gem.add_runtime_dependency "fernet", '~> 2.1'
|
|
19
19
|
gem.add_development_dependency "minitest", '~> 5.4'
|
|
20
|
-
end
|
|
20
|
+
end
|
data/lib/rack/fernet.rb
CHANGED
|
@@ -4,6 +4,8 @@ require 'rack'
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
module Rack
|
|
7
|
+
class FernetError < StandardError; end
|
|
8
|
+
|
|
7
9
|
module Auth
|
|
8
10
|
class Fernet < Rack::Auth::Basic
|
|
9
11
|
def initialize(app, secret, realm=nil)
|
|
@@ -28,25 +30,61 @@ module Rack
|
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
def call(env)
|
|
31
|
-
|
|
33
|
+
payload = env["rack.input"].read
|
|
34
|
+
|
|
35
|
+
unless payload.empty?
|
|
36
|
+
payload = decrypt_request(env, payload)
|
|
37
|
+
env["CONTENT_TYPE"] = @content_type
|
|
38
|
+
env["rack.input"] = StringIO.new(payload)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
status, headers, body = @app.call(env)
|
|
42
|
+
str_body = read_body(body)
|
|
43
|
+
unless str_body.empty?
|
|
44
|
+
encoded = encrypt_response(env, str_body)
|
|
45
|
+
headers['Content-Type'] = 'application/octet-stream'
|
|
46
|
+
headers['Content-Length'] = encoded.length
|
|
47
|
+
body = [ encoded ]
|
|
48
|
+
end
|
|
49
|
+
[status, headers, body]
|
|
50
|
+
rescue ::Fernet::Error
|
|
51
|
+
bad_request
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def read_body(body)
|
|
57
|
+
if body.respond_to? :join
|
|
58
|
+
body.join('')
|
|
59
|
+
else
|
|
60
|
+
result = []
|
|
61
|
+
body.each { |line| result << line }
|
|
62
|
+
result.join('')
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def secret(env)
|
|
67
|
+
if @secret.respond_to?(:call)
|
|
32
68
|
@secret.call(env)
|
|
33
69
|
else
|
|
34
70
|
@secret
|
|
35
71
|
end
|
|
36
|
-
|
|
37
|
-
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def encrypt_response(env, payload)
|
|
75
|
+
::Fernet.generate(secret(env), payload)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def decrypt_request(env, payload)
|
|
79
|
+
# read the payload
|
|
80
|
+
verifier = ::Fernet.verifier(secret(env), payload)
|
|
38
81
|
if verifier.valid?
|
|
39
|
-
|
|
40
|
-
env["rack.input"] = StringIO.new(verifier.message)
|
|
41
|
-
@app.call(env)
|
|
42
|
-
elsif payload.size.zero?
|
|
43
|
-
@app.call(env)
|
|
82
|
+
verifier.message
|
|
44
83
|
else
|
|
45
|
-
|
|
84
|
+
raise ::Fernet::Error
|
|
46
85
|
end
|
|
47
86
|
end
|
|
48
87
|
|
|
49
|
-
private
|
|
50
88
|
def bad_request
|
|
51
89
|
return [ 400,
|
|
52
90
|
{ 'Content-Type' => 'text/plain',
|
data/test/test_fernet.rb
CHANGED
|
@@ -5,9 +5,6 @@ require 'rack/mock'
|
|
|
5
5
|
|
|
6
6
|
class FernetTest < Minitest::Test
|
|
7
7
|
def setup
|
|
8
|
-
unprotected_app = Rack::Lint.new(lambda do |env|
|
|
9
|
-
[ 200, {'Content-Type' => env["CONTENT_TYPE"].to_s }, [env["rack.input"].read] ]
|
|
10
|
-
end)
|
|
11
8
|
@secret = "SqD5Mz/qFnXPLVTvkQKRDyVpli3Q6/habc7i89IrBRA="
|
|
12
9
|
@app = Rack::Fernet.new(unprotected_app, @secret)
|
|
13
10
|
@request = Rack::MockRequest.new(@app)
|
|
@@ -15,46 +12,69 @@ class FernetTest < Minitest::Test
|
|
|
15
12
|
|
|
16
13
|
def test_invalid_signature
|
|
17
14
|
request("garbage") do |response|
|
|
18
|
-
assert_equal(response.status
|
|
15
|
+
assert_equal(400, response.status)
|
|
19
16
|
end
|
|
20
17
|
end
|
|
21
18
|
|
|
22
19
|
def test_valid_signature
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
assert_equal(response.
|
|
26
|
-
assert_equal(response.
|
|
20
|
+
data = '{"hello"=>"world"}'
|
|
21
|
+
request(encrypt(data)) do |response|
|
|
22
|
+
assert_equal(200, response.status)
|
|
23
|
+
assert_equal(data, decrypt(response.body))
|
|
24
|
+
assert_equal('application/octet-stream', response.headers['Content-Type'])
|
|
27
25
|
end
|
|
28
26
|
end
|
|
29
27
|
|
|
30
28
|
def test_empty_payload
|
|
31
29
|
request do |response|
|
|
32
|
-
assert_equal(response.status
|
|
30
|
+
assert_equal(200, response.status)
|
|
33
31
|
end
|
|
34
32
|
end
|
|
35
33
|
|
|
36
34
|
protected
|
|
37
|
-
def
|
|
38
|
-
|
|
35
|
+
def unprotected_app
|
|
36
|
+
Rack::Lint.new(lambda do |env|
|
|
37
|
+
request_body = env["rack.input"].read
|
|
38
|
+
content_type = env["CONTENT_TYPE"].to_s
|
|
39
|
+
unless request_body.empty?
|
|
40
|
+
assert_equal('application/json', content_type)
|
|
41
|
+
end
|
|
42
|
+
[ 200, {'Content-Type' => content_type }, [request_body] ]
|
|
43
|
+
end)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def request(body='', headers={})
|
|
47
|
+
yield @request.get('/', :input => body, 'CONTENT_TYPE' => 'application/octet-stream')
|
|
39
48
|
end
|
|
40
49
|
|
|
41
|
-
def data
|
|
42
|
-
Fernet.generate(@secret,
|
|
50
|
+
def encrypt(data)
|
|
51
|
+
Fernet.generate(@secret, data)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def decrypt(data)
|
|
55
|
+
verifier = Fernet.verifier(@secret, data)
|
|
56
|
+
if verifier.valid?
|
|
57
|
+
verifier.message
|
|
58
|
+
end
|
|
43
59
|
end
|
|
44
60
|
end
|
|
45
61
|
|
|
46
62
|
class DynamicFernetTest < FernetTest
|
|
47
63
|
def setup
|
|
48
|
-
unprotected_app = Rack::Lint.new(lambda do |env|
|
|
49
|
-
[ 200, {'Content-Type' => env["CONTENT_TYPE"].to_s }, [env["rack.input"].read] ]
|
|
50
|
-
end)
|
|
51
64
|
@secret = ->(env) { "SqD5Mz/qFnXPLVTvkQKRDyVpli3Q6/habc7i89IrBRA=" }
|
|
52
65
|
@app = Rack::Fernet.new(unprotected_app, @secret)
|
|
53
66
|
@request = Rack::MockRequest.new(@app)
|
|
54
67
|
end
|
|
55
68
|
|
|
56
69
|
protected
|
|
57
|
-
def data
|
|
58
|
-
Fernet.generate(@secret.call(nil),
|
|
70
|
+
def encrypt(data)
|
|
71
|
+
Fernet.generate(@secret.call(nil), data)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def decrypt(data)
|
|
75
|
+
verifier = Fernet.verifier(@secret.call(nil), data)
|
|
76
|
+
if verifier.valid?
|
|
77
|
+
verifier.message
|
|
78
|
+
end
|
|
59
79
|
end
|
|
60
80
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fernet-rack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '0.
|
|
4
|
+
version: '0.7'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Timothée Peignier
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-08-
|
|
11
|
+
date: 2014-08-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: fernet
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '2.
|
|
19
|
+
version: '2.1'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '2.
|
|
26
|
+
version: '2.1'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: minitest
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|