From a7f13331e845aba1569be8d101082e3da6f5a4dc Mon Sep 17 00:00:00 2001 From: Kirill Solomko Date: Wed, 10 Jun 2026 13:55:17 +0200 Subject: [PATCH] MT#65048 check subscriber profile preferences on update * when subcsriber preferences are modified, keys are checked against a subscriber profile and if any of them is not accessible (disabled in the assigned profile) a 422 error is now raised. That is mostly relevant for PATCH "op":"add" that returned 204 OK before regardless. This change only affects access to /api/subscriberpreferences by the 'subscriber' and the 'subscriberadmin' roles * Controller::API::SubscriberPreferencesItem: remove unintended "last" from catch {}. * Utils::Preferences: remove 2 debug lines. Change-Id: Ie20e5b8d4420c814bc786c34ddd952ee13d355ae --- .../API/SubscriberPreferencesItem.pm | 3 --- lib/NGCP/Panel/Utils/Preferences.pm | 18 +++++++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/NGCP/Panel/Controller/API/SubscriberPreferencesItem.pm b/lib/NGCP/Panel/Controller/API/SubscriberPreferencesItem.pm index a7617683d2..bfc21571aa 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberPreferencesItem.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberPreferencesItem.pm @@ -88,7 +88,6 @@ sub GET :Allow { } unless ($c->has_errors) { $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', $e); - last; } } return; @@ -159,7 +158,6 @@ sub PATCH :Allow { } unless ($c->has_errors) { $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', $e); - last; } } return; @@ -226,7 +224,6 @@ sub PUT :Allow { } unless ($c->has_errors) { $self->error($c, HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', $e); - last; } } return; diff --git a/lib/NGCP/Panel/Utils/Preferences.pm b/lib/NGCP/Panel/Utils/Preferences.pm index 5982fd38ba..0c7ac71c22 100644 --- a/lib/NGCP/Panel/Utils/Preferences.pm +++ b/lib/NGCP/Panel/Utils/Preferences.pm @@ -442,6 +442,8 @@ sub update_preferences { my $reseller_id; my $full_rs; my $old_auth_prefs = {}; + my $has_profile = 0; + my %profile_allowed_attrs; if($type eq "domains") { delete $resource->{domain_id}; @@ -481,10 +483,13 @@ sub update_preferences { }); if ($elem && $elem->voip_subscriber_profile) { - my @allowed_attr_ids = $elem->voip_subscriber_profile->profile_attributes - ->get_column('attribute_id')->all; + $has_profile = 1; + %profile_allowed_attrs = + map { $_ => 1 } + $elem->voip_subscriber_profile->profile_attributes + ->get_column('attribute_id')->all; $full_rs = $full_rs->search_rs({ - 'attribute.id' => { '-in' => \@allowed_attr_ids }, + 'attribute.id' => { '-in' => [keys %profile_allowed_attrs] }, }); } } @@ -522,7 +527,6 @@ sub update_preferences { undef); my ($stmt, @bind_vals) = @{${$full_rs->as_query}}; @bind_vals = map { $_->[1]; } @bind_vals; - $c->log->debug("got contract preferences rs with sql: " . $stmt . " and bind values: " . join(",", @bind_vals)); $pref_type = 'contract_pref'; $reseller_id = $item->contact->reseller_id; } elsif($type eq "pbxdevicemodels") { @@ -726,6 +730,11 @@ sub update_preferences { return; } + if ($has_profile && !$profile_allowed_attrs{$meta->id}) { + &$err_code(HTTP_UNPROCESSABLE_ENTITY, "The entity could not be processed: A pointer that references a non-existent value (pointer: /$pref)", "requested profile preference '$pref' is not enabled"); + return; + } + try { my $vtype = ref $resource->{$pref}; my $maxlen = 128; @@ -982,7 +991,6 @@ sub update_preferences { }; my ($stmt, @bind_vals) = @{${$pref_rs->as_query}}; @bind_vals = map { $_->[1]; } @bind_vals; - $c->log->debug("preferences update rs with sql: " . $stmt . " and bind values: " . join(",", @bind_vals)); if ($meta->data_type eq 'blob') { if ($resource->{$pref}->{data} ne '#blob'){