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 +4 -4
- data/CHANGELOG.md +16 -0
- data/activerecord-cipherstash-pg-adapter.gemspec +1 -1
- data/lib/active_record/connection_adapters/6.1/postgres_cipherstash_adapter.rb +25 -12
- data/lib/active_record/connection_adapters/7.0/postgres_cipherstash_adapter.rb +25 -13
- data/lib/active_record/connection_adapters/cipherstash_column_mapper.rb +52 -0
- data/lib/activerecord-cipherstash-pg-adapter.rb +10 -0
- data/lib/version.rb +1 -1
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a76ecda67534aee78fe658b78c5ba3f7834f59c229b7391d75fd736d7aa4e23
|
4
|
+
data.tar.gz: 13284339b37ab578d8ce181a9c291bb4826f556caedbac55f9cc2b9cb1fb3084
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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", "
|
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
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
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
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
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
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.
|
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-
|
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.
|
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.
|
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: []
|