X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fsvc_acct.pm;h=1584cce513afecc8527d403bb02c76c0f6d08c98;hp=d3e23f237037b8846f4e4a173250bfc9e837099a;hb=5a7fbc51bbbe090d45655862f3ab222d28b60962;hpb=c44432a5f0f1c1841ff8b50e734a30bd9aeef945 diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index d3e23f237..1584cce51 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -44,7 +44,6 @@ use FS::PagedSearch qw( psearch ); # XXX in v4, replace with FS::Cursor use FS::part_pkg; use FS::part_svc; use FS::svc_acct_pop; -use FS::cust_main_invoice; use FS::svc_domain; use FS::svc_pbx; use FS::raddb; @@ -68,12 +67,12 @@ FS::UID->install_callback( sub { @shells = $conf->config('shells'); $usernamemin = $conf->config('usernamemin') || 2; $usernamemax = $conf->config('usernamemax'); - $passwordmin = $conf->config('passwordmin'); # || 6; - #blank->6, keep 0 + $passwordmin = $conf->config('passwordmin'); + #blank->8, keep 0 $passwordmin = ( defined($passwordmin) && $passwordmin =~ /\d+/ ) ? $passwordmin - : 6; - $passwordmax = $conf->config('passwordmax') || 8; + : 8; + $passwordmax = $conf->config('passwordmax') || 12; $username_letter = $conf->exists('username-letter'); $username_letterfirst = $conf->exists('username-letterfirst'); $username_noperiod = $conf->exists('username-noperiod'); @@ -94,12 +93,11 @@ FS::UID->install_callback( sub { $smtpmachine = $conf->config('smtpmachine'); $radius_password = $conf->config('radius-password') || 'Password'; $radius_ip = $conf->config('radius-ip') || 'Framed-IP-Address'; - @pw_set = ( 'A'..'Z' ) if $conf->exists('password-generated-allcaps'); + @pw_set = FS::svc_acct->pw_set; } ); @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' ); -@pw_set = ( 'a'..'z', 'A'..'Z', '0'..'9', '(', ')', '#', '.', ',' ); sub _cache { my $self = shift; @@ -298,7 +296,7 @@ sub table_info { disable_inventory => 1, }, '_password' => { label => 'Password', - required => 1 + #required => 1 }, 'gid' => { label => 'GID', @@ -318,6 +316,7 @@ sub table_info { 'domsvc' => { label => 'Domain', type => 'select', + select_svc => 1, select_table => 'svc_domain', select_key => 'svcnum', select_label => 'domain', @@ -330,6 +329,15 @@ sub table_info { disable_select => 1, #UI wonky, pry works otherwise }, 'sectornum' => 'Tower sector', + 'routernum' => 'Router/block', + 'blocknum' => { + 'label' => 'Address block', + 'type' => 'select', + 'select_table' => 'addr_block', + 'select_key' => 'blocknum', + 'select_label' => 'cidr', + 'disable_inventory' => 1, + }, 'usergroup' => { label => 'RADIUS groups', type => 'select-radius_group.html', @@ -711,23 +719,46 @@ sub insert { || $conf->exists('emailinvoiceauto') && ! $cust_main->invoicing_list_emailonly ) { - my @invoicing_list = $cust_main->invoicing_list; - push @invoicing_list, $self->email; - $cust_main->invoicing_list(\@invoicing_list); - } - #welcome email - my @welcome_exclude_svcparts = $conf->config('svc_acct_welcome_exclude'); - unless ( grep { $_ eq $self->svcpart } @welcome_exclude_svcparts ) { - my $error = ''; - my $msgnum = $conf->config('welcome_msgnum', $agentnum); - if ( $msgnum ) { - my $msg_template = qsearchs('msg_template', { msgnum => $msgnum }); - $error = $msg_template->send('cust_main' => $cust_main, - 'object' => $self); - #should this do something on error? - } + # slight false laziness w/ edit/process/cust_main.cgi... + # and also slightly arbitrary behavior. + # + # this will never happen but check it anyway + my ($contact) = map { $_->contact } + qsearch('contact_email', { emailaddress => $self->email }); + + if (!$contact) { + # if the "real name" of this account matches the first + last name + # of a contact, attach the email address to that person. + my @contacts = map { $_->contact } $cust_main->cust_contact; + my $myname = $self->get('finger'); + my ($contact) = + grep { $_->get('first') . ' ' . $_->get('last') eq $myname } @contacts; + # otherwise just pick the first one + $contact = $contacts[0]; + } + # if there is one + $contact ||= FS::contact->new({ + 'custnum' => $cust_main->get('custnum'), + 'locationnum' => $cust_main->get('bill_locationnum'), + 'last' => $cust_main->get('last'), + 'first' => $cust_main->get('first'), + }); + $contact->set('emailaddress', $self->email); + $contact->set('invoice_dest', 'Y'); + + if ( $contact->get('contactnum') ) { + $error = $contact->replace; + } else { + $error = $contact->insert; + } + + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "creating invoice destination contact: $error"; + } } + } # if $cust_pkg $dbh->commit or die $dbh->errstr if $oldAutoCommit; @@ -800,37 +831,32 @@ sub delete { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - foreach my $cust_main_invoice ( - qsearch( 'cust_main_invoice', { 'dest' => $self->svcnum } ) + foreach my $svc_domain ( + qsearch( 'svc_domain', { 'catchall' => $self->svcnum } ) ) { - unless ( defined($cust_main_invoice) ) { - warn "WARNING: something's wrong with qsearch"; - next; - } - my %hash = $cust_main_invoice->hash; - $hash{'dest'} = $self->email; - my $new = new FS::cust_main_invoice \%hash; - my $error = $new->replace($cust_main_invoice); + my %hash = new FS::svc_domain->hash; + $hash{'catchall'} = ''; + my $new = new FS::svc_domain \%hash; + my $error = $new->replace($svc_domain); if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; } } - foreach my $svc_domain ( - qsearch( 'svc_domain', { 'catchall' => $self->svcnum } ) + foreach my $svc_phone ( + qsearch( 'svc_phone', { 'forward_svcnum' => $self->svcnum }) ) { - my %hash = new FS::svc_domain->hash; - $hash{'catchall'} = ''; - my $new = new FS::svc_domain \%hash; - my $error = $new->replace($svc_domain); + $svc_phone->set('forward_svcnum', ''); + my $error = $svc_phone->replace; if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; } } - my $error = $self->SUPER::delete; # usergroup here + my $error = $self->delete_password_history + || $self->SUPER::delete; # usergroup here if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -1306,8 +1332,7 @@ sub check { $recref->{_password} = $1; } else { return gettext('illegal_password'). " $passwordmin-$passwordmax ". - FS::Msgcat::_gettext('illegal_password_characters'). - ": ". $recref->{_password}; + FS::Msgcat::_gettext('illegal_password_characters'); } if ( $password_noampersand ) { @@ -1955,6 +1980,9 @@ sub _op_usage { return '' unless $amount; + return '' + if $self->cust_svc->part_svc->part_svc_column($column)->columnflag eq 'F'; + local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; local $SIG{QUIT} = 'IGNORE'; @@ -2290,8 +2318,8 @@ sub last_login_text { Returns a paged search (L) for Call Detail Records associated with this service. For svc_acct, "associated with" means that -either the "src" or the "charged_party" field of the CDR matches the -"username" field of the service. +either the "src" or the "charged_party" field of the CDR matches either +the "username" field of the service or the username@domain label. =cut @@ -2302,6 +2330,7 @@ sub psearch_cdrs { my @where; my $did = dbh->quote($self->username); + my $diddomain = dbh->quote($self->label); my $prefix = $options{'default_prefix'} || ''; #convergent.au '+61' my $prefixdid = dbh->quote($prefix . $self->username); @@ -2317,12 +2346,16 @@ sub psearch_cdrs { if (!$options{'disable_charged_party'}) { push @orwhere, "charged_party = $did", - "charged_party = $prefixdid"; + "charged_party = $prefixdid", + "charged_party = $diddomain" + ; } if (!$options{'disable_src'}) { push @orwhere, "src = $did AND charged_party IS NULL", - "src = $prefixdid AND charged_party IS NULL"; + "src = $prefixdid AND charged_party IS NULL", + "src = $diddomain AND charged_party IS NULL" + ; } push @where, '(' . join(' OR ', @orwhere) . ')'; @@ -2521,6 +2554,11 @@ sub crypt_password { ); } elsif ( $encryption eq 'md5' ) { return unix_md5_crypt( $self->_password ); + } elsif ( $encryption eq 'sha512' ) { + return crypt( + $self->_password, + '$6$rounds=15420$'. join('', map $saltset[int(rand(64))], (1..16) ) + ); } elsif ( $encryption eq 'sha1_base64' ) { #for acct_sql my $pass = sha1_base64( $self->_password ); $pass .= '=' x (4 - length($pass) % 4); #properly padded base64 @@ -2666,6 +2704,25 @@ sub virtual_maildir { $self->domain. '/maildirs/'. $self->username. '/'; } +=item password_svc_check + +Override, for L. Not really intended for other use. + +=cut + +sub password_svc_check { + my ($self, $password) = @_; + foreach my $field ( qw(username finger) ) { + foreach my $word (split(/\W+/,$self->get($field))) { + next unless length($word) > 2; + if ($password =~ /$word/i) { + return qq(Password contains account information '$word'); + } + } + } + return ''; +} + =back =head1 CLASS METHODS