activerecord-cipherstash-pg-adapter 0.3.0 → 0.5.0

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
  SHA256:
3
- metadata.gz: 3eaa0c02e8ccecc531934417632599e4f91edcd67fed514f315ebef2bc424ee8
4
- data.tar.gz: 369c9295c615b3468421bcef9142421ac767c4dd6ef3f4a46139ce0183adc37f
3
+ metadata.gz: 1a76ecda67534aee78fe658b78c5ba3f7834f59c229b7391d75fd736d7aa4e23
4
+ data.tar.gz: 13284339b37ab578d8ce181a9c291bb4826f556caedbac55f9cc2b9cb1fb3084
5
5
  SHA512:
6
- metadata.gz: '09b55773769ab21a814208fd25058a82cad19a6c047ccbc84d4a715447bdcfade7b68e399242049e0285c26d0d22725310a02cb62fc4532621d6f095d90e6a93'
7
- data.tar.gz: a74e2ead6f0c3029725fbd2b4d1e0b76c228446b8b284a954ce737e8ae488743105baa0f356ad922d5fdedd23051d3059b2a6618cad30b507fe6a2554cc7b3b9
6
+ metadata.gz: 9644a5705b513fa4356f193995fc5b462acac8d66fba7c02031a51e3a0ad2e864865d84f561ea70ec0582129815a38920b3e557c1a29753597c86f0346c6d5df
7
+ data.tar.gz: cc240e5e9b255e4075cfc9ea13c40cf9b5715b8cd1b4a82f4dff8b98ae9112999413afaff9a10984947a2629d334868d95888e36b5ff3ea29fb82d5f29344ee4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.5.0] - 2023-04-19
4
+
5
+ ### Added
6
+
7
+ - Support for Rails credentials to set the required driver environment variables.
8
+
9
+ ### Fixed
10
+
11
+ - Hide internal CipherStash columns.
12
+
13
+ ## [0.4.0] - 2023-04-06
14
+
15
+ ### Changed
16
+
17
+ - Bump version of cipherstash-pg.
18
+
3
19
  ## [0.3.0] - 2023-04-04
4
20
  ### Added
5
21
 
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
31
31
 
32
32
  # Runtime dependencies here; dev+test go in Gemfile.
33
33
  spec.add_dependency "activerecord", ">= 6.0.0", "< 8.0.0"
34
- spec.add_dependency "cipherstash-pg", "~> 1.4.5"
34
+ spec.add_dependency "cipherstash-pg", ">= 1.0.0.beta.1"
35
35
  end
@@ -3,6 +3,7 @@
3
3
  require "active_support/core_ext/object/try"
4
4
  require "active_record/connection_adapters/abstract_adapter"
5
5
  require "active_record/connection_adapters/statement_pool"
6
+ require "active_record/connection_adapters/cipherstash_column_mapper"
6
7
 
7
8
  require_relative "./cipherstash_pg/column"
8
9
  require_relative "./cipherstash_pg/database_statements"
@@ -805,19 +806,31 @@ module ActiveRecord
805
806
  # Query implementation notes:
806
807
  # - format_type includes the column size constraint, e.g. varchar(50)
807
808
  # - ::regclass is a function that gives the id for a table name
809
+ #
810
+ # NOTE: this method has been modified from the original version that was lifted
811
+ # from ActiveRecord's PostgreSQL adapter. The query is untouched, but
812
+ # `CipherStashColumnMapper` is custom. See the docs in `CipherStashColumnMapper`
813
+ # for details.
814
+ #
815
+ # Original source:
816
+ # https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L1009-L1041
808
817
  def column_definitions(table_name)
