From dedea3b357ed643dbc96d773740dfa5067f6846b Mon Sep 17 00:00:00 2001 From: Gerhard Jungwirth Date: Fri, 10 Mar 2017 18:22:05 +0100 Subject: [PATCH] TT#4335 api reminders via subscriber login Change-Id: Ieba906d23695380600feecd82eab9e06b7a68702 --- lib/NGCP/Panel/Controller/API/Reminders.pm | 16 +++++- .../Panel/Controller/API/RemindersItem.pm | 11 ++-- lib/NGCP/Panel/Role/API/CallForwards.pm | 34 ++++------- lib/NGCP/Panel/Role/API/Reminders.pm | 57 +++++++++++++++++-- lib/NGCP/Panel/Utils/Preferences.pm | 27 +++++++++ 5 files changed, 111 insertions(+), 34 deletions(-) diff --git a/lib/NGCP/Panel/Controller/API/Reminders.pm b/lib/NGCP/Panel/Controller/API/Reminders.pm index fa5204c408..3ec34a924e 100644 --- a/lib/NGCP/Panel/Controller/API/Reminders.pm +++ b/lib/NGCP/Panel/Controller/API/Reminders.pm @@ -61,7 +61,7 @@ __PACKAGE__->config( action => { map { $_ => { ACLDetachTo => '/api/root/invalid_user', - AllowedRole => [qw/admin reseller/], + AllowedRole => [qw/admin reseller subscriberadmin subscriber/], Args => 0, Does => [qw(ACL CheckTrailingSlash RequireSSL)], Method => $_, @@ -76,6 +76,7 @@ sub auto :Private { $self->set_body($c); $self->log_request($c); + return 1; } sub GET :Allow { @@ -157,6 +158,7 @@ sub POST :Allow { last unless $resource; my $form = $self->get_form($c); + $form->field('subscriber_id')->required(0) if ($c->user->roles eq "subscriber"); last unless $self->validate_form( c => $c, resource => $resource, @@ -168,6 +170,17 @@ sub POST :Allow { return unless $sub; $resource->{subscriber_id} = $sub->provisioning_voip_subscriber->id; + my $allowed_prefs = NGCP::Panel::Utils::Preferences::get_subscriber_allowed_prefs( + c => $c, + prov_subscriber => $sub->provisioning_voip_subscriber, + pref_list => ['reminder'], + ); + unless ($allowed_prefs->{reminder}) { + $c->log->error("Not permitted to create reminder for this subscriber via subscriber profile"); + $self->error($c, HTTP_FORBIDDEN, "Not permitted to create reminder"); + return; + } + my $item; $item = $c->model('DB')->resultset('voip_reminder')->find({ subscriber_id => $resource->{subscriber_id}, @@ -205,6 +218,7 @@ sub end : Private { my ($self, $c) = @_; $self->log_response($c); + return; } 1; diff --git a/lib/NGCP/Panel/Controller/API/RemindersItem.pm b/lib/NGCP/Panel/Controller/API/RemindersItem.pm index 0850a986a2..e7121afacc 100644 --- a/lib/NGCP/Panel/Controller/API/RemindersItem.pm +++ b/lib/NGCP/Panel/Controller/API/RemindersItem.pm @@ -39,7 +39,7 @@ __PACKAGE__->config( action => { (map { $_ => { ACLDetachTo => '/api/root/invalid_user', - AllowedRole => [qw/admin reseller/], + AllowedRole => [qw/admin reseller subscriberadmin subscriber/], Args => 1, Does => [qw(ACL RequireSSL)], Method => $_, @@ -47,7 +47,7 @@ __PACKAGE__->config( } } @{ __PACKAGE__->allowed_methods }), @{ __PACKAGE__->get_journal_action_config(__PACKAGE__->resource_name,{ ACLDetachTo => '/api/root/invalid_user', - AllowedRole => [qw/admin reseller/], + AllowedRole => [qw/admin reseller subscriberadmin subscriber/], Does => [qw(ACL RequireSSL)], }) } }, @@ -59,6 +59,7 @@ sub auto :Private { $self->set_body($c); $self->log_request($c); + return 1; } sub GET :Allow { @@ -72,9 +73,8 @@ sub GET :Allow { my $response = HTTP::Response->new(HTTP_OK, undef, HTTP::Headers->new( (map { # XXX Data::HAL must be able to generate links with multiple relations - s|rel="(http://purl.org/sipwise/ngcp-api/#rel-resellers)"|rel="item $1"|; - s/rel=self/rel="item self"/; - $_ + s|rel="(http://purl.org/sipwise/ngcp-api/#rel-\w+)"|rel="item $1"|r =~ + s/rel=self/rel="item self"/r; } $hal->http_headers), ), $hal->as_json); $c->response->headers($response->headers); @@ -224,6 +224,7 @@ sub end : Private { my ($self, $c) = @_; $self->log_response($c); + return; } 1; diff --git a/lib/NGCP/Panel/Role/API/CallForwards.pm b/lib/NGCP/Panel/Role/API/CallForwards.pm index 078d1e34df..0a2c1f61eb 100644 --- a/lib/NGCP/Panel/Role/API/CallForwards.pm +++ b/lib/NGCP/Panel/Role/API/CallForwards.pm @@ -13,6 +13,7 @@ use HTTP::Status qw(:constants); use JSON::Types; use NGCP::Panel::Form::CFSimpleAPI; use NGCP::Panel::Utils::Subscriber; +use NGCP::Panel::Utils::Preferences; sub get_form { my ($self, $c) = @_; @@ -47,7 +48,11 @@ sub hal_from_item { relation => 'ngcp:'.$self->resource_name, ); - my $allowed_prefs = $self->_get_allowed_prefs($c, $prov_subs); + my $allowed_prefs = NGCP::Panel::Utils::Preferences::get_subscriber_allowed_prefs( + c => $c, + prov_subscriber => $prov_subs, + pref_list => [qw/cfu cfb cft cfna cfs/], + ); @resource{qw/cfu cfb cft cfna cfs/} = ({}) x 5; for my $item_cf ($item->provisioning_voip_subscriber->voip_cf_mappings->all) { next unless ($allowed_prefs->{$item_cf->type}); @@ -118,7 +123,11 @@ sub update_item { my $prov_subs = $item->provisioning_voip_subscriber; die "need provisioning_voip_subscriber" unless $prov_subs; my $prov_subscriber_id = $prov_subs->id; - my $allowed_prefs = $self->_get_allowed_prefs($c, $prov_subs); + my $allowed_prefs = NGCP::Panel::Utils::Preferences::get_subscriber_allowed_prefs( + c => $c, + prov_subscriber => $prov_subs, + pref_list => [qw/cfu cfb cft cfna cfs/], + ); return unless $self->validate_form( c => $c, @@ -338,26 +347,5 @@ sub _contents_from_cfm { return {times => \@times, destinations => \@destinations, sources => \@sources}; } -sub _get_allowed_prefs { - my ($self, $c, $prov_subs) = @_; - - my %allowed_prefs = map {$_ => 1} (qw/cfu cfb cft cfna cfs/); - - if ($c->user->roles eq "subscriber" || $c->user->roles eq "subscriberadmin") { - if ($prov_subs && $prov_subs->voip_subscriber_profile) { - my $profile = $prov_subs->voip_subscriber_profile; - my @allowed_attr_ids = $profile->profile_attributes - ->get_column('attribute_id')->all; - my @allowed_attrs = $c->model('DB')->resultset('voip_preferences')->search_rs({ - 'id' => { '-in' => \@allowed_attr_ids }, - 'attribute' => { '-in' => [qw/cfu cfb cft cfna cfs/]}, - })->get_column('attribute')->all; - %allowed_prefs = map {$_ => 1} @allowed_attrs; - } - } - - return \%allowed_prefs; -} - 1; # vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Role/API/Reminders.pm b/lib/NGCP/Panel/Role/API/Reminders.pm index 42a8532c41..bb08ee5a67 100644 --- a/lib/NGCP/Panel/Role/API/Reminders.pm +++ b/lib/NGCP/Panel/Role/API/Reminders.pm @@ -11,18 +11,42 @@ use NGCP::Panel::Utils::DataHal qw(); use NGCP::Panel::Utils::DataHalLink qw(); use HTTP::Status qw(:constants); use NGCP::Panel::Form::Reminder::API; +use NGCP::Panel::Utils::Preferences; sub _item_rs { my ($self, $c) = @_; my $item_rs = $c->model('DB')->resultset('voip_reminder'); - if($c->user->roles eq "admin") { - } elsif($c->user->roles eq "reseller") { + if ($c->user->roles eq "admin") { + } elsif ($c->user->roles eq "reseller") { $item_rs = $item_rs->search({ 'contact.reseller_id' => $c->user->reseller_id },{ join => { subscriber => { voip_subscriber => { contract => 'contact' } } }, }); + } elsif ($c->user->roles eq "subscriberadmin") { + $item_rs = $item_rs->search({ + 'contract.id' => $c->user->account_id, + '-or' => [ + 'voip_subscriber_profile_left.id' => undef, + 'attribute.attribute' => 'reminder', + ], + },{ + join => { subscriber => [ + { voip_subscriber => 'contract' }, + { voip_subscriber_profile_left => { profile_attributes => 'attribute' } }, + ] }, + }); + } elsif ($c->user->roles eq "subscriber") { + $item_rs = $item_rs->search({ + 'subscriber.uuid' => $c->user->uuid, + '-or' => [ + 'voip_subscriber_profile_left.id' => undef, + 'attribute.attribute' => 'reminder', + ], + },{ + join => { 'subscriber' => { voip_subscriber_profile_left => {profile_attributes => 'attribute' } } }, + }); } return $item_rs; } @@ -97,6 +121,17 @@ sub update_item { my $sub = $self->get_subscriber_by_id($c, $resource->{subscriber_id} ); return unless $sub; + my $allowed_prefs = NGCP::Panel::Utils::Preferences::get_subscriber_allowed_prefs( + c => $c, + prov_subscriber => $sub->provisioning_voip_subscriber, + pref_list => ['reminder'], + ); + unless ($allowed_prefs->{reminder}) { + $c->log->error("Not permitted to edit reminder via subscriber profile"); + $self->error($c, HTTP_FORBIDDEN, "Not permitted to edit reminder"); + return; + } + $resource->{subscriber_id} = $sub->provisioning_voip_subscriber->id; my $dup = $c->model('DB')->resultset('voip_reminder')->search({ @@ -114,26 +149,38 @@ sub update_item { return $item; } -sub get_subscriber_by_id{ +sub get_subscriber_by_id { my ($self, $c, $subscriber_id) = @_; my $sub_rs = $c->model('DB')->resultset('voip_subscribers')->search({ 'me.id' => $subscriber_id, }); - if($c->user->roles eq "reseller") { + if ($c->user->roles eq "reseller") { $sub_rs = $sub_rs->search({ 'contact.reseller_id' => $c->user->reseller_id, },{ join => { contract => 'contact' }, }); + } elsif ($c->user->roles eq "subscriberadmin") { + $sub_rs = $sub_rs->search({ + 'contract.id' => $c->user->account_id, + },{ + join => 'contract', + }); + } elsif ($c->user->roles eq "subscriber") { + # quitely override any given subscriber_id, we don't need it + $sub_rs = $c->model('DB')->resultset('voip_subscribers')->search({ + 'me.uuid' => $c->user->uuid, + }); } my $sub = $sub_rs->first; - unless($sub && $sub->provisioning_voip_subscriber) { + unless ($sub && $sub->provisioning_voip_subscriber) { $c->log->error("invalid subscriber_id '$subscriber_id'"); # TODO: user, message, trace, ... $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber does not exist"); return; } return $sub; } + 1; # vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Utils/Preferences.pm b/lib/NGCP/Panel/Utils/Preferences.pm index 63bcb57eb9..7320443eea 100644 --- a/lib/NGCP/Panel/Utils/Preferences.pm +++ b/lib/NGCP/Panel/Utils/Preferences.pm @@ -1194,6 +1194,33 @@ sub api_preferences_defs{ } return $resource; } + +sub get_subscriber_allowed_prefs { + my %params = @_; + + my $c = $params{c}; + my $schema = $params{schema} // $c->model('DB'); + my $prov_subs = $params{prov_subscriber}; + my $pref_list = $params{pref_list}; + + my %allowed_prefs = map {$_ => 1} @{ $pref_list }; + + if ($c->user->roles eq "subscriber" || $c->user->roles eq "subscriberadmin") { + if ($prov_subs && $prov_subs->voip_subscriber_profile) { + my $profile = $prov_subs->voip_subscriber_profile; + my @result = $profile->profile_attributes->search_rs({ + 'attribute.attribute' => { '-in' => $pref_list }, + },{ + join => 'attribute' + })->get_column('attribute.attribute')->all; + %allowed_prefs = map {$_ => 1} @result; + } + + } + + return \%allowed_prefs +} + 1; =head1 NAME