sequel_vault 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79908bf231a085221e910b96b7345983e900a794
4
- data.tar.gz: ce9c51ff401740d8b402dae1edf45c7aa323b991
3
+ metadata.gz: 165282372b352387b3f41c17d6a652db49e6fd88
4
+ data.tar.gz: bcf9013ae07860c426d1e9895dac5c8fc50eed21
5
5
  SHA512:
6
- metadata.gz: df113a38e57794ac31a830f01ad5b0a65ad9970b5f89c1bda85bc592516849704ad101c75e95b77756fbd07b4c76a48492967636ddf7072a487fbf6c708427ca
7
- data.tar.gz: 7953a1f131303b5f2eb28edf48d183c2ee255b76bb7530403e3577c44fc75a85dcee7ad0191c025e58f64e28485741722c5cb69522df15a2efbb57cca4056e69
6
+ metadata.gz: 35567135ac68c423cba3e794f1f4e96a336fdb8c34bbea44857ecc02b630175f455f06dc46b50f85d1a1127ce5cc642efe6d749a5db7fc83826ec15c0fed2ebf
7
+ data.tar.gz: 161c4e25ecad6ff8720f419803c415183971853c0884f6d18480137d6983954abd6a5c66b5a199bf608344407267b283a3b46287f48c7c1159fbdf9bb36c7acf
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sequel_vault (0.1)
4
+ sequel_vault (0.2)
5
5
  fernet (~> 2.1, >= 2.1)
6
6
  sequel (~> 4.21, >= 4.21.0)
7
7
 
@@ -10,23 +10,23 @@ GEM
10
10
  specs:
11
11
  diff-lcs (1.2.5)
12
12
  docile (1.1.5)
13
- fernet (2.1)
13
+ fernet (2.1.1)
14
14
  valcro (= 0.1)
15
- multi_json (1.11.0)
16
- rspec (3.2.0)
17
- rspec-core (~> 3.2.0)
18
- rspec-expectations (~> 3.2.0)
19
- rspec-mocks (~> 3.2.0)
20
- rspec-core (3.2.2)
21
- rspec-support (~> 3.2.0)
22
- rspec-expectations (3.2.0)
15
+ multi_json (1.11.1)
16
+ rspec (3.3.0)
17
+ rspec-core (~> 3.3.0)
18
+ rspec-expectations (~> 3.3.0)
19
+ rspec-mocks (~> 3.3.0)
20
+ rspec-core (3.3.1)
21
+ rspec-support (~> 3.3.0)
22
+ rspec-expectations (3.3.0)
23
23
  diff-lcs (>= 1.2.0, < 2.0)
24
- rspec-support (~> 3.2.0)
25
- rspec-mocks (3.2.1)
24
+ rspec-support (~> 3.3.0)
25
+ rspec-mocks (3.3.1)
26
26
  diff-lcs (>= 1.2.0, < 2.0)
27
- rspec-support (~> 3.2.0)
28
- rspec-support (3.2.2)
29
- sequel (4.21.0)
27
+ rspec-support (~> 3.3.0)
28
+ rspec-support (3.3.0)
29
+ sequel (4.23.0)
30
30
  simplecov (0.9.2)
31
31
  docile (~> 1.1.0)
32
32
  multi_json (~> 1.0)
data/lib/sequel_vault.rb CHANGED
@@ -1,40 +1,47 @@
1
1
  require "fernet"
2
+ require "sequel"
2
3
 
3
4
  module Sequel
4
5
  module Plugins
5
6
  module Vault
6
7
  class InvalidCiphertext < Exception; end
7
8
 
8
- def self.configure(model, keys = nil, *attrs)
9
+ def self.apply(model, keys = [], *attrs)
10
+ model.instance_eval do
11
+ @vault_attrs = attrs
12
+ @vault_keys = keys
13
+ end
14
+ end
15
+
16
+ def self.configure(model, keys = [], *attrs)
9
17
  model.vault_attributes(keys, *attrs) unless attrs.empty?
10
18
  end
11
19
 
12
20
  module ClassMethods
13
- attr_accessor :vault_attributes_module
21
+ attr_reader :vault_attrs
22
+ attr_reader :vault_keys
23
+ attr_reader :vault_module
24
+
25
+ Plugins.inherited_instance_variables(self, :@vault_attrs => :dup, :@vault_keys => :dup)
14
26
 
15
27
  def vault_attributes(keys, *attrs)
16
- include(self.vault_attributes_module ||= Module.new) unless vault_attributes_module
17
- vault_attributes_module.class_eval do
18
- attrs.each do |attr|
19
- define_method(attr) do
20
- cypher = super()
21
- decrypt(keys, cypher) unless cypher.nil?
22
- end
28
+ raise(Error, 'must provide both keys name and attrs when setting up vault') unless keys && attrs
29
+ @vault_keys = keys
30
+ @vault_attrs = attrs
23
31
 
