activerecord-cipherstash-pg-adapter 0.3.0 → 0.5.0

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
  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: []