summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xattachment.cgi4
-rw-r--r--extensions/BMO/Extension.pm59
-rw-r--r--extensions/BMO/bin/migrate-github-pull-requests.pl90
-rw-r--r--extensions/BMO/lib/Data.pm5
-rw-r--r--template/en/default/attachment/edit.html.tmpl3
5 files changed, 159 insertions, 2 deletions
diff --git a/attachment.cgi b/attachment.cgi
index 350cf91f1..95d793e75 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -52,6 +52,7 @@ use Bugzilla::Attachment;
use Bugzilla::Attachment::PatchReader;
use Bugzilla::Token;
use Bugzilla::Keyword;
+use Bugzilla::Hook;
use Encode qw(encode find_encoding);
@@ -386,6 +387,9 @@ sub view {
# Return the appropriate HTTP response headers.
$attachment->datasize || ThrowUserError("attachment_removed");
+ # BMO add a hook for github url redirection
+ Bugzilla::Hook::process('attachment_view', { attachment => $attachment });
+
$filename =~ s/^.*[\/\\]//;
# escape quotes and backslashes in the filename, per RFCs 2045/822
$filename =~ s/\\/\\\\/g; # escape backslashes
diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm
index fd9068fe7..1fdb7d3c2 100644
--- a/extensions/BMO/Extension.pm
+++ b/extensions/BMO/Extension.pm
@@ -33,6 +33,7 @@ use Bugzilla::Mailer;
use Bugzilla::Product;
use Bugzilla::Status;
use Bugzilla::Token;
+use Bugzilla::Install::Filesystem;
use Bugzilla::User;
use Bugzilla::User::Setting;
use Bugzilla::Util;
@@ -580,6 +581,55 @@ sub bug_end_of_create {
}
}
+# detect github pull requests and set a unique content-type
+sub attachment_process_data {
+ my ($self, $args) = @_;
+ my $attributes = $args->{attributes};
+
+ # quick checks - must be a text/plain non-patch
+ return if $attributes->{ispatch} || $attributes->{mimetype} ne 'text/plain';
+
+ # check the attachment size, and get attachment content if it isn't too large
+ my $data = $attributes->{data};
+ my $url;
+ if (blessed($data) && blessed($data) eq 'Fh') {
+ # filehandle
+ my $size = -s $data;
+ return if $size > 256;
+ sysread($data, $url, $size);
+ seek($data, 0, 0);
+ } else {
+ # string
+ return if length($data) > 256;
+ $url = $data;
+ }
+
+ # trim and check for the pull request url
+ $url = trim($url);
+ return if $url =~ /\s/;
+ return unless $url =~ m#^https://github\.com/[^/]+/[^/]+/pull/\d+$#i;
+
+ # must be a valid pull-request
+ $attributes->{mimetype} = GITHUB_PR_CONTENT_TYPE;
+}
+
+# redirect automatically to github urls
+sub attachment_view {
+ my ($self, $args) = @_;
+ my $attachment = $args->{attachment};
+ my $cgi = Bugzilla->cgi;
+
+ # don't redirect if the content-type is specified explicitly
+ return if defined $cgi->param('content_type');
+
+ # must be our github content-type
+ return unless $attachment->contenttype eq GITHUB_PR_CONTENT_TYPE;
+
+ # redirect
+ print $cgi->redirect(trim($attachment->data));
+ exit;
+}
+
sub install_before_final_checks {
my ($self, $args) = @_;
@@ -1064,4 +1114,13 @@ sub _check_default_product_security_group {
}
}
+sub install_filesystem {
+ my ($self, $args) = @_;
+ my $files = $args->{files};
+ my $extensions_dir = bz_locations()->{extensionsdir};
+ $files->{"$extensions_dir/BMO/bin/migrate-github-pull-requests.pl"} = {
+ perms => Bugzilla::Install::Filesystem::OWNER_EXECUTE
+ };
+}
+
__PACKAGE__->NAME;
diff --git a/extensions/BMO/bin/migrate-github-pull-requests.pl b/extensions/BMO/bin/migrate-github-pull-requests.pl
new file mode 100644
index 000000000..eba0dd422
--- /dev/null
+++ b/extensions/BMO/bin/migrate-github-pull-requests.pl
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This Source Code Form is "Incompatible With Secondary Licenses", as
+# defined by the Mozilla Public License, v. 2.0.
+
+use strict;
+use warnings;
+
+use FindBin qw($RealBin);
+use lib "$RealBin/../../..";
+
+use Bugzilla;
+BEGIN { Bugzilla->extensions() }
+
+use Bugzilla::Extension::BMO::Data;
+use Bugzilla::Field;
+use Bugzilla::Install::Util qw(indicate_progress);
+use Bugzilla::User;
+use Bugzilla::Util qw(trim);
+
+my $dbh = Bugzilla->dbh;
+my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' });
+my $field = Bugzilla::Field->check({ name => 'attachments.mimetype' });
+
+# grab list of suitable attachments
+
+my $sql = <<EOF;
+SELECT attachments.attach_id,
+ attachments.bug_id,
+ attachments.mimetype,
+ attach_data.thedata
+ FROM attachments
+ INNER JOIN attach_data ON attach_data.id = attachments.attach_id
+ WHERE ispatch = 0
+ AND mimetype = 'text/plain'
+ AND thedata IS NOT NULL
+ AND LENGTH(thedata) > 0
+ AND LENGTH(thedata) <= 256
+EOF
+print "Searching for suitable attachments..\n";
+my $attachments = $dbh->selectall_arrayref($sql, { Slice => {} });
+my ($current, $total, $updated) = (1, scalar(@$attachments), 0);
+
+die "No suitable attachments found\n" unless $total;
+print "About to check $total attachments for github pull requests, and\n";
+print "update content-type if required.\n";
+print "Press <enter> to start, or ^C to cancel...\n";
+<>;
+
+foreach my $attachment (@$attachments) {
+ indicate_progress({ current => $current++, total => $total, every => 25 });
+
+ # check payload
+ my $url = trim($attachment->{thedata});
+ next if $url =~ /\s/;
+ next unless $url =~ m#^https://github\.com/[^/]+/[^/]+/pull/\d+$#i;
+
+ $dbh->bz_start_transaction;
+
+ # set content-type
+ $dbh->do(
+ "UPDATE attachments SET mimetype = ? WHERE attach_id = ?",
+ undef,
+ GITHUB_PR_CONTENT_TYPE, $attachment->{attach_id}
+ );
+
+ # insert into bugs_activity
+ my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
+ $dbh->do(
+ "INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added)
+ VALUES (?, ?, ?, ?, ?, ?)",
+ undef,
+ $attachment->{bug_id}, $nobody->id, $timestamp, $field->id,
+ $attachment->{mimetype}, GITHUB_PR_CONTENT_TYPE
+ );
+ $dbh->do(
+ "UPDATE bugs SET delta_ts = ?, lastdiffed = ? WHERE bug_id = ?",
+ undef,
+ $timestamp, $timestamp, $attachment->{bug_id}
+ );
+
+ $dbh->bz_commit_transaction;
+ $updated++;
+}
+
+print "Attachments updated: $updated\n";
diff --git a/extensions/BMO/lib/Data.pm b/extensions/BMO/lib/Data.pm
index e730f84ea..e070cd244 100644
--- a/extensions/BMO/lib/Data.pm
+++ b/extensions/BMO/lib/Data.pm
@@ -39,7 +39,10 @@ our @EXPORT = qw( $cf_visible_in_products
%group_auto_cc
%product_sec_groups
%create_bug_formats
- @default_named_queries );
+ @default_named_queries
+ GITHUB_PR_CONTENT_TYPE );
+
+use constant GITHUB_PR_CONTENT_TYPE => 'text/x-github-pull-request';
# Which custom fields are visible in which products and components.
#
diff --git a/template/en/default/attachment/edit.html.tmpl b/template/en/default/attachment/edit.html.tmpl
index 530b2d04c..cbc66e95a 100644
--- a/template/en/default/attachment/edit.html.tmpl
+++ b/template/en/default/attachment/edit.html.tmpl
@@ -208,7 +208,8 @@
readonly = 'readonly'
%]
[% ELSE %]
- <iframe id="viewFrame" src="attachment.cgi?id=[% attachment.id %]">
+ <iframe id="viewFrame" src="attachment.cgi?id=[% attachment.id %]
+ [%- "&amp;content_type=text/plain" IF attachment.contenttype == 'text/x-github-pull-request' %]">
<b>You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
<a href="attachment.cgi?id=[% attachment.id %]">View the attachment on a separate page</a>.</b>
</iframe>