diff options
Diffstat (limited to 'Bugzilla/WebService/User.pm')
-rw-r--r-- | Bugzilla/WebService/User.pm | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/Bugzilla/WebService/User.pm b/Bugzilla/WebService/User.pm index 5f9b54787..c569cf9d8 100644 --- a/Bugzilla/WebService/User.pm +++ b/Bugzilla/WebService/User.pm @@ -24,6 +24,7 @@ use Bugzilla::WebService::Util qw(filter filter_wants validate use Bugzilla::Hook; use List::Util qw(first); +use Taint::Util qw(untaint); # Don't need auth to login use constant LOGIN_EXEMPT => { @@ -33,6 +34,7 @@ use constant LOGIN_EXEMPT => { use constant READ_ONLY => qw( get + suggest ); use constant PUBLIC_METHODS => qw( @@ -135,6 +137,70 @@ sub create { return { id => $self->type('int', $user->id) }; } +sub suggest { + my ($self, $params) = @_; + + Bugzilla->switch_to_shadow_db(); + + ThrowCodeError('params_required', { function => 'User.suggest', params => ['match'] }) + unless defined $params->{match}; + + ThrowUserError('user_access_by_match_denied') + unless Bugzilla->user->id; + + untaint($params->{match}); + my $s = $params->{match}; + trim($s); + return { users => [] } if length($s) < 3; + + my $dbh = Bugzilla->dbh; + my @select = ('userid AS id', 'realname AS real_name', 'login_name AS name'); + my $order = 'last_seen_date DESC'; + my $where; + state $have_mysql = $dbh->isa('Bugzilla::DB::Mysql'); + + if ($s =~ /^[:@](.+)$/s) { + $where = $dbh->sql_prefix_match(nickname => $1); + } + elsif ($s =~ /@/) { + $where = $dbh->sql_prefix_match(login_name => $s); + } + else { + if ($have_mysql && ( $s =~ /[[:space:]]/ || $s =~ /[^[:ascii:]]/ ) ) { + my $match = sprintf 'MATCH(realname) AGAINST (%s) ', $dbh->quote($s); + push @select, "$match AS relevance"; + $order = 'relevance DESC'; + $where = $match; + } + elsif ($have_mysql && $s =~ /^[[:upper:]]/) { + my $match = sprintf 'MATCH(realname) AGAINST (%s) ', $dbh->quote($s); + $where = join ' OR ', + $match, + $dbh->sql_prefix_match( nickname => $s ), + $dbh->sql_prefix_match( login_name => $s ); + } + else { + $where = join ' OR ', $dbh->sql_prefix_match( nickname => $s ), $dbh->sql_prefix_match( login_name => $s ); + } + } + $where = "($where) AND is_enabled = 1"; + + my $sql = 'SELECT ' . join(', ', @select) . " FROM profiles WHERE $where ORDER BY $order LIMIT 25"; + my $results = $dbh->selectall_arrayref($sql, { Slice => {} }); + + my @users = map { + { + id => $self->type(int => $_->{id}), + real_name => $self->type(string => $_->{real_name}), + name => $self->type(email => $_->{name}), + } + } @$results; + + Bugzilla::Hook::process('webservice_user_suggest', + { webservice => $self, params => $params, users => \@users }); + + return { users => \@users }; +} # function to return user information by passing either user ids or # login names or both together: |