Skip to content

Commit

Permalink
Merge pull request #1811 from openfoodfacts/issue-1810/protect-manufa…
Browse files Browse the repository at this point in the history
…cturer-data

disallow edits from apps to product data and images sent by manufacturers
  • Loading branch information
stephanegigandet authored May 29, 2019
2 parents 3dde072 + 3e88352 commit 3721cce
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 86 deletions.
12 changes: 11 additions & 1 deletion cgi/product_image_crop.pl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,17 @@
exit(0);
}

my $product_ref = process_image_crop($code, $id, $imgid, $angle, $normalize, $white_magic, $x1, $y1, $x2, $y2);
# Check if we have a picture from the manufacturer

my $product_ref = retrieve_product($code);

if ((defined $product_ref) and (has_tag($product_ref,"data_sources","producers")) and (defined $product_ref->{images}) and (defined $product_ref->{images}{$id})
and (referer() !~ /\/cgi\/product.pl/)) {
print STDERR "product_image_crop.pl - skip image id $id for product code $code (data from producer) - referer: " . referer() . "\n";
}
else {
$product_ref = process_image_crop($code, $id, $imgid, $angle, $normalize, $white_magic, $x1, $y1, $x2, $y2);
}

my $data = encode_json({ status => 'status ok',
image => {
Expand Down
193 changes: 108 additions & 85 deletions cgi/product_jqm_multilingual.pl
Original file line number Diff line number Diff line change
Expand Up @@ -171,23 +171,38 @@
}

elsif (defined param($field)) {
$product_ref->{$field} = remove_tags_and_quote(decode utf8=>param($field));

if ((defined $language_fields{$field}) and (defined $product_ref->{lc})) {
my $field_lc = $field . "_" . $product_ref->{lc};
$product_ref->{$field_lc} = $product_ref->{$field};

# Do not allow edits / removal through API for data provided by producers (only additions for non existing fields)
if ((has_tag($product_ref,"data_sources","producers")) and (defined $product_ref->{$field}) and ($product_ref->{$field} ne "")) {
print STDERR "product_jqm_multilingual.pm - code: $code - producer data already exists for field $field\n";
}
else {
$product_ref->{$field} = remove_tags_and_quote(decode utf8=>param($field));

compute_field_tags($product_ref, $lc, $field);
if ((defined $language_fields{$field}) and (defined $product_ref->{lc})) {
my $field_lc = $field . "_" . $product_ref->{lc};
$product_ref->{$field_lc} = $product_ref->{$field};
}

compute_field_tags($product_ref, $lc, $field);
}
}

if (defined $language_fields{$field}) {

foreach my $param_lang (@param_langs) {
my $field_lc = $field . '_' . $param_lang;
if (defined param($field_lc)) {
$product_ref->{$field_lc} = remove_tags_and_quote(decode utf8=>param($field_lc));
compute_field_tags($product_ref, $lc, $field_lc);

# Do not allow edits / removal through API for data provided by producers (only additions for non existing fields)
if ((has_tag($product_ref,"data_sources","producers")) and (defined $product_ref->{$field_lc}) and ($product_ref->{$field_lc} ne "")) {
print STDERR "product_jqm_multilingual.pm - code: $code - producer data already exists for field $field_lc\n";
}
else {

$product_ref->{$field_lc} = remove_tags_and_quote(decode utf8=>param($field_lc));
compute_field_tags($product_ref, $lc, $field_lc);
}
}
}
}
Expand Down Expand Up @@ -240,105 +255,113 @@
detect_allergens_from_text($product_ref);

# Nutrition data

if (defined param("no_nutrition_data")) {
$product_ref->{no_nutrition_data} = remove_tags_and_quote(decode utf8=>param("no_nutrition_data"));

# Do not allow nutrition edits through API for data provided by producers
if ((has_tag($product_ref,"data_sources","producers")) and (defined $product_ref->{"nutriments"})) {
print STDERR "product_jqm_multilingual.pm - code: $code - nutrition data provided by producer exists, skip nutrients\n";
}
else {

if (defined param("no_nutrition_data")) {
$product_ref->{no_nutrition_data} = remove_tags_and_quote(decode utf8=>param("no_nutrition_data"));
}

my $no_nutrition_data = 0;
if ((defined $product_ref->{no_nutrition_data}) and ($product_ref->{no_nutrition_data} eq 'on')) {
$no_nutrition_data = 1;
}
my $no_nutrition_data = 0;
if ((defined $product_ref->{no_nutrition_data}) and ($product_ref->{no_nutrition_data} eq 'on')) {
$no_nutrition_data = 1;
}

defined $product_ref->{nutriments} or $product_ref->{nutriments} = {};
defined $product_ref->{nutriments} or $product_ref->{nutriments} = {};

my @unknown_nutriments = ();
foreach my $nid (sort keys %{$product_ref->{nutriments}}) {
next if $nid =~ /_/;
if ((not exists $Nutriments{$nid}) and (defined $product_ref->{nutriments}{$nid . "_label"})) {
push @unknown_nutriments, $nid;
$log->debug("unknown nutrient", { nid => $nid }) if $log->is_debug();
my @unknown_nutriments = ();
foreach my $nid (sort keys %{$product_ref->{nutriments}}) {
next if $nid =~ /_/;
if ((not exists $Nutriments{$nid}) and (defined $product_ref->{nutriments}{$nid . "_label"})) {
push @unknown_nutriments, $nid;
$log->debug("unknown nutrient", { nid => $nid }) if $log->is_debug();
}
}
}

my @new_nutriments = ();
my $new_max = remove_tags_and_quote(param('new_max'));
for (my $i = 1; $i <= $new_max; $i++) {
push @new_nutriments, "new_$i";
}
my @new_nutriments = ();
my $new_max = remove_tags_and_quote(param('new_max'));
for (my $i = 1; $i <= $new_max; $i++) {
push @new_nutriments, "new_$i";
}

foreach my $nutriment (@{$nutriments_tables{$nutriment_table}}, @unknown_nutriments, @new_nutriments) {
next if $nutriment =~ /^\#/;
foreach my $nutriment (@{$nutriments_tables{$nutriment_table}}, @unknown_nutriments, @new_nutriments) {
next if $nutriment =~ /^\#/;

my $nid = $nutriment;
$nid =~ s/^(-|!)+//g;
$nid =~ s/-$//g;
my $nid = $nutriment;
$nid =~ s/^(-|!)+//g;
$nid =~ s/-$//g;

next if $nid =~ /^nutrition-score/;
next if $nid =~ /^nutrition-score/;

my $enid = encodeURIComponent($nid);
my $enid = encodeURIComponent($nid);

# do not delete values if the nutriment is not provided
next if not defined param("nutriment_${enid}");
# do not delete values if the nutriment is not provided
next if not defined param("nutriment_${enid}");

my $value = remove_tags_and_quote(decode utf8=>param("nutriment_${enid}"));
my $unit = remove_tags_and_quote(decode utf8=>param("nutriment_${enid}_unit"));
my $label = remove_tags_and_quote(decode utf8=>param("nutriment_${enid}_label"));
my $value = remove_tags_and_quote(decode utf8=>param("nutriment_${enid}"));
my $unit = remove_tags_and_quote(decode utf8=>param("nutriment_${enid}_unit"));
my $label = remove_tags_and_quote(decode utf8=>param("nutriment_${enid}_label"));

my $modifier = undef;
my $modifier = undef;

normalize_nutriment_value_and_modifier(\$value, \$modifier);
normalize_nutriment_value_and_modifier(\$value, \$modifier);

# New label?
my $new_nid = undef;
if ((defined $label) and ($label ne '')) {
$new_nid = canonicalize_nutriment($lc,$label);
$log->debug("unknown nutrient", { nid => $nid, lc => $lc, canonicalize_nutriment => $new_nid }) if $log->is_debug();
# New label?
my $new_nid = undef;
if ((defined $label) and ($label ne '')) {
$new_nid = canonicalize_nutriment($lc,$label);
$log->debug("unknown nutrient", { nid => $nid, lc => $lc, canonicalize_nutriment => $new_nid }) if $log->is_debug();

if ($new_nid ne $nid) {
delete $product_ref->{nutriments}{$nid};
delete $product_ref->{nutriments}{$nid . "_unit"};
delete $product_ref->{nutriments}{$nid . "_value"};
delete $product_ref->{nutriments}{$nid . "_modifier"};
delete $product_ref->{nutriments}{$nid . "_label"};
delete $product_ref->{nutriments}{$nid . "_100g"};
delete $product_ref->{nutriments}{$nid . "_serving"};
$log->debug("unknown nutrient, but known canonical new id", { nid => $nid, lc => $lc, canonicalize_nutriment => $new_nid }) if $log->is_debug();
$nid = $new_nid;
if ($new_nid ne $nid) {
delete $product_ref->{nutriments}{$nid};
delete $product_ref->{nutriments}{$nid . "_unit"};
delete $product_ref->{nutriments}{$nid . "_value"};
delete $product_ref->{nutriments}{$nid . "_modifier"};
delete $product_ref->{nutriments}{$nid . "_label"};
delete $product_ref->{nutriments}{$nid . "_100g"};
delete $product_ref->{nutriments}{$nid . "_serving"};
$log->debug("unknown nutrient, but known canonical new id", { nid => $nid, lc => $lc, canonicalize_nutriment => $new_nid }) if $log->is_debug();
$nid = $new_nid;
}
$product_ref->{nutriments}{$nid . "_label"} = $label;
}
$product_ref->{nutriments}{$nid . "_label"} = $label;
}

if (($nid eq '') or (not defined $value) or ($value eq '')) {
delete $product_ref->{nutriments}{$nid};
delete $product_ref->{nutriments}{$nid . "_unit"};
delete $product_ref->{nutriments}{$nid . "_value"};
delete $product_ref->{nutriments}{$nid . "_modifier"};
delete $product_ref->{nutriments}{$nid . "_label"};
delete $product_ref->{nutriments}{$nid . "_100g"};
delete $product_ref->{nutriments}{$nid . "_serving"};
}
else {
assign_nid_modifier_value_and_unit($product_ref, $nid, $modifier, $value, $unit);
if (($nid eq '') or (not defined $value) or ($value eq '')) {
delete $product_ref->{nutriments}{$nid};
delete $product_ref->{nutriments}{$nid . "_unit"};
delete $product_ref->{nutriments}{$nid . "_value"};
delete $product_ref->{nutriments}{$nid . "_modifier"};
delete $product_ref->{nutriments}{$nid . "_label"};
delete $product_ref->{nutriments}{$nid . "_100g"};
delete $product_ref->{nutriments}{$nid . "_serving"};
}
else {
assign_nid_modifier_value_and_unit($product_ref, $nid, $modifier, $value, $unit);
}
}
}

if ($no_nutrition_data) {
# Delete all non-carbon-footprint nids.
foreach my $key (keys %{$product_ref->{nutriments}}) {
next if $key =~ /_/;
next if $key eq 'carbon-footprint';

delete $product_ref->{nutriments}{$key};
delete $product_ref->{nutriments}{$key . "_unit"};
delete $product_ref->{nutriments}{$key . "_value"};
delete $product_ref->{nutriments}{$key . "_modifier"};
delete $product_ref->{nutriments}{$key . "_label"};
delete $product_ref->{nutriments}{$key . "_100g"};
delete $product_ref->{nutriments}{$key . "_serving"};
if ($no_nutrition_data) {
# Delete all non-carbon-footprint nids.
foreach my $key (keys %{$product_ref->{nutriments}}) {
next if $key =~ /_/;
next if $key eq 'carbon-footprint';

delete $product_ref->{nutriments}{$key};
delete $product_ref->{nutriments}{$key . "_unit"};
delete $product_ref->{nutriments}{$key . "_value"};
delete $product_ref->{nutriments}{$key . "_modifier"};
delete $product_ref->{nutriments}{$key . "_label"};
delete $product_ref->{nutriments}{$key . "_100g"};
delete $product_ref->{nutriments}{$key . "_serving"};
}
}
}



# Compute nutrition data per 100g and per serving

$log->trace("compute_serving_size_date") if ($admin and $log->is_trace());
Expand Down

0 comments on commit 3721cce

Please sign in to comment.