MT#65092 address query param string pattern match in certain endpoints

* new function Generic::Utils::parse_query_string($str) that performs
  the following:
   - escapes unescaped '%' and '_' occurrences when needed
     (as they are reserved internally for the "like" operation
   - converts all unescaped '*' and '?' chars to their "sql like op"
     '%' and '_' counterparts.
* change endpoints that used escape_search_string_pattern() to use
  parse_query_string() instead, to avoid:
    a) overescaping
    b) automatic string wrapping with '*' that prevents strict
       match
  all sql builder queries that use $q after parse_query_string()
  use returned $op ('like', '=') as the operator, to easily
  set strict or like match.

Change-Id: I961b5d032036f13a7460d91f8c197538ffba1997
(cherry picked from commit 8089861097)
mr13.5
Kirill Solomko 2 months ago
parent 3aae763172
commit 540fd925ee

@ -31,8 +31,8 @@ sub query_params {
description => 'Filter for domains matching the given pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
{ domain => { like => $q } };
my ($q, $op) = parse_search_string(shift);
{ domain => { $op => $q } };
},
second => sub { },
},

@ -25,10 +25,10 @@ sub query_params {
description => 'Filter for items (subscribers) where name or password field match given pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
my ($q, $op) = parse_search_string(shift);
return { '-or' => [
{ 'voip_fax_preference.name' => { like => $q } },
{ 'voip_fax_preference.password' => { like => $q } },
{ 'voip_fax_preference.name' => { $op => $q } },
{ 'voip_fax_preference.password' => { $op => $q } },
] };
},
second => sub {

@ -57,8 +57,8 @@ sub query_params {
description => 'Search for PBX devices matching a subscriber\'s extension pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift,0,1,1);
{ 'provisioning_voip_subscriber.pbx_extension' => { like => $q } };
my ($q, $op) = parse_search_string(shift);
{ 'provisioning_voip_subscriber.pbx_extension' => { $op => $q } };
},
second => sub {
@ -71,10 +71,10 @@ sub query_params {
description => 'Search for PBX devices matching a subscriber\'s display name pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
my ($q, $op) = parse_search_string(shift);
{
'attribute.attribute' => 'display_name',
'voip_usr_preferences.value' => { like => $q }
'voip_usr_preferences.value' => { $op => $q }
};
},

@ -27,8 +27,8 @@ sub query_params {
description => 'Filter for subscribers of contracts with a specific primary number pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift,0,1,1);
{ \['concat(primary_number.cc, primary_number.ac, primary_number.sn) like ?', $q ] };
my ($q, $op) = parse_search_string(shift);
{ \["concat(primary_number.cc, primary_number.ac, primary_number.sn) $op ?", $q ] };
},
second => sub {
@ -41,8 +41,8 @@ sub query_params {
description => 'Filter for subscribers of contracts with a specific PBX extension',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift,0,1,1);
{ 'provisioning_voip_subscriber.pbx_extension' => { like => $q } };
my ($q, $op) = parse_search_string(shift);
{ 'provisioning_voip_subscriber.pbx_extension' => { $op => $q } };
},
second => sub {
@ -55,10 +55,10 @@ sub query_params {
description => 'Filter for subscribers of contracts with a specific display name',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
my ($q, $op) = parse_search_string(shift);
{
'attribute.attribute' => 'display_name',
'voip_usr_preferences.value' => { like => $q }
'voip_usr_preferences.value' => { $op => $q }
};
},

@ -43,8 +43,8 @@ sub query_params {
description => 'Filter for profile packages containing a billing profile with specific name pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
{ 'billing_profile.name' => { like => $q } };
my ($q, $op) = parse_search_string(shift);
{ 'billing_profile.name' => { $op => $q } };
},
second => sub {
return { join => { profiles => 'billing_profile' },
@ -57,8 +57,8 @@ sub query_params {
description => 'Filter for profile packages containing a billing network with specific name pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
{ 'billing_network.name' => { like => $q } };
my ($q, $op) = parse_search_string(shift);
{ 'billing_network.name' => { $op => $q } };
},
second => sub {
return { join => { profiles => 'billing_network' },

@ -80,8 +80,8 @@ sub query_params {
description => 'Filter for subscribers in specific domain pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
return { 'domain.domain' => { like => $q } };
my ($q, $op) = parse_search_string(shift);
return { 'domain.domain' => { $op => $q } };
},
second => sub {
my $q = shift;
@ -107,8 +107,8 @@ sub query_params {
description => 'Filter for subscribers of a specific customer external_id pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
return { 'contract.external_id' => { like => $q } };
my ($q, $op) = parse_search_string(shift);
return { 'contract.external_id' => { $op => $q } };
},
second => sub {
return { join => 'contract' };
@ -120,8 +120,8 @@ sub query_params {
description => 'Filter for subscribers by subscriber\'s external_id pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
return { 'me.external_id' => { like => $q } };
my ($q, $op) = parse_search_string(shift);
return { 'me.external_id' => { $op => $q } };
},
second => sub {
return { };
@ -184,9 +184,9 @@ sub query_params {
description => 'Filter for subscribers who has specified alias pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift,0,1,1);
my ($q, $op) = parse_search_string(shift);
{
'voip_dbaliases.username' => { like => $q },
'voip_dbaliases.username' => { $op => $q },
};
},
second => sub {
@ -226,9 +226,8 @@ sub query_params {
description => 'Filter for subscribers of contracts with a specific primary number pattern',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift,0,1,1);
{ \['concat(primary_number.cc, primary_number.ac, primary_number.sn) like ?', $q ] };
my ($q, $op) = parse_search_string(shift);
{ \["concat(primary_number.cc, primary_number.ac, primary_number.sn) $op ?", $q ] };
},
second => sub {
return { join => 'primary_number' }
@ -240,8 +239,8 @@ sub query_params {
description => 'Filter for subscribers of contracts with a specific PBX extension',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift,0,1,1);
{ 'provisioning_voip_subscriber.pbx_extension' => { like => $q } };
my ($q, $op) = parse_search_string(shift);
{ 'provisioning_voip_subscriber.pbx_extension' => { $op => $q } };
},
second => sub {
@ -254,10 +253,10 @@ sub query_params {
description => 'Filter for subscribers of contracts with a specific display name',
query => {
first => sub {
my ($q,$is_pattern) = escape_search_string_pattern(shift);
my ($q, $op) = parse_search_string(shift);
{
'attribute.attribute' => 'display_name',
'voip_usr_preferences.value' => { like => $q }
'voip_usr_preferences.value' => { $op => $q }
};
},

@ -62,10 +62,9 @@ sub query_params {
description => 'Filter for the greeting type',
query => {
first => sub {
my $q = shift;
($q, my $is_pattern) = escape_search_string_pattern('/var/spool/asterisk/voicemail/*/' . $q);
my ($q, $op) = parse_search_string('/var/spool/asterisk/voicemail/*/' . shift);
return {
'me.dir' => { like => $q },
'me.dir' => { $op => $q },
};
},
second => sub {},

@ -45,10 +45,9 @@ sub query_params {
description => 'Filter for voicemails in a specific folder (one of INBOX, Old, Friends, Family, Cust1 to Cust4)',
query => {
first => sub {
my $q = shift;
($q, my $is_pattern) = escape_search_string_pattern('*/' . $q);
my ($str, $op) = parse_search_string('*/' . shift);
# join is already done in get_item_rs
{ 'me.dir' => { like => $q } };
{ 'me.dir' => { $op => $q } };
},
second => sub { },
},

@ -8,9 +8,9 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = ();
@EXPORT_OK = qw(is_int is_integer is_decimal merge compare is_false is_true get_inflated_columns_all hash2obj mime_type_to_extension extension_to_mime_type array_to_map escape_js escape_uri trim escape_search_string_pattern run_module_method get_module_var);
%EXPORT_TAGS = ( DEFAULT => [qw(&is_int &is_integer &is_decimal &merge &compare &is_false &is_true &mime_type_to_extension &extension_to_mime_type &array_to_map &escape_js &escape_uri &trim &escape_search_string_pattern &run_module_method &get_module_var)],
all => [qw(&is_int &is_integer &is_decimal &merge &compare &is_false &is_true &get_inflated_columns_all &hash2obj &mime_type_to_extension &extension_to_mime_type &array_to_map &escape_js &escape_uri &trim &escape_search_string_pattern &run_module_method &get_module_var)]);
@EXPORT_OK = qw(is_int is_integer is_decimal merge compare is_false is_true get_inflated_columns_all hash2obj mime_type_to_extension extension_to_mime_type array_to_map escape_js escape_uri trim escape_search_string_pattern parse_search_string run_module_method get_module_var);
%EXPORT_TAGS = ( DEFAULT => [qw(&is_int &is_integer &is_decimal &merge &compare &is_false &is_true &mime_type_to_extension &extension_to_mime_type &array_to_map &escape_js &escape_uri &trim &escape_search_string_pattern &parse_search_string &run_module_method &get_module_var)],
all => [qw(&is_int &is_integer &is_decimal &merge &compare &is_false &is_true &get_inflated_columns_all &hash2obj &mime_type_to_extension &extension_to_mime_type &array_to_map &escape_js &escape_uri &trim &escape_search_string_pattern &parse_search_string &run_module_method &get_module_var)]);
use Hash::Merge;
use Data::Compare qw//;
@ -263,6 +263,22 @@ sub escape_search_string_pattern {
}
sub parse_search_string {
my $str = shift;
my $has_wildcards = $str =~ /(?<!\\)[\*\?]/;
$str =~ s/(?<!\\)([%_])/\\$1/g if $has_wildcards;
my $op = (
$str =~ s/(?<!\\)\*/%/g
||
$str =~ s/(?<!\\)\?/_/g
) ? 'like' : '=';
return ($str, $op);
}
sub _load_module {
my $package_element = shift;
eval {

Loading…
Cancel
Save