Skip to content

Commit

Permalink
feat: Try parsing auth header Display
Browse files Browse the repository at this point in the history
  • Loading branch information
hangy committed Jan 28, 2024
1 parent 0e1595d commit 6f195f1
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 10 deletions.
4 changes: 0 additions & 4 deletions cgi/display.pl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
use ProductOpener::Display qw/:all/;
use ProductOpener::Users qw/:all/;
use ProductOpener::Lang qw/:all/;
use ProductOpener::API qw/:all/;

use CGI qw/:cgi :form escapeHTML/;
use URI::Escape::XS;
Expand Down Expand Up @@ -69,9 +68,6 @@
read_request_body($request_ref);
decode_json_request_body($request_ref);
}

# The API V3 requests supports Bearer Authentication headers. Copy the bearer token to request_ref for auth.
process_auth_header($request_ref, $r);
}

if (($env_query_string !~ /^\/?api\/v(3(\.\d+)?)\//) or ($request_ref->{method} !~ /^(POST|PUT|PATCH)$/)) {
Expand Down
8 changes: 4 additions & 4 deletions lib/ProductOpener/API.pm
Original file line number Diff line number Diff line change
Expand Up @@ -853,14 +853,14 @@ Reference to the Apache2 request object
=head3 Return value
None
1 if the user has been signed in, -1 if the Bearer token was invalid, 0 otherwise.
=cut

sub process_auth_header ($request_ref, $r) {
my $token = _read_auth_header($request_ref, $r);
unless ($token) {
return;
return 0;
}

my $access_token;
Expand All @@ -879,7 +879,7 @@ sub process_auth_header ($request_ref, $r) {
impact => {id => 'failure'},
}
);
return;
return -1;
}

$request_ref->{access_token} = $access_token;
Expand All @@ -904,7 +904,7 @@ sub process_auth_header ($request_ref, $r) {
param('user_session', $user_session);
init_user($request_ref);

return;
return 1;
}

=head2 _read_auth_header ( $request_ref, $r )
Expand Down
17 changes: 16 additions & 1 deletion lib/ProductOpener/Display.pm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is part of Product Opener.
#
# Product Opener
# Copyright (C) 2011-2023 Association Open Food Facts
# Copyright (C) 2011-2024 Association Open Food Facts
# Contact: [email protected]
# Address: 21 rue des Iles, 94100 Saint-Maur des Fossés, France
#
Expand Down Expand Up @@ -810,6 +810,21 @@ sub init_request ($request_ref = {}) {
}
) if $log->is_debug();

my $signed_in_oidc = process_auth_header($request_ref, $r);
if ($signed_in_oidc < 0) {
# We were sent a bad bearer token
# Otherwise we return an error page in HTML (including for v0 / v1 / v2 API queries)
if (not((defined $request_ref->{api_version}) and ($request_ref->{api_version} >= 3))
and (not($r->uri() =~ /\/cgi\/auth\.pl/)))
{
$log->debug(
"init_request - init_user error - display error page",
{init_user_error => $request_ref->{init_user_error}}
) if $log->is_debug();
display_error_and_exit($signed_in_oidc, 403);
}
}

