From 99100d7e0d0b22a1844dde88acd529e79d096463 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 10 Aug 2009 11:50:04 +0000 Subject: [PATCH] when using pkg-balances, limit self-service access when a customer with multiple packages logs on, RT#4189 --- FS/FS/ClientAPI/MyAccount.pm | 149 +++++++++++++++------ fs_selfservice/FS-SelfService/SelfService.pm | 1 + fs_selfservice/FS-SelfService/cgi/login.html | 2 +- fs_selfservice/FS-SelfService/cgi/logout.html | 2 +- .../cgi/make_thirdparty_payment.html | 13 +- fs_selfservice/FS-SelfService/cgi/myaccount.html | 12 +- .../FS-SelfService/cgi/myaccount_menu.html | 65 +++++---- fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 10 +- 8 files changed, 174 insertions(+), 80 deletions(-) diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 9d031be33..b6934f8bd 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -60,17 +60,20 @@ sub skin_info { my $conf = new FS::Conf; - my %skin = ( - 'head' => join("\n", $conf->config('selfservice-head') ), - 'body_header' => join("\n", $conf->config('selfservice-body_header') ), - 'body_footer' => join("\n", $conf->config('selfservice-body_footer') ), - 'body_bgcolor' => scalar( $conf->config('selfservice-body_bgcolor') ), - 'box_bgcolor' => scalar( $conf->config('selfservice-box_bgcolor') ), + use vars qw($skin_info); #cache for performance. + #agentnum eventually...? but if they're not logged in yet.. ? + + $skin_info ||= { + 'head' => join("\n", $conf->config('selfservice-head') ), + 'body_header' => join("\n", $conf->config('selfservice-body_header') ), + 'body_footer' => join("\n", $conf->config('selfservice-body_footer') ), + 'body_bgcolor' => scalar( $conf->config('selfservice-body_bgcolor') ), + 'box_bgcolor' => scalar( $conf->config('selfservice-box_bgcolor') ), 'company_name' => scalar($conf->config('company_name')), - ); + }; - \%skin; + $skin_info; } @@ -80,6 +83,7 @@ sub login_info { my $conf = new FS::Conf; my %info = ( + %{ skin_info() }, 'phone_login' => $conf->exists('selfservice_server-phone_login'), 'single_domain'=> scalar($conf->config('selfservice_server-single_domain')), ); @@ -122,16 +126,6 @@ sub login { ); return { error => 'User not found.' } unless $svc_acct; - #my $pkg_svc = $svc_acct->cust_svc->pkg_svc; - #return { error => 'Only primary user may log in.' } - # if $conf->exists('selfservice_server-primary_only') - # && ( ! $pkg_svc || $pkg_svc->primary_svc ne 'Y' ); - my $cust_svc = $svc_acct->cust_svc; - my $part_pkg = $cust_svc->cust_pkg->part_pkg; - return { error => 'Only primary user may log in.' } - if $conf->exists('selfservice_server-primary_only') - && $cust_svc->svcpart != $part_pkg->svcpart('svc_acct'); - return { error => 'Incorrect password.' } unless $svc_acct->check_password($p->{'password'}); @@ -143,14 +137,28 @@ sub login { 'svcnum' => $svc_x->svcnum, }; - my $cust_pkg = $svc_x->cust_svc->cust_pkg; + my $cust_svc = $svc_x->cust_svc; + my $cust_pkg = $cust_svc->cust_pkg; if ( $cust_pkg ) { my $cust_main = $cust_pkg->cust_main; $session->{'custnum'} = $cust_main->custnum; - $session->{'pkgnum'} = $cust_pkg->pkgnum - if $conf->exists('pkg-balances'); + if ( $conf->exists('pkg-balances') ) { + my @cust_pkg = grep { $_->part_pkg->freq !~ /^(0|$)/ } + $cust_main->ncancelled_pkgs; + $session->{'pkgnum'} = $cust_pkg->pkgnum + if scalar(@cust_pkg) > 1; + } } + #my $pkg_svc = $svc_acct->cust_svc->pkg_svc; + #return { error => 'Only primary user may log in.' } + # if $conf->exists('selfservice_server-primary_only') + # && ( ! $pkg_svc || $pkg_svc->primary_svc ne 'Y' ); + my $part_pkg = $cust_pkg->part_pkg; + return { error => 'Only primary user may log in.' } + if $conf->exists('selfservice_server-primary_only') + && $cust_svc->svcpart != $part_pkg->svcpart([qw( svc_acct svc_phone )]); + my $session_id; do { $session_id = md5_hex(md5_hex(time(). {}. rand(). $$)) @@ -168,12 +176,57 @@ sub logout { my $p = shift; if ( $p->{'session_id'} ) { _cache->remove($p->{'session_id'}); - return { 'error' => '' }; + return { %{ skin_info() }, 'error' => '' }; } else { - return { 'error' => "Can't resume session" }; #better error message + return { %{ skin_info() }, 'error' => "Can't resume session" }; #better error message } } +sub access_info { + my $p = shift; + + my $conf = new FS::Conf; + + my $info = skin_info($p); + + use vars qw( $cust_paybys ); #cache for performance + unless ( $cust_paybys ) { + + my %cust_paybys = map { $_ => 1 } + map { FS::payby->payby2payment($_) } + $conf->config('signup_server-payby'); + + $cust_paybys = [ keys %cust_paybys ]; + + } + $info->{'cust_paybys'} = $cust_paybys; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) + or return { 'error' => "unknown custnum $custnum" }; + + $info->{hide_payment_fields} = + [ + map { FS::payby->realtime($_) && + $cust_main + ->agent + ->payment_gateway( 'method' => FS::payby->payby2bop($_) ) + ->gateway_namespace + eq 'Business::OnlineThirdPartyPayment' + } + @{ $info->{cust_paybys} } + ]; + + return { %$info, + 'custnum' => $custnum, + 'pkgnum' => $session->{'pkgnum'}, + 'svcnum' => $session->{'svcnum'}, + 'nonprimary' => $session->{'nonprimary'}, + }; +} + sub customer_info { my $p = shift; @@ -196,21 +249,32 @@ sub customer_info { my $cust_main = qsearchs('cust_main', $search ) or return { 'error' => "unknown custnum $custnum" }; - $return{balance} = $cust_main->balance; + if ( $session->{'pkgnum'} ) { + $return{balance} = $cust_main->balance_pkgnum( $session->{'pkgnum'} ); + } else { + $return{balance} = $cust_main->balance; + } $return{tickets} = [ ($cust_main->tickets) ]; - my @open = map { - { - invnum => $_->invnum, - date => time2str("%b %o, %Y", $_->_date), - owed => $_->owed, - }; - } $cust_main->open_cust_bill; - $return{open_invoices} = \@open; + unless ( $session->{'pkgnum'} ) { + my @open = map { + { + invnum => $_->invnum, + date => time2str("%b %o, %Y", $_->_date), + owed => $_->owed, + }; + } $cust_main->open_cust_bill; + $return{open_invoices} = \@open; + } $return{small_custview} = - small_custview( $cust_main, $conf->config('countrydefault') ); + small_custview( $cust_main, + scalar($conf->config('countrydefault')), + ( $session->{'pkgnum'} ? 1 : 0 ), #nobalance + ); + + warn $return{small_custview}; $return{name} = $cust_main->first. ' '. $cust_main->get('last'); @@ -359,6 +423,12 @@ sub payment_info { 'country' => $conf->config('countrydefault') || 'US' } ); + my %cust_paybys = map { $_ => 1 } + map { FS::payby->payby2payment($_) } + $conf->config('signup_server-payby'); + + my @cust_paybys = keys %cust_paybys; + $payment_info = { #list all counties/states/countries @@ -374,9 +444,7 @@ sub payment_info { 'paytypes' => [ @FS::cust_main::paytypes ], 'paybys' => [ $conf->config('signup_server-payby') ], - 'cust_paybys' => [ map { FS::payby->payby2payment($_) } - $conf->config('signup_server-payby') - ], + 'cust_paybys' => \@cust_paybys, 'stateid_label' => FS::Msgcat::_gettext('stateid'), 'stateid_state_label' => FS::Msgcat::_gettext('stateid_state'), @@ -411,7 +479,7 @@ sub payment_info { @{ $return{cust_paybys} } ]; - $return{balance} = $cust_main->balance; + $return{balance} = $cust_main->balance; #XXX pkg-balances? $return{payname} = $cust_main->payname || ( $cust_main->first. ' '. $cust_main->get('last') ); @@ -589,7 +657,11 @@ sub realtime_collect { ); return { 'error' => $error } unless ref( $error ); - return { 'error' => '', amount => $cust_main->balance, %$error }; + my $amount = $session->{'pkgnum'} + ? $cust_main->balance_pkgnum( $session->{'pkgnum'} ) + : $cust_main->balance; + + return { 'error' => '', amount => $amount, %$error }; } sub process_payment_order_pkg { @@ -802,6 +874,7 @@ sub list_svcs { foreach my $cust_pkg ( $p->{'ncancelled'} ? $cust_main->ncancelled_pkgs : $cust_main->unsuspended_pkgs ) { + next if $session->{'pkgnum'} && $cust_pkg->pkgnum != $session->{'pkgnum'}; push @cust_svc, @{[ $cust_pkg->cust_svc ]}; #@{[ ]} to force array context } if ( $p->{'svcdb'} ) { diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index d275fa86d..743057d88 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -61,6 +61,7 @@ $socket .= '.'.$tag if defined $tag && length($tag); 'myaccount_passwd' => 'MyAccount/myaccount_passwd', 'signup_info' => 'Signup/signup_info', 'skin_info' => 'MyAccount/skin_info', + 'access_info' => 'MyAccount/access_info', 'domain_select_hash' => 'Signup/domain_select_hash', # expose? 'new_customer' => 'Signup/new_customer', 'capture_payment' => 'Signup/capture_payment', diff --git a/fs_selfservice/FS-SelfService/cgi/login.html b/fs_selfservice/FS-SelfService/cgi/login.html index 760f579bb..eef412da3 100644 --- a/fs_selfservice/FS-SelfService/cgi/login.html +++ b/fs_selfservice/FS-SelfService/cgi/login.html @@ -3,7 +3,7 @@ Login <%= $head %> - + <%= $body_header %> Login

