From 13f822a442f093f5658e5571c3d236b80be0113f Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 13 Jun 2002 23:00:15 +0000 Subject: [PATCH] fuzzy username searching (Bug#422) --- FS/FS/svc_acct.pm | 102 +++++++++++++++++++++++++++++++++++++++++ httemplate/index.html | 2 +- httemplate/search/svc_acct.cgi | 44 +++++++++++++++++- 3 files changed, 145 insertions(+), 3 deletions(-) diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index ce76fe51b..aa089d065 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -303,6 +303,14 @@ sub insert { } } + #false laziness with sub replace (and cust_main) + my $queue = new FS::queue { 'job' => 'FS::svc_acct::append_fuzzyfiles' }; + $error = $queue->insert($self->username); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "queueing job (transaction rolled back): $error"; + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; #no error } @@ -478,6 +486,15 @@ sub replace { } + #false laziness with sub insert (and cust_main) + my $queue = new FS::queue { '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 } @@ -860,6 +877,89 @@ sub radius_groups { =head1 SUBROUTINES +=over 4 + +=item check_and_rebuild_fuzzyfiles + +=cut + +sub check_and_rebuild_fuzzyfiles { + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + -e "$dir/svc_acct.username" + or &rebuild_fuzzyfiles; +} + +=item rebuild_fuzzyfiles + +=cut + +sub rebuild_fuzzyfiles { + + use Fcntl qw(:flock); + + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + + #username + + open(USERNAMELOCK,">>$dir/svc_acct.username") + or die "can't open $dir/svc_acct.username: $!"; + flock(USERNAMELOCK,LOCK_EX) + or die "can't lock $dir/svc_acct.username: $!"; + + my @all_username = map $_->getfield('username'), qsearch('svc_acct', {}); + + open (USERNAMECACHE,">$dir/svc_acct.username.tmp") + or die "can't open $dir/svc_acct.username.tmp: $!"; + print USERNAMECACHE join("\n", @all_username), "\n"; + close USERNAMECACHE or die "can't close $dir/svc_acct.username.tmp: $!"; + + rename "$dir/svc_acct.username.tmp", "$dir/svc_acct.username"; + close USERNAMELOCK; + +} + +=item all_username + +=cut + +sub all_username { + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + open(USERNAMECACHE,"<$dir/svc_acct.username") + or die "can't open $dir/svc_acct.username: $!"; + my @array = map { chomp; $_; } ; + close USERNAMECACHE; + \@array; +} + +=item append_fuzzyfiles USERNAME + +=cut + +sub append_fuzzyfiles { + my $username = shift; + + &check_and_rebuild_fuzzyfiles; + + use Fcntl qw(:flock); + + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + + open(USERNAME,">>$dir/svc_acct.username") + or die "can't open $dir/svc_acct.username: $!"; + flock(USERNAME,LOCK_EX) + or die "can't lock $dir/svc_acct.username: $!"; + + print USERNAME "$username\n"; + + flock(USERNAME,LOCK_UN) + or die "can't unlock $dir/svc_acct.username: $!"; + close USERNAME; + + 1; +} + + + =item radius_usergroup_selector GROUPS_ARRAYREF [ SELECTNAME ] =cut @@ -909,6 +1009,8 @@ END $html; } +=back + =head1 BUGS The $recref stuff in sub check should be cleaned up. diff --git a/httemplate/index.html b/httemplate/index.html index 8ce12569e..5e47b9464 100644 --- a/httemplate/index.html +++ b/httemplate/index.html @@ -31,7 +31,7 @@
Customer # or all customers by customer number
Last name or all customers by last name
Company or all customers by company
-
Username or all accounts by username
+
Username or all accounts by username
Domain or all domains
diff --git a/httemplate/search/svc_acct.cgi b/httemplate/search/svc_acct.cgi index 0a4338b52..549231d3f 100755 --- a/httemplate/search/svc_acct.cgi +++ b/httemplate/search/svc_acct.cgi @@ -244,10 +244,50 @@ sub uid_sort { sub usernamesearch { + my @svc_acct; + + my %username_type; + foreach ( $cgi->param('username_type') ) { + $username_type{$_}++; + } + $cgi->param('username') =~ /^([\w\-\.\&]+)$/; #untaint username_text - my($username)=$1; + my $username = $1; + + if ( $username_type{'Exact'} || $username_type{'Fuzzy'} ) { + push @svc_acct, qsearch( 'svc_acct', + { 'username' => { 'op' => 'ILIKE', + 'value' => $username } } ); + } + + if ( $username_type{'Substring'} || $username_type{'All'} ) { + push @svc_acct, qsearch( 'svc_acct', + { 'username' => { 'op' => 'ILIKE', + 'value' => "%$username%" } } ); + } + + if ( $username_type{'Fuzzy'} || $username_type{'All'} ) { + &FS::svc_acct::check_and_rebuild_fuzzyfiles; + my $all_username = &FS::svc_acct::all_username; + + my %username; + if ( $username_type{'Fuzzy'} || $username_type{'All'} ) { + foreach ( amatch($username, [ qw(i) ], @$all_username) ) { + $username{$_}++; + } + } + + #if ($username_type{'Sound-alike'}) { + #} + + foreach ( keys %username ) { + push @svc_acct, qsearch('svc_acct',{'username'=>$_}); + } + + } - [ qsearch('svc_acct',{'username'=>$username}) ]; + #[ qsearch('svc_acct',{'username'=>$username}) ]; + \@svc_acct; } -- 2.11.0