fernet 2.0.rc1 → 2.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
data/.rdoc_options ADDED
@@ -0,0 +1,16 @@
1
+ --- !ruby/object:RDoc::Options
2
+ encoding: UTF-8
3
+ static_path: []
4
+ rdoc_include:
5
+ - .
6
+ charset: UTF-8
7
+ exclude:
8
+ hyperlink_all: false
9
+ line_numbers: false
10
+ main_page:
11
+ markup: tomdoc
12
+ show_hash: false
13
+ tab_width: 8
14
+ title:
15
+ visibility: :protected
16
+ webcvs:
data/.travis.yml CHANGED
@@ -4,6 +4,5 @@ rvm:
4
4
  - "1.9.3"
5
5
  - "1.9.2"
6
6
  - "2.0.0"
7
- - "ruby-head"
8
7
 
9
8
  script: bundle exec rspec -b spec
data/lib/fernet.rb CHANGED
@@ -10,11 +10,56 @@ require 'fernet/configuration'
10
10
  Fernet::Configuration.run
11
11
 
12
12
  module Fernet
13
- def self.generate(secret, message = '', opts = {}, &block)
13
+ # Public: generates a fernet token
14
+ #
15
+ # secret - a base64 encoded, 32 byte string
16
+ # message - the message being secured in plain text
17
+ #
18
+ # Returns the fernet token as a string
19
+ #
20
+ # Examples
21
+ #
22
+ # secret = ...
23
+ # token = Fernet.generate(secret, 'my secrets')
24
+ def self.generate(secret, message = '', opts = {})
14
25
  Generator.new(opts.merge({secret: secret, message: message})).
15
- generate(&block)
26
+ generate
16
27
  end
17
28
 
29
+ # Public: verifies a fernet token
30
+ #
31
+ # secret - the secret used to generate the token
32
+ # token - the token to verify as a string
33
+ # opts - an optional hash containing
34
+ # enforce_ttl: whether to enforce TTL in this verification
35
+ # ttl: number of seconds token is valid
36
+ #
37
+ # Both enforce_ttl and ttl can be configured globally via Configuration
38
+ #
39
+ # Returns a verifier object, which responds to valid? and message
40
+ #
41
+ # Raises Fernet::Token::InvalidToken if token is invalid and message
42
+ # is attempted to be extracted
43
+ #
44
+ # Examples
45
+ #
46
+ # secret = ...
47
+ # token = ...
48
+ # verifier = Fernet.verifier(secret, old_token, enforce_ttl: false)
49
+ # if verifier.valid?
50
+ # verifier.message # original message in plain text
51
+ # end
52
+ #
53
+ # verifier = Fernet.verifier(secret, old_token)
54
+ # if verifier.valid?
55
+ # verifier.message
56
+ # else
57
+ # verifier.errors
58
+ # # -> { issued_timestamp: "is too far in the past: token expired" }
59
+ # verifier.error_messages
60
+ # # -> ["issued_timestamp is too far in the past: token expired"]
61
+ # end
62
+ #
18
63
  def self.verifier(secret, token, opts = {})
19
64
  Verifier.new(opts.merge({secret: secret, token: token}))
20
65
  end
@@ -1,14 +1,25 @@
1
1
  module Fernet
2
+ # Internal: wrappers used for consistent bit packing across rubies
3
+ #
4
+ # Ruby 1.9.2 and below silently ignore endianness specifiers in
5
+ # packing/unpacking format directives
2
6
  module BitPacking
3
7
  extend self
4
8
 
5
- # N.B. Ruby 1.9.2 and below silently ignore endianness specifiers in
6
- # packing/unpacking format directives; we work around it with this
7
-
9
+ # Internal - packs a value as a big endian, 64 bit integer
10
+ #
11
+ # value - a byte sequence as a string
12
+ #
13
+ # Returns array containing each value
8
14
  def pack_int64_bigendian(value)
9
15
  (0..7).map { |index| (value >> (index * 8)) & 0xFF }.reverse.map(&:chr).join
