From f1038a648b3d53db925b23519e7cd2a30c6837ed Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 20 Mar 2002 21:31:49 +0000 Subject: new export! infostreet and sqlradius provisioning switched over (Bug #299 - doesn't close it, but all the groundwork is done) also removes non-transactional ICRADIUS export from svc_acct.export (closes: Bug#347) --- FS/FS/Conf.pm | 12 +- FS/FS/part_export.pm | 427 +++++++++++++++++++++++++++++++++++++++++++- FS/FS/part_export_option.pm | 2 +- FS/FS/part_svc.pm | 12 +- FS/FS/svc_acct.pm | 236 +++++++----------------- FS/bin/freeside-queued | 3 +- 6 files changed, 509 insertions(+), 183 deletions(-) (limited to 'FS') diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 91fea7ef7..645dbf1c4 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -396,29 +396,29 @@ httemplate/docs/config.html { 'key' => 'icradiusmachines', - 'section' => 'radius', - 'description' => 'Turn this option on to enable radcheck and radreply table population - by default in the Freeside database, or in the database specified by the icradius_secrets config option (the radcheck and radreply tables needs to be created manually). You do not need to use MySQL for your Freeside database to export to an ICRADIUS/FreeRADIUS MySQL database with this option.
ADDITIONAL DEPRECATED FUNCTIONALITY (instead use MySQL replication or point icradius_secrets to the external database) - your ICRADIUS machines or FreeRADIUS (with MySQL authentication) machines, one per line. Machines listed in this file will have the radcheck table exported to them. Each line should contain four items, separted by whitespace: machine name, MySQL database name, MySQL username, and MySQL password. For example: "radius.isp.tld radius_db radius_user passw0rd"
', + 'section' => 'deprecated', + 'description' => 'DEPRECATED, add sqlradius exports to Service definitions instead. This option used to enable radcheck and radreply table population - by default in the Freeside database, or in the database specified by the icradius_secrets config option (the radcheck and radreply tables needs to be created manually). You do not need to use MySQL for your Freeside database to export to an ICRADIUS/FreeRADIUS MySQL database with this option.
ADDITIONAL DEPRECATED FUNCTIONALITY (instead use MySQL replication or point icradius_secrets to the external database) - your ICRADIUS machines or FreeRADIUS (with MySQL authentication) machines, one per line. Machines listed in this file will have the radcheck table exported to them. Each line should contain four items, separted by whitespace: machine name, MySQL database name, MySQL username, and MySQL password. For example: "radius.isp.tld radius_db radius_user passw0rd"
', 'type' => [qw( checkbox textarea )], }, { 'key' => 'icradius_mysqldest', - 'section' => 'radius', + 'section' => 'deprecated', 'description' => 'DEPRECATED (instead use MySQL replication or point icradius_secrets to the external database) - Destination directory for the MySQL databases, on the ICRADIUS/FreeRADIUS machines. Defaults to "/usr/local/var/".', 'type' => 'text', }, { 'key' => 'icradius_mysqlsource', - 'section' => 'radius', + 'section' => 'deprecated', 'description' => 'DEPRECATED (instead use MySQL replication or point icradius_secrets to the external database) - Source directory for for the MySQL radcheck table files, on the Freeside machine. Defaults to "/usr/local/var/freeside".', 'type' => 'text', }, { 'key' => 'icradius_secrets', - 'section' => 'radius', - 'description' => 'Optionally specifies a database for ICRADIUS/FreeRADIUS export. Three lines: DBI data source, username and password.', + 'section' => 'deprecated', + 'description' => 'DEPRECATED, add sqlradius exports to Service definitions instead. This option used to specify a database for ICRADIUS/FreeRADIUS export. Three lines: DBI data source, username and password.', 'type' => 'textarea', }, diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index a0de03b63..444e86aa0 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -122,6 +122,7 @@ sub insert { my $options = shift; foreach my $optionname ( keys %{$options} ) { my $part_export_option = new FS::part_export_option ( { + 'exportnum' => $self->exportnum, 'optionname' => $optionname, 'optionvalue' => $options->{$optionname}, } ); @@ -144,16 +145,92 @@ Delete this record from the database. =cut -# the delete method can be inherited from FS::Record +#foreign keys would make this much less tedious... grr dumb mysql +sub delete { + my $self = shift; + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = $self->SUPER::delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + foreach my $part_export_option ( $self->part_export_option ) { + my $error = $part_export_option->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; -=item replace OLD_RECORD +} + +=item replace OLD_RECORD HASHREF Replaces the OLD_RECORD with this one in the database. If there is an error, returns the error, otherwise returns false. +If a hash reference of options is supplied, part_export_option records are +created or modified (see L). + =cut -# the replace method can be inherited from FS::Record +sub replace { + my $self = shift; + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = $self->SUPER::replace; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + my $options = shift; + foreach my $optionname ( keys %{$options} ) { + my $old = qsearchs( 'part_export_option', { + 'exportnum' => $self->exportnum, + 'optionname' => $optionname, + } ); + my $new = new FS::part_export_option ( { + 'exportnum' => $self->exportnum, + 'optionname' => $optionname, + 'optionvalue' => $options->{$optionname}, + } ); + my $error = $old ? $new->replace($old) : $new->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; + +}; =item check @@ -198,12 +275,356 @@ sub part_svc { qsearchs('part_svc', { svcpart => $self->svcpart } ); } +=item part_export_option + +=cut + +sub part_export_option { + my $self = shift; + qsearch('part_export_option', { 'exportnum' => $self->exportnum } ); +} + +=item options + +=cut + +sub options { + my $self = shift; + map { $_->optionname => $_->optionvalue } $self->part_export_option; +} + +=item option + +=cut + +sub option { + my $self = shift; + my $part_export_option = + qsearchs('part_export_option', { + exportnum => $self->exportnum, + optionname => shift, + } ); + $part_export_option ? $part_export_option->optionvalue : ''; +} + +=item rebless + +=cut + +sub rebless { + my $self = shift; + my $exporttype = $self->exporttype; + my $class = ref($self); + bless($self, $class."::$exporttype"); +} + +=item export_insert SVC_OBJECT + +Calls the appropriate export_I for this object's exporttype. + +=cut + +sub export_insert { + my $self = shift; + $self->rebless; + $self->_export_insert(@_); +} + +#sub AUTOLOAD { +# my $self = shift; +# $self->rebless; +# my $method = $AUTOLOAD; +# #$method =~ s/::(\w+)$/::_$1/; #infinite loop prevention +# $method =~ s/::(\w+)$/_$1/; #infinite loop prevention +# $self->$method(@_); +#} + +=item export_replace + +=cut + +sub export_replace { + my $self = shift; + $self->rebless; + $self->_export_replace(@_); +} + +=item export_delete + +=cut + +sub export_delete { + my $self = shift; + $self->rebless; + $self->_export_delete(@_); +} + =back +#infostreet + +package FS::part_export::infostreet; +use vars qw(@ISA); +@ISA = qw(FS::part_export); + +sub _export_insert { + my( $self, $svc_acct ) = (shift, shift); + $self->infostreet_queue( $svc_acct->svcnum, + 'createUser', $svc_acct->username, $svc_acct->password ); +} + +sub _export_replace { + my( $self, $new, $old ) = (shift, shift, shift); + return "can't change username with InfoStreet" + if $old->username ne $new->username; + return '' unless $old->_password ne $new->_password; + $self->infostreet_queue( $new->svcnum, + 'passwd', $new->username, $new->password ); +} + +sub _export_delete { + my( $self, $svc_acct ) = (shift, shift); + $self->infostreet_queue( $svc_acct->svcnum, + 'purgeAccount,releaseUsername', $svc_acct->username ); +} + +sub infostreet_queue { + my( $self, $svcnum, $method ) = (shift, shift, shift); + my $queue = new FS::queue { + 'svcnum' => $svcnum, + 'job' => 'FS::part_export::infostreet::infostreet_command', + }; + $queue->insert( + $self->option('url'), + $self->option('login'), + $self->option('password'), + $self->option('groupID'), + $method, + @_, + ); +} + +sub infostreet_command { #subroutine, not method + my($url, $username, $password, $groupID, $method, @args) = @_; + + #quelle hack + if ( $method =~ /,/ ) { + foreach my $part ( split(/,\s*/, $method) ) { + infostreet_command($url, $username, $password, $groupID, $part, @args); + } + return; + } + + eval "use Frontier::Client;"; + + my $conn = Frontier::Client->new( url => $url ); + my $key_result = $conn->call( 'authenticate', $username, $password, $groupID); + my %key_result = _infostreet_parse($key_result); + die $key_result{error} unless $key_result{success}; + my $key = $key_result{data}; + + my $result = $conn->call($opt{method}, $key, @{$opt{args}}); + my %result = _infostreet_parse($result); + die $result{error} unless $result{success}; + +} + +sub _infostreet_parse { #subroutine, not method + my $arg = shift; + map { + my $value = $arg->{$_}; + #warn ref($value); + $value = $value->value() + if ref($value) && $value->isa('Frontier::RPC2::DataType'); + $_=>$value; + } keys %$arg; +} + +#sqlradius + +package FS::part_export::sqlradius; +use vars qw(@ISA); +@ISA = qw(FS::part_export); + +sub _export_insert { + my($self, $svc_acct) = (shift, shift); + $self->sqlradius_queue( $svc_acct->svcnum, 'insert', + 'reply', $svc_acct->username, $svc_acct->radius_reply ); + $self->sqlradius_queue( $svc_acct->svcnum, 'insert', + 'check', $svc_acct->username, $svc_acct->radius_check ); +} + +sub _export_replace { + my( $self, $new, $old ) = (shift, shift, shift); + + #return "can't (yet) change username with sqlradius" + # if $old->username ne $new->username; + if ( $old->username ne $new->username ) { + my $error = $self->sqlradius_queue( $new->svcnum, 'rename', + $new->username, $old->username ); + return $error if $error; + } + + foreach my $table (qw(reply check)) { + my $method = "radius_$table"; + my %new = $new->$method; + my %old = $old->$method; + if ( grep { !exists $old{$_} #new attributes + || $new{$n} ne $old{$n} #changed + } keys %new + ) { + my $error = $self->sqlradius_queue( $new->svcnum, 'insert' + $table, $new->username, %new ); + return $error if $error; + } + + my @del = grep { !exists $new{$_} } keys %old; + my $error = $self->sqlradius_queue( $new->svcnum, 'sqlradius_attrib_delete', + $table, $new->username, @del ); + return $error if $error; + } + + ''; +} + +sub _export_delete { + my( $self, $svc_something ) = (shift, shift); + $self->sqlradius_queue( $svc_acct->svcnum, 'delete', + $svc_something->username ); +} + +sub sqlradius_queue { + my( $self, $svcnum, $method ) = (shift, shift, shift); + my $queue = new FS::queue { + 'svcnum' => $svcnum, + 'job' => "FS::part_export::sqlradius::sqlradius_$method", + }; + $queue->insert( + $self->option('datasrc'), + $self->option('username'), + $self->option('password'), + @_, + ); +} + +sub sqlradius_insert { #subroutine, not method + my $dbh = sqlradius_connect(shift, shift, shift); + my( $replycheck, $username, %attributes ) = @_; + + foreach my $attribute ( keys %attributes ) { + my $u_sth = $dbh->prepare( + "UPDATE rad$replycheck SET Value = ? WHERE UserName = ? AND Attribute = ?" ) or die $dbh->errstr; + my $i_sth = $dbh->prepare( + "INSERT INTO rad$replycheck ( id, UserName, Attribute, Value ) ". + "VALUES ( ?, ?, ?, ? )" ) + or die $dbh->errstr; + $u_sth->execute($attributes{$attribute}, $username, $attribute) > 0 + or $i_sth->execute( '', $username, $attribute, $attributes{$attribute} ) + or die "can't insert into rad$replycheck table: ". $i_sth->errstr; + } + $dbh->disconnect; +} + +sub sqlradius_rename { #subroutine, not method + my $dbh = sqlradius_connect(shift, shift, shift); + my($new_username, $old_username) = @_; + foreach my $table (qw(radreply radcheck)) { + my $sth = $dbh->prepare("UPDATE $table SET Username = ? WHERE UserName = ?") + or die $dbh->errstr; + $sth->execute($new_username, $old_username) + or die "can't update $table: ". $sth->errstr; + } + $dbh->disconnect; +} + +sub sqlradius_attrib_delete { #subroutine, not method + my $dbh = sqlradius_connect(shift, shift, shift); + my( $replycheck, $username, @attrib ) = @_; + + foreach my $attribute ( @attrib ) { + my $sth = $dbh->prepare( + "DELETE FROM $table WHERE UserName = ? AND Attribute = ?" ) + or die $dbh->errstr; + $sth->execute($username,$attribute) + or die "can't delete from $table table: ". $sth->errstr; + } + $dbh->disconnect; +} + +sub sqlradius_delete { #subroutine, not method + my $dbh = sqlradius_connect(shift, shift, shift); + my $username = shift; + + foreach my $table (qw( radcheck radreply )) { + my $sth = $dbh->prepare( "DELETE FROM $table WHERE UserName = ?" ); + $sth->execute($username) + or die "can't delete from $table table: ". $sth->errstr; + } + $dbh->disconnect; +} + +sub sqlradius_connect { + #my($datasrc, $username, $password) = @_; + #DBI->connect($datasrc, $username, $password) or die $DBI::errstr; + DBI->connect(@_) or die $DBI::errstr; +} + +=head1 NOTES + +Writing a new export class: + +#myexport + +package FS::part_export::myexport; +use vars qw(@ISA); +@ISA = qw(FS::part_export); + +sub _export_insert { + my($self, $svc_something) = (shift, shift); + $self->myexport_queue( $svc_acct->svcnum, 'insert', + $svc_something->username, $svc_something->password ); +} + +sub _export_replace { + my( $self, $new, $old ) = (shift, shift, shift); + #return "can't change username with myexport" + # if $old->username ne $new->username; + #return '' unless $old->_password ne $new->_password; + $self->myexport_queue( $new->svcnum, + 'replace', $new->username, $new->password ); +} + +sub _export_delete { + my( $self, $svc_something ) = (shift, shift); + $self->myexport_queue( $svc_acct->svcnum, + 'delete', $svc_something->username ); +} + +#a good idea to queue anything that could fail or take any time +sub myexport_queue { + my( $self, $svcnum, $method ) = (shift, shift, shift); + my $queue = new FS::queue { + 'svcnum' => $svcnum, + 'job' => "FS::part_export::myexport::myexport_$method", + }; + $queue->insert( @_ ); +} + +sub myexport_insert { #subroutine, not method +} +sub myexport_replace { #subroutine, not method +} +sub myexport_delete { #subroutine, not method +} + =head1 BUGS Probably. +Hmm, export code has wound up in here. Move those sub-classes out into their +own files, at least. Also hmm... cust_export class (not necessarily a +database table...) ... ? + =head1 SEE ALSO L, L, L, L, diff --git a/FS/FS/part_export_option.pm b/FS/FS/part_export_option.pm index 1ce0de65f..61ea956ae 100644 --- a/FS/FS/part_export_option.pm +++ b/FS/FS/part_export_option.pm @@ -40,7 +40,7 @@ currently supported: =item optionname - option name -=item opeionvalue - option value +=item optionvalue - option value =back diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm index 41ee21d31..82935dd2b 100644 --- a/FS/FS/part_svc.pm +++ b/FS/FS/part_svc.pm @@ -295,11 +295,21 @@ sub all_part_svc_column { qsearch('part_svc_column', { 'svcpart' => $self->svcpart } ); } +=item part_export + +=cut + +sub part_export { + my $self = shift; + my %search = ( 'svcpart' => $self->svcpart ); + qsearch('part_export', \%search); +} + =back =head1 VERSION -$Id: part_svc.pm,v 1.9 2002-01-28 06:57:23 ivan Exp $ +$Id: part_svc.pm,v 1.10 2002-03-20 21:31:49 ivan Exp $ =head1 BUGS diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index bb9fe67b3..2305aeb80 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -1,7 +1,8 @@ package FS::svc_acct; use strict; -use vars qw( @ISA $nossh_hack $conf $dir_prefix @shells $usernamemin +use vars qw( @ISA $nossh_hack $noexport_hack $conf + $dir_prefix @shells $usernamemin $usernamemax $passwordmin $passwordmax $username_ampersand $username_letter $username_letterfirst $username_noperiod $username_uppercase @@ -9,7 +10,6 @@ use vars qw( @ISA $nossh_hack $conf $dir_prefix @shells $usernamemin $cyrus_server $cyrus_admin_user $cyrus_admin_pass $cp_server $cp_user $cp_pass $cp_workgroup $dirhash - $icradius_dbh @saltset @pw_set $rsync $ssh $exportdir $vpopdir); use Carp; @@ -88,18 +88,7 @@ $FS::UID::callback{'FS::svc_acct'} = sub { $cp_pass = ''; $cp_workgroup = ''; } - if ( $conf->exists('icradiusmachines') ) { - if ( $conf->exists('icradius_secrets') ) { - #need some sort of late binding so it's only connected to when - # actually used, hmm - $icradius_dbh = DBI->connect($conf->config('icradius_secrets')) - or die $DBI::errstr; - } else { - $icradius_dbh = dbh; - } - } else { - $icradius_dbh = ''; - } + $dirhash = $conf->config('dirhash') || 0; $exportdir = "/usr/local/etc/freeside/export." . datasrc; if ( $conf->exists('vpopmailmachines') ) { @@ -246,6 +235,8 @@ $username, $uid, $gid, $dir, and $shell. (TODOC: cyrus config file, L and L) +(TODOC: new exports! $noexport_hack) + =cut sub insert { @@ -297,6 +288,20 @@ sub insert { return $error; } + #new-style exports! + unless ( $noexport_hack ) { + foreach my $part_export ( $self->cust_svc->part_svc->part_export ) { + my $error = $part_export->export_insert($self); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "exporting to ". $part_export->exporttype. + " (transaction rolled back): $error"; + } + } + } + + #old-style exports + my( $username, $uid, $gid, $dir, $shell ) = ( $self->username, $self->uid, @@ -340,37 +345,6 @@ sub insert { } } - if ( $icradius_dbh ) { - - my $radcheck_queue = - new FS::queue { - 'svcnum' => $self->svcnum, - 'job' => 'FS::svc_acct::icradius_rc_insert' - }; - $error = $radcheck_queue->insert( $self->username, - $self->_password, - $self->radius_check - ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "queueing job (transaction rolled back): $error"; - } - - my $radreply_queue = - new FS::queue { - 'svcnum' => $self->svcnum, - 'job' => 'FS::svc_acct::icradius_rr_insert' - }; - $error = $radreply_queue->insert( $self->username, - $self->_password, - $self->radius_reply - ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "queueing job (transaction rolled back): $error"; - } - } - if ( $vpopdir ) { my $vpopmail_queue = @@ -390,6 +364,7 @@ sub insert { } + #end of old-style exports $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; #no error @@ -451,56 +426,6 @@ sub cp_insert { die $app->message."\n" unless $app->ok; } -sub icradius_rc_insert { - my( $username, $password, %radcheck ) = @_; - - my $sth = $icradius_dbh->prepare( - "INSERT INTO radcheck ( id, UserName, Attribute, Value ) VALUES ( ". - join(", ", map { $icradius_dbh->quote($_) } ( - '', - $username, - "Password", - $password, - ) ). " )" - ); - $sth->execute or die "can't insert into radcheck table: ". $sth->errstr; - - foreach my $attribute ( keys %radcheck ) { - my $sth = $icradius_dbh->prepare( - "INSERT INTO radcheck ( id, UserName, Attribute, Value ) VALUES ( ". - join(", ", map { $icradius_dbh->quote($_) } ( - '', - $username, - $attribute, - $radcheck{$attribute}, - ) ). " )" - ); - $sth->execute or die "can't insert into radcheck table: ". $sth->errstr; - } - - 1; -} - -sub icradius_rr_insert { - my( $username, $password, %radreply ) = @_; - - foreach my $attribute ( keys %radreply ) { - my $sth = $icradius_dbh->prepare( - "INSERT INTO radreply ( id, UserName, Attribute, Value ) VALUES ( ". - join(", ", map { $icradius_dbh->quote($_) } ( - '', - $username, - $attribute, - $radreply{$attribute}, - ) ). " )" - ); - $sth->execute or die "can't insert into radreply table: ". $sth->errstr; - } - - 1; -} - - sub vpopmail_insert { my( $username, $password, $domain, $vpopdir ) = @_; @@ -571,6 +496,8 @@ $username and $dir. (TODOC: cyrus config file) +(TODOC: new exports! $noexport_hack) + =cut sub delete { @@ -590,7 +517,7 @@ sub delete { return "Can't delete an account with (svc_www) web service!" if qsearch( 'svc_www', { 'usersvc' => $self->usersvc } ); - # what about records in session ? + # what about records in session ? (they should refer to history table) local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; @@ -639,6 +566,20 @@ sub delete { return $error; } + #new-style exports! + unless ( $noexport_hack ) { + foreach my $part_export ( $self->cust_svc->part_svc->part_export ) { + my $error = $part_export->export_delete($self); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "exporting to ". $part_export->exporttype. + " (transaction rolled back): $error"; + } + } + } + + #old-style exports + my( $username, $dir ) = ( $self->username, $self->dir, @@ -671,24 +612,6 @@ sub delete { } } - if ( $icradius_dbh ) { - - my $radcheck_queue = - new FS::queue { 'job' => 'FS::svc_acct::icradius_rc_delete' }; - $error = $radcheck_queue->insert( $self->username ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "queueing job (transaction rolled back): $error"; - } - - my $radreply_queue = - new FS::queue { 'job' => 'FS::svc_acct::icradius_rr_delete' }; - $error = $radreply_queue->insert( $self->username ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "queueing job (transaction rolled back): $error"; - } - } if ( $vpopdir ) { my $queue = new FS::queue { 'job' => 'FS::svc_acct::vpopmail_delete' }; $error = $queue->insert( $self->username, $self->domain ); @@ -699,6 +622,8 @@ sub delete { } + #end of old-style exports + $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; } @@ -742,30 +667,6 @@ sub cp_delete { die $app->message."\n" unless $app->ok; } -sub icradius_rc_delete { - my $username = shift; - - my $sth = $icradius_dbh->prepare( - 'DELETE FROM radcheck WHERE UserName = ?' - ); - $sth->execute($username) - or die "can't delete from radcheck table: ". $sth->errstr; - - 1; -} - -sub icradius_rr_delete { - my $username = shift; - - my $sth = $icradius_dbh->prepare( - 'DELETE FROM radreply WHERE UserName = ?' - ); - $sth->execute($username) - or die "can't delete from radreply table: ". $sth->errstr; - - 1; -} - sub vpopmail_delete { my( $username, $domain ) = @_; @@ -858,6 +759,20 @@ sub replace { return $error if $error; } + #new-style exports! + unless ( $noexport_hack ) { + foreach my $part_export ( $new->cust_svc->part_svc->part_export ) { + my $error = $part_export->export_replace($new,$old); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "exporting to ". $part_export->exporttype. + " (transaction rolled back): $error"; + } + } + } + + #old-style exports + my ( $old_dir, $new_dir, $uid, $gid ) = ( $old->getfield('dir'), $new->getfield('dir'), @@ -900,19 +815,6 @@ sub replace { } } - if ( $icradius_dbh ) { - my $queue = new FS::queue { - 'svcnum' => $new->svcnum, - 'job' => 'FS::svc_acct::icradius_rc_replace' - }; - $error = $queue->insert( $new->username, - $new->_password, - ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "queueing job (transaction rolled back): $error"; - } - } if ( $vpopdir ) { my $cpassword = crypt( $new->_password,$saltset[int(rand(64))].$saltset[int(rand(64))] @@ -938,23 +840,12 @@ sub replace { } } + #end of old-style exports $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; #no error } -sub icradius_rc_replace { - my( $username, $new_password ) = @_; - - my $sth = $icradius_dbh->prepare( - "UPDATE radcheck SET Value = ? WHERE UserName = ? and Attribute = ?" - ); - $sth->execute($new_password, $username, 'Password' ) - or die "can't update radcheck table: ". $sth->errstr; - - 1; -} - sub cp_rename { my ( $old_username, $new_username ) = @_; @@ -1305,19 +1196,22 @@ sub radius_reply { Returns key/value pairs, suitable for assigning to a hash, for any RADIUS check attributes of this record. -Accessing RADIUS attributes directly is not supported and will break in the -future. +Note that this is now the preferred method for reading RADIUS attributes - +accessing the columns directly is discouraged, as the column names are +expected to change in the future. =cut sub radius_check { my $self = shift; - map { - /^(rc_(.*))$/; - my($column, $attrib) = ($1, $2); - #$attrib =~ s/_/\-/g; - ( $FS::raddb::attrib{lc($attrib)}, $self->getfield($column) ); - } grep { /^rc_/ && $self->getfield($_) } fields( $self->table ); + ( 'Password' => $self->_password, + map { + /^(rc_(.*))$/; + my($column, $attrib) = ($1, $2); + #$attrib =~ s/_/\-/g; + ( $FS::raddb::attrib{lc($attrib)}, $self->getfield($column) ); + } grep { /^rc_/ && $self->getfield($_) } fields( $self->table ) + ); } =item domain diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued index 56475d059..c3c9240d2 100644 --- a/FS/bin/freeside-queued +++ b/FS/bin/freeside-queued @@ -15,6 +15,7 @@ use FS::queue; use FS::cust_main; use FS::svc_acct; use Net::SSH 0.05; +use FS::part_export; my $pid_file = '/var/run/freeside-queued.pid'; @@ -85,7 +86,7 @@ while (1) { my $eval = "&". $ljob->job. '(@args);'; warn "running $eval"; - eval $eval; + eval $eval; #throw away return value? suppose so if ( $@ ) { warn "job $eval failed"; my %hash = $ljob->hash; -- cgit v1.2.1