From b4d172efa2225ef5070c1a6f168eb98fce8c5c62 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 29 May 2002 04:40:31 +0000 Subject: add fs_selfservice --- fs_selfservice/FS-SelfService/Changes | 6 + fs_selfservice/FS-SelfService/MANIFEST | 6 + fs_selfservice/FS-SelfService/Makefile.PL | 15 ++ fs_selfservice/FS-SelfService/SelfService.pm | 66 +++++++++ fs_selfservice/FS-SelfService/test.pl | 17 +++ fs_selfservice/freeside-selfservice-server | 198 +++++++++++++++++++++++++++ 6 files changed, 308 insertions(+) create mode 100644 fs_selfservice/FS-SelfService/Changes create mode 100644 fs_selfservice/FS-SelfService/MANIFEST create mode 100644 fs_selfservice/FS-SelfService/Makefile.PL create mode 100644 fs_selfservice/FS-SelfService/SelfService.pm create mode 100644 fs_selfservice/FS-SelfService/test.pl create mode 100644 fs_selfservice/freeside-selfservice-server (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/Changes b/fs_selfservice/FS-SelfService/Changes new file mode 100644 index 000000000..b9e26b7dc --- /dev/null +++ b/fs_selfservice/FS-SelfService/Changes @@ -0,0 +1,6 @@ +Revision history for Perl extension FS::SelfService. + +0.01 Tue May 28 16:49:41 2002 + - original version; created by h2xs 1.21 with options + -A -X -n FS::SelfService + diff --git a/fs_selfservice/FS-SelfService/MANIFEST b/fs_selfservice/FS-SelfService/MANIFEST new file mode 100644 index 000000000..3c490e7dd --- /dev/null +++ b/fs_selfservice/FS-SelfService/MANIFEST @@ -0,0 +1,6 @@ +Changes +Makefile.PL +MANIFEST +README +SelfService.pm +test.pl diff --git a/fs_selfservice/FS-SelfService/Makefile.PL b/fs_selfservice/FS-SelfService/Makefile.PL new file mode 100644 index 000000000..da0a0aa24 --- /dev/null +++ b/fs_selfservice/FS-SelfService/Makefile.PL @@ -0,0 +1,15 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + 'NAME' => 'FS::SelfService', + 'VERSION_FROM' => 'SelfService.pm', # finds $VERSION + 'EXE_FILES' => [ 'freeside-selfservice-clientd' ], + 'INSTALLSCRIPT' => '/usr/local/sbin', + 'INSTALLSITEBIN' => '/usr/local/sbin', + 'PERM_RWX' => '750', + 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1 + ($] >= 5.005 ? ## Add these new keywords supported since 5.005 + (ABSTRACT_FROM => 'SelfService.pm', # retrieve abstract from module + AUTHOR => 'Ivan Kohler ') : ()), +); diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm new file mode 100644 index 000000000..75e550a2d --- /dev/null +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -0,0 +1,66 @@ +package FS::SelfService; + +use 5.006; +use strict; +use warnings; + +require Exporter; + +our @ISA = qw(Exporter); + +# Items to export into callers namespace by default. Note: do not export +# names by default without a very good reason. Use EXPORT_OK instead. +# Do not simply export all your public functions/methods/constants. + +# This allows declaration use FS::SelfService ':all'; +# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK +# will save memory. +our %EXPORT_TAGS = ( 'all' => [ qw( + +) ] ); + +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); + +our @EXPORT = qw( + +); +our $VERSION = '0.01'; + + +# Preloaded methods go here. + +1; +__END__ +# Below is stub documentation for your module. You better edit it! + +=head1 NAME + +FS::SelfService - Perl extension for blah blah blah + +=head1 SYNOPSIS + + use FS::SelfService; + blah blah blah + +=head1 DESCRIPTION + +Stub documentation for FS::SelfService, created by h2xs. It looks like the +author of the extension was negligent enough to leave the stub +unedited. + +Blah blah blah. + +=head2 EXPORT + +None by default. + + +=head1 AUTHOR + +A. U. Thor, Ea.u.thor@a.galaxy.far.far.awayE + +=head1 SEE ALSO + +L. + +=cut diff --git a/fs_selfservice/FS-SelfService/test.pl b/fs_selfservice/FS-SelfService/test.pl new file mode 100644 index 000000000..7468ea471 --- /dev/null +++ b/fs_selfservice/FS-SelfService/test.pl @@ -0,0 +1,17 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### + +# change 'tests => 1' to 'tests => last_test_to_print'; + +use Test; +BEGIN { plan tests => 1 }; +use FS::SelfService; +ok(1); # If we made it this far, we're ok. + +######################### + +# Insert your test code below, the Test module is use()ed here so read +# its man page ( perldoc Test ) for help writing this test script. + diff --git a/fs_selfservice/freeside-selfservice-server b/fs_selfservice/freeside-selfservice-server new file mode 100644 index 000000000..6146d3752 --- /dev/null +++ b/fs_selfservice/freeside-selfservice-server @@ -0,0 +1,198 @@ +#!/usr/bin/perl -w +# +# freeside-selfservice-server + +# alas, much false laziness with freeside-queued and fs_signup_server. at +# least it is slated to replace fs_{signup,passwd,mailadmin}_server +# should probably generalize the version in here, or better yet use +# Proc::Daemon or somesuch + +use strict; +use vars qw( $kids $max_kids $shutdown $log_file ); +use vars qw($ssh_pid); +use Fcntl qw(:flock); +use POSIX qw(setsid); +use IO::Handle; +use Storable qw(nstore_fd fd_retrieve); +use Net::SSH qw(sshopen2); +use FS::UID qw(adminsuidsetup); + +#use Tie::RefHash; +#use FS::Conf; +#use FS::Record qw( qsearch qsearchs ); +#use FS::cust_main_county; +#use FS::cust_main; +#use FS::Msgcat qw(gettext); + +$shutdown = 0; +$max_kids = '10'; #? +$kids = 0; + +my $user = shift or die &usage; +my $machine = shift or die &usage; +my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; +#my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; $FS::UID::datasrc not posible, but should include machine name at least, hmm + +&init($user); + +my $clientd = "/usr/local/sbin/freeside-selfservice-clientd"; #better name? + +my %dispatch = ( + 'signup' => \&signup, + #'signup_init' => 'signup_init', + 'passwd' => \&passwd, + +); + +my $warnkids=0; +while (1) { + my($reader, $writer) = (new IO::Handle, new IO::Handle); + warn "connecting to $machine"; + $ssh_pid = sshopen2($machine,$reader,$writer,$clientd); + + warn "entering main loop"; + while (1) { + + warn "waiting for packet from client"; + my $packet = eval { + local $SIG{__DIE__}; + local $SIG{ALRM} = sub { die "alarm\n" }; #NB: \n required + alarm 5; + my $p = fd_retrieve($reader); + alarm 0; + $p; + }; + if ($@) { + die $@ unless $@ eq "alarm\n"; + #timeout + next unless $shutdown; + &shutdown; + } + warn "packet received"; + + #prevent runaway forking + my $warnkids = 0; + while ( $kids >= $max_kids ) { + warn "WARNING: maximum $kids children reached" unless $warnkids++; + sleep 1; + } + + warn "forking child"; + defined( my $pid = fork ) or die "can't fork: $!"; + if ( $pid ) { + warn "child $pid spawned"; + $kids++; + } else { #kid time + + #get new db handle + $FS::UID::dbh->{InactiveDestroy} = 1; + forksuidsetup($user); + + my $sub = $dispatch{$packet->{_packet}}; + my $rv; + if ( $sub ) { + warn "calling $sub handler"; + $rv = &{$sub}($packet); + } else { + warn my $error = "WARNING: unknown packet type ". $packet->{_packet}; + $rv = { _error => $error }; + } + $rv->{_token} = $packet->{_token}; #identifier + + warn "sending response"; + flock($writer, LOCK_EX); #acquire write lock + nstore_fd($rv, $writer) or die "can't send response: $!"; + $writer->flush; + flock($writer, LOCK_UN); #release write lock + + warn "child exiting"; + exit; #end-of-kid + } + + } + +} + +### +# utility subroutines +### + +sub init { + my $user = shift; + + chdir "/" or die "Can't chdir to /: $!"; + open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; + defined(my $pid = fork) or die "Can't fork: $!"; + if ( $pid ) { + print "freeside-selfservice-server to $machine started with pid $pid\n"; #logging to $log_file + exit unless $pid_file; + my $pidfh = new IO::File ">$pid_file" or exit; + print $pidfh "$pid\n"; + exit; + } + + sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; } + $SIG{CHLD} = \&REAPER; + + $shutdown = 0; + $SIG{HUP} = sub { warn "SIGHUP received; shutting down\n"; $shutdown++; }; + $SIG{INT} = sub { warn "SIGINT received; shutting down\n"; $shutdown++; }; + $SIG{TERM} = sub { warn "SIGTERM received; shutting down\n"; $shutdown++; }; + $SIG{QUIT} = sub { warn "SIGQUIT received; shutting down\n"; $shutdown++; }; + $SIG{PIPE} = sub { warn "SIGPIPE received; shutting down\n"; $shutdown++; }; + + $> = $FS::UID::freeside_uid unless $>; + $< = $>; + $ENV{HOME} = (getpwuid($>))[7]; #for ssh + adminsuidsetup $user; + + #$log_file = "/usr/local/etc/freeside/selfservice.". $FS::UID::datasrc; #MACHINE NAME + $log_file = "/usr/local/etc/freeside/selfservice.$machine.log"; + + open STDOUT, '>/dev/null' + or die "Can't write to /dev/null: $!"; + setsid or die "Can't start a new session: $!"; + open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; + + $SIG{__DIE__} = \&_die; + $SIG{__WARN__} = \&_logmsg; + + warn "freeside-selfservice-server starting\n"; + +} + +sub shutdown { + my $wait = 12; #wait up to 1 minute + while ( $kids && $wait-- ) { + warn "waiting for $kids children to terminate"; + sleep 5; + } + warn "abandoning $kids children" if $kids; + kill 'TERM', $ssh_pid if $ssh_pid; + die "exiting"; +} + +sub _die { + my $msg = shift; + unlink $pid_file if -e $pid_file; + _logmsg($msg); +} + +sub _logmsg { + chomp( my $msg = shift ); + my $log = new IO::File ">>$log_file"; + flock($log, LOCK_EX); + seek($log, 0, 2); + print $log "[server] [". time2str("%a %b %e %T %Y",time). "] [$$] $msg\n"; + flock($log, LOCK_UN); + close $log; +} + +sub usage { + die "Usage:\n\n fs_signup_server user machine\n"; +} + +### +# handlers... should go in their own files eventually... +### + -- cgit v1.2.1 From b58821fcd50e52ae726834ef3863b85ed293379f Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 11 Jul 2002 13:52:39 +0000 Subject: finally working async framework --- fs_selfservice/DEPLOY | 8 + fs_selfservice/FS-SelfService/MANIFEST | 2 +- fs_selfservice/FS-SelfService/SelfService.pm | 103 ++++++---- .../FS-SelfService/freeside-selfservice-clientd | 222 +++++++++++++++++++++ fs_selfservice/freeside-selfservice-server | 115 +++++++++-- fs_selfservice/fs_passwd_test | 14 ++ 6 files changed, 409 insertions(+), 55 deletions(-) create mode 100755 fs_selfservice/DEPLOY create mode 100644 fs_selfservice/FS-SelfService/freeside-selfservice-clientd create mode 100755 fs_selfservice/fs_passwd_test (limited to 'fs_selfservice') diff --git a/fs_selfservice/DEPLOY b/fs_selfservice/DEPLOY new file mode 100755 index 000000000..9b03bf259 --- /dev/null +++ b/fs_selfservice/DEPLOY @@ -0,0 +1,8 @@ +#!/bin/sh + +cd FS-SelfService +perl Makefile.PL && make && make install + +cd .. +kill `cat /var/run/freeside-selfservice-server.ivan.pid`; sleep 3 +./freeside-selfservice-server ivan localhost diff --git a/fs_selfservice/FS-SelfService/MANIFEST b/fs_selfservice/FS-SelfService/MANIFEST index 3c490e7dd..ebd0d3b1a 100644 --- a/fs_selfservice/FS-SelfService/MANIFEST +++ b/fs_selfservice/FS-SelfService/MANIFEST @@ -1,6 +1,6 @@ Changes Makefile.PL MANIFEST -README SelfService.pm test.pl +freeside-selfservice-clientd diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index 75e550a2d..3cd4fd94e 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -1,66 +1,95 @@ package FS::SelfService; -use 5.006; use strict; -use warnings; +use vars qw($VERSION @ISA @EXPORT_OK $socket); +use Exporter; +use Socket; +use FileHandle; +#use IO::Handle; +use IO::Select; +use Storable qw(nstore_fd fd_retrieve); -require Exporter; +$VERSION = '0.03'; -our @ISA = qw(Exporter); +@ISA = qw( Exporter ); +@EXPORT_OK = qw( passwd ); -# Items to export into callers namespace by default. Note: do not export -# names by default without a very good reason. Use EXPORT_OK instead. -# Do not simply export all your public functions/methods/constants. +$socket = "/usr/local/freeside/selfservice_socket"; -# This allows declaration use FS::SelfService ':all'; -# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK -# will save memory. -our %EXPORT_TAGS = ( 'all' => [ qw( - -) ] ); +$ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin'; +$ENV{'SHELL'} = '/bin/sh'; +$ENV{'IFS'} = " \t\n"; +$ENV{'CDPATH'} = ''; +$ENV{'ENV'} = ''; +$ENV{'BASH_ENV'} = ''; -our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); +my $freeside_uid = scalar(getpwnam('freeside')); +die "not running as the freeside user\n" if $> != $freeside_uid; -our @EXPORT = qw( - -); -our $VERSION = '0.01'; +=head1 NAME +FS::SelfService - Freeside self-service API -# Preloaded methods go here. +=head1 SYNOPSIS -1; -__END__ -# Below is stub documentation for your module. You better edit it! +=head1 DESCRIPTION -=head1 NAME +Use this API to implement your own client "self-service" module. -FS::SelfService - Perl extension for blah blah blah +If you just want to customize the look of the existing "self-service" module, +see XXXX instead. -=head1 SYNOPSIS +=head1 FUNCTIONS - use FS::SelfService; - blah blah blah +=over 4 -=head1 DESCRIPTION +=item passwd -Stub documentation for FS::SelfService, created by h2xs. It looks like the -author of the extension was negligent enough to leave the stub -unedited. +Returns the empty value on success, or an error message on errors. -Blah blah blah. +=cut -=head2 EXPORT +sub passwd { + my $param; + if ( ref($_[0]) ) { + $param = shift; + } else { + $param = { @_ }; + } -None by default. + $param->{_packet} = 'passwd'; + simple_packet($param); +} -=head1 AUTHOR +sub simple_packet { + my $packet = shift; + socket(SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!"; + connect(SOCK, sockaddr_un($socket)) or die "connect: $!"; + nstore_fd($packet, \*SOCK) or die "can't send packet: $!"; + SOCK->flush; -A. U. Thor, Ea.u.thor@a.galaxy.far.far.awayE + #shoudl trap: Magic number checking on storable file failed at blib/lib/Storable.pm (autosplit into blib/lib/auto/Storable/fd_retrieve.al) line 337, at /usr/local/share/perl/5.6.1/FS/SelfService.pm line 71 + + #block until there is a message on socket +# my $w = new IO::Select; +# $w->add(\*SOCK); +# my @wait = $w->can_read; + my $return = fd_retrieve(\*SOCK) or die "error reading result: $!"; + die $return->{'_error'} if defined $return->{_error} && $return->{_error}; + + $return->{'error'}; +} + +=back + +=head1 BUGS =head1 SEE ALSO -L. +L, L =cut + +1; + diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd new file mode 100644 index 000000000..149f894e0 --- /dev/null +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd @@ -0,0 +1,222 @@ +#!/usr/bin/perl -w +# +# freeside-selfservice-clientd +# +# This is run REMOTELY over ssh by freeside-selfservice-server + +use strict; +use subs qw(spawn logmsg); +use Fcntl qw(:flock); +use Socket; +use Storable qw(nstore_fd fd_retrieve); +use IO::Handle; +use IO::Select; +use IPC::Open2; + +use LockFile::Simple qw(lock unlock); + +use vars qw( $Debug ); +$Debug = 2; + +my $socket = "/usr/local/freeside/selfservice_socket"; +my $pid_file = "$socket.pid"; +my $lock_file = "$socket.lock"; +unlink $lock_file; + +my $me = '[client]'; + +$|=1; + +#read data to be cached or something +#warn "$me Reading init data\n" if $Debug; +#my $signup_init = + +warn "[client] Creating $socket\n" if $Debug; +my $uaddr = sockaddr_un($socket); +my $proto = getprotobyname('tcp'); +socket(Server,PF_UNIX,SOCK_STREAM,0) or die "socket: $!"; +unlink($socket); +bind(Server, $uaddr) or die "bind: $!"; +listen(Server,SOMAXCONN) or die "listen: $!"; + +if ( -e $pid_file ) { + open(PIDFILE,"<$pid_file"); + #chomp( my $old_pid = ); + my $old_pid = ; + close PIDFILE; + $old_pid =~ /^(\d+)$/; + kill 'TERM', $1; +} +open(PIDFILE,">$pid_file"); +print PIDFILE "$$\n"; +close PIDFILE; + +#my $waitedpid; +#sub REAPER { $waitedpid = wait; $SIG{CHLD} = \&REAPER; } +#$SIG{CHLD} = \&REAPER; + +warn "[client] entering main loop\n" if $Debug; + +#sub spawn; +#sub logmsg; + +my %kids; + + # my $gar = ; + +#my $s = new IO::Select; +#$s->add(\*STDIN); +#$s->add(\*Server); + +#for ( $waitedpid = 0; +# accept(Client,Server) || $waitedpid; +# $waitedpid = 0, close Client) +#{ +# next if $waitedpid; + +#$SIG{PIPE} = sub { warn "SIGPIPE received" }; +#$SIG{CHLD} = sub { warn "SIGCHLD received" }; + +sub REAPER { warn "SIGCHLD received"; my $pid = wait; $SIG{CHLD} = \&REAPER; } +#sub REAPER { my $pid = wait; delete $kids{$pid}; $SIG{CHLD} = \&REAPER; } +$SIG{CHLD} = \&REAPER; + +warn "[client] creating IO::Select\n" if $Debug; +my $s = new IO::Select; +$s->add(\*STDIN); +$s->add(\*Server); + +while (1) { + +warn "[client] waiting for connection or token\n" if $Debug; +while ( my @handles = $s->can_read ) { + + foreach my $handle ( @handles ) { + + if ( $handle == \*STDIN ) { + +# my $gar = ; +# die $gar; + + my $packet = fd_retrieve(\*STDIN); + my $token = $packet->{'_token'}; + warn "[client] received packet with token $token\n". + join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) + if $Debug; + if ( exists($kids{$token}) ) { + warn "[client] sending return packet to $token via $kids{$token}\n" + if $Debug; + nstore_fd($packet, $kids{$token}); + warn "[client] flushing $kids{$token}\n" if $Debug; + $kids{$token}->flush; + #eval { $kids{$token}->flush; }; + #die "error flushing?!?!? $@\n" if $@ ne ''; + #warn "[client] closing $kids{$token}\n"; + #close $kids{$token}; + #warn "[client] deleting $kids{$token}\n"; + #delete $kids{$token}; + warn "[client] done with $token\n" if $Debug; + } else { + warn "[client] WARNING: unknown token $token, discarding message"; + #die "[client] FATAL: unknown token $token, discarding message"; + } + + } elsif ( $handle == \*Server ) { + + warn "[client] received local connection; forking\n" if $Debug; + + accept(Client, Server); + + spawn sub { #child + warn "[client-$$] reading packet from local client" if $Debug > 1; + my $packet = fd_retrieve(\*Client); + warn "[client-$$] packet received:\n". + join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) + if $Debug > 1; + my $command = $packet->{'command'}; + #handle some commands weirdly? + $packet->{_token}=$$; #?? + + warn "[client-$$] sending packet to remote server" if $Debug > 1; + flock(STDOUT, LOCK_EX); #acquire write lock + #lock($lock_file); + nstore_fd($packet, \*STDOUT); + STDOUT->flush; + #unlock($lock_file); + flock(STDOUT, LOCK_UN); #release write lock + + warn "[client-$$] waiting for response from parent" if $Debug > 1; + + #block until parent has a message + my $w = new IO::Select; + $w->add(\*STDIN); + my @wait = $w->can_read; + my $rv = fd_retrieve(\*STDIN); + + #close STDIN; + + warn "[client-$$] sending response to local client" if $Debug > 1; + + #send message to local client + nstore_fd($rv, \*Client); + Client->flush; + + close Client; + + warn "[client-$$] child exiting" if $Debug > 1; + + #while (1) { sleep 5 }; + #sleep 5; + exit; + + }; #eo child + + #close Client; #in parent, right? + + } else { + die "wtf? $handle"; + } + + } + + warn "[client] done handling messages; returning to wait-state" if $Debug;; + +} + +#die "[client] died unexpectedly: $!\n"; +warn "[client] fell-through unexpectedly: $!\n" if $Debug; + +} #WTF? + +sub spawn { + my $coderef = shift; + + unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') { + use Carp; + confess "usage: spawn CODEREF"; + } + + my $pid; + #if (!defined($pid = fork)) { + my $kid = new IO::Handle; + if (!defined($pid = open($kid, '|-'))) { + logmsg "WARNING: cannot fork: $!"; + return; + } elsif ($pid) { + logmsg "begat $pid" if $Debug; + $kids{$pid} = $kid; + #$kids{$pid}->autoflush; + return; # I'm the parent + } + # else I'm the child -- go spawn + +# open(STDIN, "<&Client") || die "can't dup client to stdin"; +# open(STDOUT, ">&Client") || die "can't dup client to stdout"; + ## open(STDERR, ">&STDOUT") || die "can't dup stdout to stderr"; + exit &$coderef(); +} + +#sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" } +#DON'T PRINT!!!!! +sub logmsg { warn "[client] $0 $$: @_ at ", scalar localtime, "\n" } + diff --git a/fs_selfservice/freeside-selfservice-server b/fs_selfservice/freeside-selfservice-server index 6146d3752..7b4a88166 100644 --- a/fs_selfservice/freeside-selfservice-server +++ b/fs_selfservice/freeside-selfservice-server @@ -12,10 +12,13 @@ use vars qw( $kids $max_kids $shutdown $log_file ); use vars qw($ssh_pid); use Fcntl qw(:flock); use POSIX qw(setsid); +use Date::Format; use IO::Handle; use Storable qw(nstore_fd fd_retrieve); use Net::SSH qw(sshopen2); -use FS::UID qw(adminsuidsetup); +use FS::UID qw(adminsuidsetup forksuidsetup); + +use LockFile::Simple qw(lock unlock); #use Tie::RefHash; #use FS::Conf; @@ -32,6 +35,8 @@ my $user = shift or die &usage; my $machine = shift or die &usage; my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; #my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; $FS::UID::datasrc not posible, but should include machine name at least, hmm +my $lock_file = "/usr/local/etc/freeside/freeside-selfservice-server.$user.lock"; +unlink $lock_file; &init($user); @@ -47,51 +52,64 @@ my %dispatch = ( my $warnkids=0; while (1) { my($reader, $writer) = (new IO::Handle, new IO::Handle); - warn "connecting to $machine"; + warn "connecting to $machine\n"; $ssh_pid = sshopen2($machine,$reader,$writer,$clientd); - warn "entering main loop"; +# nstore_fd(\*writer, {'hi'=>'there'}); + + warn "entering main loop\n"; + my $undisp = 0; while (1) { - warn "waiting for packet from client"; + warn "waiting for packet from client\n" unless $undisp; + $undisp = 1; my $packet = eval { local $SIG{__DIE__}; - local $SIG{ALRM} = sub { die "alarm\n" }; #NB: \n required + local $SIG{ALRM} = sub { local $SIG{__DIE__};die "MyAlarm\n" }; #NB: \n required alarm 5; + #my $string = <$reader>; + #die $string; my $p = fd_retrieve($reader); alarm 0; $p; }; if ($@) { - die $@ unless $@ eq "alarm\n"; + &shutdown if $shutdown && $@; + die "Fatal error receiving packet from client: $@" if $@ !~ /^MyAlarm/; + #die $@ unless $@ eq "alarm\n" || $@ eq 'Alarm'; #????? #timeout next unless $shutdown; &shutdown; } - warn "packet received"; + warn "packet received\n". + join('', map { " $_=>$packet->{$_}\n" } keys %$packet ); + + $undisp = 0; #prevent runaway forking my $warnkids = 0; while ( $kids >= $max_kids ) { - warn "WARNING: maximum $kids children reached" unless $warnkids++; + warn "WARNING: maximum $kids children reached\n" unless $warnkids++; sleep 1; } - warn "forking child"; + warn "forking child\n"; defined( my $pid = fork ) or die "can't fork: $!"; if ( $pid ) { - warn "child $pid spawned"; + warn "child $pid spawned\n"; $kids++; } else { #kid time + #local($SIG{PIPE}); + #get new db handle - $FS::UID::dbh->{InactiveDestroy} = 1; + #$FS::UID::dbh->{InactiveDestroy} = 1; forksuidsetup($user); my $sub = $dispatch{$packet->{_packet}}; my $rv; if ( $sub ) { - warn "calling $sub handler"; + warn "calling $sub handler\n"; $rv = &{$sub}($packet); } else { warn my $error = "WARNING: unknown packet type ". $packet->{_packet}; @@ -99,13 +117,15 @@ while (1) { } $rv->{_token} = $packet->{_token}; #identifier - warn "sending response"; + warn "sending response\n"; flock($writer, LOCK_EX); #acquire write lock + #lock($lock_file); nstore_fd($rv, $writer) or die "can't send response: $!"; $writer->flush; + #unlock($lock_file); flock($writer, LOCK_UN); #release write lock - - warn "child exiting"; +# + warn "child exiting\n"; exit; #end-of-kid } @@ -113,6 +133,50 @@ while (1) { } +### +# dispatch subroutines (should live elsewhere eventually) +### + +sub passwd { + #sleep 3; + use FS::Record qw(qsearchs); + use FS::svc_acct; + #use FS::svc_domain; + + my $packet = shift; + + #my $domain = qsearchs('svc_domain', { 'domain' => $packet->{'domain'} } ) + # or return { error => "Domain $domain not found" }; + + my $old_password = $packet->{'old_password'}; + my $new_password = $packet->{'new_password'}; + my $new_gecos = $packet->{'new_gecos'}; + my $new_shell = $packet->{'new_shell'}; + + my $svc_acct = + ( length($old_password) < 13 + && qsearchs( 'svc_acct', { 'username' => $packet->{'username'}, + #'domsvc' => $svc_domain->domsvc, + '_password' => $old_password } ) + ) + || qsearchs( 'svc_acct', { 'username' => $packet->{'username'}, + #'domsvc' => $svc_domain->domsvc, + '_password' => $old_password } ); + + unless ( $svc_acct ) { return { error => 'Incorrect password.' } } + + my %hash = $svc_acct->hash; + my $new_svc_acct = new FS::svc_acct ( \%hash ); + $new_svc_acct->setfield('_password', $new_password ) + if $new_password && $new_password ne $old_password; + $new_svc_acct->setfield('finger',$new_gecos) if $new_gecos; + $new_svc_acct->setfield('shell',$new_shell) if $new_shell; + my $error = $new_svc_acct->replace($svc_acct); + + return { error => $error }; + +} + ### # utility subroutines ### @@ -143,6 +207,23 @@ sub init { $> = $FS::UID::freeside_uid unless $>; $< = $>; + + #false laziness w/freeside-queued + my $freeside_gid = scalar(getgrnam('freeside')) + or die "can't setgid to freeside group\n"; + $) = $freeside_gid; + $( = $freeside_gid; + #if freebsd can't setuid(), presumably it can't setgid() either. grr fleabsd + ($(,$)) = ($),$(); + $) = $freeside_gid; + + $> = $FS::UID::freeside_uid; + $< = $FS::UID::freeside_uid; + #freebsd is sofa king broken, won't setuid() + ($<,$>) = ($>,$<); + $> = $FS::UID::freeside_uid; + #eslaf + $ENV{HOME} = (getpwuid($>))[7]; #for ssh adminsuidsetup $user; @@ -152,7 +233,7 @@ sub init { open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!"; setsid or die "Can't start a new session: $!"; - open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; +# open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; $SIG{__DIE__} = \&_die; $SIG{__WARN__} = \&_logmsg; @@ -163,7 +244,7 @@ sub init { sub shutdown { my $wait = 12; #wait up to 1 minute - while ( $kids && $wait-- ) { + while ( $kids > 0 && $wait-- ) { warn "waiting for $kids children to terminate"; sleep 5; } diff --git a/fs_selfservice/fs_passwd_test b/fs_selfservice/fs_passwd_test new file mode 100755 index 000000000..77782e651 --- /dev/null +++ b/fs_selfservice/fs_passwd_test @@ -0,0 +1,14 @@ +#!/usr/bin/perl -w + +use strict; +use FS::SelfService qw(passwd); + +my $error = passwd( + 'username' => 'ivan', + 'old_password' => 'heyhoo', + 'new_password' => 'haloo', +); + +die $error if $error; + +print "password changed sucessfully\n"; -- cgit v1.2.1 From 0393935877eebdd5bc0932d5ba0ef030bc46d167 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 15 Jul 2002 08:28:18 +0000 Subject: working framework, no hung clients, whew --- .../FS-SelfService/freeside-selfservice-clientd | 174 +++++++++++---------- fs_selfservice/freeside-selfservice-server | 121 +++++++------- fs_selfservice/fs_passwd_test | 8 +- 3 files changed, 158 insertions(+), 145 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd index 149f894e0..319d4254f 100644 --- a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd @@ -7,31 +7,35 @@ use strict; use subs qw(spawn logmsg); use Fcntl qw(:flock); +use POSIX qw(:sys_wait_h); use Socket; use Storable qw(nstore_fd fd_retrieve); -use IO::Handle; +use IO::Handle qw(_IONBF); use IO::Select; -use IPC::Open2; +use IO::File; -use LockFile::Simple qw(lock unlock); +STDOUT->setbuf(''); use vars qw( $Debug ); -$Debug = 2; +$Debug = 2; #2 will turn on child logging, 3 will log packet contents, + #including potentially compromising information my $socket = "/usr/local/freeside/selfservice_socket"; my $pid_file = "$socket.pid"; -my $lock_file = "$socket.lock"; -unlink $lock_file; -my $me = '[client]'; +my $log_file = "/usr/local/freeside/selfservice.log"; + +#my $me = '[client]'; $|=1; +$SIG{__WARN__} = \&_logmsg; + #read data to be cached or something #warn "$me Reading init data\n" if $Debug; #my $signup_init = -warn "[client] Creating $socket\n" if $Debug; +warn "Creating $socket\n" if $Debug; my $uaddr = sockaddr_un($socket); my $proto = getprotobyname('tcp'); socket(Server,PF_UNIX,SOCK_STREAM,0) or die "socket: $!"; @@ -41,7 +45,6 @@ listen(Server,SOMAXCONN) or die "listen: $!"; if ( -e $pid_file ) { open(PIDFILE,"<$pid_file"); - #chomp( my $old_pid = ); my $old_pid = ; close PIDFILE; $old_pid =~ /^(\d+)$/; @@ -55,18 +58,13 @@ close PIDFILE; #sub REAPER { $waitedpid = wait; $SIG{CHLD} = \&REAPER; } #$SIG{CHLD} = \&REAPER; -warn "[client] entering main loop\n" if $Debug; - -#sub spawn; -#sub logmsg; +warn "entering main loop\n" if $Debug; my %kids; - # my $gar = ; - -#my $s = new IO::Select; -#$s->add(\*STDIN); -#$s->add(\*Server); +my $s = new IO::Select; +$s->add(\*STDIN); +$s->add(\*Server); #for ( $waitedpid = 0; # accept(Client,Server) || $waitedpid; @@ -77,116 +75,117 @@ my %kids; #$SIG{PIPE} = sub { warn "SIGPIPE received" }; #$SIG{CHLD} = sub { warn "SIGCHLD received" }; -sub REAPER { warn "SIGCHLD received"; my $pid = wait; $SIG{CHLD} = \&REAPER; } +#sub REAPER { warn "SIGCHLD received"; my $pid = wait; $SIG{CHLD} = \&REAPER; } +#sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; } #sub REAPER { my $pid = wait; delete $kids{$pid}; $SIG{CHLD} = \&REAPER; } -$SIG{CHLD} = \&REAPER; - -warn "[client] creating IO::Select\n" if $Debug; -my $s = new IO::Select; -$s->add(\*STDIN); -$s->add(\*Server); +#$SIG{CHLD} = \&REAPER; +my $undisp = 0; while (1) { -warn "[client] waiting for connection or token\n" if $Debug; -while ( my @handles = $s->can_read ) { + &reap_kids; + + warn "waiting for connection\n" if $Debug && !$undisp; + #my @handles = $s->can_read(); + my @handles = $s->can_read(5); + $undisp = !scalar(@handles); foreach my $handle ( @handles ) { if ( $handle == \*STDIN ) { -# my $gar = ; -# die $gar; + warn "receiving packet from server\n" if $Debug; my $packet = fd_retrieve(\*STDIN); my $token = $packet->{'_token'}; - warn "[client] received packet with token $token\n". - join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) + warn "received packet from server with token $token\n". + ( $Debug > 2 + ? join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) + : '' ) if $Debug; + if ( exists($kids{$token}) ) { - warn "[client] sending return packet to $token via $kids{$token}\n" + warn "sending return packet to $token via $kids{$token}\n" if $Debug; nstore_fd($packet, $kids{$token}); - warn "[client] flushing $kids{$token}\n" if $Debug; - $kids{$token}->flush; - #eval { $kids{$token}->flush; }; - #die "error flushing?!?!? $@\n" if $@ ne ''; - #warn "[client] closing $kids{$token}\n"; - #close $kids{$token}; - #warn "[client] deleting $kids{$token}\n"; - #delete $kids{$token}; - warn "[client] done with $token\n" if $Debug; + warn "flushing to $token\n" if $Debug; + until ( $kids{$token}->flush ) { + warn "WARNING: error flushing: $!"; + sleep 1; + } + #no close or delete here - will block waiting for child + warn "done with $token\n" if $Debug; } else { - warn "[client] WARNING: unknown token $token, discarding message"; - #die "[client] FATAL: unknown token $token, discarding message"; + warn "WARNING: unknown token $token, discarding message"; } } elsif ( $handle == \*Server ) { - warn "[client] received local connection; forking\n" if $Debug; + until ( accept(Client, Server) ) { + warn "WARNING: accept failed: $!"; + next; + } - accept(Client, Server); + warn "received local connection; forking\n" if $Debug; spawn sub { #child - warn "[client-$$] reading packet from local client" if $Debug > 1; + warn "[child-$$] reading packet from local client" if $Debug > 1; my $packet = fd_retrieve(\*Client); - warn "[client-$$] packet received:\n". + warn "[child-$$] packet received:\n". join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) - if $Debug > 1; + if $Debug > 2; my $command = $packet->{'command'}; #handle some commands weirdly? - $packet->{_token}=$$; #?? - - warn "[client-$$] sending packet to remote server" if $Debug > 1; - flock(STDOUT, LOCK_EX); #acquire write lock - #lock($lock_file); - nstore_fd($packet, \*STDOUT); - STDOUT->flush; - #unlock($lock_file); - flock(STDOUT, LOCK_UN); #release write lock + $packet->{_token}=$$; - warn "[client-$$] waiting for response from parent" if $Debug > 1; + warn "[child-$$] sending packet to remote server" if $Debug > 1; + flock(STDOUT, LOCK_EX) or die "FATAL: can't lock write stream: $!"; + nstore_fd($packet, \*STDOUT) or die "FATAL: can't send response: $!"; + STDOUT->flush or die "FATAL: can't flush: $!"; + flock(STDOUT, LOCK_UN) or die "FATAL: can't release write lock: $!"; + close STDOUT or die "FATAL: can't close write stream: $!"; #??! - #block until parent has a message + warn "[child-$$] waiting for response from parent" if $Debug > 1; my $w = new IO::Select; $w->add(\*STDIN); - my @wait = $w->can_read; + until ( $w->can_read ) { + warn "[child-$$] WARNING: interrupted select: $!\n"; + } my $rv = fd_retrieve(\*STDIN); #close STDIN; - warn "[client-$$] sending response to local client" if $Debug > 1; - - #send message to local client + warn "[child-$$] sending response to local client" if $Debug > 1; nstore_fd($rv, \*Client); - Client->flush; - - close Client; + Client->flush or die "FATAL: can't flush to local client: $!"; + close Client or die "FATAL: can't close connection to local client: $!"; - warn "[client-$$] child exiting" if $Debug > 1; - - #while (1) { sleep 5 }; - #sleep 5; + warn "[child-$$] child exiting" if $Debug > 1; exit; }; #eo child - #close Client; #in parent, right? + #close Client; } else { die "wtf? $handle"; } } - - warn "[client] done handling messages; returning to wait-state" if $Debug;; - + } -#die "[client] died unexpectedly: $!\n"; -warn "[client] fell-through unexpectedly: $!\n" if $Debug; - -} #WTF? +sub reap_kids { + #warn "reaping kids\n"; + foreach my $pid ( keys %kids ) { + my $kid = waitpid($pid, WNOHANG); + if ( $kid > 0 ) { + close $kids{$kid}; + delete $kids{$kid}; + } + } + #warn "done reaping\n"; +} sub spawn { my $coderef = shift; @@ -200,10 +199,10 @@ sub spawn { #if (!defined($pid = fork)) { my $kid = new IO::Handle; if (!defined($pid = open($kid, '|-'))) { - logmsg "WARNING: cannot fork: $!"; + warn "WARNING: cannot fork: $!"; return; } elsif ($pid) { - logmsg "begat $pid" if $Debug; + warn "begat $pid" if $Debug; $kids{$pid} = $kid; #$kids{$pid}->autoflush; return; # I'm the parent @@ -212,11 +211,16 @@ sub spawn { # open(STDIN, "<&Client") || die "can't dup client to stdin"; # open(STDOUT, ">&Client") || die "can't dup client to stdout"; - ## open(STDERR, ">&STDOUT") || die "can't dup stdout to stderr"; +# open(STDERR, ">&STDOUT") || die "can't dup stdout to stderr"; exit &$coderef(); } -#sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" } -#DON'T PRINT!!!!! -sub logmsg { warn "[client] $0 $$: @_ at ", scalar localtime, "\n" } - +sub _logmsg { + chomp( my $msg = shift ); + my $log = new IO::File ">>$log_file"; + flock($log, LOCK_EX); + seek($log, 0, 2); + print $log "[client] [". scalar(localtime). "] [$$] $msg\n"; + flock($log, LOCK_UN); + close $log; +} diff --git a/fs_selfservice/freeside-selfservice-server b/fs_selfservice/freeside-selfservice-server index 7b4a88166..0e1c75e43 100644 --- a/fs_selfservice/freeside-selfservice-server +++ b/fs_selfservice/freeside-selfservice-server @@ -8,17 +8,16 @@ # Proc::Daemon or somesuch use strict; -use vars qw( $kids $max_kids $shutdown $log_file ); -use vars qw($ssh_pid); +use vars qw( $Debug %kids $kids $max_kids $shutdown $log_file $ssh_pid ); use Fcntl qw(:flock); -use POSIX qw(setsid); -use Date::Format; +use POSIX qw(:sys_wait_h setsid); use IO::Handle; +use IO::Select; +use IO::File; use Storable qw(nstore_fd fd_retrieve); use Net::SSH qw(sshopen2); -use FS::UID qw(adminsuidsetup forksuidsetup); -use LockFile::Simple qw(lock unlock); +use FS::UID qw(adminsuidsetup forksuidsetup); #use Tie::RefHash; #use FS::Conf; @@ -27,6 +26,9 @@ use LockFile::Simple qw(lock unlock); #use FS::cust_main; #use FS::Msgcat qw(gettext); +$Debug = 1; # >= 2 will log packet contents, including potentially compromising + # information + $shutdown = 0; $max_kids = '10'; #? $kids = 0; @@ -35,8 +37,6 @@ my $user = shift or die &usage; my $machine = shift or die &usage; my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; #my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; $FS::UID::datasrc not posible, but should include machine name at least, hmm -my $lock_file = "/usr/local/etc/freeside/freeside-selfservice-server.$user.lock"; -unlink $lock_file; &init($user); @@ -51,65 +51,61 @@ my %dispatch = ( my $warnkids=0; while (1) { - my($reader, $writer) = (new IO::Handle, new IO::Handle); - warn "connecting to $machine\n"; + my($writer,$reader,$error) = (new IO::Handle, new IO::Handle, new IO::Handle); + warn "connecting to $machine\n" if $Debug; + $ssh_pid = sshopen2($machine,$reader,$writer,$clientd); # nstore_fd(\*writer, {'hi'=>'there'}); - warn "entering main loop\n"; + warn "entering main loop\n" if $Debug; my $undisp = 0; + my $s = IO::Select->new( $reader ); while (1) { - warn "waiting for packet from client\n" unless $undisp; + &reap_kids; + + warn "waiting for packet from client\n" if $Debug && !$undisp; $undisp = 1; - my $packet = eval { - local $SIG{__DIE__}; - local $SIG{ALRM} = sub { local $SIG{__DIE__};die "MyAlarm\n" }; #NB: \n required - alarm 5; - #my $string = <$reader>; - #die $string; - my $p = fd_retrieve($reader); - alarm 0; - $p; - }; - if ($@) { - &shutdown if $shutdown && $@; - die "Fatal error receiving packet from client: $@" if $@ !~ /^MyAlarm/; - #die $@ unless $@ eq "alarm\n" || $@ eq 'Alarm'; #????? - #timeout - next unless $shutdown; - &shutdown; + my @handles = $s->can_read(5); + unless ( @handles ) { + &shutdown if $shutdown; + next; } - warn "packet received\n". - join('', map { " $_=>$packet->{$_}\n" } keys %$packet ); $undisp = 0; + warn "receiving packet from client\n" if $Debug; + + my $packet = fd_retrieve($reader); + warn "packet received\n". + join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) + if $Debug > 1; + #prevent runaway forking my $warnkids = 0; while ( $kids >= $max_kids ) { warn "WARNING: maximum $kids children reached\n" unless $warnkids++; + &reap_kids; sleep 1; } - warn "forking child\n"; + warn "forking child\n" if $Debug; defined( my $pid = fork ) or die "can't fork: $!"; if ( $pid ) { - warn "child $pid spawned\n"; $kids++; + $kids{$pid} = 1; + warn "child $pid spawned\n" if $Debug; } else { #kid time - #local($SIG{PIPE}); - #get new db handle - #$FS::UID::dbh->{InactiveDestroy} = 1; + $FS::UID::dbh->{InactiveDestroy} = 1; forksuidsetup($user); my $sub = $dispatch{$packet->{_packet}}; my $rv; if ( $sub ) { - warn "calling $sub handler\n"; + warn "calling $sub handler\n" if $Debug; $rv = &{$sub}($packet); } else { warn my $error = "WARNING: unknown packet type ". $packet->{_packet}; @@ -117,15 +113,13 @@ while (1) { } $rv->{_token} = $packet->{_token}; #identifier - warn "sending response\n"; - flock($writer, LOCK_EX); #acquire write lock - #lock($lock_file); - nstore_fd($rv, $writer) or die "can't send response: $!"; - $writer->flush; - #unlock($lock_file); - flock($writer, LOCK_UN); #release write lock -# - warn "child exiting\n"; + warn "sending response\n" if $Debug; + flock($writer, LOCK_EX) or die "FATAL: can't lock write stream: $!"; + nstore_fd($rv, $writer) or die "FATAL: can't send response: $!"; + $writer->flush or die "FATAL: can't flush: $!"; + flock($writer, LOCK_UN) or die "WARNING: can't release write lock: $!"; + + warn "child exiting\n" if $Debug; exit; #end-of-kid } @@ -181,11 +175,23 @@ sub passwd { # utility subroutines ### +sub reap_kids { + #warn "reaping kids\n"; + foreach my $pid ( keys %kids ) { + my $kid = waitpid($pid, WNOHANG); + if ( $kid > 0 ) { + $kids--; + delete $kids{$kid}; + } + } + #warn "done reaping\n"; +} + sub init { my $user = shift; chdir "/" or die "Can't chdir to /: $!"; - open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; + open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; defined(my $pid = fork) or die "Can't fork: $!"; if ( $pid ) { print "freeside-selfservice-server to $machine started with pid $pid\n"; #logging to $log_file @@ -195,8 +201,9 @@ sub init { exit; } - sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; } - $SIG{CHLD} = \&REAPER; +# sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; } +# #sub REAPER { my $pid = wait; $kids--; $SIG{CHLD} = \&REAPER; } +# $SIG{CHLD} = \&REAPER; $shutdown = 0; $SIG{HUP} = sub { warn "SIGHUP received; shutting down\n"; $shutdown++; }; @@ -205,9 +212,6 @@ sub init { $SIG{QUIT} = sub { warn "SIGQUIT received; shutting down\n"; $shutdown++; }; $SIG{PIPE} = sub { warn "SIGPIPE received; shutting down\n"; $shutdown++; }; - $> = $FS::UID::freeside_uid unless $>; - $< = $>; - #false laziness w/freeside-queued my $freeside_gid = scalar(getgrnam('freeside')) or die "can't setgid to freeside group\n"; @@ -233,7 +237,7 @@ sub init { open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!"; setsid or die "Can't start a new session: $!"; -# open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; + open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; $SIG{__DIE__} = \&_die; $SIG{__WARN__} = \&_logmsg; @@ -260,11 +264,16 @@ sub _die { } sub _logmsg { + chomp( my $msg = shift ); + _do_logmsg( "[server] [". scalar(localtime). "] [$$] $msg\n" ); +} + +sub _do_logmsg { chomp( my $msg = shift ); my $log = new IO::File ">>$log_file"; flock($log, LOCK_EX); seek($log, 0, 2); - print $log "[server] [". time2str("%a %b %e %T %Y",time). "] [$$] $msg\n"; + print $log "$msg\n"; flock($log, LOCK_UN); close $log; } @@ -273,7 +282,3 @@ sub usage { die "Usage:\n\n fs_signup_server user machine\n"; } -### -# handlers... should go in their own files eventually... -### - diff --git a/fs_selfservice/fs_passwd_test b/fs_selfservice/fs_passwd_test index 77782e651..c6a297968 100755 --- a/fs_selfservice/fs_passwd_test +++ b/fs_selfservice/fs_passwd_test @@ -9,6 +9,10 @@ my $error = passwd( 'new_password' => 'haloo', ); -die $error if $error; +if ( $error eq 'Incorrect password.' ) { + exit; +} else { + die $error if $error; + die "no error"; +} -print "password changed sucessfully\n"; -- cgit v1.2.1 From 6ff02eb18af2dd61ce2dca064414ca183fa02e6e Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 16 Jul 2002 12:28:02 +0000 Subject: invoice viewing... --- fs_selfservice/DEPLOY | 7 ++ fs_selfservice/FS-SelfService/SelfService.pm | 41 +++++--- fs_selfservice/FS-SelfService/cgi/login.html | 23 +++++ fs_selfservice/FS-SelfService/cgi/myaccount.html | 47 +++++++++ fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 109 +++++++++++++++++++++ .../FS-SelfService/cgi/view_invoice.html | 21 ++++ .../FS-SelfService/freeside-selfservice-clientd | 2 +- fs_selfservice/freeside-selfservice-server | 74 ++------------ fs_selfservice/fs_passwd_test | 3 +- 9 files changed, 246 insertions(+), 81 deletions(-) create mode 100644 fs_selfservice/FS-SelfService/cgi/login.html create mode 100644 fs_selfservice/FS-SelfService/cgi/myaccount.html create mode 100644 fs_selfservice/FS-SelfService/cgi/selfservice.cgi create mode 100644 fs_selfservice/FS-SelfService/cgi/view_invoice.html (limited to 'fs_selfservice') diff --git a/fs_selfservice/DEPLOY b/fs_selfservice/DEPLOY index 9b03bf259..7c68e78ec 100755 --- a/fs_selfservice/DEPLOY +++ b/fs_selfservice/DEPLOY @@ -1,8 +1,15 @@ #!/bin/sh +( cd ..; make deploy; cd fs_selfservice ) + cd FS-SelfService perl Makefile.PL && make && make install cd .. kill `cat /var/run/freeside-selfservice-server.ivan.pid`; sleep 3 ./freeside-selfservice-server ivan localhost + +cp /home/ivan/freeside_current/fs_selfservice/FS-SelfService/cgi/* /var/www/MyAccount +chown freeside /var/www/MyAccount/selfservice.cgi +chmod 4755 /var/www/MyAccount/selfservice.cgi +ln -s /var/www/MyAccount/selfservice.cgi /var/www/MyAccount/index.cgi diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index 3cd4fd94e..9019ea4f8 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -1,7 +1,7 @@ package FS::SelfService; use strict; -use vars qw($VERSION @ISA @EXPORT_OK $socket); +use vars qw($VERSION @ISA @EXPORT_OK $socket %autoload ); use Exporter; use Socket; use FileHandle; @@ -12,10 +12,19 @@ use Storable qw(nstore_fd fd_retrieve); $VERSION = '0.03'; @ISA = qw( Exporter ); -@EXPORT_OK = qw( passwd ); $socket = "/usr/local/freeside/selfservice_socket"; +%autoload = ( + 'passwd' => 'passwd/passwd', + 'chfn' => 'passwd/passwd', + 'chsh' => 'passwd/passwd', + 'login' => 'MyAccount/login', + 'customer_info' => 'MyAccount/customer_info', + 'invoice' => 'MyAccount/invoice', +); +@EXPORT_OK = keys %autoload; + $ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin'; $ENV{'SHELL'} = '/bin/sh'; $ENV{'IFS'} = " \t\n"; @@ -49,17 +58,25 @@ Returns the empty value on success, or an error message on errors. =cut -sub passwd { - my $param; - if ( ref($_[0]) ) { - $param = shift; - } else { - $param = { @_ }; - } +foreach my $autoload ( keys %autoload ) { + + my $eval = + "sub $autoload { ". ' + my $param; + if ( ref($_[0]) ) { + $param = shift; + } else { + $param = { @_ }; + } + + $param->{_packet} = \''. $autoload{$autoload}. '\'; + + simple_packet($param); + }'; - $param->{_packet} = 'passwd'; + eval $eval; + die $@ if $@; - simple_packet($param); } sub simple_packet { @@ -78,7 +95,7 @@ sub simple_packet { my $return = fd_retrieve(\*SOCK) or die "error reading result: $!"; die $return->{'_error'} if defined $return->{_error} && $return->{_error}; - $return->{'error'}; + $return; } =back diff --git a/fs_selfservice/FS-SelfService/cgi/login.html b/fs_selfservice/FS-SelfService/cgi/login.html new file mode 100644 index 000000000..dfbd0137a --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/login.html @@ -0,0 +1,23 @@ +Login +Login

+<%= $error %> +
+ + + + + + + + + + + + + + + +
Username
Domain
Password
+

+
+ diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html new file mode 100644 index 000000000..f8a916eea --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html @@ -0,0 +1,47 @@ +MyAccount +MyAccount

+<%= $url = "$selfurl?session=$session_id;action="; ''; %> +
+MyAccount
+SomethingElse
+
+ +Hello <%= $name %>!

+Your customer number is <%= $custnum %>

+Your contact information
<%= $small_custview %> +Your outstanding balance is $<%= $balance %>

+ +<%= + if ( @open_invoices ) { + $OUT .= ''. + '$td${a}Invoice #". $invoice->{'invnum'}. "$td". + "$td$a". $invoice->{'date'}. "$td". + qq!'. + ''; + $col = $col eq $col1 ? $col2 : $col1; + } + $OUT .= '
Open Invoices'; + my $link = qq!!; + my $a=qq!'; + $OUT .= + "
$a\$!. $invoice->{'owed'}. + '
'; + } else { + $OUT .= 'You have no outstanding invoices.

'; + } +%> + +
+
+small text + + + + diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi new file mode 100644 index 000000000..eae373931 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -0,0 +1,109 @@ +#!/usr/bin/perl -Tw + +use strict; +use vars qw($cgi $session_id $form_max $template_dir); +use subs qw(do_template); +use CGI; +use CGI::Carp qw(fatalsToBrowser); +use Text::Template; +use FS::SelfService qw(login customer_info invoice); + +$template_dir = '.'; + +$form_max = 255; + +$cgi = new CGI; + +unless ( defined $cgi->param('session') ) { + do_template('login',{}); + 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} ) { + do_template('login', { + 'error' => $rv->{error}, + 'username' => $username, + 'domain' => $domain, + } ); + exit; + } else { + $cgi->param('session' => $rv->{session_id} ); + $cgi->param('action' => 'myaccount' ); + } +} + +$session_id = $cgi->param('session'); + +$cgi->param('action') =~ /^(myaccount|view_invoice)$/ + or die "unknown action ". $cgi->param('action'); +my $action = $1; + +my $result = eval "&$action();"; +die $@ if $@; + +if ( $result->{error} eq "Can't resume session" ) { #ick + do_template('login',{}); + exit; +} + +#warn $result->{'open_invoices'}; +#warn scalar(@{$result->{'open_invoices'}}); + +do_template($action, { + 'session_id' => $session_id, + %{$result} +}); + +#-- + +sub myaccount { customer_info( 'session_id' => $session_id ); } + +sub view_invoice { + + $cgi->param('invnum') =~ /^(\d+)$/ or die "illegal invnum"; + my $invnum = $1; + + invoice( 'session_id' => $session_id, + 'invnum' => $invnum, + ); + +} + +#-- + +sub do_template { + my $name = shift; + my $fill_in = shift; + + $cgi->delete_all(); + $fill_in->{'self_url'} = $cgi->self_url; + + my $template = new Text::Template( TYPE => 'FILE', + SOURCE => "$template_dir/$name.html", + DELIMITERS => [ '<%=', '%>' ], + UNTAINT => 1, ) + or die $Text::Template::ERROR; + + print $cgi->header( '-expires' => 'now' ), + $template->fill_in( HASH => $fill_in ); +} + diff --git a/fs_selfservice/FS-SelfService/cgi/view_invoice.html b/fs_selfservice/FS-SelfService/cgi/view_invoice.html new file mode 100644 index 000000000..33388de99 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/view_invoice.html @@ -0,0 +1,21 @@ +MyAccount +MyAccount

+<%= $url = "$selfurl?session=$session_id;action="; ''; %> +
+MyAccount
+SomethingElse
+
+ +<-- back to MyAccount

+ +
+<%= $invoice_text %>
+
+ +
+
+small text + + + + diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd index 319d4254f..0c25c3407 100644 --- a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd @@ -17,7 +17,7 @@ use IO::File; STDOUT->setbuf(''); use vars qw( $Debug ); -$Debug = 2; #2 will turn on child logging, 3 will log packet contents, +$Debug = 3; #2 will turn on child logging, 3 will log packet contents, #including potentially compromising information my $socket = "/usr/local/freeside/selfservice_socket"; diff --git a/fs_selfservice/freeside-selfservice-server b/fs_selfservice/freeside-selfservice-server index 0e1c75e43..e55ca4984 100644 --- a/fs_selfservice/freeside-selfservice-server +++ b/fs_selfservice/freeside-selfservice-server @@ -16,17 +16,10 @@ use IO::Select; use IO::File; use Storable qw(nstore_fd fd_retrieve); use Net::SSH qw(sshopen2); - use FS::UID qw(adminsuidsetup forksuidsetup); +use FS::ClientAPI; -#use Tie::RefHash; -#use FS::Conf; -#use FS::Record qw( qsearch qsearchs ); -#use FS::cust_main_county; -#use FS::cust_main; -#use FS::Msgcat qw(gettext); - -$Debug = 1; # >= 2 will log packet contents, including potentially compromising +$Debug = 2; # >= 2 will log packet contents, including potentially compromising # information $shutdown = 0; @@ -42,13 +35,6 @@ my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; my $clientd = "/usr/local/sbin/freeside-selfservice-clientd"; #better name? -my %dispatch = ( - 'signup' => \&signup, - #'signup_init' => 'signup_init', - 'passwd' => \&passwd, - -); - my $warnkids=0; while (1) { my($writer,$reader,$error) = (new IO::Handle, new IO::Handle, new IO::Handle); @@ -102,13 +88,11 @@ while (1) { $FS::UID::dbh->{InactiveDestroy} = 1; forksuidsetup($user); - my $sub = $dispatch{$packet->{_packet}}; - my $rv; - if ( $sub ) { - warn "calling $sub handler\n" if $Debug; - $rv = &{$sub}($packet); - } else { - warn my $error = "WARNING: unknown packet type ". $packet->{_packet}; + my $type = $packet->{_packet}; + warn "calling $type handler\n" if $Debug; + my $rv = eval { FS::ClientAPI->dispatch($type, $packet); }; + if ( $@ ) { + warn my $error = "WARNING: error dispatching $type: $@"; $rv = { _error => $error }; } $rv->{_token} = $packet->{_token}; #identifier @@ -127,50 +111,6 @@ while (1) { } -### -# dispatch subroutines (should live elsewhere eventually) -### - -sub passwd { - #sleep 3; - use FS::Record qw(qsearchs); - use FS::svc_acct; - #use FS::svc_domain; - - my $packet = shift; - - #my $domain = qsearchs('svc_domain', { 'domain' => $packet->{'domain'} } ) - # or return { error => "Domain $domain not found" }; - - my $old_password = $packet->{'old_password'}; - my $new_password = $packet->{'new_password'}; - my $new_gecos = $packet->{'new_gecos'}; - my $new_shell = $packet->{'new_shell'}; - - my $svc_acct = - ( length($old_password) < 13 - && qsearchs( 'svc_acct', { 'username' => $packet->{'username'}, - #'domsvc' => $svc_domain->domsvc, - '_password' => $old_password } ) - ) - || qsearchs( 'svc_acct', { 'username' => $packet->{'username'}, - #'domsvc' => $svc_domain->domsvc, - '_password' => $old_password } ); - - unless ( $svc_acct ) { return { error => 'Incorrect password.' } } - - my %hash = $svc_acct->hash; - my $new_svc_acct = new FS::svc_acct ( \%hash ); - $new_svc_acct->setfield('_password', $new_password ) - if $new_password && $new_password ne $old_password; - $new_svc_acct->setfield('finger',$new_gecos) if $new_gecos; - $new_svc_acct->setfield('shell',$new_shell) if $new_shell; - my $error = $new_svc_acct->replace($svc_acct); - - return { error => $error }; - -} - ### # utility subroutines ### diff --git a/fs_selfservice/fs_passwd_test b/fs_selfservice/fs_passwd_test index c6a297968..4f8b8a888 100755 --- a/fs_selfservice/fs_passwd_test +++ b/fs_selfservice/fs_passwd_test @@ -3,11 +3,12 @@ use strict; use FS::SelfService qw(passwd); -my $error = passwd( +my $rv = passwd( 'username' => 'ivan', 'old_password' => 'heyhoo', 'new_password' => 'haloo', ); +my $error = $rv->{error}; if ( $error eq 'Incorrect password.' ) { exit; -- cgit v1.2.1 From 920c0d8dea4535893157a547c87dda63dca64599 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 22 Jul 2002 10:51:22 +0000 Subject: adding --- fs_selfservice/FS-SelfService/cgi/passwd.html | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 fs_selfservice/FS-SelfService/cgi/passwd.html (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/cgi/passwd.html b/fs_selfservice/FS-SelfService/cgi/passwd.html new file mode 100644 index 000000000..fadc4df8b --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/passwd.html @@ -0,0 +1,25 @@ + + + Change password + + +

Change password

+
+ + + + + + + + + + + + + +
Username
Current password
New password
Re-enter new password
+
+ + + -- cgit v1.2.1 From a09332084464d9319cd98aaabae901ad1be0ebb7 Mon Sep 17 00:00:00 2001 From: steve Date: Mon, 23 Dec 2002 14:38:51 +0000 Subject: added stuff for selfservice_server-quiet, signup_server-quiet, and emailcancel messages. --- fs_selfservice/freeside-selfservice-server | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'fs_selfservice') diff --git a/fs_selfservice/freeside-selfservice-server b/fs_selfservice/freeside-selfservice-server index e55ca4984..264cbc56d 100644 --- a/fs_selfservice/freeside-selfservice-server +++ b/fs_selfservice/freeside-selfservice-server @@ -19,6 +19,10 @@ use Net::SSH qw(sshopen2); use FS::UID qw(adminsuidsetup forksuidsetup); use FS::ClientAPI; +use FS::Conf; +use FS::cust_bill; +use FS::cust_pkg; + $Debug = 2; # >= 2 will log packet contents, including potentially compromising # information @@ -33,6 +37,13 @@ my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; &init($user); +my $conf = new FS::Conf; + +if ($conf->exists('selfservice_server-quiet')) { + $FS::cust_bill::quiet = 1; + $FS::cust_pkg::quiet = 1; +} + my $clientd = "/usr/local/sbin/freeside-selfservice-clientd"; #better name? my $warnkids=0; -- cgit v1.2.1 From 1bfcd9ce4738e5c9f3c8a309775235e823b2f82c Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 14 Jan 2003 09:26:49 +0000 Subject: move freeside-selfservice-server to proper MakeMaker install location --- fs_selfservice/freeside-selfservice-server | 235 ----------------------------- 1 file changed, 235 deletions(-) delete mode 100644 fs_selfservice/freeside-selfservice-server (limited to 'fs_selfservice') diff --git a/fs_selfservice/freeside-selfservice-server b/fs_selfservice/freeside-selfservice-server deleted file mode 100644 index 264cbc56d..000000000 --- a/fs_selfservice/freeside-selfservice-server +++ /dev/null @@ -1,235 +0,0 @@ -#!/usr/bin/perl -w -# -# freeside-selfservice-server - -# alas, much false laziness with freeside-queued and fs_signup_server. at -# least it is slated to replace fs_{signup,passwd,mailadmin}_server -# should probably generalize the version in here, or better yet use -# Proc::Daemon or somesuch - -use strict; -use vars qw( $Debug %kids $kids $max_kids $shutdown $log_file $ssh_pid ); -use Fcntl qw(:flock); -use POSIX qw(:sys_wait_h setsid); -use IO::Handle; -use IO::Select; -use IO::File; -use Storable qw(nstore_fd fd_retrieve); -use Net::SSH qw(sshopen2); -use FS::UID qw(adminsuidsetup forksuidsetup); -use FS::ClientAPI; - -use FS::Conf; -use FS::cust_bill; -use FS::cust_pkg; - -$Debug = 2; # >= 2 will log packet contents, including potentially compromising - # information - -$shutdown = 0; -$max_kids = '10'; #? -$kids = 0; - -my $user = shift or die &usage; -my $machine = shift or die &usage; -my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; -#my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; $FS::UID::datasrc not posible, but should include machine name at least, hmm - -&init($user); - -my $conf = new FS::Conf; - -if ($conf->exists('selfservice_server-quiet')) { - $FS::cust_bill::quiet = 1; - $FS::cust_pkg::quiet = 1; -} - -my $clientd = "/usr/local/sbin/freeside-selfservice-clientd"; #better name? - -my $warnkids=0; -while (1) { - my($writer,$reader,$error) = (new IO::Handle, new IO::Handle, new IO::Handle); - warn "connecting to $machine\n" if $Debug; - - $ssh_pid = sshopen2($machine,$reader,$writer,$clientd); - -# nstore_fd(\*writer, {'hi'=>'there'}); - - warn "entering main loop\n" if $Debug; - my $undisp = 0; - my $s = IO::Select->new( $reader ); - while (1) { - - &reap_kids; - - warn "waiting for packet from client\n" if $Debug && !$undisp; - $undisp = 1; - my @handles = $s->can_read(5); - unless ( @handles ) { - &shutdown if $shutdown; - next; - } - - $undisp = 0; - - warn "receiving packet from client\n" if $Debug; - - my $packet = fd_retrieve($reader); - warn "packet received\n". - join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) - if $Debug > 1; - - #prevent runaway forking - my $warnkids = 0; - while ( $kids >= $max_kids ) { - warn "WARNING: maximum $kids children reached\n" unless $warnkids++; - &reap_kids; - sleep 1; - } - - warn "forking child\n" if $Debug; - defined( my $pid = fork ) or die "can't fork: $!"; - if ( $pid ) { - $kids++; - $kids{$pid} = 1; - warn "child $pid spawned\n" if $Debug; - } else { #kid time - - #get new db handle - $FS::UID::dbh->{InactiveDestroy} = 1; - forksuidsetup($user); - - my $type = $packet->{_packet}; - warn "calling $type handler\n" if $Debug; - my $rv = eval { FS::ClientAPI->dispatch($type, $packet); }; - if ( $@ ) { - warn my $error = "WARNING: error dispatching $type: $@"; - $rv = { _error => $error }; - } - $rv->{_token} = $packet->{_token}; #identifier - - warn "sending response\n" if $Debug; - flock($writer, LOCK_EX) or die "FATAL: can't lock write stream: $!"; - nstore_fd($rv, $writer) or die "FATAL: can't send response: $!"; - $writer->flush or die "FATAL: can't flush: $!"; - flock($writer, LOCK_UN) or die "WARNING: can't release write lock: $!"; - - warn "child exiting\n" if $Debug; - exit; #end-of-kid - } - - } - -} - -### -# utility subroutines -### - -sub reap_kids { - #warn "reaping kids\n"; - foreach my $pid ( keys %kids ) { - my $kid = waitpid($pid, WNOHANG); - if ( $kid > 0 ) { - $kids--; - delete $kids{$kid}; - } - } - #warn "done reaping\n"; -} - -sub init { - my $user = shift; - - chdir "/" or die "Can't chdir to /: $!"; - open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; - defined(my $pid = fork) or die "Can't fork: $!"; - if ( $pid ) { - print "freeside-selfservice-server to $machine started with pid $pid\n"; #logging to $log_file - exit unless $pid_file; - my $pidfh = new IO::File ">$pid_file" or exit; - print $pidfh "$pid\n"; - exit; - } - -# sub REAPER { my $pid = wait; $SIG{CHLD} = \&REAPER; $kids--; } -# #sub REAPER { my $pid = wait; $kids--; $SIG{CHLD} = \&REAPER; } -# $SIG{CHLD} = \&REAPER; - - $shutdown = 0; - $SIG{HUP} = sub { warn "SIGHUP received; shutting down\n"; $shutdown++; }; - $SIG{INT} = sub { warn "SIGINT received; shutting down\n"; $shutdown++; }; - $SIG{TERM} = sub { warn "SIGTERM received; shutting down\n"; $shutdown++; }; - $SIG{QUIT} = sub { warn "SIGQUIT received; shutting down\n"; $shutdown++; }; - $SIG{PIPE} = sub { warn "SIGPIPE received; shutting down\n"; $shutdown++; }; - - #false laziness w/freeside-queued - my $freeside_gid = scalar(getgrnam('freeside')) - or die "can't setgid to freeside group\n"; - $) = $freeside_gid; - $( = $freeside_gid; - #if freebsd can't setuid(), presumably it can't setgid() either. grr fleabsd - ($(,$)) = ($),$(); - $) = $freeside_gid; - - $> = $FS::UID::freeside_uid; - $< = $FS::UID::freeside_uid; - #freebsd is sofa king broken, won't setuid() - ($<,$>) = ($>,$<); - $> = $FS::UID::freeside_uid; - #eslaf - - $ENV{HOME} = (getpwuid($>))[7]; #for ssh - adminsuidsetup $user; - - #$log_file = "/usr/local/etc/freeside/selfservice.". $FS::UID::datasrc; #MACHINE NAME - $log_file = "/usr/local/etc/freeside/selfservice.$machine.log"; - - open STDOUT, '>/dev/null' - or die "Can't write to /dev/null: $!"; - setsid or die "Can't start a new session: $!"; - open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; - - $SIG{__DIE__} = \&_die; - $SIG{__WARN__} = \&_logmsg; - - warn "freeside-selfservice-server starting\n"; - -} - -sub shutdown { - my $wait = 12; #wait up to 1 minute - while ( $kids > 0 && $wait-- ) { - warn "waiting for $kids children to terminate"; - sleep 5; - } - warn "abandoning $kids children" if $kids; - kill 'TERM', $ssh_pid if $ssh_pid; - die "exiting"; -} - -sub _die { - my $msg = shift; - unlink $pid_file if -e $pid_file; - _logmsg($msg); -} - -sub _logmsg { - chomp( my $msg = shift ); - _do_logmsg( "[server] [". scalar(localtime). "] [$$] $msg\n" ); -} - -sub _do_logmsg { - chomp( my $msg = shift ); - my $log = new IO::File ">>$log_file"; - flock($log, LOCK_EX); - seek($log, 0, 2); - print $log "$msg\n"; - flock($log, LOCK_UN); - close $log; -} - -sub usage { - die "Usage:\n\n fs_signup_server user machine\n"; -} - -- cgit v1.2.1 From e5e992881cee6c8bb5c64c101d1985d47fd62cd6 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 17 Jan 2003 06:21:38 +0000 Subject: selfservice cancel functionality --- fs_selfservice/FS-SelfService/SelfService.pm | 1 + 1 file changed, 1 insertion(+) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index 9019ea4f8..4d68d614a 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -22,6 +22,7 @@ $socket = "/usr/local/freeside/selfservice_socket"; 'login' => 'MyAccount/login', 'customer_info' => 'MyAccount/customer_info', 'invoice' => 'MyAccount/invoice', + 'cancel' => 'MyAccount/cancel', ); @EXPORT_OK = keys %autoload; -- cgit v1.2.1 From 1a6e8ccb610247daf9f475358471cfeed44f4e65 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 9 May 2003 06:03:53 +0000 Subject: updated freebsd install --- fs_selfservice/DEPLOY | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/DEPLOY b/fs_selfservice/DEPLOY index 7c68e78ec..7ab3b2a7a 100755 --- a/fs_selfservice/DEPLOY +++ b/fs_selfservice/DEPLOY @@ -9,7 +9,7 @@ cd .. kill `cat /var/run/freeside-selfservice-server.ivan.pid`; sleep 3 ./freeside-selfservice-server ivan localhost -cp /home/ivan/freeside_current/fs_selfservice/FS-SelfService/cgi/* /var/www/MyAccount +cp /home/ivan/freeside/fs_selfservice/FS-SelfService/cgi/* /var/www/MyAccount chown freeside /var/www/MyAccount/selfservice.cgi -chmod 4755 /var/www/MyAccount/selfservice.cgi -ln -s /var/www/MyAccount/selfservice.cgi /var/www/MyAccount/index.cgi +chmod 755 /var/www/MyAccount/selfservice.cgi +ln -s /var/www/MyAccount/selfservice.cgi /var/www/MyAccount/index.cgi || true -- cgit v1.2.1 From 6a961cb36a8f9606a168331fd5c3625c3bbec9c2 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 12 May 2003 07:34:15 +0000 Subject: setbuf call doesn't appear to be working... --- fs_selfservice/FS-SelfService/freeside-selfservice-clientd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd index 0c25c3407..f13dd42d7 100644 --- a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd @@ -14,7 +14,7 @@ use IO::Handle qw(_IONBF); use IO::Select; use IO::File; -STDOUT->setbuf(''); +#STDOUT->setbuf(''); use vars qw( $Debug ); $Debug = 3; #2 will turn on child logging, 3 will log packet contents, -- cgit v1.2.1 From 9033414f18177eb733d1a227d2be1c15d244f766 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 13 May 2003 03:22:35 +0000 Subject: - self-service updates: cleanup and beginnings of "make a payment" - fix pod masking FS::svc_acct::cust_svc --- fs_selfservice/FS-SelfService/cgi/login.html | 15 ++++++++++++--- fs_selfservice/FS-SelfService/cgi/myaccount.html | 13 ++++++++----- fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 8 ++++++-- fs_selfservice/FS-SelfService/cgi/view_invoice.html | 4 ++-- 4 files changed, 28 insertions(+), 12 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/cgi/login.html b/fs_selfservice/FS-SelfService/cgi/login.html index dfbd0137a..112cc34ea 100644 --- a/fs_selfservice/FS-SelfService/cgi/login.html +++ b/fs_selfservice/FS-SelfService/cgi/login.html @@ -6,16 +6,25 @@ - + - + - +
Username + + +
Domain + + +
Password + + +


diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html index f8a916eea..d8bfe0cb1 100644 --- a/fs_selfservice/FS-SelfService/cgi/myaccount.html +++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html @@ -3,20 +3,23 @@ <%= $url = "$selfurl?session=$session_id;action="; ''; %> @@ -23,7 +23,7 @@
MyAccount
-SomethingElse
+
Hello <%= $name %>!

-Your customer number is <%= $custnum %>

Your contact information
<%= $small_custview %> -Your outstanding balance is $<%= $balance %>

+
+<%= if ( $balance ) { + $OUT .= qq! Make a $balance payment!; +} %> +

<%= if ( @open_invoices ) { $OUT .= ''. '
Open Invoices'; - my $link = qq!myaccount!; my $col1 = "ffffff"; my $col2 = "dddddd"; my $col = $col1; @@ -40,7 +43,7 @@ Your outstanding balance is $<%= $balance %>


-small text +powered by freeside diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index eae373931..9b8bdc100 100644 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -53,7 +53,7 @@ if ( $cgi->param('session') eq 'login' ) { $session_id = $cgi->param('session'); -$cgi->param('action') =~ /^(myaccount|view_invoice)$/ +$cgi->param('action') =~ /^(myaccount|view_invoice|make_payment)$/ or die "unknown action ". $cgi->param('action'); my $action = $1; @@ -88,6 +88,10 @@ sub view_invoice { } +sub make_payment { + +} + #-- sub do_template { @@ -95,7 +99,7 @@ sub do_template { my $fill_in = shift; $cgi->delete_all(); - $fill_in->{'self_url'} = $cgi->self_url; + $fill_in->{'selfurl'} = $cgi->self_url; my $template = new Text::Template( TYPE => 'FILE', SOURCE => "$template_dir/$name.html", diff --git a/fs_selfservice/FS-SelfService/cgi/view_invoice.html b/fs_selfservice/FS-SelfService/cgi/view_invoice.html index 33388de99..d2b012b5d 100644 --- a/fs_selfservice/FS-SelfService/cgi/view_invoice.html +++ b/fs_selfservice/FS-SelfService/cgi/view_invoice.html @@ -3,7 +3,7 @@ <%= $url = "$selfurl?session=$session_id;action="; ''; %>
MyAccount
-SomethingElse
+
<-- back to MyAccount

@@ -14,7 +14,7 @@

-small text +powered by freeside -- cgit v1.2.1 From d1d57ae4fa0f2a30b36a70c656aa2672744f75a3 Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 18 May 2003 06:20:21 +0000 Subject: self-service: make payment UI done --- fs_selfservice/FS-SelfService/SelfService.pm | 1 + fs_selfservice/FS-SelfService/cgi/login.html | 4 ++-- fs_selfservice/FS-SelfService/cgi/myaccount.html | 7 ++----- fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 5 +++-- 4 files changed, 8 insertions(+), 9 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index 4d68d614a..c561dabdb 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -23,6 +23,7 @@ $socket = "/usr/local/freeside/selfservice_socket"; 'customer_info' => 'MyAccount/customer_info', 'invoice' => 'MyAccount/invoice', 'cancel' => 'MyAccount/cancel', + 'payment_info' => 'MyAccount/payment_info', ); @EXPORT_OK = keys %autoload; diff --git a/fs_selfservice/FS-SelfService/cgi/login.html b/fs_selfservice/FS-SelfService/cgi/login.html index 112cc34ea..ca6251eb1 100644 --- a/fs_selfservice/FS-SelfService/cgi/login.html +++ b/fs_selfservice/FS-SelfService/cgi/login.html @@ -8,7 +8,7 @@
Username - +
Password - +
diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html index d8bfe0cb1..f1a63870a 100644 --- a/fs_selfservice/FS-SelfService/cgi/myaccount.html +++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html @@ -9,12 +9,9 @@ Hello <%= $name %>!

Your contact information
<%= $small_custview %>
-<%= if ( $balance ) { - $OUT .= qq! Make a $balance payment!; +<%= if ( $balance > 0 ) { + $OUT .= qq! Make a payment

!; } %> -

- <%= if ( @open_invoices ) { $OUT .= ''. diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index 9b8bdc100..7b392bcf4 100644 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -6,7 +6,7 @@ use subs qw(do_template); use CGI; use CGI::Carp qw(fatalsToBrowser); use Text::Template; -use FS::SelfService qw(login customer_info invoice); +use FS::SelfService qw(login customer_info invoice payment_info); $template_dir = '.'; @@ -68,6 +68,7 @@ if ( $result->{error} eq "Can't resume session" ) { #ick #warn $result->{'open_invoices'}; #warn scalar(@{$result->{'open_invoices'}}); +warn "processing template $action\n"; do_template($action, { 'session_id' => $session_id, %{$result} @@ -89,7 +90,7 @@ sub view_invoice { } sub make_payment { - + payment_info( 'session_id' => $session_id ); } #-- -- cgit v1.2.1 From 416dc3b6df09133c4130445008919408f04586c3 Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 18 May 2003 08:08:12 +0000 Subject: more self-service make payment UI work --- fs_selfservice/DEPLOY | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/DEPLOY b/fs_selfservice/DEPLOY index 7ab3b2a7a..4aef4cfa4 100755 --- a/fs_selfservice/DEPLOY +++ b/fs_selfservice/DEPLOY @@ -1,14 +1,12 @@ #!/bin/sh +kill `cat /var/run/freeside-selfservice-server.fs_selfservice.pid` + ( cd ..; make deploy; cd fs_selfservice ) cd FS-SelfService perl Makefile.PL && make && make install -cd .. -kill `cat /var/run/freeside-selfservice-server.ivan.pid`; sleep 3 -./freeside-selfservice-server ivan localhost - cp /home/ivan/freeside/fs_selfservice/FS-SelfService/cgi/* /var/www/MyAccount chown freeside /var/www/MyAccount/selfservice.cgi chmod 755 /var/www/MyAccount/selfservice.cgi -- cgit v1.2.1 From 2c88b03550a72438bbd75ec7461d2c26fc797efc Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 18 May 2003 08:09:41 +0000 Subject: forgot this file --- .../FS-SelfService/cgi/make_payment.html | 118 +++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 fs_selfservice/FS-SelfService/cgi/make_payment.html (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html new file mode 100644 index 000000000..d469bddb6 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html @@ -0,0 +1,118 @@ +MyAccount +MyAccount

+<%= $url = "$selfurl?session=$session_id;action="; ''; %> +
+MyAccount
+ +
+Make a payment

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Amount Due +
+ $<%=sprintf("%.2f",$balance)%> +
+
Payment amount +
+ $"> +
+
Card type + +
Card number + + + + + + + + +
+ Exp. + + / + +
+
Exact name on card
Card billing address + +
Address line 2 + +
City + + + + + + + + +
+ + State + + Zip + +
+
+ + Remember this information +
+ NAME="CARD"> + Charge future payments to this card automatically +
+ + +
+
+powered by freeside + + -- cgit v1.2.1 From 667a729f660ad4f871acd5eb3173303396543eeb Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 18 May 2003 11:44:37 +0000 Subject: interface for making payments all done --- fs_selfservice/FS-SelfService/cgi/make_payment.html | 14 ++++++++------ fs_selfservice/FS-SelfService/cgi/myaccount.html | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html index d469bddb6..ce1db6865 100644 --- a/fs_selfservice/FS-SelfService/cgi/make_payment.html +++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html @@ -6,7 +6,7 @@ Make a payment

-
+ @@ -29,8 +29,8 @@ - +
Card type @@ -63,7 +63,7 @@
Exact name on card
Card billing address @@ -85,7 +85,7 @@ State @@ -109,7 +109,9 @@
- +
+ +

diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html index f1a63870a..f48fdedea 100644 --- a/fs_selfservice/FS-SelfService/cgi/myaccount.html +++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html @@ -7,7 +7,7 @@ Hello <%= $name %>!

-Your contact information
<%= $small_custview %> +<%= $small_custview %>
<%= if ( $balance > 0 ) { $OUT .= qq! Make a payment

!; -- cgit v1.2.1 From f0afbc011e7b909a2e6ac54039c975710e76f341 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 19 May 2003 00:15:20 +0000 Subject: processing payments... --- .../FS-SelfService/cgi/make_payment.html | 4 +- fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 73 +++++++++++++++++++++- 2 files changed, 74 insertions(+), 3 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html index ce1db6865..6adc0bde0 100644 --- a/fs_selfservice/FS-SelfService/cgi/make_payment.html +++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html @@ -99,12 +99,12 @@ - + Remember this information - NAME="CARD"> + NAME="auto" VALUE="1"> Charge future payments to this card automatically diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index 7b392bcf4..2ce2c8b6c 100644 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -53,7 +53,8 @@ if ( $cgi->param('session') eq 'login' ) { $session_id = $cgi->param('session'); -$cgi->param('action') =~ /^(myaccount|view_invoice|make_payment)$/ +$cgi->param('action') =~ + /^(myaccount|view_invoice|make_payment|process_payment)$/ or die "unknown action ". $cgi->param('action'); my $action = $1; @@ -93,6 +94,76 @@ sub make_payment { payment_info( 'session_id' => $session_id ); } +sub process_payment { + + $cgi->param('amount') =~ /^\s*(\d+(\.\d{2})?)\s*$/ + or die "illegal amount"; #!!! + my $amount = $1; + + my $payinfo = $cgi->param('payinfo'); + $payinfo =~ s/\D//g; + $payinfo =~ /^(\d{13,16})$/ + #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo; + or die "illegal card"; #!!! + $payinfo = $1; + validate($payinfo) + #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo; + or die "invalid card"; #!!! + cardtype($payinfo) eq $cgi->param('card_type') + #or $error ||= $init_data->{msgcat}{not_a}. $cgi->param('CARD_type'); + or die "not a ". $cgi->param('card_type'); + + $cgi->param('month') =~ /^(\d{2})$/ or die "illegal month"; + my $month = $1; + $cgi->param('year') =~ /^(\d{4})$/ or die "illegal year"; + my $year = $1; + + $cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname"; + my $payname = $1; + + $cgi->param('address1') =~ /^(.{0,80})$/ or die "illegal address1"; + my $address1 = $1; + + $cgi->param('address2') =~ /^(.{0,80})$/ or die "illegal address2"; + my $address2 = $1; + + $cgi->param('city') =~ /^(.{0,80})$/ or die "illegal city"; + my $city = $1; + + $cgi->param('state') =~ /^(.{2})$/ or die "illegal state"; + my $state = $1; + + $cgi->param('zip') =~ /^(.{0,10})$/ or die "illegal zip"; + my $zip = $1; + + my $save = 0; + $save = 1 if $cgi->param('save'); + + my $auto = 0; + $auto = 1 if $cgi->param('auto'); + + $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch"; + my $patbatch = $1; + + process_payment( + 'session_id' => $session_id, + 'amount' => $amount, + 'payinfo' => $payinfo, + 'month' => $month, + 'year' => $year, + 'payname' => $payname, + 'address1' => $address1, + 'address2' => $address2, + 'city' => $city, + 'state' => $state, + 'zip' => $zip, + 'save' => $save, + 'auto' => $auto, + 'paybatch' => $paybatch, + ); + +} + #-- sub do_template { -- cgit v1.2.1 From a1295d0682aa81a408abe06fcaa7c14440f6a2e2 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 19 May 2003 13:38:41 +0000 Subject: first crack at payment processing with self-service (step two of the process) --- fs_selfservice/FS-SelfService/cgi/make_payment.html | 4 ++-- fs_selfservice/FS-SelfService/cgi/process_payment.html | 18 ++++++++++++++++++ fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 4 +++- 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 fs_selfservice/FS-SelfService/cgi/process_payment.html (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html index 6adc0bde0..fdb411b11 100644 --- a/fs_selfservice/FS-SelfService/cgi/make_payment.html +++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html @@ -31,7 +31,7 @@ @@ -104,7 +104,7 @@ - NAME="auto" VALUE="1"> + NAME="auto" VALUE="1" onClick="if (this.checked) { document.OneTrueForm.save.checked=true; }"> Charge future payments to this card automatically diff --git a/fs_selfservice/FS-SelfService/cgi/process_payment.html b/fs_selfservice/FS-SelfService/cgi/process_payment.html new file mode 100644 index 000000000..e4946dc8f --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_payment.html @@ -0,0 +1,18 @@ +MyAccount +MyAccount

+<%= $url = "$selfurl?session=$session_id;action="; ''; %> +
+MyAccount
+ +
+Payment results

+<%= if ( $error ) { + $OUT .= qq!Error processing your payment: $error +
+
+powered by freeside + + diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index 2ce2c8b6c..d43df4041 100644 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -96,6 +96,8 @@ sub make_payment { sub process_payment { + use Business::CreditCard; + $cgi->param('amount') =~ /^\s*(\d+(\.\d{2})?)\s*$/ or die "illegal amount"; #!!! my $amount = $1; @@ -143,7 +145,7 @@ sub process_payment { $auto = 1 if $cgi->param('auto'); $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch"; - my $patbatch = $1; + my $paybatch = $1; process_payment( 'session_id' => $session_id, -- cgit v1.2.1 From e2a51e422dbd070a4571f229f8e5c6929950d137 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 19 May 2003 13:54:55 +0000 Subject: fix up some bugs in processing payments via self-service... appears to be working so far --- fs_selfservice/FS-SelfService/SelfService.pm | 17 +++++++++-------- fs_selfservice/FS-SelfService/cgi/make_payment.html | 4 ++-- fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 7 ++++--- 3 files changed, 15 insertions(+), 13 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index c561dabdb..5849b28d1 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -16,14 +16,15 @@ $VERSION = '0.03'; $socket = "/usr/local/freeside/selfservice_socket"; %autoload = ( - 'passwd' => 'passwd/passwd', - 'chfn' => 'passwd/passwd', - 'chsh' => 'passwd/passwd', - 'login' => 'MyAccount/login', - 'customer_info' => 'MyAccount/customer_info', - 'invoice' => 'MyAccount/invoice', - 'cancel' => 'MyAccount/cancel', - 'payment_info' => 'MyAccount/payment_info', + 'passwd' => 'passwd/passwd', + 'chfn' => 'passwd/passwd', + 'chsh' => 'passwd/passwd', + 'login' => 'MyAccount/login', + 'customer_info' => 'MyAccount/customer_info', + 'invoice' => 'MyAccount/invoice', + 'cancel' => 'MyAccount/cancel', + 'payment_info' => 'MyAccount/payment_info', + 'process_payment' => 'MyAccount/process_payment', ); @EXPORT_OK = keys %autoload; diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html index fdb411b11..1d860f08a 100644 --- a/fs_selfservice/FS-SelfService/cgi/make_payment.html +++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html @@ -8,7 +8,7 @@ Make a payment

- + @@ -110,7 +110,7 @@
Amount Due

- +
diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index d43df4041..456d2dde2 100644 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -6,7 +6,8 @@ use subs qw(do_template); use CGI; use CGI::Carp qw(fatalsToBrowser); use Text::Template; -use FS::SelfService qw(login customer_info invoice payment_info); +use FS::SelfService qw( login customer_info invoice payment_info + process_payment ); $template_dir = '.'; @@ -54,7 +55,7 @@ if ( $cgi->param('session') eq 'login' ) { $session_id = $cgi->param('session'); $cgi->param('action') =~ - /^(myaccount|view_invoice|make_payment|process_payment)$/ + /^(myaccount|view_invoice|make_payment|do_payment)$/ or die "unknown action ". $cgi->param('action'); my $action = $1; @@ -94,7 +95,7 @@ sub make_payment { payment_info( 'session_id' => $session_id ); } -sub process_payment { +sub do_payment { use Business::CreditCard; -- cgit v1.2.1 From e354694764fb1442b6bc74a63189f094c51f1a89 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 20 May 2003 05:43:47 +0000 Subject: working self-service self-payments! --- fs_selfservice/FS-SelfService/cgi/make_payment.html | 2 +- fs_selfservice/FS-SelfService/cgi/payment_results.html | 18 ++++++++++++++++++ fs_selfservice/FS-SelfService/cgi/process_payment.html | 18 ------------------ fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 4 ++-- 4 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 fs_selfservice/FS-SelfService/cgi/payment_results.html delete mode 100644 fs_selfservice/FS-SelfService/cgi/process_payment.html (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/cgi/make_payment.html b/fs_selfservice/FS-SelfService/cgi/make_payment.html index 1d860f08a..a1cda6d49 100644 --- a/fs_selfservice/FS-SelfService/cgi/make_payment.html +++ b/fs_selfservice/FS-SelfService/cgi/make_payment.html @@ -8,7 +8,7 @@ Make a payment

- + diff --git a/fs_selfservice/FS-SelfService/cgi/payment_results.html b/fs_selfservice/FS-SelfService/cgi/payment_results.html new file mode 100644 index 000000000..92c8cf51b --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/payment_results.html @@ -0,0 +1,18 @@ +MyAccount +MyAccount

+<%= $url = "$selfurl?session=$session_id;action="; ''; %> +
Amount Due
+MyAccount
+ +
+Payment results

+<%= if ( $error ) { + $OUT .= qq!Error processing your payment: $error!; +} else { + $OUT .= 'Your payment was processed sucessfully. Thank you.'; +} %> +
+
+powered by freeside + + diff --git a/fs_selfservice/FS-SelfService/cgi/process_payment.html b/fs_selfservice/FS-SelfService/cgi/process_payment.html deleted file mode 100644 index e4946dc8f..000000000 --- a/fs_selfservice/FS-SelfService/cgi/process_payment.html +++ /dev/null @@ -1,18 +0,0 @@ -MyAccount -MyAccount

-<%= $url = "$selfurl?session=$session_id;action="; ''; %> -
-MyAccount
- -
-Payment results

-<%= if ( $error ) { - $OUT .= qq!Error processing your payment: $error -
-
-powered by freeside - - diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index 456d2dde2..6d6716ddc 100644 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -55,7 +55,7 @@ if ( $cgi->param('session') eq 'login' ) { $session_id = $cgi->param('session'); $cgi->param('action') =~ - /^(myaccount|view_invoice|make_payment|do_payment)$/ + /^(myaccount|view_invoice|make_payment|payment_results)$/ or die "unknown action ". $cgi->param('action'); my $action = $1; @@ -95,7 +95,7 @@ sub make_payment { payment_info( 'session_id' => $session_id ); } -sub do_payment { +sub payment_results { use Business::CreditCard; -- cgit v1.2.1 From 7c5ac7082001b4aee97e0cdde41e492869b9fbaa Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 19 Sep 2003 11:35:57 +0000 Subject: finish moving signup server functions to self-service interace --- fs_selfservice/FS-SelfService/SelfService.pm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index 5849b28d1..5d3f50b10 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -15,6 +15,7 @@ $VERSION = '0.03'; $socket = "/usr/local/freeside/selfservice_socket"; +#maybe should ask ClientAPI for this list %autoload = ( 'passwd' => 'passwd/passwd', 'chfn' => 'passwd/passwd', @@ -25,6 +26,8 @@ $socket = "/usr/local/freeside/selfservice_socket"; 'cancel' => 'MyAccount/cancel', 'payment_info' => 'MyAccount/payment_info', 'process_payment' => 'MyAccount/process_payment', + 'signup_info' => 'Signup/signup_info', + 'new_customer' => 'Signup/new_customer', ); @EXPORT_OK = keys %autoload; -- cgit v1.2.1 From 9679b64218a5bb0b148d07582589dd8ef0de7567 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 25 Sep 2003 10:28:13 +0000 Subject: freebsd portability fix --- .../FS-SelfService/freeside-selfservice-clientd | 33 ++++++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd index f13dd42d7..438d472c9 100644 --- a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd @@ -5,7 +5,7 @@ # This is run REMOTELY over ssh by freeside-selfservice-server use strict; -use subs qw(spawn logmsg); +use subs qw(spawn logmsg lock_write unlock_write); use Fcntl qw(:flock); use POSIX qw(:sys_wait_h); use Socket; @@ -25,6 +25,8 @@ my $pid_file = "$socket.pid"; my $log_file = "/usr/local/freeside/selfservice.log"; +my $lock_file = "/usr/local/freeside/selfservice.writelock"; + #my $me = '[client]'; $|=1; @@ -35,6 +37,9 @@ $SIG{__WARN__} = \&_logmsg; #warn "$me Reading init data\n" if $Debug; #my $signup_init = +warn "Creating $lock_file\n" if $Debug; +open(LOCKFILE,">$lock_file") or die "can't open $lock_file: $!"; + warn "Creating $socket\n" if $Debug; my $uaddr = sockaddr_un($socket); my $proto = getprotobyname('tcp'); @@ -138,11 +143,19 @@ while (1) { #handle some commands weirdly? $packet->{_token}=$$; + warn "[child-$$] locking write stream" if $Debug > 1; + lock_write; + warn "[child-$$] sending packet to remote server" if $Debug > 1; - flock(STDOUT, LOCK_EX) or die "FATAL: can't lock write stream: $!"; nstore_fd($packet, \*STDOUT) or die "FATAL: can't send response: $!"; + + warn "[child-$$] flushing write stream" if $Debug > 1; STDOUT->flush or die "FATAL: can't flush: $!"; - flock(STDOUT, LOCK_UN) or die "FATAL: can't release write lock: $!"; + + warn "[child-$$] releasing write lock" if $Debug > 1; + unlock_write; + + warn "[child-$$] closing write stream" if $Debug > 1; close STDOUT or die "FATAL: can't close write stream: $!"; #??! warn "[child-$$] waiting for response from parent" if $Debug > 1; @@ -224,3 +237,17 @@ sub _logmsg { flock($log, LOCK_UN); close $log; } + +sub lock_write { + #broken on freebsd? + #flock(STDOUT, LOCK_EX) or die "FATAL: can't lock write stream: $!"; + + flock(LOCKFILE, LOCK_EX) or die "FATAL: can't lock $lock_file: $!"; +} + +sub unlock_write { + #broken on freebsd? + #flock(STDOUT, LOCK_UN) or die "FATAL: can't release write lock: $!"; + + flock(LOCKFILE, LOCK_UN) or die "FATAL: can't unlock $lock_file: $!"; +} -- cgit v1.2.1 From d8ea8ef98411f56069ff4036bd5a2403b456655b Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 2 Oct 2003 11:23:04 +0000 Subject: removing testing info --- fs_selfservice/FS-SelfService/cgi/login.html | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/cgi/login.html b/fs_selfservice/FS-SelfService/cgi/login.html index ca6251eb1..5607de783 100644 --- a/fs_selfservice/FS-SelfService/cgi/login.html +++ b/fs_selfservice/FS-SelfService/cgi/login.html @@ -7,23 +7,20 @@ Username - - + Domain - - + Password - - + -- cgit v1.2.1 From 98527623b1fea1107b2c0422a0838b4602c21fa9 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 2 Oct 2003 12:42:23 +0000 Subject: update Makefile.PL dependancies (PREREQ_PM) for self-service module and signup wrapper --- fs_selfservice/FS-SelfService/Makefile.PL | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/Makefile.PL b/fs_selfservice/FS-SelfService/Makefile.PL index da0a0aa24..e5cbd1aef 100644 --- a/fs_selfservice/FS-SelfService/Makefile.PL +++ b/fs_selfservice/FS-SelfService/Makefile.PL @@ -8,7 +8,9 @@ WriteMakefile( 'INSTALLSCRIPT' => '/usr/local/sbin', 'INSTALLSITEBIN' => '/usr/local/sbin', 'PERM_RWX' => '750', - 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1 + 'PREREQ_PM' => { + 'Storable' => 0, + }, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'SelfService.pm', # retrieve abstract from module AUTHOR => 'Ivan Kohler ') : ()), -- cgit v1.2.1 From 2563e2d621c76a1fe9987e99e68fbe33e3f7aa7e Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 2 Oct 2003 13:08:58 +0000 Subject: turn off super-verbose logging --- fs_selfservice/FS-SelfService/freeside-selfservice-clientd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd index 438d472c9..45d9da9c7 100644 --- a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd @@ -17,7 +17,7 @@ use IO::File; #STDOUT->setbuf(''); use vars qw( $Debug ); -$Debug = 3; #2 will turn on child logging, 3 will log packet contents, +$Debug = 2; #2 will turn on child logging, 3 will log packet contents, #including potentially compromising information my $socket = "/usr/local/freeside/selfservice_socket"; -- cgit v1.2.1 From bacea004a735c7a9c30a35e9184a63897a200e6e Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 15 Oct 2003 15:03:56 +0000 Subject: add tagging ability so we can run multiple self-service clients on one machine --- fs_selfservice/FS-SelfService/SelfService.pm | 3 ++- fs_selfservice/FS-SelfService/freeside-selfservice-clientd | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index 5d3f50b10..b2532be71 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -1,7 +1,7 @@ package FS::SelfService; use strict; -use vars qw($VERSION @ISA @EXPORT_OK $socket %autoload ); +use vars qw($VERSION @ISA @EXPORT_OK $socket %autoload $tag); use Exporter; use Socket; use FileHandle; @@ -14,6 +14,7 @@ $VERSION = '0.03'; @ISA = qw( Exporter ); $socket = "/usr/local/freeside/selfservice_socket"; +$socket .= '.'.$tag if defined $tag && length($tag); #maybe should ask ClientAPI for this list %autoload = ( diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd index 45d9da9c7..a8b1e713b 100644 --- a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd @@ -16,16 +16,18 @@ use IO::File; #STDOUT->setbuf(''); +my $tag = scalar(@ARGV) ? '.'.shift : ''; + use vars qw( $Debug ); $Debug = 2; #2 will turn on child logging, 3 will log packet contents, #including potentially compromising information -my $socket = "/usr/local/freeside/selfservice_socket"; +my $socket = "/usr/local/freeside/selfservice_socket$tag"; my $pid_file = "$socket.pid"; -my $log_file = "/usr/local/freeside/selfservice.log"; +my $log_file = "/usr/local/freeside/selfservice$tag.log"; -my $lock_file = "/usr/local/freeside/selfservice.writelock"; +my $lock_file = "/usr/local/freeside/selfservice$tag.writelock"; #my $me = '[client]'; -- cgit v1.2.1 From 8bf0686b09cde9eb2aa453420e3a7bcc4ada9f88 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 8 Nov 2003 16:31:49 +0000 Subject: documentation for self-service functions! --- fs_selfservice/FS-SelfService/SelfService.pm | 559 +++++++++++++++++++++++++-- 1 file changed, 536 insertions(+), 23 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index b2532be71..be6dd3a8a 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -27,6 +27,9 @@ $socket .= '.'.$tag if defined $tag && length($tag); 'cancel' => 'MyAccount/cancel', 'payment_info' => 'MyAccount/payment_info', 'process_payment' => 'MyAccount/process_payment', + 'list_pkgs' => 'MyAccount/list_pkgs', + 'order_pkg' => 'MyAccount/order_pkg', + 'cancel_pkg' => 'MyAccount/cancel_pkg', 'signup_info' => 'Signup/signup_info', 'new_customer' => 'Signup/new_customer', ); @@ -42,29 +45,6 @@ $ENV{'BASH_ENV'} = ''; my $freeside_uid = scalar(getpwnam('freeside')); die "not running as the freeside user\n" if $> != $freeside_uid; -=head1 NAME - -FS::SelfService - Freeside self-service API - -=head1 SYNOPSIS - -=head1 DESCRIPTION - -Use this API to implement your own client "self-service" module. - -If you just want to customize the look of the existing "self-service" module, -see XXXX instead. - -=head1 FUNCTIONS - -=over 4 - -=item passwd - -Returns the empty value on success, or an error message on errors. - -=cut - foreach my $autoload ( keys %autoload ) { my $eval = @@ -105,6 +85,539 @@ sub simple_packet { $return; } +=head1 NAME + +FS::SelfService - Freeside self-service API + +=head1 SYNOPSIS + + # password and shell account changes + use FS::SelfService qw(passwd chfn chsh); + + # "my account" functionality + use FS::SelfService qw( login customer_info invoice cancel payment_info process_payment ); + + my $rv = login( { 'username' => $username, + 'domain' => $domain, + 'password' => $password, + } + ); + + if ( $rv->{'error'} ) { + #handle login error... + } else { + #successful login + my $session_id = $rv->{'session_id'}; + } + + my $customer_info = customer_info( { 'session_id' => $session_id } ); + + #payment_info and process_payment are available in 1.5+ only + my $payment_info = payment_info) { 'session_id' => $session_id } ); + + #!!! process_payment example + + #!!! list_pkgs example + + #!!! order_pkg example + + #!!! cancel_pkg example + + # signup functionality + use FS::SelfService qw( signup_info new_customer ); + + my $signup_info = signup_info; + + $rv = new_customer( { + 'first' => $first, + 'last' => $last, + 'company' => $company, + 'address1' => $address1, + 'address2' => $address2, + 'city' => $city, + 'state' => $state, + 'zip' => $zip, + 'country' => $country, + 'daytime' => $daytime, + 'night' => $night, + 'fax' => $fax, + 'payby' => $payby, + 'payinfo' => $payinfo, + 'paycvv' => $paycvv, + 'paydate' => $paydate, + 'payname' => $payname, + 'invoicing_list' => $invoicing_list, + 'referral_custnum' => $referral_custnum, + 'pkgpart' => $pkgpart, + 'username' => $username, + '_password' => $password, + 'popnum' => $popnum, + 'agentnum' => $agentnum, + } + ); + + my $error = $rv->{'error'}; + if ( $error eq '_decline' ) { + print_decline(); + } elsif ( $error ) { + reprint_signup(); + } else { + print_success(); + } + +=head1 DESCRIPTION + +Use this API to implement your own client "self-service" module. + +If you just want to customize the look of the existing "self-service" module, +see XXXX instead. + +=head1 PASSWORD, GECOS, SHELL CHANGING FUNCTIONS + +=over 4 + +=item passwd + +=item chfn + +=item chsh + +=back + +=head1 "MY ACCOUNT" FUNCTIONS + +=over 4 + +=item login HASHREF + +Creates a user session. Takes a hash reference as parameter with the +following keys: + +=over 4 + +=item username + +=item domain + +=item password + +=back + +Returns a hash reference with the following keys: + +=over 4 + +=item error + +Empty on success, or an error message on errors. + +=item session_id + +Session identifier for successful logins + +=back + +=item customer_info HASHREF + +Returns general customer information. + +Takes a hash reference as parameter with a single key: B + +Returns a hash reference with the following keys: + +=over 4 + +=item name + +Customer name + +=item balance + +Balance owed + +=item open + +Array reference of hash references of open inoices. Each hash reference has +the following keys: invnum, date, owed + +=item small_custview + +An HTML fragment containing shipping and billing addresses. + +=back + +=item invoice HASHREF + +Returns an invoice. Takes a hash reference as parameter with two keys: +session_id and invnum + +Returns a hash reference with the following keys: + +=over 4 + +=item error + +Empty on success, or an error message on errors + +=item invnum + +Invoice number + +=item invoice_text + +Invoice text + +=back + +=item cancel HASHREF + +Cancels this customer. + +Takes a hash reference as parameter with a single key: B + +Returns a hash reference with a single key, B, which is empty on +success or an error message on errors. + +=item payment_info HASHREF + +Returns information that may be useful in displaying a payment page. + +Takes a hash reference as parameter with a single key: B. + +Returns a hash reference with the following keys: + +=over 4 + +=item error + +Empty on success, or an error message on errors + +=item balance + +Balance owed + +=item payname + +Exact name on credit card (CARD/DCRD) + +=item address1 + +=item address2 + +=item city + +=item state + +=item zip + +=item payby + +Customer's current default payment type. + +=item card_type + +For CARD/DCRD payment types, the card type (Visa card, MasterCard, Discover card, American Express card, etc.) + +=item payinfo + +For CARD/DCRD payment types, the card number + +=item month + +For CARD/DCRD payment types, expiration month + +=item year + +For CARD/DCRD payment types, expiration year + +=item cust_main_county + +County/state/country data - array reference of hash references, each of which has the fields of a cust_main_county record (see L). Note these are not FS::cust_main_county objects, but hash references of columns and values. + +=item states + +Array reference of all states in the current default country. + +=item card_types + +Hash reference of card types; keys are card types, values are the exact strings +passed to the process_payment function + +=item paybatch + +Unique transaction identifier (prevents multiple charges), passed to the +process_payment function + +=back + +=item process_payment HASHREF + +Processes a payment and possible change of address or payment type. Takes a +hash reference as parameter with the following keys: + +=over 4 + +=item session_id + +=item save + +If true, address and card information entered will be saved for subsequent +transactions. + +=item auto + +If true, future credit card payments will be done automatically (sets payby to +CARD). If false, future credit card payments will be done on-demand (sets +payby to DCRD). This option only has meaning if B is set true. + +=item payname + +=item address1 + +=item address2 + +=item city + +=item state + +=item zip + +=item payinfo + +Card number + +=item month + +Card expiration month + +=item year + +Card expiration year + +=item paybatch + +Unique transaction identifier, returned from the payment_info function. +Prevents multiple charges. + +=back + +Returns a hash reference with a single key, B, empty on success, or an +error message on errors + +=item list_pkgs + +Returns package information for this customer. + +Takes a hash reference as parameter with a single key: B + +Returns a hash reference containing customer package information. The hash reference contains the following keys: + +=over 4 + +=item cust_pkg HASHREF + +Array reference of hash references, each of which has the fields of a cust_pkg record (see L). Note these are not FS::cust_pkg objects, but hash references of columns and values. + +=back + +=item order_pkg + +Orders a package for this customer. + +Takes a hash reference as parameter with the following keys: + +=over 4 + +=item session_id + +=item pkgpart + +=item svcpart + +optional svcpart, required only if the package definition does not contain +one svc_acct service definition with quantity 1 (it may contain others with +quantity >1) + +=item username + +=item _password + +=item sec_phrase + +=item popnum + +=back + +Returns a hash reference with a single key, B, empty on success, or an +error message on errors. The special error '_decline' is returned for +declined transactions. + +=item cancel_pkg + +Cancels a package for this customer. + +Takes a hash reference as parameter with the following keys: + +=over 4 + +=item session_id + +=item pkgpart + +=back + +Returns a hash reference with a single key, B, empty on success, or an +error message on errors. + +=back + +=head1 SIGNUP FUNCTIONS + +=over 4 + +=item signup_info + +Returns a hash reference containing information that may be useful in +displaying a signup page. The hash reference contains the following keys: + +=over 4 + +=item cust_main_county + +County/state/country data - array reference of hash references, each of which has the fields of a cust_main_county record (see L). Note these are not FS::cust_main_county objects, but hash references of columns and values. + +=item part_pkg + +Available packages - array reference of hash references, each of which has the fields of a part_pkg record (see L). Each hash reference also has an additional 'payby' field containing an array reference of acceptable payment types specific to this package (see below and L). Note these are not FS::part_pkg objects, but hash references of columns and values. Requires the 'signup_server-default_agentnum' configuration value to be set. + +=item agent + +Array reference of hash references, each of which has the fields of an agent record (see L). Note these are not FS::agent objects, but hash references of columns and values. + +=item agentnum2part_pkg + +Hash reference; keys are agentnums, values are array references of available packages for that agent, in the same format as the part_pkg arrayref above. + +=item svc_acct_pop + +Access numbers - array reference of hash references, each of which has the fields of an svc_acct_pop record (see L). Note these are not FS::svc_acct_pop objects, but hash references of columns and values. + +=item security_phrase + +True if the "security_phrase" feature is enabled + +=item payby + +Array reference of acceptable payment types for signup + +=over 4 + +=item CARD (credit card - automatic) + +=item DCRD (credit card - on-demand - version 1.5+ only) + +=item CHEK (electronic check - automatic) + +=item DCHK (electronic check - on-demand - version 1.5+ only) + +=item LECB (Phone bill billing) + +=item BILL (billing, not recommended for signups) + +=item COMP (free, definately not recommended for signups) + +=item PREPAY (special billing type: applies a credit (see FS::prepay_credit) and sets billing type to BILL) + +=back + +=item cvv_enabled + +True if CVV features are available (1.5+ or 1.4.2 with CVV schema patch) + +=item msgcat + +Hash reference of message catalog values, to support error message customization. Currently available keys are: passwords_dont_match, invalid_card, unknown_card_type, and not_a (as in "Not a Discover card"). Values are configured in the web interface under "View/Edit message catalog". + +=item statedefault + +Default state + +=item countrydefault + +Default country + +=back + +=item new_customer HASHREF + +Creates a new customer. Takes a hash reference as parameter with the +following keys: + +=over 4 + +=item first - first name (required) + +=item last - last name (required) + +=item ss (not typically collected; mostly used for ACH transactions) + +=item company + +=item address1 (required) + +=item address2 + +=item city (required) + +=item county + +=item state (required) + +=item zip (required) + +=item daytime - phone + +=item night - phone + +=item fax - phone + +=item payby - CARD, DCRD, CHEK, DCHK, LECB, BILL, COMP or PREPAY (see L (required) + +=item payinfo - Card number for CARD/DCRD, account_number@aba_number for CHEK/DCHK, prepaid "pin" for PREPAY, purchase order number for BILL + +=item paycvv - Credit card CVV2 number (1.5+ or 1.4.2 with CVV schema patch) + +=item paydate - Expiration date for CARD/DCRD + +=item payname - Exact name on credit card for CARD/DCRD, bank name for CHEK/DCHK + +=item invoicing_list - comma-separated list of email addresses for email invoices. The special value 'POST' is used to designate postal invoicing (it may be specified alone or in addition to email addresses), + +=item referral_custnum - referring customer number + +=item pkgpart - pkgpart of initial package + +=item username + +=item _password + +=item sec_phrase - security phrase + +=item popnum - access number (index, not the literal number) + +=item agentnum - agent number + +=back + +Returns a hash reference with the following keys: + +=over 4 + +=item error Empty on success, or an error message on errors. The special error '_decline' is returned for declined transactions; other error messages should be suitable for display to the user (and are customizable in under Sysadmin | View/Edit message catalog) + +=back + + =back =head1 BUGS -- cgit v1.2.1 From 3631b278f61e0dd08026f7a21ac2d24964f1ea99 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 15 Nov 2003 07:18:39 +0000 Subject: add trailing newline to supress useless error messages in log --- fs_selfservice/FS-SelfService/freeside-selfservice-clientd | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd index a8b1e713b..925bce6d2 100644 --- a/fs_selfservice/FS-SelfService/freeside-selfservice-clientd +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-clientd @@ -145,22 +145,22 @@ while (1) { #handle some commands weirdly? $packet->{_token}=$$; - warn "[child-$$] locking write stream" if $Debug > 1; + warn "[child-$$] locking write stream\n" if $Debug > 1; lock_write; - warn "[child-$$] sending packet to remote server" if $Debug > 1; + warn "[child-$$] sending packet to remote server\n" if $Debug > 1; nstore_fd($packet, \*STDOUT) or die "FATAL: can't send response: $!"; - warn "[child-$$] flushing write stream" if $Debug > 1; + warn "[child-$$] flushing write stream\n" if $Debug > 1; STDOUT->flush or die "FATAL: can't flush: $!"; - warn "[child-$$] releasing write lock" if $Debug > 1; + warn "[child-$$] releasing write lock\n" if $Debug > 1; unlock_write; - warn "[child-$$] closing write stream" if $Debug > 1; + warn "[child-$$] closing write stream\n" if $Debug > 1; close STDOUT or die "FATAL: can't close write stream: $!"; #??! - warn "[child-$$] waiting for response from parent" if $Debug > 1; + warn "[child-$$] waiting for response from parent\n" if $Debug > 1; my $w = new IO::Select; $w->add(\*STDIN); until ( $w->can_read ) { -- cgit v1.2.1 From 38d7ed9d33840a59bbbf6895e3c7a6d191094c03 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 23 Dec 2003 00:51:37 +0000 Subject: add edit_info to selfservice API --- fs_selfservice/FS-SelfService/SelfService.pm | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'fs_selfservice') diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index be6dd3a8a..715f935f3 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -23,6 +23,7 @@ $socket .= '.'.$tag if defined $tag && length($tag); 'chsh' => 'passwd/passwd', 'login' => 'MyAccount/login', 'customer_info' => 'MyAccount/customer_info', + 'edit_info' => 'MyAccount/edit_info', 'invoice' => 'MyAccount/invoice', 'cancel' => 'MyAccount/cancel', 'payment_info' => 'MyAccount/payment_info', @@ -113,7 +114,7 @@ FS::SelfService - Freeside self-service API my $customer_info = customer_info( { 'session_id' => $session_id } ); #payment_info and process_payment are available in 1.5+ only - my $payment_info = payment_info) { 'session_id' => $session_id } ); + my $payment_info = payment_info( { 'session_id' => $session_id } ); #!!! process_payment example @@ -244,8 +245,23 @@ the following keys: invnum, date, owed An HTML fragment containing shipping and billing addresses. +=item The following fields are also returned: first last company address1 address2 city county state zip country daytime night fax ship_first ship_last ship_company ship_address1 ship_address2 ship_city ship_state ship_zip ship_country ship_daytime ship_night ship_fax + =back +=item edit_info HASHREF + +Takes a hash reference as parameter with any of the following keys: + +first last company address1 address2 city county state zip country daytime night fax ship_first ship_last ship_company ship_address1 ship_address2 ship_city ship_state ship_zip ship_country ship_daytime ship_night ship_fax + +If a field exists, the customer record is updated with the new value of that +field. If a field does not exist, that field is not changed on the customer +record. + +Returns a hash reference with a single key, B, empty on success, or an +error message on errors + =item invoice HASHREF Returns an invoice. Takes a hash reference as parameter with two keys: -- cgit v1.2.1