10
16
  end
11
17
 
18
+ # Internal - unpacks a string of big endian, 64 bit integers
19
+ #
20
+ # bytes - an array of ints
21
+ #
22
+ # Returns the original byte sequence as a string
12
23
  def unpack_int64_bigendian(bytes)
13
24
  bytes.each_byte.to_a.reverse.each_with_index.
14
25
  reduce(0) { |val, (byte, index)| val | (byte << (index * 8)) }
@@ -1,16 +1,32 @@
1
1
  require 'singleton'
2
2
  module Fernet
3
+ # Public - singleton class used to globally set various
4
+ # configuration defaults
3
5
  class Configuration
4
6
  include Singleton
5
7
 
6
- # Whether to enforce a message TTL
7
- # (true or false)
8
+ # Public: Returns whether to enforce a message TTL (true or false)
8
9
  attr_accessor :enforce_ttl
9
10
 
10
- # How long messages are considered valid to the verifier
11
- # (an integer in seconds)
11
+ # Public: Returns how many seconds messages are considered valid for
12
12
  attr_accessor :ttl
13
13
 
14
+ # Public: used to configure fernet, typically invoked in an initialization
15
+ # routine
16
+ #
17
+ # Sets the following values:
18
+ #
19
+ # * enforce_ttl: true
20
+ # * ttl: 60
21
+ #
22
+ # Yields the singleton configuration object, where above defaults can be
23
+ # overridden
24
+ #
25
+ # Examples
26
+ #
27
+ # Fernet::Configuration.run do |config|
28
+ # config.enforce_ttl = false
29
+ # end
14
30
  def self.run
15
31
  self.instance.enforce_ttl = true
16
32
  self.instance.ttl = 60
@@ -1,9 +1,25 @@
1
1
  require 'openssl'
2
2
 
3
3
  module Fernet
4
+ # Internal: Encapsulates encryption and signing primitives
4
5
  module Encryption
5
6
  AES_BLOCK_SIZE = 16.freeze
6
7
 
8
+ # Internal: Encrypts the provided message using a AES-128-CBC cipher with a
9
+ # random IV and the provided encryption key
10
+ #
11
+ # opts - a hash containing
12
+ # message: the message to encrypt
13
+ # key: the encryption key
14
+ # iv: override for the random IV, only used for testing
15
+ #
16
+ # Returns a two-element array containing the ciphertext and the random IV
17
+ #
18
+ # Examples
19
+ #
20
+ # ciphertext, iv = Fernet::Encryption.encrypt(
21
+ # message: 'this is a secret', key: encryption_key
22
+ # )
7
23
  def self.encrypt(opts)
8
24
  cipher = OpenSSL::Cipher.new('AES-128-CBC')
9
25
  cipher.encrypt
@@ -13,6 +29,21 @@ module Fernet
13
29
  [cipher.update(opts[:message]) + cipher.final, iv]
14
30
  end
15
31
 
32
+ # Internal: Decrypts the provided ciphertext using a AES-128-CBC cipher with a
33
+ # the provided IV and encryption key
34
+ #
35
+ # opts - a hash containing
36
+ # ciphertext: encrypted message
37
+ # key: encryption key used to encrypt the message
38
+ # iv: initialization vector used in the ciphertext's cipher
39
+ #
40
+ # Returns a two-element array containing the ciphertext and the random IV
41
+ #
42
+ # Examples
43
+ #
44
+ # ciphertext, iv = Fernet::Encryption.encrypt(
45
+ # message: 'this is a secret', key: encryption_key
46
+ # )
16
47
  def self.decrypt(opts)
17
48
  decipher = OpenSSL::Cipher.new('AES-128-CBC')
18
49
  decipher.decrypt
@@ -21,8 +52,15 @@ module Fernet
21
52
  decipher.update(opts[:ciphertext]) + decipher.final
22
53
  end
23
54
 
