slosilo 1.1.0 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,25 +1,40 @@
1
1
  module Slosilo
2
2
  class Symmetric
3
+ VERSION_MAGIC = 'G'
4
+ TAG_LENGTH = 16
5
+
3
6
  def initialize
4
- @cipher = OpenSSL::Cipher.new 'AES-256-CBC'
7
+ @cipher = OpenSSL::Cipher.new 'aes-256-gcm' # NB: has to be lower case for whatever reason.
5
8
  end
6
-
9
+
10
+ # This lets us do a final sanity check in migrations from older encryption versions
11
+ def cipher_name
12
+ @cipher.name
13
+ end
14
+
7
15
  def encrypt plaintext, opts = {}
8
16
  @cipher.reset
9
17
  @cipher.encrypt
10
- @cipher.key = opts[:key]
18
+ @cipher.key = (opts[:key] or raise("missing :key option"))
11
19
  @cipher.iv = iv = random_iv
12
- ctxt = @cipher.update(plaintext)
13
- iv + ctxt + @cipher.final
20
+ @cipher.auth_data = opts[:aad] || "" # Nothing good happens if you set this to nil, or don't set it at all
21
+ ctext = @cipher.update(plaintext) + @cipher.final
22
+ tag = @cipher.auth_tag(TAG_LENGTH)
23
+ "#{VERSION_MAGIC}#{tag}#{iv}#{ctext}"
14
24
  end
15
-
25
+
16
26
  def decrypt ciphertext, opts = {}
27
+ version, tag, iv, ctext = unpack ciphertext
28
+
29
+ raise "Invalid version magic: expected #{VERSION_MAGIC} but was #{version}" unless version == VERSION_MAGIC
30
+
17
31
  @cipher.reset
18
32
  @cipher.decrypt
19
33
  @cipher.key = opts[:key]
20
- @cipher.iv, ctxt = ciphertext.unpack("a#{@cipher.iv_len}a*")
21
- ptxt = @cipher.update(ctxt)
22
- ptxt + @cipher.final
34
+ @cipher.iv = iv
35
+ @cipher.auth_tag = tag
36
+ @cipher.auth_data = opts[:aad] || ""
37
+ @cipher.update(ctext) + @cipher.final
23
38
  end
24
39
 
25
40
  def random_iv
@@ -29,5 +44,11 @@ module Slosilo
29
44
  def random_key
30
45
  @cipher.random_key
31
46
  end
47
+
48
+ private
49
+ # return tag, iv, ctext
50
+ def unpack msg
51
+ msg.unpack "aa#{TAG_LENGTH}a#{@cipher.iv_len}a*"
52
+ end
32
53
  end
33
54
  end
@@ -1,3 +1,3 @@
1
1
  module Slosilo
2
- VERSION = "1.1.0"
2
+ VERSION = "2.2.2"
3
3
  end
@@ -24,4 +24,9 @@ namespace :slosilo do
24
24
  task :migrate => :environment do |t|
25
25
  Slosilo.adapter.migrate!
26
26
  end
27
+
28
+ desc "Recalculate fingerprints in keystore"
29
+ task :recalculate_fingerprints => :environment do |t|
30
+ Slosilo.adapter.recalculate_fingerprints
31
+ end
27
32
  end
@@ -0,0 +1,11 @@
1
+ #!/bin/bash -e
2
+
3
+ docker pull registry.tld/conjurinc/publish-rubygem
4
+
5
+ docker run -i --rm -v $PWD:/src -w /src alpine/git clean -fxd
6
+
7
+ summon --yaml "RUBYGEMS_API_KEY: !var rubygems/api-key" \
8
+ docker run --rm --env-file @SUMMONENVFILE -v "$(pwd)":/opt/src \
9
+ registry.tld/conjurinc/publish-rubygem slosilo
10
+
11
+ docker run -i --rm -v $PWD:/src -w /src alpine/git clean -fxd
@@ -1,5 +1,12 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/slosilo/version', __FILE__)
2
+ begin
3
+ require File.expand_path('../lib/slosilo/version', __FILE__)
4
+ rescue LoadError
5
+ # so that bundle can be run without the app code
6
+ module Slosilo
7
+ VERSION = '0.0.0'
8
+ end
9
+ end
3
10
 