24
- define_method("#{attr}=") do |plain|
25
- return if plain.nil?
26
- cypher = encrypt(keys, plain)
27
- digest = OpenSSL::HMAC.digest('sha512', keys.first, plain)
28
- super(cypher)
29
- send("#{attr}_digest=", digest)
32
+ self.class.instance_eval do
33
+ attrs.each do |attr|
34
+ define_method("#{attr}_lookup") do |plain|
35
+ digests = keys.map { |key| Sequel.blob(digest(key, plain)) }
36
+ where("#{attr}_digest": digests).first
30
37
  end
31
38
  end
32
39
  end
33
40
  end
34
- end
35
41
 
36
- module InstanceMethods
37
- private
42
+ def digest(keys, plain)
43
+ OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha512'), Array(keys).first, plain)
44
+ end
38
45
 
39
46
  def encrypt(keys, plain)
40
47
  ::Fernet.generate(keys.first, plain)
@@ -49,6 +56,28 @@ module Sequel
49
56
  raise InvalidCiphertext, "Could not decrypt field"
50
57
  end
51
58
  end
59
+
60
+ module DatasetMethods
61
+ end
62
+
63
+ module InstanceMethods
64
+ def []=(attr, plain)
65
+ if model.vault_attrs.include?(attr) && !plain.nil?
66
+ send("#{attr}_digest=", self.class.digest(model.vault_keys, plain))
67
+ value = self.class.encrypt(model.vault_keys, plain)
68
+ end
69
+ super(attr, value || plain)
70
+ end
71
+
72
+ def [](attr)
73
+ if model.vault_attrs.include?(attr)
74
+ cypher = super(attr)
75
+ self.class.decrypt(model.vault_keys, cypher) unless cypher.nil?
76
+ else
77
+ super(attr)
78
+ end
79
+ end
80
+ end
52
81
  end
53
82
  end
54
83
  end
data/sequel_vault.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
13
13
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
14
  gem.name = "sequel_vault"
15
15
  gem.require_paths = ["lib"]
16
- gem.version = '0.2'
16
+ gem.version = '0.3'
17
17
 
18
18
  gem.add_runtime_dependency 'sequel', '~> 4.21', '>= 4.21.0'
19
19
  gem.add_runtime_dependency 'fernet', '~> 2.1', '>= 2.1'
@@ -2,42 +2,51 @@
2
2
  require "spec_helper"
3
3
 
4
4
  describe Sequel::Plugins::Vault do
5
- let(:db) { Sequel.mock }
5
+ let(:db) { Sequel.mock(autoid: 1) }
6
6
  let(:klass) do
7
7
  Class.new(Sequel::Model(db[:vm])) do
8
8
  set_primary_key :id
9
+ unrestrict_primary_key
9
10
  set_columns([:id, :secret, :secret_digest])
10
11
 
11
12
  plugin :vault
12
13
  end
13
14
  end
15
+ let(:dataset) { klass.dataset }
14
16
  let(:model) { klass.new }
15
17
  let(:keys) do
16
18
  ["woRXJWevRaxZLxgoiEQtCDPBSf9TNg57bki0RUK1U48=",
17
19
  "fih3l0Z9e4NBpy5KIj+rmXVexY5O9LspzuqCFyqavjg="]
18
20
  end
19
- let(:sqls) { db.sqls }
20
21
  let(:secret) { "Attack at once." }
22
+ let(:cypher) { klass.encrypt(keys, secret) }
21
23
  let(:digest) { OpenSSL::HMAC.digest('sha512', keys.first, secret) }
22
24
 
23
25
  it "should encrypt vault attributes" do
24
- model.class.vault_attributes(keys, :secret)
26
+ klass.vault_attributes(keys, :secret)
25
27
  model.secret = secret
26
28
  expect(model.values[:secret]).to_not eq(secret)
27
29
  expect(model.secret).to eq(secret)
28
30
  end
29
31
 
30
32
  it "should allow nil value" do
31
- model.class.vault_attributes(keys, :secret)
33
+ klass.vault_attributes(keys, :secret)
32
34
  model.secret = nil
33
35
  expect(model.values[:secret]).to be_nil
34
36
  expect(model.secret).to be_nil
35
37
  end
36
38
 
37
39
  it "should write a digest of the value" do
38
- model.class.vault_attributes(keys, :secret)
40
+ klass.vault_attributes(keys, :secret)
39
41
  model.secret = secret
40
42
  expect(model.values[:secret_digest]).to_not eq(secret)
41
43
  expect(model.secret_digest).to eq(digest)
42
44
  end
45
+
46
+ it "should provide a digest lookup" do
47
+ dataset._fetch = { id: 1, secret: cypher, secret_digest: digest }
48
+ klass.vault_attributes(keys, :secret)
49
+ lookup = klass.secret_lookup("secret")
50
+ expect(lookup.secret).to eq(secret)
51
+ end
43
52
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_vault
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: '0.3'
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: 2015-06-28 00:00:00.000000000 Z
11
+ date: 2015-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel