From 411d8aa970005f4c98c6662c72672bdc7b0c4a77 Mon Sep 17 00:00:00 2001 From: John Gomersall Date: Mon, 29 May 2023 12:45:10 +0100 Subject: [PATCH 1/3] Update delete_user to append unique hash --- cpanfile | 1 + lib/ProductOpener/Products.pm | 25 +++++++++---------------- lib/ProductOpener/Users.pm | 3 ++- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/cpanfile b/cpanfile index 0cc6f29480c95..605e5040a1e8f 100644 --- a/cpanfile +++ b/cpanfile @@ -69,6 +69,7 @@ requires 'XML::XML2JSON'; requires 'Redis'; requires 'Digest::SHA1'; requires 'Data::Difference'; +requires 'Data::TUID'; # Mojolicious/Minion requires 'Mojolicious::Lite'; diff --git a/lib/ProductOpener/Products.pm b/lib/ProductOpener/Products.pm index 32b0fdf6c92d9..a15dd6a0430a1 100644 --- a/lib/ProductOpener/Products.pm +++ b/lib/ProductOpener/Products.pm @@ -1844,7 +1844,7 @@ we can rename it to a generic user account like openfoodfacts-contributors. # Fields that contain usernames my @users_fields = qw(editors_tags photographers_tags informers_tags correctors_tags checkers_tags weighers_tags); -sub replace_user_id_in_product ($product_id, $user_id, $new_user_id) { +sub replace_user_id_in_product ($product_id, $user_id, $new_user_id, $existing_collection) { my $path = product_path_from_id($product_id); @@ -1852,7 +1852,8 @@ sub replace_user_id_in_product ($product_id, $user_id, $new_user_id) { my $changes_ref = retrieve("$data_root/products/$path/changes.sto"); if (not defined $changes_ref) { - $changes_ref = []; + $log->warn("replace_user_id_in_products - no changes file found for " . $product_id); + return; } my $most_recent_product_ref; @@ -1925,7 +1926,7 @@ sub replace_user_id_in_product ($product_id, $user_id, $new_user_id) { } if ((defined $most_recent_product_ref) and (not $most_recent_product_ref->{deleted})) { - my $products_collection = get_products_collection(); + my $products_collection = $existing_collection // get_products_collection(); $products_collection->replace_one({"_id" => $most_recent_product_ref->{_id}}, $most_recent_product_ref, {upsert => 1}); } @@ -1964,18 +1965,9 @@ sub find_and_replace_user_id_in_products ($user_id, $new_user_id) { my $query_ref = {'$or' => $or}; - my $products_collection = get_products_collection(); - - my $count = $products_collection->count_documents($query_ref); - - $log->info( - "find_and_replace_user_id_in_products - matching products", - {user_id => $user_id, new_user_id => $new_user_id, count => $count} - ) if $log->is_info(); - - # wait to give time to display the product count - sleep(2) if $log->is_debug(); + my $products_collection = get_products_collection({timeout => 60 * 60 * 1000}); + my $count = 0; my $cursor = $products_collection->query($query_ref)->fields({_id => 1, code => 1, owner => 1}); $cursor->immortal(1); @@ -1987,10 +1979,11 @@ sub find_and_replace_user_id_in_products ($user_id, $new_user_id) { next if (not defined $product_id) or ($product_id eq ""); $log->info("find_and_replace_user_id_in_products - product_id", - {user_id => $user_id, new_user_id => $product_id, product_id => $product_id}) + {user_id => $user_id, new_user_id => $new_user_id, product_id => $product_id}) if $log->is_info(); - replace_user_id_in_product($product_id, $user_id, $new_user_id); + replace_user_id_in_product($product_id, $user_id, $new_user_id, $products_collection); + $count++; } $log->info("find_and_replace_user_id_in_products - done", diff --git a/lib/ProductOpener/Users.pm b/lib/ProductOpener/Users.pm index d0bf666c1a460..2f0fb85d8f1bc 100644 --- a/lib/ProductOpener/Users.pm +++ b/lib/ProductOpener/Users.pm @@ -91,6 +91,7 @@ use Crypt::PasswdMD5 qw(unix_md5_crypt); use Math::Random::Secure qw(irand); use Crypt::ScryptKDF qw(scrypt_hash scrypt_hash_verify); use Log::Any qw($log); +use Data::TUID qw(tuid); my @user_groups = qw(producer database app bot moderator pro_moderator); @@ -193,7 +194,7 @@ Takes in the $user_ref of the user to be deleted sub delete_user ($user_ref) { my $userid = get_string_id_for_lang("no_language", $user_ref->{userid}); - my $new_userid = "openfoodfacts-contributors"; + my $new_userid = "anonymous-" . lc(tuid length => -1); $log->info("delete_user", {userid => $userid, new_userid => $new_userid}) if $log->is_info(); From 1b731d48efbb9a10dc1cf83ce8f96cdfddcdeb5a Mon Sep 17 00:00:00 2001 From: John Gomersall Date: Mon, 29 May 2023 16:27:01 +0100 Subject: [PATCH 2/3] Switched to own-generated unique suffix --- cpanfile | 2 +- lib/ProductOpener/Users.pm | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cpanfile b/cpanfile index 605e5040a1e8f..559842c6a5905 100644 --- a/cpanfile +++ b/cpanfile @@ -9,6 +9,7 @@ requires 'LWP::UserAgent'; # libwww-perl requires 'Image::Magick'; # libimage-magick-perl requires 'XML::Encoding'; # libxml-encoding-perl requires 'MIME::Lite'; # libmime-lite-perl +requires 'MIME::Base32'; requires 'Cache::Memcached::Fast'; #libcache-memcached-fast-perl requires 'JSON'; # libjson-perl requires 'JSON::PP'; # libjson-pp-perl @@ -69,7 +70,6 @@ requires 'XML::XML2JSON'; requires 'Redis'; requires 'Digest::SHA1'; requires 'Data::Difference'; -requires 'Data::TUID'; # Mojolicious/Minion requires 'Mojolicious::Lite'; diff --git a/lib/ProductOpener/Users.pm b/lib/ProductOpener/Users.pm index 2f0fb85d8f1bc..108258cb558b9 100644 --- a/lib/ProductOpener/Users.pm +++ b/lib/ProductOpener/Users.pm @@ -91,7 +91,7 @@ use Crypt::PasswdMD5 qw(unix_md5_crypt); use Math::Random::Secure qw(irand); use Crypt::ScryptKDF qw(scrypt_hash scrypt_hash_verify); use Log::Any qw($log); -use Data::TUID qw(tuid); +use MIME::Base32 qw(encode_base32); my @user_groups = qw(producer database app bot moderator pro_moderator); @@ -194,7 +194,8 @@ Takes in the $user_ref of the user to be deleted sub delete_user ($user_ref) { my $userid = get_string_id_for_lang("no_language", $user_ref->{userid}); - my $new_userid = "anonymous-" . lc(tuid length => -1); + # Suffix is a combination of seconds since epoch plus a 16 bit random number + my $new_userid = "anonymous-" . lc(encode_base32(pack('LS', time(), rand(65536)))); $log->info("delete_user", {userid => $userid, new_userid => $new_userid}) if $log->is_info(); From ee4db726b2a362ccd513d8385c0c3f385d794030 Mon Sep 17 00:00:00 2001 From: John Gomersall Date: Mon, 29 May 2023 16:34:08 +0100 Subject: [PATCH 3/3] Make products_collection mandatory --- lib/ProductOpener/Products.pm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/ProductOpener/Products.pm b/lib/ProductOpener/Products.pm index a15dd6a0430a1..26167bc1b9986 100644 --- a/lib/ProductOpener/Products.pm +++ b/lib/ProductOpener/Products.pm @@ -1844,7 +1844,7 @@ we can rename it to a generic user account like openfoodfacts-contributors. # Fields that contain usernames my @users_fields = qw(editors_tags photographers_tags informers_tags correctors_tags checkers_tags weighers_tags); -sub replace_user_id_in_product ($product_id, $user_id, $new_user_id, $existing_collection) { +sub replace_user_id_in_product ($product_id, $user_id, $new_user_id, $products_collection) { my $path = product_path_from_id($product_id); @@ -1926,7 +1926,6 @@ sub replace_user_id_in_product ($product_id, $user_id, $new_user_id, $existing_c } if ((defined $most_recent_product_ref) and (not $most_recent_product_ref->{deleted})) { - my $products_collection = $existing_collection // get_products_collection(); $products_collection->replace_one({"_id" => $most_recent_product_ref->{_id}}, $most_recent_product_ref, {upsert => 1}); }