4
11
  Gem::Specification.new do |gem|
5
12
  gem.authors = ["Rafa\305\202 Rzepecki"]
@@ -16,12 +23,14 @@ Gem::Specification.new do |gem|
16
23
  gem.require_paths = ["lib"]
17
24
  gem.version = Slosilo::VERSION
18
25
  gem.required_ruby_version = '>= 1.9.3'
19
-
26
+
20
27
  gem.add_development_dependency 'rake'
21
28
  gem.add_development_dependency 'rspec', '~> 3.0'
22
29
  gem.add_development_dependency 'ci_reporter_rspec'
23
30
  gem.add_development_dependency 'simplecov'
31
+ gem.add_development_dependency 'simplecov-cobertura'
24
32
  gem.add_development_dependency 'io-grab', '~> 0.0.1'
25
33
  gem.add_development_dependency 'sequel' # for sequel tests
26
34
  gem.add_development_dependency 'sqlite3' # for sequel tests
35
+ gem.add_development_dependency 'activesupport' # for convenience in specs
27
36
  end
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+ require 'slosilo/attr_encrypted'
3
+
4
+ describe Slosilo::EncryptedAttributes do
5
+ before(:all) do
6
+ Slosilo::encryption_key = OpenSSL::Cipher.new("aes-256-gcm").random_key
7
+ end
8
+
9
+ let(:aad) { proc{ |_| "hithere" } }
10
+
11
+ let(:base){
12
+ Class.new do
13
+ attr_accessor :normal_ivar,:with_aad
14
+ def stupid_ivar
15
+ side_effect!
16
+ @_explicit
17
+ end
18
+ def stupid_ivar= e
19
+ side_effect!
20
+ @_explicit = e
21
+ end
22
+ def side_effect!
23
+
24
+ end
25
+ end
26
+ }
27
+
28
+ let(:sub){
29
+ Class.new(base) do
30
+ attr_encrypted :normal_ivar, :stupid_ivar
31
+ end
32
+ }
33
+
34
+ subject{ sub.new }
35
+
36
+ context "when setting a normal ivar" do
37
+ let(:value){ "some value" }
38
+ it "stores an encrypted value in the ivar" do
39
+ subject.normal_ivar = value
40
+ expect(subject.instance_variable_get(:"@normal_ivar")).to_not eq(value)
41
+ end
42
+
43
+ it "recovers the value set" do
44
+ subject.normal_ivar = value
45
+ expect(subject.normal_ivar).to eq(value)
46
+ end
47
+ end
48
+
49
+ context "when setting an attribute with an implementation" do
50
+ it "calls the base class method" do
51
+ expect(subject).to receive_messages(:side_effect! => nil)
52
+ subject.stupid_ivar = "hi"
53
+ expect(subject.stupid_ivar).to eq("hi")
54
+ end
55
+ end
56
+
57
+ context "when given an :aad option" do
58
+
59
+ let(:cipher){ Slosilo::EncryptedAttributes.cipher }
60
+ let(:key){ Slosilo::EncryptedAttributes.key}
61
+ context "that is a string" do
62
+ let(:aad){ "hello there" }
63
+ before{ sub.attr_encrypted :with_aad, aad: aad }
64
+ it "encrypts the value with the given string for auth data" do
65
+ expect(cipher).to receive(:encrypt).with("hello", key: key, aad: aad)
66
+ subject.with_aad = "hello"
67
+ end
68
+
69
+ it "decrypts the encrypted value" do
70
+ subject.with_aad = "foo"
71
+ expect(subject.with_aad).to eq("foo")
72
+ end
73
+ end
74
+
75
+ context "that is nil" do
76
+ let(:aad){ nil }
77
+ before{ sub.attr_encrypted :with_aad, aad: aad }
78
+ it "encrypts the value with an empty string for auth data" do
79
+ expect(cipher).to receive(:encrypt).with("hello",key: key, aad: "").and_call_original
80
+ subject.with_aad = "hello"
81
+ end
82
+
83
+ it "decrypts the encrypted value" do
84
+ subject.with_aad = "hello"
85
+ expect(subject.with_aad).to eq("hello")
86
+ end
87
+ end
88
+
89
+ context "that is a proc" do
90
+ let(:aad){
91
+ proc{ |o| "x" }
92
+ }
93
+
94
+ before{ sub.attr_encrypted :with_aad, aad: aad }
95
+
96
+ it "calls the proc with the object being encrypted" do
97
+ expect(aad).to receive(:[]).with(subject).and_call_original
98
+ subject.with_aad = "hi"
99
+ end
100
+
101
+ it "encrypts the value with the string returned for auth data" do
102
+ expect(cipher).to receive(:encrypt).with("hello", key: key, aad: aad[subject]).and_call_original
103
+ subject.with_aad = "hello"
104
+ end
105
+ it "decrypts the encrypted value" do
106
+ subject.with_aad = "hello"
107
+ expect(subject.with_aad).to eq("hello")
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+
114
+ end
@@ -22,7 +22,7 @@ describe Slosilo::Adapters::FileAdapter do
22
22
  context "unacceptable id" do
