legacy-fernet 1.6.1 → 1.6.2
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.
- data/Gemfile.lock +1 -1
- data/README.md +1 -108
- data/fernet.gemspec +2 -2
- data/lib/fernet.rb +2 -2
- data/lib/fernet/configuration.rb +1 -1
- data/lib/fernet/generator.rb +2 -2
- data/lib/fernet/secret.rb +1 -1
- data/lib/fernet/verifier.rb +2 -2
- data/lib/fernet/version.rb +3 -3
- data/spec/fernet_spec.rb +28 -28
- metadata +5 -5
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,108 +1 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
[](http://travis-ci.org/hgmnz/fernet)
|
4
|
-
[](https://codeclimate.com/github/hgmnz/fernet)
|
5
|
-
|
6
|
-
Fernet allows you to easily generate and verify **HMAC based authentication
|
7
|
-
tokens** for issuing API requests between remote servers. It also **encrypts**
|
8
|
-
data by default, so it can be used to transmit secure messages over the wire.
|
9
|
-
|
10
|
-

|
11
|
-
|
12
|
-
Fernet is usually served as a *digestif* after a meal but may also be served
|
13
|
-
with coffee and espresso or mixed into coffee and espresso drinks.
|
14
|
-
|
15
|
-
Fernet about it!
|
16
|
-
|
17
|
-
## Installation
|
18
|
-
|
19
|
-
Add this line to your application's Gemfile:
|
20
|
-
|
21
|
-
gem 'fernet'
|
22
|
-
|
23
|
-
And then execute:
|
24
|
-
|
25
|
-
$ bundle
|
26
|
-
|
27
|
-
Or install it yourself as:
|
28
|
-
|
29
|
-
$ gem install fernet
|
30
|
-
|
31
|
-
## Usage
|
32
|
-
|
33
|
-
Both server and client must share a secret.
|
34
|
-
|
35
|
-
You want to encode some data in the token as well, for example, an email
|
36
|
-
address can be used to verify it on the other end.
|
37
|
-
|
38
|
-
```ruby
|
39
|
-
token = Fernet.generate(secret) do |generator|
|
40
|
-
generator.data = { email: 'harold@heroku.com' }
|
41
|
-
end
|
42
|
-
```
|
43
|
-
On the server side, the receiver can use this token to verify whether it's
|
44
|
-
legit:
|
45
|
-
|
46
|
-
```ruby
|
47
|
-
verified = Fernet.verify(secret, token) do |verifier|
|
48
|
-
verifier.data['email'] == 'harold@heroku.com'
|
49
|
-
end
|
50
|
-
```
|
51
|
-
|
52
|
-
The `verified` variable will be true if:
|
53
|
-
|
54
|
-
* The email encoded in the token data is `harold@heroku.com`
|
55
|
-
* The token was generated in the last 60 seconds
|
56
|
-
* The secret used to generate the token matches
|
57
|
-
|
58
|
-
Otherwise, `verified` will be false, and you should deny the request with an
|
59
|
-
HTTP 401, for example.
|
60
|
-
|
61
|
-
The `Fernet.verify` method can be awkward if extracting the plain text data is
|
62
|
-
required. For this case, a `verifier` can be requested that makes that
|
63
|
-
use case more pleasent:
|
64
|
-
|
65
|
-
```ruby
|
66
|
-
verifier = Fernet.verifier(secret, token)
|
67
|
-
if verifier.valid? # signature valid, TTL verified
|
68
|
-
operate_on(verifier.data) # the original, decrypted data
|
69
|
-
end
|
70
|
-
```
|
71
|
-
|
72
|
-
The specs
|
73
|
-
([spec/fernet_spec.rb](https://github.com/hgmnz/fernet/blob/master/spec/fernet_spec.rb))
|
74
|
-
have more usage examples.
|
75
|
-
|
76
|
-
### Global configuration
|
77
|
-
|
78
|
-
It's possible to configure fernet via the `Configuration` class. Put this in an initializer:
|
79
|
-
|
80
|
-
```ruby
|
81
|
-
# default values shown here
|
82
|
-
Fernet::Configuration.run do |config|
|
83
|
-
config.enforce_ttl = true
|
84
|
-
config.ttl = 60
|
85
|
-
config.encrypt = true
|
86
|
-
end
|
87
|
-
```
|
88
|
-
|
89
|
-
### Generating a secret
|
90
|
-
|
91
|
-
Generating appropriate secrets is beyond the scope of `Fernet`, but you should
|
92
|
-
generate it using `/dev/random` in a *nix. To generate a base64-encoded 256 bit
|
93
|
-
(32 byte) random sequence, try:
|
94
|
-
|
95
|
-
dd if=/dev/urandom bs=32 count=1 2>/dev/null | openssl base64
|
96
|
-
|
97
|
-
### Attribution
|
98
|
-
|
99
|
-
This library was largely made possible by [Mr. Tom
|
100
|
-
Maher](http://twitter.com/#tmaher), who clearly articulated the mechanics
|
101
|
-
behind this process, and further found ways to make it
|
102
|
-
[more](https://github.com/hgmnz/fernet/commit/2bf0b4a66b49ef3fc92ef50708a2c8b401950fc2)
|
103
|
-
[secure](https://github.com/hgmnz/fernet/commit/051161d0afb0b41480734d84bc824bdbc7f9c563).
|
104
|
-
|
105
|
-
## License
|
106
|
-
|
107
|
-
Fernet is copyright (c) Harold Giménez and is released under the terms of the
|
108
|
-
MIT License found in the LICENSE file.
|
1
|
+
Please see https://github.com/hgmnz/fernet instead
|
data/fernet.gemspec
CHANGED
@@ -13,10 +13,10 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
14
|
gem.name = "legacy-fernet"
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.version = Legacy::
|
16
|
+
gem.version = Fernet::Legacy::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency "oj"
|
19
18
|
gem.add_dependency "multi_json"
|
20
19
|
|
21
20
|
gem.add_development_dependency "rspec"
|
21
|
+
gem.add_development_dependency "oj"
|
22
22
|
end
|
data/lib/fernet.rb
CHANGED
@@ -8,9 +8,9 @@ if RUBY_VERSION == '1.8.7'
|
|
8
8
|
require 'shim/base64'
|
9
9
|
end
|
10
10
|
|
11
|
-
Legacy::
|
11
|
+
Fernet::Legacy::Configuration.run
|
12
12
|
|
13
|
-
module Legacy
|
13
|
+
module Fernet::Legacy
|
14
14
|
def self.generate(secret, encrypt = Configuration.encrypt, &block)
|
15
15
|
Generator.new(secret, encrypt).generate(&block)
|
16
16
|
end
|
data/lib/fernet/configuration.rb
CHANGED
data/lib/fernet/generator.rb
CHANGED
@@ -3,7 +3,7 @@ require 'multi_json'
|
|
3
3
|
require 'openssl'
|
4
4
|
require 'date'
|
5
5
|
|
6
|
-
module Legacy
|
6
|
+
module Fernet::Legacy
|
7
7
|
class Generator
|
8
8
|
attr_accessor :data, :payload
|
9
9
|
|
@@ -30,7 +30,7 @@ module Legacy::Fernet
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def inspect
|
33
|
-
"#<Legacy::
|
33
|
+
"#<Fernet::Legacy::Generator @secret=[masked] @data=#{@data.inspect}>"
|
34
34
|
end
|
35
35
|
alias to_s inspect
|
36
36
|
|
data/lib/fernet/secret.rb
CHANGED
data/lib/fernet/verifier.rb
CHANGED
@@ -3,7 +3,7 @@ require 'multi_json'
|
|
3
3
|
require 'openssl'
|
4
4
|
require 'date'
|
5
5
|
|
6
|
-
module Legacy
|
6
|
+
module Fernet::Legacy
|
7
7
|
class Verifier
|
8
8
|
attr_reader :token, :data
|
9
9
|
attr_accessor :ttl, :enforce_ttl
|
@@ -33,7 +33,7 @@ module Legacy::Fernet
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def inspect
|
36
|
-
"#<Legacy::
|
36
|
+
"#<Fernet::Legacy::Verifier @secret=[masked] @token=#{@token} @data=#{@data.inspect} @ttl=#{@ttl}>"
|
37
37
|
end
|
38
38
|
alias to_s inspect
|
39
39
|
|
data/lib/fernet/version.rb
CHANGED
data/spec/fernet_spec.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'fernet'
|
3
3
|
|
4
|
-
describe Legacy
|
5
|
-
after { Legacy::
|
4
|
+
describe Fernet::Legacy do
|
5
|
+
after { Fernet::Legacy::Configuration.run }
|
6
6
|
|
7
7
|
let(:token_data) do
|
8
8
|
{ :email => 'harold@heroku.com', :id => '123', :arbitrary => 'data' }
|
@@ -12,48 +12,48 @@ describe Legacy::Fernet do
|
|
12
12
|
let(:bad_secret) { 'badICDH6x3M7duQeM8dJEMK4Y5TkBIsYDw1lPy35RiY=' }
|
13
13
|
|
14
14
|
it 'can verify tokens it generates' do
|
15
|
-
token = Legacy
|
15
|
+
token = Fernet::Legacy.generate(secret) do |generator|
|
16
16
|
generator.data = token_data
|
17
17
|
end
|
18
18
|
|
19
19
|
expect(
|
20
|
-
Legacy
|
20
|
+
Fernet::Legacy.verify(secret, token) do |verifier|
|
21
21
|
verifier.data['email'] == 'harold@heroku.com'
|
22
22
|
end
|
23
23
|
).to be_true
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'fails with a bad secret' do
|
27
|
-
token = Legacy
|
27
|
+
token = Fernet::Legacy.generate(secret) do |generator|
|
28
28
|
generator.data = token_data
|
29
29
|
end
|
30
30
|
|
31
31
|
expect(
|
32
|
-
Legacy
|
32
|
+
Fernet::Legacy.verify(bad_secret, token) do |verifier|
|
33
33
|
verifier.data['email'] == 'harold@heroku.com'
|
34
34
|
end
|
35
35
|
).to be_false
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'fails with a bad custom verification' do
|
39
|
-
token = Legacy
|
39
|
+
token = Fernet::Legacy.generate(secret) do |generator|
|
40
40
|
generator.data = { :email => 'harold@heroku.com' }
|
41
41
|
end
|
42
42
|
|
43
43
|
expect(
|
44
|
-
Legacy
|
44
|
+
Fernet::Legacy.verify(secret, token) do |verifier|
|
45
45
|
verifier.data['email'] == 'lol@heroku.com'
|
46
46
|
end
|
47
47
|
).to be_false
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'fails if the token is too old' do
|
51
|
-
token = Legacy
|
51
|
+
token = Fernet::Legacy.generate(secret) do |generator|
|
52
52
|
generator.data = token_data
|
53
53
|
end
|
54
54
|
|
55
55
|
expect(
|
56
|
-
Legacy
|
56
|
+
Fernet::Legacy.verify(secret, token) do |verifier|
|
57
57
|
verifier.ttl = 1
|
58
58
|
|
59
59
|
def verifier.now
|
@@ -67,20 +67,20 @@ describe Legacy::Fernet do
|
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'verifies without a custom verification' do
|
70
|
-
token = Legacy
|
70
|
+
token = Fernet::Legacy.generate(secret) do |generator|
|
71
71
|
generator.data = token_data
|
72
72
|
end
|
73
73
|
|
74
|
-
expect(Legacy
|
74
|
+
expect(Fernet::Legacy.verify(secret, token)).to be_true
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'can ignore TTL enforcement' do
|
78
|
-
token = Legacy
|
78
|
+
token = Fernet::Legacy.generate(secret) do |generator|
|
79
79
|
generator.data = token_data
|
80
80
|
end
|
81
81
|
|
82
82
|
expect(
|
83
|
-
Legacy
|
83
|
+
Fernet::Legacy.verify(secret, token) do |verifier|
|
84
84
|
def verifier.now
|
85
85
|
Time.now + 99999999999
|
86
86
|
end
|
@@ -91,16 +91,16 @@ describe Legacy::Fernet do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
it 'can ignore TTL enforcement via global config' do
|
94
|
-
Legacy::
|
94
|
+
Fernet::Legacy::Configuration.run do |config|
|
95
95
|
config.enforce_ttl = false
|
96
96
|
end
|
97
97
|
|
98
|
-
token = Legacy
|
98
|
+
token = Fernet::Legacy.generate(secret) do |generator|
|
99
99
|
generator.data = token_data
|
100
100
|
end
|
101
101
|
|
102
102
|
expect(
|
103
|
-
Legacy
|
103
|
+
Fernet::Legacy.verify(secret, token) do |verifier|
|
104
104
|
def verifier.now
|
105
105
|
Time.now + 99999999999
|
106
106
|
end
|
@@ -110,54 +110,54 @@ describe Legacy::Fernet do
|
|
110
110
|
end
|
111
111
|
|
112
112
|
it 'generates without custom data' do
|
113
|
-
token = Legacy
|
113
|
+
token = Fernet::Legacy.generate(secret)
|
114
114
|
|
115
|
-
expect(Legacy
|
115
|
+
expect(Fernet::Legacy.verify(secret, token)).to be_true
|
116
116
|
end
|
117
117
|
|
118
118
|
it 'can encrypt the payload' do
|
119
|
-
token = Legacy
|
119
|
+
token = Fernet::Legacy.generate(secret, true) do |generator|
|
120
120
|
generator.data['password'] = 'password1'
|
121
121
|
end
|
122
122
|
|
123
123
|
expect(Base64.decode64(token)).not_to match /password1/
|
124
124
|
|
125
|
-
Legacy
|
125
|
+
Fernet::Legacy.verify(secret, token) do |verifier|
|
126
126
|
expect(verifier.data['password']).to eq('password1')
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
130
|
it 'does not encrypt when asked nicely' do
|
131
|
-
token = Legacy
|
131
|
+
token = Fernet::Legacy.generate(secret, false) do |generator|
|
132
132
|
generator.data['password'] = 'password1'
|
133
133
|
end
|
134
134
|
|
135
135
|
expect(Base64.decode64(token)).to match /password1/
|
136
136
|
|
137
|
-
Legacy
|
137
|
+
Fernet::Legacy.verify(secret, token, false) do |verifier|
|
138
138
|
expect(verifier.data['password']).to eq('password1')
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
142
|
it 'can disable encryption via global configuration' do
|
143
|
-
Legacy::
|
144
|
-
token = Legacy
|
143
|
+
Fernet::Legacy::Configuration.run { |c| c.encrypt = false }
|
144
|
+
token = Fernet::Legacy.generate(secret) do |generator|
|
145
145
|
generator.data['password'] = 'password1'
|
146
146
|
end
|
147
147
|
|
148
148
|
expect(Base64.decode64(token)).to match /password1/
|
149
149
|
|
150
|
-
Legacy
|
150
|
+
Fernet::Legacy.verify(secret, token) do |verifier|
|
151
151
|
expect(verifier.data['password']).to eq('password1')
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
155
|
it 'returns the unencrypted message upon verify' do
|
156
|
-
token = Legacy
|
156
|
+
token = Fernet::Legacy.generate(secret) do |generator|
|
157
157
|
generator.data['password'] = 'password1'
|
158
158
|
end
|
159
159
|
|
160
|
-
verifier = Legacy
|
160
|
+
verifier = Fernet::Legacy.verifier(secret, token)
|
161
161
|
expect(verifier.valid?).to be_true
|
162
162
|
expect(verifier.data['password']).to eq('password1')
|
163
163
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: legacy-fernet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ cert_chain: []
|
|
12
12
|
date: 2013-08-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: multi_json
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
@@ -28,14 +28,14 @@ dependencies:
|
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: rspec
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
35
|
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: '0'
|
38
|
-
type: :
|
38
|
+
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: oj
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|