24
- def self.hmac_digest(key, blob)
25
- OpenSSL::HMAC.digest('sha256', key, blob)
55
+ # Internal: Creates an HMAC signature (sha356 hashing) of the given bytes
56
+ # with the provided signing key
57
+ #
58
+ # key - the signing key
59
+ # bytes - blob of bytes to sign
60
+ #
61
+ # Returns the HMAC signature as a string
62
+ def self.hmac_digest(key, bytes)
63
+ OpenSSL::HMAC.digest('sha256', key, bytes)
26
64
  end
27
65
  end
28
66
  end
@@ -4,9 +4,16 @@ require 'openssl'
4
4
  require 'date'
5
5
 
6
6
  module Fernet
7
+ # Internal: Generates Fernet tokens
7
8
  class Generator
9
+ # Returns the token's message
8
10
  attr_accessor :message
9
11
 
12
+ # Internal: Initializes a generator
13
+ #
14
+ # opts - a hash containing the following keys:
15
+ # secret: a string containing a secret, optionally Base64 encoded
16
+ # message: the message
10
17
  def initialize(opts)
11
18
  @secret = opts.fetch(:secret)
12
19
  @message = opts[:message]
@@ -14,6 +21,21 @@ module Fernet
14
21
  @now = opts[:now]
15
22
  end
16
23
 
24
+ # Internal: generates a secret token
25
+ #
26
+ # Yields itself, useful for setting or overriding the message
27
+ #
28
+ # Returns the token as a string
29
+ #
30
+ # Examples
31
+ # generator = Generator.new(secret: some_secret)
32
+ # token = generator.generate do |g|
33
+ # g.message = 'this is my message'
34
+ # end
35
+ #
36
+ # generator = Generator.new(secret: some_secret,
37
+ # message: 'this is my message')
38
+ # token = generator.generate
17
39
  def generate
18
40
  yield self if block_given?
19
41
 
@@ -24,13 +46,16 @@ module Fernet
24
46
  token.to_s
25
47
  end
26
48
 
49
+ # Public: string representation of this generator, masks secret to avoid
50
+ # leaks
27
51
  def inspect
28
52
  "#<Fernet::Generator @secret=[masked] @message=#{@message.inspect}>"
29
53
  end
30
54
  alias to_s inspect
31
55
 
56
+ # Deprecated: used to set the message
32
57
  def data=(message)
33
- puts "[WARNING] 'data' is deprecated, use 'message' instead"
58
+ puts "[WARNING] 'data=' is deprecated, use 'message=' instead"
34
59
  @message = message
35
60
  end
36
61
  end
data/lib/fernet/secret.rb CHANGED
@@ -1,23 +1,45 @@
1
1
  require 'base64'
2
+
2
3
  module Fernet
4
+ # Internal: Encapsulates a secret key, a 32-byte sequence consisting
5
+ # of an encryption and a signing key.
3
6
  class Secret
4
7
  class InvalidSecret < RuntimeError; end
5
8
 
9
+ # Internal - Initialize a Secret
10
+ #
11
+ # secret - the secret, optionally encoded with either standard or
12
+ # URL safe variants of Base64 encoding
13
+ #
14
+ # Raises Fernet::Secret::InvalidSecret if it cannot be decoded or is
15
+ # not of the expected length
6
16
  def initialize(secret)
7
- @secret = Base64.urlsafe_decode64(secret)
8
- unless @secret.bytesize == 32
9
- raise InvalidSecret, "Secret must be 32 bytes, instead got #{@secret.bytesize}"
17
+ if secret.bytesize == 32
18
+ @secret = secret
19
+ else
20
+ begin
21
+ @secret = Base64.urlsafe_decode64(secret)
22
+ rescue ArgumentError
23
+ @secret = Base64.decode64(secret)
24
+ end
25
+ unless @secret.bytesize == 32
26
+ raise InvalidSecret,
27
+ "Secret must be 32 bytes, instead got #{@secret.bytesize}"
28
+ end
10
29
  end
11
30
  end
