sequel_vault 0.2 → 0.3

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