809
- query(<<~SQL, "SCHEMA")
810
- SELECT a.attname, format_type(a.atttypid, a.atttypmod),
811
- pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
812
- c.collname, col_description(a.attrelid, a.attnum) AS comment
813
- FROM pg_attribute a
814
- LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
815
- LEFT JOIN pg_type t ON a.atttypid = t.oid
816
- LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
817
- WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
818
- AND a.attnum > 0 AND NOT a.attisdropped
819
- ORDER BY a.attnum
820
- SQL
818
+ column_definitions =
819
+ query(<<~SQL, "SCHEMA")
820
+ SELECT a.attname, format_type(a.atttypid, a.atttypmod),
821
+ pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
822
+ c.collname, col_description(a.attrelid, a.attnum) AS comment,
823
+ #{supports_virtual_columns? ? 'attgenerated' : quote('')} as attgenerated
824
+ FROM pg_attribute a
825
+ LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
826
+ LEFT JOIN pg_type t ON a.atttypid = t.oid
827
+ LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
828
+ WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
829
+ AND a.attnum > 0 AND NOT a.attisdropped
830
+ ORDER BY a.attnum
831
+ SQL
832
+
833
+ CipherStashColumnMapper.map_column_definitions(column_definitions)
821
834
  end
822
835
 
823
836
  def extract_table_ref_from_insert_sql(sql)
@@ -3,6 +3,7 @@
3
3
  require "active_support/core_ext/object/try"
4
4
  require "active_record/connection_adapters/abstract_adapter"
5
5
  require "active_record/connection_adapters/statement_pool"
6
+ require "active_record/connection_adapters/cipherstash_column_mapper"
6
7
 
7
8
  require_relative "./cipherstash_pg/column"
8
9
  require_relative "./cipherstash_pg/database_statements"
@@ -911,20 +912,31 @@ module ActiveRecord
911
912
  # Query implementation notes:
912
913
  # - format_type includes the column size constraint, e.g. varchar(50)
913
914
  # - ::regclass is a function that gives the id for a table name
915
+ #
916
+ # NOTE: this method has been modified from the original version that was lifted
917
+ # from ActiveRecord's PostgreSQL adapter. The query is untouched, but
918
+ # `CipherStashColumnMapper` is custom. See the docs in `CipherStashColumnMapper`
919
+ # for details.
920
+ #
921
+ # Original source:
922
+ # https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L1009-L1041
914
923
  def column_definitions(table_name)
915
- query(<<~SQL, "SCHEMA")
916
- SELECT a.attname, format_type(a.atttypid, a.atttypmod),
917
- pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
918
- c.collname, col_description(a.attrelid, a.attnum) AS comment,
919
- #{supports_virtual_columns? ? 'attgenerated' : quote('')} as attgenerated
920
- FROM pg_attribute a
921
- LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
922
- LEFT JOIN pg_type t ON a.atttypid = t.oid
923
- LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
924
- WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
925
- AND a.attnum > 0 AND NOT a.attisdropped
926
- ORDER BY a.attnum
927
- SQL
924
+ column_definitions =
925
+ query(<<~SQL, "SCHEMA")
926
+ SELECT a.attname, format_type(a.atttypid, a.atttypmod),
927
+ pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
928
+ c.collname, col_description(a.attrelid, a.attnum) AS comment,
929
+ #{supports_virtual_columns? ? 'attgenerated' : quote('')} as attgenerated
930
+ FROM pg_attribute a
931
+ LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
932
+ LEFT JOIN pg_type t ON a.atttypid = t.oid
933
+ LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
934
+ WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
935
+ AND a.attnum > 0 AND NOT a.attisdropped
936
+ ORDER BY a.attnum
937
+ SQL
938
+
939
+ CipherStashColumnMapper.map_column_definitions(column_definitions)
928
940
  end
929
941
 
930
942
  def extract_table_ref_from_insert_sql(sql)