23
23
  let(:id) { "foo.bar" }
24
24
  it "isn't accepted" do
25
- expect { subject.put_key id, key }.to raise_error
25
+ expect { subject.put_key id, key }.to raise_error /id should not contain a period/
26
26
  end
27
27
  end
28
28
  context "acceptable id" do
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ # (Mostly) integration tests for JWT token format
4
+ describe Slosilo::Key do
5
+ include_context "with example key"
6
+
7
+ describe '#issue_jwt' do
8
+ it 'issues an JWT token with given claims' do
9
+ allow(Time).to receive(:now) { DateTime.parse('2014-06-04 23:22:32 -0400').to_time }
10
+
11
+ tok = key.issue_jwt sub: 'host/example', cidr: %w(fec0::/64)
12
+
13
+ expect(tok).to be_frozen
14
+
15
+ expect(tok.header).to eq \
16
+ alg: 'conjur.org/slosilo/v2',
17
+ kid: key_fingerprint
18
+ expect(tok.claims).to eq \
19
+ iat: 1401938552,
20
+ sub: 'host/example',
21
+ cidr: ['fec0::/64']
22
+
23
+ expect(key.verify_signature tok.string_to_sign, tok.signature).to be_truthy
24
+ end
25
+ end
26
+ end
27
+
28
+ describe Slosilo::JWT do
29
+ context "with a signed token" do
30
+ let(:signature) { 'very signed, such alg' }
31
+ subject(:token) { Slosilo::JWT.new test: "token" }
32
+ before do
33
+ allow(Time).to receive(:now) { DateTime.parse('2014-06-04 23:22:32 -0400').to_time }
34
+ token.add_signature(alg: 'test-sig') { signature }
35
+ end
36
+
37
+ it 'allows conversion to JSON representation with #to_json' do
38
+ json = JSON.load token.to_json
39
+ expect(JSON.load Base64.urlsafe_decode64 json['protected']).to eq \
40
+ 'alg' => 'test-sig'
41
+ expect(JSON.load Base64.urlsafe_decode64 json['payload']).to eq \
42
+ 'iat' => 1401938552, 'test' => 'token'
43
+ expect(Base64.urlsafe_decode64 json['signature']).to eq signature
44
+ end
45
+
46
+ it 'allows conversion to compact representation with #to_s' do
47
+ h, c, s = token.to_s.split '.'
48
+ expect(JSON.load Base64.urlsafe_decode64 h).to eq \
49
+ 'alg' => 'test-sig'
50
+ expect(JSON.load Base64.urlsafe_decode64 c).to eq \
51
+ 'iat' => 1401938552, 'test' => 'token'
52
+ expect(Base64.urlsafe_decode64 s).to eq signature
53
+ end
54
+ end
55
+
56
+ describe '#to_json' do
57
+ it "passes any parameters" do
58
+ token = Slosilo::JWT.new
59
+ allow(token).to receive_messages \
60
+ header: :header,
61
+ claims: :claims,
62
+ signature: :signature
63
+ expect_any_instance_of(Hash).to receive(:to_json).with :testing
64
+ expect(token.to_json :testing)
65
+ end
66
+ end
67
+
68
+ describe '()' do
69
+ include_context "with example key"
70
+
71
+ it 'understands both serializations' do
72
+ [COMPACT_TOKEN, JSON_TOKEN].each do |token|
73
+ token = Slosilo::JWT token
74
+ expect(token.header).to eq \
75
+ 'typ' => 'JWT',
76
+ 'alg' => 'conjur.org/slosilo/v2',
77
+ 'kid' => key_fingerprint
78
+ expect(token.claims).to eq \
79
+ 'sub' => 'host/example',
80
+ 'iat' => 1401938552,
81
+ 'exp' => 1401938552 + 60*60,
82
+ 'cidr' => ['fec0::/64']
83
+ expect(key.verify_signature token.string_to_sign, token.signature).to be_truthy
84
+ end
85
+ end
86
+
87
+ it 'is a noop if already parsed' do
88
+ token = Slosilo::JWT COMPACT_TOKEN
89
+ expect(Slosilo::JWT token).to eq token
90
+ end
91
+
92
+ it 'raises ArgumentError on failure to convert' do
93
+ expect { Slosilo::JWT "foo bar" }.to raise_error ArgumentError
94
+ expect { Slosilo::JWT elite: 31337 }.to raise_error ArgumentError
95
+ expect { Slosilo::JWT "foo.bar.xyzzy" }.to raise_error ArgumentError
96
+ end
97
+ end
98
+
99
+ COMPACT_TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJjb25qdXIub3JnL3Nsb3NpbG8vdjIiLCJraWQiOiIxMDdiZGI4NTAxYzQxOWZhZDJmZGIyMGI0NjdkNGQwYTYyYTE2YTk4YzM1ZjJkYTBlYjNiMWZmOTI5Nzk1YWQ5In0=.eyJzdWIiOiJob3N0L2V4YW1wbGUiLCJjaWRyIjpbImZlYzA6Oi82NCJdLCJleHAiOjE0MDE5NDIxNTIsImlhdCI6MTQwMTkzODU1Mn0=.qSxy6gx0DbiIc-Wz_vZhBsYi1SCkHhzxfMGPnnG6MTqjlzy7ntmlU2H92GKGoqCRo6AaNLA_C3hA42PeEarV5nMoTj8XJO_kwhrt2Db2OX4u83VS0_enoztWEZG5s45V0Lv71lVR530j4LD-hpqhm_f4VuISkeH84u0zX7s1zKOlniuZP-abCAHh0htTnrVz9wKG0VywkCUmWYyNNqC2h8PRf64SvCWcQ6VleHpjO-ms8OeTw4ZzRbzKMi0mL6eTmQlbT3PeBArUaS0pNJPg9zdDQaL2XDOofvQmj6Yy_8RA4eCt9HEfTYEdriVqK-_9QCspbGzFVn9GTWf51MRi5dngV9ItsDoG9ktDtqFuMttv7TcqjftsIHZXZsAZ175E".freeze
100
+
101
+ JSON_TOKEN = "{\"protected\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJjb25qdXIub3JnL3Nsb3NpbG8vdjIiLCJraWQiOiIxMDdiZGI4NTAxYzQxOWZhZDJmZGIyMGI0NjdkNGQwYTYyYTE2YTk4YzM1ZjJkYTBlYjNiMWZmOTI5Nzk1YWQ5In0=\",\"payload\":\"eyJzdWIiOiJob3N0L2V4YW1wbGUiLCJjaWRyIjpbImZlYzA6Oi82NCJdLCJleHAiOjE0MDE5NDIxNTIsImlhdCI6MTQwMTkzODU1Mn0=\",\"signature\":\"qSxy6gx0DbiIc-Wz_vZhBsYi1SCkHhzxfMGPnnG6MTqjlzy7ntmlU2H92GKGoqCRo6AaNLA_C3hA42PeEarV5nMoTj8XJO_kwhrt2Db2OX4u83VS0_enoztWEZG5s45V0Lv71lVR530j4LD-hpqhm_f4VuISkeH84u0zX7s1zKOlniuZP-abCAHh0htTnrVz9wKG0VywkCUmWYyNNqC2h8PRf64SvCWcQ6VleHpjO-ms8OeTw4ZzRbzKMi0mL6eTmQlbT3PeBArUaS0pNJPg9zdDQaL2XDOofvQmj6Yy_8RA4eCt9HEfTYEdriVqK-_9QCspbGzFVn9GTWf51MRi5dngV9ItsDoG9ktDtqFuMttv7TcqjftsIHZXZsAZ175E\"}".freeze
102
+ end
@@ -1,5 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
+ require 'active_support'
4
+ require 'active_support/core_ext/numeric/time'
5
+
3
6
  describe Slosilo::Key do
