Commit e377a5b0 authored by Dave Lawrence's avatar Dave Lawrence

Bug 577329 - WebServices should filter email addresses same as the web UI as…

Bug 577329 - WebServices should filter email addresses same as the web UI as users are not always required to login r/a=LpSolit
parent af38912d
...@@ -74,6 +74,12 @@ sub get_param_list { ...@@ -74,6 +74,12 @@ sub get_param_list {
}, },
{ {
name => 'webservice_email_filter',
type => 'b',
default => 0
},
{
name => 'emailregexp', name => 'emailregexp',
type => 't', type => 't',
default => q:^[\\w\\.\\+\\-=]+@[\\w\\.\\-]+\\.[\\w\\-]+$:, default => q:^[\\w\\.\\+\\-=]+@[\\w\\.\\-]+\\.[\\w\\-]+$:,
......
...@@ -22,7 +22,7 @@ use base qw(Exporter); ...@@ -22,7 +22,7 @@ use base qw(Exporter);
is_7bit_clean bz_crypt generate_random_password is_7bit_clean bz_crypt generate_random_password
validate_email_syntax check_email_syntax clean_text validate_email_syntax check_email_syntax clean_text
get_text template_var disable_utf8 get_text template_var disable_utf8
detect_encoding); detect_encoding email_filter);
use Bugzilla::Constants; use Bugzilla::Constants;
use Bugzilla::RNG qw(irand); use Bugzilla::RNG qw(irand);
......
...@@ -72,6 +72,11 @@ A floating-point number. May be null. ...@@ -72,6 +72,11 @@ A floating-point number. May be null.
A string. May be null. A string. May be null.
=item C<email>
A string representing an email address. This value, when returned,
may be filtered based on if the user is logged in or not. May be null.
=item C<dateTime> =item C<dateTime>
A date/time. Represented differently in different interfaces to this API. A date/time. Represented differently in different interfaces to this API.
......
...@@ -302,8 +302,8 @@ sub _translate_comment { ...@@ -302,8 +302,8 @@ sub _translate_comment {
return filter $filters, { return filter $filters, {
id => $self->type('int', $comment->id), id => $self->type('int', $comment->id),
bug_id => $self->type('int', $comment->bug_id), bug_id => $self->type('int', $comment->bug_id),
creator => $self->type('string', $comment->author->login), creator => $self->type('email', $comment->author->login),
author => $self->type('string', $comment->author->login), author => $self->type('email', $comment->author->login),
time => $self->type('dateTime', $comment->creation_ts), time => $self->type('dateTime', $comment->creation_ts),
creation_time => $self->type('dateTime', $comment->creation_ts), creation_time => $self->type('dateTime', $comment->creation_ts),
is_private => $self->type('boolean', $comment->is_private), is_private => $self->type('boolean', $comment->is_private),
...@@ -873,18 +873,18 @@ sub _bug_to_hash { ...@@ -873,18 +873,18 @@ sub _bug_to_hash {
# We don't do the SQL calls at all if the filter would just # We don't do the SQL calls at all if the filter would just
# eliminate them anyway. # eliminate them anyway.
if (filter_wants $params, 'assigned_to') { if (filter_wants $params, 'assigned_to') {
$item{'assigned_to'} = $self->type('string', $bug->assigned_to->login); $item{'assigned_to'} = $self->type('email', $bug->assigned_to->login);
} }
if (filter_wants $params, 'blocks') { if (filter_wants $params, 'blocks') {
my @blocks = map { $self->type('int', $_) } @{ $bug->blocked }; my @blocks = map { $self->type('int', $_) } @{ $bug->blocked };
$item{'blocks'} = \@blocks; $item{'blocks'} = \@blocks;
} }
if (filter_wants $params, 'cc') { if (filter_wants $params, 'cc') {
my @cc = map { $self->type('string', $_) } @{ $bug->cc || [] }; my @cc = map { $self->type('email', $_) } @{ $bug->cc || [] };
$item{'cc'} = \@cc; $item{'cc'} = \@cc;
} }
if (filter_wants $params, 'creator') { if (filter_wants $params, 'creator') {
$item{'creator'} = $self->type('string', $bug->reporter->login); $item{'creator'} = $self->type('email', $bug->reporter->login);
} }
if (filter_wants $params, 'depends_on') { if (filter_wants $params, 'depends_on') {
my @depends_on = map { $self->type('int', $_) } @{ $bug->dependson }; my @depends_on = map { $self->type('int', $_) } @{ $bug->dependson };
...@@ -908,7 +908,7 @@ sub _bug_to_hash { ...@@ -908,7 +908,7 @@ sub _bug_to_hash {
} }
if (filter_wants $params, 'qa_contact') { if (filter_wants $params, 'qa_contact') {
my $qa_login = $bug->qa_contact ? $bug->qa_contact->login : ''; my $qa_login = $bug->qa_contact ? $bug->qa_contact->login : '';
$item{'qa_contact'} = $self->type('string', $qa_login); $item{'qa_contact'} = $self->type('email', $qa_login);
} }
if (filter_wants $params, 'see_also') { if (filter_wants $params, 'see_also') {
my @see_also = map { $self->type('string', $_->name) } my @see_also = map { $self->type('string', $_->name) }
...@@ -985,7 +985,7 @@ sub _attachment_to_hash { ...@@ -985,7 +985,7 @@ sub _attachment_to_hash {
# the filter wants them. # the filter wants them.
foreach my $field (qw(creator attacher)) { foreach my $field (qw(creator attacher)) {
if (filter_wants $filters, $field) { if (filter_wants $filters, $field) {
$item->{$field} = $self->type('string', $attach->attacher->login); $item->{$field} = $self->type('email', $attach->attacher->login);
} }
} }
...@@ -1018,7 +1018,7 @@ sub _flag_to_hash { ...@@ -1018,7 +1018,7 @@ sub _flag_to_hash {
foreach my $field (qw(setter requestee)) { foreach my $field (qw(setter requestee)) {
my $field_id = $field . "_id"; my $field_id = $field . "_id";
$item->{$field} = $self->type('string', $flag->$field->login) $item->{$field} = $self->type('email', $flag->$field->login)
if $flag->$field_id; if $flag->$field_id;
} }
......
...@@ -235,10 +235,10 @@ sub _component_to_hash { ...@@ -235,10 +235,10 @@ sub _component_to_hash {
description => description =>
$self->type('string' , $component->description), $self->type('string' , $component->description),
default_assigned_to => default_assigned_to =>
$self->type('string' , $component->default_assignee->login), $self->type('email', $component->default_assignee->login),
default_qa_contact => default_qa_contact =>
$self->type('string' , $component->default_qa_contact ? $self->type('email', $component->default_qa_contact ?
$component->default_qa_contact->login : ''), $component->default_qa_contact->login : ""),
sort_key => # sort_key is returned to match Bug.fields sort_key => # sort_key is returned to match Bug.fields
0, 0,
is_active => is_active =>
......
...@@ -26,7 +26,7 @@ BEGIN { ...@@ -26,7 +26,7 @@ BEGIN {
use Bugzilla::Error; use Bugzilla::Error;
use Bugzilla::WebService::Constants; use Bugzilla::WebService::Constants;
use Bugzilla::WebService::Util qw(taint_data); use Bugzilla::WebService::Util qw(taint_data);
use Bugzilla::Util qw(correct_urlbase trim disable_utf8); use Bugzilla::Util;
use HTTP::Message; use HTTP::Message;
use MIME::Base64 qw(decode_base64 encode_base64); use MIME::Base64 qw(decode_base64 encode_base64);
...@@ -209,6 +209,9 @@ sub type { ...@@ -209,6 +209,9 @@ sub type {
utf8::encode($value) if utf8::is_utf8($value); utf8::encode($value) if utf8::is_utf8($value);
$retval = encode_base64($value, ''); $retval = encode_base64($value, '');
} }
elsif ($type eq 'email' && Bugzilla->params->{'webservice_email_filter'}) {
$retval = email_filter($value);
}
return $retval; return $retval;
} }
......
...@@ -19,6 +19,7 @@ if ($ENV{MOD_PERL}) { ...@@ -19,6 +19,7 @@ if ($ENV{MOD_PERL}) {
} }
use Bugzilla::WebService::Constants; use Bugzilla::WebService::Constants;
use Bugzilla::Util;
# Allow WebService methods to call XMLRPC::Lite's type method directly # Allow WebService methods to call XMLRPC::Lite's type method directly
BEGIN { BEGIN {
...@@ -30,6 +31,12 @@ BEGIN { ...@@ -30,6 +31,12 @@ BEGIN {
$value = Bugzilla::WebService::Server->datetime_format_outbound($value); $value = Bugzilla::WebService::Server->datetime_format_outbound($value);
$value =~ s/-//g; $value =~ s/-//g;
} }
elsif ($type eq 'email') {
$type = 'string';
if (Bugzilla->params->{'webservice_email_filter'}) {
$value = email_filter($value);
}
}
return XMLRPC::Data->type($type)->value($value); return XMLRPC::Data->type($type)->value($value);
}; };
} }
......
...@@ -159,8 +159,8 @@ sub get { ...@@ -159,8 +159,8 @@ sub get {
\@user_objects, $params); \@user_objects, $params);
@users = map {filter $params, { @users = map {filter $params, {
id => $self->type('int', $_->id), id => $self->type('int', $_->id),
real_name => $self->type('string', $_->name), real_name => $self->type('string', $_->name),
name => $self->type('string', $_->login), name => $self->type('email', $_->login),
}} @$in_group; }} @$in_group;
return { users => \@users }; return { users => \@users };
...@@ -201,7 +201,7 @@ sub get { ...@@ -201,7 +201,7 @@ sub get {
} }
} }
} }
my $in_group = $self->_filter_users_by_group( my $in_group = $self->_filter_users_by_group(
\@user_objects, $params); \@user_objects, $params);
...@@ -209,22 +209,22 @@ sub get { ...@@ -209,22 +209,22 @@ sub get {
my $user_info = { my $user_info = {
id => $self->type('int', $user->id), id => $self->type('int', $user->id),
real_name => $self->type('string', $user->name), real_name => $self->type('string', $user->name),
name => $self->type('string', $user->login), name => $self->type('email', $user->login),
email => $self->type('string', $user->email), email => $self->type('email', $user->email),
can_login => $self->type('boolean', $user->is_enabled ? 1 : 0), can_login => $self->type('boolean', $user->is_enabled ? 1 : 0),
groups => $self->_filter_bless_groups($user->groups), groups => $self->_filter_bless_groups($user->groups),
}; };
if (Bugzilla->user->in_group('editusers')) { if (Bugzilla->user->in_group('editusers')) {
$user_info->{email_enabled} = $self->type('boolean', $user->email_enabled); $user_info->{email_enabled} = $self->type('boolean', $user->email_enabled);
$user_info->{login_denied_text} = $self->type('string', $user->disabledtext); $user_info->{login_denied_text} = $self->type('string', $user->disabledtext);
} }
if (Bugzilla->user->id == $user->id) { if (Bugzilla->user->id == $user->id) {
$user_info->{saved_searches} = [map { $self->_query_to_hash($_) } @{ $user->queries }]; $user_info->{saved_searches} = [map { $self->_query_to_hash($_) } @{ $user->queries }];
$user_info->{saved_reports} = [map { $self->_report_to_hash($_) } @{ $user->reports }]; $user_info->{saved_reports} = [map { $self->_report_to_hash($_) } @{ $user->reports }];
} }
push(@users, filter($params, $user_info)); push(@users, filter($params, $user_info));
} }
......
...@@ -93,6 +93,13 @@ ...@@ -93,6 +93,13 @@
"front page will require a login. No anonymous users will " _ "front page will require a login. No anonymous users will " _
"be permitted.", "be permitted.",
webservice_email_filter =>
"Filter email addresses returned by the WebService API depending on " _
"if the user is logged in or not. This works similarly to how the " _
"web UI currently filters email addresses. If <tt>requirelogin</tt> " _
"is enabled, then this parameter has no effect as users must be logged " _
"in to use Bugzilla.",
emailregexp => emailregexp =>
"This defines the regular expression to use for legal email addresses. " _ "This defines the regular expression to use for legal email addresses. " _
"The default tries to match fully qualified email addresses. " _ "The default tries to match fully qualified email addresses. " _
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment