X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fsvc_acct.pm;h=7d3c9c5fd7f43e34cf146530986dcc85eae1a9ed;hb=90b1d7e95a49d8806cc1459a8cb35ba338705a6e;hp=19f292157dc364aab1ab06fd50e8678f3c72c5fc;hpb=085516df97471506ac68d1fdd015ea6a33bb38bd;p=freeside.git diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 19f292157..7d3c9c5fd 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -38,6 +38,7 @@ 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; use FS::queue; use FS::radius_usergroup; @@ -161,45 +162,71 @@ FS::svc_Common. The following fields are currently supported: =over 4 -=item svcnum - primary key (assigned automatcially for new accounts) +=item svcnum + +Primary key (assigned automatcially for new accounts) =item username -=item _password - generated if blank +=item _password + +generated if blank + +=item _password_encoding + +plain, crypt, ldap (or empty for autodetection) + +=item sec_phrase -=item _password_encoding - plain, crypt, ldap (or empty for autodetection) +security phrase -=item sec_phrase - security phrase +=item popnum -=item popnum - Point of presence (see L) +Point of presence (see L) =item uid =item gid -=item finger - GECOS +=item finger -=item dir - set automatically if blank (and uid is not) +GECOS + +=item dir + +set automatically if blank (and uid is not) =item shell -=item quota - (unimplementd) +=item quota + +=item slipip + +IP address + +=item seconds -=item slipip - IP address +=item upbytes -=item seconds - +=item downbyte -=item upbytes - +=item totalbytes -=item downbytes - +=item domsvc + +svcnum from svc_domain + +=item pbxsvc -=item totalbytes - +Optional svcnum from svc_pbx -=item domsvc - svcnum from svc_domain +=item radius_I -=item radius_I - I (reply) +I (reply) -=item rc_I - I (check) +=item rc_I + +I (check) =back @@ -244,8 +271,64 @@ 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_aliases' => { + label => 'Communigate aliases', + type => 'text', + disable_inventory => 1, + disable_select => 1, + }, + 'password_selfchange' => { label => 'Password modification', + type => 'checkbox', + }, + 'password_recover' => { label => 'Password recovery', + type => 'checkbox', + }, + '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, + }, 'quota' => { - label => 'Quota', + label => 'Quota', #Mail storage limit + type => 'text', + disable_inventory => 1, + disable_select => 1, + }, + 'file_quota'=> { + label => 'File storage limit', + type => 'text', + disable_inventory => 1, + disable_select => 1, + }, + 'file_maxnum'=> { + label => 'Number of files limit', + type => 'text', + disable_inventory => 1, + disable_select => 1, + }, + 'file_maxsize'=> { + label => 'File size limit', type => 'text', disable_inventory => 1, disable_select => 1, @@ -275,6 +358,20 @@ sub table_info { 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', + disable_inventory => 1, + disable_select => 1, #UI wonky, pry works otherwise + }, 'usergroup' => { label => 'RADIUS groups', type => 'radius_usergroup_selector', @@ -436,13 +533,7 @@ sub search_sql { $class->search_sql_field('username', $string ). ' ) '; } else { - ' ( '. - $class->search_sql_field('username', $string). - ( $string =~ /^\d+$/ - ? 'OR '. $class->search_sql_field('svcnum', $string) - : '' - ). - ' ) '; + $class->search_sql_field('username', $string); } } @@ -662,13 +753,16 @@ sub insert { } # set usage fields and thresholds if unset but set in a package def +# AND the package already has a last bill date (otherwise they get double added) sub preinsert_hook_first { my $self = shift; return '' unless $self->pkgnum; my $cust_pkg = qsearchs( 'cust_pkg', { 'pkgnum' => $self->pkgnum } ); - my $part_pkg = $cust_pkg->part_pkg if $cust_pkg; + return '' unless $cust_pkg && $cust_pkg->last_bill; + + my $part_pkg = $cust_pkg->part_pkg; return '' unless $part_pkg && $part_pkg->can('usage_valuehash'); my %values = $part_pkg->usage_valuehash; @@ -1017,15 +1111,21 @@ sub check { my $error = $self->ut_numbern('svcnum') #|| $self->ut_number('domsvc') - || $self->ut_foreign_key('domsvc', 'svc_domain', 'svcnum' ) + || $self->ut_foreign_key( 'domsvc', 'svc_domain', 'svcnum' ) + || $self->ut_foreign_keyn('pbxsvc', 'svc_pbx', 'svcnum' ) || $self->ut_textn('sec_phrase') || $self->ut_snumbern('seconds') || $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_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') ; return $error if $error; @@ -1161,8 +1261,12 @@ sub check { or return "Illegal finger: ". $self->getfield('finger'); $self->setfield('finger', $1); - $recref->{quota} =~ /^(\w*)$/ or return "Illegal quota"; - $recref->{quota} = $1; + for (qw( quota file_quota file_maxsize )) { + $recref->{$_} =~ /^(\w*)$/ or return "Illegal $_"; + $recref->{$_} = $1; + } + $recref->{file_maxnum} =~ /^\s*(\d*)\s*$/ or return "Illegal file_maxnum"; + $recref->{file_maxnum} = $1; unless ( $part_svc->part_svc_column('slipip')->columnflag eq 'F' ) { if ( $recref->{slipip} eq '' ) { @@ -1295,80 +1399,81 @@ is >0), one will be generated randomly. =cut sub set_password { - my $self = shift; - my $pass = shift; - my ($encoding, $encryption); + my( $self, $pass ) = ( shift, shift ); + + warn "[$me] set_password (to $pass) called on $self: ". Dumper($self) + if $DEBUG; + my $failure = gettext('illegal_password'). " $passwordmin-$passwordmax ". FS::Msgcat::_gettext('illegal_password_characters'). ": ". $pass; - if(($passwordmin and length($pass) < $passwordmin) or - ($passwordmax and length($pass) > $passwordmax)) { - return $failure; - } + my( $encoding, $encryption ) = ('', ''); - if($self->_password_encoding) { + if ( $self->_password_encoding ) { $encoding = $self->_password_encoding; # identify existing encryption method, try to use it. $encryption = $self->_password_encryption; - if(!$encryption) { + if (!$encryption) { # use the system default undef $encoding; } } - if(!$encoding) { + if ( !$encoding ) { # set encoding to system default - ($encoding, $encryption) = split(/-/, lc($conf->config('default-password-encoding'))); + ($encoding, $encryption) = + split(/-/, lc($conf->config('default-password-encoding'))); $encoding ||= 'legacy'; $self->_password_encoding($encoding); } - if($encoding eq 'legacy') { + if ( $encoding eq 'legacy' ) { + # The legacy behavior from check(): # If the password is blank, randomize it and set encoding to 'plain'. if(!defined($pass) or (length($pass) == 0 and $passwordmin)) { $pass = join('',map($pw_set[ int(rand $#pw_set) ], (0..7) ) ); $self->_password_encoding('plain'); - } - else { + } else { # Prefix + valid-length password if ( $pass =~ /^((\*SUSPENDED\* |!!?)?)([^\t\n]{$passwordmin,$passwordmax})$/ ) { $pass = $1.$3; $self->_password_encoding('plain'); - } # Prefix + crypt string - elsif ( $pass =~ /^((\*SUSPENDED\* |!!?)?)([\w\.\/\$\;\+]{13,64})$/ ) { + } elsif ( $pass =~ /^((\*SUSPENDED\* |!!?)?)([\w\.\/\$\;\+]{13,64})$/ ) { $pass = $1.$3; $self->_password_encoding('crypt'); - } # Various disabled crypt passwords - elsif ( $pass eq '*' or - $pass eq '!' or - $pass eq '!!' ) { + } elsif ( $pass eq '*' || $pass eq '!' || $pass eq '!!' ) { $self->_password_encoding('crypt'); - } - else { + } else { return $failure; } - } + } + + $self->_password($pass); + return; + } - elsif($encoding eq 'crypt') { - if($encryption eq 'md5') { + + return $failure + if $passwordmin && length($pass) < $passwordmin + or $passwordmax && length($pass) > $passwordmax; + + if ( $encoding eq 'crypt' ) { + if ($encryption eq 'md5') { $pass = unix_md5_crypt($pass); - } - elsif($encryption eq 'des') { + } elsif ($encryption eq 'des') { $pass = crypt($pass, $saltset[int(rand(64))].$saltset[int(rand(64))]); } - } - elsif($encoding eq 'ldap') { - if($encryption eq 'md5') { + + } elsif ( $encoding eq 'ldap' ) { + if ($encryption eq 'md5') { $pass = md5_base64($pass); - } - elsif($encryption eq 'sha1') { + } elsif ($encryption eq 'sha1') { $pass = sha1_base64($pass); - } - elsif($encryption eq 'crypt') { + } elsif ($encryption eq 'crypt') { $pass = crypt($pass, $saltset[int(rand(64))].$saltset[int(rand(64))]); } # else $encryption eq 'plain', do nothing @@ -1636,30 +1741,20 @@ for the password. sub radius_password { my $self = shift; - my($pw_attrib, $password); + my $pw_attrib; if ( $self->_password_encoding eq 'ldap' ) { - $pw_attrib = 'Password-With-Header'; - $password = $self->_password; - } elsif ( $self->_password_encoding eq 'crypt' ) { - $pw_attrib = 'Crypt-Password'; - $password = $self->_password; - } elsif ( $self->_password_encoding eq 'plain' ) { - - $pw_attrib = $radius_password; #Cleartext-Password? man rlm_pap - $password = $self->_password; - + $pw_attrib = $radius_password; } else { - - $pw_attrib = length($password) <= 12 ? $radius_password : 'Crypt-Password'; - $password = $self->_password; - + $pw_attrib = length($self->_password) <= 12 + ? $radius_password + : 'Crypt-Password'; } - ($pw_attrib, $password); + ($pw_attrib, $self->_password); } @@ -2122,8 +2217,8 @@ sub set_usage { #$self->snapshot; #not necessary, we retain the old values #create an object with the updated usage values my $new = qsearchs('svc_acct', { 'svcnum' => $self->svcnum }); - #call exports - my $error = $new->replace($self); + local($FS::Record::nowarn_identical) = 1; + my $error = $new->replace($self); #call exports if ( $error ) { $dbh->rollback if $oldAutoCommit; return "Error replacing: $error";