You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
502 lines
15 KiB
502 lines
15 KiB
package NGCP::Panel::Controller::Pbx;
|
|
use NGCP::Panel::Utils::Generic qw(:all);
|
|
use Sipwise::Base;
|
|
use parent 'Catalyst::Controller';
|
|
|
|
use NGCP::Panel::Utils::Message;
|
|
use NGCP::Panel::Utils::DateTime;
|
|
use NGCP::Panel::Utils::Contract;
|
|
use NGCP::Panel::Utils::Phonebook;
|
|
|
|
sub auto :Private {
|
|
my ($self, $c) = @_;
|
|
$c->log->debug(__PACKAGE__ . '::auto');
|
|
NGCP::Panel::Utils::Navigation::check_redirect_chain(c => $c);
|
|
return 1;
|
|
}
|
|
|
|
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';
|
|
$c->stash->{host} = $c->config->{deviceprovisioning}->{host} // $c->req->uri->host;
|
|
$c->stash->{port} = $c->config->{deviceprovisioning}->{port} // 1444;
|
|
$c->stash->{cisco_port} = $c->config->{deviceprovisioning}->{cisco_port} // 1447;
|
|
|
|
$c->log->debug("SSL_CLIENT_M_DN: " . ($c->request->env->{SSL_CLIENT_M_DN} // ""));
|
|
unless(
|
|
($c->user_exists && ($c->user->roles eq "admin" || $c->user->roles eq "reseller")) ||
|
|
defined $c->request->env->{SSL_CLIENT_M_DN}
|
|
) {
|
|
$c->response->content_type('text/plain');
|
|
if($c->config->{features}->{debug}) {
|
|
$c->response->body("403 - unauthenticated pbx access");
|
|
} else {
|
|
$c->response->body("403 - forbidden");
|
|
}
|
|
$c->response->status(403);
|
|
return;
|
|
}
|
|
}
|
|
|
|
sub spa_directory_getsearch :Chained('base') :PathPart('pbx/directory/spasearch') :Args(1) {
|
|
my ($self, $c, $id) = @_;
|
|
|
|
my $schema = $c->stash->{schema};
|
|
my $host = $c->stash->{host};
|
|
my $port = $c->stash->{cisco_port};
|
|
|
|
my $baseuri = "$schema://$host:$port/pbx/directory/spa/$id";
|
|
my $data = '';
|
|
|
|
$data = <<EOF;
|
|
<CiscoIPPhoneInput>
|
|
<Title>Search User</Title>
|
|
<Prompt>Enter (part of) Name</Prompt>
|
|
<URL>$baseuri</URL>
|
|
<InputItem>
|
|
<QueryStringParam>q</QueryStringParam>
|
|
<InputFlags>A</InputFlags>
|
|
</InputItem>
|
|
</CiscoIPPhoneInput>
|
|
EOF
|
|
|
|
$c->log->debug("providing config to $id");
|
|
$c->log->debug($data);
|
|
|
|
$c->response->content_type('text/xml');
|
|
$c->response->body($data);
|
|
return;
|
|
}
|
|
|
|
sub spa_directory_list :Chained('base') :PathPart('pbx/directory/spa') :Args(1) {
|
|
my ($self, $c, $id) = @_;
|
|
|
|
unless($id) {
|
|
$c->response->content_type('text/plain');
|
|
if($c->config->{features}->{debug}) {
|
|
$c->response->body("404 - device id not given");
|
|
} else {
|
|
$c->response->body("404 - device not found");
|
|
}
|
|
$c->response->status(404);
|
|
return;
|
|
}
|
|
|
|
$id =~ s/^([^\=]+)\=0$/$1/;
|
|
$id = lc $id;
|
|
|
|
my $dev = $c->model('DB')->resultset('autoprov_field_devices')->find({
|
|
identifier => $id
|
|
});
|
|
unless($dev) {
|
|
$c->response->content_type('text/plain');
|
|
if($c->config->{features}->{debug}) {
|
|
$c->response->body("404 - device id '" . $id . "' not found");
|
|
} else {
|
|
$c->response->body("404 - device not found");
|
|
}
|
|
$c->response->status(404);
|
|
return;
|
|
}
|
|
|
|
my $schema = $c->stash->{schema};
|
|
my $host = $c->stash->{host};
|
|
my $port = $c->stash->{cisco_port};
|
|
|
|
my $baseuri = "$schema://$host:$port/pbx/directory/spa/$id";
|
|
my $data = '';
|
|
|
|
my $delim = '?';
|
|
my $q;
|
|
my $dirsuffix = '';
|
|
if(exists $c->req->params->{q} && length($c->req->params->{q})) {
|
|
$q = $c->req->params->{q};
|
|
$baseuri .= "?q=$q";
|
|
$delim = '&';
|
|
$dirsuffix = ' (Search Results)';
|
|
}
|
|
|
|
|
|
my $customer = $dev->contract;
|
|
|
|
my $page = $c->req->params->{page} // 1;
|
|
my $rows = 10;
|
|
|
|
my $rs = $self->_get_dirsearch_rs($customer, $q);
|
|
my $total = $rs->count;
|
|
my ($nextpage, $prevpage);
|
|
|
|
if(($total / $rows) > $page ) {
|
|
$nextpage = $page + 1;
|
|
}
|
|
if($page > 1) {
|
|
$prevpage = $page - 1;
|
|
}
|
|
|
|
my @entries = ();
|
|
my %entries = ();
|
|
foreach my $sub($rs->search(undef,{page => $page, rows => $rows})->all) {
|
|
my $prov_sub = $sub->provisioning_voip_subscriber;
|
|
next unless($prov_sub && $prov_sub->pbx_extension);
|
|
my $display_name = $sub->get_column('display_name');
|
|
push @entries, { name => $display_name, ext => $prov_sub->pbx_extension };
|
|
$entries{$prov_sub->pbx_extension} = 1;
|
|
}
|
|
|
|
$self->add_phonebook_entries($c, $dev, \@entries, \%entries);
|
|
|
|
my $nexturi = $baseuri . $delim . 'page='.($nextpage//0);
|
|
my $prevuri = $baseuri . $delim . 'page='.($prevpage//0);
|
|
|
|
my $searchuri = "$schema://$host:$port/pbx/directory/spasearch/$id";
|
|
|
|
$data = "<CiscoIPPhoneDirectory><Title>PBX Address Book$dirsuffix</Title><Prompt>Select the User</Prompt>";
|
|
$data .= join '', map {"<DirectoryEntry><Name>$$_{name}</Name><Telephone>$$_{ext}</Telephone></DirectoryEntry>"} @entries;
|
|
$data .= "<SoftKeyItem><Name>Dial</Name><URL>SoftKey:Dial</URL><Position>1</Position></SoftKeyItem>";
|
|
if($prevpage) {
|
|
$data .= "<SoftKeyItem><Name>Prev</Name><URL>$prevuri</URL><Position>2</Position></SoftKeyItem>";
|
|
} else {
|
|
$data .= "<SoftKeyItem><Name>Search</Name><URL>$searchuri</URL><Position>2</Position></SoftKeyItem>";
|
|
}
|
|
$data .= "<SoftKeyItem><Name>Next</Name><URL>$nexturi</URL><Position>3</Position></SoftKeyItem>"
|
|
if($nextpage);
|
|
$data .= "<SoftKeyItem><Name>Cancel</Name><URL>Init:Services</URL><Position>4</Position></SoftKeyItem>";
|
|
$data .= '</CiscoIPPhoneDirectory>';
|
|
|
|
$c->log->debug("providing config to $id");
|
|
$c->log->debug($data);
|
|
|
|
$c->response->content_type('text/xml');
|
|
$c->response->body($data);
|
|
}
|
|
|
|
sub panasonic_directory_list :Chained('base') :PathPart('pbx/directory/panasonic') :Args() {
|
|
my ($self, $c) = @_;
|
|
|
|
my $id = $c->req->params->{userid};
|
|
my $q = $c->req->params->{name};
|
|
|
|
unless($id) {
|
|
$c->response->content_type('text/plain');
|
|
if($c->config->{features}->{debug}) {
|
|
$c->response->body("404 - device id not given");
|
|
} else {
|
|
$c->response->body("404 - device not found");
|
|
}
|
|
$c->response->status(404);
|
|
return;
|
|
}
|
|
|
|
$id =~ s/^([^\=]+)\=0$/$1/;
|
|
$id = lc $id;
|
|
|
|
my $dev = $c->model('DB')->resultset('autoprov_field_devices')->find({
|
|
identifier => $id
|
|
});
|
|
unless($dev) {
|
|
$c->response->content_type('text/plain');
|
|
if($c->config->{features}->{debug}) {
|
|
$c->response->body("404 - device id '" . $id . "' not found");
|
|
} else {
|
|
$c->response->body("404 - device not found");
|
|
}
|
|
$c->response->status(404);
|
|
return;
|
|
}
|
|
|
|
my $schema = $c->stash->{schema};
|
|
my $host = $c->stash->{host};
|
|
my $port = $c->stash->{port};
|
|
|
|
my $customer = $dev->contract;
|
|
my $rs = $self->_get_dirsearch_rs($customer, $q);
|
|
|
|
my @entries = ();
|
|
my %entries = ();
|
|
foreach my $sub($rs->all) {
|
|
my $prov_sub = $sub->provisioning_voip_subscriber;
|
|
next unless($prov_sub && $prov_sub->pbx_extension);
|
|
my $display_name = $sub->get_column('display_name');
|
|
push @entries, { name => $display_name, ext => $prov_sub->pbx_extension };
|
|
$entries{$prov_sub->pbx_extension} = 1;
|
|
}
|
|
|
|
$self->add_phonebook_entries($c, $dev, \@entries, \%entries);
|
|
|
|
my $data = <<'EOS_XML';
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
<ppxml xmlns="http://panasonic/sip_phone"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://panasonic/sip_phone sip_phone.xsd">
|
|
<Screen version="2.0">
|
|
<PhoneBook version="2.0">
|
|
EOS_XML
|
|
my $person_id = 0;
|
|
$data .= join '', map {
|
|
$person_id++;
|
|
<<EOS_XMLLOOP;
|
|
<Personnel id="$person_id">
|
|
<Name>$$_{name}</Name>
|
|
<PhoneNums>
|
|
<PhoneNum type="ext">$$_{ext}</PhoneNum>
|
|
</PhoneNums>
|
|
</Personnel>
|
|
EOS_XMLLOOP
|
|
} @entries;
|
|
|
|
$data .= <<EOS_XML;
|
|
</PhoneBook>
|
|
</Screen>
|
|
</ppxml>
|
|
EOS_XML
|
|
|
|
|
|
$c->log->debug("providing config to $id");
|
|
$c->log->debug($data);
|
|
|
|
$c->response->content_type('text/xml');
|
|
$c->response->body($data);
|
|
}
|
|
|
|
sub yealink_directory_list :Chained('base') :PathPart('pbx/directory/yealink') :Args() {
|
|
my ($self, $c) = @_;
|
|
|
|
my $id = $c->req->params->{userid};
|
|
my $q = $c->req->params->{name};
|
|
|
|
unless($id) {
|
|
$c->response->content_type('text/plain');
|
|
if($c->config->{features}->{debug}) {
|
|
$c->response->body("404 - device id not given");
|
|
} else {
|
|
$c->response->body("404 - device not found");
|
|
}
|
|
$c->response->status(404);
|
|
return;
|
|
}
|
|
|
|
$id =~ s/^([^\=]+)\=0$/$1/;
|
|
$id = lc $id;
|
|
|
|
my $dev = $c->model('DB')->resultset('autoprov_field_devices')->find({
|
|
identifier => $id
|
|
});
|
|
unless($dev) {
|
|
$c->response->content_type('text/plain');
|
|
if($c->config->{features}->{debug}) {
|
|
$c->response->body("404 - device id '" . $id . "' not found");
|
|
} else {
|
|
$c->response->body("404 - device not found");
|
|
}
|
|
$c->response->status(404);
|
|
return;
|
|
}
|
|
|
|
my $schema = $c->stash->{schema};
|
|
my $host = $c->stash->{host};
|
|
my $port = $c->stash->{port};
|
|
|
|
my $customer = $dev->contract;
|
|
my $rs = $self->_get_dirsearch_rs($customer, $q);
|
|
|
|
my @entries = ();
|
|
my %entries = ();
|
|
foreach my $sub($rs->all) {
|
|
my $prov_sub = $sub->provisioning_voip_subscriber;
|
|
next unless($prov_sub && $prov_sub->pbx_extension);
|
|
my $display_name = $sub->get_column('display_name');
|
|
push @entries, { name => $display_name, ext => $prov_sub->pbx_extension };
|
|
$entries{$prov_sub->pbx_extension} = 1;
|
|
}
|
|
|
|
$self->add_phonebook_entries($c, $dev, \@entries, \%entries);
|
|
|
|
my $req_uri = $c->req->uri;
|
|
my $data = <<EOS_XML;
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
<SipwiseIPPhoneDirectory>
|
|
<SoftKeyItem>
|
|
<Name>0</Name>
|
|
<URL>$req_uri</URL>
|
|
</SoftKeyItem>
|
|
EOS_XML
|
|
$data .= join '', map { <<EOS_XMLLOOP;
|
|
<DirectoryEntry>
|
|
<Name>$$_{name}</Name>
|
|
<Telephone>$$_{ext}</Telephone>
|
|
</DirectoryEntry>
|
|
EOS_XMLLOOP
|
|
} @entries;
|
|
$data .= '</SipwiseIPPhoneDirectory>';
|
|
|
|
|
|
$c->log->debug("providing config to $id");
|
|
$c->log->debug($data);
|
|
|
|
$c->response->content_type('text/xml');
|
|
$c->response->body($data);
|
|
}
|
|
|
|
sub polycom_directory_list :Chained('base') :PathPart('pbx/directory/polycom') :Args(1) {
|
|
my ($self, $c, $id) = @_;
|
|
|
|
$id =~ s/\-directory\.xml$//;
|
|
my $q;
|
|
|
|
unless($id) {
|
|
$c->response->content_type('text/plain');
|
|
if($c->config->{features}->{debug}) {
|
|
$c->response->body("404 - device id not given");
|
|
} else {
|
|
$c->response->body("404 - device not found");
|
|
}
|
|
$c->response->status(404);
|
|
return;
|
|
}
|
|
|
|
$id = lc $id;
|
|
my $dev = $c->model('DB')->resultset('autoprov_field_devices')->find({
|
|
identifier => $id
|
|
});
|
|
unless($dev) {
|
|
$c->response->content_type('text/plain');
|
|
if($c->config->{features}->{debug}) {
|
|
$c->response->body("404 - device id '" . $id . "' not found");
|
|
} else {
|
|
$c->response->body("404 - device not found");
|
|
}
|
|
$c->response->status(404);
|
|
return;
|
|
}
|
|
|
|
my $schema = $c->stash->{schema};
|
|
my $host = $c->stash->{host};
|
|
my $port = $c->stash->{port};
|
|
|
|
my $customer = $dev->contract;
|
|
my $rs = $self->_get_dirsearch_rs($customer, $q);
|
|
|
|
my @entries = ();
|
|
my %entries = ();
|
|
foreach my $sub($rs->all) {
|
|
my $prov_sub = $sub->provisioning_voip_subscriber;
|
|
next unless($prov_sub && $prov_sub->pbx_extension);
|
|
my $display_name = $sub->get_column('display_name');
|
|
push @entries, { name => $display_name, ext => $prov_sub->pbx_extension };
|
|
$entries{$prov_sub->pbx_extension} = 1;
|
|
}
|
|
|
|
$self->add_phonebook_entries($c, $dev, \@entries, \%entries);
|
|
|
|
foreach my $entry (@entries) {
|
|
my ($fname, @rest) = split / +/, $entry->{name};
|
|
my $lname = join ' ', @rest;
|
|
$entry->{fname} = $fname;
|
|
$entry->{lname} = $lname;
|
|
}
|
|
|
|
my $data = <<EOS_XML;
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
<directory>
|
|
<item_list>
|
|
EOS_XML
|
|
|
|
# ln last name
|
|
# fn first name
|
|
# ct contact
|
|
# sd speed-dial index
|
|
# rt ring type
|
|
# dc divert contact for auto divert
|
|
# ad auto divert
|
|
# ar auto reject
|
|
# bw buddy watching
|
|
# bb buddy block
|
|
|
|
$data .= join '', map { <<EOS_XMLLOOP;
|
|
<item>
|
|
<ln>$$_{lname}</ln>
|
|
<fn>$$_{fname}</fn>
|
|
<ct>$$_{ext}</ct>
|
|
<sd/>
|
|
<rt/>
|
|
<dc/>
|
|
<ad>0</ad>
|
|
<ar>0</ar>
|
|
<bw>0</bw>
|
|
<bb>0</bb>
|
|
</item>
|
|
EOS_XMLLOOP
|
|
} @entries;
|
|
$data .= '</item_list></directory>';
|
|
|
|
$c->log->debug("providing config to $id");
|
|
$c->log->debug($data);
|
|
|
|
$c->response->content_type('text/xml');
|
|
$c->response->body($data);
|
|
}
|
|
|
|
sub _get_dirsearch_rs :Private {
|
|
my ($self, $customer, $q) = @_;
|
|
|
|
my $rs = $customer->voip_subscribers->search({
|
|
'status' => 'active',
|
|
'provisioning_voip_subscriber.pbx_extension' => { '!=' => undef },
|
|
'voip_usr_preferences.value' => { '!=' => undef },
|
|
'attribute.attribute' => 'display_name',
|
|
defined $q ? (
|
|
-or => [
|
|
'voip_usr_preferences.value' => { like => "%$q%" },
|
|
'provisioning_voip_subscriber.pbx_extension' => { like => "$q%" }
|
|
]
|
|
) : (),
|
|
},{
|
|
join => { provisioning_voip_subscriber => { voip_usr_preferences => 'attribute' } },
|
|
'+select' => [qw/voip_usr_preferences.value/],
|
|
'+as' => [qw/display_name/],
|
|
order_by => { '-asc' => 'voip_usr_preferences.value' },
|
|
});
|
|
|
|
return $rs;
|
|
}
|
|
|
|
sub add_phonebook_entries {
|
|
my ($self, $c, $dev, $entries, $entries_existent) = @_;
|
|
my %phonebook = ();
|
|
foreach my $private_line ($dev->autoprov_field_device_lines->search_rs({ line_type => 'private' })->all) {
|
|
my $private_line_subscriber_id = $private_line->provisioning_voip_subscriber->voip_subscriber->id;
|
|
$phonebook{$private_line_subscriber_id} //= NGCP::Panel::Utils::Phonebook::get_subscriber_phonebook($c, $private_line_subscriber_id);
|
|
foreach my $entry (@{$phonebook{$private_line_subscriber_id}}) {
|
|
push @$entries, { name => $entry->{name}, ext => $entry->{number} }
|
|
unless $entries_existent->{$entry->{number}};
|
|
$entries_existent->{$entry->{number}} = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
1;
|
|
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
NGCP::Panel::Controller::Pbx
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
A controller to manipulate the PBX data
|
|
|
|
=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:
|