fernet 2.0.rc1 → 2.0.rc2

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/.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