summaryrefslogtreecommitdiffstats
path: root/Bugzilla/WebService/User.pm
diff options
context:
space:
mode:
authorDylan William Hardison <dylan@hardison.net>2018-08-04 18:24:15 +0200
committerDylan William Hardison <dylan@hardison.net>2018-08-04 18:24:15 +0200
commitf44392e8cdbea85ac308b2472f813ee605ebae4b (patch)
tree6e7adaf99a0e5a43eb1bf5a0d673d86b60f34f99 /Bugzilla/WebService/User.pm
parent5be3a7fd0061aa0bc3059e09079741873b9b833f (diff)
parent4528b21bc922f8b1e0ba8581d230a492aa43c9cf (diff)
downloadbugzilla-f44392e8cdbea85ac308b2472f813ee605ebae4b.tar.gz
bugzilla-f44392e8cdbea85ac308b2472f813ee605ebae4b.tar.xz
Merge branch 'mojo-poc'
Diffstat (limited to 'Bugzilla/WebService/User.pm')
-rw-r--r--Bugzilla/WebService/User.pm66
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: