package FS::svc_acct;
use strict;
-use vars qw( @ISA $noexport_hack $conf
+use vars qw( @ISA $DEBUG $me $conf
$dir_prefix @shells $usernamemin
$usernamemax $passwordmin $passwordmax
$username_ampersand $username_letter $username_letterfirst
$username_uppercase
$welcome_template $welcome_from $welcome_subject $welcome_mimetype
$smtpmachine
+ $radius_password
$dirhash
@saltset @pw_set );
use Carp;
@ISA = qw( FS::svc_Common );
+$DEBUG = 0;
+$me = '[FS::svc_acct]';
+
#ask FS::UID to run this stuff for us later
$FS::UID::callback{'FS::svc_acct'} = sub {
$conf = new FS::Conf;
$welcome_template = '';
}
$smtpmachine = $conf->config('smtpmachine');
+ $radius_password = $conf->config('radius-password') || 'Password';
};
@saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
(TODOC: L<FS::queue> and L<freeside-queued>)
-(TODOC: new exports! $noexport_hack)
+(TODOC: new exports!)
=cut
# qsearch('export_svc', { 'exportnum' => $part_export->exportnum });
#}
- my $nodomain = $exports->{$part_export->exporttype}{'nodomain'};
+ #my $nodomain = $exports->{$part_export->exporttype}{'nodomain'};
+ #silly kludge to avoid uninitialized value errors
+ my $nodomain = exists( $exports->{$part_export->exporttype}{'nodomain'} )
+ ? $exports->{$part_export->exporttype}{'nodomain'}
+ : '';
if ( $nodomain =~ /^Y/i ) {
$conflict_user_svcpart{$_} = $part_export->exportnum
foreach @svcparts;
'subject' => $welcome_subject,
'mimetype' => $welcome_mimetype,
'body' => $welcome_template->fill_in( HASH => {
+ 'custnum' => $self->custnum,
'username' => $self->username,
'password' => $self->_password,
'first' => $cust_main->first,
The corresponding FS::cust_svc record will be deleted as well.
-(TODOC: new exports! $noexport_hack)
+(TODOC: new exports!)
=cut
sub replace {
my ( $new, $old ) = ( shift, shift );
my $error;
+ warn "$me replacing $old with $new\n" if $DEBUG;
return "Username in use"
if $old->username ne $new->username &&
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
+ # redundant, but so $new->usergroup gets set
+ $error = $new->check;
+ return $error if $error;
+
$old->usergroup( [ $old->radius_groups ] );
+ warn "old groups: ". join(' ',@{$old->usergroup}). "\n" if $DEBUG;
+ warn "new groups: ". join(' ',@{$new->usergroup}). "\n" if $DEBUG;
if ( $new->usergroup ) {
#(sorta) false laziness with FS::part_export::sqlradius::_export_replace
my @newgroups = @{$new->usergroup};
return $error if $error;
}
- #false laziness with sub insert (and cust_main)
- my $queue = new FS::queue {
- 'svcnum' => $new->svcnum,
- 'job' => 'FS::svc_acct::append_fuzzyfiles'
- };
- $error = $queue->insert($new->username);
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "queueing job (transaction rolled back): $error";
+ if ( $new->username ne $old->username ) {
+ #false laziness with sub insert (and cust_main)
+ my $queue = new FS::queue {
+ 'svcnum' => $new->svcnum,
+ 'job' => 'FS::svc_acct::append_fuzzyfiles'
+ };
+ $error = $queue->insert($new->username);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
}
-
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
''; #no error
}
sub radius_check {
my $self = shift;
- ( 'Password' => $self->_password,
+ my $password = $self->_password;
+ my $pw_attrib = length($password) <= 12 ? $radius_password : 'Crypt-Password';
+ ( $pw_attrib => $password,
map {
/^(rc_(.*))$/;
my($column, $attrib) = ($1, $2);
=item seconds_since TIMESTAMP
-Returns the number of seconds this account has been online since TIMESTAMP.
-See L<FS::session>
+Returns the number of seconds this account has been online since TIMESTAMP,
+according to the session monitor (see L<FS::Session>).
TIMESTAMP is specified as a UNIX timestamp; see L<perlfunc/"time">. Also see
L<Time::Local> and L<Date::Parse> for conversion functions.
$self->cust_svc->seconds_since(@_);
}
+=item seconds_since_sqlradacct TIMESTAMP_START TIMESTAMP_END
+
+Returns the numbers of seconds this account has been online between
+TIMESTAMP_START (inclusive) and TIMESTAMP_END (exclusive), according to an
+external SQL radacct table, specified via sqlradius export. Sessions which
+started in the specified range but are still open are counted from session
+start to the end of the range (unless they are over 1 day old, in which case
+they are presumed missing their stop record and not counted). Also, sessions
+which end in therange but started earlier are counted from the start of the
+range to session end. Finally, sessions which start before the range but end
+after are counted for the entire range.
+
+TIMESTAMP_START and TIMESTAMP_END are specified as UNIX timestamps; see
+L<perlfunc/"time">. Also see L<Time::Local> and L<Date::Parse> for conversion
+functions.
+
+=cut
+
+#note: POD here, implementation in FS::cust_svc
+sub seconds_since_sqlradacct {
+ my $self = shift;
+ $self->cust_svc->seconds_since_sqlradacct(@_);
+}
+
+=item attribute_since_sqlradacct TIMESTAMP_START TIMESTAMP_END ATTRIBUTE
+
+Returns the sum of the given attribute for all accounts (see L<FS::svc_acct>)
+in this package for sessions ending between TIMESTAMP_START (inclusive) and
+TIMESTAMP_END (exclusive).
+
+TIMESTAMP_START and TIMESTAMP_END are specified as UNIX timestamps; see
+L<perlfunc/"time">. Also see L<Time::Local> and L<Date::Parse> for conversion
+functions.
+
+=cut
+
+#note: POD here, implementation in FS::cust_svc
+sub attribute_since_sqlradacct {
+ my $self = shift;
+ $self->cust_svc->attribute_since_sqlradacct(@_);
+}
+
=item radius_groups
Returns all RADIUS groups for this account (see L<FS::radius_usergroup>).