From 9d021be65a77e4b831d785b65dbfc7db3d29eda9 Mon Sep 17 00:00:00 2001 From: Kirill Solomko Date: Tue, 23 Jul 2024 21:38:20 +0200 Subject: [PATCH] MT#59979 add license control * UI and API parts are now under license control * new Util::License::get_license($c, $name) - fetches license status by name (1 if enabled, and also if /proc/ngcp/check if 'ok') * add Catalyst::Plugins::NGCP::License with license($name) to fetch valid license by name from anywhere using $c->license('pbx') or from the templates using c.license('pbx'). It internally uses Util::License::get_license($c, $name) * License::get_license_status($c) now requires $c as first argument as well logs license status check errors. * new ActionRoles::License that enables usage of :Does(License) RequiresLicense('pbx') LicenseDetachTo('/denied_page') in the Controller chains * Add license control for UI elements and return 403 Forbidden if a resource is covered by licenses and the license is not active * Hide UI elements if a license is not active * API/Entities/Entities new $c->set_config key: - per endpoint: $c->set_config({ required_licenses => [qw/pbx device_provisioning/] } - or per method: $c->set_config({ required_licenses => { POST => [qw/pbx device_provisioning/] } } } * In case if an API endpoint does not have a license: 403 Forbidden "Invalid license" reply is returned. * Add license based restrictions to API endpoints * /api documentation: - completely hide endpoints that do not have an active license - hide only methods that does not have an active license Change-Id: Iba45fc5068b02306a617fed7b5405f2210574b61 --- lib/Catalyst/Plugin/NGCP/License.pm | 33 +++++++ lib/NGCP/Panel.pm | 1 + lib/NGCP/Panel/ActionRole/License.pm | 93 +++++++++++++++++++ .../Panel/Controller/API/BalanceIntervals.pm | 1 + .../Controller/API/BalanceIntervalsItem.pm | 1 + lib/NGCP/Panel/Controller/API/BillingFees.pm | 1 + .../Panel/Controller/API/BillingFeesItem.pm | 1 + .../Panel/Controller/API/BillingNetworks.pm | 1 + .../Controller/API/BillingNetworksItem.pm | 3 +- .../Panel/Controller/API/BillingProfiles.pm | 3 + .../Controller/API/BillingProfilesItem.pm | 3 +- lib/NGCP/Panel/Controller/API/BillingZones.pm | 1 + .../Panel/Controller/API/BillingZonesItem.pm | 3 +- .../Controller/API/CallRecordingFiles.pm | 1 + .../Controller/API/CallRecordingFilesItem.pm | 1 + .../Controller/API/CallRecordingStreams.pm | 1 + .../API/CallRecordingStreamsItem.pm | 1 + .../Panel/Controller/API/CallRecordings.pm | 1 + .../Controller/API/CallRecordingsItem.pm | 1 + .../Panel/Controller/API/CustomerBalances.pm | 1 + .../Controller/API/CustomerBalancesItem.pm | 3 +- .../API/CustomerPhonebookEntries.pm | 1 + .../API/CustomerPhonebookEntriesItem.pm | 1 + .../Panel/Controller/API/CustomerZoneCosts.pm | 1 + .../Controller/API/CustomerZoneCostsItem.pm | 1 + .../Panel/Controller/API/FaxRecordings.pm | 1 + .../Panel/Controller/API/FaxRecordingsItem.pm | 1 + lib/NGCP/Panel/Controller/API/Faxes.pm | 1 + lib/NGCP/Panel/Controller/API/FaxesItem.pm | 1 + .../Panel/Controller/API/FaxserverSettings.pm | 1 + .../Controller/API/FaxserverSettingsItem.pm | 1 + .../Panel/Controller/API/HeaderRuleActions.pm | 1 + .../Controller/API/HeaderRuleActionsItem.pm | 1 + .../Controller/API/HeaderRuleConditions.pm | 1 + .../API/HeaderRuleConditionsItem.pm | 1 + .../Panel/Controller/API/HeaderRuleSets.pm | 1 + .../Controller/API/HeaderRuleSetsItem.pm | 1 + lib/NGCP/Panel/Controller/API/HeaderRules.pm | 1 + .../Panel/Controller/API/HeaderRulesItem.pm | 1 + .../Panel/Controller/API/InvoiceTemplates.pm | 1 + .../Controller/API/InvoiceTemplatesItem.pm | 1 + lib/NGCP/Panel/Controller/API/Invoices.pm | 4 +- lib/NGCP/Panel/Controller/API/InvoicesItem.pm | 1 + .../Panel/Controller/API/MailToFaxSettings.pm | 1 + .../Controller/API/MailToFaxSettingsItem.pm | 3 +- .../Controller/API/PbxDeviceConfigFiles.pm | 1 + .../API/PbxDeviceConfigFilesItem.pm | 1 + .../Panel/Controller/API/PbxDeviceConfigs.pm | 1 + .../Controller/API/PbxDeviceConfigsItem.pm | 1 + .../API/PbxDeviceFirmwareBinaries.pm | 1 + .../API/PbxDeviceFirmwareBinariesItem.pm | 1 + .../Controller/API/PbxDeviceFirmwares.pm | 1 + .../Controller/API/PbxDeviceFirmwaresItem.pm | 1 + .../Controller/API/PbxDeviceModelImages.pm | 4 +- .../API/PbxDeviceModelImagesItem.pm | 1 + .../Panel/Controller/API/PbxDeviceModels.pm | 3 +- .../Controller/API/PbxDeviceModelsItem.pm | 3 +- .../Controller/API/PbxDevicePreferenceDefs.pm | 1 + .../Controller/API/PbxDevicePreferences.pm | 1 + .../API/PbxDevicePreferencesItem.pm | 3 +- .../API/PbxDeviceProfilePreferenceDefs.pm | 1 + .../API/PbxDeviceProfilePreferences.pm | 1 + .../API/PbxDeviceProfilePreferencesItem.pm | 3 +- .../Panel/Controller/API/PbxDeviceProfiles.pm | 1 + .../Controller/API/PbxDeviceProfilesItem.pm | 1 + lib/NGCP/Panel/Controller/API/PbxDevices.pm | 1 + .../Panel/Controller/API/PbxDevicesItem.pm | 1 + .../API/PbxFieldDevicePreferenceDefs.pm | 1 + .../API/PbxFieldDevicePreferences.pm | 1 + .../API/PbxFieldDevicePreferencesItem.pm | 3 +- .../Panel/Controller/API/ProfilePackages.pm | 1 + .../Controller/API/ProfilePackagesItem.pm | 3 +- .../Controller/API/ProvisioningTemplates.pm | 1 + .../API/ProvisioningTemplatesItem.pm | 1 + .../Controller/API/ResellerBrandingLogos.pm | 3 + .../API/ResellerBrandingLogosItem.pm | 1 + .../Panel/Controller/API/ResellerBrandings.pm | 3 + .../Controller/API/ResellerBrandingsItem.pm | 3 +- .../API/ResellerPhonebookEntries.pm | 1 + .../API/ResellerPhonebookEntriesItem.pm | 1 + .../Controller/API/ResellerPreferenceDefs.pm | 1 + .../Controller/API/ResellerPreferences.pm | 1 + .../Controller/API/ResellerPreferencesItem.pm | 1 + lib/NGCP/Panel/Controller/API/Resellers.pm | 3 + .../Panel/Controller/API/ResellersItem.pm | 3 +- lib/NGCP/Panel/Controller/API/Root.pm | 53 ++++++++++- lib/NGCP/Panel/Controller/API/SIPCaptures.pm | 1 + .../Panel/Controller/API/SIPCapturesItem.pm | 1 + lib/NGCP/Panel/Controller/API/SMS.pm | 4 +- lib/NGCP/Panel/Controller/API/SMSItem.pm | 4 +- .../API/SubscriberPhonebookEntries.pm | 1 + .../API/SubscriberPhonebookEntriesItem.pm | 1 + .../API/SubscriberPreferencesItem.pm | 2 +- lib/NGCP/Panel/Controller/API/TopupCash.pm | 1 + lib/NGCP/Panel/Controller/API/TopupLogs.pm | 1 + .../Panel/Controller/API/TopupLogsItem.pm | 1 + .../Panel/Controller/API/TopupVouchers.pm | 1 + lib/NGCP/Panel/Controller/API/Vouchers.pm | 1 + lib/NGCP/Panel/Controller/API/VouchersItem.pm | 1 + .../Panel/Controller/BatchProvisioning.pm | 2 +- lib/NGCP/Panel/Controller/Billing.pm | 2 +- lib/NGCP/Panel/Controller/Contract.pm | 13 ++- lib/NGCP/Panel/Controller/Customer.pm | 18 ++-- lib/NGCP/Panel/Controller/Device.pm | 2 +- lib/NGCP/Panel/Controller/Header.pm | 2 +- lib/NGCP/Panel/Controller/Invoice.pm | 8 +- lib/NGCP/Panel/Controller/InvoiceTemplate.pm | 2 +- lib/NGCP/Panel/Controller/Network.pm | 2 +- lib/NGCP/Panel/Controller/Package.pm | 2 +- lib/NGCP/Panel/Controller/Pbx.pm | 2 +- lib/NGCP/Panel/Controller/Phonebook.pm | 2 +- lib/NGCP/Panel/Controller/Reseller.pm | 14 +-- lib/NGCP/Panel/Controller/Sound.pm | 6 +- lib/NGCP/Panel/Controller/Subscriber.pm | 20 ++-- lib/NGCP/Panel/Controller/Voucher.pm | 2 +- lib/NGCP/Panel/Form/DestinationSet.pm | 2 +- lib/NGCP/Panel/Form/SubscriberCFSimple.pm | 2 +- lib/NGCP/Panel/Role/API.pm | 27 +++++- lib/NGCP/Panel/Role/API/Subscribers.pm | 2 +- lib/NGCP/Panel/Role/Entities.pm | 4 + lib/NGCP/Panel/Role/EntitiesItem.pm | 4 + lib/NGCP/Panel/Utils/License.pm | 88 ++++++++++++++---- lib/NGCP/Panel/Utils/Preferences.pm | 2 +- lib/NGCP/Panel/Utils/Sounds.pm | 4 +- lib/NGCP/Panel/Utils/Subscriber.pm | 8 +- share/templates/billing/list.tt | 2 +- share/templates/contract/list.tt | 14 ++- share/templates/customer/details.tt | 24 +++-- share/templates/ncos/pattern_list.tt | 2 +- share/templates/reseller/details.tt | 2 + share/templates/reseller/list.tt | 10 +- share/templates/subscriber/master.tt | 2 + share/templates/subscriber/preferences.tt | 6 +- .../widgets/admin_topmenu_settings.tt | 14 ++- .../widgets/reseller_topmenu_settings.tt | 10 +- .../widgets/subscriber_topmenu_settings.tt | 4 +- .../subscriberadmin_topmenu_settings.tt | 2 +- 137 files changed, 537 insertions(+), 119 deletions(-) create mode 100644 lib/Catalyst/Plugin/NGCP/License.pm create mode 100644 lib/NGCP/Panel/ActionRole/License.pm diff --git a/lib/Catalyst/Plugin/NGCP/License.pm b/lib/Catalyst/Plugin/NGCP/License.pm new file mode 100644 index 0000000000..8789421c51 --- /dev/null +++ b/lib/Catalyst/Plugin/NGCP/License.pm @@ -0,0 +1,33 @@ +package Catalyst::Plugin::NGCP::License; +use warnings; +use strict; +use MRO::Compat; + +use NGCP::Panel::Utils::Generic qw(); + +sub licenses { + return NGCP::Panel::Utils::License::get_licenses(@_); +} + +sub license { + return NGCP::Panel::Utils::License::get_license(@_); +} + +sub license_meta { + return NGCP::Panel::Utils::License::get_license_meta(@_); +} + +sub license_max_pbx_groups { + return NGCP::Panel::Utils::License::get_max_pbx_groups(@_); +} + +sub license_max_subscribers { + return NGCP::Panel::Utils::License::get_max_subscribers(@_); +} + +sub license_max_pbx_subscribers { + return NGCP::Panel::Utils::License::get_max_pbx_subscribers(@_); +} + +1; + diff --git a/lib/NGCP/Panel.pm b/lib/NGCP/Panel.pm index e7549c0c06..38976ba81b 100644 --- a/lib/NGCP/Panel.pm +++ b/lib/NGCP/Panel.pm @@ -29,6 +29,7 @@ use Catalyst qw/ NGCP::EscapeSensitiveValue NGCP::EscapeJs NGCP::EscapeURI + NGCP::License I18N /; use Log::Log4perl::Catalyst qw(); diff --git a/lib/NGCP/Panel/ActionRole/License.pm b/lib/NGCP/Panel/ActionRole/License.pm new file mode 100644 index 0000000000..734218a0a4 --- /dev/null +++ b/lib/NGCP/Panel/ActionRole/License.pm @@ -0,0 +1,93 @@ +package NGCP::Panel::ActionRole::License; +use Moose::Role; +use namespace::autoclean; + +sub BUILD { } + +after BUILD => sub { + my $class = shift; + my ($args) = @_; + + my $attr = $args->{attributes}; + + unless (exists $attr->{RequiresLicense} || exists $attr->{AllowedLicense}) { + Catalyst::Exception->throw( + "Action '$args->{reverse}' requires at least one RequiresLicense or AllowedLicense attribute"); + } + unless (exists $attr->{LicenseDetachTo} && $attr->{LicenseDetachTo}) { + Catalyst::Exception->throw( + "Action '$args->{reverse}' requires the LicenseDetachTo() attribute"); + } + +}; + +around execute => sub { + my $orig = shift; + my $self = shift; + my ($controller, $c) = @_; + + if ($self->check_license($c)) { + return $self->$orig(@_); + } + + my $denied = $self->attributes->{ACLDetachTo}[0]; + + $c->detach($denied); +}; + +sub check_license { + my ($self, $c) = @_; + + my $required = $self->attributes->{RequiresLicense}; + my $allowed = $self->attributes->{AllowedLicense}; + + if ($required && $allowed) { + for my $license (@$required) { + return unless $c->license($license); + } + for my $license (@$allowed) { + return 1 if $c->license($license); + } + return; + } + elsif ($required) { + for my $license (@$required) { + return unless $c->license($license); + } + return 1; + } + elsif ($allowed) { + for my $license (@$allowed) { + return 1 if $c->license($license); + } + return; + } + + return; +} + +1; + +__END__ +=pod + +=head1 NAME + +NGCP::Panel::ActionRole::License + +=head1 DESCRIPTION + +A helper to check NGCP License info + +=head1 AUTHOR + +Sipwise Development Team + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut +# vim: set tabstop=4 expandtab: + diff --git a/lib/NGCP/Panel/Controller/API/BalanceIntervals.pm b/lib/NGCP/Panel/Controller/API/BalanceIntervals.pm index 8d4cc4a520..953967c31a 100644 --- a/lib/NGCP/Panel/Controller/API/BalanceIntervals.pm +++ b/lib/NGCP/Panel/Controller/API/BalanceIntervals.pm @@ -82,6 +82,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/BalanceIntervalsItem.pm b/lib/NGCP/Panel/Controller/API/BalanceIntervalsItem.pm index d8496bbd60..925b910825 100644 --- a/lib/NGCP/Panel/Controller/API/BalanceIntervalsItem.pm +++ b/lib/NGCP/Panel/Controller/API/BalanceIntervalsItem.pm @@ -56,6 +56,7 @@ sub query_params { __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare/], + required_licenses => [qw/billing/], action_add => { item_base => { Chained => '/', diff --git a/lib/NGCP/Panel/Controller/API/BillingFees.pm b/lib/NGCP/Panel/Controller/API/BillingFees.pm index 3db78146b0..ab64cce634 100644 --- a/lib/NGCP/Panel/Controller/API/BillingFees.pm +++ b/lib/NGCP/Panel/Controller/API/BillingFees.pm @@ -61,6 +61,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub auto :Private { diff --git a/lib/NGCP/Panel/Controller/API/BillingFeesItem.pm b/lib/NGCP/Panel/Controller/API/BillingFeesItem.pm index 4c4b2dd257..f7d714814f 100644 --- a/lib/NGCP/Panel/Controller/API/BillingFeesItem.pm +++ b/lib/NGCP/Panel/Controller/API/BillingFeesItem.pm @@ -31,6 +31,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/BillingNetworks.pm b/lib/NGCP/Panel/Controller/API/BillingNetworks.pm index 74991c84fc..78a312c8d3 100644 --- a/lib/NGCP/Panel/Controller/API/BillingNetworks.pm +++ b/lib/NGCP/Panel/Controller/API/BillingNetworks.pm @@ -70,6 +70,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/BillingNetworksItem.pm b/lib/NGCP/Panel/Controller/API/BillingNetworksItem.pm index 88da24ab19..7da9b6b1a8 100644 --- a/lib/NGCP/Panel/Controller/API/BillingNetworksItem.pm +++ b/lib/NGCP/Panel/Controller/API/BillingNetworksItem.pm @@ -43,7 +43,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller/], Journal => [qw/admin reseller/], - } + }, + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/BillingProfiles.pm b/lib/NGCP/Panel/Controller/API/BillingProfiles.pm index 30dbc84eb8..0345d7623b 100644 --- a/lib/NGCP/Panel/Controller/API/BillingProfiles.pm +++ b/lib/NGCP/Panel/Controller/API/BillingProfiles.pm @@ -62,6 +62,9 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare/], + required_licenses => { + POST => [qw/billing/], + } }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/BillingProfilesItem.pm b/lib/NGCP/Panel/Controller/API/BillingProfilesItem.pm index a51704de21..e66afff7f2 100644 --- a/lib/NGCP/Panel/Controller/API/BillingProfilesItem.pm +++ b/lib/NGCP/Panel/Controller/API/BillingProfilesItem.pm @@ -40,7 +40,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller ccareadmin ccare/], Journal => [qw/admin reseller ccareadmin ccare/], - } + }, + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/BillingZones.pm b/lib/NGCP/Panel/Controller/API/BillingZones.pm index 068ec97271..e4713665ac 100644 --- a/lib/NGCP/Panel/Controller/API/BillingZones.pm +++ b/lib/NGCP/Panel/Controller/API/BillingZones.pm @@ -55,6 +55,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/BillingZonesItem.pm b/lib/NGCP/Panel/Controller/API/BillingZonesItem.pm index 9688d01203..be1267ca78 100644 --- a/lib/NGCP/Panel/Controller/API/BillingZonesItem.pm +++ b/lib/NGCP/Panel/Controller/API/BillingZonesItem.pm @@ -38,7 +38,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller/], Journal => [qw/admin reseller/], - } + }, + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/CallRecordingFiles.pm b/lib/NGCP/Panel/Controller/API/CallRecordingFiles.pm index 90715286dc..c2bf255a5a 100644 --- a/lib/NGCP/Panel/Controller/API/CallRecordingFiles.pm +++ b/lib/NGCP/Panel/Controller/API/CallRecordingFiles.pm @@ -34,6 +34,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/call_recording/], }); 1; diff --git a/lib/NGCP/Panel/Controller/API/CallRecordingFilesItem.pm b/lib/NGCP/Panel/Controller/API/CallRecordingFilesItem.pm index 7fcc845a33..4344731c99 100644 --- a/lib/NGCP/Panel/Controller/API/CallRecordingFilesItem.pm +++ b/lib/NGCP/Panel/Controller/API/CallRecordingFilesItem.pm @@ -29,6 +29,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/call_recording/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/CallRecordingStreams.pm b/lib/NGCP/Panel/Controller/API/CallRecordingStreams.pm index 5e4414159d..7dd5ca2141 100644 --- a/lib/NGCP/Panel/Controller/API/CallRecordingStreams.pm +++ b/lib/NGCP/Panel/Controller/API/CallRecordingStreams.pm @@ -67,6 +67,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/call_recording/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/CallRecordingStreamsItem.pm b/lib/NGCP/Panel/Controller/API/CallRecordingStreamsItem.pm index 999483218b..28c944fcad 100644 --- a/lib/NGCP/Panel/Controller/API/CallRecordingStreamsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CallRecordingStreamsItem.pm @@ -30,6 +30,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/call_recording/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/CallRecordings.pm b/lib/NGCP/Panel/Controller/API/CallRecordings.pm index e6f0e00412..ddaef36b7c 100644 --- a/lib/NGCP/Panel/Controller/API/CallRecordings.pm +++ b/lib/NGCP/Panel/Controller/API/CallRecordings.pm @@ -7,6 +7,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::CallRecordings __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/call_recording/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/CallRecordingsItem.pm b/lib/NGCP/Panel/Controller/API/CallRecordingsItem.pm index 0bd44675d4..f34d11f741 100644 --- a/lib/NGCP/Panel/Controller/API/CallRecordingsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CallRecordingsItem.pm @@ -10,6 +10,7 @@ use HTTP::Status qw(:constants); __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/call_recording/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/CustomerBalances.pm b/lib/NGCP/Panel/Controller/API/CustomerBalances.pm index d76bbb695b..f91b9c5c4a 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerBalances.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerBalances.pm @@ -112,6 +112,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/CustomerBalancesItem.pm b/lib/NGCP/Panel/Controller/API/CustomerBalancesItem.pm index ad9fe957ed..e5e5621450 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerBalancesItem.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerBalancesItem.pm @@ -39,7 +39,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller ccareadmin ccare/], Journal => [qw/admin reseller ccareadmin ccare/], - } + }, + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/CustomerPhonebookEntries.pm b/lib/NGCP/Panel/Controller/API/CustomerPhonebookEntries.pm index 87bac60dfc..7bb190a73a 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerPhonebookEntries.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerPhonebookEntries.pm @@ -15,6 +15,7 @@ __PACKAGE__->set_config({ }, allowed_roles => [qw/admin reseller subscriberadmin/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/phonebook/], }); sub allowed_methods { diff --git a/lib/NGCP/Panel/Controller/API/CustomerPhonebookEntriesItem.pm b/lib/NGCP/Panel/Controller/API/CustomerPhonebookEntriesItem.pm index de8c929107..e4879a6ea5 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerPhonebookEntriesItem.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerPhonebookEntriesItem.pm @@ -8,6 +8,7 @@ use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::CustomerPh __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/phonebook/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/CustomerZoneCosts.pm b/lib/NGCP/Panel/Controller/API/CustomerZoneCosts.pm index 9ef9e84f01..8e66db334b 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerZoneCosts.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerZoneCosts.pm @@ -65,6 +65,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/CustomerZoneCostsItem.pm b/lib/NGCP/Panel/Controller/API/CustomerZoneCostsItem.pm index 689d0d3d96..cc4d691952 100644 --- a/lib/NGCP/Panel/Controller/API/CustomerZoneCostsItem.pm +++ b/lib/NGCP/Panel/Controller/API/CustomerZoneCostsItem.pm @@ -34,6 +34,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/FaxRecordings.pm b/lib/NGCP/Panel/Controller/API/FaxRecordings.pm index 8a62cc0ff7..fb3e97131e 100644 --- a/lib/NGCP/Panel/Controller/API/FaxRecordings.pm +++ b/lib/NGCP/Panel/Controller/API/FaxRecordings.pm @@ -34,6 +34,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/fax/], }); 1; diff --git a/lib/NGCP/Panel/Controller/API/FaxRecordingsItem.pm b/lib/NGCP/Panel/Controller/API/FaxRecordingsItem.pm index cba05884ba..609d1e304c 100644 --- a/lib/NGCP/Panel/Controller/API/FaxRecordingsItem.pm +++ b/lib/NGCP/Panel/Controller/API/FaxRecordingsItem.pm @@ -34,6 +34,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/fax/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/Faxes.pm b/lib/NGCP/Panel/Controller/API/Faxes.pm index ace74f5293..76525bb1f7 100644 --- a/lib/NGCP/Panel/Controller/API/Faxes.pm +++ b/lib/NGCP/Panel/Controller/API/Faxes.pm @@ -15,6 +15,7 @@ use NGCP::Panel::Utils::Fax; __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/fax/], dont_validate_hal => 1, no_item_created => 1, backward_allow_empty_upload => 1, diff --git a/lib/NGCP/Panel/Controller/API/FaxesItem.pm b/lib/NGCP/Panel/Controller/API/FaxesItem.pm index 4438900dae..3a0109682c 100644 --- a/lib/NGCP/Panel/Controller/API/FaxesItem.pm +++ b/lib/NGCP/Panel/Controller/API/FaxesItem.pm @@ -7,6 +7,7 @@ use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::Faxes/; __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/fax/], dont_validate_hal => 1, }); diff --git a/lib/NGCP/Panel/Controller/API/FaxserverSettings.pm b/lib/NGCP/Panel/Controller/API/FaxserverSettings.pm index 8c0967b6ec..19a0e265ad 100644 --- a/lib/NGCP/Panel/Controller/API/FaxserverSettings.pm +++ b/lib/NGCP/Panel/Controller/API/FaxserverSettings.pm @@ -7,6 +7,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::FaxserverSetti __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare subscriber subscriberadmin/], + required_licenses => [qw/fax/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/FaxserverSettingsItem.pm b/lib/NGCP/Panel/Controller/API/FaxserverSettingsItem.pm index 3e0f0c9baa..c72218abbe 100644 --- a/lib/NGCP/Panel/Controller/API/FaxserverSettingsItem.pm +++ b/lib/NGCP/Panel/Controller/API/FaxserverSettingsItem.pm @@ -14,6 +14,7 @@ __PACKAGE__->set_config({ Default => [qw/admin reseller ccareadmin ccare subscriber subscriberadmin/], Journal => [qw/admin reseller ccareadmin ccare subscriber subscriberadmin/], }, + required_licenses => [qw/fax/], PATCH => { ops => [qw/add replace remove copy/] }, }); diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm index 43da25ddd0..c193937c1c 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleActions.pm @@ -10,6 +10,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::HeaderRuleActi __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/header_manipulation/], }); sub allowed_methods { diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleActionsItem.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleActionsItem.pm index e740440749..82be43443a 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRuleActionsItem.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleActionsItem.pm @@ -13,6 +13,7 @@ __PACKAGE__->set_config({ Journal => [qw/admin reseller/], }, allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/header_manipulation/], PATCH => { ops => [qw/add replace remove copy/] }, }); diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm index 189dc452c8..cbf073ca4f 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleConditions.pm @@ -10,6 +10,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::HeaderRuleCond __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/header_manipulation/], }); sub allowed_methods { diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleConditionsItem.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleConditionsItem.pm index d73b1d5001..8b04a3e015 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRuleConditionsItem.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleConditionsItem.pm @@ -13,6 +13,7 @@ __PACKAGE__->set_config({ Journal => [qw/admin reseller/], }, allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/header_manipulation/], PATCH => { ops => [qw/add replace remove copy/] }, }); diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm index 24a283a07c..5178c3c91a 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleSets.pm @@ -9,6 +9,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::HeaderRuleSets __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/header_manipulation/], }); sub allowed_methods { diff --git a/lib/NGCP/Panel/Controller/API/HeaderRuleSetsItem.pm b/lib/NGCP/Panel/Controller/API/HeaderRuleSetsItem.pm index 6748aa0424..402a2524dd 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRuleSetsItem.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRuleSetsItem.pm @@ -13,6 +13,7 @@ __PACKAGE__->set_config({ Journal => [qw/admin reseller/], }, allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/header_manipulation/], PATCH => { ops => [qw/add replace remove copy/] }, }); diff --git a/lib/NGCP/Panel/Controller/API/HeaderRules.pm b/lib/NGCP/Panel/Controller/API/HeaderRules.pm index e38c9dacdc..a67d9b82ae 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRules.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRules.pm @@ -10,6 +10,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::HeaderRules/; __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/header_manipulation/], }); sub allowed_methods { diff --git a/lib/NGCP/Panel/Controller/API/HeaderRulesItem.pm b/lib/NGCP/Panel/Controller/API/HeaderRulesItem.pm index 5437c6a302..109a0bb866 100644 --- a/lib/NGCP/Panel/Controller/API/HeaderRulesItem.pm +++ b/lib/NGCP/Panel/Controller/API/HeaderRulesItem.pm @@ -13,6 +13,7 @@ __PACKAGE__->set_config({ Journal => [qw/admin reseller/], }, allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/header_manipulation/], PATCH => { ops => [qw/add replace remove copy/] }, }); diff --git a/lib/NGCP/Panel/Controller/API/InvoiceTemplates.pm b/lib/NGCP/Panel/Controller/API/InvoiceTemplates.pm index 18f2d376ec..b0240e02a3 100644 --- a/lib/NGCP/Panel/Controller/API/InvoiceTemplates.pm +++ b/lib/NGCP/Panel/Controller/API/InvoiceTemplates.pm @@ -55,6 +55,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare/], + required_licenses => [qw/invoice/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/InvoiceTemplatesItem.pm b/lib/NGCP/Panel/Controller/API/InvoiceTemplatesItem.pm index dbab6eda6a..6c937fde05 100644 --- a/lib/NGCP/Panel/Controller/API/InvoiceTemplatesItem.pm +++ b/lib/NGCP/Panel/Controller/API/InvoiceTemplatesItem.pm @@ -31,6 +31,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare/], + required_licenses => [qw/invoice/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/Invoices.pm b/lib/NGCP/Panel/Controller/API/Invoices.pm index 80adf5d54b..c2dc08a253 100644 --- a/lib/NGCP/Panel/Controller/API/Invoices.pm +++ b/lib/NGCP/Panel/Controller/API/Invoices.pm @@ -6,7 +6,9 @@ use HTTP::Status qw(:constants); use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::Invoices/; -__PACKAGE__->set_config(); +__PACKAGE__->set_config({ + required_licenses => [qw/invoice/], +}); sub allowed_methods{ return [qw/GET POST OPTIONS HEAD/]; diff --git a/lib/NGCP/Panel/Controller/API/InvoicesItem.pm b/lib/NGCP/Panel/Controller/API/InvoicesItem.pm index e2cac54801..921e32880a 100644 --- a/lib/NGCP/Panel/Controller/API/InvoicesItem.pm +++ b/lib/NGCP/Panel/Controller/API/InvoicesItem.pm @@ -6,6 +6,7 @@ use NGCP::Panel::Utils::Generic qw(:all); use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::Invoices/; __PACKAGE__->set_config({ + required_licenses => [qw/invoice/], log_response => 0, GET => { #first element of array is default, if no accept header was received. diff --git a/lib/NGCP/Panel/Controller/API/MailToFaxSettings.pm b/lib/NGCP/Panel/Controller/API/MailToFaxSettings.pm index 327eb63655..38dd451fff 100644 --- a/lib/NGCP/Panel/Controller/API/MailToFaxSettings.pm +++ b/lib/NGCP/Panel/Controller/API/MailToFaxSettings.pm @@ -72,6 +72,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare subscriberadmin subscriber/], + required_licenses => [qw/fax/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/MailToFaxSettingsItem.pm b/lib/NGCP/Panel/Controller/API/MailToFaxSettingsItem.pm index 812cc805ec..49de12098f 100644 --- a/lib/NGCP/Panel/Controller/API/MailToFaxSettingsItem.pm +++ b/lib/NGCP/Panel/Controller/API/MailToFaxSettingsItem.pm @@ -39,7 +39,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller ccareadmin ccare subscriberadmin subscriber/], Journal => [qw/admin reseller ccareadmin ccare subscriberadmin subscriber/], - } + }, + required_licenses => [qw/fax/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigFiles.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigFiles.pm index e9d035b411..37a94e098e 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigFiles.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigFiles.pm @@ -39,6 +39,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub auto :Private { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigFilesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigFilesItem.pm index d4e5489a4f..05f9dfbd69 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigFilesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigFilesItem.pm @@ -31,6 +31,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigs.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigs.pm index e631613de2..a12bd1afc1 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigs.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigs.pm @@ -72,6 +72,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigsItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigsItem.pm index 3394ce32ab..4efb1bb80a 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceConfigsItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceConfigsItem.pm @@ -31,6 +31,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwareBinaries.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwareBinaries.pm index 7974f6e2ea..331557314e 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwareBinaries.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwareBinaries.pm @@ -39,6 +39,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub auto :Private { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwareBinariesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwareBinariesItem.pm index 5f68926e0b..d161ef2952 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwareBinariesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwareBinariesItem.pm @@ -32,6 +32,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwares.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwares.pm index 3370766648..01ac197940 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwares.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwares.pm @@ -73,6 +73,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwaresItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwaresItem.pm index 53da87a504..ccae61507d 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwaresItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceFirmwaresItem.pm @@ -31,6 +31,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceModelImages.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceModelImages.pm index 9ae359a042..1649fee547 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceModelImages.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceModelImages.pm @@ -5,7 +5,9 @@ use NGCP::Panel::Utils::Generic qw(:all); use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::PbxDeviceModelImages NGCP::Panel::Role::API::PbxDeviceModels/; -__PACKAGE__->set_config(); +__PACKAGE__->set_config({ + required_licenses => [qw/pbx device_provisioning/], +}); sub config_allowed_roles { return [qw/admin reseller subscriberadmin subscriber/]; diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceModelImagesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceModelImagesItem.pm index 22a6671de1..7e2680cf4d 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceModelImagesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceModelImagesItem.pm @@ -13,6 +13,7 @@ __PACKAGE__->set_config({ }, log_response => 0, allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/pbx device_provisioning/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm index ca05e99f9d..2b5ad3eb26 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceModels.pm @@ -19,7 +19,8 @@ __PACKAGE__->set_config({ allowed_roles => { 'Default' => [qw/admin reseller subscriberadmin subscriber/], 'POST' => [qw/admin reseller/], - } + }, + required_licenses => [qw/pbx device_provisioning/], }); # curl -v -X POST --user $USER --insecure -F front_image=@sandbox/spa504g-front.png -F mac_image=@sandbox/spa504g-back.png -F front_thumbnail=@sandbox/spa504g-front-small.png -F json='{"reseller_id":1, "vendor":"Cisco", "model":"SPA999", "linerange":[{"name": "Phone Keys", "can_private":true, "can_shared":true, "can_blf":true, "can_speeddial":true, "can_forward":true, "can_transfer":true, "keys":[{"labelpos":"top", "x":5110, "y":5120},{"labelpos":"top", "x":5310, "y":5320}]}]}' https://localhost:4443/api/pbxdevicemodels/ diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceModelsItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceModelsItem.pm index 5bfd773929..2ed40cc9a9 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceModelsItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceModelsItem.pm @@ -14,7 +14,8 @@ __PACKAGE__->set_config({ 'Default' => [qw/admin reseller subscriberadmin subscriber/], 'PUT' => [qw/admin reseller/], 'PATCH' => [qw/admin reseller/], - } + }, + required_licenses => [qw/pbx device_provisioning/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/PbxDevicePreferenceDefs.pm b/lib/NGCP/Panel/Controller/API/PbxDevicePreferenceDefs.pm index 04660a03e4..6f029ac9d5 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDevicePreferenceDefs.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDevicePreferenceDefs.pm @@ -13,6 +13,7 @@ sub allowed_methods{ __PACKAGE__->set_config({ preferences_group => 'dev_pref', allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); 1; diff --git a/lib/NGCP/Panel/Controller/API/PbxDevicePreferences.pm b/lib/NGCP/Panel/Controller/API/PbxDevicePreferences.pm index a1e9df85e1..efb223acb8 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDevicePreferences.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDevicePreferences.pm @@ -8,6 +8,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::Preferences/; __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/PbxDevicePreferencesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDevicePreferencesItem.pm index db33bab683..ad9f11fb0f 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDevicePreferencesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDevicePreferencesItem.pm @@ -10,7 +10,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller/], Journal => [qw/admin reseller/], - } + }, + required_licenses => [qw/pbx device_provisioning/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferenceDefs.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferenceDefs.pm index a35899b5f0..dd96f5cd92 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferenceDefs.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferenceDefs.pm @@ -13,6 +13,7 @@ sub allowed_methods{ __PACKAGE__->set_config({ preferences_group => 'devprof_pref', allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); 1; diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferences.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferences.pm index 1ce46fecea..3cb37cdaf2 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferences.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferences.pm @@ -7,6 +7,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::Preferences/; __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferencesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferencesItem.pm index ef62424e6c..04dc14547a 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferencesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilePreferencesItem.pm @@ -10,7 +10,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller/], Journal => [qw/admin reseller/], - } + }, + required_licenses => [qw/pbx device_provisioning/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm index dc37c3fa42..daaa6326bd 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm @@ -50,6 +50,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm index 5d2d773489..339167042b 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm @@ -34,6 +34,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDevices.pm b/lib/NGCP/Panel/Controller/API/PbxDevices.pm index 652d89d3ca..7506fb44d2 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDevices.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDevices.pm @@ -104,6 +104,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxDevicesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDevicesItem.pm index a5518eb8e4..12fcd133c7 100644 --- a/lib/NGCP/Panel/Controller/API/PbxDevicesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxDevicesItem.pm @@ -34,6 +34,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin/], + required_licenses => [qw/pbx device_provisioning/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferenceDefs.pm b/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferenceDefs.pm index 3f1cd1ff77..c8e4c0c5a2 100644 --- a/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferenceDefs.pm +++ b/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferenceDefs.pm @@ -13,6 +13,7 @@ sub allowed_methods{ __PACKAGE__->set_config({ preferences_group => 'fielddev_pref', allowed_roles => [qw/admin reseller/], + required_licenses => [qw/pbx device_provisioning/], }); 1; diff --git a/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferences.pm b/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferences.pm index ebfc733022..d4401e9513 100644 --- a/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferences.pm +++ b/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferences.pm @@ -7,6 +7,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::Preferences/; __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin/], + required_licenses => [qw/pbx device_provisioning/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferencesItem.pm b/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferencesItem.pm index 0ab4cdf35e..86ca871f3c 100644 --- a/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferencesItem.pm +++ b/lib/NGCP/Panel/Controller/API/PbxFieldDevicePreferencesItem.pm @@ -10,7 +10,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller subscriberadmin/], Journal => [qw/admin reseller/], - } + }, + required_licenses => [qw/pbx device_provisioning/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/ProfilePackages.pm b/lib/NGCP/Panel/Controller/API/ProfilePackages.pm index 8233b75bd5..8f0a9b00af 100644 --- a/lib/NGCP/Panel/Controller/API/ProfilePackages.pm +++ b/lib/NGCP/Panel/Controller/API/ProfilePackages.pm @@ -84,6 +84,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/ProfilePackagesItem.pm b/lib/NGCP/Panel/Controller/API/ProfilePackagesItem.pm index cc60e31c79..a346485f01 100644 --- a/lib/NGCP/Panel/Controller/API/ProfilePackagesItem.pm +++ b/lib/NGCP/Panel/Controller/API/ProfilePackagesItem.pm @@ -38,7 +38,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller ccareadmin ccare/], Journal => [qw/admin reseller ccareadmin ccare/], - } + }, + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/ProvisioningTemplates.pm b/lib/NGCP/Panel/Controller/API/ProvisioningTemplates.pm index ef9c72f952..784c9d0153 100644 --- a/lib/NGCP/Panel/Controller/API/ProvisioningTemplates.pm +++ b/lib/NGCP/Panel/Controller/API/ProvisioningTemplates.pm @@ -54,6 +54,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller ccareadmin ccare/], + required_licenses => [qw/batch_provisioning/], }); sub create_item { diff --git a/lib/NGCP/Panel/Controller/API/ProvisioningTemplatesItem.pm b/lib/NGCP/Panel/Controller/API/ProvisioningTemplatesItem.pm index 70fa0c3042..478ef21a49 100644 --- a/lib/NGCP/Panel/Controller/API/ProvisioningTemplatesItem.pm +++ b/lib/NGCP/Panel/Controller/API/ProvisioningTemplatesItem.pm @@ -42,6 +42,7 @@ sub get_journal_methods{ } __PACKAGE__->set_config({ + required_licenses => [qw/batch_provisioning/], action_add => { item_base => { Chained => '/', diff --git a/lib/NGCP/Panel/Controller/API/ResellerBrandingLogos.pm b/lib/NGCP/Panel/Controller/API/ResellerBrandingLogos.pm index b192ceda34..3dc6da6aaa 100644 --- a/lib/NGCP/Panel/Controller/API/ResellerBrandingLogos.pm +++ b/lib/NGCP/Panel/Controller/API/ResellerBrandingLogos.pm @@ -10,6 +10,9 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::ResellerBrandi __PACKAGE__->set_config({ log_response => 0, allowed_roles => [qw/admin reseller subscriberadmin/], + required_licenses => { + POST => [qw/reseller/], + } }); sub allowed_methods { diff --git a/lib/NGCP/Panel/Controller/API/ResellerBrandingLogosItem.pm b/lib/NGCP/Panel/Controller/API/ResellerBrandingLogosItem.pm index 69a63301a9..b76240eca6 100644 --- a/lib/NGCP/Panel/Controller/API/ResellerBrandingLogosItem.pm +++ b/lib/NGCP/Panel/Controller/API/ResellerBrandingLogosItem.pm @@ -10,6 +10,7 @@ use HTTP::Status qw(:constants); __PACKAGE__->set_config({ log_response => 0, allowed_roles => [qw/admin reseller subscriberadmin/], + required_licenses => [qw/reseller/], }); sub allowed_methods { diff --git a/lib/NGCP/Panel/Controller/API/ResellerBrandings.pm b/lib/NGCP/Panel/Controller/API/ResellerBrandings.pm index 49042cd6cd..5020e1a015 100644 --- a/lib/NGCP/Panel/Controller/API/ResellerBrandings.pm +++ b/lib/NGCP/Panel/Controller/API/ResellerBrandings.pm @@ -18,6 +18,9 @@ __PACKAGE__->set_config({ allowed_roles => { 'Default' => [qw/admin reseller subscriberadmin subscriber/], 'POST' => [qw/admin reseller/], + }, + required_licenses => { + POST => [qw/reseller/], } }); diff --git a/lib/NGCP/Panel/Controller/API/ResellerBrandingsItem.pm b/lib/NGCP/Panel/Controller/API/ResellerBrandingsItem.pm index bbd67df271..10f36aa968 100644 --- a/lib/NGCP/Panel/Controller/API/ResellerBrandingsItem.pm +++ b/lib/NGCP/Panel/Controller/API/ResellerBrandingsItem.pm @@ -14,7 +14,8 @@ __PACKAGE__->set_config({ 'Default' => [qw/admin reseller subscriberadmin subscriber/], 'PUT' => [qw/admin reseller/], 'PATCH' => [qw/admin reseller/], - } + }, + required_licenses => [qw/reseller/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/ResellerPhonebookEntries.pm b/lib/NGCP/Panel/Controller/API/ResellerPhonebookEntries.pm index e6fe604af3..e34e1493a9 100644 --- a/lib/NGCP/Panel/Controller/API/ResellerPhonebookEntries.pm +++ b/lib/NGCP/Panel/Controller/API/ResellerPhonebookEntries.pm @@ -15,6 +15,7 @@ __PACKAGE__->set_config({ }, allowed_roles => [qw/admin reseller/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/phonebook/], }); sub allowed_methods { diff --git a/lib/NGCP/Panel/Controller/API/ResellerPhonebookEntriesItem.pm b/lib/NGCP/Panel/Controller/API/ResellerPhonebookEntriesItem.pm index 1bb433bf12..c18c8a6956 100644 --- a/lib/NGCP/Panel/Controller/API/ResellerPhonebookEntriesItem.pm +++ b/lib/NGCP/Panel/Controller/API/ResellerPhonebookEntriesItem.pm @@ -8,6 +8,7 @@ use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::ResellerPh __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/phonebook/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/ResellerPreferenceDefs.pm b/lib/NGCP/Panel/Controller/API/ResellerPreferenceDefs.pm index 2c0570ae12..0e1efd253a 100644 --- a/lib/NGCP/Panel/Controller/API/ResellerPreferenceDefs.pm +++ b/lib/NGCP/Panel/Controller/API/ResellerPreferenceDefs.pm @@ -13,6 +13,7 @@ sub allowed_methods{ __PACKAGE__->set_config({ preferences_group => 'reseller_pref', allowed_roles => [qw/admin reseller/], + required_licenses => [qw/reseller/], }); 1; diff --git a/lib/NGCP/Panel/Controller/API/ResellerPreferences.pm b/lib/NGCP/Panel/Controller/API/ResellerPreferences.pm index 48636c76bb..f7d8edd507 100644 --- a/lib/NGCP/Panel/Controller/API/ResellerPreferences.pm +++ b/lib/NGCP/Panel/Controller/API/ResellerPreferences.pm @@ -7,6 +7,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::Preferences/; __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/reseller/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/ResellerPreferencesItem.pm b/lib/NGCP/Panel/Controller/API/ResellerPreferencesItem.pm index 220a3fdbf7..788709361d 100644 --- a/lib/NGCP/Panel/Controller/API/ResellerPreferencesItem.pm +++ b/lib/NGCP/Panel/Controller/API/ResellerPreferencesItem.pm @@ -8,6 +8,7 @@ use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::Preference __PACKAGE__->set_config({ PATCH => { ops => [qw/add replace remove copy/] }, allowed_roles => [qw/admin reseller/], + required_licenses => [qw/reseller/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/Resellers.pm b/lib/NGCP/Panel/Controller/API/Resellers.pm index 5afbc2d8bd..aacdd24c02 100644 --- a/lib/NGCP/Panel/Controller/API/Resellers.pm +++ b/lib/NGCP/Panel/Controller/API/Resellers.pm @@ -57,6 +57,9 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin/], + required_licenses => { + POST => [qw/reseller/], + } }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/ResellersItem.pm b/lib/NGCP/Panel/Controller/API/ResellersItem.pm index 03f5b2fa25..ce0390cdb2 100644 --- a/lib/NGCP/Panel/Controller/API/ResellersItem.pm +++ b/lib/NGCP/Panel/Controller/API/ResellersItem.pm @@ -39,7 +39,8 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin/], Journal => [qw/admin/], - } + }, + required_licenses => [qw/reseller/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/Root.pm b/lib/NGCP/Panel/Controller/API/Root.pm index dc3b89728e..aa1d5e9b1c 100644 --- a/lib/NGCP/Panel/Controller/API/Root.pm +++ b/lib/NGCP/Panel/Controller/API/Root.pm @@ -13,7 +13,7 @@ use JSON qw(to_json encode_json decode_json); use YAML::XS qw/Dump/; use Safe::Isa qw($_isa); use NGCP::Panel::Utils::API; -use List::Util qw(none); +use List::Util qw(none all); use parent qw/Catalyst::Controller NGCP::Panel::Role::API/; use NGCP::Panel::Utils::Journal qw(); @@ -103,10 +103,20 @@ sub GET : Allow { next unless $user_roles{$role}; } - my $allowed_ngcp_types = $full_mod->config->{allowed_ngcp_types} // []; - if (@{$allowed_ngcp_types}) { - next if none { $_ eq $c->config->{general}{ngcp_type} } - @{$allowed_ngcp_types}; + if ($full_mod->can('config')) { + my $allowed_ngcp_types = $full_mod->config->{allowed_ngcp_types} // []; + if (@{$allowed_ngcp_types}) { + next if none { $_ eq $c->config->{general}{ngcp_type} } + @{$allowed_ngcp_types}; + } + + my $required_licenses = $full_mod->config->{required_licenses} // undef; + if (ref $required_licenses eq 'ARRAY') { + if (@{$required_licenses} && + ! all { $c->license($_) } @{$required_licenses}) { + next; + } + } } my $query_params = []; @@ -122,6 +132,21 @@ sub GET : Allow { } else { $actions = [ sort keys %{ $full_mod->config->{action} } ]; } + + if ($full_mod->can('config')) { + my $required_licenses = $full_mod->config->{required_licenses} // undef; + if (ref $required_licenses eq 'HASH') { + foreach my $method (qw/GET HEAD OPTIONS POST/) { + if (my $method_licenses = $required_licenses->{$method}) { + if (@{$method_licenses} && + ! all { $c->license($_) } @{$method_licenses}) { + $actions = [grep { $_ ne $method } @{$actions}]; + } + } + } + } + } + my $uri = "/api/$rel/"; my $item_actions = []; my $journal_resource_config = {}; @@ -137,6 +162,24 @@ sub GET : Allow { push @{ $item_actions }, $m; } } + + my $required_licenses = $full_item_mod->config->{required_licenses} // undef; + if (ref $required_licenses eq 'ARRAY') { + if (@{$required_licenses} && + ! all { $c->license($_) } @{$required_licenses}) { + $item_actions = []; + } + } elsif (ref $required_licenses eq 'HASH') { + foreach my $method (qw/GET HEAD OPTIONS PUT PATCH DELETE/) { + if (my $method_licenses = $required_licenses->{$method}) { + if (@{$method_licenses} && + ! all { $c->license($_) } @{$method_licenses}) { + $item_actions = [grep { $_ ne $method } @{$actions}]; + } + } + } + } + if($full_item_mod->can('resource_name')) { my @operations = (); my $op_config = {}; diff --git a/lib/NGCP/Panel/Controller/API/SIPCaptures.pm b/lib/NGCP/Panel/Controller/API/SIPCaptures.pm index 12d4a7c0b2..87dcc5ea23 100644 --- a/lib/NGCP/Panel/Controller/API/SIPCaptures.pm +++ b/lib/NGCP/Panel/Controller/API/SIPCaptures.pm @@ -9,6 +9,7 @@ use parent qw/NGCP::Panel::Role::Entities NGCP::Panel::Role::API::SIPCaptures/; __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/voisniff-mysql_dump/], }); diff --git a/lib/NGCP/Panel/Controller/API/SIPCapturesItem.pm b/lib/NGCP/Panel/Controller/API/SIPCapturesItem.pm index 792a0132dc..6d26b0b171 100644 --- a/lib/NGCP/Panel/Controller/API/SIPCapturesItem.pm +++ b/lib/NGCP/Panel/Controller/API/SIPCapturesItem.pm @@ -16,6 +16,7 @@ use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::SIPCapture __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], + required_licenses => [qw/voisniff-mysql_dump/], log_response => 0, }); diff --git a/lib/NGCP/Panel/Controller/API/SMS.pm b/lib/NGCP/Panel/Controller/API/SMS.pm index e5a92daad5..f6d5ad963f 100644 --- a/lib/NGCP/Panel/Controller/API/SMS.pm +++ b/lib/NGCP/Panel/Controller/API/SMS.pm @@ -10,7 +10,9 @@ use NGCP::Panel::Utils::Preferences; use UUID; -__PACKAGE__->set_config(); +__PACKAGE__->set_config({ + required_licenses => [qw/sms/], +}); sub allowed_methods{ return [qw/GET POST OPTIONS HEAD/]; diff --git a/lib/NGCP/Panel/Controller/API/SMSItem.pm b/lib/NGCP/Panel/Controller/API/SMSItem.pm index c94e3510d0..c862fb3ca0 100644 --- a/lib/NGCP/Panel/Controller/API/SMSItem.pm +++ b/lib/NGCP/Panel/Controller/API/SMSItem.pm @@ -6,7 +6,9 @@ use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::SMS/; use HTTP::Status qw(:constants); -__PACKAGE__->set_config(); +__PACKAGE__->set_config({ + required_licenses => [qw/sms/], +}); sub allowed_methods{ return [qw/GET OPTIONS HEAD/]; diff --git a/lib/NGCP/Panel/Controller/API/SubscriberPhonebookEntries.pm b/lib/NGCP/Panel/Controller/API/SubscriberPhonebookEntries.pm index ae987efbfa..d6c56dac33 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberPhonebookEntries.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberPhonebookEntries.pm @@ -15,6 +15,7 @@ __PACKAGE__->set_config({ }, allowed_roles => [qw/admin reseller subscriberadmin subscriber/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/phonebook/], }); sub allowed_methods { diff --git a/lib/NGCP/Panel/Controller/API/SubscriberPhonebookEntriesItem.pm b/lib/NGCP/Panel/Controller/API/SubscriberPhonebookEntriesItem.pm index 034164db5c..4230521c70 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberPhonebookEntriesItem.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberPhonebookEntriesItem.pm @@ -8,6 +8,7 @@ use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::Subscriber __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller subscriberadmin subscriber/], allowed_ngcp_types => [qw/carrier sppro/], + required_licenses => [qw/phonebook/], }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/SubscriberPreferencesItem.pm b/lib/NGCP/Panel/Controller/API/SubscriberPreferencesItem.pm index 273b65063c..cbcf5e1e4e 100644 --- a/lib/NGCP/Panel/Controller/API/SubscriberPreferencesItem.pm +++ b/lib/NGCP/Panel/Controller/API/SubscriberPreferencesItem.pm @@ -19,7 +19,7 @@ __PACKAGE__->set_config({ allowed_roles => { Default => [qw/admin reseller ccareadmin ccare subscriberadmin subscriber/], Journal => [qw/admin reseller ccareadmin ccare subscriberadmin subscriber/], - } + }, }); sub allowed_methods{ diff --git a/lib/NGCP/Panel/Controller/API/TopupCash.pm b/lib/NGCP/Panel/Controller/API/TopupCash.pm index 2d7fbec99c..69136d3875 100644 --- a/lib/NGCP/Panel/Controller/API/TopupCash.pm +++ b/lib/NGCP/Panel/Controller/API/TopupCash.pm @@ -44,6 +44,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub POST :Allow { diff --git a/lib/NGCP/Panel/Controller/API/TopupLogs.pm b/lib/NGCP/Panel/Controller/API/TopupLogs.pm index f513ee633f..47daa52398 100644 --- a/lib/NGCP/Panel/Controller/API/TopupLogs.pm +++ b/lib/NGCP/Panel/Controller/API/TopupLogs.pm @@ -167,6 +167,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/TopupLogsItem.pm b/lib/NGCP/Panel/Controller/API/TopupLogsItem.pm index 8c1af6df94..269ca3ce12 100644 --- a/lib/NGCP/Panel/Controller/API/TopupLogsItem.pm +++ b/lib/NGCP/Panel/Controller/API/TopupLogsItem.pm @@ -31,6 +31,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/TopupVouchers.pm b/lib/NGCP/Panel/Controller/API/TopupVouchers.pm index 626035a268..c09fd80551 100644 --- a/lib/NGCP/Panel/Controller/API/TopupVouchers.pm +++ b/lib/NGCP/Panel/Controller/API/TopupVouchers.pm @@ -44,6 +44,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub POST :Allow { diff --git a/lib/NGCP/Panel/Controller/API/Vouchers.pm b/lib/NGCP/Panel/Controller/API/Vouchers.pm index 02ab3c6095..ade14c49d1 100644 --- a/lib/NGCP/Panel/Controller/API/Vouchers.pm +++ b/lib/NGCP/Panel/Controller/API/Vouchers.pm @@ -61,6 +61,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/API/VouchersItem.pm b/lib/NGCP/Panel/Controller/API/VouchersItem.pm index abd890661a..d1d60fa77a 100644 --- a/lib/NGCP/Panel/Controller/API/VouchersItem.pm +++ b/lib/NGCP/Panel/Controller/API/VouchersItem.pm @@ -31,6 +31,7 @@ sub relation{ __PACKAGE__->set_config({ allowed_roles => [qw/admin reseller/], + required_licenses => [qw/billing/], }); sub GET :Allow { diff --git a/lib/NGCP/Panel/Controller/BatchProvisioning.pm b/lib/NGCP/Panel/Controller/BatchProvisioning.pm index 83097821bf..cb2019b4ba 100644 --- a/lib/NGCP/Panel/Controller/BatchProvisioning.pm +++ b/lib/NGCP/Panel/Controller/BatchProvisioning.pm @@ -13,7 +13,7 @@ use NGCP::Panel::Utils::Generic qw(run_module_method get_module_var); use NGCP::Panel::Form::ProvisioningTemplate::Admin qw(); use NGCP::Panel::Form::ProvisioningTemplate::Reseller qw(); -sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) :AllowedRole(ccareadmin) :AllowedRole(ccare) { +sub auto :Does(License) :RequiresLicense('batch_provisioning') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) :AllowedRole(ccareadmin) :AllowedRole(ccare) { my ($self, $c) = @_; $c->log->debug(__PACKAGE__ . '::auto'); NGCP::Panel::Utils::Navigation::check_redirect_chain(c => $c); diff --git a/lib/NGCP/Panel/Controller/Billing.pm b/lib/NGCP/Panel/Controller/Billing.pm index 98b9317d65..3b5e5e4978 100644 --- a/lib/NGCP/Panel/Controller/Billing.pm +++ b/lib/NGCP/Panel/Controller/Billing.pm @@ -38,7 +38,7 @@ sub profile_list :Chained('/') :PathPart('billing') :CaptureArgs(0) :Does(ACL) : $c->stash(template => 'billing/list.tt'); } -sub profile_list_restricted :Chained('profile_list') :PathPart('') :CaptureArgs(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub profile_list_restricted :Chained('profile_list') :PathPart('') :CaptureArgs(0) :Does(License) :RequiresLicense('billing') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; } diff --git a/lib/NGCP/Panel/Controller/Contract.pm b/lib/NGCP/Panel/Controller/Contract.pm index a64f37bf48..88fcd40cd0 100644 --- a/lib/NGCP/Panel/Controller/Contract.pm +++ b/lib/NGCP/Panel/Controller/Contract.pm @@ -139,6 +139,10 @@ sub edit :Chained('base') :PathPart('edit') :Args(0) { $form = NGCP::Panel::Form::get("NGCP::Panel::Form::Contract::Peering", $c); $is_peering_reseller = 1; } elsif ( NGCP::Panel::Utils::Contract::is_reseller_product( c => $c, product => $contract->product ) ) { + if (!$c->license('reseller')) { + $c->detach('/denied_page'); + return; + } $form = NGCP::Panel::Form::get("NGCP::Panel::Form::Contract::Reseller", $c); $is_peering_reseller = 1; } else { @@ -253,6 +257,13 @@ sub terminate :Chained('base') :PathPart('terminate') :Args(0) { my ($self, $c) = @_; my $contract = $c->stash->{contract}; + if ( NGCP::Panel::Utils::Contract::is_reseller_product( c => $c, product => $contract->product ) ) { + if (!$c->license('reseller')) { + $c->detach('/denied_page'); + return; + } + } + if ($contract->id == 1) { NGCP::Panel::Utils::Message::error( c => $c, @@ -490,7 +501,7 @@ sub reseller_ajax_contract_filter :Chained('reseller_list') :PathPart('ajax/cont $c->detach( $c->view("JSON") ); } -sub reseller_create :Chained('reseller_list') :PathPart('create') :Args(0) { +sub reseller_create :Chained('reseller_list') :PathPart('create') :Args(0) :Does(License) :RequiresLicense('batch_provisioning') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; my $posted = ($c->request->method eq 'POST'); diff --git a/lib/NGCP/Panel/Controller/Customer.pm b/lib/NGCP/Panel/Controller/Customer.pm index 323fca3e74..0394104f3a 100644 --- a/lib/NGCP/Panel/Controller/Customer.pm +++ b/lib/NGCP/Panel/Controller/Customer.pm @@ -190,7 +190,7 @@ sub create :Chained('list_customer') :PathPart('create') :Args(0) { delete $params->{contact}; } - if($c->config->{features}->{cloudpbx}) { + if($c->license('pbx') && $c->config->{features}->{cloudpbx}) { $form = NGCP::Panel::Form::get("NGCP::Panel::Form::Contract::ProductSelect", $c); } else { $form = NGCP::Panel::Form::get("NGCP::Panel::Form::Contract::Customer", $c); @@ -374,7 +374,7 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) { # only show the extension if it's a pbx extension. otherwise (and in case of a pilot?) show the # number - if($c->config->{features}->{cloudpbx} && $product->class eq "pbxaccount") { + if($c->license('pbx') && $c->config->{features}->{cloudpbx} && $product->class eq "pbxaccount") { $c->stash->{subscriber_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [ { name => "id", search => 1, title => $c->loc("#") }, { name => "username", search => 1, title => $c->loc("Name") }, @@ -444,7 +444,7 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) { $c->stash->{subscribers} = $subscribers_rs->search_rs({'provisioning_voip_subscriber.is_pbx_group' => 0}); - if($c->config->{features}->{cloudpbx}) { + if($c->license('pbx') && $c->config->{features}->{cloudpbx}) { $c->stash->{pbx_groups} = $subscribers_rs->search_rs({'provisioning_voip_subscriber.is_pbx_group' => 1}); } @@ -541,7 +541,7 @@ sub edit :Chained('base_restricted') :PathPart('edit') :Args(0) { $params->{billing_profile}->{id} = $billing_profile->id; $params = merge($params, $c->session->{created_objects}); # TODO: created billing profiles/networks will not be pre-selected #$c->log->debug('customer/edit'); - if($c->config->{features}->{cloudpbx}) { + if($c->license('pbx') && $c->config->{features}->{cloudpbx}) { #$c->log->debug('ProductSelect'); $form = NGCP::Panel::Form::get("NGCP::Panel::Form::Contract::ProductSelect", $c); } else { @@ -787,7 +787,7 @@ sub subscriber_create :Chained('base') :PathPart('subscriber/create') :Args(0) { my $params = {}; - if($c->config->{features}->{cloudpbx} && $pbx) { + if($c->license('pbx') && $c->config->{features}->{cloudpbx} && $pbx) { $c->stash(customer_id => $c->stash->{contract}->id); # we need to create a pilot subscriber first unless($c->stash->{pilot}) { @@ -2560,7 +2560,7 @@ sub phonebook_root :Chained('base') :PathPart('phonebook') :Args(0) { my ($self, $c) = @_; } -sub phonebook_create :Chained('base') :PathPart('phonebook/create') :Args(0) { +sub phonebook_create :Chained('base') :PathPart('phonebook/create') :Args(0) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; my $contract = $c->stash->{contract}; @@ -2609,7 +2609,7 @@ sub phonebook_create :Chained('base') :PathPart('phonebook/create') :Args(0) { ); } -sub phonebook_base :Chained('base') :PathPart('phonebook') :CaptureArgs(1) { +sub phonebook_base :Chained('base') :PathPart('phonebook') :CaptureArgs(1) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c, $phonebook_id) = @_; unless($phonebook_id && is_int($phonebook_id)) { @@ -2708,7 +2708,7 @@ sub phonebook_delete :Chained('phonebook_base') :PathPart('delete') :Args(0) { NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for_action("/customer/details", [$contract->id])); } -sub phonebook_upload_csv :Chained('base') :PathPart('phonebook_upload_csv') :Args(0) { +sub phonebook_upload_csv :Chained('base') :PathPart('phonebook_upload_csv') :Args(0) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; my $contract = $c->stash->{contract}; @@ -2726,7 +2726,7 @@ sub phonebook_upload_csv :Chained('base') :PathPart('phonebook_upload_csv') :Arg return; } -sub phonebook_download_csv :Chained('base') :PathPart('phonebook_download_csv') :Args(0) { +sub phonebook_download_csv :Chained('base') :PathPart('phonebook_download_csv') :Args(0) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; my $contract = $c->stash->{contract}; diff --git a/lib/NGCP/Panel/Controller/Device.pm b/lib/NGCP/Panel/Controller/Device.pm index 36f5650dcf..81ec9edf03 100644 --- a/lib/NGCP/Panel/Controller/Device.pm +++ b/lib/NGCP/Panel/Controller/Device.pm @@ -144,7 +144,7 @@ sub base :Chained('/') :PathPart('device') :CaptureArgs(0) { ); } -sub root :Chained('base') :PathPart('') :Args(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub root :Chained('base') :PathPart('') :Args(0) :Does(License) :RequiresLicense('pbx') :RequiresLicense('device_provisioning') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; } diff --git a/lib/NGCP/Panel/Controller/Header.pm b/lib/NGCP/Panel/Controller/Header.pm index 69bfa7f436..042a0cd816 100644 --- a/lib/NGCP/Panel/Controller/Header.pm +++ b/lib/NGCP/Panel/Controller/Header.pm @@ -11,7 +11,7 @@ use NGCP::Panel::Utils::Rewrite; use NGCP::Panel::Utils::Navigation; use NGCP::Panel::Utils::HeaderManipulations; -sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub auto :Does(License) :RequiresLicense('header_manipulation') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; $c->log->debug(__PACKAGE__ . '::auto'); my $ngcp_type = $c->config->{general}{ngcp_type} // ''; diff --git a/lib/NGCP/Panel/Controller/Invoice.pm b/lib/NGCP/Panel/Controller/Invoice.pm index 2453cfcf3e..c9f0fb03d9 100644 --- a/lib/NGCP/Panel/Controller/Invoice.pm +++ b/lib/NGCP/Panel/Controller/Invoice.pm @@ -50,6 +50,10 @@ sub inv_list :Chained('/') :PathPart('invoice') :CaptureArgs(0) :Does(ACL) :ACLD $c->stash(template => 'invoice/invoice_list.tt'); } +sub inv_list_restricted :Chained('/') :PathPart('invoice') :CaptureArgs(0) :Does(License) :RequiresLicense('invoice') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) :AllowedRole(subscriberadmin) { + my ($self, $c) = @_; +} + sub customer_inv_list :Chained('/') :PathPart('invoice/customer') :CaptureArgs(1) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) :AllowedRole(ccareadmin) :AllowedRole(ccare) :AllowedRole(subscriberadmin) { my ( $self, $c, $contract_id ) = @_; @@ -118,7 +122,7 @@ sub customer_ajax :Chained('customer_inv_list') :PathPart('ajax') :Args(0) { $c->detach( $c->view("JSON") ); } -sub base :Chained('inv_list') :PathPart('') :CaptureArgs(1) { +sub base :Chained('inv_list_restricted') :PathPart('') :CaptureArgs(1) { my ($self, $c, $inv_id) = @_; unless($inv_id && is_int($inv_id)) { @@ -142,7 +146,7 @@ sub base :Chained('inv_list') :PathPart('') :CaptureArgs(1) { $c->stash(inv => $res); } -sub create :Chained('inv_list') :PathPart('create') :Args() :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub create :Chained('inv_list_restricted') :PathPart('create') :Args() :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; my $posted = ($c->request->method eq 'POST'); diff --git a/lib/NGCP/Panel/Controller/InvoiceTemplate.pm b/lib/NGCP/Panel/Controller/InvoiceTemplate.pm index b1c6fcb8b3..8785d20709 100644 --- a/lib/NGCP/Panel/Controller/InvoiceTemplate.pm +++ b/lib/NGCP/Panel/Controller/InvoiceTemplate.pm @@ -39,7 +39,7 @@ sub template_list :Chained('/') :PathPart('invoicetemplate') :CaptureArgs(0) :Do $c->stash(template => 'invoice/template_list.tt'); } -sub template_list_restricted :Chained('template_list') :PathPart('') :CaptureArgs(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub template_list_restricted :Chained('template_list') :PathPart('') :CaptureArgs(0) :Does(License) :RequiresLicense('invoice') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; } diff --git a/lib/NGCP/Panel/Controller/Network.pm b/lib/NGCP/Panel/Controller/Network.pm index e5a2a48109..5612881c8b 100644 --- a/lib/NGCP/Panel/Controller/Network.pm +++ b/lib/NGCP/Panel/Controller/Network.pm @@ -35,7 +35,7 @@ sub network_list :Chained('/') :PathPart('network') :CaptureArgs(0) :Does(ACL) : template => 'network/list.tt'); } -sub network_list_restricted :Chained('network_list') :PathPart('') :CaptureArgs(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub network_list_restricted :Chained('network_list') :PathPart('') :CaptureArgs(0) :Does(License) :RequiresLicense('billing') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; } diff --git a/lib/NGCP/Panel/Controller/Package.pm b/lib/NGCP/Panel/Controller/Package.pm index de7cbbcd79..a5334383ca 100644 --- a/lib/NGCP/Panel/Controller/Package.pm +++ b/lib/NGCP/Panel/Controller/Package.pm @@ -36,7 +36,7 @@ sub package_list :Chained('/') :PathPart('package') :CaptureArgs(0) :Does(ACL) : template => 'package/list.tt'); } -sub package_list_restricted :Chained('package_list') :PathPart('') :CaptureArgs(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub package_list_restricted :Chained('package_list') :PathPart('') :CaptureArgs(0) :Does(License) :RequiresLicense('billing') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; } diff --git a/lib/NGCP/Panel/Controller/Pbx.pm b/lib/NGCP/Panel/Controller/Pbx.pm index 6e4ede737c..2361a6a60c 100644 --- a/lib/NGCP/Panel/Controller/Pbx.pm +++ b/lib/NGCP/Panel/Controller/Pbx.pm @@ -15,7 +15,7 @@ sub auto :Private { return 1; } -sub base :Chained('/') :PathPart('') :CaptureArgs(0) { +sub base :Chained('/') :PathPart('') :CaptureArgs(0) :Does(License) :RequiresLicense('device_provisioning') :RequiresLicense('pbx') :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; $c->stash->{schema} = $c->config->{deviceprovisioning}->{secure} ? 'https' : 'http'; diff --git a/lib/NGCP/Panel/Controller/Phonebook.pm b/lib/NGCP/Panel/Controller/Phonebook.pm index 36c42327d4..eef402cdcd 100644 --- a/lib/NGCP/Panel/Controller/Phonebook.pm +++ b/lib/NGCP/Panel/Controller/Phonebook.pm @@ -10,7 +10,7 @@ use NGCP::Panel::Utils::Message; use NGCP::Panel::Utils::Navigation; use NGCP::Panel::Utils::Phonebook; -sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub auto :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; $c->log->debug(__PACKAGE__ . '::auto'); my $ngcp_type = $c->config->{general}{ngcp_type} // ''; diff --git a/lib/NGCP/Panel/Controller/Reseller.pm b/lib/NGCP/Panel/Controller/Reseller.pm index cd69fc30e0..b80f2eb744 100644 --- a/lib/NGCP/Panel/Controller/Reseller.pm +++ b/lib/NGCP/Panel/Controller/Reseller.pm @@ -73,7 +73,7 @@ sub ajax :Chained('list_reseller') :PathPart('ajax') :Args(0) :Does(ACL) :ACLDet return; } -sub create :Chained('list_reseller') :PathPart('create') :Args(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) { +sub create :Chained('list_reseller') :PathPart('create') :Args(0) :Does(License) :RequiresLicense('reseller') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) { my ($self, $c) = @_; $c->detach('/denied_page') @@ -136,7 +136,7 @@ sub create :Chained('list_reseller') :PathPart('create') :Args(0) :Does(ACL) :AC $c->stash(form => $form); } -sub base :Chained('list_reseller') :PathPart('') :CaptureArgs(1) { +sub base :Chained('list_reseller_restricted') :PathPart('') :CaptureArgs(1) :Does(License) :RequiresLicense('reseller') :LicenseDetachTo('/denied_page') { my ($self, $c, $reseller_id) = @_; unless($reseller_id && is_int($reseller_id)) { @@ -410,7 +410,7 @@ sub ajax_contract :Chained('list_reseller') :PathPart('ajax_contract') :Args(0) $c->detach( $c->view("JSON") ); } -sub create_defaults :Path('create_defaults') :Args(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) { +sub create_defaults :Path('create_defaults') :Args(0) :Does(License) :RequiresLicense('reseller') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) { my ($self, $c) = @_; $c->detach('/denied_page') unless $c->request->method eq 'POST'; $c->detach('/denied_page') @@ -754,7 +754,7 @@ sub phonebook_root :Chained('base_details') :PathPart('phonebook') :Args(0) { my ($self, $c) = @_; } -sub phonebook_create :Chained('base_details') :PathPart('phonebook/create') :Args(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { +sub phonebook_create :Chained('base_details') :PathPart('phonebook/create') :Args(0) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; my $reseller = $c->stash->{reseller}->first; @@ -803,7 +803,7 @@ sub phonebook_create :Chained('base_details') :PathPart('phonebook/create') :Arg ); } -sub phonebook_base :Chained('base_details') :PathPart('phonebook') :CaptureArgs(1) { +sub phonebook_base :Chained('base_details') :PathPart('phonebook') :CaptureArgs(1) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c, $phonebook_id) = @_; unless($phonebook_id && is_int($phonebook_id)) { @@ -902,7 +902,7 @@ sub phonebook_delete :Chained('phonebook_base') :PathPart('delete') :Args(0) :Do NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for_action("/reseller/details", [$reseller->id])); } -sub phonebook_upload_csv :Chained('base_details') :PathPart('phonebook_upload_csv') :Args(0) { +sub phonebook_upload_csv :Chained('base_details') :PathPart('phonebook_upload_csv') :Args(0) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; my $reseller = $c->stash->{reseller}->first; @@ -920,7 +920,7 @@ sub phonebook_upload_csv :Chained('base_details') :PathPart('phonebook_upload_cs return; } -sub phonebook_download_csv :Chained('base') :PathPart('phonebook_download_csv') :Args(0) { +sub phonebook_download_csv :Chained('base') :PathPart('phonebook_download_csv') :Args(0) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; my $reseller = $c->stash->{reseller}->first; diff --git a/lib/NGCP/Panel/Controller/Sound.pm b/lib/NGCP/Panel/Controller/Sound.pm index ee0852bd89..586b401768 100644 --- a/lib/NGCP/Panel/Controller/Sound.pm +++ b/lib/NGCP/Panel/Controller/Sound.pm @@ -19,7 +19,7 @@ sub auto :Private { NGCP::Panel::Utils::Navigation::check_redirect_chain(c => $c); # only allow access to admin/reseller if cloudpbx is not enabled - if(!$c->config->{features}->{cloudpbx} && + if((!$c->license('pbx') || !$c->config->{features}->{cloudpbx}) && $c->user->roles ne "admin" && $c->user->roles ne "reseller") { @@ -215,7 +215,7 @@ sub edit :Chained('base') :PathPart('edit') { } else { $form = NGCP::Panel::Form::get("NGCP::Panel::Form::Sound::CustomerSet", $c); } - unless ($c->config->{features}->{cloudpbx} || $params->{contract}{id} ) { + unless (($c->license('pbx') && $c->config->{features}->{cloudpbx}) || $params->{contract}{id} ) { my $form_render_list = $form->block('fields')->render_list; $form->block('fields')->render_list([ grep {$_ !~ m/^contract(_default)?/} @{ $form_render_list } ]); } @@ -409,7 +409,7 @@ sub create :Chained('sets_list') :PathPart('create') :Args() { } else { $form = NGCP::Panel::Form::get("NGCP::Panel::Form::Sound::CustomerSet", $c); } - unless ($c->config->{features}->{cloudpbx}) { + unless ($c->license('pbx') && $c->config->{features}->{cloudpbx}) { my $form_render_list = $form->block('fields')->render_list; $form->block('fields')->render_list([ grep {$_ !~ m/^contract(_default)?/} @{ $form_render_list } ]); } diff --git a/lib/NGCP/Panel/Controller/Subscriber.pm b/lib/NGCP/Panel/Controller/Subscriber.pm index 48ce5ea240..b00f9a8edd 100644 --- a/lib/NGCP/Panel/Controller/Subscriber.pm +++ b/lib/NGCP/Panel/Controller/Subscriber.pm @@ -226,7 +226,7 @@ sub base :Chained('sub_list') :PathPart('') :CaptureArgs(1) { ); } -sub webfax :Chained('base') :PathPart('webfax') :Args(0) { +sub webfax :Chained('base') :Does(License) :RequiresLicense('fax') :LicenseDetachTo('/denied_page') :PathPart('webfax') :Args(0) { my ($self, $c) = @_; $c->stash( @@ -234,7 +234,7 @@ sub webfax :Chained('base') :PathPart('webfax') :Args(0) { ); } -sub webfax_send :Chained('base') :PathPart('webfax/send') :Args(0) { +sub webfax_send :Chained('base') :Does(License) :RequiresLicense('fax') :LicenseDetachTo('/denied_page') :PathPart('webfax/send') :Args(0) { my ($self, $c) = @_; my $subscriber = $c->stash->{subscriber}; @@ -3653,7 +3653,7 @@ sub edit_voicebox :Chained('base') :PathPart('preferences/voicebox/edit') :Args( ); } -sub edit_fax :Chained('base') :PathPart('preferences/fax/edit') :Args(1) { +sub edit_fax :Chained('base') :PathPart('preferences/fax/edit') :Args(1) :Does(License) :RequiresLicense('fax') :LicenseDetachTo('/denied_page') { my ($self, $c, $attribute) = @_; $c->detach('/denied_page') @@ -3794,7 +3794,7 @@ sub edit_fax :Chained('base') :PathPart('preferences/fax/edit') :Args(1) { ); } -sub edit_mail_to_fax :Chained('base') :PathPart('preferences/mail_to_fax/edit') :Args(1) { +sub edit_mail_to_fax :Chained('base') :PathPart('preferences/mail_to_fax/edit') :Args(1) :Does(License) :RequiresLicense('fax') :LicenseDetachTo('/denied_page') { my ($self, $c, $attribute) = @_; $c->detach('/denied_page') @@ -5489,7 +5489,7 @@ sub phonebook_root :Chained('master') :PathPart('phonebook') :Args(0) { my ($self, $c) = @_; } -sub phonebook_create :Chained('master') :PathPart('phonebook/create') :Args(0) { +sub phonebook_create :Chained('master') :PathPart('phonebook/create') :Args(0) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; my $subscriber = $c->stash->{subscriber}; @@ -5539,7 +5539,7 @@ sub phonebook_create :Chained('master') :PathPart('phonebook/create') :Args(0) { ); } -sub phonebook_base :Chained('master') :PathPart('phonebook') :CaptureArgs(1) { +sub phonebook_base :Chained('master') :PathPart('phonebook') :CaptureArgs(1) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c, $phonebook_id) = @_; unless($phonebook_id && is_int($phonebook_id)) { @@ -5639,7 +5639,7 @@ sub phonebook_delete :Chained('phonebook_base') :PathPart('delete') :Args(0) { NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for_action("/subscriber/details", [$subscriber->id])); } -sub phonebook_upload_csv :Chained('master') :PathPart('phonebook_upload_csv') :Args(0) { +sub phonebook_upload_csv :Chained('master') :PathPart('phonebook_upload_csv') :Args(0) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; my $subscriber = $c->stash->{subscriber}; @@ -5657,7 +5657,7 @@ sub phonebook_upload_csv :Chained('master') :PathPart('phonebook_upload_csv') :A return; } -sub phonebook_download_csv :Chained('base') :PathPart('phonebook_download_csv') :Args(0) { +sub phonebook_download_csv :Chained('base') :PathPart('phonebook_download_csv') :Args(0) :Does(License) :RequiresLicense('phonebook') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; my $subscriber = $c->stash->{subscriber}; @@ -5696,7 +5696,7 @@ sub header_rules_ajax :Chained('header_rules_list') :PathPart('ajax') :Args(0) { ); } -sub header_rules_base :Chained('header_rules_list') :PathPart('') :CaptureArgs(1) { +sub header_rules_base :Chained('header_rules_list') :PathPart('') :CaptureArgs(1) :Does(License) :RequiresLicense('header_manipulation') :LicenseDetachTo('/denied_page') { my ($self, $c, $rule_id) = @_; return NGCP::Panel::Utils::HeaderManipulations::ui_rules_base( @@ -5720,7 +5720,7 @@ sub header_rules_delete :Chained('header_rules_base') :PathPart('delete') { ); } -sub header_rules_create :Chained('header_rules_list') :PathPart('create') :Args(0) { +sub header_rules_create :Chained('header_rules_list') :PathPart('create') :Args(0) :Does(License) :RequiresLicense('header_manipulation') :LicenseDetachTo('/denied_page') { my ($self, $c) = @_; return NGCP::Panel::Utils::HeaderManipulations::ui_rules_create( diff --git a/lib/NGCP/Panel/Controller/Voucher.pm b/lib/NGCP/Panel/Controller/Voucher.pm index 7c1810bc8d..c6513239ed 100644 --- a/lib/NGCP/Panel/Controller/Voucher.pm +++ b/lib/NGCP/Panel/Controller/Voucher.pm @@ -27,7 +27,7 @@ sub voucher_list :Chained('/') :PathPart('voucher') :CaptureArgs(0) { my ( $self, $c ) = @_; $c->detach('/denied_page') - unless($c->config->{features}->{voucher}); + unless($c->license('billing') && $c->config->{features}->{voucher}); my $voucher_rs = $c->model('DB')->resultset('vouchers'); #->search_rs(undef, { #'join' => { 'customer' => 'contact'}, diff --git a/lib/NGCP/Panel/Form/DestinationSet.pm b/lib/NGCP/Panel/Form/DestinationSet.pm index 73b2f13863..a3a5b62e02 100644 --- a/lib/NGCP/Panel/Form/DestinationSet.pm +++ b/lib/NGCP/Panel/Form/DestinationSet.pm @@ -62,7 +62,7 @@ sub build_destinations { if($c->config->{features}->{callingcard}); push @options, { label => 'Call Through', value => 'callthrough' } if($c->config->{features}->{callthrough}); - if($c->config->{features}->{cloudpbx} && $c->stash->{pbx}){ + if($c->license('pbx') && $c->config->{features}->{cloudpbx} && $c->stash->{pbx}){ push @options, { label => 'Auto Attendant', value => 'autoattendant' }, { label => 'Office Hours Announcement', value => 'officehours'} ; diff --git a/lib/NGCP/Panel/Form/SubscriberCFSimple.pm b/lib/NGCP/Panel/Form/SubscriberCFSimple.pm index 30f9b8c40a..c65831d033 100644 --- a/lib/NGCP/Panel/Form/SubscriberCFSimple.pm +++ b/lib/NGCP/Panel/Form/SubscriberCFSimple.pm @@ -65,7 +65,7 @@ sub build_destinations { if($c->config->{features}->{callingcard}); push @options, { label => 'Call Through', value => 'callthrough' } if($c->config->{features}->{callthrough}); - if($c->config->{features}->{cloudpbx} && $c->stash->{pbx}){ + if($c->license('pbx') && $c->config->{features}->{cloudpbx} && $c->stash->{pbx}){ push @options, { label => 'Auto Attendant', value => 'autoattendant' }, { label => 'Office Hours Announcement', value => 'officehours' }; diff --git a/lib/NGCP/Panel/Role/API.pm b/lib/NGCP/Panel/Role/API.pm index 2dee5b8d4f..d6bb4af9f3 100644 --- a/lib/NGCP/Panel/Role/API.pm +++ b/lib/NGCP/Panel/Role/API.pm @@ -26,7 +26,7 @@ use Data::HAL qw(); use Data::HAL::Link qw(); use NGCP::Panel::Utils::ValidateJSON qw(); use NGCP::Panel::Utils::Journal qw(); -use List::Util qw(any); +use List::Util qw(any all); #It is expected to work for all our 3 common cases: #1. Body is the plain json data @@ -1746,6 +1746,27 @@ sub check_allowed_ngcp_types { return 1; } +sub check_licenses { + my ($self, $c) = @_; + + my $required_licenses = $self->get_config('required_licenses') // []; + if (ref $required_licenses eq 'ARRAY') { + if (@{$required_licenses} && + ! all { $c->license($_) } @{$required_licenses}) { + return; + } + } elsif (ref $required_licenses eq 'HASH') { + my $method = $c->req->method; + if (my $method_licenses = $required_licenses->{$method}) { + if (@{$method_licenses} && + ! all { $c->license($_) } @{$method_licenses}) { + return; + } + } + } + return 1; +} + sub validate_request { my ($self, $c) = @_; @@ -1845,6 +1866,10 @@ sub allowed_ngcp_types { return $_[0]->config->{allowed_ngcp_types}; } +sub required_licenses { + return $_[0]->config->{required_licenses}; +} + #------ /accessors --- sub return_representation{ my($self, $c, %params) = @_; diff --git a/lib/NGCP/Panel/Role/API/Subscribers.pm b/lib/NGCP/Panel/Role/API/Subscribers.pm index 0f90df19e2..652615ae8a 100644 --- a/lib/NGCP/Panel/Role/API/Subscribers.pm +++ b/lib/NGCP/Panel/Role/API/Subscribers.pm @@ -617,7 +617,7 @@ sub subscriberadmin_write_access { && $c->config->{privileges}->{subscriberadmin}->{subscribers} =~/write/ ) || - ( $c->config->{features}->{cloudpbx} #user can disable pbx feature after some time of using it + ( $c->license('pbx') && $c->config->{features}->{cloudpbx} #user can disable pbx feature after some time of using it && $c->user->contract->product->class eq 'pbxaccount' ) ) { diff --git a/lib/NGCP/Panel/Role/Entities.pm b/lib/NGCP/Panel/Role/Entities.pm index 241bf3ce2d..56cfa1f871 100644 --- a/lib/NGCP/Panel/Role/Entities.pm +++ b/lib/NGCP/Panel/Role/Entities.pm @@ -24,6 +24,10 @@ sub auto :Private { $self->error($c, HTTP_NOT_FOUND, "Path not found"); return; } + if (! $self->check_licenses($c)) { + $self->error($c, HTTP_FORBIDDEN, "Invalid license"); + return; + } return $self->validate_request($c); } diff --git a/lib/NGCP/Panel/Role/EntitiesItem.pm b/lib/NGCP/Panel/Role/EntitiesItem.pm index 2b50c60a97..0602da1eb7 100644 --- a/lib/NGCP/Panel/Role/EntitiesItem.pm +++ b/lib/NGCP/Panel/Role/EntitiesItem.pm @@ -29,6 +29,10 @@ sub auto :Private { $self->error($c, HTTP_NOT_FOUND, "Path not found"); return; } + if (! $self->check_licenses($c)) { + $self->error($c, HTTP_FORBIDDEN, "Invalid license"); + return; + } return $self->validate_request($c); } diff --git a/lib/NGCP/Panel/Utils/License.pm b/lib/NGCP/Panel/Utils/License.pm index 9986f15b68..cd88ed6adb 100644 --- a/lib/NGCP/Panel/Utils/License.pm +++ b/lib/NGCP/Panel/Utils/License.pm @@ -5,55 +5,101 @@ use warnings; use Sipwise::Base; use List::Util qw(none); +use Fcntl; +use IO::Select; + sub get_license_status { - my ($ref) = @_; + my ($c, $ref) = @_; my $fd; { no autodie qw(open); - if (!open($fd, '<', '/proc/ngcp/check')) { + if (!sysopen($fd, '/proc/ngcp/check', O_NONBLOCK|O_RDONLY)) { + $c->log->error('License status check failed: could not check license'); return 'missing'; } } - my $status = <$fd>; + my $status = ''; + my @h = IO::Select->new($fd)->can_read(1); + map { $status = <$_> } @h; close($fd); + unless ($status) { + $c->log->error('License status check failed: missing license'); + return 'missing'; + } chomp($status); if ($status =~ /^ok/) { return 'ok'; } if ($status =~ /missing license/) { + $c->log->error("License status check failed: $status"); return 'missing'; } if ($status =~ /^(warning|error) \((.*)\)$/) { if (ref($ref) eq 'SCALAR') { - $$ref = $2; + $$ref = $status; } - return $1; + if ($status =~ /^warning/) { + # do not spam logs with warnings as it's related to graceful thresholds + } else { + $c->log->error("License status check failed: $status"); + } + return $status; } if (ref($ref) eq 'SCALAR') { $$ref = 'internal error'; } + $c->log->error("License status check failed: internal error"); return 'error'; } sub is_license_status { - my (@allowed) = @_; - my $status = get_license_status(); + my $c = shift; + my @allowed = @_; + my $status = get_license_status($c); return scalar grep {$_ eq $status} @allowed; } sub is_license_error { - my (@allowed) = @_; + my $c = shift; + my @allowed = @_; @allowed or @allowed = ('error'); my $ext; - my $status = get_license_status(\$ext); + my $status = get_license_status($c, \$ext); if (!grep {$_ eq $status} @allowed) { return 0; } return $ext || $status; } +sub get_license { + my ($c, $lic_name) = @_; + + return 1 if $c->config->{general}{ngcp_type} eq 'spce'; + + my $proc_dir = '/proc/ngcp/flags'; + unless (-d $proc_dir) { + $c->log->error("Failed to access $proc_dir"); + return; + }; + + my $lic_file = $proc_dir . '/' . $lic_name; + return unless (-r $lic_file); + + sysopen(my $fd, "$lic_file", O_NONBLOCK|O_RDONLY) || do { + $c->log->error("Failed to open license file $lic_name: $!"); + return; + }; + my $enabled; + my @h = IO::Select->new($fd)->can_read(1); + map { $enabled = <$_> } @h; + close $fd; + chomp($enabled) if defined $enabled; + + return $enabled; +} + sub get_licenses { my $c = shift; @@ -71,14 +117,16 @@ sub get_licenses { while (readdir($dh)) { my $lf = $_; next if $lf =~ /^\.+$/; - open(my $fh, '<', "$proc_dir/$lf") || do { + sysopen(my $fd, "$proc_dir/$lf", O_NONBLOCK|O_RDONLY) || do { $c->log->error("Failed to open license file $lf: $!"); next; }; - my $enabled = <$fh>; + my $enabled; + my @h = IO::Select->new($fd)->can_read(1); + map { $enabled = <$_> } @h; + close $fd; chomp($enabled) if defined $enabled; push @lics, $lf if $enabled && $enabled == 1; - close $fh; } closedir $dh; my @sorted_lics = sort @lics; @@ -119,14 +167,16 @@ sub get_license_meta { my $lf = $_; next if $lf =~ /^\.+$/; next if none { $lf eq $_ } @collect; - open(my $fh, '<', "$proc_dir/$lf") || do { + sysopen(my $fd, "$proc_dir/$lf", O_NONBLOCK|O_RDONLY) || do { $c->log->error("Failed to open license file $lf: $!"); next; }; - my $value = <$fh>; + my $value; + my @h = IO::Select->new($fd)->can_read(1); + map { $value = <$_> } @h; + close $fd; chomp($value) if defined $value; $meta->{$lf} = $value =~ /^-?\d+(\.\d+)?$/ ? $value+0 : $value; - close $fh; } closedir $dh; return $meta; @@ -158,7 +208,7 @@ a more detailed status description is written into that scalar in the 'warning' and 'error' cases. Example: -my $status = get_license_status(\$ext_status); +my $status = get_license_status($c, \$ext_status); =head2 is_license_status @@ -166,16 +216,16 @@ Takes a list of strings as argument list. Returns true or false if the license status is one of the status names given in the argument list. Example: -if (is_license_status(qw(missing error))) ... +if (is_license_status($c, qw(missing error))) ... =head2 is_license_error -Similar to is_license_status() but returns the status string instead of true if +Similar to is_license_status($c) but returns the status string instead of true if the license status is one of the values given. If the argument list is empty, it defaults to ('error'). Example: -if (my $status = is_license_error()) ... +if (my $status = is_license_error($c)) ... =head1 AUTHOR diff --git a/lib/NGCP/Panel/Utils/Preferences.pm b/lib/NGCP/Panel/Utils/Preferences.pm index 2514229a0b..342c2487d1 100644 --- a/lib/NGCP/Panel/Utils/Preferences.pm +++ b/lib/NGCP/Panel/Utils/Preferences.pm @@ -1276,7 +1276,7 @@ sub load_preference_list { my $customer_view = $params{customer_view} // 0; my $subscriber_view = $params{subscriber_view} // 0; - my $cloudpbx_enabled = $c->config->{features}{cloudpbx}; + my $cloudpbx_enabled = $c->license('pbx') && $c->config->{features}{cloudpbx}; my $search_conditions = $params{search_conditions}; diff --git a/lib/NGCP/Panel/Utils/Sounds.pm b/lib/NGCP/Panel/Utils/Sounds.pm index 25e83a671f..f4d57d5652 100644 --- a/lib/NGCP/Panel/Utils/Sounds.pm +++ b/lib/NGCP/Panel/Utils/Sounds.pm @@ -182,10 +182,10 @@ sub get_file_handles { order_by => { -asc => 'handles.name' } }); - unless($c->config->{features}->{cloudpbx}) { + unless($c->license('pbx') && $c->config->{features}->{cloudpbx}) { $handles_rs = $handles_rs->search({ 'group.name' => { '!=' => 'pbx' } }); } - unless($c->config->{features}->{cloudpbx} || $c->config->{features}->{musiconhold}) { + unless(($c->license('pbx') && $c->config->{features}->{cloudpbx}) || $c->config->{features}->{musiconhold}) { $handles_rs = $handles_rs->search({ 'group.name' => { '!=' => 'music_on_hold' } }); } unless($c->config->{features}->{callingcard}) { diff --git a/lib/NGCP/Panel/Utils/Subscriber.pm b/lib/NGCP/Panel/Utils/Subscriber.pm index 603fe43e9b..5dfd9da33a 100644 --- a/lib/NGCP/Panel/Utils/Subscriber.pm +++ b/lib/NGCP/Panel/Utils/Subscriber.pm @@ -242,7 +242,7 @@ sub prepare_resource { delete $resource->{domain}; $resource->{domain_id} = $domain->id; } elsif ($c->user->roles eq "subscriberadmin") { - if ( $c->config->{features}->{cloudpbx} && $c->user->contract->product->class eq 'pbxaccount') { + if ( $c->license('pbx') && $c->config->{features}->{cloudpbx} && $c->user->contract->product->class eq 'pbxaccount') { my $pilot = $schema->resultset('provisioning_voip_subscribers')->search({ account_id => $c->user->account_id, is_pbx_pilot => 1, @@ -431,7 +431,7 @@ sub prepare_resource { delete $resource->{$pref}; } $admin = $resource->{admin} // 0; - } elsif($c->config->{features}->{cloudpbx}) { + } elsif($c->license('pbx') && $c->config->{features}->{cloudpbx}) { $preferences->{cloud_pbx} = 1; my $subs = $c->model('DB')->resultset('voip_subscribers')->search({ contract_id => $customer->id, @@ -617,7 +617,7 @@ sub create_subscriber { my $prov_domain = $schema->resultset('voip_domains') ->find({domain => $billing_domain->domain}); - if (my $status = NGCP::Panel::Utils::License::is_license_error()) { + if (my $status = NGCP::Panel::Utils::License::is_license_error($c)) { $c->log->warn("invalid license status: $status"); # die("invalid license status: $status"); } @@ -2512,7 +2512,7 @@ sub create_cf_destination{ sub get_subscriber_pbx_status{ my($c, $subscriber) = @_; - if($c->config->{features}->{cloudpbx}) { + if($c->license('pbx') && $c->config->{features}->{cloudpbx}) { my $pbx_pref = NGCP::Panel::Utils::Preferences::get_usr_preference_rs( c => $c, attribute => 'cloud_pbx', diff --git a/share/templates/billing/list.tt b/share/templates/billing/list.tt index 7a0daa04b6..671014d8ec 100644 --- a/share/templates/billing/list.tt +++ b/share/templates/billing/list.tt @@ -21,7 +21,7 @@ { name = c.loc('Fees'), uri = "/billing/'+full[\"id\"]+'/fees", class = 'btn-small btn-tertiary', icon = 'icon-shopping-cart' }, { name = c.loc('Off-Peaktimes'), uri = "/billing/'+full[\"id\"]+'/peaktimes", class = 'btn-small btn-tertiary', icon = 'icon-time' }, ]; - IF c.user.roles == "admin" || c.user.roles == "reseller"; + IF c.license('billing') && (c.user.roles == "admin" || c.user.roles == "reseller"); helper.top_buttons = [ { name = c.loc('Create Billing Profile'), uri = c.uri_for('/billing/create'), icon = 'icon-star' }, ]; diff --git a/share/templates/contract/list.tt b/share/templates/contract/list.tt index 8777e06a02..0fcd853c10 100644 --- a/share/templates/contract/list.tt +++ b/share/templates/contract/list.tt @@ -73,10 +73,16 @@ $( document ).ready(function() { { name = c.loc('Edit'), uri = "/contract/'+full.id+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' }, { name = c.loc('Terminate'), uri = "/contract/'+full.id+'/terminate", class = 'btn-small btn-secondary', icon = 'icon-remove' }, ]; - helper.top_buttons = [ - { name = c.loc('Create Peering Contract'), uri = c.uri_for_action('/contract/peering_create'), icon = 'icon-star' }, - { name = c.loc('Create Reseller Contract'), uri = c.uri_for_action('/contract/reseller_create'), icon = 'icon-star' }, - ]; + IF c.license('reseller'); + helper.top_buttons = [ + { name = c.loc('Create Peering Contract'), uri = c.uri_for_action('/contract/peering_create'), icon = 'icon-star' }, + { name = c.loc('Create Reseller Contract'), uri = c.uri_for_action('/contract/reseller_create'), icon = 'icon-star' }, + ]; + ELSE; + helper.top_buttons = [ + { name = c.loc('Create Peering Contract'), uri = c.uri_for_action('/contract/peering_create'), icon = 'icon-star' }, + ]; + END; END; PROCESS 'helpers/datatables.tt'; diff --git a/share/templates/customer/details.tt b/share/templates/customer/details.tt index 4c3923ae9f..f88c2db1e5 100644 --- a/share/templates/customer/details.tt +++ b/share/templates/customer/details.tt @@ -186,6 +186,7 @@ $(function() { + [% IF c.license('billing') -%]
[% c.loc('Billing Profile Schedule') %] @@ -225,6 +226,7 @@ $(function() {
[% END -%] + [% END -%]
@@ -238,7 +240,7 @@ $(function() { contract.max_subscribers.defined && subscriber_count < contract.max_subscribers -%]
[% c.loc('[_1] of maximum [_2] subscribers [_3] created',subscriber_count,contract.max_subscribers, - c.config.features.cloudpbx ? c.loc('(including PBX groups) ') : '') %] + c.license('pbx') && c.config.features.cloudpbx ? c.loc('(including PBX groups) ') : '') %]
[% IF !c.user.read_only -%] @@ -248,7 +250,7 @@ $(function() { [% ELSIF contract.max_subscribers.defined -%]
[% c.loc('Maximum number of [_1] subscribers [_2] created',contract.max_subscribers, - c.config.features.cloudpbx ? c.loc('(including PBX groups) ') : '') %] + c.license('pbx') && c.config.features.cloudpbx ? c.loc('(including PBX groups) ') : '') %]
[% ELSIF (c.user.roles == "subscriberadmin" && product.class == "pbxaccount") || c.user.roles == "admin" || c.user.roles == "reseller" || @@ -290,7 +292,7 @@ $(function() {
- [% IF c.config.features.cloudpbx && product.class == 'pbxaccount' && subscribers.count -%] + [% IF c.license('pbx') && c.config.features.cloudpbx && product.class == 'pbxaccount' && subscribers.count -%] + [% END -%] [% IF ((c.user.roles == "subscriberadmin" && product.class == "pbxaccount") || c.user.roles == "admin" || c.user.roles == "reseller" || @@ -775,6 +781,7 @@ $(function() { [% END -%] [% IF c.config.general.ngcp_type != 'spce' -%] + [% IF c.license('phonebook') -%] [% IF (c.user.roles == "subscriberadmin" && product.class == "pbxaccount") || c.user.roles == "admin" || c.user.roles == "reseller" || c.user.roles == "ccareadmin" || c.user.roles == "ccare" -%] @@ -821,6 +828,7 @@ $(function() { [% END -%] [% END -%] + [% END -%] @@ -901,7 +909,7 @@ $(function() { [% END -%] -[% IF c.config.features.cloudpbx && device_flag -%] +[% IF c.license('pbx') && c.config.features.cloudpbx && device_flag -%]