]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 253721: Add group-based lists to whining
authorerik%dasbistro.com <>
Sat, 19 Feb 2005 06:41:09 +0000 (06:41 +0000)
committererik%dasbistro.com <>
Sat, 19 Feb 2005 06:41:09 +0000 (06:41 +0000)
Patch by Erik Stambaugh <erik@dasbistro.com>
r=joel, r,a=justdave

Bugzilla/Constants.pm
Bugzilla/Group.pm [new file with mode: 0644]
Bugzilla/Search.pm
checksetup.pl
editgroups.cgi
editwhines.cgi
template/en/default/whine/schedule.html.tmpl
whine.pl

index a3e16251ca4f36d088557a384d1d232fb209d28c..8837d22761312c5d8a6ac2239eaa2eaa15105692 100644 (file)
@@ -62,6 +62,9 @@ use base qw(Exporter);
     GROUP_BLESS
     GROUP_VISIBLE
 
+    MAILTO_USER
+    MAILTO_GROUP
+
     DEFAULT_COLUMN_LIST
     DEFAULT_QUERY_NAME
 
@@ -206,6 +209,9 @@ use constant GROUP_MEMBERSHIP => 0;
 use constant GROUP_BLESS => 1;
 use constant GROUP_VISIBLE => 2;
 
+use constant MAILTO_USER => 0;
+use constant MAILTO_GROUP => 1;
+
 # The default list of columns for buglist.cgi
 use constant DEFAULT_COLUMN_LIST => (
     "bug_severity", "priority", "rep_platform","assigned_to",
diff --git a/Bugzilla/Group.pm b/Bugzilla/Group.pm
new file mode 100644 (file)
index 0000000..2cb8e53
--- /dev/null
@@ -0,0 +1,51 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# The Initial Developer of the Original Code is Netscape Communications
+# Corporation. Portions created by Netscape are
+# Copyright (C) 1998 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s): Joel Peshkin <bugreport@peshkin.net>
+#                 Erik Stambaugh <erik@dasbistro.com>
+
+use strict;
+
+package Bugzilla::Group;
+
+use Bugzilla::Config;
+
+# ValidateGroupName checks to see if ANY of the users in the provided list 
+# of user objects can see the named group.  It returns the group id if
+# successful and undef otherwise.
+sub ValidateGroupName {
+    my ($name, @users) = (@_);
+    my $dbh = Bugzilla->dbh;
+    my $query = "SELECT id FROM groups " .
+                "WHERE name = ?";
+    if (Param('usevisibilitygroups')) {
+        my @visible = (-1);
+        foreach my $user (@users) {
+            $user && push @visible, @{$user->visible_groups_direct};
+        }
+        my $visible = join(', ', @visible);
+        $query .= " AND id IN($visible)";
+    }
+    my $sth = $dbh->prepare($query);
+    $sth->execute($name);
+    my ($ret) = $sth->fetchrow_array();
+    return $ret;
+}
+
+1;
index 816b4b0a19fac6d0103bc886befa9538ab32938d..e58278f483903373da9601cc47c9d0360a54b375 100644 (file)
@@ -40,6 +40,7 @@ use Bugzilla::Config;
 use Bugzilla::Error;
 use Bugzilla::Util;
 use Bugzilla::Constants;
+use Bugzilla::Group;
 
 use Date::Format;
 use Date::Parse;
@@ -382,7 +383,7 @@ sub init {
         (
          "^(?:assigned_to|reporter|qa_contact),(?:notequals|equals|anyexact),%group\\.(\\w+)%" => sub {
              my $group = $1;
-             my $groupid = ValidateGroupName( $group, ($user));
+             my $groupid = Bugzilla::Group::ValidateGroupName( $group, ($user));
              $groupid || ThrowUserError('invalid_group_name',{name => $group});
              my @childgroups = @{$user->flatten_group_membership($groupid)};
              my $table = "user_group_map_$chartid";
@@ -419,7 +420,7 @@ sub init {
 
          "^(?:cc),(?:notequals|equals|anyexact),%group\\.(\\w+)%" => sub {
              my $group = $1;
-             my $groupid = ValidateGroupName( $group, ($user));
+             my $groupid = Bugzilla::Group::ValidateGroupName( $group, ($user));
              $groupid || ThrowUserError('invalid_group_name',{name => $group});
              my @childgroups = @{$user->flatten_group_membership($groupid)};
              my $chartseq = $chartid;
@@ -1495,24 +1496,6 @@ sub pronoun {
     return 0;
 }
 
-# ValidateGroupName checks to see if ANY of the users in the provided list 
-# of user objects can see the named group.  It returns the group id if
-# successful and undef otherwise.
-sub ValidateGroupName {
-    my ($name, @users) = (@_);
-    my @visible = (-1);
-    foreach my $user (@users) {
-        $user && push @visible, @{$user->visible_groups_direct};
-    }
-    my $visible = join(', ', @visible);
-    my $dbh = Bugzilla->dbh;
-    my $sth = $dbh->prepare("SELECT id FROM groups " .
-                            "WHERE name = ? AND id IN($visible)");
-    $sth->execute($name);
-    my ($ret) = $sth->fetchrow_array();
-    return $ret;
-}
-
 # Validate that the query type is one we can deal with
 sub IsValidQueryType
 {
index 287b0baa6186ad95a3e1b83160e4b3b615490d7b..7404b59122e09fa17cb21fb7fb8099bac3869087 100755 (executable)
@@ -2108,7 +2108,8 @@ $table{whine_schedules} =
      run_day        varchar(32),
      run_time       varchar(32),
      run_next       datetime,
-     mailto_userid  mediumint       not null,
+     mailto         mediumint       not null,
+     mailto_type    smallint        not null default 0,
      
      index(run_next),
      index(eventid)';
@@ -4223,6 +4224,11 @@ AddField("profiles", "extern_id", "varchar(64)");
 AddField('flagtypes', 'grant_group_id', 'mediumint null');
 AddField('flagtypes', 'request_group_id', 'mediumint null');
 
+# 2004-01-03 - bug 253721 erik@dasbistro.com
+# mailto is no longer just userids
+RenameField('whine_schedules', 'mailto_userid', 'mailto');
+AddField('whine_schedules', 'mailto_type', 'smallint not null default 0');
+
 # 2005-01-29 - mkanat@kerio.com
 if (!GetFieldDef('longdescs', 'already_wrapped')) {
     AddField('longdescs', 'already_wrapped', 'tinyint not null default 0');
index f7362cb5fa2c4d8eac892c56bafe88378b8aa986..abef251f426e882aa8b4bcfa1c34f24662f77653 100755 (executable)
@@ -424,6 +424,9 @@ if ($action eq 'delete') {
         SendSQL("DELETE FROM group_group_map WHERE grantor_id = $gid");
         SendSQL("DELETE FROM bug_group_map WHERE group_id = $gid");
         SendSQL("DELETE FROM group_control_map WHERE group_id = $gid");
+        SendSQL("DELETE FROM whine_schedules WHERE " .
+                "mailto_type = " . MAILTO_GROUP . " " .
+                "AND mailto = $gid");
         SendSQL("DELETE FROM groups WHERE id = $gid");
     }
 
index 8c7c269e82b7bb4661bfc58586e761459a667085..b9808941a667a929900ddd388dfd353b13d71e95 100755 (executable)
@@ -35,6 +35,7 @@ use vars qw( $vars );
 
 use Bugzilla::Constants;
 use Bugzilla::User;
+use Bugzilla::Group;
 # require the user to have logged in
 Bugzilla->login(LOGIN_REQUIRED);
 
@@ -67,7 +68,8 @@ my $sth; # database statement handle
 #  'schedule' - array ref containing hashes of:
 #       'day' - Day or range of days this schedule will be run
 #       'time' - time or interval to run
-#       'mailto' - person who will receive the results
+#       'mailto_type' - MAILTO_USER or MAILTO_GROUP
+#       'mailto' - person/group who will receive the results
 #       'id' - row ID for the schedule
 my $events = get_events($userid);
 
@@ -158,10 +160,10 @@ if ($cgi->param('update')) {
                 if ($cgi->param("add_schedule_$eventid")) {
                     # the schedule table must be locked before altering
                     $sth = $dbh->prepare("INSERT INTO whine_schedules " .
-                                         "(eventid, mailto_userid, " .
+                                         "(eventid, mailto_type, mailto, " .
                                          "run_day, run_time) " .
-                                         "VALUES (?, ?, 'Sun', 2)");
-                    $sth->execute($eventid, $userid);
+                                         "VALUES (?, ?, ?, 'Sun', 2)");
+                    $sth->execute($eventid, MAILTO_USER, $userid);
                 }
                 # add a query
                 elsif ($cgi->param("add_query_$eventid")) {
@@ -181,17 +183,19 @@ if ($cgi->param('update')) {
                                  "WHERE eventid=?");
             $sth->execute($eventid);
             my @scheduleids = ();
-            for (@{$sth->fetchall_arrayref}) {
-                push @scheduleids, $_->[0];
-            };
+            while (my ($sid) = $sth->fetchrow_array) {
+                push @scheduleids, $sid;
+            }
 
             # we need to double-check all of the user IDs in mailto to make
             # sure they exist
             my $arglist = {};   # args for match_field
             for my $sid (@scheduleids) {
-                $arglist->{"mailto_$sid"} = {
-                    'type' => 'single',
-                };
+                if ($cgi->param("mailto_type_$sid") == MAILTO_USER) {
+                    $arglist->{"mailto_$sid"} = {
+                        'type' => 'single',
+                    };
+                }
             }
             if (scalar %{$arglist}) {
                 &Bugzilla::User::match_field($arglist);
@@ -217,30 +221,58 @@ if ($cgi->param('update')) {
                     }
                 }
                 else {
-                    my $o_day    = $cgi->param("orig_day_$sid");
-                    my $day      = $cgi->param("day_$sid");
-                    my $o_time   = $cgi->param("orig_time_$sid");
-                    my $time     = $cgi->param("time_$sid");
-                    my $o_mailto = $cgi->param("orig_mailto_$sid");
-                    my $mailto   = $cgi->param("mailto_$sid");
-
-                    $o_day    = '' unless length($o_day);
-                    $o_time   = '' unless length($o_time);
-                    $o_mailto = '' unless length($o_mailto);
-                    $day      = '' unless length($day);
-                    $time     = '' unless length($time);
-                    $mailto   = '' unless length($mailto);
-
-                    my $mail_uid = $userid;
-
-                    # get a userid for the mailto address
-                    if ($can_mail_others and $mailto) {
-                        trick_taint($mailto);
-                        $mail_uid = DBname_to_id($mailto);
+                    my $o_day         = $cgi->param("orig_day_$sid");
+                    my $day           = $cgi->param("day_$sid");
+                    my $o_time        = $cgi->param("orig_time_$sid");
+                    my $time          = $cgi->param("time_$sid");
+                    my $o_mailto      = $cgi->param("orig_mailto_$sid");
+                    my $mailto        = $cgi->param("mailto_$sid");
+                    my $o_mailto_type = lc $cgi->param("orig_mailto_type_$sid");
+                    my $mailto_type   = $cgi->param("mailto_type_$sid");
+
+                    $o_day         = '' unless length($o_day);
+                    $o_time        = '' unless length($o_time);
+                    $o_mailto      = '' unless length($o_mailto);
+                    $o_mailto_type = '' unless length($o_mailto_type);
+                    $day           = '' unless length($day);
+                    $time          = '' unless length($time);
+                    $mailto        = '' unless length($mailto);
+                    $mailto_type   = '' unless length($mailto_type);
+
+                    my $mailto_id = $userid;
+
+                    # get an id for the mailto address
+                    if ($can_mail_others && $mailto) {
+                        if ($mailto_type == MAILTO_USER) {
+                            # detaint
+                            my $emailregexp = Param('emailregexp');
+                            $mailto =~ /($emailregexp)/;
+                            $mailto =~ $1;
+                            $mailto_id = DBname_to_id($mailto);
+                        }
+                        elsif ($mailto_type == MAILTO_GROUP) {
+                            # detaint the group parameter
+                            $mailto =~ /^([0-9a-z_\-\.]+)/i;
+                            my $group = $1;
+
+                            $mailto_id = Bugzilla::Group::ValidateGroupName(
+                                $group, ($user));
+                            $mailto_id || ThrowUserError(
+                                'invalid_group_name', {name => $group});
+                        }
+                        else {
+                            # bad value, so it will just mail to the whine
+                            # owner.  $mailto_id was already set above.
+                            $mailto_type = MAILTO_USER;
+                        }
                     }
 
+                    detaint_natural($mailto_type);
+
                     if ( ($o_day  ne $day) ||
-                         ($o_time ne $time) ){
+                         ($o_time ne $time) ||
+                         ($o_mailto != $mailto) ||
+                         ($o_mailto_type != $mailto_type) ){
 
                         trick_taint($day) if length($day);
                         trick_taint($time) if length($time);
@@ -248,10 +280,11 @@ if ($cgi->param('update')) {
                         # the schedule table must be locked
                         $sth = $dbh->prepare("UPDATE whine_schedules " .
                                              "SET run_day=?, run_time=?, " .
-                                             "mailto_userid=?, " .
+                                             "mailto_type=?, mailto=?, " .
                                              "run_next=NULL " .
                                              "WHERE id=?");
-                        $sth->execute($day, $time, $mail_uid, $sid);
+                        $sth->execute($day, $time, $mailto_type,
+                                      $mailto_id, $sid);
                     }
                 }
             }
@@ -262,9 +295,9 @@ if ($cgi->param('update')) {
                                  "WHERE eventid=?");
             $sth->execute($eventid);
             my @queries = ();
-            for (@{$sth->fetchall_arrayref}) {
-                push @queries, $_->[0];
-            };
+            while (my ($qid) = $sth->fetchrow_array) {
+                push @queries, $qid;
+            }
 
             for my $qid (@queries) {
                 if ($cgi->param("remove_query_$qid")) {
@@ -365,19 +398,30 @@ for my $event_id (keys %{$events}) {
     $events->{$event_id}->{'queries'} = [];
 
     # schedules
-    $sth = $dbh->prepare("SELECT run_day, run_time, profiles.login_name, id " .
+    $sth = $dbh->prepare("SELECT run_day, run_time, mailto_type, mailto, id " .
                          "FROM whine_schedules " .
-                         "LEFT JOIN profiles " .
-                         "ON whine_schedules.mailto_userid = " .
-                         "profiles.userid " .
                          "WHERE eventid=?");
     $sth->execute($event_id);
     for my $row (@{$sth->fetchall_arrayref}) {
+        my $mailto_type = $row->[2];
+        my $mailto = '';
+        if ($mailto_type == MAILTO_USER) {
+            my $mailto_user = new Bugzilla::User($row->[3]);
+            $mailto = $mailto_user->login;
+        }
+        elsif ($mailto_type == MAILTO_GROUP) {
+            $sth = $dbh->prepare("SELECT name FROM groups WHERE id=?");
+            $sth->execute($row->[3]);
+            $mailto = $sth->fetch->[0];
+            $mailto = "" unless Bugzilla::Group::ValidateGroupName(
+                                $mailto, ($user));
+        }
         my $this_schedule = {
-            'day'    => $row->[0],
-            'time'   => $row->[1],
-            'mailto' => $row->[2],
-            'id'     => $row->[3],
+            'day'         => $row->[0],
+            'time'        => $row->[1],
+            'mailto_type' => $mailto_type,
+            'mailto'      => $mailto,
+            'id'          => $row->[4],
         };
         push @{$events->{$event_id}->{'schedule'}}, $this_schedule;
     }
@@ -408,8 +452,8 @@ $sth = $dbh->prepare("SELECT name FROM namedqueries WHERE userid=?");
 $sth->execute($userid);
 
 $vars->{'available_queries'} = [];
-while (my $query = $sth->fetch) {
-    push @{$vars->{'available_queries'}}, $query->[0];
+while (my ($query) = $sth->fetchrow_array) {
+    push @{$vars->{'available_queries'}}, $query;
 }
 
 $template->process("whine/schedule.html.tmpl", $vars)
@@ -425,11 +469,11 @@ sub get_events {
                             "FROM whine_events " .
                             "WHERE owner_userid=?");
     $sth->execute($userid);
-    for (@{$sth->fetchall_arrayref}) {
-        $events->{$_->[0]} = {
-            'subject' => $_->[1],
-            'body'    => $_->[2],
-        }
+    while (my ($ev, $sub, $bod) = $sth->fetchrow_array) {
+        $events->{$ev} = {
+            'subject' => $sub,
+            'body' => $bod,
+        };
     }
     return $events;
 }
index 60c0f3cd8d9af8c50922af5d30f74fddf4d33c5a..f227987d62a20f306ddf91f7a005ca7e720ffb99 100644 (file)
@@ -25,7 +25,8 @@
   #     schedule: array of hashes containing schedule info:
   #         day:    value in day column
   #         time:   value selected in time column
-  #         mailto: recipient's email address
+  #         mailto_type: 0=user 1=group
+  #         mailto: recipient's id (profile or group)
   #     queries:  as with schedule, an anonymous array containing hashes of:
   #         name:  the named query's name
   #         title: title to be displayed on the results
               </td>
               <td align="left">
                 [% IF mail_others %]
+                  <input type="hidden" name="orig_mailto_type_[% schedule.id %]"
+                         value="[% schedule.mailto_type FILTER html %]">
+                  <select name="mailto_type_[% schedule.id %]">
+                    <option value="0" [% IF schedule.mailto_type == 0 %]
+                                        selected
+                                      [% END %]>User</option>
+                    <option value="1" [% IF schedule.mailto_type == 1 %]
+                                        selected
+                                      [% END %]>Group</option>
+                  </select>
                   <input type="hidden" name="orig_mailto_[% schedule.id %]"
                          value="[% schedule.mailto FILTER html %]">
                   <input type="text" name="mailto_[% schedule.id %]"
index d3584db681ab19afed1302af2a32c514b4ac4f87..997e4a58a98c1dec46d6282d1b07e96c76ec3886 100755 (executable)
--- a/whine.pl
+++ b/whine.pl
@@ -75,7 +75,7 @@ my $sth_next_scheduled_event = $dbh->prepare(
 
 # get all pending schedules matching an eventid
 my $sth_schedules_by_event = $dbh->prepare(
-    "SELECT id, mailto_userid " .
+    "SELECT id, mailto_type, mailto " .
     "FROM whine_schedules " .
     "WHERE eventid=? AND run_next <= NOW()"
 );
@@ -245,18 +245,42 @@ sub get_next_event {
 
         # Add the users from those schedules to the list
         while (my $row = $sth_schedules_by_event->fetch) {
-            my ($sid, $mailto) = @{$row};
+            my ($sid, $mailto_type, $mailto) = @{$row};
 
             # Only bother doing any work if this user has whine permission
             if ($owner->in_group('bz_canusewhines')) {
-                if (not defined $user_objects{$mailto}) {
-                    if ($mailto == $owner_id) {
-                        $user_objects{$mailto} = $owner;
+
+                if ($mailto_type == MAILTO_USER) {
+                    if (not defined $user_objects{$mailto}) {
+                        if ($mailto == $owner_id) {
+                            $user_objects{$mailto} = $owner;
+                        }
+                        elsif ($whineatothers) {
+                            $user_objects{$mailto} = Bugzilla::User->new($mailto);
+                        }
                     }
-                    elsif ($whineatothers) {
-                        $user_objects{$mailto} = Bugzilla::User->new($mailto);
+                }
+                elsif ($mailto_type == MAILTO_GROUP) {
+                    my $sth = $dbh->prepare("SELECT name FROM groups " .
+                                            "WHERE id=?");
+                    $sth->execute($mailto);
+                    my $groupname = $sth->fetch->[0];
+                    my $group_id = Bugzilla::Group::ValidateGroupName(
+                        $groupname, $owner);
+                    if ($group_id) {
+                        $sth = $dbh->prepare("SELECT user_id FROM " .
+                                             "user_group_map " .
+                                             "WHERE group_id=?");
+                        $sth->execute($group_id);
+                        for my $row (@{$sth->fetchall_arrayref}) {
+                            if (not defined $user_objects{$row->[0]}) {
+                                $user_objects{$row->[0]} =
+                                    Bugzilla::User->new($row->[0]);
+                            }
+                        }
                     }
                 }
+
             }
 
             reset_timer($sid);