12
31
 
32
+ # Internal: Returns the portion of the secret token used for encryption
13
33
  def encryption_key
14
34
  @secret.slice(16, 16)
15
35
  end
16
36
 
37
+ # Internal: Returns the portion of the secret token used for signing
17
38
  def signing_key
18
39
  @secret.slice(0, 16)
19
40
  end
20
41
 
42
+ # Public: String representation of this secret, masks to avoid leaks.
21
43
  def to_s
22
44
  "<Fernet::Secret [masked]>"
23
45
  end
data/lib/fernet/token.rb CHANGED
@@ -3,34 +3,51 @@ require 'base64'
3
3
  require 'valcro'
4
4
 
5
5
  module Fernet
6
+ # Internal: encapsulates a fernet token structure and validation
6
7
  class Token
7
8
  include Valcro
8
9
 
9
10
  class InvalidToken < StandardError; end
10
11
 
12
+ # Internal: the default token version
11
13
  DEFAULT_VERSION = 0x80.freeze
14
+ # Internal: max allowed clock skew for calculating TTL
12
15
  MAX_CLOCK_SKEW = 60.freeze
13
16
 
17
+ # Internal: initializes a Token object
18
+ #
19
+ # token - the string representation of this token
20
+ # opts - a has containing
21
+ # secret: the secret, optionally base 64 encoded (required)
22
+ # enforce_ttl: whether to enforce TTL upon validation. Defaults to value
23
+ # set in Configuration.enforce_ttl
24
+ # ttl: number of seconds token is valid, defaults to Configuration.ttl
14
25
  def initialize(token, opts = {})
15
26
  @token = token
27
+ @secret = Secret.new(opts.fetch(:secret))
16
28
  @enforce_ttl = opts.fetch(:enforce_ttl) { Configuration.enforce_ttl }
17
29
  @ttl = opts[:ttl] || Configuration.ttl
18
30
  @now = opts[:now]
19
31
  end
20
32
 
33
+ # Internal: returns the token as a string
21
34
  def to_s
22
35
  @token
23
36
  end
24
37
 
25
- def secret=(secret)
26
- @secret = Secret.new(secret)
27
- end
28
-
38
+ # Internal: Validates this token and returns true if it's valid
39
+ #
40
+ # Returns a boolean set to true if it's valid, false otherwise
29
41
  def valid?
30
42
  validate
31
43
  super
32
44
  end
33
45
 
46
+ # Internal: returns the decrypted message in this token
47
+ #
48
+ # Raises InvalidToken if it cannot be decrypted or is invalid
49
+ #
50
+ # Returns a string containing the original message in plain text
34
51
  def message
35
52
  if valid?
36
53
  begin
@@ -45,22 +62,27 @@ module Fernet
45
62
  end
46
63
  end
47
64
 
48
- def self.generate(params)
49
- unless params[:secret]
65
+ # Internal: generates a Fernet Token
66
+ #
67
+ # opts - a hash containing
68
+ # secret: a string containing the secret, optionally base64 encoded
69
+ # message: the message in plain text
70
+ def self.generate(opts)
71
+ unless opts[:secret]
50
72
  raise ArgumentError, 'Secret not provided'
51
73
  end
52
- secret = Secret.new(params[:secret])
74
+ secret = Secret.new(opts.fetch(:secret))
53
75
  encrypted_message, iv = Encryption.encrypt(key: secret.encryption_key,
54
- message: params[:message],
55
- iv: params[:iv])
56
- issued_timestamp = (params[:now] || Time.now).to_i
76
+ message: opts[:message],
77
+ iv: opts[:iv])
78
+ issued_timestamp = (opts[:now] || Time.now).to_i
57
79
 
58
80
  payload = [DEFAULT_VERSION].pack("C") +
59
81
  BitPacking.pack_int64_bigendian(issued_timestamp) +
60
82
  iv +
61
83
  encrypted_message
62
84
  mac = OpenSSL::HMAC.digest('sha256', secret.signing_key, payload)