@@ -0,0 +1,52 @@
1
+ require "set"
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ # A module for mapping CipherStash internal columns to columns that ActiveRecord can work with.
6
+ #
7
+ # @private
8
+ class CipherStashColumnMapper
9
+ ENCRYPTED_INDEX_COLUMN_REGEX = /^__.+_(match|ore|unique)$/
10
+ ENCRYPTED_SOURCE_COLUMN_REGEX = /^__(.+)_encrypted$/
11
+
12
+ class << self
13
+ # Maps the given column definitions by filtering out CipherStash internal columns. This method
14
+ # also adds in plaintext columns if necessary (for example, when using the driver in "encrypted"
15
+ # mode after the original plaintext columns have been dropped).
16
+ def map_column_definitions(column_definitions)
17
+ all_column_names = column_definitions.map(&:first).to_set
18
+
19
+ column_definitions
20
+ .reject { |column_definition| encrypted_index_column?(column_definition) }
21
+ .map { |column_definition| maybe_rename_source_column(column_definition, all_column_names) }
22
+ .reject { |column_definition| encrypted_source_column?(column_definition) }
23
+ end
24
+
25
+ private
26
+
27
+ def encrypted_index_column?(column_definition)
28
+ ENCRYPTED_INDEX_COLUMN_REGEX =~ column_name(column_definition)
29
+ end
30
+
31
+ def encrypted_source_column?(column_definition)
32
+ ENCRYPTED_SOURCE_COLUMN_REGEX =~ column_name(column_definition)
33
+ end
34
+
35
+ def column_name(column_definition)
36
+ column_definition.first
37
+ end
38
+
39
+ def maybe_rename_source_column(column_definition, all_column_names)
40
+ column_name, *rest = column_definition
41
+ match = column_name.match(ENCRYPTED_SOURCE_COLUMN_REGEX)
42
+
43
+ if match && !all_column_names.include?(match.captures.first)
44
+ [match.captures.first, *rest]
45
+ else
46
+ column_definition
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -11,6 +11,16 @@ module ActiveRecord
11
11
  rake_tasks do
12
12
  load "cipherstash_tasks.rake"
13
13
  end
14
+
15
+ initializer "postgres_cipherstash_adapter.configure" do
16
+ if defined?(Rails.application.credentials)
17
+ cs_credentials = Rails.application.credentials.try(:cipherstash)
18
+ ENV["CS_CLIENT_ID"] = cs_credentials&.fetch(:client_id, nil)
19
+ ENV["CS_CLIENT_KEY"] = cs_credentials&.fetch(:client_key, nil)
20
+ ENV["CS_WORKSPACE_ID"] = cs_credentials&.fetch(:workspace_id, nil)
21
+ ENV["CS_CLIENT_ACCESS_KEY"] = cs_credentials&.fetch(:client_access_key, nil)
22
+ end
23
+ end
14
24
  end
15
25
 
16
26
  # Method to install CipherStash custom ORE types
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ActiveRecord
2
- CIPHERSTASH_PG_ADAPTER_VERSION = "0.3.0"
2
+ CIPHERSTASH_PG_ADAPTER_VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-cipherstash-pg-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robin Howard
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-04 00:00:00.000000000 Z
11
+ date: 2023-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -34,16 +34,16 @@ dependencies:
34
34
  name: cipherstash-pg
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "~>"
37
+ - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 1.4.5
39
+ version: 1.0.0.beta.1
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - "~>"
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 1.4.5
46
+ version: 1.0.0.beta.1
47
47
  description: CipherStash PostgreSQL adapter for ActiveRecord.
48
48
  email:
49
49
  - robin@cipherstash.com
@@ -135,6 +135,7 @@ files:
135
135
  - lib/active_record/connection_adapters/7.0/cipherstash_pg/type_metadata.rb
136
136
  - lib/active_record/connection_adapters/7.0/cipherstash_pg/utils.rb
137
137
  - lib/active_record/connection_adapters/7.0/postgres_cipherstash_adapter.rb
138
+ - lib/active_record/connection_adapters/cipherstash_column_mapper.rb
138
139
  - lib/active_record/connection_adapters/cipherstash_pg/database_extensions.rb
139
140
  - lib/active_record/connection_adapters/cipherstash_pg/database_tasks.rb
140
141
  - lib/active_record/connection_adapters/postgres_cipherstash_adapter.rb
@@ -148,7 +149,7 @@ metadata:
148
149
  homepage_uri: https://github.com/cipherstash/activerecord-cipherstash-pg-adapter
149
150
  source_code_uri: https://github.com/cipherstash/activerecord-cipherstash-pg-adapter.git
150
151
  changelog_uri: https://github.com/cipherstash/activerecord-cipherstash-pg-adapter/blob/main/CHANGELOG.md
151
- post_install_message:
152
+ post_install_message:
152
153
  rdoc_options: []
153
154
  require_paths:
154
155
  - lib
@@ -164,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
165
  version: '0'
165
166
  requirements: []
166
167
  rubygems_version: 3.3.7
167
- signing_key:
168
+ signing_key:
168
169
  specification_version: 4
169
170
  summary: CipherStash PostgreSQL adapter for ActiveRecord.
170
171
  test_files: []