X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fsvc_acct.pm;h=7ef8ed3aa071c4c6a5b24779e0f96415fd9fc4d0;hb=b79a8cb932946c849328a3c117c35821d9d21e66;hp=2887e28c78f95a72c98d865e3e855c470854943c;hpb=61ec626ec5e6493a16dcb9d4cabcd826f1306b5b;p=freeside.git diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 2887e28c7..7ef8ed3aa 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -1,12 +1,15 @@ package FS::svc_acct; use strict; -use vars qw( @ISA $DEBUG $me $conf $skip_fuzzyfiles +use base qw( FS::svc_Domain_Mixin FS::svc_CGP_Mixin FS::svc_CGPRule_Mixin + FS::svc_Common ); +use vars qw( $DEBUG $me $conf $skip_fuzzyfiles $dir_prefix @shells $usernamemin $usernamemax $passwordmin $passwordmax $username_ampersand $username_letter $username_letterfirst $username_noperiod $username_nounderscore $username_nodash $username_uppercase $username_percent $username_colon + $username_slash $username_equals $username_pound $password_noampersand $password_noexclamation $warning_template $warning_from $warning_subject $warning_mimetype $warning_cc @@ -32,8 +35,6 @@ use FS::Msgcat qw(gettext); use FS::UI::bytecount; use FS::UI::Web; use FS::part_pkg; -use FS::svc_Common; -use FS::cust_svc; use FS::part_svc; use FS::svc_acct_pop; use FS::cust_main_invoice; @@ -42,13 +43,13 @@ use FS::svc_pbx; use FS::raddb; use FS::queue; use FS::radius_usergroup; +use FS::radius_group; use FS::export_svc; use FS::part_export; use FS::svc_forward; use FS::svc_www; use FS::cdr; - -@ISA = qw( FS::svc_Common ); +use FS::acct_snarf; $DEBUG = 0; $me = '[FS::svc_acct]'; @@ -75,6 +76,9 @@ FS::UID->install_callback( sub { $username_ampersand = $conf->exists('username-ampersand'); $username_percent = $conf->exists('username-percent'); $username_colon = $conf->exists('username-colon'); + $username_slash = $conf->exists('username-slash'); + $username_equals = $conf->exists('username-equals'); + $username_pound = $conf->exists('username-pound'); $password_noampersand = $conf->exists('password-noexclamation'); $password_noexclamation = $conf->exists('password-noexclamation'); $dirhash = $conf->config('dirhash') || 0; @@ -102,7 +106,7 @@ FS::UID->install_callback( sub { ); @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' ); -@pw_set = ( 'a'..'z', 'A'..'Z', '0'..'9', '(', ')', '#', '!', '.', ',' ); +@pw_set = ( 'a'..'z', 'A'..'Z', '0'..'9', '(', ')', '#', '.', ',' ); sub _cache { my $self = shift; @@ -271,32 +275,12 @@ sub table_info { disable_fixed => 1, disable_select => 1, }, - 'cgp_type'=> { - label => 'Communigate account type', - type => 'select', - select_list => [qw( MultiMailbox TextMailbox MailDirMailbox AGrade BGrade CGrade )], - disable_inventory => 1, - disable_select => 1, - }, - 'cgp_accessmodes' => { - label => 'Communigate enabled services', - type => 'communigate_pro-accessmodes', - disable_inventory => 1, - disable_select => 1, - }, - 'cgp_deletemode' => { - label => 'Communigate message delete method', - type => 'select', - select_list => [ 'Move To Trash', 'Immediately', 'Mark' ], - disable_inventory => 1, - disable_select => 1, - }, - 'cgp_emptytrash' => { - label => 'Communigate on logout remove trash', - type => 'text', - disable_inventory => 1, - disable_select => 1, - }, + 'password_selfchange' => { label => 'Password modification', + type => 'checkbox', + }, + 'password_recover' => { label => 'Password recovery', + type => 'checkbox', + }, 'quota' => { label => 'Quota', #Mail storage limit type => 'text', @@ -344,16 +328,6 @@ sub table_info { select_key => 'svcnum', select_label => 'domain', disable_inventory => 1, - - }, - 'domsvc' => { - label => 'Domain', - type => 'select', - select_table => 'svc_domain', - select_key => 'svcnum', - select_label => 'domain', - disable_inventory => 1, - }, 'pbxsvc' => { label => 'PBX', type => 'select-svc_pbx.html', @@ -362,7 +336,7 @@ sub table_info { }, 'usergroup' => { label => 'RADIUS groups', - type => 'radius_usergroup_selector', + type => 'select-radius_group.html', disable_inventory => 1, disable_select => 1, }, @@ -435,6 +409,120 @@ sub table_info { label => 'Last logout', type => 'disabled', }, + + 'cgp_aliases' => { + label => 'Communigate aliases', + type => 'text', + disable_inventory => 1, + disable_select => 1, + }, + #settings + 'cgp_type'=> { + label => 'Communigate account type', + type => 'select', + select_list => [qw( MultiMailbox TextMailbox MailDirMailbox AGrade BGrade CGrade )], + disable_inventory => 1, + disable_select => 1, + }, + 'cgp_accessmodes' => { + label => 'Communigate enabled services', + type => 'communigate_pro-accessmodes', + disable_inventory => 1, + disable_select => 1, + }, + 'cgp_rulesallowed' => { + label => 'Allowed mail rules', + type => 'select', + select_list => [ '', 'No', 'Filter Only', 'All But Exec', 'Any' ], + disable_inventory => 1, + disable_select => 1, + }, + 'cgp_rpopallowed' => { label => 'RPOP modifications', + type => 'checkbox', + }, + 'cgp_mailtoall' => { label => 'Accepts mail to "all"', + type => 'checkbox', + }, + 'cgp_addmailtrailer' => { label => 'Add trailer to sent mail', + type => 'checkbox', + }, + 'cgp_archiveafter' => { + label => 'Archive messages after', + type => 'select', + select_hash => [ + -2 => 'default(730 days)', + 0 => 'Never', + 86400 => '24 hours', + 172800 => '2 days', + 259200 => '3 days', + 432000 => '5 days', + 604800 => '7 days', + 1209600 => '2 weeks', + 2592000 => '30 days', + 7776000 => '90 days', + 15552000 => '180 days', + 31536000 => '365 days', + 63072000 => '730 days', + ], + disable_inventory => 1, + disable_select => 1, + }, + #XXX mailing lists + + #preferences + 'cgp_deletemode' => { + label => 'Communigate message delete method', + type => 'select', + select_list => [ 'Move To Trash', 'Immediately', 'Mark' ], + disable_inventory => 1, + disable_select => 1, + }, + 'cgp_emptytrash' => { + label => 'Communigate on logout remove trash', + type => 'select', + select_list => __PACKAGE__->cgp_emptytrash_values, + disable_inventory => 1, + disable_select => 1, + }, + 'cgp_language' => { + label => 'Communigate language', + type => 'select', + select_list => [ '', qw( English Arabic Chinese Dutch French German Hebrew Italian Japanese Portuguese Russian Slovak Spanish Thai ) ], + disable_inventory => 1, + disable_select => 1, + }, + 'cgp_timezone' => { + label => 'Communigate time zone', + type => 'select', + select_list => __PACKAGE__->cgp_timezone_values, + disable_inventory => 1, + disable_select => 1, + }, + 'cgp_skinname' => { + label => 'Communigate layout', + type => 'select', + select_list => [ '', '***', 'GoldFleece', 'Skin2' ], + disable_inventory => 1, + disable_select => 1, + }, + 'cgp_prontoskinname' => { + label => 'Communigate Pronto style', + type => 'select', + select_list => [ '', 'Pronto', 'Pronto-darkflame', 'Pronto-steel', 'Pronto-twilight', ], + disable_inventory => 1, + disable_select => 1, + }, + 'cgp_sendmdnmode' => { + label => 'Communigate send read receipts', + type => 'select', + select_list => [ '', 'Never', 'Manually', 'Automatically' ], + disable_inventory => 1, + disable_select => 1, + }, + + #mail + #XXX RPOP settings + }, }; } @@ -622,10 +710,10 @@ sub insert { } if ( $self->usergroup ) { - foreach my $groupname ( @{$self->usergroup} ) { + foreach my $groupnum ( @{$self->usergroup} ) { my $radius_usergroup = new FS::radius_usergroup ( { svcnum => $self->svcnum, - groupname => $groupname, + groupnum => $groupnum, } ); my $error = $radius_usergroup->insert; if ( $error ) { @@ -659,82 +747,93 @@ sub insert { } #welcome email - my ($to,$welcome_template,$welcome_from,$welcome_subject,$welcome_subject_template,$welcome_mimetype) - = ('','','','','',''); - - if ( $conf->exists('welcome_email', $agentnum) ) { - $welcome_template = new Text::Template ( - TYPE => 'ARRAY', - SOURCE => [ map "$_\n", $conf->config('welcome_email', $agentnum) ] - ) or warn "can't create welcome email template: $Text::Template::ERROR"; - $welcome_from = $conf->config('welcome_email-from', $agentnum); - # || 'your-isp-is-dum' - $welcome_subject = $conf->config('welcome_email-subject', $agentnum) - || 'Welcome'; - $welcome_subject_template = new Text::Template ( - TYPE => 'STRING', - SOURCE => $welcome_subject, - ) or warn "can't create welcome email subject template: $Text::Template::ERROR"; - $welcome_mimetype = $conf->config('welcome_email-mimetype', $agentnum) - || 'text/plain'; - } - if ( $welcome_template && $cust_pkg ) { - my $to = join(', ', grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list ); - if ( $to ) { - - my %hash = ( - 'custnum' => $self->custnum, - 'username' => $self->username, - 'password' => $self->_password, - 'first' => $cust_main->first, - 'last' => $cust_main->getfield('last'), - 'pkg' => $cust_pkg->part_pkg->pkg, - ); - my $wqueue = new FS::queue { - 'svcnum' => $self->svcnum, - 'job' => 'FS::svc_acct::send_email' - }; - my $error = $wqueue->insert( - 'to' => $to, - 'from' => $welcome_from, - 'subject' => $welcome_subject_template->fill_in( HASH => \%hash, ), - 'mimetype' => $welcome_mimetype, - 'body' => $welcome_template->fill_in( HASH => \%hash, ), - ); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "error queuing welcome email: $error"; - } - - if ( $options{'depend_jobnum'} ) { - warn "$me depend_jobnum found; adding to welcome email dependancies" - if $DEBUG; - if ( ref($options{'depend_jobnum'}) ) { - warn "$me adding jobs ". join(', ', @{$options{'depend_jobnum'}} ). - "to welcome email dependancies" - if $DEBUG; - push @jobnums, @{ $options{'depend_jobnum'} }; - } else { - warn "$me adding job $options{'depend_jobnum'} ". - "to welcome email dependancies" - if $DEBUG; - push @jobnums, $options{'depend_jobnum'}; - } + 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); } - - foreach my $jobnum ( @jobnums ) { - my $error = $wqueue->depend_insert($jobnum); - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "error queuing welcome email job dependancy: $error"; + else { #!$msgnum + my ($to,$welcome_template,$welcome_from,$welcome_subject,$welcome_subject_template,$welcome_mimetype) + = ('','','','','',''); + + if ( $conf->exists('welcome_email', $agentnum) ) { + $welcome_template = new Text::Template ( + TYPE => 'ARRAY', + SOURCE => [ map "$_\n", $conf->config('welcome_email', $agentnum) ] + ) or warn "can't create welcome email template: $Text::Template::ERROR"; + $welcome_from = $conf->config('welcome_email-from', $agentnum); + # || 'your-isp-is-dum' + $welcome_subject = $conf->config('welcome_email-subject', $agentnum) + || 'Welcome'; + $welcome_subject_template = new Text::Template ( + TYPE => 'STRING', + SOURCE => $welcome_subject, + ) or warn "can't create welcome email subject template: $Text::Template::ERROR"; + $welcome_mimetype = $conf->config('welcome_email-mimetype', $agentnum) + || 'text/plain'; } - } - - } - + if ( $welcome_template ) { + my $to = join(', ', grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list ); + if ( $to ) { + + my %hash = ( + 'custnum' => $self->custnum, + 'username' => $self->username, + 'password' => $self->_password, + 'first' => $cust_main->first, + 'last' => $cust_main->getfield('last'), + 'pkg' => $cust_pkg->part_pkg->pkg, + ); + my $wqueue = new FS::queue { + 'svcnum' => $self->svcnum, + 'job' => 'FS::svc_acct::send_email' + }; + my $error = $wqueue->insert( + 'to' => $to, + 'from' => $welcome_from, + 'subject' => $welcome_subject_template->fill_in( HASH => \%hash, ), + 'mimetype' => $welcome_mimetype, + 'body' => $welcome_template->fill_in( HASH => \%hash, ), + ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "error queuing welcome email: $error"; + } + + if ( $options{'depend_jobnum'} ) { + warn "$me depend_jobnum found; adding to welcome email dependancies" + if $DEBUG; + if ( ref($options{'depend_jobnum'}) ) { + warn "$me adding jobs ". join(', ', @{$options{'depend_jobnum'}} ). + "to welcome email dependancies" + if $DEBUG; + push @jobnums, @{ $options{'depend_jobnum'} }; + } else { + warn "$me adding job $options{'depend_jobnum'} ". + "to welcome email dependancies" + if $DEBUG; + push @jobnums, $options{'depend_jobnum'}; + } + } + + foreach my $jobnum ( @jobnums ) { + my $error = $wqueue->depend_insert($jobnum); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "error queuing welcome email job dependancy: $error"; + } + } + + } + + } # if $welcome_template + } # if !$msgnum } - - } # if ( $cust_pkg ) + } # if $cust_pkg $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; #no error @@ -894,6 +993,10 @@ sub replace { } + return "can't change username" + if $old->username ne $new->username + && $conf->exists('svc_acct-no_edit_username'); + #change homdir when we change username $new->setfield('dir', '') if $old->username ne $new->username; @@ -912,10 +1015,10 @@ sub replace { $error = $new->check; return $error if $error; - $old->usergroup( [ $old->radius_groups ] ); + $old->usergroup( [ $old->radius_groups('NUMBERS') ] ); if ( $DEBUG ) { warn $old->email. " old groups: ". join(' ',@{$old->usergroup}). "\n"; - warn $new->email. "new groups: ". join(' ',@{$new->usergroup}). "\n"; + warn $new->email. " new groups: ". join(' ',@{$new->usergroup}). "\n"; } if ( $new->usergroup ) { #(sorta) false laziness with FS::part_export::sqlradius::_export_replace @@ -927,7 +1030,7 @@ sub replace { } my $radius_usergroup = qsearchs('radius_usergroup', { svcnum => $old->svcnum, - groupname => $oldgroup, + groupnum => $oldgroup, } ); my $error = $radius_usergroup->delete; if ( $error ) { @@ -939,7 +1042,7 @@ sub replace { foreach my $newgroup ( @newgroups ) { my $radius_usergroup = new FS::radius_usergroup ( { svcnum => $new->svcnum, - groupname => $newgroup, + groupnum => $newgroup, } ); my $error = $radius_usergroup->insert; if ( $error ) { @@ -1106,16 +1209,33 @@ sub check { || $self->ut_snumbern('upbytes') || $self->ut_snumbern('downbytes') || $self->ut_snumbern('totalbytes') - || $self->ut_enum( '_password_encoding', - [ '', qw( plain crypt ldap ) ] - ) - || $self->ut_enum( 'password_selfchange', [ '', 'Y' ] ) - || $self->ut_enum( 'password_recover', [ '', 'Y' ] ) - || $self->ut_textn( 'cgp_accessmodes' ) - || $self->ut_alphan( 'cgp_type' ) - || $self->ut_textn( 'cgp_aliases' ) #well - || $self->ut_alphasn( 'cgp_deletemode' ) - || $self->ut_alphan( 'cgp_emptytrash' ) + || $self->ut_snumbern('seconds_threshold') + || $self->ut_snumbern('upbytes_threshold') + || $self->ut_snumbern('downbytes_threshold') + || $self->ut_snumbern('totalbytes_threshold') + || $self->ut_enum('_password_encoding', ['',qw(plain crypt ldap)]) + || $self->ut_enum('password_selfchange', [ '', 'Y' ]) + || $self->ut_enum('password_recover', [ '', 'Y' ]) + #cardfortress + || $self->ut_anything('cf_privatekey') + #communigate + || $self->ut_textn('cgp_accessmodes') + || $self->ut_alphan('cgp_type') + || $self->ut_textn('cgp_aliases' ) #well + # settings + || $self->ut_alphasn('cgp_rulesallowed') + || $self->ut_enum('cgp_rpopallowed', [ '', 'Y' ]) + || $self->ut_enum('cgp_mailtoall', [ '', 'Y' ]) + || $self->ut_enum('cgp_addmailtrailer', [ '', 'Y' ]) + || $self->ut_snumbern('cgp_archiveafter') + # preferences + || $self->ut_alphasn('cgp_deletemode') + || $self->ut_enum('cgp_emptytrash', $self->cgp_emptytrash_values) + || $self->ut_alphan('cgp_language') + || $self->ut_textn('cgp_timezone') + || $self->ut_textn('cgp_skinname') + || $self->ut_textn('cgp_prontoskinname') + || $self->ut_alphan('cgp_sendmdnmode') ; return $error if $error; @@ -1135,16 +1255,14 @@ sub check { } my $ulen = $usernamemax || $self->dbdef_table->column('username')->length; - if ( $username_uppercase ) { - $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})$/ - or return gettext('illegal_username'). " ($usernamemin-$ulen): ". $recref->{username}; - $recref->{username} = $1; - } + $recref->{username} =~ /^([a-z0-9_\-\.\&\%\:\/\=\#]{$usernamemin,$ulen})$/i + or return gettext('illegal_username'). " ($usernamemin-$ulen): ". $recref->{username}; + $recref->{username} = $1; + + unless ( $username_uppercase ) { + $recref->{username} =~ /[A-Z]/ and return gettext('illegal_username'); + } if ( $username_letterfirst ) { $recref->{username} =~ /^[a-z]/ or return gettext('illegal_username'); } elsif ( $username_letter ) { @@ -1168,6 +1286,16 @@ sub check { unless ( $username_colon ) { $recref->{username} =~ /\:/ and return gettext('illegal_username'); } + unless ( $username_slash ) { + $recref->{username} =~ /\// and return gettext('illegal_username'); + } + unless ( $username_equals ) { + $recref->{username} =~ /\=/ and return gettext('illegal_username'); + } + unless ( $username_pound ) { + $recref->{username} =~ /\#/ and return gettext('illegal_username'); + } + $recref->{popnum} =~ /^(\d*)$/ or return "Illegal popnum: ".$recref->{popnum}; $recref->{popnum} = $1; @@ -1211,7 +1339,7 @@ sub check { unless ( $part_svc->part_svc_column('dir')->columnflag eq 'F' ) { - $recref->{dir} =~ /^([\/\w\-\.\&]*)$/ + $recref->{dir} =~ /^([\/\w\-\.\&\:\#]*)$/ or return "Illegal directory: ". $recref->{dir}; $recref->{dir} = $1; return "Illegal directory" @@ -1246,8 +1374,7 @@ sub check { $self->setfield('finger', $cust_main->first.' '.$cust_main->get('last') ); } } - $self->getfield('finger') =~ - /^([\w \t\!\@\#\$\%\&\(\)\-\+\;\'\"\,\.\?\/\*\<\>]*)$/ + $self->getfield('finger') =~ /^([\w \,\.\-\'\&\t\!\@\#\$\%\(\)\+\;\"\?\/\*\<\>]+)$/ or return "Illegal finger: ". $self->getfield('finger'); $self->setfield('finger', $1); @@ -1467,6 +1594,8 @@ sub set_password { $pass = crypt($pass, $saltset[int(rand(64))].$saltset[int(rand(64))]); } # else $encryption eq 'plain', do nothing + $pass .= '=' x (4 - length($pass) % 4) #properly padded base64 + if $encryption eq 'md5' || $encryption eq 'sha1'; $pass = '{'.uc($encryption).'}'.$pass; } # else encoding eq 'plain' @@ -1800,22 +1929,6 @@ sub domain { $svc_domain->domain; } -=item svc_domain - -Returns the FS::svc_domain record for this account's domain (see -L). - -=cut - -# FS::h_svc_acct has a history-aware svc_domain override - -sub svc_domain { - my $self = shift; - $self->{'_domsvc'} - ? $self->{'_domsvc'} - : qsearchs( 'svc_domain', { 'svcnum' => $self->domsvc } ); -} - =item cust_svc Returns the FS::cust_svc record for this account (see L). @@ -1841,17 +1954,27 @@ sub email { =item acct_snarf Returns an array of FS::acct_snarf records associated with the account. -If the acct_snarf table does not exist or there are no associated records, -an empty list is returned =cut sub acct_snarf { my $self = shift; - return () unless dbdef->table('acct_snarf'); - eval "use FS::acct_snarf;"; - die $@ if $@; - qsearch('acct_snarf', { 'svcnum' => $self->svcnum } ); + qsearch({ + 'table' => 'acct_snarf', + 'hashref' => { 'svcnum' => $self->svcnum }, + #'order_by' => 'ORDER BY priority ASC', + }); +} + +=item cgp_rpop_hashref + +Returns an arrayref of RPOP data suitable for Communigate Pro API commands. + +=cut + +sub cgp_rpop_hashref { + my $self = shift; + { map { $_->snarfname => $_->cgp_hashref } $self->acct_snarf }; } =item decrement_upbytes OCTETS @@ -2104,20 +2227,19 @@ sub _op_overlimit { my $cust_pkg = $self->cust_svc->cust_pkg; - my $conf_overlimit = + my @conf_overlimit = $cust_pkg ? $conf->config('overlimit_groups', $cust_pkg->cust_main->agentnum ) : $conf->config('overlimit_groups'); foreach my $part_export ( $self->cust_svc->part_svc->part_export ) { - my $groups = $conf_overlimit || $part_export->option('overlimit_groups'); - next unless $groups; - - my $gref = &{ $self->_fieldhandlers->{'usergroup'} }( $self, $groups ); + my @groups = scalar(@conf_overlimit) ? @conf_overlimit + : split(' ',$part_export->option('overlimit_groups')); + next unless scalar(@groups); my $other = new FS::svc_acct $self->hashref; - $other->usergroup( $gref ); + $other->usergroup(\@groups); my($new,$old); if ($action eq 'suspend') { @@ -2166,7 +2288,7 @@ sub set_usage { my $reset = 0; my %handyhash = (); if ( $options{null} ) { - %handyhash = ( map { ( $_ => 'NULL', $_."_threshold" => 'NULL' ) } + %handyhash = ( map { ( $_ => undef, $_."_threshold" => undef ) } qw( seconds upbytes downbytes totalbytes ) ); } @@ -2188,7 +2310,7 @@ sub set_usage { #die $error if $error; #services not explicity changed via the UI my $sql = "UPDATE svc_acct SET " . - join (',', map { "$_ = $handyhash{$_}" } (keys %handyhash) ). + join (',', map { "$_ = ?" } (keys %handyhash) ). " WHERE svcnum = ". $self->svcnum; warn "$me $sql\n" @@ -2197,7 +2319,7 @@ sub set_usage { if (scalar(keys %handyhash)) { my $sth = $dbh->prepare( $sql ) or die "Error preparing $sql: ". $dbh->errstr; - my $rv = $sth->execute(); + my $rv = $sth->execute(values %handyhash); die "Error executing $sql: ". $sth->errstr unless defined($rv); die "Can't update usage for svcnum ". $self->svcnum @@ -2440,10 +2562,26 @@ sub radius_groups { unless ref($self->usergroup) eq 'ARRAY'; #when provisioning records, export callback runs in svc_Common.pm before #radius_usergroup records can be inserted... - @{$self->usergroup}; + my $groups = join(',',@{$self->usergroup}); + my @groups; + return @groups unless length($groups); + @groups = qsearch({ 'table' => 'radius_group', + 'extra_sql' => "where groupnum in ($groups)", + }); + map { $_->groupname } @groups; } else { - map { $_->groupname } - qsearch('radius_usergroup', { 'svcnum' => $self->svcnum } ); + my $format = shift || ''; + my @groups = qsearch({ 'table' => 'radius_usergroup', + 'addl_from' => 'left join radius_group using (groupnum)', + 'select' => 'radius_group.*', + 'hashref' => { 'svcnum' => $self->svcnum }, + }); + + # this is to preserve various legacy behaviour / avoid re-writing other code + return map { $_->groupnum } @groups if $format eq 'NUMBERS'; + return map { $_->description . " (" . $_->groupname . ")" } @groups + if $format eq 'COMBINED'; + map { $_->groupname } @groups; } } @@ -2557,12 +2695,12 @@ sub crypt_password { my $encryption = ( scalar(@_) && $_[0] ) ? shift : 'crypt'; if ( $encryption eq 'crypt' ) { - crypt( + return crypt( $self->_password, $saltset[int(rand(64))].$saltset[int(rand(64))] ); } elsif ( $encryption eq 'md5' ) { - unix_md5_crypt( $self->_password ); + return unix_md5_crypt( $self->_password ); } elsif ( $encryption eq 'blowfish' ) { croak "unknown encryption method $encryption"; } else { @@ -2570,7 +2708,7 @@ sub crypt_password { } } elsif ( $self->_password =~ /^\{CRYPT\}(.+)$/ ) { - $1; + return $1; } } elsif ( $self->_password_encoding eq 'crypt' ) { @@ -2583,12 +2721,16 @@ sub crypt_password { my $encryption = ( scalar(@_) && $_[0] ) ? shift : 'crypt'; if ( $encryption eq 'crypt' ) { - crypt( + return crypt( $self->_password, $saltset[int(rand(64))].$saltset[int(rand(64))] ); } elsif ( $encryption eq 'md5' ) { - unix_md5_crypt( $self->_password ); + return unix_md5_crypt( $self->_password ); + } elsif ( $encryption eq 'sha1_base64' ) { #for acct_sql + my $pass = sha1_base64( $self->_password ); + $pass .= '=' x (4 - length($pass) % 4); #properly padded base64 + return $pass; } elsif ( $encryption eq 'blowfish' ) { croak "unknown encryption method $encryption"; } else { @@ -2609,12 +2751,12 @@ sub crypt_password { my $encryption = ( scalar(@_) && $_[0] ) ? shift : 'crypt'; if ( $encryption eq 'crypt' ) { - crypt( + return crypt( $self->_password, $saltset[int(rand(64))].$saltset[int(rand(64))] ); } elsif ( $encryption eq 'md5' ) { - unix_md5_crypt( $self->_password ); + return unix_md5_crypt( $self->_password ); } elsif ( $encryption eq 'blowfish' ) { croak "unknown encryption method $encryption"; } else { @@ -2980,56 +3122,6 @@ sub append_fuzzyfiles { } - -=item radius_usergroup_selector GROUPS_ARRAYREF [ SELECTNAME ] - -=cut - -sub radius_usergroup_selector { - my $sel_groups = shift; - my %sel_groups = map { $_=>1 } @$sel_groups; - - my $selectname = shift || 'radius_usergroup'; - - my $dbh = dbh; - my $sth = $dbh->prepare( - 'SELECT DISTINCT(groupname) FROM radius_usergroup ORDER BY groupname' - ) or die $dbh->errstr; - $sth->execute() or die $sth->errstr; - my @all_groups = map { $_->[0] } @{$sth->fetchall_arrayref}; - - my $html = < - function ${selectname}_doadd(object) { - var myvalue = object.${selectname}_add.value; - var optionName = new Option(myvalue,myvalue,false,true); - var length = object.$selectname.length; - object.$selectname.options[length] = optionName; - object.${selectname}_add.value = ""; - } - - '; - - $html .= qq!
!. - qq!!; - - $html; -} - =item reached_threshold Performs some activities when svc_acct thresholds (such as number of seconds @@ -3119,9 +3211,6 @@ The suspend, unsuspend and cancel methods update the database, but not the current object. This is probably a bug as it's unexpected and counterintuitive. -radius_usergroup_selector? putting web ui components in here? they should -probably live somewhere else... - insertion of RADIUS group stuff in insert could be done with child_objects now (would probably clean up export of them too) @@ -3137,61 +3226,4 @@ schema.html from the base documentation. =cut -=item domain_select_hash %OPTIONS - -Returns a hash SVCNUM => DOMAIN ... representing the domains this customer -may at present purchase. - -Currently available options are: I I - -=cut - -sub domain_select_hash { - my ($self, %options) = @_; - my %domains = (); - my $part_svc; - my $cust_pkg; - - if (ref($self)) { - $part_svc = $self->part_svc; - $cust_pkg = $self->cust_svc->cust_pkg - if $self->cust_svc; - } - - $part_svc = qsearchs('part_svc', { 'svcpart' => $options{svcpart} }) - if $options{'svcpart'}; - - $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $options{pkgnum} }) - if $options{'pkgnum'}; - - if ($part_svc && ( $part_svc->part_svc_column('domsvc')->columnflag eq 'S' - || $part_svc->part_svc_column('domsvc')->columnflag eq 'F')) { - %domains = map { $_->svcnum => $_->domain } - map { qsearchs('svc_domain', { 'svcnum' => $_ }) } - split(',', $part_svc->part_svc_column('domsvc')->columnvalue); - }elsif ($cust_pkg && !$conf->exists('svc_acct-alldomains') ) { - %domains = map { $_->svcnum => $_->domain } - map { qsearchs('svc_domain', { 'svcnum' => $_->svcnum }) } - map { qsearch('cust_svc', { 'pkgnum' => $_->pkgnum } ) } - qsearch('cust_pkg', { 'custnum' => $cust_pkg->custnum }); - }else{ - %domains = map { $_->svcnum => $_->domain } qsearch('svc_domain', {} ); - } - - if ($part_svc && $part_svc->part_svc_column('domsvc')->columnflag eq 'D') { - my $svc_domain = qsearchs('svc_domain', - { 'svcnum' => $part_svc->part_svc_column('domsvc')->columnvalue } ); - if ( $svc_domain ) { - $domains{$svc_domain->svcnum} = $svc_domain->domain; - }else{ - warn "unknown svc_domain.svcnum for part_svc_column domsvc: ". - $part_svc->part_svc_column('domsvc')->columnvalue; - - } - } - - (%domains); -} - 1; -