summaryrefslogtreecommitdiffstats
path: root/Bugzilla/WebService/Util.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/WebService/Util.pm')
-rw-r--r--Bugzilla/WebService/Util.pm115
1 files changed, 105 insertions, 10 deletions
diff --git a/Bugzilla/WebService/Util.pm b/Bugzilla/WebService/Util.pm
index fe4105ca2..a0421ad9a 100644
--- a/Bugzilla/WebService/Util.pm
+++ b/Bugzilla/WebService/Util.pm
@@ -32,32 +32,56 @@ our @EXPORT_OK = qw(
filter_wants
taint_data
validate
+ translate
+ params_to_objects
+ fix_credentials
);
-sub filter ($$) {
- my ($params, $hash) = @_;
+sub filter ($$;$) {
+ my ($params, $hash, $prefix) = @_;
my %newhash = %$hash;
foreach my $key (keys %$hash) {
- delete $newhash{$key} if !filter_wants($params, $key);
+ delete $newhash{$key} if !filter_wants($params, $key, $prefix);
}
return \%newhash;
}
-sub filter_wants ($$) {
- my ($params, $field) = @_;
+sub filter_wants ($$;$) {
+ my ($params, $field, $prefix) = @_;
+
+ # Since this is operation is resource intensive, we will cache the results
+ # This assumes that $params->{*_fields} doesn't change between calls
+ my $cache = Bugzilla->request_cache->{filter_wants} ||= {};
+ $field = "${prefix}.${field}" if $prefix;
+
+ if (exists $cache->{$field}) {
+ return $cache->{$field};
+ }
+
my %include = map { $_ => 1 } @{ $params->{'include_fields'} || [] };
my %exclude = map { $_ => 1 } @{ $params->{'exclude_fields'} || [] };
- if (defined $params->{include_fields}) {
- return 0 if !$include{$field};
+ my $wants = 1;
+ if (defined $params->{exclude_fields} && $exclude{$field}) {
+ $wants = 0;
}
- if (defined $params->{exclude_fields}) {
- return 0 if $exclude{$field};
+ elsif (defined $params->{include_fields} && !$include{$field}) {
+ if ($prefix) {
+ # Include the field if the parent is include (and this one is not excluded)
+ $wants = 0 if !$include{$prefix};
+ }
+ else {
+ # We want to include this if one of the sub keys is included
+ my $key = $field . '.';
+ my $len = length($key);
+ $wants = 0 if ! grep { substr($_, 0, $len) eq $key } keys %include;
+ }
}
- return 1;
+ $cache->{$field} = $wants;
+ return $wants;
}
sub taint_data {
@@ -108,6 +132,48 @@ sub validate {
return ($self, $params);
}
+sub translate {
+ my ($params, $mapped) = @_;
+ my %changes;
+ while (my ($key,$value) = each (%$params)) {
+ my $new_field = $mapped->{$key} || $key;
+ $changes{$new_field} = $value;
+ }
+ return \%changes;
+}
+
+sub params_to_objects {
+ my ($params, $class) = @_;
+ my (@objects, @objects_by_ids);
+
+ @objects = map { $class->check($_) }
+ @{ $params->{names} } if $params->{names};
+
+ @objects_by_ids = map { $class->check({ id => $_ }) }
+ @{ $params->{ids} } if $params->{ids};
+
+ push(@objects, @objects_by_ids);
+ my %seen;
+ @objects = grep { !$seen{$_->id}++ } @objects;
+ return \@objects;
+}
+
+sub fix_credentials {
+ my ($params) = @_;
+ # Allow user to pass in login=foo&password=bar as a convenience
+ # even if not calling GET /login. We also do not delete them as
+ # GET /login requires "login" and "password".
+ if (exists $params->{'login'} && exists $params->{'password'}) {
+ $params->{'Bugzilla_login'} = $params->{'login'};
+ $params->{'Bugzilla_password'} = $params->{'password'};
+ }
+ # Allow user to pass token=12345678 as a convenience which becomes
+ # "Bugzilla_token" which is what the auth code looks for.
+ if (exists $params->{'token'}) {
+ $params->{'Bugzilla_token'} = $params->{'token'};
+ }
+}
+
__END__
=head1 NAME
@@ -136,6 +202,13 @@ of WebService methods. Given a hash (the second argument to this subroutine),
this will remove any keys that are I<not> in C<include_fields> and then remove
any keys that I<are> in C<exclude_fields>.
+An optional third option can be passed that prefixes the field name to allow
+filtering of data two or more levels deep.
+
+For example, if you want to filter out the C<id> key/value in components returned
+by Product.get, you would use the value C<component.id> in your C<exclude_fields>
+list.
+
=head2 filter_wants
Returns C<1> if a filter would preserve the specified field when passing
@@ -147,3 +220,25 @@ This helps in the validation of parameters passed into the WebService
methods. Currently it converts listed parameters into an array reference
if the client only passed a single scalar value. It modifies the parameters
hash in place so other parameters should be unaltered.
+
+=head2 params_to_objects
+
+Creates objects of the type passed in as the second parameter, using the
+parameters passed to a WebService method (the first parameter to this function).
+Helps make life simpler for WebService methods that internally create objects
+via both "ids" and "names" fields. Also de-duplicates objects that were loaded
+by both "ids" and "names". Returns an arrayref of objects.
+
+=head2 fix_credentials
+
+Allows for certain parameters related to authentication such as Bugzilla_login,
+Bugzilla_password, and Bugzilla_token to have shorter named equivalents passed in.
+This function converts the shorter versions to their respective internal names.
+
+=head1 B<Methods in need of POD>
+
+=over
+
+=item taint_data
+
+=back