From 01503e37e5415702b30e0fe8ff58c31d69e404a0 Mon Sep 17 00:00:00 2001 From: "justdave%syndicomm.com" <> Date: Mon, 13 Aug 2001 07:46:18 +0000 Subject: Fix for bug 39816: Anyone in CC, Reporter, QA Contact, or Asigned To fields can now be given access to view a bug even if the permissions on that bug are set to a group that would normally exclude those people. Patch by Myk Melez r= justdave@syndicomm.com --- CGI.pl | 71 ++++++++++++++++++++++++++++++++++---------- bug_form.pl | 92 +++++++++++++++++++++++++++++++++++---------------------- checksetup.pl | 13 ++++++++ process_bug.cgi | 29 ++++++++++++++++++ 4 files changed, 154 insertions(+), 51 deletions(-) diff --git a/CGI.pl b/CGI.pl index 2f1a189b3..5a86b7ad1 100644 --- a/CGI.pl +++ b/CGI.pl @@ -266,33 +266,72 @@ sub ValidateBugID { # the user is a member of all groups to which the bug is restricted # and is authorized to access the bug. + # A user is also authorized to access a bug if she is the reporter, + # assignee, QA contact, or member of the cc: list of the bug and the bug + # allows users in those roles to see the bug. The boolean fields + # reporter_accessible, assignee_accessible, qacontact_accessible, and + # cclist_accessible identify whether or not those roles can see the bug. + # Bit arithmetic is performed by MySQL instead of Perl because bitset # fields in the database are 64 bits wide (BIGINT), and Perl installations # may or may not support integers larger than 32 bits. Using bitsets # and doing bitset arithmetic is probably not cross-database compatible, # however, so these mechanisms are likely to change in the future. - SendSQL("SELECT ((groupset & $usergroupset) = groupset) - FROM bugs WHERE bug_id = $id"); + + # Get data from the database about whether or not the user belongs to + # all groups the bug is in, and who are the bug's reporter and qa_contact + # along with which roles can always access the bug. + SendSQL("SELECT ((groupset & $usergroupset) = groupset) , reporter , assigned_to , qa_contact , + reporter_accessible , assignee_accessible , qacontact_accessible , cclist_accessible + FROM bugs + WHERE bug_id = $id"); # Make sure the bug exists in the database. MoreSQLData() || DisplayError("Bug #$id does not exist.") && exit; - # Make sure the user is authorized to access the bug. - my ($isauthorized) = FetchSQLData(); - $isauthorized - || ( - $userid ? - DisplayError("You are not authorized to access bug #$id.") : - DisplayError( - qq|You are not authorized to access bug #$id. - To see this bug, you must first - log in - to an account with the appropriate permissions.| - ) - ) - && exit; + my ($isauthorized, $reporter, $assignee, $qacontact, $reporter_accessible, + $assignee_accessible, $qacontact_accessible, $cclist_accessible) = FetchSQLData(); + + # Finish validation and return if the user is authorized either by being + # a member of all necessary groups or by being the reporter, assignee, or QA contact. + return + if $isauthorized + || ($reporter_accessible && $reporter == $userid) + || ($assignee_accessible && $assignee == $userid) + || ($qacontact_accessible && $qacontact == $userid); + + # Try to authorize the user one more time by seeing if they are on + # the cc: list. If so, finish validation and return. + if ( $cclist_accessible ) { + my @cclist; + SendSQL("SELECT cc.who + FROM bugs , cc + WHERE bugs.bug_id = $id + AND cc.bug_id = bugs.bug_id + "); + while (my ($ccwho) = FetchSQLData()) { + push @cclist , $ccwho; + } + return if grep($userid == $_ , @cclist); + } + + # The user did not pass any of the authorization tests, which means they + # are not authorized to see the bug. Display an error and stop execution. + # The error the user sees depends on whether or not they are logged in + # (i.e. $userid contains the user's positive integer ID). + if ($userid) { + DisplayError("You are not authorized to access bug #$id."); + } else { + DisplayError( + qq|You are not authorized to access bug #$id. To see this bug, you + must first log in + to an account with the appropriate permissions.| + ); + } + exit; + } # check and see if a given string actually represents a positive diff --git a/bug_form.pl b/bug_form.pl index 27c19e74c..55128e8a7 100644 --- a/bug_form.pl +++ b/bug_form.pl @@ -74,46 +74,24 @@ select sum(votes.count) from bugs left join votes using(bug_id) where bugs.bug_id = $id -and bugs.groupset & $::usergroupset = bugs.groupset group by bugs.bug_id"; SendSQL($query); my %bug; my @row; -if (@row = FetchSQLData()) { - my $count = 0; - foreach my $field ("bug_id", "product", "version", "rep_platform", - "op_sys", "bug_status", "resolution", "priority", - "bug_severity", "component", "assigned_to", "reporter", - "bug_file_loc", "short_desc", "target_milestone", - "qa_contact", "status_whiteboard", "creation_ts", - "groupset", "delta_ts", "votes") { - $bug{$field} = shift @row; - if (!defined $bug{$field}) { - $bug{$field} = ""; - } - $count++; +@row = FetchSQLData(); +my $count = 0; +foreach my $field ("bug_id", "product", "version", "rep_platform", + "op_sys", "bug_status", "resolution", "priority", + "bug_severity", "component", "assigned_to", "reporter", + "bug_file_loc", "short_desc", "target_milestone", + "qa_contact", "status_whiteboard", "creation_ts", + "groupset", "delta_ts", "votes") { + $bug{$field} = shift @row; + if (!defined $bug{$field}) { + $bug{$field} = ""; } -} else { - SendSQL("select groupset from bugs where bug_id = $id"); - if (@row = FetchSQLData()) { - print "

Permission denied.

\n"; - if ($loginok) { - print "Sorry; you do not have the permissions necessary to see\n"; - print "bug $id.\n"; - } else { - print "Sorry; bug $id can only be viewed when logged\n"; - print "into an account with the appropriate permissions. To\n"; - print "see this bug, you must first\n"; - print ""; - print "log in."; - } - } else { - print "

Bug not found

\n"; - print "There does not seem to be a bug numbered $id.\n"; - } - PutFooter(); - exit; + $count++; } my $assignedtoid = $bug{'assigned_to'}; @@ -205,7 +183,7 @@ print " make_options($::versions{$bug{'product'}}, $bug{'version'}) . "   - Cc: + CC: $cc_element Status: @@ -401,8 +379,52 @@ if ($::usergroupset ne '0') { print "$description
\n"; } } + + # If the user is a member of an active bug group, then they also have the + # ability to determine whether or not the reporter, assignee, QA contact, + # or users on the cc: list should be able to see the bug even when they + # are not members of the groups to which the bug is restricted, so display + # checkboxes that allow the user to make these determinations. + SendSQL("SELECT bit FROM groups WHERE bit & $::usergroupset != 0 AND isbuggroup != 0 AND isactive = 1"); + if ( FetchSQLData() ) { + # Determine whether or not the bug is always accessible by the reporter, + # QA contact, and/or users on the cc: list. + SendSQL("SELECT reporter_accessible , assignee_accessible , + qacontact_accessible , cclist_accessible + FROM bugs + WHERE bug_id = $id + "); + my ($reporter_accessible, $assignee_accessible, $qacontact_accessible, $cclist_accessible) = FetchSQLData(); + + # Convert boolean data about which roles always have access to the bug + # into "checked" attributes for the HTML checkboxes by which users + # set and change these values. + my $reporter_checked = $reporter_accessible ? " checked" : ""; + my $assignee_checked = $assignee_accessible ? " checked" : ""; + my $qacontact_checked = $qacontact_accessible ? " checked" : ""; + my $cclist_checked = $cclist_accessible ? " checked" : ""; + + # Display interface for changing the values. + print qq| +

+ But users in the roles selected below can always view this bug:
+ (Does not take effect unless the bug is restricted to at least one group.) +

+ +

+ Reporter + Assignee + QA Contact + CC List +

+ |; + } } + + + + print "
Leave as $bug{'bug_status'} $bug{'resolution'}
"; diff --git a/checksetup.pl b/checksetup.pl index 14a58eee0..4eeec8ef1 100755 --- a/checksetup.pl +++ b/checksetup.pl @@ -894,6 +894,10 @@ $table{bugs} = . ' lastdiffed datetime not null, everconfirmed tinyint not null, + reporter_accessible tinyint not null default 1, + assignee_accessible tinyint not null default 1, + qacontact_accessible tinyint not null default 1, + cclist_accessible tinyint not null default 1, index (assigned_to), index (creation_ts), @@ -2455,6 +2459,15 @@ if (GetFieldDef('bugs_activity', 'oldvalue')) { # http://bugzilla.mozilla.org/show_bug.cgi?id=90933 ChangeFieldType("profiles", "disabledtext", "mediumtext not null"); +# 2001-07-26 myk@mozilla.org bug39816: +# Add fields to the bugs table that record whether or not the reporter, +# assignee, QA contact, and users on the cc: list can see bugs even when +# they are not members of groups to which the bugs are restricted. +AddField("bugs", "reporter_accessible", "tinyint not null default 1"); +AddField("bugs", "assignee_accessible", "tinyint not null default 1"); +AddField("bugs", "qacontact_accessible", "tinyint not null default 1"); +AddField("bugs", "cclist_accessible", "tinyint not null default 1"); + # If you had to change the --TABLE-- definition in any way, then add your # differential change code *** A B O V E *** this comment. # diff --git a/process_bug.cgi b/process_bug.cgi index 511150911..020e92739 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -529,6 +529,35 @@ if (defined $::FORM{'qa_contact'}) { + +# If the user is submitting changes from show_bug.cgi for a single bug +# and they have access to an active bug group, process the flags that +# indicate whether or not the reporter, assignee, QA contact, and users +# on the CC list can see the bug regardless of its group restrictions. +if ( $::FORM{'id'} ) { + SendSQL("SELECT bit FROM groups WHERE bit & $::usergroupset != 0 + AND isbuggroup != 0 AND isactive = 1"); + my ($groupbits) = FetchSQLData(); + if ( $groupbits ) { + DoComma(); + $::FORM{'reporter_accessible'} = $::FORM{'reporter_accessible'} ? '1' : '0'; + $::query .= "reporter_accessible = $::FORM{'reporter_accessible'}"; + + DoComma(); + $::FORM{'assignee_accessible'} = $::FORM{'assignee_accessible'} ? '1' : '0'; + $::query .= "assignee_accessible = $::FORM{'assignee_accessible'}"; + + DoComma(); + $::FORM{'qacontact_accessible'} = $::FORM{'qacontact_accessible'} ? '1' : '0'; + $::query .= "qacontact_accessible = $::FORM{'qacontact_accessible'}"; + + DoComma(); + $::FORM{'cclist_accessible'} = $::FORM{'cclist_accessible'} ? '1' : '0'; + $::query .= "cclist_accessible = $::FORM{'cclist_accessible'}"; + } +} + + my $removedCcString = ""; my $duplicate = 0; -- cgit v1.2.3-24-g4f1b