diff --git a/lib/NGCP/Panel/Utils/Preferences.pm b/lib/NGCP/Panel/Utils/Preferences.pm index eb77cabcae..6a57d34ed3 100644 --- a/lib/NGCP/Panel/Utils/Preferences.pm +++ b/lib/NGCP/Panel/Utils/Preferences.pm @@ -854,6 +854,33 @@ sub update_preferences { ); last SWITCH; }; + /^allowed_clis$/ && do { + if ($replace) { + #check duplicates in case of PUT + if ($resource->{$pref}) { + my %seen; + foreach my $allowed_cli (@{$resource->{$pref}}) { + next unless $seen{$allowed_cli}++; + $c->log->error("Duplicate $pref value: ".$allowed_cli); + &$err_code(HTTP_UNPROCESSABLE_ENTITY, "Duplicate $pref value: ".$allowed_cli); + return; + } + } + } + else { + #in case of PATCH, check duplicates only for new values, since there could already be duplicates in some systems + if ($resource->{$pref} && $old_resource->{$pref}) { + my @new_clis = @{$resource->{$pref}}[scalar @{$old_resource->{$pref}} .. scalar @{$resource->{$pref}} - 1]; + my %existing_clis = map {$_ => 1} @{$old_resource->{$pref}}; + my ($allowed_cli) = grep { exists $existing_clis{$_} } @new_clis; + if ( $allowed_cli ) { + $c->log->error("Duplicate $pref value: ".$allowed_cli); + &$err_code(HTTP_UNPROCESSABLE_ENTITY, "Duplicate $pref value: ".$allowed_cli); + return; + } + } + } + }; # default if($meta->max_occur != 1) { $pref_rs->delete; @@ -1626,6 +1653,33 @@ sub create_preference_form { $c->response->redirect($base_uri); return 1; } + } elsif ($attribute eq "allowed_clis") { + my $v = $form->field($attribute)->value; + my $existing_cli = $pref_rs->search({ + attribute_id => $c->stash->{preference_meta}->id, + value => $v + }); + if ($existing_cli->first) { + NGCP::Panel::Utils::Message::error( + c => $c, + error => $c->loc('Duplicate preference [_1]', $attribute), + data => \%log_data, + desc => $c->loc('Duplicate preference [_1]', $attribute), + ); + $c->response->redirect($base_uri); + return 1; + } + else { + $pref_rs->create({ + attribute_id => $c->stash->{preference_meta}->id, + value => $form->values->{$c->stash->{preference_meta}->attribute}, + }); + NGCP::Panel::Utils::Message::info( + c => $c, + data => \%log_data, + desc => $c->loc('Preference [_1] successfully created', $attribute), + ); + } } elsif ($c->stash->{preference_meta}->max_occur != 1) { if($c->stash->{subscriber} && ($c->stash->{preference_meta}->attribute eq "block_in_list" || $c->stash->{preference_meta}->attribute eq "block_out_list")) { diff --git a/t/api-rest/api-preferences.t b/t/api-rest/api-preferences.t index c6e45bfe68..08a4f087e9 100644 --- a/t/api-rest/api-preferences.t +++ b/t/api-rest/api-preferences.t @@ -154,7 +154,7 @@ foreach my $api (@apis){ (undef, $preferences_new->{content}) = $test_machine->check_item_get($preferences->{uri}); is_deeply([@{$preferences_new->{content}->{allowed_clis}}[-4..-1]], $addmulti_value, "check patched allowed_clis: add multi to absent"); - $addmulti_value = ['222','222','222','555','666']; + $addmulti_value = ['444','555','666','777','888']; $preferences_patch_op = [ {'op' => 'add', 'path' => '/allowed_clis', value => $addmulti_value, mode => 'append' }, ]; @@ -164,12 +164,12 @@ foreach my $api (@apis){ is_deeply([@{$preferences_new->{content}->{allowed_clis}}[-5..-1]], $addmulti_value, "check patched allowed_clis: add multi to existing"); $preferences_patch_op = [ - {'op' => 'remove', 'path' => '/allowed_clis', value => '222', 'index' => 2 }, + {'op' => 'remove', 'path' => '/allowed_clis', value => '222', 'index' => 1 }, ]; ($res, $preferences_put->{content}) = $test_machine->request_patch($preferences_patch_op,$preferences->{uri}); $test_machine->http_code_msg(200, "check extended patch result: remove by value", $res, $preferences_put->{content}); (undef, $preferences_new->{content}) = $test_machine->check_item_get($preferences->{uri}); - is_deeply([@{$preferences_new->{content}->{allowed_clis}}[-8..-1]], ['111','222','222','333','222','222','555','666'], "check patched allowed_clis: remove by value."); + is_deeply([@{$preferences_new->{content}->{allowed_clis}}[-8..-1]], ['111','222','333','444','555','666','777','888'], "check patched allowed_clis: remove by value."); }