Commit b1c2301d authored by Per Cederqvist's avatar Per Cederqvist
Browse files

Imported Bugzilla 2.21.1.

parent 1f9fb3c7
......@@ -33,6 +33,66 @@ use Bugzilla::Constants;
use Bugzilla::DB;
use Bugzilla::Template;
use Bugzilla::User;
use Bugzilla::Error;
use Bugzilla::Util;
use File::Basename;
#####################################################################
# Constants
#####################################################################
# Scripts that are not stopped by shutdownhtml being in effect.
use constant SHUTDOWNHTML_EXEMPT => [
'doeditparams.cgi',
'editparams.cgi',
'checksetup.pl',
];
#####################################################################
# Global Code
#####################################################################
# If Bugzilla is shut down, do not allow anything to run, just display a
# message to the user about the downtime and log out. Scripts listed in
# SHUTDOWNHTML_EXEMPT are exempt from this message.
#
# This code must go here. It cannot go anywhere in Bugzilla::CGI, because
# it uses Template, and that causes various dependency loops.
if (Param("shutdownhtml")
&& lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1)
{
# For security reasons, log out users when Bugzilla is down.
# Bugzilla->login() is required to catch the logincookie, if any.
my $user = Bugzilla->login(LOGIN_OPTIONAL);
my $userid = $user->id;
Bugzilla->logout();
my $template = Bugzilla->template;
my $vars = {};
$vars->{'message'} = 'shutdown';
$vars->{'userid'} = $userid;
# Generate and return a message about the downtime, appropriately
# for if we're a command-line script or a CGI sript.
my $extension;
if (i_am_cgi() && (!Bugzilla->cgi->param('format')
|| Bugzilla->cgi->param('format') eq 'html')) {
$extension = 'html';
}
else {
$extension = 'txt';
}
print Bugzilla->cgi->header() if i_am_cgi();
my $t_output;
$template->process("global/message.$extension.tmpl", $vars, \$t_output)
|| ThrowTemplateError($template->error);
print $t_output . "\n";
exit;
}
#####################################################################
# Subroutines and Methods
#####################################################################
my $_template;
sub template {
......
......@@ -20,91 +20,384 @@
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Myk Melez <myk@mozilla.org>
############################################################################
# Module Initialization
############################################################################
use strict;
package Bugzilla::Attachment;
# This module requires that its caller have said "require CGI.pl" to import
# relevant functions from that script and its companion globals.pl.
=head1 NAME
Bugzilla::Attachment - a file related to a bug that a user has uploaded
to the Bugzilla server
=head1 SYNOPSIS
use Bugzilla::Attachment;
# Get the attachment with the given ID.
my $attachment = Bugzilla::Attachment->get($attach_id);
# Get the attachments with the given IDs.
my $attachments = Bugzilla::Attachment->get_list($attach_ids);
=head1 DESCRIPTION
This module defines attachment objects, which represent files related to bugs
that users upload to the Bugzilla server.
=cut
# This module requires that its caller have said "require globals.pl"
# to import relevant functions from that script.
# Use the Flag module to handle flags.
use Bugzilla::Flag;
use Bugzilla::Config qw(:locations);
use Bugzilla::User;
############################################################################
# Functions
############################################################################
sub new {
# Returns a hash of information about the attachment with the given ID.
sub get {
my $invocant = shift;
my $id = shift;
my ($invocant, $id) = @_;
return undef if !$id;
my $self = { 'id' => $id };
my $class = ref($invocant) || $invocant;
bless($self, $class);
&::PushGlobalSQLState();
&::SendSQL("SELECT 1, description, bug_id, isprivate FROM attachments " .
"WHERE attach_id = $id");
($self->{'exists'},
$self->{'summary'},
$self->{'bug_id'},
$self->{'isprivate'}) = &::FetchSQLData();
&::PopGlobalSQLState();
my $attachments = _retrieve([$id]);
my $self = $attachments->[0];
bless($self, ref($invocant) || $invocant) if $self;
return $self;
}
sub query
{
# Retrieves and returns an array of attachment records for a given bug.
# This data should be given to attachment/list.html.tmpl in an
# "attachments" variable.
my ($bugid) = @_;
my $dbh = Bugzilla->dbh;
# Retrieve a list of attachments for this bug and write them into an array
# of hashes in which each hash represents a single attachment.
my $list = $dbh->selectall_arrayref("SELECT attach_id, " .
$dbh->sql_date_format('creation_ts', '%Y.%m.%d %H:%i') .
", mimetype, description, ispatch,
isobsolete, isprivate, LENGTH(thedata)
FROM attachments
WHERE bug_id = ? ORDER BY attach_id",
undef, $bugid);
my @attachments = ();
foreach my $row (@$list) {
my %a;
($a{'attachid'}, $a{'date'}, $a{'contenttype'},
$a{'description'}, $a{'ispatch'}, $a{'isobsolete'},
$a{'isprivate'}, $a{'datasize'}) = @$row;
# Retrieve a list of flags for this attachment.
$a{'flags'} = Bugzilla::Flag::match({ 'attach_id' => $a{'attachid'},
'is_active' => 1 });
# A zero size indicates that the attachment is stored locally.
if ($a{'datasize'} == 0) {
my $attachid = $a{'attachid'};
my $hash = ($attachid % 100) + 100;
$hash =~ s/.*(\d\d)$/group.$1/;
if (open(AH, "$attachdir/$hash/attachment.$attachid")) {
$a{'datasize'} = (stat(AH))[7];
sub get_list {
my $invocant = shift;
my $ids = shift;
my $attachments = _retrieve($ids);
foreach my $attachment (@$attachments) {
bless($attachment, ref($invocant) || $invocant);
}
return $attachments;
}
sub _retrieve {
my ($ids) = @_;
return [] if scalar(@$ids) == 0;
my @columns = (
'attachments.attach_id AS id',
'attachments.bug_id AS bug_id',
'attachments.description AS description',
'attachments.mimetype AS contenttype',
'attachments.submitter_id AS _attacher_id',
Bugzilla->dbh->sql_date_format('attachments.creation_ts',
'%Y.%m.%d %H:%i') . " AS attached",
'attachments.filename AS filename',
'attachments.ispatch AS ispatch',
'attachments.isobsolete AS isobsolete',
'attachments.isprivate AS isprivate'
);
my $columns = join(", ", @columns);
my $records = Bugzilla->dbh->selectall_arrayref("SELECT $columns
FROM attachments
WHERE attach_id IN (" .
join(",", @$ids) . ")",
{ Slice => {} });
return $records;
}
=pod
=head2 Instance Properties
=over
=item C<id>
the unique identifier for the attachment
=back
=cut
sub id {
my $self = shift;
return $self->{id};
}
=over
=item C<bug_id>
the ID of the bug to which the attachment is attached
=back
=cut
# XXX Once Bug.pm slims down sufficiently this should become a reference
# to a bug object.
sub bug_id {
my $self = shift;
return $self->{bug_id};
}
=over
=item C<description>
user-provided text describing the attachment
=back
=cut
sub description {
my $self = shift;
return $self->{description};
}
=over
=item C<contenttype>
the attachment's MIME media type
=back
=cut
sub contenttype {
my $self = shift;
return $self->{contenttype};
}
=over
=item C<attacher>
the user who attached the attachment
=back
=cut
sub attacher {
my $self = shift;
return $self->{attacher} if exists $self->{attacher};
$self->{attacher} = new Bugzilla::User($self->{_attacher_id});
return $self->{attacher};
}
=over
=item C<attached>
the date and time on which the attacher attached the attachment
=back
=cut
sub attached {
my $self = shift;
return $self->{attached};
}
=over
=item C<filename>
the name of the file the attacher attached
=back
=cut
sub filename {
my $self = shift;
return $self->{filename};
}
=over
=item C<ispatch>
whether or not the attachment is a patch
=back
=cut
sub ispatch {
my $self = shift;
return $self->{ispatch};
}
=over
=item C<isobsolete>
whether or not the attachment is obsolete
=back
=cut
sub isobsolete {
my $self = shift;
return $self->{isobsolete};
}
=over
=item C<isprivate>
whether or not the attachment is private
=back
=cut
sub isprivate {
my $self = shift;
return $self->{isprivate};
}
=over
=item C<data>
the content of the attachment
=back
=cut
sub data {
my $self = shift;
return $self->{data} if exists $self->{data};
# First try to get the attachment data from the database.
($self->{data}) = Bugzilla->dbh->selectrow_array("SELECT thedata
FROM attach_data
WHERE id = ?",
undef,
$self->{id});
# If there's no attachment data in the database, the attachment is stored
# in a local file, so retrieve it from there.
if (length($self->{data}) == 0) {
if (open(AH, $self->_get_local_filename())) {
binmode AH;
$self->{data} = <AH>;
close(AH);
}
}
push @attachments, \%a;
}
return $self->{data};
}
=over
=item C<datasize>
the length (in characters) of the attachment content
=back
=cut
# datasize is a property of the data itself, and it's unclear whether we should
# expose it at all, since you can easily derive it from the data itself: in TT,
# attachment.data.size; in Perl, length($attachment->{data}). But perhaps
# it makes sense for performance reasons, since accessing the data forces it
# to get retrieved from the database/filesystem and loaded into memory,
# while datasize avoids loading the attachment into memory, calling SQL's
# LENGTH() function or stat()ing the file instead. I've left it in for now.
sub datasize {
my $self = shift;
return $self->{datasize} if exists $self->{datasize};
# If we have already retrieved the data, return its size.
return length($self->{data}) if exists $self->{data};
($self->{datasize}) =
Bugzilla->dbh->selectrow_array("SELECT LENGTH(thedata)
FROM attach_data
WHERE id = ?",
undef,
$self->{id});
# If there's no attachment data in the database, the attachment
# is stored in a local file, so retrieve its size from the file.
if ($self->{datasize} == 0) {
if (open(AH, $self->_get_local_filename())) {
binmode AH;
$self->{datasize} = (stat(AH))[7];
close(AH);
}
}
return $self->{datasize};
}
=over
=item C<flags>
flags that have been set on the attachment
=back
=cut
sub flags {
my $self = shift;
return $self->{flags} if exists $self->{flags};
$self->{flags} = Bugzilla::Flag::match({ attach_id => $self->id,
is_active => 1 });
return $self->{flags};
}
# Instance methods; no POD documentation here yet because the only one so far
# is private.
sub _get_local_filename {
my $self = shift;
my $hash = ($self->id % 100) + 100;
$hash =~ s/.*(\d\d)$/group.$1/;
return "$attachdir/$hash/attachment." . $self->id;
}
=pod
=head2 Class Methods
=over
=item C<get_attachments_by_bug($bug_id)>
Description: retrieves and returns the attachments for the given bug.
Params: C<$bug_id> - integer - the ID of the bug for which
to retrieve and return attachments.
Returns: a reference to an array of attachment objects.
=back
=cut
return \@attachments;
sub get_attachments_by_bug {
my ($class, $bug_id) = @_;
my $attach_ids = Bugzilla->dbh->selectcol_arrayref("SELECT attach_id
FROM attachments
WHERE bug_id = ?
ORDER BY attach_id",
undef, $bug_id);
my $attachments = Bugzilla::Attachment->get_list($attach_ids);
return $attachments;
}
1;
/README/1.2/Thu Jul 29 02:45:38 2004//TBUGZILLA-2_20
/README/1.2/Thu Jul 29 02:45:38 2004//TBUGZILLA-2_21_1
D/Login////
D/Verify////
NBUGZILLA-2_20
NBUGZILLA-2_21_1
/WWW.pm/1.6.4.1/Wed Jul 27 19:08:42 2005//TBUGZILLA-2_20
/WWW.pm/1.7/Tue Jul 26 14:09:47 2005//TBUGZILLA-2_21_1
D/WWW////
/Cookie.pm/1.3/Tue Mar 22 22:41:07 2005//TBUGZILLA-2_20
/Cookie.pm/1.3/Tue Mar 22 22:41:07 2005//TBUGZILLA-2_21_1
D
/CGI.pm/1.12/Fri Jul 8 04:48:47 2005//TBUGZILLA-2_20
/Env.pm/1.4.2.1/Tue Jul 26 14:57:04 2005//TBUGZILLA-2_20
/CGI.pm/1.12/Fri Jul 8 04:48:47 2005//TBUGZILLA-2_21_1
/Env.pm/1.6/Thu Aug 18 20:09:37 2005//TBUGZILLA-2_21_1
D/CGI////
......@@ -38,6 +38,7 @@ sub login {
my $matched_userid = '';
my $matched_extern_id = '';
my $disabledtext = '';
my $new_login_name = 0;
my $dbh = Bugzilla->dbh;
my $sth;
......@@ -122,6 +123,7 @@ sub login {
") VALUES ( ?, ?, ?, '' )");
$sth->execute($env_email, '*', $env_realname);
$matched_userid = $dbh->bz_last_key('profiles', 'userid');
$new_login_name = $matched_userid;
}
}
}
......@@ -147,9 +149,16 @@ sub login {
($env_realname || $this_realname),
$matched_userid);
$sth->execute;
$new_login_name = $matched_userid;
}
}
# If the login name may be new, make sure the regexp groups are current
if ($new_login_name) {
my $userprofile = new Bugzilla::User($matched_userid);
$userprofile->derive_regexp_groups;
}
# Now we throw an error if the user has been disabled
if ($disabledtext) {
ThrowUserError("account_disabled",
......
/DB.pm/1.5.2.1/Wed Jul 13 04:02:21 2005//TBUGZILLA-2_20
/LDAP.pm/1.6/Fri Jul 8 02:31:42 2005//TBUGZILLA-2_20
/DB.pm/1.6/Wed Jul 13 03:57:02 2005//TBUGZILLA-2_21_1
/LDAP.pm/1.6/Fri Jul 8 02:31:42 2005//TBUGZILLA-2_21_1
D
......@@ -36,11 +36,11 @@ use vars qw($legal_keywords @legal_platform
use CGI::Carp qw(fatalsToBrowser);
use Bugzilla;
use Bugzilla::Attachment;
use Bugzilla::BugMail;