summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla.pm39
-rw-r--r--Bugzilla/Attachment/PatchReader.pm9
-rw-r--r--Bugzilla/Config/Admin.pm6
-rw-r--r--Bugzilla/Search.pm1
-rw-r--r--Bugzilla/WebService/Bug.pm14
-rwxr-xr-xattachment.cgi4
-rwxr-xr-xshow_bug.cgi5
-rw-r--r--template/en/default/admin/params/admin.html.tmpl4
-rwxr-xr-xuserprefs.cgi9
9 files changed, 90 insertions, 1 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm
index fa95128d1..b14b92e0d 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -594,6 +594,45 @@ sub switch_to_main_db {
return $class->dbh_main;
}
+sub log_user_request {
+ my ($class, $bug_id, $attach_id, $action) = @_;
+
+ return unless Bugzilla->params->{log_user_requests};
+
+ my $cgi = $class->cgi;
+ my $user_id = $class->user->id;
+ my $request_url = $cgi->request_uri // '';
+ my $method = $cgi->request_method;
+ my $user_agent = $cgi->user_agent // '';
+ my $script_name = $cgi->script_name;
+ my $server = "web";
+
+ if ($script_name =~ /rest\.cgi/) {
+ $server = $script_name =~ /BzAPI/ ? "bzapi" : "rest";
+ }
+ elsif ($script_name =~ /xmlrpc\.cgi/) {
+ $server = "xmlrpc";
+ }
+ elsif ($script_name =~ /jsonrpc\.cgi/) {
+ $server = "jsonrpc";
+ }
+
+ my @params = ($user_id, remote_ip(), $user_agent, $request_url, $method, $bug_id, $attach_id, $action, $server);
+ foreach my $param (@params) {
+ trick_taint($param) if defined $param;
+ }
+
+ eval {
+ local $class->request_cache->{dbh};
+ $class->switch_to_main_db();
+ $class->dbh->do("INSERT INTO user_request_log
+ (user_id, ip_address, user_agent, request_url,
+ method, timestamp, bug_id, attach_id, action, server)
+ VALUES (?, ?, ?, ?, ?, NOW(), ?, ?, ?, ?)", undef, @params);
+ };
+ warn $@ if $@;
+}
+
sub is_shadow_db {
my $class = shift;
return $class->request_cache->{dbh} != $class->dbh_main;
diff --git a/Bugzilla/Attachment/PatchReader.pm b/Bugzilla/Attachment/PatchReader.pm
index 1ab14f386..2c1647736 100644
--- a/Bugzilla/Attachment/PatchReader.pm
+++ b/Bugzilla/Attachment/PatchReader.pm
@@ -38,6 +38,9 @@ sub process_diff {
if ($format eq 'raw') {
require Bugzilla::PatchReader::DiffPrinter::raw;
$last_reader->sends_data_to(new Bugzilla::PatchReader::DiffPrinter::raw());
+
+ Bugzilla->log_user_request($attachment->bug_id, $attachment->id, "attachment-get")
+ if Bugzilla->user->id;
# Actually print out the patch.
print $cgi->header(-type => 'text/plain',
-expires => '+3M');
@@ -93,6 +96,12 @@ sub process_interdiff {
my $lc = Bugzilla->localconfig;
my $vars = {};
+ if (Bugzilla->user->id) {
+ foreach my $attachment ($old_attachment, $new_attachment) {
+ Bugzilla->log_user_request($attachment->bug_id, $attachment->id, "attachment-get");
+ }
+ }
+
# Encode attachment data as utf8 if it's going to be displayed in a HTML
# page using the UTF-8 encoding.
if ($format ne 'raw' && Bugzilla->params->{'utf8'}) {
diff --git a/Bugzilla/Config/Admin.pm b/Bugzilla/Config/Admin.pm
index 769e3170b..b0c0bad9a 100644
--- a/Bugzilla/Config/Admin.pm
+++ b/Bugzilla/Config/Admin.pm
@@ -63,6 +63,12 @@ sub get_param_list {
type => 't',
default => 10,
checker => \&check_numeric
+ },
+
+ {
+ name => 'log_user_requests',
+ type => 'b',
+ default => 0,
});
return @param_list;
}
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index 46d959c3c..ff0db1baa 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -787,6 +787,7 @@ sub data {
return $self->{data} if $self->{data};
my $dbh = Bugzilla->dbh;
+ Bugzilla->log_user_request(undef, undef, "search") if Bugzilla->user->id;
# If all fields belong to the 'bugs' table, there is no need to split
# the original query into two pieces. Else we override the 'fields'
# argument to first get bug IDs based on the search criteria defined
diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm
index d0fe8465f..d7a1d8f9b 100644
--- a/Bugzilla/WebService/Bug.pm
+++ b/Bugzilla/WebService/Bug.pm
@@ -458,6 +458,11 @@ sub get {
$self->_add_update_tokens($params, \@bugs, \@hashes);
+ if (Bugzilla->user->id) {
+ foreach my $bug (@bugs) {
+ Bugzilla->log_user_request($bug->id, undef, 'bug-get');
+ }
+ }
return { bugs => \@hashes, faults => \@faults };
}
@@ -1196,6 +1201,7 @@ sub attachments {
}
my %attachments;
+ my @log_attachments;
foreach my $attach (@{Bugzilla::Attachment->new_from_list($attach_ids)}) {
Bugzilla::Bug->check($attach->bug_id);
if ($attach->isprivate && !Bugzilla->user->is_insider) {
@@ -1203,10 +1209,18 @@ sub attachments {
object => 'attachment',
attach_id => $attach->id});
}
+ push @log_attachments, $attach;
+
$attachments{$attach->id} =
$self->_attachment_to_hash($attach, $params);
}
+ if (Bugzilla->user->id) {
+ foreach my $attachment (@log_attachments) {
+ Bugzilla->log_user_request($attachment->bug_id, $attachment->id, "attachment-get");
+ }
+ }
+
return { bugs => \%bugs, attachments => \%attachments };
}
diff --git a/attachment.cgi b/attachment.cgi
index 78023560d..104ee0ca8 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -435,6 +435,8 @@ sub view {
}
}
}
+ Bugzilla->log_user_request($attachment->bug_id, $attachment->id, "attachment-get")
+ if Bugzilla->user->id;
print $cgi->header(-type=>"$contenttype; name=\"$filename\"",
-content_disposition=> "$disposition; filename=\"$filename\"",
-content_length => $attachment->datasize);
@@ -669,6 +671,8 @@ sub edit {
$vars->{'attachment'} = $attachment;
$vars->{'attachments'} = $bugattachments;
+ Bugzilla->log_user_request($attachment->bug_id, $attachment->id, "attachment-get")
+ if Bugzilla->user->id;
print $cgi->header();
# Generate and return the UI (HTML page) from the appropriate template.
diff --git a/show_bug.cgi b/show_bug.cgi
index 06d17e352..fbcf4e828 100755
--- a/show_bug.cgi
+++ b/show_bug.cgi
@@ -133,6 +133,11 @@ foreach ($cgi->param("excludefield")) {
$vars->{'displayfields'} = \%displayfields;
+if ($user->id) {
+ foreach my $bug_id (@bugids) {
+ Bugzilla->log_user_request($bug_id, undef, 'bug-get');
+ }
+}
print $cgi->header($format->{'ctype'});
$template->process($format->{'template'}, $vars)
diff --git a/template/en/default/admin/params/admin.html.tmpl b/template/en/default/admin/params/admin.html.tmpl
index f84dbc701..df0580783 100644
--- a/template/en/default/admin/params/admin.html.tmpl
+++ b/template/en/default/admin/params/admin.html.tmpl
@@ -40,5 +40,7 @@
"will ever happen."
last_visit_keep_days => "This option controls how many days $terms.Bugzilla will " _
- "remember when users visit specific ${terms.bugs}."}
+ "remember when users visit specific ${terms.bugs}.",
+
+ log_user_requests => "This option controls logging of authenticated requests in the user_request_log table"}
%]
diff --git a/userprefs.cgi b/userprefs.cgi
index 6c6a246ff..bd1bb8ab7 100755
--- a/userprefs.cgi
+++ b/userprefs.cgi
@@ -853,6 +853,12 @@ sub SaveApiKey {
revoked => $revoked,
});
$api_key->update();
+ if ($revoked) {
+ Bugzilla->log_user_request(undef, undef, 'api-key-revoke')
+ }
+ else {
+ Bugzilla->log_user_request(undef, undef, 'api-key-unrevoke')
+ }
}
}
}
@@ -912,6 +918,7 @@ sub MfaApiKey {
revoked => 0,
});
$api_key->update();
+ Bugzilla->log_user_request(undef, undef, 'api-key-unrevoke');
$dbh->bz_commit_transaction;
}
}
@@ -926,6 +933,8 @@ sub _create_api_key {
description => $description,
});
+ Bugzilla->log_user_request(undef, undef, 'api-key-create');
+
# As a security precaution, we always sent out an e-mail when
# an API key is created
my $template = Bugzilla->template_inner($user->setting('lang'));