Mailing List Archive

rt branch, 5.0/rest2-efficiently-get-ticket-attachment-list, created. rt-5.0.0-53-gcc82acb804
The branch, 5.0/rest2-efficiently-get-ticket-attachment-list has been created
at cc82acb8044d3733d6211fca301701f427c17a8f (commit)

- Log -----------------------------------------------------------------
commit cc82acb8044d3733d6211fca301701f427c17a8f
Author: Dianne Skoll <dianne@bestpractical.com>
Date: Fri Oct 16 14:50:57 2020 -0400

Add the REST2 endpoint: GET /ticket/:id/attachments?field=F1,F2,...,Fn

This endpoint returns a list of attachments associated with a ticket; the
"fields" query parameter lets you select which fields to return for each
attachment.

diff --git a/lib/RT/REST2.pm b/lib/RT/REST2.pm
index 1079f95cd6..5f9bf1ba9d 100644
--- a/lib/RT/REST2.pm
+++ b/lib/RT/REST2.pm
@@ -557,6 +557,9 @@ Below are some examples using the endpoints above.
GET /transaction/:id/attachments
get attachments for transaction

+ GET /ticket/:id/attachments
+ get attachments associated with a ticket
+
GET /attachment/:id
retrieve an attachment

diff --git a/lib/RT/REST2/Resource.pm b/lib/RT/REST2/Resource.pm
index 670cbb7eb0..e4746e0140 100644
--- a/lib/RT/REST2/Resource.pm
+++ b/lib/RT/REST2/Resource.pm
@@ -110,7 +110,8 @@ sub expand_field {

push @{ $result }, values %values if %values;
}
-
+ } elsif ($field eq 'ContentLength' && $item->can('ContentLength')) {
+ $result = $item->ContentLength;
} elsif ($item->can('_Accessible') && $item->_Accessible($field => 'read')) {
# RT::Record derived object, so we can check access permissions.

diff --git a/lib/RT/REST2/Resource/Attachments.pm b/lib/RT/REST2/Resource/Attachments.pm
index d098aaa01a..413bad0303 100644
--- a/lib/RT/REST2/Resource/Attachments.pm
+++ b/lib/RT/REST2/Resource/Attachments.pm
@@ -69,7 +69,38 @@ sub dispatch_rules {
$txn->Load($match->pos(1));
return { collection => $txn->Attachments };
},
- )
+ ),
+ Path::Dispatcher::Rule::Regex->new(
+ regex => qr{^/ticket/(\d+)/attachments/?$},
+ block => sub {
+ my ($match, $req) = @_;
+ return _get_ticket_attachments($match, $req);
+ },
+ ),
+}
+
+# Get a collection of attachments associated with a ticket This code
+# was put into a subroutine as it was a little long to put inline
+# above and maintain readability.
+
+sub _get_ticket_attachments
+{
+ my ($match, $req) = @_;
+
+ my $ticket = RT::Ticket->new($req->env->{"rt.current_user"});
+ my $id = $ticket->Load($match->pos(1));
+ my $attachments = RT::Attachments->new($req->env->{"rt.current_user"});
+
+ # Return empty list if no such ticket
+ return { collection => $attachments } unless $id;
+
+ # Explicitly check for permission to see the ticket.
+ # If we do not do that, we leak the total number of attachments
+ # even though the actual attachments themselves are not shown.
+ return { collection => $attachments } unless $ticket->CurrentUserHasRight('ShowTicket');
+
+ $attachments->LimitByTicket($id);
+ return { collection => $attachments };
}

__PACKAGE__->meta->make_immutable;
diff --git a/t/rest2/attachments.t b/t/rest2/attachments.t
index d7aa05fac7..416ea504e5 100644
--- a/t/rest2/attachments.t
+++ b/t/rest2/attachments.t
@@ -98,6 +98,60 @@ $image_content = MIME::Base64::encode_base64($image_content);
ok(!$attachments->[3]->Subject);
}

+# Check the GET /ticket/:id/attachments endpoint
+{
+ my $res = $mech->get(
+ "$rest_base_path/ticket/$ticket_id/attachments?fields=Subject,Filename,ContentType,ContentLength",
+ 'Authorization' => $auth
+ );
+ is( $res->code, 200 );
+
+ cmp_deeply(
+ $mech->json_response,
+ { per_page => 20,
+ pages => 1,
+ total => 4,
+ page => 1,
+ count => 4,
+ items => [.
+ { type => 'attachment',
+ Subject => 'HTML comment with PNG image and text file',
+ _url => re(qr/^https?:/),
+ ContentType => 'multipart/mixed',
+ ContentLength => 0,
+ Filename => '',
+ id => re(qr/^\d+$/)
+ },
+ { type => 'attachment',
+ Subject => '',
+ _url => re(qr/^https?:/),
+ ContentType => 'text/html',
+ ContentLength => 31,
+ Filename => '',
+ id => re(qr/^\d+$/)
+ },
+ { type => 'attachment',
+ Subject => '',
+ _url => re(qr/^https?:/),
+ ContentType => 'image/png',
+ ContentLength => 3929,
+ Filename => 'image.png',
+ id => re(qr/^\d+$/)
+ },
+ { type => 'attachment',
+ Subject => '',
+ _url => re(qr/^https?:/),
+ ContentType => 'text/plain',
+ ContentLength => 19,
+ Filename => 'password',
+ id => re(qr/^\d+$/)
+ },
+ ]
+ },
+ 'Got expected attachment list'
+ );
+}
+
# Comment ticket with image attachment and no content through JSON Base64
{
my $payload = {

-----------------------------------------------------------------------
_______________________________________________
rt-commit mailing list
rt-commit@lists.bestpractical.com
http://lists.bestpractical.com/cgi-bin/mailman/listinfo/rt-commit