From 13d121618fe8ab49beb954a4aa744a0c75c2074f Mon Sep 17 00:00:00 2001 From: Kirill Solomko Date: Mon, 17 Dec 2018 22:49:44 +0100 Subject: [PATCH] TT#47004 Implement Header Manipulation API endpoints Change-Id: Id15f087511e6c71b4507a73cdb03caf10d3661e6 --- .../Panel/Controller/API/HeaderRuleActions.pm | 49 ++++++ .../Controller/API/HeaderRuleActionsItem.pm | 46 +++++ .../Controller/API/HeaderRuleConditions.pm | 49 ++++++ .../API/HeaderRuleConditionsItem.pm | 46 +++++ .../Panel/Controller/API/HeaderRuleSets.pm | 59 +++++++ .../Controller/API/HeaderRuleSetsItem.pm | 46 +++++ lib/NGCP/Panel/Controller/API/HeaderRules.pm | 63 +++++++ .../Panel/Controller/API/HeaderRulesItem.pm | 46 +++++ lib/NGCP/Panel/Form/Header/ActionAPI.pm | 26 +++ lib/NGCP/Panel/Form/Header/AdminRuleSetAPI.pm | 23 +++ lib/NGCP/Panel/Form/Header/ConditionAPI.pm | 43 +++++ .../Panel/Form/Header/ResellerRuleSetAPI.pm | 14 ++ lib/NGCP/Panel/Form/Header/RuleAPI.pm | 32 ++++ lib/NGCP/Panel/Role/API/HeaderRuleActions.pm | 140 +++++++++++++++ .../Panel/Role/API/HeaderRuleConditions.pm | 162 ++++++++++++++++++ lib/NGCP/Panel/Role/API/HeaderRuleSets.pm | 89 ++++++++++ lib/NGCP/Panel/Role/API/HeaderRules.pm | 92 ++++++++++ 17 files changed, 1025 insertions(+) create mode 100644 lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm create mode 100644 lib/NGCP/Panel/Controller/API/HeaderRuleActionsItem.pm create mode 100644 lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm create mode 100644 lib/NGCP/Panel/Controller/API/HeaderRuleConditionsItem.pm create mode 100644 lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm create mode 100644 lib/NGCP/Panel/Controller/API/HeaderRuleSetsItem.pm create mode 100644 lib/NGCP/Panel/Controller/API/HeaderRules.pm create mode 100644 lib/NGCP/Panel/Controller/API/HeaderRulesItem.pm create mode 100644 lib/NGCP/Panel/Form/Header/ActionAPI.pm create mode 100644 lib/NGCP/Panel/Form/Header/AdminRuleSetAPI.pm create mode 100644 lib/NGCP/Panel/Form/Header/ConditionAPI.pm create mode 100644 lib/NGCP/Panel/Form/Header/ResellerRuleSetAPI.pm create mode 100644 lib/NGCP/Panel/Form/Header/RuleAPI.pm create mode 100644 lib/NGCP/Panel/Role/API/HeaderRuleActions.pm create mode 100644 lib/NGCP/Panel/Role/API/HeaderRuleConditions.pm create mode 100644 lib/NGCP/Panel/Role/API/HeaderRuleSets.pm create mode 100644 lib/NGCP/Panel/Role/API/HeaderRules.pm diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm new file mode 100644 index 0000000000..2854c7212d --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm @@ -0,0 +1,49 @@ +package NGCP::Panel::Controller::API::HeaderRuleActions; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::HeaderManipulations; +use HTTP::Status qw(:constants); + +use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::HeaderRuleActions/; + +__PACKAGE__->set_config({ + allowed_roles => [qw/admin reseller/], +}); + +sub allowed_methods { + return [qw/GET POST OPTIONS HEAD/]; +} + +sub api_description { + return 'Defines a set of Header Manipulation Rule Actions.'; +}; + +sub query_params { + return [ + ]; +} + +sub create_item { + my ($self, $c, $resource, $form, $process_extras) = @_; + + my $item; + my $schema = $c->model('DB'); + try { + $item = $schema->resultset('voip_header_rule_actions') + ->create($resource); + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $item->rule->ruleset->id + ); + } catch($e) { + $c->log->error("failed to create a header rule actions: $e"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule actions."); + return; + } + + return $item; +} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleActionsItem.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleActionsItem.pm new file mode 100644 index 0000000000..ac44aee080 --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleActionsItem.pm @@ -0,0 +1,46 @@ +package NGCP::Panel::Controller::API::HeaderRuleActionsItem; + +use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::HeaderRuleActions/; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::HeaderManipulations; +use HTTP::Status qw(:constants); + +__PACKAGE__->set_config({ + allowed_roles => { + Default => [qw/admin reseller/], + Journal => [qw/admin reseller/], + }, + PATCH => { ops => [qw/add replace remove copy/] }, +}); + +sub allowed_methods { + return [qw/GET OPTIONS HEAD PATCH PUT DELETE/]; +} + +sub journal_query_params { + my($self,$query_params) = @_; + return $self->get_journal_query_params($query_params); +} + +sub get_journal_methods { + return [qw/handle_item_base_journal handle_journals_get handle_journalsitem_get handle_journals_options handle_journalsitem_options handle_journals_head handle_journalsitem_head/]; +} + +sub delete_item { + my ($self, $c, $item) = @_; + + my $set_id = $item->rule->ruleset->id; + my $res = $self->SUPER::delete_item($c, $item); + + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $set_id + ); + + return $res; +} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm new file mode 100644 index 0000000000..482303dc43 --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm @@ -0,0 +1,49 @@ +package NGCP::Panel::Controller::API::HeaderRuleConditions; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::HeaderManipulations; +use HTTP::Status qw(:constants); + +use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::HeaderRuleConditions/; + +__PACKAGE__->set_config({ + allowed_roles => [qw/admin reseller/], +}); + +sub allowed_methods { + return [qw/GET POST OPTIONS HEAD/]; +} + +sub api_description { + return 'Defines a set of Header Manipulation Rule Conditions.'; +}; + +sub query_params { + return [ + ]; +} + +sub create_item { + my ($self, $c, $resource, $form, $process_extras) = @_; + + my $item; + my $schema = $c->model('DB'); + try { + $item = $schema->resultset('voip_header_rule_conditions') + ->create($resource); + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $item->rule->ruleset->id + ); + } catch($e) { + $c->log->error("failed to create a header rule condition: $e"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule condition."); + return; + } + + return $item; +} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleConditionsItem.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleConditionsItem.pm new file mode 100644 index 0000000000..4cdd358cc4 --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleConditionsItem.pm @@ -0,0 +1,46 @@ +package NGCP::Panel::Controller::API::HeaderRuleConditionsItem; + +use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::HeaderRuleConditions/; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::HeaderManipulations; +use HTTP::Status qw(:constants); + +__PACKAGE__->set_config({ + allowed_roles => { + Default => [qw/admin reseller/], + Journal => [qw/admin reseller/], + }, + PATCH => { ops => [qw/add replace remove copy/] }, +}); + +sub allowed_methods { + return [qw/GET OPTIONS HEAD PATCH PUT DELETE/]; +} + +sub journal_query_params { + my($self,$query_params) = @_; + return $self->get_journal_query_params($query_params); +} + +sub get_journal_methods { + return [qw/handle_item_base_journal handle_journals_get handle_journalsitem_get handle_journals_options handle_journalsitem_options handle_journals_head handle_journalsitem_head/]; +} + +sub delete_item { + my ($self, $c, $item) = @_; + + my $set_id = $item->rule->ruleset->id; + my $res = $self->SUPER::delete_item($c, $item); + + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $set_id + ); + + return $res; +} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm new file mode 100644 index 0000000000..675c8e9a1e --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm @@ -0,0 +1,59 @@ +package NGCP::Panel::Controller::API::HeaderRuleSets; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use HTTP::Status qw(:constants); + +use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::HeaderRuleSets/; + +__PACKAGE__->set_config({ + allowed_roles => [qw/admin reseller/], +}); + +sub allowed_methods { + return [qw/GET POST OPTIONS HEAD/]; +} + +sub api_description { + return 'Defines header manipulation rule sets.'; +}; + +sub query_params { + return [ + { + param => 'reseller_id', + description => 'Filter for header rule sets of a specific reseller', + query_type => 'string_eq', + }, + { + param => 'name', + description => 'Filter for header rule sets with a specific name (wildcard pattern allowed)', + query_type => 'string_like', + }, + { + param => 'description', + description => 'Filter header rule sets for a certain description (wildcard pattern allowed).', + query_type => 'string_like', + }, + ]; +} + +sub create_item { + my ($self, $c, $resource, $form, $process_extras) = @_; + + my $item; + my $schema = $c->model('DB'); + try { + $item = $schema->resultset('voip_header_rule_sets')->create($resource); + } catch($e) { + $c->log->error("failed to create a header rule set: $e"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule set."); + return; + } + + return $item; +} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleSetsItem.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleSetsItem.pm new file mode 100644 index 0000000000..465bb3b4cd --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleSetsItem.pm @@ -0,0 +1,46 @@ +package NGCP::Panel::Controller::API::HeaderRuleSetsItem; + +use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::HeaderRuleSets/; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::HeaderManipulations; +use HTTP::Status qw(:constants); + +__PACKAGE__->set_config({ + allowed_roles => { + Default => [qw/admin reseller/], + Journal => [qw/admin reseller/], + }, + PATCH => { ops => [qw/add replace remove copy/] }, +}); + +sub allowed_methods { + return [qw/GET OPTIONS HEAD PATCH PUT DELETE/]; +} + +sub journal_query_params { + my($self,$query_params) = @_; + return $self->get_journal_query_params($query_params); +} + +sub get_journal_methods { + return [qw/handle_item_base_journal handle_journals_get handle_journalsitem_get handle_journals_options handle_journalsitem_options handle_journals_head handle_journalsitem_head/]; +} + +sub delete_item { + my ($self, $c, $item) = @_; + + my $set_id = $item->id; + my $res = $self->SUPER::delete_item($c, $item); + + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $set_id + ); + + return $res; +} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/HeaderRules.pm b/lib/NGCP/Panel/Controller/API/HeaderRules.pm new file mode 100644 index 0000000000..d0772e8621 --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/HeaderRules.pm @@ -0,0 +1,63 @@ +package NGCP::Panel::Controller::API::HeaderRules; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::HeaderManipulations; +use HTTP::Status qw(:constants); + +use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::HeaderRules/; + +__PACKAGE__->set_config({ + allowed_roles => [qw/admin reseller/], +}); + +sub allowed_methods { + return [qw/GET POST OPTIONS HEAD/]; +} + +sub api_description { + return 'Defines a set of Header Manipulation Rules.'; +}; + +sub query_params { + return [ + { + param => 'name', + description => 'Filter for header rules with a specific name (wildcard pattern allowed)', + query_type => 'string_like', + }, + { + param => 'description', + description => 'Filter rules for a certain description (wildcards possible).', + query_type => 'string_like', + }, + { + param => 'set_id', + description => 'Filter for rules belonging to a specific header rule set.', + query_type => 'string_eq', + }, + ]; +} + +sub create_item { + my ($self, $c, $resource, $form, $process_extras) = @_; + + my $item; + my $schema = $c->model('DB'); + try { + $item = $schema->resultset('voip_header_rules')->create($resource); + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $item->ruleset->id + ); + } catch($e) { + $c->log->error("failed to create a header rule: $e"); + $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create a header rule."); + return; + } + + return $item; +} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/HeaderRulesItem.pm b/lib/NGCP/Panel/Controller/API/HeaderRulesItem.pm new file mode 100644 index 0000000000..d3216db605 --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/HeaderRulesItem.pm @@ -0,0 +1,46 @@ +package NGCP::Panel::Controller::API::HeaderRulesItem; + +use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::HeaderRules/; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::HeaderManipulations; +use HTTP::Status qw(:constants); + +__PACKAGE__->set_config({ + allowed_roles => { + Default => [qw/admin reseller/], + Journal => [qw/admin reseller/], + }, + PATCH => { ops => [qw/add replace remove copy/] }, +}); + +sub allowed_methods { + return [qw/GET OPTIONS HEAD PATCH PUT DELETE/]; +} + +sub journal_query_params { + my($self,$query_params) = @_; + return $self->get_journal_query_params($query_params); +} + +sub get_journal_methods { + return [qw/handle_item_base_journal handle_journals_get handle_journalsitem_get handle_journals_options handle_journalsitem_options handle_journals_head handle_journalsitem_head/]; +} + +sub delete_item { + my ($self, $c, $item) = @_; + + my $set_id = $item->ruleset->id; + my $res = $self->SUPER::delete_item($c, $item); + + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $set_id + ); + + return $res; +} + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/Header/ActionAPI.pm b/lib/NGCP/Panel/Form/Header/ActionAPI.pm new file mode 100644 index 0000000000..3fdcfcc514 --- /dev/null +++ b/lib/NGCP/Panel/Form/Header/ActionAPI.pm @@ -0,0 +1,26 @@ +package NGCP::Panel::Form::Header::ActionAPI; + +use HTML::FormHandler::Moose; +extends 'NGCP::Panel::Form::Header::Action'; + +has_field 'rwr_dp' => ( + type => 'Select', + options => [ + { value => '' }, + { value => 'caller_in' }, + { value => 'callee_in' }, + { value => 'caller_out' }, + { value => 'callee_out' }, + ], + required => 0, +); + +has_block 'fields' => ( + tag => 'div', + class => [qw/modal-body/], + render_list => [qw/rule_id header header_part action_type value_part value rwr_set_id rwr_dp enabled/ ], +); + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/Header/AdminRuleSetAPI.pm b/lib/NGCP/Panel/Form/Header/AdminRuleSetAPI.pm new file mode 100644 index 0000000000..1370f96ca0 --- /dev/null +++ b/lib/NGCP/Panel/Form/Header/AdminRuleSetAPI.pm @@ -0,0 +1,23 @@ +package NGCP::Panel::Form::Header::AdminRuleSetAPI; + +use HTML::FormHandler::Moose; +extends 'NGCP::Panel::Form::Header::ResellerRuleSet'; + +has_field 'reseller_id' => ( + type => 'PosInteger', + required => 1, + element_attr => { + rel => ['tooltip'], + title => ['The reseller who can use the Ruleset.'], + }, +); + +has_block 'fields' => ( + tag => 'div', + class => [qw/modal-body/], + render_list => [qw/reseller_id name description/], +); + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/Header/ConditionAPI.pm b/lib/NGCP/Panel/Form/Header/ConditionAPI.pm new file mode 100644 index 0000000000..ee15175c8d --- /dev/null +++ b/lib/NGCP/Panel/Form/Header/ConditionAPI.pm @@ -0,0 +1,43 @@ +package NGCP::Panel::Form::Header::ConditionAPI; + +use HTML::FormHandler::Moose; +extends 'NGCP::Panel::Form::Header::Condition'; + +has_field 'rwr_dp' => ( + type => 'Select', + options => [ + { value => '' }, + { value => 'caller_in' }, + { value => 'callee_in' }, + { value => 'caller_out' }, + { value => 'callee_out' }, + ], + required => 0, +); + +has_field 'values' => ( + type => 'Repeatable', + element_attr => { + rel => ['tooltip'], + title => ['An array of values.'], + }, +); + +has_field 'values.condition_id' => ( + type => 'Hidden', +); + +has_field 'values.value' => ( + type => 'Text', + label => 'Source', +); + +has_block 'fields' => ( + tag => 'div', + class => [qw/modal-body/], + render_list => [qw/match_type match_part match_name expression expression_negation value_type rule_id rwr_set_id rwr_dp enabled values/ ], +); + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/Header/ResellerRuleSetAPI.pm b/lib/NGCP/Panel/Form/Header/ResellerRuleSetAPI.pm new file mode 100644 index 0000000000..c23b0a3848 --- /dev/null +++ b/lib/NGCP/Panel/Form/Header/ResellerRuleSetAPI.pm @@ -0,0 +1,14 @@ +package NGCP::Panel::Form::Header::ResellerRuleSetAPI; + +use HTML::FormHandler::Moose; +extends 'NGCP::Panel::Form::Header::ResellerRuleSet'; + +has_block 'fields' => ( + tag => 'div', + class => [qw/modal-body/], + render_list => [qw/name description/], +); + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Form/Header/RuleAPI.pm b/lib/NGCP/Panel/Form/Header/RuleAPI.pm new file mode 100644 index 0000000000..c2a13158f3 --- /dev/null +++ b/lib/NGCP/Panel/Form/Header/RuleAPI.pm @@ -0,0 +1,32 @@ +package NGCP::Panel::Form::Header::RuleAPI; + +use HTML::FormHandler::Moose; +extends 'NGCP::Panel::Form::Header::Rule'; + +has_field 'set_id' => ( + type => 'PosInteger', + required => 1, + element_attr => { + rel => ['tooltip'], + title => ['Header rule set id, one the rule must belong to.'], + }, +); + +has_field 'priority' => ( + type => 'PosInteger', + required => 1, + element_attr => { + rel => ['tooltip'], + title => ['Header rule priority, smaller value has the higher priority.'], + }, +); + +has_block 'fields' => ( + tag => 'div', + class => [qw/modal-body/], + render_list => [qw/name direction description stopper enabled set_id priority/], +); + +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Role/API/HeaderRuleActions.pm b/lib/NGCP/Panel/Role/API/HeaderRuleActions.pm new file mode 100644 index 0000000000..68d266382b --- /dev/null +++ b/lib/NGCP/Panel/Role/API/HeaderRuleActions.pm @@ -0,0 +1,140 @@ +package NGCP::Panel::Role::API::HeaderRuleActions; + +use parent qw/NGCP::Panel::Role::API/; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::API; +use HTTP::Status qw(:constants); + +sub item_name { + return 'headerruleaction'; +} + +sub resource_name { + return 'headerruleactions'; +} + +sub config_allowed_roles { + return [qw/admin reseller/]; +} + +sub _item_rs { + my ($self, $c, $type) = @_; + my $item_rs; + + if ($c->user->roles eq "admin") { + $item_rs = $c->model('DB')->resultset('voip_header_rule_actions'); + } elsif ($c->user->roles eq "reseller") { + $item_rs = $c->model('DB')->resultset('voip_header_rule_actions')->search_rs({ + 'ruleset.reseller_id' => $c->user->reseller_id, + },{ + join => { rule => 'ruleset' }, + }); + } + return $item_rs; +} + +sub get_form { + my ($self, $c) = @_; + return ( NGCP::Panel::Form::get("NGCP::Panel::Form::Header::ActionAPI", $c) ); +} + +sub hal_links { + my ($self, $c, $item, $resource, $form) = @_; + return [ + Data::HAL::Link->new(relation => "ngcp:headerrulesets", href => sprintf("/api/headerrulesets/%d", $item->rule->set_id)), + Data::HAL::Link->new(relation => "ngcp:headerrules", href => sprintf("/api/headerrules/%d", $item->rule->id)), + ]; +} + +sub post_process_hal_resource { + my ($self, $c, $item, $resource, $form) = @_; + my $dp_id = delete $resource->{rwr_dp_id}; + if ($item->rwr_set) { + my %rwr_set_cols = $item->rwr_set->get_inflated_columns; + foreach my $dp_t (qw(callee_in callee_out caller_in caller_out)) { + my $c_dp_id = $rwr_set_cols{$dp_t.'_dpid'} // next; + if ($c_dp_id == $dp_id) { + $resource->{rwr_dp} = $dp_t; + last; + } + } + } + return $resource; +} + +sub check_resource { + my ($self, $c, $item, $old_resource, $resource, $form, $process_extras) = @_; + my $schema = $c->model('DB'); + + unless (defined $resource->{rule_id}) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Required: 'rule_id'"); + return; + } + + my $reseller_id; + if ($c->user->roles eq "reseller") { + $reseller_id = $c->user->reseller_id; + } + + my $rule = $schema->resultset('voip_header_rules')->find({ + id => $resource->{rule_id}, + ($reseller_id ? ('ruleset.reseller_id' => $reseller_id) : ()), + },{ + join => 'ruleset', + }); + unless ($rule) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'rule_id'."); + return; + } + return 1 unless $resource->{rwr_set_id}; + + my $rwr_set = $schema->resultset('voip_rewrite_rule_sets')->find({ + id => $resource->{rwr_set_id}, + ($reseller_id ? ('ruleset.reseller_id' => $reseller_id) : ()), + }); + unless ($rwr_set) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'rwr_set_id'."); + return; + } + unless ($resource->{rwr_dp} || $resource->{rwr_dp_id}) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Missing 'rwr_dp' (when rwr_set_id is set)."); + return; + } + + my %rwr_set_cols = $rwr_set->get_inflated_columns; + + # normally when resource already exists, + # so to check if rwr_dp_id belongs to the same rwr_set + # if somehow it is forcibly passed as a wrong value + if ($resource->{rwr_dp_id}) { + foreach my $dp_t (qw(callee_in callee_out caller_in caller_out)) { + my $c_dp_id = $rwr_set_cols{$dp_t.'_dpid'} // next; + return 1 if $c_dp_id == $resource->{rwr_dp_id}; + } + # the provided rwr_dp_id does not belong to the rwr_set + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'rwr_dp_id' (does not belong to the rwr_set_id)."); + return; + } else { + my $rwr_dp = delete $resource->{rwr_dp}; + $resource->{rwr_dp_id} = $rwr_set_cols{$rwr_dp.'_dpid'}; + } + + return 1; +} + +sub update_item_model { + my ($self, $c, $item, $old_resource, $resource, $form) = @_; + + $item = $self->SUPER::update_item_model($c, $item, $old_resource, $resource, $form); + + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $item->rule->ruleset->id + ); + + return $item; +} + +1; +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Role/API/HeaderRuleConditions.pm b/lib/NGCP/Panel/Role/API/HeaderRuleConditions.pm new file mode 100644 index 0000000000..fd98b3ecad --- /dev/null +++ b/lib/NGCP/Panel/Role/API/HeaderRuleConditions.pm @@ -0,0 +1,162 @@ +package NGCP::Panel::Role::API::HeaderRuleConditions; + +use parent qw/NGCP::Panel::Role::API/; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::HeaderManipulations; +use NGCP::Panel::Utils::API; +use HTTP::Status qw(:constants); + +sub item_name { + return 'headerrulecondition'; +} + +sub resource_name { + return 'headerruleconditions'; +} + +sub config_allowed_roles { + return [qw/admin reseller/]; +} + +sub _item_rs { + my ($self, $c, $type) = @_; + my $item_rs; + + if ($c->user->roles eq "admin") { + $item_rs = $c->model('DB')->resultset('voip_header_rule_conditions'); + } elsif ($c->user->roles eq "reseller") { + $item_rs = $c->model('DB')->resultset('voip_header_rule_conditions')->search_rs({ + 'ruleset.reseller_id' => $c->user->reseller_id, + },{ + join => { rule => 'ruleset' }, + }); + } + return $item_rs; +} + +sub get_form { + my ($self, $c) = @_; + return ( NGCP::Panel::Form::get("NGCP::Panel::Form::Header::ConditionAPI", $c) ); +} + +sub hal_links { + my ($self, $c, $item, $resource, $form) = @_; + return [ + Data::HAL::Link->new(relation => "ngcp:headerrulesets", href => sprintf("/api/headerrulesets/%d", $item->rule->set_id)), + Data::HAL::Link->new(relation => "ngcp:headerrules", href => sprintf("/api/headerrules/%d", $item->rule->id)), + ]; +} + +sub post_process_hal_resource { + my ($self, $c, $item, $resource, $form) = @_; + my $dp_id = delete $resource->{rwr_dp_id}; + my @values = (); + if ($item->rwr_set) { + my %rwr_set_cols = $item->rwr_set->get_inflated_columns; + foreach my $dp_t (qw(callee_in callee_out caller_in caller_out)) { + my $c_dp_id = $rwr_set_cols{$dp_t.'_dpid'} // next; + if ($c_dp_id == $dp_id) { + $resource->{rwr_dp} = $dp_t; + last; + } + } + } + foreach my $r ($item->values->all) { + push @values, $r->value; + } + $resource->{values} = \@values; + return $resource; +} + +sub resource_from_item { + my ($self, $c, $item, $form) = @_; + + my %resource = $item->get_inflated_columns; + my @values = (); + + foreach my $r ($item->values->all) { + push @values, { $r->get_inflated_columns }; + } + $resource{values} = \@values; + + return \%resource; +} + +sub check_resource { + my ($self, $c, $item, $old_resource, $resource, $form, $process_extras) = @_; + my $schema = $c->model('DB'); + + unless (defined $resource->{rule_id}) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Required: 'rule_id'"); + return; + } + + my $reseller_id; + if ($c->user->roles eq "reseller") { + $reseller_id = $c->user->reseller_id; + } + + my $rule = $schema->resultset('voip_header_rules')->find({ + id => $resource->{rule_id}, + ($reseller_id ? ('ruleset.reseller_id' => $reseller_id) : ()), + },{ + join => 'ruleset', + }); + unless ($rule) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'rule_id'."); + return; + } + return 1 unless $resource->{rwr_set_id}; + + my $rwr_set = $schema->resultset('voip_rewrite_rule_sets')->find({ + id => $resource->{rwr_set_id}, + ($reseller_id ? ('ruleset.reseller_id' => $reseller_id) : ()), + }); + unless ($rwr_set) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'rwr_set_id'."); + return; + } + unless ($resource->{rwr_dp} || $resource->{rwr_dp_id}) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Missing 'rwr_dp' (when rwr_set_id is set)."); + return; + } + + my %rwr_set_cols = $rwr_set->get_inflated_columns; + + # normally when resource already exists, + # so to check if rwr_dp_id belongs to the same rwr_set + # if somehow it is forcibly passed as a wrong value + if ($resource->{rwr_dp_id}) { + foreach my $dp_t (qw(callee_in callee_out caller_in caller_out)) { + my $c_dp_id = $rwr_set_cols{$dp_t.'_dpid'} // next; + return 1 if $c_dp_id == $resource->{rwr_dp_id}; + } + # the provided rwr_dp_id does not belong to the rwr_set + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'rwr_dp_id' (does not belong to the rwr_set_id)."); + return; + } else { + my $rwr_dp = delete $resource->{rwr_dp}; + $resource->{rwr_dp_id} = $rwr_set_cols{$rwr_dp.'_dpid'}; + } + + return 1; +} + +sub update_item_model { + my ($self, $c, $item, $old_resource, $resource, $form) = @_; + + NGCP::Panel::Utils::HeaderManipulations::update_condition( + c => $c, resource => $resource, item => $item + ); + + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $item->rule->ruleset->id + ); + + return $item; +} + +1; +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Role/API/HeaderRuleSets.pm b/lib/NGCP/Panel/Role/API/HeaderRuleSets.pm new file mode 100644 index 0000000000..7f72492a88 --- /dev/null +++ b/lib/NGCP/Panel/Role/API/HeaderRuleSets.pm @@ -0,0 +1,89 @@ +package NGCP::Panel::Role::API::HeaderRuleSets; + +use parent qw/NGCP::Panel::Role::API/; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::API; +use NGCP::Panel::Utils::HeaderManipulations; +use HTTP::Status qw(:constants); + +sub item_name { + return 'headerruleset'; +} + +sub resource_name { + return 'headerrulesets'; +} + +sub get_form { + my ($self, $c, $type) = @_; + + if ($c->user->roles eq "admin") { + return (NGCP::Panel::Form::get("NGCP::Panel::Form::Header::AdminRuleSetAPI", $c)); + } else { + return (NGCP::Panel::Form::get("NGCP::Panel::Form::Header::ResellerRuleSetAPI", $c)); + } +} + +sub _item_rs { + my ($self, $c, $type) = @_; + my $item_rs; + + if ($c->user->roles eq "admin") { + $item_rs = $c->model('DB')->resultset('voip_header_rule_sets'); + } elsif ($c->user->roles eq "reseller") { + $item_rs = $c->model('DB')->resultset('voip_header_rule_sets') + ->search_rs({reseller_id => $c->user->reseller_id}); + } + return $item_rs; +} + +sub process_form_resource { + my ($self,$c, $item, $old_resource, $resource, $form, $process_extras) = @_; + NGCP::Panel::Utils::API::apply_resource_reseller_id($c, $resource); + return $resource; +} + +sub check_resource { + my ($self, $c, $item, $old_resource, $resource, $form, $process_extras) = @_; + my $schema = $c->model('DB'); + if (!$old_resource || ( $old_resource->{reseller_id} != $resource->{reseller_id}) ) { + my $reseller = $c->model('DB')->resultset('resellers') + ->find($resource->{reseller_id}); + unless($reseller) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'reseller_id'"); + return; + } + } + return 1; +} + +sub check_duplicate { + my ($self, $c, $item, $old_resource, $resource, $form, $process_extras) = @_; + + my $schema = $c->model('DB'); + my $existing_item = $schema->resultset('voip_header_rule_sets')->search_rs({ + name => $resource->{name} + })->first; + if ($existing_item && (!$item || $item->id != $existing_item->id)) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Header manipulation rule set with this 'name' already exists."); + return; + } + return 1; +} + +sub update_item_model { + my ($self, $c, $item, $old_resource, $resource, $form) = @_; + + $item = $self->SUPER::update_item_model($c, $item, $old_resource, $resource, $form); + + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $item->id + ); + + return $item; +} + +1; +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Role/API/HeaderRules.pm b/lib/NGCP/Panel/Role/API/HeaderRules.pm new file mode 100644 index 0000000000..1ef5186bb1 --- /dev/null +++ b/lib/NGCP/Panel/Role/API/HeaderRules.pm @@ -0,0 +1,92 @@ +package NGCP::Panel::Role::API::HeaderRules; + +use parent qw/NGCP::Panel::Role::API/; + +use Sipwise::Base; +use NGCP::Panel::Utils::Generic qw(:all); +use NGCP::Panel::Utils::API; +use NGCP::Panel::Utils::HeaderManipulations; +use HTTP::Status qw(:constants); + +sub item_name { + return 'headerrule'; +} + +sub resource_name { + return 'headerrules'; +} + +sub config_allowed_roles { + return [qw/admin reseller/]; +} + +sub _item_rs { + my ($self, $c, $type) = @_; + my $item_rs; + + if ($c->user->roles eq "admin") { + $item_rs = $c->model('DB')->resultset('voip_header_rules'); + } elsif ($c->user->roles eq "reseller") { + $item_rs = $c->model('DB')->resultset('voip_header_rules')->search_rs({ + 'ruleset.reseller_id' => $c->user->reseller_id, + },{ + join => 'ruleset' + }); + } + return $item_rs; +} + +sub get_form { + my ($self, $c) = @_; + return ( NGCP::Panel::Form::get("NGCP::Panel::Form::Header::RuleAPI", $c) ); +} + +sub hal_links { + my ($self, $c, $item, $resource, $form) = @_; + return [ + Data::HAL::Link->new(relation => "ngcp:headerrulesets", href => sprintf("/api/headerrulesets/%d", $item->set_id)), + ]; +} + +sub check_resource { + my ($self, $c, $item, $old_resource, $resource, $form, $process_extras) = @_; + my $schema = $c->model('DB'); + + unless (defined $resource->{set_id}) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Required: 'set_id'"); + return; + } + + my $reseller_id; + if ($c->user->roles eq "reseller") { + $reseller_id = $c->user->reseller_id; + } + + my $ruleset = $schema->resultset('voip_header_rule_sets')->find({ + id => $resource->{set_id}, + ($reseller_id ? (reseller_id => $reseller_id) : ()), + }); + unless ($ruleset) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'set_id'."); + return; + } + + $c->stash->{checked}->{ruleset} = $ruleset; + + return 1; +} + +sub update_item_model { + my ($self, $c, $item, $old_resource, $resource, $form) = @_; + + $item = $self->SUPER::update_item_model($c, $item, $old_resource, $resource, $form); + + NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset( + c => $c, set_id => $item->ruleset->id + ); + + return $item; +} + +1; +# vim: set tabstop=4 expandtab: