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.
www_csc/lib/csc/Controller/account.pm

1106 lines
36 KiB

package csc::Controller::account;
use strict;
use warnings;
use base 'Catalyst::Controller';
use csc::Utils;
=head1 NAME
csc::Controller::account - Catalyst Controller
=head1 DESCRIPTION
Catalyst Controller for account administration.
=head1 METHODS
=head2 index
Does a redirect to /account/info or /account/pass depending on whether
display_account_info is set.
=cut
sub index : Private {
my ( $self, $c ) = @_;
$c->log->debug('***account::index called');
if($c->config->{display_account_info}) {
$c->response->redirect('/account/info');
} else {
$c->response->redirect('/account/pass');
}
}
=head2 info
Displays some basic information about the SIP account and server system
like username, phone number, SIP proxy server and TFTP boot server.
=cut
sub info : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::info called');
if($c->session->{user}{username} eq 'demonstration' or ! $c->config->{display_account_info}) {
$c->response->redirect($c->uri_for($c->config->{site_config}{default_uri}));
return;
}
unless($c->model('Provisioning')->get_usr_preferences($c)) {
$c->stash->{template} = 'tt/account_info.tt';
return 1;
}
$c->stash->{subscriber}{active_number} = csc::Utils::get_active_number_string($c);
if($c->session->{user}{extension}) {
my $ext = $c->session->{user}{preferences}{extension};
$c->stash->{subscriber}{active_number} =~ s/$ext$/ - $ext/;
}
$c->stash->{sip_domain} = $c->config->{site_domain};
$c->stash->{sip_server} = $c->config->{sip_server};
$c->stash->{tftp_server} = $c->config->{tftp_server};
$c->stash->{template} = 'tt/account_info.tt';
}
=head2 pass
Allows the user to change its webpassword.
=cut
sub pass : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::pass called');
if($c->session->{user}{username} eq 'demonstration') {
$c->response->redirect($c->uri_for($c->config->{site_config}{default_uri}));
return;
}
$c->stash->{template} = 'tt/account_pass.tt';
}
=head2 savepass
Changes the password for the user.
=cut
sub savepass : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::savepass called');
if($c->session->{user}{username} eq 'demonstration') {
$c->response->redirect($c->uri_for($c->config->{site_config}{default_uri}));
return;
}
unless($c->model('Provisioning')->get_usr_preferences($c)) {
$c->response->redirect('/account/pass');
return;
}
my %messages;
my $oldpass = $c->request->params->{oldpass};
my $passwd1 = $c->request->params->{newpass1};
my $passwd2 = $c->request->params->{newpass2};
# $c->stash->{refill}{oldpass} = $oldpass;
# $c->stash->{refill}{passwd1} = $passwd1;
# $c->stash->{refill}{passwd2} = $passwd2;
if(!defined $oldpass or length $oldpass == 0) {
$messages{msgoldpass} = 'Client.Voip.MissingOldPass';
}
if(!defined $passwd1 or length $passwd1 == 0) {
$messages{msgpasswd} = 'Client.Voip.MissingPass';
} elsif(length $passwd1 < 6) {
$messages{msgpasswd} = 'Client.Voip.PassLength';
} elsif(!defined $passwd2 or length $passwd2 == 0) {
$messages{msgpasswd} = 'Client.Voip.MissingPass2';
} elsif($passwd1 ne $passwd2) {
$messages{msgpasswd} = 'Client.Voip.PassNoMatch';
}
unless(keys %messages) {
unless($c->model('Provisioning')->call_prov($c, 'voip', 'authenticate_webuser',
{ webusername => $c->session->{user}{webusername},
domain => $c->session->{user}{domain},
webpassword => $oldpass,
},
))
{
$c->session->{prov_error} = 'Client.Voip.IncorrectPass';
$c->response->redirect('/account/pass');
return;
}
my $account;
unless($c->model('Provisioning')->call_prov($c, 'billing', 'get_voip_account_by_id',
{ id => $c->session->{user}{data}{account_id} },
\$account,
))
{
$c->response->redirect('/account/pass');
return;
}
if($c->model('Provisioning')->call_prov($c, 'voip', 'update_webuser_password',
{ webusername => $c->session->{user}{webusername},
domain => $c->session->{user}{domain},
webpassword => $passwd1
}
))
{
$messages{topmsg} = 'Server.Voip.SavedPass';
$c->session->{user}{password} = $passwd1;
}
}
$c->session->{messages} = \%messages;
$c->response->redirect('/account/pass');
}
=head2 balance
Displays the current account balance and asks the user to top up.
=cut
sub balance : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::balance called');
unless($c->session->{user}{admin} and $c->config->{payment_features}) {
$c->response->redirect('/account');
return;
}
unless($c->model('Provisioning')->get_account_balance($c)) {
$c->stash->{template} = 'tt/account_balance.tt';
return 1;
}
$c->stash->{refill} = $c->session->{refill};
delete $c->session->{refill};
$c->stash->{subscriber}{account}{cash_balance} = sprintf "%.2f", $c->session->{user}{account}{cash_balance} / 100;
$c->stash->{template} = 'tt/account_balance.tt';
}
=head2 setpay
Prepares the payment process and redirects the user to /account/dopay.
=cut
sub setpay : Local {
my ( $self, $c ) = @_;
my %messages;
$c->log->debug('***account::setpay called');
unless($c->session->{user}{admin} and $c->config->{payment_features}) {
$c->response->redirect('/account');
return;
}
delete $c->session->{payment}{credit_id} if exists $c->session->{payment}{credit_id};
delete $c->session->{mpay24} if exists $c->session->{mpay24};
delete $c->session->{paypal} if exists $c->session->{paypal};
my $amount = $c->request->params->{amount};
if($amount !~ /^\d+$/) {
$messages{msgamount} = 'Client.Billing.MalformedAmount';
$c->session->{refill}{amount} = $amount;
}
my $auto_reload = $c->request->params->{auto_reload};
my $auto_amount = $c->request->params->{auto_amount};
if($auto_reload) {
if($auto_amount !~ /^\d+$/) {
$messages{msgautoamount} = 'Client.Billing.MalformedAmount';
$c->session->{refill}{auto_amount} = $auto_amount;
}
}
if(keys %messages) {
$c->session->{messages} = \%messages;
$c->response->redirect($c->uri_for('/account/balance'));
return;
}
$c->session->{payment}{auto_reload} = $auto_reload;
$c->session->{payment}{auto_amount} = $auto_amount;
unless($c->model('Provisioning')->get_usr_preferences($c)) {
$c->response->redirect($c->uri_for('/account/balance'));
return;
}
$c->session->{payment}{amount} = $amount * 100;
$c->response->redirect('/account/dopay');
}
=head2 dopay
Displays the payment forms and errors, if any.
=cut
sub dopay : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::dopay called');
unless($c->session->{user}{admin} and $c->config->{payment_features}) {
$c->response->redirect('/account');
return;
}
unless($c->session->{payment}{amount}) {
$c->response->redirect($c->uri_for('/account/balance'));
return;
}
if(exists $c->session->{mpay24_errors}) {
$c->stash->{mpay24_errors} = $c->session->{mpay24_errors};
delete $c->session->{mpay24_errors};
}
if(exists $c->session->{refill}) {
$c->stash->{refill} = $c->session->{refill};
delete $c->session->{refill};
}
$c->stash->{backend} = 'account';
$c->stash->{template} = 'tt/account_payment.tt';
$c->stash->{payment} = $c->session->{payment};
$c->stash->{mpay24_errors}{elv} = $c->session->{elv_error} if $c->session->{elv_error};
delete $c->session->{elv_error};
}
=head2 dopay_elv
Executes payment via electronic wire transfer. Not yet implemented.
=cut
sub dopay_elv : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::dopay_elv called');
my $amount = $c->session->{payment}{amount};
my $accountnumber = $c->request->params->{accountnumber};
my $bankid = $c->request->params->{bankid};
# my $tid = $self->_start_transaction($c, 'elv', $amount);
# unless($tid) {
# $c->response->redirect('/account/dopay');
# return;
# }
$c->session->{elv_error} = "Bezahlen via Bankeinzug ist noch nicht implementiert!";
$c->response->redirect('/account/dopay');
return;
}
=head2 dopay_cc
Implements payment via credit card.
=cut
sub dopay_cc : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::dopay_cc called');
my $amount = $c->session->{payment}{amount};
my $cctype = $c->request->params->{cctype};
my $cardnum = $c->request->params->{cardnum};
my $cvc = $c->request->params->{cvc};
my $cc_month = $c->request->params->{cc_month};
my $cc_year = $c->request->params->{cc_year};
$cc_year =~ s/^\d\d//;
my $expiry = sprintf("%02d%02d", $cc_year, $cc_month);
my $tid = $self->_start_transaction($c, 'cc', $amount);
unless($tid) {
$c->response->redirect('/account/dopay');
return;
}
my $rc = $c->model('Mpay24')->accept_cc_payment($c, $tid, $amount, $cctype, $cardnum, $expiry, $cvc);
if($rc == 1) {
unless($c->model('Provisioning')->update_account_balance($c, $amount)) {
# that's not good. money has already been transfered!
$self->_fail_transaction($c, $tid);
$c->response->redirect('/account/balance');
return;
}
unless($self->_finish_transaction($c, $tid)) {
# hmm, what? some logging, at least.
}
$c->session->{messages}{topmsg} = 'Server.Billing.Success';
$c->response->redirect('/account/balance');
} elsif($rc == 2) {
unless($c->model('Provisioning')->call_prov($c, 'billing', 'update_payment',
{ id => $tid,
data => { state => 'transact' },
},
undef
))
{
return;
}
$c->response->redirect($c->session->{mpay24}{LOCATION});
$c->log->info("redirected customer to ". $c->session->{mpay24}{LOCATION});
} elsif(defined $c->session->{mpay24}) {
$self->_fail_transaction($c, $tid);
$c->session->{mpay24_errors}{cc} = $c->session->{mpay24}{EXTERNALSTATUS}
|| $c->model('Provisioning')->localize($c, 'Web.Payment.UnknownError');
$c->session->{refill}{cc}{cctype} = $cctype;
$c->session->{refill}{cc}{cardnum} = $cardnum;
$c->session->{refill}{cc}{cvc} = $cvc;
$c->session->{refill}{cc}{cc_month} = $cc_month;
$c->session->{refill}{cc}{cc_year} = $cc_year;
$c->response->redirect('/account/dopay#cc');
} else {
$self->_fail_transaction($c, $tid);
$c->session->{mpay24_errors}{cc} = $c->model('Provisioning')->localize($c, 'Web.Payment.HttpFailed');
$c->session->{refill}{cc}{cctype} = $cctype;
$c->session->{refill}{cc}{cardnum} = $cardnum;
$c->session->{refill}{cc}{cvc} = $cvc;
$c->session->{refill}{cc}{cc_month} = $cc_month;
$c->session->{refill}{cc}{cc_year} = $cc_year;
$c->response->redirect('/account/dopay#cc');
}
return 1;
}
=head2 dopay_eps
Implements payment via the electronic payment system, offered by most
banks via their online banking interfaces.
=cut
sub dopay_eps : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::dopay_eps called');
my $amount = $c->session->{payment}{amount};
my $bankname = $c->request->params->{bankname};
my ($bank, $bankid);
$bank = $bankname;
if($bankname =~ /^ARZ_/) {
($bank, $bankid) = split /_/, $bankname;
}
my $tid = $self->_start_transaction($c, 'eps', $amount);
unless($tid) {
$c->response->redirect('/account/dopay');
return;
}
if($c->model('Mpay24')->accept_eps_payment($c, $tid, $amount, $bank, $bankid)) {
unless($c->model('Provisioning')->call_prov($c, 'billing', 'update_payment',
{ id => $tid,
data => { state => 'transact' },
},
undef
))
{
return;
}
$c->response->redirect($c->session->{mpay24}{LOCATION});
$c->log->info("redirected customer to ". $c->session->{mpay24}{LOCATION});
} elsif(defined $c->session->{mpay24}) { # application error
$self->_fail_transaction($c, $tid);
$c->session->{mpay24_errors}{eps} = $c->session->{mpay24}{EXTERNALSTATUS}
|| $c->model('Provisioning')->localize($c, 'Web.Payment.UnknownError');
$c->session->{refill}{eps}{bankname} = $bankname;
$c->response->redirect('/account/dopay#eps');
} else { # transport error
$self->_fail_transaction($c, $tid);
$c->session->{mpay24_errors}{eps} = $c->model('Provisioning')->localize($c, 'Web.Payment.HttpFailed');
$c->session->{refill}{eps}{bankname} = $bankname;
$c->response->redirect('/account/dopay#eps');
}
return 1;
}
=head2 dopay_maestro
Implements payment via maestro secure code.
=cut
sub dopay_maestro : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::dopay_maestro called');
my $amount = $c->session->{payment}{amount};
my $cardnum = $c->request->params->{cardnum};
my $maestro_month = $c->request->params->{maestro_month};
my $maestro_year = $c->request->params->{maestro_year};
$maestro_year =~ s/^\d\d//;
my $expiry = sprintf("%02d%02d", $maestro_year, $maestro_month);
my $tid = $self->_start_transaction($c, 'maestro', $amount);
unless($tid) {
$c->response->redirect('/account/dopay');
return;
}
if($c->model('Mpay24')->accept_maestro_payment($c, $tid, $amount, $cardnum, $expiry)) {
unless($c->model('Provisioning')->call_prov($c, 'billing', 'update_payment',
{ id => $tid,
data => { state => 'transact' },
},
undef
))
{
return;
}
$c->response->redirect($c->session->{mpay24}{LOCATION});
$c->log->info("redirected customer to ". $c->session->{mpay24}{LOCATION});
} elsif(defined $c->session->{mpay24}) {
$self->_fail_transaction($c, $tid);
$c->session->{mpay24_errors}{maestro} = $c->session->{mpay24}{EXTERNALSTATUS}
|| $c->model('Provisioning')->localize($c, 'Web.Payment.UnknownError');
$c->session->{refill}{maestro}{cardnum} = $cardnum;
$c->session->{refill}{maestro}{maestro_month} = $maestro_month;
$c->session->{refill}{maestro}{maestro_year} = $maestro_year;
$c->response->redirect('/account/dopay#maestro');
} else {
$self->_fail_transaction($c, $tid);
$c->session->{mpay24_errors}{maestro} = $c->model('Provisioning')->localize($c, 'Web.Payment.HttpFailed');
$c->session->{refill}{maestro}{cardnum} = $cardnum;
$c->session->{refill}{maestro}{maestro_month} = $maestro_month;
$c->session->{refill}{maestro}{maestro_year} = $maestro_year;
$c->response->redirect('/account/dopay#maestro');
}
return 1;
}
=head2 dopay_paypal
Implements payment via PayPal.
=cut
sub dopay_paypal : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::dopay_paypal called');
my $amount = $c->session->{payment}{amount};
my $tid = $self->_start_transaction($c, 'paypal', $amount);
unless($tid) {
$c->response->redirect('/account/dopay');
return;
}
$c->session->{paypal}{tid} = $tid;
# TODO: specify PayPal return and error url
unless($c->model('Paypal')->set_express_checkout($c, $amount, 'csc')) {
$c->response->redirect('/account/dopay');
return;
}
$c->response->redirect($c->config->{paypal_redirecturl} . $c->session->{paypal}{Token});
}
=head2 paidack
Finalizes successful payments via PayPal.
=cut
sub paidack : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::paidack called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/account/info'));
return;
}
my $token = $c->request->params->{token};
my $payerid = $c->request->params->{PayerID};
if($c->session->{paypal}{Token} eq $token and length $payerid) {
$c->session->{paypal}{PayerID} = $payerid;
} else {
$c->session->{prov_error} = 'Server.Paypal.Invalid';
$c->response->redirect('/account/dopay');
return;
}
unless($c->model('Provisioning')->update_account_balance($c, $c->session->{paypal}{Amount})) {
$self->_fail_transaction($c, $c->session->{paypal}{tid});
$c->response->redirect('/account/dopay');
return;
}
unless($c->model('Paypal')->do_express_checkout($c)) {
$self->_fail_transaction($c, $c->session->{paypal}{tid});
$c->model('Provisioning')->update_account_balance($c, (0 - $c->session->{paypal}{Amount}));
$c->response->redirect('/account/dopay');
return;
}
$self->_finish_transaction($c, $c->session->{paypal}{tid});
$c->session->{messages}{topmsg} = 'Server.Billing.Success';
$c->response->redirect('/account/balance');
}
=head2 paiderr
Finalizes failed payments via PayPal.
=cut
sub paiderr : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::paiderr called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/account/info'));
return;
}
$self->_fail_transaction($c, $c->session->{paypal}{tid});
$c->session->{prov_error} = 'Server.Paypal.Error';
$c->response->redirect('/account/dopay');
}
=head2 success
Finalizes successful payments via mPAY24.
=cut
sub success : Local {
my ( $self, $c ) = @_;
use Data::Dumper;
$c->log->info("***account::success called!");
$c->log->info(Dumper $c->request->params);
unless($c->request->params->{tid} == $c->session->{payment}{tid}) {
$c->session->{mpay24_errors}{top} = $c->model('Provisioning')->localize($c, 'Web.Payment.HttpFailed');
$c->response->redirect('/account/dopay');
}
my $payment;
unless($c->model('Provisioning')->call_prov($c, 'billing', 'get_payment',
{ id => $c->request->params->{tid} },
\$payment
))
{
$c->response->redirect('/account/dopay');
return;
}
if($$payment{status} eq 'RESERVED' or $$payment{status} eq 'BILLED') {
unless($c->model('Provisioning')->update_account_balance($c, $$payment{amount})) {
$self->_fail_transaction($c, $c->request->params->{tid});
$c->response->redirect('/account/dopay');
return;
}
$self->_finish_transaction($c, $c->request->params->{tid});
$c->session->{messages}{topmsg} = 'Server.Billing.Success';
} else {
$self->_fail_transaction($c, $$payment{id});
$c->session->{messages}{toperr} = 'Server.Billing.Failed';
}
$c->response->redirect('/account/balance');
}
=head2 error
Finalizes failed payments via mPAY24.
=cut
sub error : Local {
my ( $self, $c ) = @_;
use Data::Dumper;
$c->log->info("***account::error called!");
$c->log->info(Dumper $c->request->params);
$c->session->{mpay24_errors}{top} = $c->model('Provisioning')->localize($c, 'Web.Payment.ExternalError');
unless($c->request->params->{tid} == $c->session->{payment}{tid}) {
$c->response->redirect('/account/dopay');
return;
}
$self->_fail_transaction($c, $c->request->params->{tid});
$c->response->redirect('/account/dopay');
}
sub _start_transaction : Private {
my ($self, $c, $type, $amount) = @_;
unless($c->session->{payment}{credit_id}
or $c->model('Provisioning')->call_prov($c, 'billing', 'create_contract_credit',
{ contract_id => $c->session->{user}{data}{account_id},
data => { value => $amount,
reason => 'CSC reload',
},
},
\$c->session->{payment}{credit_id}
))
{
return;
}
my $payment_id;
unless($c->model('Provisioning')->call_prov($c, 'billing', 'create_payment',
{ transaction_type => 'credit',
transaction_id => $c->session->{payment}{credit_id},
type => $type,
amount => $amount,
},
\$payment_id
))
{
return;
}
$c->session->{payment}{tid} = $payment_id;
return $payment_id;
}
sub _finish_transaction : Private {
my ($self, $c, $tid) = @_;
unless($c->model('Provisioning')->call_prov($c, 'billing', 'update_payment',
{ id => $tid,
data => { state => 'success',
mpaytid => $c->session->{mpay24}{MPAYTID},
status => $c->session->{mpay24}{STATUS},
},
},
undef
))
{
return;
}
unless($c->model('Provisioning')->call_prov($c, 'billing', 'update_contract_credit',
{ id => $c->session->{payment}{credit_id},
data => { state => 'success' },
},
undef
))
{
return;
}
delete $c->session->{payment}{credit_id};
return 1;
}
sub _fail_transaction : Private {
my ($self, $c, $tid) = @_;
unless($c->model('Provisioning')->call_prov($c, 'billing', 'update_payment',
{ id => $tid,
data => { state => 'failed',
mpaytid => $c->session->{mpay24}{MPAYTID},
status => $c->session->{mpay24}{STATUS},
errno => $c->session->{mpay24}{ERRNO},
returncode => $c->session->{mpay24}{RETURNCODE},
externalstatus => $c->session->{mpay24}{EXTERNALSTATUS},
},
},
undef
))
{
return;
}
return 1;
}
=head2 subscriber
Displays the account's subscribers.
=cut
sub subscriber : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::subscriber called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/account/info'));
return;
}
$c->stash->{template} = 'tt/account_subscriber.tt';
return 1 unless $c->model('Provisioning')->get_voip_account_subscribers($c);
my %subscribers;
foreach my $subscriber (@{$c->session->{user}{subscribers}}) {
if($$subscriber{preferences}{base_cli}) {
push @{$subscribers{$$subscriber{preferences}{base_cli}}{extensions}}, $subscriber;
#TODO: fixme, this is terrible inefficient
@{$subscribers{$$subscriber{preferences}{base_cli}}{extensions}} =
sort {$a->{preferences}{extension} cmp $b->{preferences}{extension}}
@{$subscribers{$$subscriber{preferences}{base_cli}}{extensions}};
} elsif($$subscriber{sn}) {
my $tmp_num = $$subscriber{cc}.$$subscriber{ac}.$$subscriber{sn};
$$subscriber{extensions} = $subscribers{$tmp_num}{extensions}
if exists $subscribers{$tmp_num};
$subscribers{$tmp_num} = $subscriber;
} else {
#TODO: subscribers without number?
$c->log->error('***account::subscriber: subscriber without E.164 number found: '.
$$subscriber{username} .'@'. $$subscriber{domain});
}
}
$c->stash->{subscribers} = [sort {$a->{username} cmp $b->{username}} values %subscribers];
}
=head2 addsubscriber
Asks the user to add a new subscriber to the account.
=cut
sub addsubscriber : Local {
my ( $self, $c, $settings ) = @_;
$c->log->debug('***account::addsubscriber called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/account/info'));
return;
}
$c->stash->{template} = 'tt/account_addsubscriber.tt';
if(defined $settings and ref $settings eq 'HASH') {
$c->stash->{refill} = $settings;
}
$c->stash->{available_numbers} = $c->model('Provisioning')->get_free_numbers($c);
if(defined $c->stash->{available_numbers} and ref $c->stash->{available_numbers} eq 'ARRAY') {
foreach my $free_number (@{$c->stash->{available_numbers}}) {
# try to reselect selected number. (if it's still available...)
if($$settings{cc} and $$free_number{cc} eq $$settings{cc} and
$$settings{ac} and $$free_number{ac} eq $$settings{ac} and
$$settings{sn} and $$free_number{sn} eq $$settings{sn})
{
$$free_number{active} = 'selected="selected"';
}
}
}
}
=head2 doaddsubscriber
Adds a new subscriber to the account.
=cut
sub doaddsubscriber : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::doaddsubscriber called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/account/info'));
return;
}
my (%settings, %messages);
my $number = $c->request->params->{fnummer};
if(defined $number) {
@settings{'cc','ac','sn'} = split /-/, $number;
} else {
$messages{msgnumber} = 'Client.Voip.ChooseNumber';
}
my $sipuri = lc($c->request->params->{fsipuri});
if(!defined $sipuri or length $sipuri == 0) {
$messages{msgsipuri} = 'Client.Syntax.MissingUsername';
} elsif($sipuri !~ /^[a-z0-9_.-]+$/) {
$messages{msgsipuri} = 'Client.Syntax.MalformedUsername';
}
$settings{sipuri} = $sipuri;
my $passwd1 = $c->request->params->{fpasswort1};
my $passwd2 = $c->request->params->{fpasswort2};
if(!defined $passwd1 or length $passwd1 == 0) {
$messages{msgpasswd} = 'Client.Voip.MissingPass';
} elsif(length $passwd1 < 6) {
$messages{msgpasswd} = 'Client.Voip.PassLength';
} elsif(!defined $passwd2) {
$messages{msgpasswd} = 'Client.Voip.MissingPass2';
} elsif($passwd1 ne $passwd2) {
$messages{msgpasswd} = 'Client.Voip.PassNoMatch';
}
unless(keys %messages) {
my %create_settings = %settings;
delete $create_settings{sipuri};
$create_settings{webusername} = $settings{sipuri};
$create_settings{username} = $settings{sipuri};
$create_settings{domain} = $c->session->{user}{domain};
$create_settings{webpassword} = $passwd1;
# TODO: sip password should be auto-generated
$create_settings{password} = $passwd1;
$c->model('Provisioning')->call_prov($c, 'billing', 'add_voip_account_subscriber',
{ id => $c->session->{user}{account_id},
subscriber => \%create_settings,
},
);
if($c->session->{prov_error}) {
if($c->session->{prov_error} eq 'Client.Voip.ExistingSubscriber') {
$c->session->{messages}{msgsipuri} = $c->session->{prov_error};
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
} elsif($c->session->{prov_error} eq 'Client.Voip.AssignedNumber') {
$c->session->{messages}{msgnumber} = $c->session->{prov_error};
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
}
$self->addsubscriber($c, \%settings);
} else {
$messages{topmsg} = 'Server.Voip.SubscriberCreated';
$c->session->{messages} = \%messages;
$c->response->redirect($c->uri_for('/account/subscriber'));
}
} else {
$messages{toperr} = "Client.Voip.InputErrorFound";
$c->session->{messages} = \%messages;
$self->addsubscriber($c, \%settings);
}
}
=head2 addextension
Asks the user to create a new extension for its PBX.
=cut
sub addextension : Local {
my ( $self, $c, $settings ) = @_;
$c->log->debug('***account::addextension called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/account/info'));
return;
}
$c->stash->{template} = 'tt/account_addextension.tt';
if(defined $settings and ref $settings eq 'HASH') {
$c->stash->{refill} = $settings;
$c->stash->{refill}{extension} = $c->request->params->{fextension};
}
$c->stash->{base_cli} = $c->request->params->{base_cli};
}
=head2 doaddextension
Creates a new extension for a PBX.
=cut
sub doaddextension : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::doaddextension called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/account/info'));
return;
}
my (%settings, %messages);
my $base_cli = $c->request->params->{base_cli};
my $extension = $c->request->params->{fextension};
if(defined $extension) {
$messages{msgnumber} = 'Web.Syntax.Numeric'
unless $extension =~ /^\d+$/;
} else {
$messages{msgnumber} = 'Client.Voip.ChooseNumber';
}
my $sipuri = lc($c->request->params->{fsipuri});
if(!defined $sipuri or length $sipuri == 0) {
$messages{msgsipuri} = 'Client.Syntax.MissingUsername';
} elsif($sipuri !~ /^[a-z0-9_.-]+$/) {
$messages{msgsipuri} = 'Client.Syntax.MalformedUsername';
}
$settings{sipuri} = $sipuri;
my $passwd1 = $c->request->params->{fpasswort1};
my $passwd2 = $c->request->params->{fpasswort2};
if(!defined $passwd1 or length $passwd1 == 0) {
$messages{msgpasswd} = 'Client.Voip.MissingPass';
} elsif(length $passwd1 < 6) {
$messages{msgpasswd} = 'Client.Voip.PassLength';
} elsif(!defined $passwd2) {
$messages{msgpasswd} = 'Client.Voip.MissingPass2';
} elsif($passwd1 ne $passwd2) {
$messages{msgpasswd} = 'Client.Voip.PassNoMatch';
}
unless(keys %messages) {
my %create_settings = %settings;
delete $create_settings{sipuri};
$create_settings{webusername} = $settings{sipuri};
$create_settings{username} = $settings{sipuri};
$create_settings{domain} = $c->session->{user}{domain};
$create_settings{webpassword} = $passwd1;
# TODO: sip password should be auto-generated
$create_settings{password} = $passwd1;
if($c->model('Provisioning')->call_prov($c, 'billing', 'add_voip_account_subscriber',
{ id => $c->session->{user}{account_id},
subscriber => \%create_settings,
},
))
{
if($c->model('Provisioning')->call_prov($c, 'voip', 'set_subscriber_preferences',
{ username => $settings{sipuri},
domain => $c->session->{user}{domain},
preferences => { base_cli => $base_cli,
extension => $extension
},
},
))
{
$messages{topmsg} = 'Server.Voip.SubscriberCreated';
$c->session->{messages} = \%messages;
$c->response->redirect($c->uri_for('/account/subscriber'));
} else {
if($c->session->{prov_error} eq 'Client.Voip.ExistingAlias') {
$messages{msgnumber} = 'Client.Voip.AssignedExtension';
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
}
$c->model('Provisioning')->delete_subscriber($c, $settings{sipuri}, $c->session->{user}{domain});
}
} else {
if($c->session->{prov_error} eq 'Client.Voip.ExistingSubscriber') {
$messages{msgsipuri} = $c->session->{prov_error};
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
} elsif($c->session->{prov_error} eq 'Client.Voip.AssignedNumber') {
$messages{msgnumber} = $c->session->{prov_error};
$c->session->{prov_error} = 'Client.Voip.InputErrorFound';
}
}
} else {
$messages{toperr} = "Client.Voip.InputErrorFound";
}
$c->session->{messages} = \%messages;
$self->addextension($c, \%settings);
}
=head2 delsubscriber
Deletes a subscriber for an account.
=cut
sub delsubscriber : Local {
my ( $self, $c ) = @_;
$c->log->debug('***account::delsubscriber called');
unless($c->session->{user}{admin}) {
$c->response->redirect($c->uri_for('/account/info'));
return;
}
my $username = lc($c->request->params->{username});
if($c->model('Provisioning')->terminate_subscriber($c, $username, $c->session->{user}{domain})) {
$c->session->{messages}{topmsg} = 'Server.Voip.SubscriberDeleted';
}
$c->response->redirect($c->uri_for('/account/subscriber'));
}
=head1 BUGS AND LIMITATIONS
=over
=item none
=back
=head1 SEE ALSO
Provisioning model, Paypal model, Catalyst
=head1 AUTHORS
Daniel Tiefnig <dtiefnig@sipwise.com>
=head1 COPYRIGHT
The account controller is Copyright (c) 2007-2010 Sipwise GmbH, Austria.
You should have received a copy of the licences terms together with the
software.
=cut
# over and out
1;