63
- new(Base64.urlsafe_encode64(payload + mac))
85
+ new(Base64.urlsafe_encode64(payload + mac), secret: opts.fetch(:secret))
64
86
  end
65
87
 
66
88
  private
@@ -92,13 +114,12 @@ module Fernet
92
114
  if valid_base64?
93
115
  if unknown_token_version?
94
116
  errors.add :version, "is unknown"
117
+ elsif enforce_ttl? && !issued_recent_enough?
118
+ errors.add :issued_timestamp, "is too far in the past: token expired"
95
119
  else
96
120
  unless signatures_match?
97
121
  errors.add :signature, "does not match"
98
122
  end
99
- if enforce_ttl? && !issued_recent_enough?
100
- errors.add :issued_timestamp, "is too far in the past: token expired"
101
- end
102
123
  if unacceptable_clock_slew?
103
124
  errors.add :issued_timestamp, "is too far in the future"
104
125
  end
@@ -4,34 +4,49 @@ require 'openssl'
4
4
  require 'date'
5
5
 
6
6
  module Fernet
7
+ # Public: verifies Fernet Tokens
7
8
  class Verifier
8
9
  class UnknownTokenVersion < RuntimeError; end
9
10
 
10
11
  attr_reader :token
11
12
  attr_accessor :ttl, :enforce_ttl
12
13
 
14
+ # Internal: initializes a Verifier
15
+ #
16
+ # opts - a hash containing
17
+ # secret: the secret used to create the token (required)
18
+ # token: the fernet token string (required)
19
+ # enforce_ttl: whether to enforce TTL, defaults to Configuration.enforce_ttl
20
+ # ttl: number of seconds the token is valid
13
21
  def initialize(opts = {})
14
22
  enforce_ttl = opts.has_key?(:enforce_ttl) ? opts[:enforce_ttl] : Configuration.enforce_ttl
15
23
  @token = Token.new(opts.fetch(:token),
24
+ secret: opts.fetch(:secret),
16
25
  enforce_ttl: enforce_ttl,
17
26
  ttl: opts[:ttl],
18
27
  now: opts[:now])
19
- @token.secret = opts.fetch(:secret)
20
28
  end
21
29
 
30
+ # Public: whether the verifier is valid. A verifier is valid if it's token
31
+ # is valid.
32
+ #
33
+ # Returns a boolean set to true if the token is valid, false otherwise
22
34
  def valid?
23
35
  @token.valid?
24
36
  end
25
37
 
38
+ # Public: Returns the token's message
26
39
  def message
27
40
  @token.message
28
41
  end
29
42
 
43
+ # Deprecated: returns the token's message
30
44
  def data
31
45
  puts "[WARNING] data is deprected. Use message instead"
32
46
  message
33
47
  end
34
48
 
49
+ # Public: String representation of this verifier, masks the secret to avoid leaks.
35
50
  def inspect
36
51
  "#<Fernet::Verifier @secret=[masked] @token=#{@token} @message=#{@message.inspect} @ttl=#{@ttl} @enforce_ttl=#{@enforce_ttl}>"
37
52
  end
@@ -42,15 +57,6 @@ module Fernet
42
57
  @must_verify || @valid.nil?
43
58
  end
44
59
 
45
- def token_recent_enough?
46
- if enforce_ttl?
47
- good_till = @issued_at + (ttl.to_f / 24 / 60 / 60)
48
- (good_till.to_i >= now.to_i) && acceptable_clock_skew?
49
- else
50
- true
51
- end
52
- end
53
-
54
60
  def acceptable_clock_skew?
55
61
  @issued_at < (now + MAX_CLOCK_SKEW)
56
62
  end
@@ -63,10 +69,6 @@ module Fernet
63
69
  end.zero?
64
70
  end
65
71
 
66
- def enforce_ttl?
67
- @enforce_ttl
68
- end
69
-
70
72
  def now
71
73
  @now ||= Time.now
72
74
  end
