pgcrypto 0.2.7 → 0.3.1
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/CHANGES.md +68 -0
- data/Gemfile +1 -1
- data/VERSION +1 -1
- data/lib/pgcrypto.rb +3 -2
- data/lib/pgcrypto/column.rb +2 -0
- data/pgcrypto.gemspec +6 -6
- data/spec/lib/pgcrypto_spec.rb +93 -78
- data/spec/spec_helper.rb +3 -6
- metadata +6 -6
- data/CHANGES +0 -59
data/CHANGES.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
## 0.3.1
|
3
|
+
- Finally solved a large bug with a very simple fix. Looks
|
4
|
+
like we're approaching stability, folks!
|
5
|
+
|
6
|
+
## 0.3.0
|
7
|
+
- Finally solved a large bug with a very simple fix. Looks
|
8
|
+
like we're approaching stability, folks!
|
9
|
+
|
10
|
+
## 0.2.7
|
11
|
+
- So, about that library I arrogantly included? Turns out we
|
12
|
+
should require it in code before expecting anything of it.
|
13
|
+
|
14
|
+
## 0.2.6
|
15
|
+
- We now use the BigSpoon library to hook into reload, because
|
16
|
+
it's SO MUCH MORE AWESOME THAN THE GARBAGE MOST PEOPLE USE.
|
17
|
+
Welp. It's been nice coding with y'all.
|
18
|
+
|
19
|
+
## 0.2.5
|
20
|
+
- PGCrypto now hooks into ActiveRecord::Base#reload in order to
|
21
|
+
reset encrypted column values as expected when calling reload.
|
22
|
+
|
23
|
+
## 0.2.2
|
24
|
+
- Don't try to load columns on new records; should further reduce
|
25
|
+
unnecessary database calls!
|
26
|
+
|
27
|
+
## 0.2.1
|
28
|
+
- Added ActiveModel::Dirty support, so you can now call *_changed?
|
29
|
+
on your models tracking pgcrypto columns.
|
30
|
+
|
31
|
+
## 0.2.0
|
32
|
+
- Overhauled key system. Unfortunately, for performance reasons
|
33
|
+
and due to the insanely hacked nature of PGCrypto, multiple keys
|
34
|
+
are NO LONGER SUPPORTED. I'm working to bring them back, but
|
35
|
+
this was the only solution to get fully performant and functional
|
36
|
+
without any disasters.
|
37
|
+
|
38
|
+
## 0.1.2
|
39
|
+
- Added automatic installation of the pgcrypto extension if'n it
|
40
|
+
doesn't already exist. Helpful, but doesn't fully make the
|
41
|
+
`rake db:test:prepare` cut yet. Still working on that bit...
|
42
|
+
|
43
|
+
## 0.1.1
|
44
|
+
- Rebuilt the WHERE clause stuff to make sure finders AND setters
|
45
|
+
both worked. It's fragile and hackish at this time, but we'll get
|
46
|
+
there, folks!
|
47
|
+
|
48
|
+
## 0.1.0
|
49
|
+
- Overhauled the underpinnings to rely on a separate column. Adds
|
50
|
+
on-demand loading of encrypted attributes from a central table
|
51
|
+
which provides dramatic speed improvements when a record's
|
52
|
+
encrypted attributes aren't needed most of the time.
|
53
|
+
|
54
|
+
## 0.0.4
|
55
|
+
- Compatibility fix between ActiveRecord ## 3.2.1 and ## 3.2.2
|
56
|
+
|
57
|
+
## 0.0.3
|
58
|
+
- Fixed a join bug on SELECT statements
|
59
|
+
|
60
|
+
## 0.0.2
|
61
|
+
- Fixed a number of key-related bugs discovered in testing with our
|
62
|
+
second production app with encrypted columns. Also duck-typed AREL
|
63
|
+
statement types in a few places.
|
64
|
+
|
65
|
+
## 0.0.1
|
66
|
+
- INSERT, SELECT, and UPDATE statements are working. But I wrote this
|
67
|
+
while testing with a production app, and thus haven't written
|
68
|
+
specific tests, so don't get your panties in a twist.
|
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.1
|
data/lib/pgcrypto.rb
CHANGED
@@ -57,6 +57,7 @@ module PGCrypto
|
|
57
57
|
remove_instance_variable("@_pgcrypto_#{column_name}") if defined?(@_pgcrypto_#{column_name})
|
58
58
|
else
|
59
59
|
@_pgcrypto_#{column_name} ||= pgcrypto_columns.select{|column| column.name == "#{column_name}"}.first || pgcrypto_columns.new(:name => "#{column_name}")
|
60
|
+
pgcrypto_columns.push(@_pgcrypto_#{column_name})
|
60
61
|
@_pgcrypto_#{column_name}.value = value
|
61
62
|
end
|
62
63
|
end
|
@@ -91,9 +92,9 @@ module PGCrypto
|
|
91
92
|
pgcrypto_column_finder = pgcrypto_columns
|
92
93
|
if key = PGCrypto.keys[:private]
|
93
94
|
pgcrypto_column_finder = pgcrypto_column_finder.select([
|
94
|
-
%("#{PGCrypto::Column.table_name}"."
|
95
|
+
%w(id owner_id owner_type owner_table).map {|column| %("#{PGCrypto::Column.table_name}"."#{column}")},
|
95
96
|
%[pgp_pub_decrypt("#{PGCrypto::Column.table_name}"."value", pgcrypto_keys.#{key.name}#{", '#{key.password}'" if key.password}) AS "value"]
|
96
|
-
]).joins(%[CROSS JOIN (SELECT #{key.dearmored} AS "#{key.name}") AS pgcrypto_keys])
|
97
|
+
].flatten).joins(%[CROSS JOIN (SELECT #{key.dearmored} AS "#{key.name}") AS pgcrypto_keys])
|
97
98
|
end
|
98
99
|
pgcrypto_column_finder.where(:name => column_name).first
|
99
100
|
rescue ActiveRecord::StatementInvalid => e
|
data/lib/pgcrypto/column.rb
CHANGED
@@ -4,6 +4,8 @@ module PGCrypto
|
|
4
4
|
before_save :set_owner_table
|
5
5
|
belongs_to :owner, :autosave => false, :inverse_of => :pgcrypto_columns, :polymorphic => true
|
6
6
|
|
7
|
+
default_scope select(%w(id owner_id owner_type owner_table))
|
8
|
+
|
7
9
|
protected
|
8
10
|
def set_owner_table
|
9
11
|
self.owner_table = self.owner.class.table_name
|
data/pgcrypto.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "pgcrypto"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Flip Sasser"]
|
12
|
-
s.date = "2012-08-
|
12
|
+
s.date = "2012-08-14"
|
13
13
|
s.description = "\n PGCrypto is an ActiveRecord::Base extension that allows you to asymmetrically\n encrypt PostgreSQL columns with as little trouble as possible. It's totally\n freaking rad.\n "
|
14
14
|
s.email = "flip@x451.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.files = [
|
20
20
|
".rspec",
|
21
21
|
".simplecov",
|
22
|
-
"CHANGES",
|
22
|
+
"CHANGES.md",
|
23
23
|
"Gemfile",
|
24
24
|
"Guardfile",
|
25
25
|
"LICENSE",
|
@@ -53,16 +53,16 @@ Gem::Specification.new do |s|
|
|
53
53
|
|
54
54
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
55
|
s.add_runtime_dependency(%q<activerecord>, [">= 3.2"])
|
56
|
-
s.add_runtime_dependency(%q<big_spoon>, [">= 0"])
|
56
|
+
s.add_runtime_dependency(%q<big_spoon>, [">= 0.2.0"])
|
57
57
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
58
58
|
else
|
59
59
|
s.add_dependency(%q<activerecord>, [">= 3.2"])
|
60
|
-
s.add_dependency(%q<big_spoon>, [">= 0"])
|
60
|
+
s.add_dependency(%q<big_spoon>, [">= 0.2.0"])
|
61
61
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
62
62
|
end
|
63
63
|
else
|
64
64
|
s.add_dependency(%q<activerecord>, [">= 3.2"])
|
65
|
-
s.add_dependency(%q<big_spoon>, [">= 0"])
|
65
|
+
s.add_dependency(%q<big_spoon>, [">= 0.2.0"])
|
66
66
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
67
67
|
end
|
68
68
|
end
|
data/spec/lib/pgcrypto_spec.rb
CHANGED
@@ -4,83 +4,98 @@ describe PGCrypto do
|
|
4
4
|
it "should extend ActiveRecord::Base" do
|
5
5
|
PGCryptoTestModel.should respond_to(:pgcrypto)
|
6
6
|
end
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
7
|
+
|
8
|
+
it "should have readers and writers" do
|
9
|
+
model = PGCryptoTestModel.new
|
10
|
+
model.should respond_to(:test_column)
|
11
|
+
model.should respond_to(:test_column=)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "be settable on create" do
|
15
|
+
model = PGCryptoTestModel.new(:test_column => 'this is a test')
|
16
|
+
model.save!.should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "be settable on update" do
|
20
|
+
model = PGCryptoTestModel.create!
|
21
|
+
model.test_column = 'this is another test'
|
22
|
+
model.save!.should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "be update-able" do
|
26
|
+
model = PGCryptoTestModel.create!(:test_column => 'i am test column')
|
27
|
+
model.update_attributes!(:test_column => 'but now i am a different column, son').should be_true
|
28
|
+
model.test_column.should == 'but now i am a different column, son'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "be retrievable at create" do
|
32
|
+
model = PGCryptoTestModel.create!(:test_column => 'i am test column')
|
33
|
+
model.test_column.should == 'i am test column'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "be retrievable after create" do
|
37
|
+
model = PGCryptoTestModel.create!(:test_column => 'i should return to you')
|
38
|
+
PGCryptoTestModel.find(model.id).test_column.should == 'i should return to you'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should be retrievable at update" do
|
42
|
+
model = PGCryptoTestModel.create!(:test_column => 'i will update')
|
43
|
+
model.test_column.should == 'i will update'
|
44
|
+
model.update_attributes!(:test_column => 'i updated')
|
45
|
+
model.test_column.should == 'i updated'
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should be retrievable without update" do
|
49
|
+
model = PGCryptoTestModel.create!(:test_column => 'i will update')
|
50
|
+
model.test_column.should == 'i will update'
|
51
|
+
model.test_column = 'i updated'
|
52
|
+
model.test_column.should == 'i updated'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "be searchable" do
|
56
|
+
model = PGCryptoTestModel.create!(:test_column => 'i am findable!')
|
57
|
+
PGCryptoTestModel.where(:test_column => model.test_column).count.should == 1
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should track changes" do
|
61
|
+
model = PGCryptoTestModel.create!(:test_column => 'i am clean')
|
62
|
+
model.test_column = "now i'm not!"
|
63
|
+
model.test_column_changed?.should be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should not be dirty if unchanged" do
|
67
|
+
model = PGCryptoTestModel.create!(:test_column => 'i am clean')
|
68
|
+
model.test_column = 'i am clean'
|
69
|
+
model.test_column_changed?.should_not be_true
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should reload with the class" do
|
73
|
+
model = PGCryptoTestModel.create!(:test_column => 'i am clean')
|
74
|
+
model.test_column = 'i am dirty'
|
75
|
+
model.reload
|
76
|
+
model.test_column.should == 'i am clean'
|
77
|
+
model.test_column_changed?.should_not be_true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should allow direct setting of values as well" do
|
81
|
+
model = PGCryptoTestModel.create!(:test_column => 'one')
|
82
|
+
model.test_column.should == 'one'
|
83
|
+
model.test_column = 'two'
|
84
|
+
model.save!.should be_true
|
85
|
+
model.select_pgcrypto_column(:test_column).value.should == 'two'
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should delete the column when I set the value to nil" do
|
89
|
+
model = PGCryptoTestModel.create!(:test_column => 'one')
|
90
|
+
model.test_column = nil
|
91
|
+
model.save!
|
92
|
+
model.select_pgcrypto_column(:test_column).should be_nil
|
93
|
+
end
|
94
|
+
|
95
|
+
it "plz work" do
|
96
|
+
model = PGCryptoTestModel.find(PGCryptoTestModel.create!(:test_column => 'one'))
|
97
|
+
model.test_column = 'two'
|
98
|
+
model.save!
|
99
|
+
model.select_pgcrypto_column(:test_column).value.should == 'two'
|
85
100
|
end
|
86
101
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -51,18 +51,15 @@ RSpec.configure do |config|
|
|
51
51
|
end
|
52
52
|
|
53
53
|
config.before :each do
|
54
|
-
|
55
|
-
|
56
|
-
DatabaseCleaner.clean_with :truncation
|
57
|
-
else
|
58
|
-
DatabaseCleaner.strategy = :transaction
|
59
|
-
end
|
54
|
+
DatabaseCleaner.strategy = :transaction
|
55
|
+
DatabaseCleaner.clean_with :transaction
|
60
56
|
DatabaseCleaner.start
|
61
57
|
|
62
58
|
ActiveRecord::Base.establish_connection(database_config)
|
63
59
|
|
64
60
|
class PGCryptoTestModel < ActiveRecord::Base
|
65
61
|
self.table_name = :pgcrypto_test_models
|
62
|
+
pgcrypto :test_column
|
66
63
|
end
|
67
64
|
end
|
68
65
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgcrypto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
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: 2012-08-
|
12
|
+
date: 2012-08-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: 0.2.0
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 0.2.0
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: jeweler
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,7 +71,7 @@ extra_rdoc_files:
|
|
71
71
|
files:
|
72
72
|
- .rspec
|
73
73
|
- .simplecov
|
74
|
-
- CHANGES
|
74
|
+
- CHANGES.md
|
75
75
|
- Gemfile
|
76
76
|
- Guardfile
|
77
77
|
- LICENSE
|
@@ -108,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
108
|
version: '0'
|
109
109
|
segments:
|
110
110
|
- 0
|
111
|
-
hash:
|
111
|
+
hash: -1773161376728593818
|
112
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
113
|
none: false
|
114
114
|
requirements:
|
data/CHANGES
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
0.2.7
|
2
|
-
* So, about that library I arrogantly included? Turns out we
|
3
|
-
should require it in code before expecting anything of it.
|
4
|
-
|
5
|
-
0.2.6
|
6
|
-
* We now use the BigSpoon library to hook into reload, because
|
7
|
-
it's SO MUCH MORE AWESOME THAN THE GARBAGE MOST PEOPLE USE.
|
8
|
-
Welp. It's been nice coding with y'all.
|
9
|
-
|
10
|
-
0.2.5
|
11
|
-
* PGCrypto now hooks into ActiveRecord::Base#reload in order to
|
12
|
-
reset encrypted column values as expected when calling reload.
|
13
|
-
|
14
|
-
0.2.2
|
15
|
-
* Don't try to load columns on new records; should further reduce
|
16
|
-
unnecessary database calls!
|
17
|
-
|
18
|
-
0.2.1
|
19
|
-
* Added ActiveModel::Dirty support, so you can now call *_changed?
|
20
|
-
on your models tracking pgcrypto columns.
|
21
|
-
|
22
|
-
0.2.0
|
23
|
-
* Overhauled key system. Unfortunately, for performance reasons
|
24
|
-
and due to the insanely hacked nature of PGCrypto, multiple keys
|
25
|
-
are NO LONGER SUPPORTED. I'm working to bring them back, but
|
26
|
-
this was the only solution to get fully performant and functional
|
27
|
-
without any disasters.
|
28
|
-
|
29
|
-
0.1.2
|
30
|
-
* Added automatic installation of the pgcrypto extension if'n it
|
31
|
-
doesn't already exist. Helpful, but doesn't fully make the
|
32
|
-
`rake db:test:prepare` cut yet. Still working on that bit...
|
33
|
-
|
34
|
-
0.1.1
|
35
|
-
* Rebuilt the WHERE clause stuff to make sure finders AND setters
|
36
|
-
both worked. It's fragile and hackish at this time, but we'll get
|
37
|
-
there, folks!
|
38
|
-
|
39
|
-
0.1.0
|
40
|
-
* Overhauled the underpinnings to rely on a separate column. Adds
|
41
|
-
on-demand loading of encrypted attributes from a central table
|
42
|
-
which provides dramatic speed improvements when a record's
|
43
|
-
encrypted attributes aren't needed most of the time.
|
44
|
-
|
45
|
-
0.0.4
|
46
|
-
* Compatibility fix between ActiveRecord 3.2.1 and 3.2.2
|
47
|
-
|
48
|
-
0.0.3
|
49
|
-
* Fixed a join bug on SELECT statements
|
50
|
-
|
51
|
-
0.0.2
|
52
|
-
* Fixed a number of key-related bugs discovered in testing with our
|
53
|
-
second production app with encrypted columns. Also duck-typed AREL
|
54
|
-
statement types in a few places.
|
55
|
-
|
56
|
-
0.0.1
|
57
|
-
* INSERT, SELECT, and UPDATE statements are working. But I wrote this
|
58
|
-
while testing with a production app, and thus haven't written
|
59
|
-
specific tests, so don't get your panties in a twist.
|