Skip to content

Commit 2e9c166

Browse files
committed
Allow jsonb columns as encrtyped targets
1 parent a2b70a0 commit 2e9c166

File tree

3 files changed

+87
-7
lines changed

3 files changed

+87
-7
lines changed

sql/021-config-functions.sql

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,18 +228,25 @@ $$ LANGUAGE plpgsql;
228228

229229
DROP FUNCTION IF EXISTS cs_encrypt_v1();
230230

231-
CREATE FUNCTION cs_encrypt_v1()
231+
CREATE FUNCTION cs_encrypt_v1(force boolean DEFAULT false)
232232
RETURNS boolean
233233
AS $$
234234
BEGIN
235-
IF NOT cs_ready_for_encryption_v1() THEN
236-
RAISE EXCEPTION 'Some pending columns do not have an encrypted target';
235+
236+
IF EXISTS (SELECT FROM cs_configuration_v1 c WHERE c.state = 'encrypting') THEN
237+
RAISE EXCEPTION 'An encryption is already in progress';
237238
END IF;
238239

239240
IF NOT EXISTS (SELECT FROM cs_configuration_v1 c WHERE c.state = 'pending') THEN
240241
RAISE EXCEPTION 'No pending configuration exists to encrypt';
241242
END IF;
242243

244+
IF NOT force THEN
245+
IF NOT cs_ready_for_encryption_v1() THEN
246+
RAISE EXCEPTION 'Some pending columns do not have an encrypted target';
247+
END IF;
248+
END IF;
249+
243250
UPDATE cs_configuration_v1 SET state = 'encrypting' WHERE state = 'pending';
244251
RETURN true;
245252
END;

sql/030-encryptindex.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ AS $$
8787
LEFT JOIN information_schema.columns s ON
8888
s.table_name = c.table_name AND
8989
(s.column_name = c.column_name OR s.column_name = c.column_name || '_encrypted') AND
90-
s.domain_name = 'cs_encrypted_v1';
90+
(s.domain_name = 'cs_encrypted_v1' OR s.data_type = 'jsonb');
9191
$$ LANGUAGE sql;
9292

9393

tests/encryptindex.sql

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ $$ LANGUAGE plpgsql;
114114

115115

116116
-- -----------------------------------------------
117-
-- Start encryptindexing wwith no target table
117+
-- Start encryptindexing with no target table
118118
--
119119
-- The schema should be validated first.
120120
-- Users table does not exist, so should fail.
@@ -129,7 +129,7 @@ DO $$
129129

130130
BEGIN
131131
PERFORM cs_encrypt_v1();
132-
RAISE NOTICE 'Missinbg users table. Encrypt should have failed.';
132+
RAISE NOTICE 'Missing users table. Encrypt should have failed.';
133133
ASSERT false; -- skipped by exception
134134
EXCEPTION
135135
WHEN OTHERS THEN
@@ -143,6 +143,29 @@ DO $$
143143
$$ LANGUAGE plpgsql;
144144

145145

146+
-- -----------------------------------------------
147+
-- FORCE start encryptindexing with no target table
148+
--
149+
-- Schema validation is skipped
150+
-- -----------------------------------------------
151+
DROP TABLE IF EXISTS users;
152+
TRUNCATE TABLE cs_configuration_v1;
153+
154+
155+
DO $$
156+
BEGIN
157+
PERFORM cs_add_index_v1('users', 'name', 'match');
158+
159+
PERFORM cs_encrypt_v1(true);
160+
RAISE NOTICE 'Missing users table. Encrypt should have failed.';
161+
162+
-- configuration state should be changed
163+
ASSERT (SELECT NOT EXISTS (SELECT FROM cs_configuration_v1 c WHERE c.state = 'pending'));
164+
ASSERT (SELECT EXISTS (SELECT FROM cs_configuration_v1 c WHERE c.state = 'encrypting'));
165+
166+
END;
167+
$$ LANGUAGE plpgsql;
168+
146169

147170
-- -----------------------------------------------
148171
-- With existing active config
@@ -171,7 +194,7 @@ INSERT INTO cs_configuration_v1 (state, data) VALUES (
171194
}'::jsonb
172195
);
173196

174-
-- Create a table with multiple plaintext columns
197+
-- Create a table with plaintext and encrypted columns
175198
DROP TABLE IF EXISTS users;
176199
CREATE TABLE users
177200
(
@@ -195,6 +218,56 @@ DO $$
195218
$$ LANGUAGE plpgsql;
196219

197220

221+
-- -----------------------------------------------
222+
-- With existing active config and an updated schema using a raw JSONB column
223+
-- Start encryptindexing
224+
-- The active config is unchanged
225+
-- The pending config should now be encrypting
226+
-- -----------------------------------------------
227+
TRUNCATE TABLE cs_configuration_v1;
228+
229+
-- create an active configuration
230+
INSERT INTO cs_configuration_v1 (state, data) VALUES (
231+
'active',
232+
'{
233+
"v": 1,
234+
"tables": {
235+
"users": {
236+
"name": {
237+
"cast_as": "text",
238+
"indexes": {
239+
"unique": {}
240+
}
241+
}
242+
}
243+
}
244+
}'::jsonb
245+
);
246+
247+
-- Create a table with plaintext and jsonb column
248+
DROP TABLE IF EXISTS users;
249+
CREATE TABLE users
250+
(
251+
id bigint GENERATED ALWAYS AS IDENTITY,
252+
name TEXT,
253+
name_encrypted jsonb,
254+
PRIMARY KEY(id)
255+
);
256+
257+
258+
-- An encrypting config should exist
259+
DO $$
260+
BEGIN
261+
PERFORM cs_add_index_v1('users', 'name', 'match');
262+
PERFORM cs_encrypt_v1();
263+
264+
ASSERT (SELECT EXISTS (SELECT FROM cs_configuration_v1 c WHERE c.state = 'active'));
265+
ASSERT (SELECT EXISTS (SELECT FROM cs_configuration_v1 c WHERE c.state = 'encrypting'));
266+
ASSERT (SELECT NOT EXISTS (SELECT FROM cs_configuration_v1 c WHERE c.state = 'pending'));
267+
END;
268+
$$ LANGUAGE plpgsql;
269+
270+
198271
-- -----------------------------------------------
199272
-- With existing active config
200273
-- Activate encrypting config

0 commit comments

Comments
 (0)