diff --git a/fs_selfservice/FS-SelfService/cgi/logout.html b/fs_selfservice/FS-SelfService/cgi/logout.html index e2de648ce..5e22ad80c 100644 --- a/fs_selfservice/FS-SelfService/cgi/logout.html +++ b/fs_selfservice/FS-SelfService/cgi/logout.html @@ -3,7 +3,7 @@ MyAccount <%= $head %> - + <%= $body_header %> MyAccount

diff --git a/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html b/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html index 042b8b37c..b2900b1e9 100755 --- a/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html +++ b/fs_selfservice/FS-SelfService/cgi/make_thirdparty_payment.html @@ -1,5 +1,6 @@ -My Account -MyAccount

+<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('header') %> + -<%= $url = "$selfurl?session=$session_id;action="; ''; %> -<%= include('myaccount_menu') %> - + Pay now

<%= if ( $error ) { @@ -34,5 +33,5 @@ EOF $OUT .= qq!!; } %> - - + +<%= include('footer') %> diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html index bcfcf9540..d6527fe76 100644 --- a/fs_selfservice/FS-SelfService/cgi/myaccount.html +++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html @@ -4,11 +4,17 @@ Hello <%= $name %>!

<%= $small_custview %>
+<%= if ( $pkgnum ) { + $OUT .= qq!Balance: \$$balance

!; + } + ''; +%> + <%= if ( $balance > 0 ) { - if (scalar(grep $_, @hide_payment_field)) { - $OUT .= qq! Make a payment

!; - } else { + if (scalar(grep $_, @hide_payment_fields)) { $OUT .= qq! Make a payment

!; + } else { + $OUT .= qq! Make a payment

!; } } %> <%= diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html index 5cf4fe2d9..617ae3ebe 100644 --- a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html +++ b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html @@ -7,15 +7,18 @@ <%= my @menu = ( -{ title=>' ' }, -{ title=>'Overview', url=>'myaccount', size=>'+1', }, -{ title=>' ' }, - -{ title=>'Purchase', size=>'+1', }, - { title=>'Purchase additional package', - url=>'customer_order_pkg', 'indent'=>2 }, + { title=>' ' }, + { title=>'Overview', url=>'myaccount', size=>'+1', }, + { title=>' ' }, + { title=>'Purchase', size=>'+1', }, ); +unless ( $pkgnum ) { + push @menu, + { title=>'Purchase additional package', + url=>'customer_order_pkg', 'indent'=>2 }; +} + if ( 1 ) { #XXXFIXME "enable selfservice prepay features" flag or something, eventually per-pkg or something really fancy #XXXFIXME still a bit sloppy for multi-gateway of differing namespace @@ -34,7 +37,7 @@ if ( 1 ) { #XXXFIXME "enable selfservice prepay features" flag or something, eve while($i < scalar(@cust_paybys)) { last if $cust_paybys[$i] =~ /^CHEK/; $i++ } if ( $cust_paybys[$i] =~ /^CHEK/ ) { push @menu, { title => 'Recharge my account with a check', - url => $hide_payment_field[$i] + url => $hide_payment_fields[$i] ? 'make_thirdparty_payment&payby_method=ECHECK' : 'make_ach_payment', indent => 2, @@ -49,26 +52,36 @@ if ( 1 ) { #XXXFIXME "enable selfservice prepay features" flag or something, eve } -push @menu, ( - -{ title=>' ' }, +push @menu, + { title=>' ' }, + { title=>'View my usage', url=>'view_usage', size=>'+1', }, +; -{ title=>'View my usage', url=>'view_usage', size=>'+1', }, -{ title=>'Setup my services', url=>'provision', size=>'+1', }, - -{ title=>' ' }, +unless ( $pkgnum ) { + push @menu, + { title=>'Setup my services', url=>'provision', size=>'+1', }, + ; +} -{ title=>'Change my information', size=>'+1', }, - { title=>'Change billing address', url=>'change_bill', indent=>2 }, - { title=>'Change service address', url=>'change_ship', indent=>2 }, - { title=>'Change payment information', url=>'change_pay', indent=>2 }, - { title=>'Change password(s)', url=>'change_password', indent=>2 }, +push @menu, + { title=>' ' }; -{ title=>' ' }, +push @menu, + { title=>'Change my information', size=>'+1', }; -{ title=>'Logout', url=>'logout', size=>'+1', }, +unless ( $pkgnum ) { + push @menu, + { title=>'Change billing address', url=>'change_bill', indent=>2 }, + { title=>'Change service address', url=>'change_ship', indent=>2 }, + { title=>'Change payment information', url=>'change_pay', indent=>2 }, + ; +} -); +push @menu, + { title=>'Change password(s)', url=>'change_password', indent=>2 }, + { title=>' ' }, + { title=>'Logout', url=>'logout', size=>'+1', }, +; foreach my $item ( @menu ) { @@ -83,15 +96,15 @@ foreach my $item ( @menu ) { } $OUT.='>'; - $OUT .= '' - if exists $item->{'size'}; - $OUT .= ' ' x $item->{'indent'} if exists $item->{'indent'}; $OUT .= '' if exists $item->{'url'} && $action ne $item->{'url'}; + $OUT .= '' + if exists $item->{'size'}; + $item->{'title'} =~ s/ / /g; $OUT .= $item->{'title'}; diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index 09cfe6073..a5a7d1844 100644 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -10,7 +10,7 @@ use HTML::Entities; use Date::Format; use Number::Format 1.50; use FS::SelfService qw( - skin_info login_info login customer_info edit_info invoice + access_info login_info login customer_info edit_info invoice payment_info process_payment realtime_collect process_prepay list_pkgs order_pkg signup_info order_recharge part_svc_info provision_acct provision_external @@ -98,7 +98,7 @@ warn "processing template $action\n" do_template($action, { 'session_id' => $session_id, 'action' => $action, #so the menu knows what tab we're on... - %{ payment_info( 'session_id' => $session_id ) }, # cust_paybys for the menu + #%{ payment_info( 'session_id' => $session_id ) }, # cust_paybys for the menu %{$result} }); @@ -645,8 +645,10 @@ sub do_template { $fill_in->{'selfurl'} = $cgi->self_url; $fill_in->{'cgi'} = \$cgi; - my $skin_info = skin_info(); - $fill_in->{$_} = $skin_info->{$_} foreach keys %$skin_info; + my $access_info = $session_id + ? 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"; -- 2.11.0