Skip to content

Commit cfe8d12

Browse files
committed
Granular errors on encrypted columnb constraint
1 parent 9154678 commit cfe8d12

File tree

1 file changed

+87
-19
lines changed

1 file changed

+87
-19
lines changed

sql/010-core.sql

Lines changed: 87 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,88 @@ BEGIN
1414
END
1515
$$;
1616

17-
DROP FUNCTION IF EXISTS _cs_encrypted_check_kind(jsonb);
18-
19-
CREATE FUNCTION _cs_encrypted_check_kind(val jsonb)
20-
RETURNS BOOLEAN
21-
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
22-
BEGIN ATOMIC
23-
RETURN (
24-
(val->>'k' = 'ct' AND val ? 'c') OR
25-
(val->>'k' = 'sv' AND val ? 'sv')
26-
) AND NOT val ? 'p';
27-
END;
17+
--
18+
-- CT payload should include a c field
19+
--
20+
DROP FUNCTION IF EXISTS _cs_encrypted_check_k_ct(jsonb);
21+
CREATE FUNCTION _cs_encrypted_check_k_ct(val jsonb)
22+
RETURNS boolean
23+
AS $$
24+
BEGIN
25+
IF (val->>'k' = 'ct' AND val ? 'c') THEN
26+
RETURN true;
27+
END IF;
28+
RAISE 'Encrypted kind (k) of "ct" missing data field (c): %', val;
29+
END;
30+
$$ LANGUAGE plpgsql;
31+
32+
--
33+
-- SV payload should include an sv field
34+
--
35+
DROP FUNCTION IF EXISTS _cs_encrypted_check_k_sv(jsonb);
36+
CREATE FUNCTION _cs_encrypted_check_k_sv(val jsonb)
37+
RETURNS boolean
38+
AS $$
39+
BEGIN
40+
IF (val->>'k' = 'sv' AND val ? 'sv') THEN
41+
RETURN true;
42+
END IF;
43+
RAISE 'Encrypted kind (k) of "sv" missing data field (sv): %', val;
44+
END;
45+
$$ LANGUAGE plpgsql;
46+
47+
48+
-- Plaintext field should never be present in an encrypted column
49+
DROP FUNCTION IF EXISTS _cs_encrypted_check_p(jsonb);
50+
CREATE FUNCTION _cs_encrypted_check_p(val jsonb)
51+
RETURNS boolean
52+
AS $$
53+
BEGIN
54+
IF NOT val ? 'p' THEN
55+
RETURN true;
56+
END IF;
57+
RAISE 'Encrypted includes plaintext (p) field: %', val;
58+
END;
59+
$$ LANGUAGE plpgsql;
60+
61+
-- Should include an ident field
62+
DROP FUNCTION IF EXISTS _cs_encrypted_check_i(jsonb);
63+
CREATE FUNCTION _cs_encrypted_check_i(val jsonb)
64+
RETURNS boolean
65+
AS $$
66+
BEGIN
67+
IF val ? 'i' THEN
68+
RETURN true;
69+
END IF;
70+
RAISE 'Encrypted missing ident (i) field: %', val;
71+
END;
72+
$$ LANGUAGE plpgsql;
73+
74+
-- Should include an ident field
75+
DROP FUNCTION IF EXISTS _cs_encrypted_check_i_ct(jsonb);
76+
CREATE FUNCTION _cs_encrypted_check_i_ct(val jsonb)
77+
RETURNS boolean
78+
AS $$
79+
BEGIN
80+
IF (val->'i' ?& array['t', 'c']) THEN
81+
RETURN true;
82+
END IF;
83+
RAISE 'Encrypted ident (i) missing table (t) or column (c) fields: %', val;
84+
END;
85+
$$ LANGUAGE plpgsql;
86+
87+
-- Should include an ident field
88+
DROP FUNCTION IF EXISTS _cs_encrypted_check_v(jsonb);
89+
CREATE FUNCTION _cs_encrypted_check_v(val jsonb)
90+
RETURNS boolean
91+
AS $$
92+
BEGIN
93+
IF (val ? 'v') THEN
94+
RETURN true;
95+
END IF;
96+
RAISE 'Encrypted missing version (v) field: %', val;
97+
END;
98+
$$ LANGUAGE plpgsql;
2899

29100

30101
DROP FUNCTION IF EXISTS cs_check_encrypted_v1(val jsonb);
@@ -34,14 +105,11 @@ CREATE FUNCTION cs_check_encrypted_v1(val jsonb)
34105
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
35106
BEGIN ATOMIC
36107
RETURN (
37-
-- version and source are required
38-
val ?& array['v'] AND
39-
40-
-- table and column
41-
val->'i' ?& array['t', 'c'] AND
42-
43-
-- plaintext or ciphertext for kind
44-
_cs_encrypted_check_kind(val)
108+
_cs_encrypted_check_v(val) AND
109+
_cs_encrypted_check_i(val) AND
110+
_cs_encrypted_check_k_ct(val) AND
111+
_cs_encrypted_check_k_sv(val) AND
112+
_cs_encrypted_check_p(val)
45113
);
46114
END;
47115

0 commit comments

Comments
 (0)