remove -w to prevent warnings from messing up otherwise working CGIs
[freeside.git] / fs_selfservice / FS-SelfService / cgi / selfservice.cgi
1 #!/usr/bin/perl -T
2 #!/usr/bin/perl -Tw
3
4 use strict;
5 use vars qw($cgi $session_id $form_max $template_dir);
6 use subs qw(do_template);
7 use CGI;
8 use CGI::Carp qw(fatalsToBrowser);
9 use Text::Template;
10 use HTML::Entities;
11 use FS::SelfService qw( login customer_info invoice
12                         payment_info process_payment 
13                         process_prepay
14                         list_pkgs
15                         part_svc_info provision_acct provision_external
16                         unprovision_svc
17                         list_svcs myaccount_passwd
18                       );
19
20 $template_dir = '.';
21
22 $form_max = 255;
23
24 $cgi = new CGI;
25
26 unless ( defined $cgi->param('session') ) {
27   do_template('login',{});
28   exit;
29 }
30
31 if ( $cgi->param('session') eq 'login' ) {
32
33   $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i
34     or die "illegal username";
35   my $username = $1;
36
37   $cgi->param('domain') =~ /^\s*([\w\-\.]{0,$form_max})\s*$/
38     or die "illegal domain";
39   my $domain = $1;
40
41   $cgi->param('password') =~ /^(.{0,$form_max})$/
42     or die "illegal password";
43   my $password = $1;
44
45   my $rv = login(
46     'username' => $username,
47     'domain'   => $domain,
48     'password' => $password,
49   );
50   if ( $rv->{error} ) {
51     do_template('login', {
52       'error'    => $rv->{error},
53       'username' => $username,
54       'domain'   => $domain,
55     } );
56     exit;
57   } else {
58     $cgi->param('session' => $rv->{session_id} );
59     $cgi->param('action'  => 'myaccount' );
60   }
61 }
62
63 $session_id = $cgi->param('session');
64
65 #order|pw_list XXX ???
66 $cgi->param('action') =~
67     /^(myaccount|view_invoice|make_payment|payment_results|recharge_prepay|recharge_results|logout|change_bill|change_ship|provision|provision_svc|process_svc_acct|process_svc_external|delete_svc|change_password|process_change_password)$/
68   or die "unknown action ". $cgi->param('action');
69 my $action = $1;
70
71 my $result = eval "&$action();";
72 die $@ if $@;
73
74 if ( $result->{error} eq "Can't resume session" ) { #ick
75   do_template('login',{});
76   exit;
77 }
78
79 #warn $result->{'open_invoices'};
80 #warn scalar(@{$result->{'open_invoices'}});
81
82 warn "processing template $action\n";
83 do_template($action, {
84   'session_id' => $session_id,
85   'action'     => $action, #so the menu knows what tab we're on...
86   %{$result}
87 });
88
89 #--
90
91 sub myaccount { customer_info( 'session_id' => $session_id ); }
92
93 sub view_invoice {
94
95   $cgi->param('invnum') =~ /^(\d+)$/ or die "illegal invnum";
96   my $invnum = $1;
97
98   invoice( 'session_id' => $session_id,
99            'invnum'     => $invnum,
100          );
101
102 }
103
104 sub make_payment {
105   payment_info( 'session_id' => $session_id );
106 }
107
108 sub payment_results {
109
110   use Business::CreditCard;
111
112   $cgi->param('amount') =~ /^\s*(\d+(\.\d{2})?)\s*$/
113     or die "illegal amount"; #!!!
114   my $amount = $1;
115
116   my $payinfo = $cgi->param('payinfo');
117   $payinfo =~ s/\D//g;
118   $payinfo =~ /^(\d{13,16})$/
119     #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
120     or die "illegal card"; #!!!
121   $payinfo = $1;
122   validate($payinfo)
123     #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
124     or die "invalid card"; #!!!
125   cardtype($payinfo) eq $cgi->param('card_type')
126     #or $error ||= $init_data->{msgcat}{not_a}. $cgi->param('CARD_type');
127     or die "not a ". $cgi->param('card_type');
128
129   $cgi->param('month') =~ /^(\d{2})$/ or die "illegal month";
130   my $month = $1;
131   $cgi->param('year') =~ /^(\d{4})$/ or die "illegal year";
132   my $year = $1;
133
134   $cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname";
135   my $payname = $1;
136
137   $cgi->param('address1') =~ /^(.{0,80})$/ or die "illegal address1";
138   my $address1 = $1;
139
140   $cgi->param('address2') =~ /^(.{0,80})$/ or die "illegal address2";
141   my $address2 = $1;
142
143   $cgi->param('city') =~ /^(.{0,80})$/ or die "illegal city";
144   my $city = $1;
145
146   $cgi->param('state') =~ /^(.{2})$/ or die "illegal state";
147   my $state = $1;
148
149   $cgi->param('zip') =~ /^(.{0,10})$/ or die "illegal zip";
150   my $zip = $1;
151
152   my $save = 0;
153   $save = 1 if $cgi->param('save');
154
155   my $auto = 0;
156   $auto = 1 if $cgi->param('auto');
157
158   $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch";
159   my $paybatch = $1;
160
161   process_payment(
162     'session_id' => $session_id,
163     'amount'     => $amount,
164     'payinfo'    => $payinfo,
165     'month'      => $month,
166     'year'       => $year,
167     'payname'    => $payname,
168     'address1'   => $address1,
169     'address2'   => $address2,
170     'city'       => $city,
171     'state'      => $state,
172     'zip'        => $zip,
173     'save'       => $save,
174     'auto'       => $auto,
175     'paybatch'   => $paybatch,
176   );
177
178 }
179
180 sub recharge_prepay {
181   customer_info( 'session_id' => $session_id );
182 }
183
184 sub recharge_results {
185
186   my $prepaid_cardnum = $cgi->param('prepaid_cardnum');
187   $prepaid_cardnum =~ s/\W//g;
188   $prepaid_cardnum =~ /^(\w*)$/ or die "illegal prepaid card number";
189   $prepaid_cardnum = $1;
190
191   process_prepay ( 'session_id'     => $session_id,
192                    'prepaid_cardnum' => $prepaid_cardnum,
193                  );
194 }
195
196 sub logout {
197   FS::SelfService::logout( 'session_id' => $session_id );
198 }
199
200 sub provision {
201   my $result = list_pkgs( 'session_id' => $session_id );
202   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
203   $result;
204 }
205
206 sub provision_svc {
207
208   my $result = part_svc_info(
209     'session_id' => $session_id,
210     map { $_ => $cgi->param($_) } qw( pkgnum svcpart ),
211   );
212   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
213
214   $result->{'svcdb'} =~ /^svc_(.*)$/
215     #or return { 'error' => 'Unknown svcdb '. $result->{'svcdb'} };
216     or die 'Unknown svcdb '. $result->{'svcdb'};
217   $action .= "_$1";
218
219   $result;
220 }
221
222 sub process_svc_acct {
223
224   my $result = provision_acct (
225     'session_id' => $session_id,
226     map { $_ => $cgi->param($_) } qw(
227       pkgnum svcpart username _password _password2 sec_phrase popnum )
228   );
229
230   if ( exists $result->{'error'} && $result->{'error'} ) { 
231     #warn "$result $result->{'error'}"; 
232     $action = 'provision_svc_acct';
233     return {
234       $cgi->Vars,
235       %{ part_svc_info( 'session_id' => $session_id,
236                         map { $_ => $cgi->param($_) } qw( pkgnum svcpart )
237                       )
238       },
239       'error' => $result->{'error'},
240     };
241   } else {
242     #warn "$result $result->{'error'}"; 
243     return $result;
244   }
245
246 }
247
248 sub process_svc_external {
249   provision_external (
250     'session_id' => $session_id,
251     map { $_ => $cgi->param($_) } qw( pkgnum svcpart )
252   );
253 }
254
255 sub delete_svc {
256   unprovision_svc(
257     'session_id' => $session_id,
258     'svcnum'     => $cgi->param('svcnum'),
259   );
260 }
261
262 sub change_password {
263   list_svcs(
264     'session_id' => $session_id,
265     'svcdb'      => 'svc_acct',
266   );
267 };
268
269 sub process_change_password {
270
271   my $result = myaccount_passwd(
272     'session_id'    => $session_id,
273     map { $_ => $cgi->param($_) } qw( svcnum new_password new_password2 )
274   );
275
276   if ( exists $result->{'error'} && $result->{'error'} ) { 
277
278     $action = 'change_password';
279     return {
280       $cgi->Vars,
281       %{ list_svcs( 'session_id' => $session_id,
282                     'svcdb'      => 'svc_acct',
283                   )
284        },
285       #'svcnum' => $cgi->param('svcnum'),
286       'error'  => $result->{'error'}
287     };
288
289  } else {
290
291    return $result;
292
293  }
294
295 }
296
297 #--
298
299 sub do_template {
300   my $name = shift;
301   my $fill_in = shift;
302
303   $cgi->delete_all();
304   $fill_in->{'selfurl'} = $cgi->self_url;
305   $fill_in->{'cgi'} = \$cgi;
306
307   my $template = new Text::Template( TYPE    => 'FILE',
308                                      SOURCE  => "$template_dir/$name.html",
309                                      DELIMITERS => [ '<%=', '%>' ],
310                                      UNTAINT => 1,                    )
311     or die $Text::Template::ERROR;
312
313   print $cgi->header( '-expires' => 'now' ),
314         $template->fill_in( PACKAGE => 'FS::SelfService::_selfservicecgi',
315                             HASH    => $fill_in
316                           );
317 }
318
319 #*FS::SelfService::_selfservicecgi::include = \&Text::Template::fill_in_file;
320
321 package FS::SelfService::_selfservicecgi;
322
323 #use FS::SelfService qw(regionselector expselect popselector);
324 use HTML::Entities;
325 use FS::SelfService qw(popselector);
326
327 #false laziness w/agent.cgi
328 sub include {
329   my $name = shift;
330   my $template = new Text::Template( TYPE   => 'FILE',
331                                      SOURCE => "$main::template_dir/$name.html",
332                                      DELIMITERS => [ '<%=', '%>' ],
333                                      UNTAINT => 1,                   
334                                    )
335     or die $Text::Template::ERROR;
336
337   $template->fill_in( PACKAGE => 'FS::SelfService::_selfservicecgi',
338                       #HASH    => $fill_in
339                     );
340
341 }
342