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 +4 -4
 - data/Gemfile.lock +15 -15
 - data/lib/sequel_vault.rb +47 -18
 - data/sequel_vault.gemspec +1 -1
 - data/spec/sequel_vault_spec.rb +14 -5
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 165282372b352387b3f41c17d6a652db49e6fd88
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: bcf9013ae07860c426d1e9895dac5c8fc50eed21
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 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. 
     | 
| 
      
 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. 
     | 
| 
       16 
     | 
    
         
            -
                rspec (3. 
     | 
| 
       17 
     | 
    
         
            -
                  rspec-core (~> 3. 
     | 
| 
       18 
     | 
    
         
            -
                  rspec-expectations (~> 3. 
     | 
| 
       19 
     | 
    
         
            -
                  rspec-mocks (~> 3. 
     | 
| 
       20 
     | 
    
         
            -
                rspec-core (3. 
     | 
| 
       21 
     | 
    
         
            -
                  rspec-support (~> 3. 
     | 
| 
       22 
     | 
    
         
            -
                rspec-expectations (3. 
     | 
| 
      
 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. 
     | 
| 
       25 
     | 
    
         
            -
                rspec-mocks (3. 
     | 
| 
      
 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. 
     | 
| 
       28 
     | 
    
         
            -
                rspec-support (3. 
     | 
| 
       29 
     | 
    
         
            -
                sequel (4. 
     | 
| 
      
 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. 
     | 
| 
      
 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 
     | 
    
         
            -
                     
     | 
| 
      
 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 
     | 
    
         
            -
                       
     | 
| 
       17 
     | 
    
         
            -
                       
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       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 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                             
     | 
| 
       28 
     | 
    
         
            -
                             
     | 
| 
       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 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
      
 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. 
     | 
| 
      
 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'
         
     | 
    
        data/spec/sequel_vault_spec.rb
    CHANGED
    
    | 
         @@ -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 
     | 
    
         
            -
                 
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
      
 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. 
     | 
| 
      
 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- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2015-06-29 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: sequel
         
     |