4
7
  include_context "with example key"
5
8
 
@@ -77,8 +80,8 @@ describe Slosilo::Key do
77
80
  end
78
81
  end
79
82
 
80
- let(:ciphertext) { "\x8B\xE6\xEC\x8C\xAB\xA4\xC0\x8EF\"\x0F\xD5Yh\xA1\aq\x00\xF5\xAC\xAB\v\a\xEC\xF6G\xA6\e\x14N\xFF\x11\x98\xDA\x19\xB5\x8994_:\xA0\xF8\x06l\xDC\x9B\xB1\xE8z\x83\xCC\x9A\x02E\x02tOhu\x92F]h".force_encoding("ASCII-8BIT") }
81
- let(:skey) { "\x15\xFF\xD4>\x9C\xF4\x0F\xB6\x04C\x18\xC1\x96\xC3\xE0T\xA3\xF5\xE8\x17\xA6\xE0\x86~rrw\xC3\xDF\x11)$\x9B\r@\x0E\xE4Zv\rw-\xFC\x1C\x84\x17\xBD\xDB\x12u\xCD\r\xFEo\xD5\xC8[\x8FEA\\\xA9\xA2F#\x8BH -\xFA\xF7\xA9\xEBf\x97\xAAT}\x8E*\xC0r\x944p\xD0\x9A\xE7\xBD\a;O\f\xEF\xE4B.y\xFA\xB4e@O\xBB\x15>y\xC9\t=\x01\xE1J\xF3X\xA9\x9E3\x04^H\x1F\xFF\x19C\x93ve)@\xF7\t_\xCF\xDE\xF1\xB7]\x83lL\xB8%A\x93p{\xE9Y\xBAu\xCE\x99T\xDC\xDF\xE7\x0FD%\xB9AXb\x1CW\x94$P\xBB\xE1g\xDEE\t\xC4\x92\x9E\xFEt\xDF\xD0\xEA\x03\xC4\x12\xA9\x02~u\xF4\x92 ;\xA0\xCE.\b+)\x05\xEDo\xA5cF\xF8\x12\xD7F\x97\xE44\xBF\xF1@\xA5\xC5\xA8\xE5\a\xE8ra<\x04\xB5\xA2\f\t\xF7T\x97\e\xF5(^\xAB\xA5%84\x10\xD1\x13e<\xCA/\xBF}%\xF6\xB1%\xB2".force_encoding("ASCII-8BIT") }
83
+ let(:ciphertext){ "G\xAD^\x17\x11\xBBQ9-b\x14\xF6\x92#Q0x\xF4\xAD\x1A\x92\xC3VZW\x89\x8E\x8Fg\x93\x05B\xF8\xD6O\xCFGCTp\b~\x916\xA3\x9AN\x8D\x961\x1F\xA3mSf&\xAD\xA77/]z\xA89\x01\xA7\xA9\x92\f".force_encoding('ASCII-8BIT') }
84
+ let(:skey){ "\x82\x93\xFAA\xA6wQA\xE1\xB5\xA6b\x8C.\xCF#I\x86I\x83u\x99\rTA\xEF\xC4\x91\xC5)-\xEBQ\xB1\xC0\xC6\xFF\x90L\xFE\x1E\x15\x81\x12\x16\xDD:A\xC5d\xE1B\xD2f@\xB8o\xB7+N\xB7\n\x92\xDC\x9E\xE3\x83\xB8>h\a\xC7\xCC\xCF\xD0t\x06\x8B\xA8\xBF\xEFe\xA4{\x88\f\xDD\roF\xEB.\xDA\xBF\x9D_0>\xF03c'\x1F!)*-\x19\x97\xAC\xD2\x1F(,6h\a\x93\xDB\x8E\x97\xF9\x1A\x11\x84\x11t\xD9\xB2\x85\xB0\x12\x7F\x03\x00O\x8F\xBE#\xFFb\xA5w\xF3g\xCF\xB4\xF2\xB7\xDBiA=\xA8\xFD1\xEC\xBF\xD7\x8E\xB6W>\x03\xACNBa\xBF\xFD\xC6\xB32\x8C\xE2\xF1\x87\x9C\xAE6\xD1\x12\vkl\xBB\xA0\xED\x9A\xEE6\xF2\xD9\xB4LL\xE2h/u_\xA1i=\x11x\x8DGha\x8EG\b+\x84[\x87\x8E\x01\x0E\xA5\xB0\x9F\xE9vSl\x18\xF3\xEA\xF4NH\xA8\xF1\x81\xBB\x98\x01\xE8p]\x18\x11f\xA3K\xA87c\xBB\x13X~K\xA2".force_encoding('ASCII-8BIT') }
82
85
  describe '#decrypt' do
83
86
  it "decrypts the symmetric key and then uses it to decrypt the ciphertext" do
84
87
  expect(subject.decrypt(ciphertext, skey)).to eq(plaintext)
@@ -120,7 +123,7 @@ describe Slosilo::Key do
120
123
  context "when given something else" do
121
124
  subject { Slosilo::Key.new "foo" }
122
125
  it "fails early" do
123
- expect { subject }.to raise_error
126
+ expect { subject }.to raise_error ArgumentError
124
127
  end
125
128
  end
126
129
  end
@@ -145,6 +148,19 @@ describe Slosilo::Key do
145
148
  expect(key.sign("this sentence is not this sentence")).to eq(expected_signature)
146
149
  end
147
150
  end
151
+
152
+ context "when given a Hash containing non-ascii characters" do
153
+ let(:unicode){ "adèle.dupuis" }
154
+ let(:encoded){
155
+ unicode.dup.tap{|s| s.force_encoding Encoding::ASCII_8BIT}
156
+ }
157
+ let(:hash){ {"data" => unicode} }
158
+
159
+ it "converts the value to raw bytes before signing it" do
160
+ expect(key).to receive(:sign_string).with("[[\"data\",\"#{encoded}\"]]").and_call_original
161
+ key.sign hash
162
+ end
163
+ end
148
164
  end
