X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=fs_selfservice%2FFS-SelfService%2Fcgi%2Fselfservice.cgi;h=2b4bb4302b82747062a5b9073cd5414c42dd780c;hb=b6cbedaae251e2b32af21fa6078446713e599ba9;hp=3f0562a818ca4ea25358e57b4edfc0ca0cdfddc6;hpb=d6741df87df9e3352d7ae47a02d0e3f46154fef9;p=freeside.git diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi old mode 100644 new mode 100755 index 3f0562a81..2b4bb4302 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -1,13 +1,15 @@ -#!/usr/bin/perl -Tw +#!/usr/bin/perl -w use strict; use vars qw($DEBUG $cgi $session_id $form_max $template_dir); use subs qw(do_template); use CGI; use CGI::Carp qw(fatalsToBrowser); +use CGI::Cookie; use Text::Template; use HTML::Entities; use Date::Format; +use Date::Parse 'str2time'; use Number::Format 1.50; use FS::SelfService qw( access_info login_info login customer_info edit_info invoice @@ -16,8 +18,11 @@ use FS::SelfService qw( part_svc_info provision_acct provision_external provision_phone unprovision_svc change_pkg suspend_pkg domainselector list_svcs list_svc_usage list_cdr_usage list_support_usage - myaccount_passwd list_invoices create_ticket get_ticket - mason_comp + myaccount_passwd list_invoices create_ticket get_ticket did_report + adjust_ticket_priority + mason_comp port_graph + start_thirdparty finish_thirdparty + reset_passwd check_reset_passwd process_reset_passwd ); $template_dir = '.'; @@ -28,54 +33,12 @@ $form_max = 255; $cgi = new CGI; -unless ( defined $cgi->param('session') ) { - my $login_info = login_info( 'agentnum' => scalar($cgi->param('agentnum')) ); - - do_template('login', $login_info ); - exit; -} - -if ( $cgi->param('session') eq 'login' ) { - - $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i - or die "illegal username"; - my $username = $1; - - $cgi->param('domain') =~ /^\s*([\w\-\.]{0,$form_max})\s*$/ - or die "illegal domain"; - my $domain = $1; - - $cgi->param('password') =~ /^(.{0,$form_max})$/ - or die "illegal password"; - my $password = $1; - - my $rv = login( - 'username' => $username, - 'domain' => $domain, - 'password' => $password, - ); - if ( $rv->{error} ) { - my $login_info = login_info( 'agentnum' => $cgi->param('agentnum') ); - do_template('login', { - 'error' => $rv->{error}, - 'username' => $username, - 'domain' => $domain, - %$login_info, - } ); - exit; - } else { - $cgi->param('session' => $rv->{session_id} ); - $cgi->param('action' => 'myaccount' ); - } -} - -$session_id = $cgi->param('session'); - #order|pw_list XXX ??? my @actions = ( qw( myaccount tktcreate tktview + ticket_priority didreport invoices view_invoice @@ -84,6 +47,8 @@ my @actions = ( qw( make_term_payment make_thirdparty_payment post_thirdparty_payment + finish_thirdparty_payment + cancel_thirdparty_payment payment_results ach_payment_results recharge_prepay @@ -110,15 +75,123 @@ my @actions = ( qw( view_usage_details view_cdr_details view_support_details + view_port_graph + real_port_graph change_password process_change_password customer_suspend_pkg process_suspend_pkg )); - -$cgi->param('action') =~ ( '^(' . join('|', @actions) . ')$' ) - or die "unknown action ". $cgi->param('action'); -my $action = $1; + +my @nologin_actions = (qw( + forgot_password + do_forgot_password + process_forgot_password + do_process_forgot_password +)); +push @actions, @nologin_actions; +my %nologin_actions = map { $_=>1 } @nologin_actions; + +my $action = 'myaccount'; # sensible default +if ( $cgi->param('action') =~ /^(\w+)$/ ) { + if (grep {$_ eq $1} @actions) { + $action = $1; + } else { + warn "WARNING: unrecognized action '$1'\n"; + } +} + +unless ( $nologin_actions{$action} ) { + + my %cookies = CGI::Cookie->fetch; + + my $login_rv = {}; + + if ( exists($cookies{'session'}) ) { + + $session_id = $cookies{'session'}->value; + + if ( $session_id eq 'login' ) { + # then we've just come back from the login page + + $cgi->param('password') =~ /^(.{0,$form_max})$/; + my $password = $1; + + if ( $cgi->param('email') =~ /^\s*([a-z0-9_\-\.\@]{1,$form_max})\s*$/i ) { + + my $email = $1; + $login_rv = login( + 'email' => $email, + 'password' => $password + ); + $session_id = $login_rv->{'session_id'}; + + } else { + + $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i; + my $username = $1; + + $cgi->param('domain') =~ /^\s*([\w\-\.]{0,$form_max})\s*$/; + my $domain = $1; + + if ( $username and $domain and $password ) { + + # authenticate + $login_rv = login( + 'username' => $username, + 'domain' => $domain, + 'password' => $password, + ); + $session_id = $login_rv->{'session_id'}; + + } elsif ( $username or $domain or $password ) { + + my $error = 'Illegal '; #XXX localization... + my $count = 0; + if ( !$username ) { + $error .= 'username'; + $count++; + } + if ( !$domain ) { + $error .= ', ' if $count; + $error .= 'domain'; + $count++; + } + if ( !$password ) { + $error .= ', ' if $count; + $error .= 'and ' if $count > 1; + $error .= 'password'; + $count++; + } + $error .= '.'; + $login_rv = { + 'username' => $username, + 'domain' => $domain, + 'password' => $password, + 'error' => $error, + }; + $session_id = undef; # attempt login again + + } + + } # else there was no input, so show no error message + + } # else session_id ne 'login' + + } # else there is no session cookie + + if ( !$session_id ) { + # show the login page + $session_id = 'login'; # set state + my $login_info = login_info( 'agentnum' => scalar($cgi->param('agentnum')) ); + + do_template('login', { %$login_rv, %$login_info }); + exit; + } + + # at this point $session_id is a real session + +} warn "calling $action sub\n" if $DEBUG; @@ -128,10 +201,11 @@ die $@ if $@; warn Dumper($result) if $DEBUG; -if ( $result->{error} eq "Can't resume session" - || $result->{error} eq "Expired session" ) { #ick +if ( $result->{error} && ( $result->{error} eq "Can't resume session" + || $result->{error} eq "Expired session") ) { #ick - my $login_info = login_info(); + $session_id = 'login'; + my $login_info = login_info( 'agentnum' => scalar($cgi->param('agentnum')) ); do_template('login', $login_info); exit; } @@ -273,11 +347,28 @@ sub tktcreate { sub tktview { get_ticket( 'session_id' => $session_id, - 'ticket_id' => $cgi->param('ticket_id'), - 'reply' => $cgi->param('reply'), + 'ticket_id' => ($cgi->param('ticket_id') || ''), + 'subject' => ($cgi->param('subject') || ''), + 'reply' => ($cgi->param('reply') || ''), ); } +sub ticket_priority { + my %values; + foreach ( $cgi->param ) { + if ( /^ticket(\d+)$/ ) { + # a 'ticket1001' param implies the existence of a 'priority1001' param + # but if that's empty, we need to send it as empty rather than forget + # it. + $values{$1} = $cgi->param("priority$1") || ''; + } + } + $action = 'myaccount'; + # this returns an updated customer_info for myaccount + adjust_ticket_priority( 'session_id' => $session_id, + 'values' => \%values ); +} + sub customer_order_pkg { my $init_data = signup_info( 'customer_session_id' => $session_id ); return $init_data if ( $init_data->{'error'} ); @@ -454,7 +545,21 @@ sub process_order_recharge { } sub make_payment { - payment_info( 'session_id' => $session_id ); + + my $payment_info = payment_info( 'session_id' => $session_id ); + + my $tr_amount_fee = mason_comp( + 'session_id' => $session_id, + 'comp' => '/elements/tr-amount_fee.html', + 'args' => [ 'amount' => $payment_info->{'balance'}, + ], + ); + + $tr_amount_fee = $tr_amount_fee->{'error'} || $tr_amount_fee->{'output'}; + + $payment_info->{'tr_amount_fee'} = $tr_amount_fee; + + $payment_info; } sub payment_results { @@ -471,7 +576,7 @@ sub payment_results { my $payinfo = $cgi->param('payinfo'); $payinfo =~ s/[^\dx]//g; - $payinfo =~ /^([\dx]{13,16})$/ + $payinfo =~ /^([\dx]{13,16}|[\dx]{8,9})$/ #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo; or die "illegal card"; #!!! $payinfo = $1; @@ -522,7 +627,10 @@ sub payment_results { my $auto = 0; $auto = 1 if $cgi->param('auto'); - $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch"; + $cgi->param('payunique') =~ /^([\w\-\.]*)$/ or die "illegal payunique"; + my $payunique = $1; + + $cgi->param('paybatch') =~ /^([\w\-\.]*)$/ or die "illegal paybatch"; my $paybatch = $1; $cgi->param('discount_term') =~ /^(\d*)$/ or die "illegal discount_term"; @@ -546,6 +654,7 @@ sub payment_results { 'country' => $country, 'save' => $save, 'auto' => $auto, + 'payunique' => $payunique, 'paybatch' => $paybatch, 'discount_term' => $discount_term, ); @@ -627,24 +736,48 @@ sub ach_payment_results { } sub make_thirdparty_payment { - payment_info('session_id' => $session_id); + my $payment_info = payment_info('session_id' => $session_id); + $cgi->param('payby_method') =~ /^(CC|ECHECK|PAYPAL)$/ + or die "illegal payby method"; + $payment_info->{'payby_method'} = $1; + $payment_info->{'error'} = $cgi->param('error'); + + $payment_info; } sub post_thirdparty_payment { - $cgi->param('payby_method') =~ /^(CC|ECHECK)$/ + $cgi->param('payby_method') =~ /^(CC|ECHECK|PAYPAL)$/ or die "illegal payby method"; my $method = $1; $cgi->param('amount') =~ /^(\d+(\.\d*)?)$/ or die "illegal amount"; my $amount = $1; - my $result = realtime_collect( + my $result = start_thirdparty( 'session_id' => $session_id, 'method' => $method, 'amount' => $amount, ); + if ( $result->{error} ) { + $cgi->param('action', 'make_thirdparty_payment'); + $cgi->param('error', $result->{error}); + print $cgi->redirect( $cgi->self_url ); + exit; + } + $result; } +sub finish_thirdparty_payment { + my %param = $cgi->Vars; + finish_thirdparty( 'session_id' => $session_id, %param ); + # result contains either 'error' => error message, or the payment details +} + +sub cancel_thirdparty_payment { + $action = 'make_thirdparty_payment'; + finish_thirdparty( 'session_id' => $session_id, '_cancel' => 1 ); +} + sub make_term_payment { $cgi->param('amount') =~ /^(\d+\.\d{2})$/ or die "illegal payment amount"; @@ -679,6 +812,15 @@ sub logout { FS::SelfService::logout( 'session_id' => $session_id ); } +sub didreport { + my $result = did_report( 'session_id' => $session_id, + 'format' => $cgi->param('type'), + 'recentonly' => $cgi->param('recentonly'), + ); + die $result->{'error'} if exists $result->{'error'} && $result->{'error'}; + $result; +} + sub provision { my $result = list_pkgs( 'session_id' => $session_id ); die $result->{'error'} if exists $result->{'error'} && $result->{'error'}; @@ -691,7 +833,7 @@ sub provision_svc { my $result = part_svc_info( 'session_id' => $session_id, - map { $_ => $cgi->param($_) } qw( pkgnum svcpart ), + map { $_ => $cgi->param($_) } qw( pkgnum svcpart svcnum ), ); die $result->{'error'} if exists $result->{'error'} && $result->{'error'}; @@ -701,6 +843,7 @@ sub provision_svc { $action .= "_$1"; $result->{'numavail'} = $cgi->param('numavail'); + $result->{'lnp'} = $cgi->param('lnp'); $result; } @@ -708,20 +851,32 @@ sub provision_svc { sub process_svc_phone { my @bulkdid = $cgi->param('bulkdid'); my $phonenum = $cgi->param('phonenum'); + my $lnp = $cgi->param('lnp'); + + my $result; + if($lnp) { + $result = provision_phone ( + 'session_id' => $session_id, + 'countrycode' => '1', + map { $_ => $cgi->param($_) } qw( pkgnum svcpart phonenum + lnp_desired_due_date lnp_other_provider + lnp_other_provider_account ) + ); + } else { + $result = provision_phone ( + 'session_id' => $session_id, + 'bulkdid' => [ @bulkdid ], + 'countrycode' => '1', + map { $_ => $cgi->param($_) } qw( pkgnum svcpart phonenum svcnum email forwarddst ) + ); + } - my $result = provision_phone ( - 'session_id' => $session_id, - 'bulkdid' => [ @bulkdid ], - 'countrycode' => '1', - map { $_ => $cgi->param($_) } qw( pkgnum svcpart phonenum ) - ); - if ( exists $result->{'error'} && $result->{'error'} ) { $action = 'provision_svc_phone'; return { $cgi->Vars, %{ part_svc_info( 'session_id' => $session_id, - map { $_ => $cgi->param($_) } qw( pkgnum svcpart ) + map { $_ => $cgi->param($_) } qw( pkgnum svcpart svcnum ) ) }, 'error' => $result->{'error'}, @@ -774,18 +929,39 @@ sub delete_svc { sub view_usage { list_svcs( 'session_id' => $session_id, - 'svcdb' => [ 'svc_acct', 'svc_phone' ], + 'svcdb' => [ 'svc_acct', 'svc_phone', 'svc_port', ], 'ncancelled' => 1, ); } +sub real_port_graph { + my $svcnum = $cgi->param('svcnum'); + my $res = port_graph( + 'session_id' => $session_id, + 'svcnum' => $svcnum, + 'beginning' => str2time($cgi->param('start')." 00:00:00"), + 'ending' => str2time($cgi->param('end') ." 23:59:59"), + ); + my @usage = @{$res->{'usage'}}; + my $png = $usage[0]->{'png'}; + { 'content' => $png, 'format' => 'png' }; +} + +sub view_port_graph { + my $svcnum = $cgi->param('svcnum'); + { 'svcnum' => $svcnum, + 'start' => $cgi->param($svcnum.'_start'), + 'end' => $cgi->param($svcnum.'_end'), + } +} + sub view_usage_details { - list_svc_usage( - 'session_id' => $session_id, - 'svcnum' => $cgi->param('svcnum'), - 'beginning' => $cgi->param('beginning') || '', - 'ending' => $cgi->param('ending') || '', - ); + list_svc_usage( + 'session_id' => $session_id, + 'svcnum' => $cgi->param('svcnum'), + 'beginning' => $cgi->param('beginning') || '', + 'ending' => $cgi->param('ending') || '', + ); } sub view_cdr_details { @@ -794,6 +970,7 @@ sub view_cdr_details { 'svcnum' => $cgi->param('svcnum'), 'beginning' => $cgi->param('beginning') || '', 'ending' => $cgi->param('ending') || '', + 'inbound' => $cgi->param('inbound') || 0, ); } @@ -841,6 +1018,31 @@ sub process_change_password { } +sub forgot_password { + login_info( 'agentnum' => scalar($cgi->param('agentnum')) ); +} + +sub do_forgot_password { + reset_passwd( + map { $_ => scalar($cgi->param($_)) } + qw( agentnum email username domain ) + ); +} + +sub process_forgot_password { + check_reset_passwd( + map { $_ => scalar($cgi->param($_)) } + qw( session_id ) + ); +} + +sub do_process_forgot_password { + process_reset_passwd( + map { $_ => scalar($cgi->param($_)) } + qw( session_id new_password new_password2 ) + ); +} + #-- sub do_template { @@ -850,28 +1052,62 @@ sub do_template { $cgi->delete_all(); $fill_in->{'selfurl'} = $cgi->self_url; $fill_in->{'cgi'} = \$cgi; + $fill_in->{'error'} = $cgi->param('error') if $cgi->param('error'); - my $access_info = $session_id + my $access_info = ($session_id and $session_id ne 'login') ? access_info( 'session_id' => $session_id ) : {}; $fill_in->{$_} = $access_info->{$_} foreach keys %$access_info; - my $source = "$template_dir/$name.html"; - #warn "creating template for $source\n"; - my $template = new Text::Template( TYPE => 'FILE', - SOURCE => $source, - DELIMITERS => [ '<%=', '%>' ], - UNTAINT => 1, - ) - or die $Text::Template::ERROR; + # update the user's authentication + my $timeout = $access_info->{'timeout'} || '3600'; + my $cookie = CGI::Cookie->new('-name' => 'session', + '-value' => $session_id, + '-expires' => '+'.$timeout.'s', + #'-secure' => 1, # would be a good idea... + ); + if ( $name eq 'logout' ) { + $cookie->expires(0); + } - #warn "filling in $template with $fill_in\n"; - my $data = $template->fill_in( - PACKAGE => 'FS::SelfService::_selfservicecgi', - HASH => $fill_in, - ) || "Error processing template $source"; # at least print _something_ - print $cgi->header( '-expires' => 'now' ); - print $data; + if ( $fill_in->{'format'} ) { + # then override content-type, and return $fill_in->{'content'} instead + # of filling in a template + if ( $fill_in->{'format'} eq 'csv') { + print $cgi->header('-expires' => 'now', + '-Content-Type' => 'text/csv', + '-Content-Disposition' => "attachment;filename=output.csv", + ); + } elsif ( $fill_in->{'format'} eq 'xls' ) { + print $cgi->header('-expires' => 'now', + '-Content-Type' => 'application/vnd.ms-excel', + '-Content-Disposition' => "attachment;filename=output.xls", + '-Content-Length' => length($fill_in->{'content'}), + ); + } elsif ( $fill_in->{'format'} eq 'png' ) { + print $cgi->header('-expires' => 'now', + '-Content-Type' => 'image/png', + ); + } + print $fill_in->{'content'}; + } else { # the usual case + my $source = "$template_dir/$name.html"; + my $template = new Text::Template( + TYPE => 'FILE', + SOURCE => $source, + DELIMITERS => [ '<%=', '%>' ], + UNTAINT => 1, + ) + or die $Text::Template::ERROR; + + my $data = $template->fill_in( + PACKAGE => 'FS::SelfService::_selfservicecgi', + HASH => $fill_in, + ) || "Error processing template $source"; # at least print _something_ + print $cgi->header( '-cookie' => $cookie, + '-expires' => 'now' ); + print $data; + } } #*FS::SelfService::_selfservicecgi::include = \&Text::Template::fill_in_file; @@ -903,4 +1139,4 @@ sub include { } -1; +