@@ -1,3 +1,3 @@
1
1
  module Fernet
2
- VERSION = "2.0.rc1"
2
+ VERSION = "2.0.rc2"
3
3
  end
data/spec/fernet_spec.rb CHANGED
@@ -8,32 +8,21 @@ describe Fernet do
8
8
  let(:bad_secret) { 'badICDH6x3M7duQeM8dJEMK4Y5TkBIsYDw1lPy35RiY=' }
9
9
 
10
10
  it 'can verify tokens it generates' do
11
- token = Fernet.generate(secret) do |generator|
12
- generator.message = 'harold@heroku.com'
13
- end
14
-
15
- verifier = Fernet.verifier(secret, token)
16
- expect(verifier).to be_valid
17
- expect(verifier.message).to eq('harold@heroku.com')
18
- end
19
-
20
- it 'can generate tokens without a block' do
21
11
  token = Fernet.generate(secret, 'harold@heroku.com')
12
+
22
13
  verifier = Fernet.verifier(secret, token)
23
14
  expect(verifier).to be_valid
24
15
  expect(verifier.message).to eq('harold@heroku.com')
25
16
  end
26
17
 
27
18
  it 'fails with a bad secret' do
28
- token = Fernet.generate(secret) do |generator|
29
- generator.message = 'harold@heroku.com'
30
- end
19
+ token = Fernet.generate(secret, 'harold@heroku.com')
31
20
 
32
21
  verifier = Fernet.verifier(bad_secret, token)
33
22
  expect(verifier.valid?).to be_false
34
23
  expect {
35
24
  verifier.message
36
- }.to raise_error
25
+ }.to raise_error Fernet::Token::InvalidToken
37
26
  end
38
27
 
39
28
  it 'fails if the token is too old' do
@@ -77,9 +66,7 @@ describe Fernet do
77
66
  config.enforce_ttl = true
78
67
  config.ttl = 0
79
68
  end
80
- token = Fernet.generate(secret) do |generator|
81
- generator.message = 'password1'
82
- end
69
+ token = Fernet.generate(secret, 'password1')
83
70
  verifier = Fernet.verifier(secret, token)
84
71
  verifier.enforce_ttl = false
85
72
  expect(verifier.valid?).to be_true
data/spec/secret_spec.rb CHANGED
@@ -2,23 +2,16 @@ require 'spec_helper'
2
2
  require 'fernet/secret'
3
3
 
4
4
  describe Fernet::Secret do
5
- it "expects base64 encoded 32 byte strings" do
6
- secret = Base64.urlsafe_encode64("A"*32)
7
- expect do
8
- Fernet::Secret.new(secret)
9
- end.to_not raise_error
5
+ it "can resolve a URL safe base64 encoded 32 byte string" do
6
+ resolves_input(Base64.urlsafe_encode64("A"*16 + "B"*16))
10
7
  end
11
8
 
12
- it "extracts encryption and signing keys" do
13
- secret = Base64.urlsafe_encode64("A"*16 + "B"*16)
14
- fernet_secret = Fernet::Secret.new(secret)
15
- expect(
16
- fernet_secret.signing_key
17
- ).to eq("A"*16)
9
+ it "can resolve a base64 encoded 32 byte string" do
10
+ resolves_input(Base64.encode64("A"*16 + "B"*16))
11
+ end
18
12
 
19
- expect(
20
- fernet_secret.encryption_key
21
- ).to eq("B"*16)
13
+ it "can resolve a 32 byte string without encoding" do
14
+ resolves_input("A"*16 + "B"*16)
22
15
  end
23
16
 
24
17
  it "fails loudly when an invalid secret is provided" do
@@ -27,4 +20,16 @@ describe Fernet::Secret do
27
20
  Fernet::Secret.new(secret)
28
21
  end.to raise_error(Fernet::Secret::InvalidSecret)
29
22
  end