149
165
 
150
166
  describe "#signed_token" do
@@ -162,7 +178,50 @@ describe Slosilo::Key do
162
178
  subject { key.signed_token data }
163
179
  it { is_expected.to eq(expected_token) }
164
180
  end
165
-
181
+
182
+ describe "#validate_jwt" do
183
+ let(:token) do
184
+ instance_double Slosilo::JWT,
185
+ header: { 'alg' => 'conjur.org/slosilo/v2' },
186
+ claims: { 'iat' => Time.now.to_i },
187
+ string_to_sign: double("string to sign"),
188
+ signature: double("signature")
189
+ end
190
+
191
+ before do
192
+ allow(key).to receive(:verify_signature).with(token.string_to_sign, token.signature) { true }
193
+ end
194
+
195
+ it "verifies the signature" do
196
+ expect { key.validate_jwt token }.not_to raise_error
197
+ end
198
+
199
+ it "rejects unknown algorithm" do
200
+ token.header['alg'] = 'HS256' # we're not supporting standard algorithms
201
+ expect { key.validate_jwt token }.to raise_error /algorithm/
202
+ end
203
+
204
+ it "rejects bad signature" do
205
+ allow(key).to receive(:verify_signature).with(token.string_to_sign, token.signature) { false }
206
+ expect { key.validate_jwt token }.to raise_error /signature/
207
+ end
208
+
209
+ it "rejects expired token" do
210
+ token.claims['exp'] = 1.hour.ago.to_i
211
+ expect { key.validate_jwt token }.to raise_error /expired/
212
+ end
213
+
214
+ it "accepts unexpired token with implicit expiration" do
215
+ token.claims['iat'] = 5.minutes.ago
216
+ expect { key.validate_jwt token }.to_not raise_error
217
+ end
218
+
219
+ it "rejects token expired with implicit expiration" do
220
+ token.claims['iat'] = 10.minutes.ago.to_i
221
+ expect { key.validate_jwt token }.to raise_error /expired/
222
+ end
223
+ end
224
+
166
225
  describe "#token_valid?" do