my $error = ProductOpener::Users::init_user($request_ref);
if ($error) {
# We were sent bad user_id / password credentials
Expand Down
54 changes: 54 additions & 0 deletions tests/integration/api_v2_product_write.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
use ProductOpener::PerlStandards;

use Test::More;
use Log::Any::Adapter 'TAP';
use Log::Any qw($log);

use ProductOpener::APITest qw/:all/;
use ProductOpener::Test qw/:all/;
use ProductOpener::TestDefaults qw/:all/;
use ProductOpener::Auth qw/get_token_using_password_credentials/;

use File::Basename "dirname";

Expand All @@ -22,6 +26,9 @@ my $ua = new_client();
my %create_user_args = (%default_user_form, (email => '[email protected]'));
create_user($ua, \%create_user_args);

my $token = get_token_using_password_credentials('tests', $test_password)->{access_token};
$log->debug('test token', {token => $token}) if $log->is_debug();

# Note: expected results are stored in json files, see execute_api_tests
my $tests_ref = [
{
Expand Down Expand Up @@ -70,11 +77,58 @@ my $tests_ref = [
nutriment_sugars => '12.5',
}
},
# Test authentication - OAuth token
{
test_case => 'post-product-oauth-token',
method => 'POST',
path => '/cgi/product_jqm_multilingual.pl',
form => {
cc => "be",
lc => "fr",
code => "1234567890005",
product_name => "Product name",
categories => "Cookies",
quantity => "250 g",
serving_size => '20 g',
ingredients_text_fr => "Farine de blé, eau, sel, sucre",
labels => "Bio, Max Havelaar",
nutriment_salt => '50.2',
nutriment_salt_unit => 'mg',
nutriment_sugars => '12.5',
},
headers_in => {
'Authorization' => 'Bearer ' . $token,
},
},
{
test_case => 'get-product-auth-good-password',
method => 'GET',
path => '/api/v2/product/1234567890002',
},
{
test_case => 'post-product-auth-bad-oauth-token',
method => 'POST',
path => '/cgi/product_jqm_multilingual.pl',
form => {
cc => "be",
lc => "fr",
code => "1234567890006",
product_name => "Product name",
categories => "Cookies",
quantity => "250 g",
serving_size => '20 g',
ingredients_text_fr => "Farine de blé, eau, sel, sucre",
labels => "Bio, Max Havelaar",
nutriment_salt => '50.2',
nutriment_salt_unit => 'mg',
nutriment_sugars => '12.5',
},
headers_in => {
'Authorization' => 'Bearer 4711',
},
expected_type => "html",
expected_status_code => 403,
},
{
test_case => 'post-product-auth-bad-user-password',
method => 'POST',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"status" : 1,
"status_verbose" : "fields saved"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"code" : "1234567890017",
"files" : [
{
"code" : "1234567890017",
"filename" : "",
"name" : "1234567890017",
"thumbnailUrl" : "/images/products/123/456/789/0017/1.100.jpg",
"url" : "/product/1234567890017"
}
],
"image" : {
"crop_url" : "1.400.jpg",
"imgid" : 1,
"thumb_url" : "1.100.jpg"
},
"imagefield" : "front_en",
"imgid" : 1,
"status" : "status ok"
}
42 changes: 41 additions & 1 deletion tests/integration/upload_images.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
use ProductOpener::PerlStandards;

use Test::More;
use Log::Any::Adapter 'TAP';
use Log::Any qw($log);

use ProductOpener::APITest qw/:all/;
use ProductOpener::Test qw/:all/;
use ProductOpener::TestDefaults qw/:all/;
use ProductOpener::Auth qw/get_token_using_password_credentials/;

use File::Basename "dirname";

Expand All @@ -19,6 +23,14 @@ remove_all_products();

my $sample_products_images_path = dirname(__FILE__) . "/inputs/upload_images";

my $ua = new_client();

my %create_user_args = (%default_user_form, (email => '[email protected]'));
create_user($ua, \%create_user_args);

my $token = get_token_using_password_credentials('tests', $test_password)->{access_token};
$log->debug('test token', {token => $token}) if $log->is_debug();

my $tests_ref = [
{
test_case => 'post-product-image',
Expand Down Expand Up @@ -118,7 +130,35 @@ my $tests_ref = [
expected_status_code => 200,

},

{
test_case => 'post-product-image-good-oauth-token',
method => 'POST',
path => '/cgi/product_image_upload.pl',
form => {
code => "1234567890017",
imagefield => "front_en",
imgupload_front_en => ["$sample_products_images_path/1.jpg", '1.jpg'],
},
headers_in => {
'Authorization' => 'Bearer ' . $token,
},
expected_status_code => 200,
},
{
test_case => 'post-product-image-bad-oauth-token',
method => 'POST',
path => '/cgi/product_image_upload.pl',
form => {
code => "1234567890018",
imagefield => "front_en",
imgupload_front_en => ["$sample_products_images_path/1.jpg", '1.jpg'],
},
headers_in => {
'Authorization' => 'Bearer 4711',
},
expected_status_code => 403,
expected_type => 'html'
},
];

execute_api_tests(__FILE__, $tests_ref);
Expand Down

0 comments on commit 6f195f1

Please sign in to comment.