23
+
24
+ def resolves_input(input)
25
+ secret = Fernet::Secret.new(input)
26
+
27
+ expect(
28
+ secret.signing_key
29
+ ).to eq("A"*16)
30
+
31
+ expect(
32
+ secret.encryption_key
33
+ ).to eq("B"*16)
34
+ end
30
35
  end
data/spec/token_spec.rb CHANGED
@@ -11,8 +11,7 @@ describe Fernet::Token, 'validation' do
11
11
  bogus_hmac = "1" * 32
12
12
  Fernet::Encryption.stub(hmac_digest: bogus_hmac)
13
13
 
14
- token = Fernet::Token.new(generated.to_s)
15
- token.secret = secret
14
+ token = Fernet::Token.new(generated.to_s, secret: secret)
16
15
 
17
16
  expect(token.valid?).to be_false
18
17
  expect(token.errors[:signature]).to include("does not match")
@@ -23,9 +22,8 @@ describe Fernet::Token, 'validation' do
23
22
  message: 'hello',
24
23
  now: Time.now - 61)
25
24
  token = Fernet::Token.new(generated.to_s, enforce_ttl: true,
26
- ttl: 60)
27
- token.secret = secret
28
-
25
+ ttl: 60,
26
+ secret: secret)
29
27
  expect(token.valid?).to be_false
30
28
  expect(token.errors[:issued_timestamp]).to include("is too far in the past: token expired")
31
29
  end
@@ -34,23 +32,21 @@ describe Fernet::Token, 'validation' do
34
32
  generated = Fernet::Token.generate(secret: secret,
35
33
  message: 'hello',
36
34
  now: Time.at(Time.now.to_i + 61))
37
- token = Fernet::Token.new(generated.to_s)
38
- token.secret = secret
35
+ token = Fernet::Token.new(generated.to_s, secret: secret)
39
36
 
40
37
  expect(token.valid?).to be_false
41
38
  expect(token.errors[:issued_timestamp]).to include("is too far in the future")
42
39
  end
43
40
 
44
41
  it 'is invalid with bad base64' do
45
- token = Fernet::Token.new('bad')
46
- token.secret = secret
42
+ token = Fernet::Token.new('bad', secret: secret)
47
43
 
48
44
  expect(token.valid?).to be_false
49
45
  expect(token.errors[:token]).to include("invalid base64")
50
46
  end
51
47
 
52
48
  it 'is invalid with an unknown token version' do
53
- token = Fernet::Token.new(Base64.urlsafe_encode64("xxxxxx"))
49
+ token = Fernet::Token.new(Base64.urlsafe_encode64("xxxxxx"), secret: secret)
54
50
 
55
51
  expect(token.valid?).to be_false
56
52
  expect(token.errors[:version]).to include("is unknown")
@@ -63,8 +59,7 @@ describe Fernet::Token, 'message' do
63
59
  generated = Fernet::Token.generate(secret: secret,
64
60
  message: 'hello',
65
61
  now: Time.now + 61)
66
- token = Fernet::Token.new(generated.to_s)
67
- token.secret = secret
62
+ token = Fernet::Token.new(generated.to_s, secret: secret)
68
63
 
69
64
  !token.valid? or raise "invalid token"
70
65
 
@@ -77,7 +72,6 @@ describe Fernet::Token, 'message' do
77
72
  it 'gives back the original message in plain text' do
78
73
  token = Fernet::Token.generate(secret: secret,
79
74
  message: 'hello')
80
- token.secret = secret
81
75
  token.valid? or raise "invalid token"
82
76
 
83
77
  expect(token.message).to eq('hello')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fernet
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.rc1
4
+ version: 2.0.rc2
5
5
  prerelease: 4
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-19 00:00:00.000000000 Z
12
+ date: 2013-09-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: valcro
@@ -52,6 +52,7 @@ extra_rdoc_files: []
52
52
  files:
53
53
  - .gitignore
54
54
  - .gitmodules
55
+ - .rdoc_options
55
56
  - .rspec
56
57
  - .travis.yml
57
58
  - Gemfile