167
226
  let(:data) { { "foo" => :bar } }
168
227
  let(:signature) { Base64::urlsafe_encode64 "\xB0\xCE{\x9FP\xEDV\x9C\xE7b\x8B[\xFAil\x87^\x96\x17Z\x97\x1D\xC2?B\x96\x9C\x8Ep-\xDF_\x8F\xC21\xD9^\xBC\n\x16\x04\x8DJ\xF6\xAF-\xEC\xAD\x03\xF9\xEE:\xDF\xB5\x8F\xF9\xF6\x81m\xAB\x9C\xAB1\x1E\x837\x8C\xFB\xA8P\xA8<\xEA\x1Dx\xCEd\xED\x84f\xA7\xB5t`\x96\xCC\x0F\xA9t\x8B\x9Fo\xBF\x92K\xFA\xFD\xC5?\x8F\xC68t\xBC\x9F\xDE\n$\xCA\xD2\x8F\x96\x0EtX2\x8Cl\x1E\x8Aa\r\x8D\xCAi\x86\x1A\xBD\x1D\xF7\xBC\x8561j\x91YlO\xFA(\x98\x10iq\xCC\xAF\x9BV\xC6\v\xBC\x10Xm\xCD\xFE\xAD=\xAA\x95,\xB4\xF7\xE8W\xB8\x83;\x81\x88\xE6\x01\xBA\xA5F\x91\x17\f\xCE\x80\x8E\v\x83\x9D<\x0E\x83\xF6\x8D\x03\xC0\xE8A\xD7\x90i\x1D\x030VA\x906D\x10\xA0\xDE\x12\xEF\x06M\xD8\x8B\xA9W\xC8\x9DTc\x8AJ\xA4\xC0\xD3!\xFA\x14\x89\xD1p\xB4J7\xA5\x04\xC2l\xDC8<\x04Y\xD8\xA4\xFB[\x89\xB1\xEC\xDA\xB8\xD7\xEA\x03Ja pinch of salt".force_encoding("ASCII-8BIT") }
@@ -60,7 +60,7 @@ describe Slosilo::Adapters::SequelAdapter do
60
60
  let(:db) { Sequel.sqlite }
61
61
  before do
62
62
  allow(subject).to receive(:create_model).and_call_original
63
- Sequel.cache_anonymous_models = false
63
+ Sequel::Model.cache_anonymous_models = false
64
64
  Sequel::Model.db = db
65
65
  end
66
66
  end