[Rt-commit] rt branch, 5.0/rest2-query-by-json-support-custom-fields, created. rt-5.0.1-19-g8ad2c8a8be
Craig Kaiser
craig at bestpractical.com
Fri Mar 5 09:46:46 EST 2021
The branch, 5.0/rest2-query-by-json-support-custom-fields has been created
at 8ad2c8a8be24f8afd2deb26fca94de78ced9b31f (commit)
- Log -----------------------------------------------------------------
commit 0010aef6cde89a1cb94169ec9470598512d072d6
Author: craig kaiser <craig at bestpractical.com>
Date: Tue Mar 2 09:42:01 2021 -0500
Add support for custom fields in REST2 JSON query
diff --git a/lib/RT/REST2/Resource/Collection/QueryByJSON.pm b/lib/RT/REST2/Resource/Collection/QueryByJSON.pm
index 00e03e2e32..da3dcb72e3 100644
--- a/lib/RT/REST2/Resource/Collection/QueryByJSON.pm
+++ b/lib/RT/REST2/Resource/Collection/QueryByJSON.pm
@@ -96,25 +96,51 @@ sub limit_collection {
$collection->{'find_disabled_rows'} = 1
if $self->request->param('find_disabled_rows');
+ my $custom_field_object = RT::CustomField->new( $self->request->env->{"rt.current_user"} );
+
for my $limit (@$query) {
- next unless $limit->{field}
- and $searchable{$limit->{field}}
- and defined $limit->{value};
-
- $collection->Limit(
- FIELD => $limit->{field},
- VALUE => $limit->{value},
- ( $limit->{operator}
+ next unless $limit->{field} && defined $limit->{value};
+
+ if ( $limit->{field} =~ /CustomField\.\{(.*)\}/ ) {
+ my $cf_name = $1;
+ next unless $cf_name;
+
+ my ($ret, $msg) = $custom_field_object->LoadByName(
+ Name => $cf_name,
+ LookupType => $collection->RecordClass->CustomFieldLookupType,
+ IncludeGlobal => 1
+ );
+
+ unless ( $ret && $custom_field_object->Id ) {
+ RT::Logger->error( "Could not load custom field: $limit->{'field'}: $msg" );
+ next;
+ }
+
+ $collection->LimitCustomField(
+ VALUE => $limit->{'value'},
+ CUSTOMFIELD => $custom_field_object->Id,
+ ( $limit->{operator}
? (OPERATOR => $limit->{operator})
: () ),
- CASESENSITIVE => ($limit->{case_sensitive} || 0),
- ( $limit->{entry_aggregator}
- ? (ENTRYAGGREGATOR => $limit->{entry_aggregator})
- : () ),
- );
+ );
+ }
+ else {
+ next unless $searchable{$limit->{field}};
+
+ $collection->Limit(
+ FIELD => $limit->{field},
+ VALUE => $limit->{value},
+ ( $limit->{operator}
+ ? (OPERATOR => $limit->{operator})
+ : () ),
+ CASESENSITIVE => ($limit->{case_sensitive} || 0),
+ ( $limit->{entry_aggregator}
+ ? (ENTRYAGGREGATOR => $limit->{entry_aggregator})
+ : () ),
+ );
+ }
}
-
- my @orderby_cols;
+ my @orderby_cols;
my @orders = $self->request->param('order');
foreach my $orderby ($self->request->param('orderby')) {
my $order = shift @orders || 'ASC';
commit 9efbab8d128536774c59f799c2ef1048c5abbce7
Author: craig kaiser <craig at bestpractical.com>
Date: Tue Mar 2 10:06:10 2021 -0500
Add test for searching users custom fields with REST2
diff --git a/t/rest2/users.t b/t/rest2/users.t
index 0b686df69d..7c77ee37d9 100644
--- a/t/rest2/users.t
+++ b/t/rest2/users.t
@@ -161,7 +161,44 @@ $test_user->PrincipalObj->GrantRight(Right => 'AdminGroupMembership');
);
}
-$test_user->PrincipalObj->RevokeRight(Right => 'ShowUserHistory');
-$test_user->PrincipalObj->RevokeRight(Right => 'AdminUsers');
+diag "Test searching users based on custom field value";
+{
+ my $cf = RT::CustomField->new(RT->SystemUser);
+ ok($cf, "Have a CustomField object");
+
+ my ($id, $msg) = $cf->Create(
+ Name => 'Department',
+ Description => 'A Testing custom field',
+ Type => 'Freeform',
+ MaxValues => 1,
+ LookupType => RT::User->CustomFieldLookupType,
+ );
+ ok($id, 'User custom field correctly created');
+ ok($cf->AddToObject( RT::User->new( RT->SystemUser ) ), 'applied Testing CF globally');
+
+ $test_user->PrincipalObj->GrantRight( Right => $_ ) for qw/SeeCustomField ModifyCustomField/;
+
+ (my $ret, $msg) = $user_foo->AddCustomFieldValue( Field => 'Department', Value => 'HR' );
+ ok ($ret, "Added Dapartment custom field value to user_foo");
+
+ my $payload = [
+ {
+ "field" => "CustomField.{Department}",
+ "value" => "HR",
+ "operator" => "="
+ }
+ ];
+
+ my $res = $mech->post_json("$rest_base_path/users/",
+ $payload,
+ 'Authorization' => $auth,
+ );
+ is($res->code, 200);
+ my $content = $mech->json_response;
+ ok( $content->{'count'} eq 1, "Found one user" );
+ ok( $content->{'items'}[0]->{'id'} eq 'foo', "Found foo user" );
+}
+
+$test_user->PrincipalObj->RevokeRight( Right => $_ ) for qw/SeeCustomField ModifyCustomField ShowUserHistory AdminUsers/;
done_testing;
commit f7345257df7abc33532a6ee34d7336b0e296a916
Author: craig kaiser <craig at bestpractical.com>
Date: Tue Mar 2 17:43:14 2021 -0500
Add test for searching groups based on custom fields with REST2
diff --git a/t/rest2/groups.t b/t/rest2/groups.t
new file mode 100644
index 0000000000..31b58d5966
--- /dev/null
+++ b/t/rest2/groups.t
@@ -0,0 +1,58 @@
+use strict;
+use warnings;
+use RT::Test::REST2 tests => undef;
+use Test::Deep;
+
+use Data::Dumper;
+my $mech = RT::Test::REST2->mech;
+
+my $auth = RT::Test::REST2->authorization_header;
+
+my $rest_base_path = '/REST/2.0';
+
+my $test_user = RT::Test::REST2->user;
+$test_user->PrincipalObj->GrantRight(Right => 'SuperUser');
+
+diag "Test searching groups based on custom field value";
+{
+ my $group1 = RT::Group->new(RT->SystemUser);
+ $group1->CreateUserDefinedGroup(Name => 'Group 1');
+
+ my $group2 = RT::Group->new(RT->SystemUser);
+ $group2->CreateUserDefinedGroup(Name => 'Group 2');
+
+ my $cf = RT::CustomField->new(RT->SystemUser);
+ ok($cf, "Have a CustomField object");
+
+ my ($id, $msg) = $cf->Create(
+ Name => 'Group Type',
+ Description => 'A Testing custom field',
+ Type => 'Freeform',
+ MaxValues => 1,
+ LookupType => RT::Group->CustomFieldLookupType,
+ );
+ ok($id, 'Group custom field correctly created');
+ ok($cf->AddToObject( RT::Group->new( RT->SystemUser ) ), 'applied Testing CF globally');
+
+ (my $ret, $msg) = $group1->AddCustomFieldValue( Field => 'Group Type', Value => 'Test' );
+ ok ($ret, "Added Group Type custom field value 'Test' to group1");
+
+ my $payload = [
+ {
+ "field" => "CustomField.{Group Type}",
+ "value" => "Test",
+ }
+ ];
+
+ my $res = $mech->post_json("$rest_base_path/groups",
+ $payload,
+ 'Authorization' => $auth,
+ );
+ is($res->code, 200);
+ my $content = $mech->json_response;
+ ok( $content->{'count'} eq 1, "Found one group" );
+ ok( $content->{'items'}[0]->{'id'} eq $group1->Id, "Found group1 group" );
+}
+$test_user->PrincipalObj->RevokeRight( Right => 'SuperUser' );
+
+done_testing();
commit 8ad2c8a8be24f8afd2deb26fca94de78ced9b31f
Author: craig kaiser <craig at bestpractical.com>
Date: Fri Mar 5 08:33:02 2021 -0500
Add documentation for REST2 custom field JSON queries
diff --git a/lib/RT/REST2.pm b/lib/RT/REST2.pm
index 2ea9fb3201..081871ebe4 100644
--- a/lib/RT/REST2.pm
+++ b/lib/RT/REST2.pm
@@ -675,6 +675,11 @@ Below are some examples using the endpoints above.
-d '[{ "field" : "id", "operator" : ">=", "value" : 0 }]'
'https://myrt.com/REST/2.0/assets'
+ # Search Assets Based On Custom Field Values using L</JSON searches>
+ curl -X POST -H "Content-Type: application/json" -u 'root:password'
+ -d '[{ "field" : "CustomField.{Department}", "value" : "Engineering" }]'
+ 'https://myrt.com/REST/2.0/assets'
+
=head3 Catalogs
GET /catalogs/all
@@ -925,6 +930,18 @@ values). An example:
The JSON payload must be an array of hashes with the keys C<field> and C<value>
and optionally C<operator>.
+
+If the field you're searching against is a Custom Field and not a core field for
+the objects you're searching on, then you use the C<CustomField.{some CF}> syntax:
+
+ curl -si -u user:pass https://rt.example.com/REST/2.0/users -XPOST --data-binary '
+ [
+ { "field" : "CustomField.{Department}",
+ "operator" : "=",
+ "value" : "Human Resources" },
+ ]
+ '
+
Results can be sorted by using multiple query parameter arguments
C<orderby> and C<order>. Each C<orderby> query parameter specify a field
to be used for sorting results. If the request includes more than one
-----------------------------------------------------------------------
More information about the rt-commit
mailing list