summaryrefslogtreecommitdiffstats
path: root/extensions/BMO/Extension.pm
diff options
context:
space:
mode:
authorByron Jones <bjones@mozilla.com>2012-12-11 01:57:41 +0100
committerByron Jones <bjones@mozilla.com>2012-12-11 01:57:41 +0100
commit30d411c5782453456a5818f04fad113305300443 (patch)
treeab68c12db28713ab63f56720148aa48eb67f4988 /extensions/BMO/Extension.pm
parentf0e84a2cf2f4390c88349d817cbcdde70ac7bca6 (diff)
downloadbugzilla-30d411c5782453456a5818f04fad113305300443.tar.gz
bugzilla-30d411c5782453456a5818f04fad113305300443.tar.xz
Bug 786777: add facility for direct read-only database access
Diffstat (limited to 'extensions/BMO/Extension.pm')
-rw-r--r--extensions/BMO/Extension.pm61
1 files changed, 61 insertions, 0 deletions
diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm
index 037cc6689..f3940cb26 100644
--- a/extensions/BMO/Extension.pm
+++ b/extensions/BMO/Extension.pm
@@ -40,6 +40,7 @@ use Scalar::Util qw(blessed);
use Date::Parse;
use DateTime;
use Encode qw(find_encoding);
+use Sys::Syslog qw(:DEFAULT setlogsock);
use Bugzilla::Extension::BMO::Constants;
use Bugzilla::Extension::BMO::FakeBug;
@@ -185,6 +186,9 @@ sub page_before_template {
elsif ($page eq 'release_tracking_report.html') {
release_tracking_report($vars);
}
+ elsif ($page eq 'query_database.html') {
+ query_database($vars);
+ }
}
sub _get_field_values_sort_key {
@@ -1012,4 +1016,61 @@ sub buglist_columns {
};
}
+sub query_database {
+ my ($vars) = @_;
+
+ # validate group membership
+ my $user = Bugzilla->user;
+ $user->in_group('query_database')
+ || ThrowUserError('auth_failure', { group => 'query_database',
+ action => 'access',
+ object => 'query_database' });
+
+ # read query
+ my $input = Bugzilla->input_params;
+ my $query = $input->{query};
+ $vars->{query} = $query;
+
+ if ($query) {
+ trick_taint($query);
+ $vars->{executed} = 1;
+
+ # add limit if missing
+ if ($query !~ /\sLIMIT\s+\d+\s*$/si) {
+ $query .= ' LIMIT 1000';
+ $vars->{query} = $query;
+ }
+
+ # log query
+ setlogsock('unix');
+ openlog('apache', 'cons', 'pid', 'local4');
+ syslog('notice', sprintf("[db_query] %s %s", $user->login, $query));
+ closelog();
+
+ # connect to database and execute
+ # switching to the shadow db gives us a read-only connection
+ my $dbh = Bugzilla->switch_to_shadow_db();
+ my $sth;
+ eval {
+ $sth = $dbh->prepare($query);
+ $sth->execute();
+ };
+ if ($@) {
+ $vars->{sql_error} = $@;
+ return;
+ }
+
+ # build result
+ my $columns = $sth->{NAME};
+ my $rows;
+ while (my @row = $sth->fetchrow_array) {
+ push @$rows, \@row;
+ }
+
+ # return results
+ $vars->{columns} = $columns;
+ $vars->{rows} = $rows;
+ }
+}
+
__PACKAGE__->NAME;