X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fsvc_acct.pm;h=1ec5429e97d4dcba2e7fa6d7cfa7abd1cf789305;hb=feef0e4c2b4bd6b776b25f5a1bd6fdbf63fd08b2;hp=6e4213d02ee45a95452317ba1e7b3f6180971d44;hpb=477cd9f54b609a7a2a94b25544e1e8eb5dda1b67;p=freeside.git diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 6e4213d02..1ec5429e9 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -6,7 +6,7 @@ use vars qw( @ISA $DEBUG $me $conf $skip_fuzzyfiles $usernamemax $passwordmin $passwordmax $username_ampersand $username_letter $username_letterfirst $username_noperiod $username_nounderscore $username_nodash - $username_uppercase + $username_uppercase $username_percent $password_noampersand $password_noexclamation $welcome_template $welcome_from $welcome_subject $welcome_mimetype $smtpmachine @@ -37,7 +37,6 @@ use FS::svc_www; @ISA = qw( FS::svc_Common ); $DEBUG = 0; -#$DEBUG = 1; $me = '[FS::svc_acct]'; #ask FS::UID to run this stuff for us later @@ -56,6 +55,7 @@ $FS::UID::callback{'FS::svc_acct'} = sub { $username_nodash = $conf->exists('username-nodash'); $username_uppercase = $conf->exists('username-uppercase'); $username_ampersand = $conf->exists('username-ampersand'); + $username_percent = $conf->exists('username-percent'); $password_noampersand = $conf->exists('password-noexclamation'); $password_noexclamation = $conf->exists('password-noexclamation'); $dirhash = $conf->config('dirhash') || 0; @@ -688,11 +688,11 @@ sub check { my $ulen = $usernamemax || $self->dbdef_table->column('username')->length; if ( $username_uppercase ) { - $recref->{username} =~ /^([a-z0-9_\-\.\&]{$usernamemin,$ulen})$/i + $recref->{username} =~ /^([a-z0-9_\-\.\&\%]{$usernamemin,$ulen})$/i or return gettext('illegal_username'). " ($usernamemin-$ulen): ". $recref->{username}; $recref->{username} = $1; } else { - $recref->{username} =~ /^([a-z0-9_\-\.\&]{$usernamemin,$ulen})$/ + $recref->{username} =~ /^([a-z0-9_\-\.\&\%]{$usernamemin,$ulen})$/ or return gettext('illegal_username'). " ($usernamemin-$ulen): ". $recref->{username}; $recref->{username} = $1; } @@ -720,6 +720,9 @@ sub check { if ( $password_noexclamation ) { $recref->{_password} =~ /\!/ and return gettext('illegal_password'); } + unless ( $username_percent ) { + $recref->{username} =~ /\%/ and return gettext('illegal_username'); + } $recref->{popnum} =~ /^(\d*)$/ or return "Illegal popnum: ".$recref->{popnum}; $recref->{popnum} = $1; @@ -1117,12 +1120,45 @@ sub acct_snarf { =item decrement_seconds SECONDS -Decrements the I field of this record by the given amount. +Decrements the I field of this record by the given amount. If there +is an error, returns the error, otherwise returns false. =cut sub decrement_seconds { - my( $self, $seconds ) = @_; + shift->_op_seconds('-', @_); +} + +=item increment_seconds SECONDS + +Increments the I field of this record by the given amount. If there +is an error, returns the error, otherwise returns false. + +=cut + +sub increment_seconds { + shift->_op_seconds('+', @_); +} + + +my %op2action = ( + '-' => 'suspend', + '+' => 'unsuspend', +); +my %op2condition = ( + '-' => sub { my($self, $seconds) = @_; + $self->seconds - $seconds <= 0; + }, + '+' => sub { my($self, $seconds) = @_; + $self->seconds + $seconds > 0; + }, +); + +sub _op_seconds { + my( $self, $op, $seconds ) = @_; + warn "$me _op_seconds called for svcnum ". $self->svcnum. + ' ('. $self->email. "): $op $seconds\n" + if $DEBUG; local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; @@ -1134,22 +1170,41 @@ sub decrement_seconds { my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; my $dbh = dbh; - - my $sth = dbh->prepare( - 'UPDATE svc_acct SET seconds = seconds - ? WHERE svcnum = ?' - ) or die dbh->errstr;; - $sth->execute($seconds, $self->svcnum) or die $sth->errstr; - if ( $conf->exists('svc_acct-usage_suspend') - && $self->seconds - $seconds <= 0 ) { - #my $error = $self->suspend; - my $error = $self->cust_svc->cust_pkg->suspend; - die $error if $error; + + my $sql = "UPDATE svc_acct SET seconds = ". + " CASE WHEN seconds IS NULL THEN 0 ELSE seconds END ". #$seconds||0 + " $op ? WHERE svcnum = ?"; + warn "$me $sql\n" + if $DEBUG; + + my $sth = $dbh->prepare( $sql ) + or die "Error preparing $sql: ". $dbh->errstr; + my $rv = $sth->execute($seconds, $self->svcnum); + die "Error executing $sql: ". $sth->errstr + unless defined($rv); + die "Can't update seconds for svcnum". $self->svcnum + if $rv == 0; + + my $action = $op2action{$op}; + + if ( $conf->exists("svc_acct-usage_$action") + && &{$op2condition{$op}}($self, $seconds) ) { + #my $error = $self->$action(); + my $error = $self->cust_svc->cust_pkg->$action(); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error ${action}ing: $error"; + } } + warn "$me update sucessful; committing\n" + if $DEBUG; $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; } + =item seconds_since TIMESTAMP Returns the number of seconds this account has been online since TIMESTAMP, @@ -1327,7 +1382,7 @@ sub crypt_password { { $self->_password; } else { - my $encryption = scalar(@_) ? shift : 'crypt'; + my $encryption = ( scalar(@_) && $_[0] ) ? shift : 'crypt'; if ( $encryption eq 'crypt' ) { crypt( $self->_password,