postgresqlPackages.anonymizer: 2.4.1 -> 3.2.2

Signed-off-by: Anish Pallati <i@anish.land>
This commit is contained in:
Anish Pallati
2026-09-24 04:57:51 -04:00
parent 2fea705bb3
commit 8ec241bbfa
3 changed files with 61 additions and 20 deletions

View File

@@ -82,6 +82,8 @@
- `jmtpfs` has been removed due to lack of maintenance and fuse3 support.
- `postgresqlPackages.anonymizer` has been updated from 2.4.1 to 3.2.2. The extension must be dropped and recreated, and masking no longer runs as a superuser. See the [upgrade notes](https://postgresql-anonymizer.readthedocs.io/en/stable/UPGRADE/) for details.
- `landrun` was updated to `0.1.17`, which included breaking changes, reference the [breaking changes](https://github.com/Zouuup/landrun/releases/tag/v0.1.17) section in the `landrun` release notes.
- `libgdata` has been removed, as it was archived upstream and relied on the insecure libsoup 2.4.

View File

@@ -19,7 +19,11 @@ let
nodes.machine =
{ pkgs, ... }:
{
environment.systemPackages = [ (pkgs.pg-dump-anon.override { postgresql = package; }) ];
users.users.anon_dumper = {
isSystemUser = true;
group = "anon_dumper";
};
users.groups.anon_dumper = { };
services.postgresql = {
inherit package;
enable = true;
@@ -44,6 +48,13 @@ let
insert into player(id,name,points) values (2,'Bar',42);
security label for anon on column player.name is 'MASKED WITH FUNCTION anon.fake_last_name()';
security label for anon on column player.points is 'MASKED WITH VALUE NULL';
create role anon_dumper login;
alter role anon_dumper set anon.transparent_dynamic_masking = true;
security label for anon on role anon_dumper is 'MASKED';
grant pg_read_all_data to anon_dumper;
create role player_owner;
alter table player owner to player_owner;
grant select on table anon.last_name to player_owner;
''}"
)
@@ -54,20 +65,18 @@ let
def check_anonymized_row(row, id, original_name):
t.assertEqual(row[0], id)
t.assertNotEqual(row[1], original_name)
t.assertFalse(bool(row[2]))
t.assertNotIn(row[1], (original_name, "", "\\N"))
t.assertIn(row[2], ("", "\\N"))
def find_xsv_in_dump(dump, sep=','):
"""
Expecting to find a CSV (for pg_dump_anon) or TSV (for pg_dump) structure, looking like
Expecting to find pg_dump's COPY block, looking like
COPY public.player ...
1,Shields,
2,Salazar,
<tab-separated rows, NULL written as \\N>
\\.
in the given dump (the commas are tabs in case of pg_dump).
Extract the CSV lines and split by `sep`.
in the given dump. Extract the data lines and split by `sep`.
"""
try:
@@ -100,12 +109,13 @@ let
sep='\t'
))
check_anonymized_rows(find_xsv_in_dump(
machine.succeed("sudo -u postgres pg_dump_anon -U postgres -h /run/postgresql -d demo"),
sep=','
machine.succeed("sudo -u anon_dumper pg_dump demo --no-security-labels --extension plpgsql"),
sep='\t'
))
with subtest("Anonymize"):
machine.succeed("sudo -u postgres psql -d demo --command 'select anon.anonymize_database();'")
# anon.nosuperuser forbids masking as a superuser
machine.succeed("sudo -u postgres psql -d demo --command 'set role player_owner; select anon.anonymize_database();'")
check_anonymized_rows(get_player_table_contents())
'';
}

View File

@@ -1,30 +1,59 @@
{
cargo-pgrx_0_16_0,
cargo-pgrx_0_19_0,
fetchFromGitLab,
jitSupport,
lib,
nixosTests,
pg-dump-anon,
nix-update-script,
postgresql,
buildPgrxExtension,
runtimeShell,
}:
buildPgrxExtension {
buildPgrxExtension (finalAttrs: {
pname = "postgresql_anonymizer";
version = "3.2.2";
inherit (pg-dump-anon) version src;
src = fetchFromGitLab {
owner = "dalibo";
repo = "postgresql_anonymizer";
tag = finalAttrs.version;
hash = "sha256-no457Cb6SC6ji1iUbRARP9xESgWERjy8OTtGk8hzmrU=";
};
inherit postgresql;
cargo-pgrx = cargo-pgrx_0_16_0;
cargoHash = "sha256-Z1uH6Z2qLV1Axr8dXqPznuEZcacAZnv11tb3lWBh1yw=";
cargo-pgrx = cargo-pgrx_0_19_0;
cargoHash = "sha256-xQvBdLfxnPw+lvCM+sepfUyGyGK8WI+6kqk4DVY7+s8=";
# Tries to copy extension into postgresql's store path.
doCheck = false;
passthru.tests = nixosTests.postgresql.anonymizer.passthru.override postgresql;
# the pg_config view is empty in nixpkgs, so anon.init() cannot locate its data
postPatch = ''
substituteInPlace sql/init.sql \
--replace-fail "SELECT setting AS sharedir" "SELECT '$out/share/postgresql' AS sharedir" \
--replace-fail "FROM pg_catalog.pg_config" "" \
--replace-fail "WHERE name = 'SHAREDIR'" ""
'';
# data loaded by anon.init(), installed by upstream's Makefile
postInstall = ''
install -Dm644 -t $out/share/postgresql/extension/anon data/*.csv data/en_US/fake/*.csv
'';
passthru = {
tests = nixosTests.postgresql.anonymizer.passthru.override postgresql;
updateScript = nix-update-script { };
};
meta = {
inherit (pg-dump-anon.meta) homepage maintainers license;
description = "Extension to mask or replace personally identifiable information (PII) or commercially sensitive data from a PostgreSQL database";
homepage = "https://postgresql-anonymizer.readthedocs.io/en/stable/";
changelog = "https://gitlab.com/dalibo/postgresql_anonymizer/-/blob/${finalAttrs.version}/CHANGELOG.md";
maintainers = with lib.maintainers; [
leona
osnyx
];
license = lib.licenses.postgresql;
};
}
})