# directly or due to regexp and which groups can be blessed
# by a user.
#
-# isderived:
-# if 0 - record was explicitly granted
-# if 1 - record was created by evaluating a regexp or group hierarchy
+# grant_type:
+# if GRANT_DIRECT - record was explicitly granted
+# if GRANT_DERIVED - record was derived from expanding a group hierarchy
+# if GRANT_REGEXP - record was created by evaluating a regexp
$table{user_group_map} =
'user_id mediumint not null,
group_id mediumint not null,
isbless tinyint not null default 0,
- isderived tinyint not null default 0,
+ grant_type tinyint not null default 0,
- unique(user_id, group_id, isderived, isbless)';
+ unique(user_id, group_id, grant_type, isbless)';
$table{group_group_map} =
'member_id mediumint not null,
$sth3->execute();
if ( !$sth3->fetchrow_array() ) {
$dbh->do("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES($uid, $gid, 0, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES($uid, $gid, 0, " . GRANT_DIRECT . ")");
}
}
# Create user can bless group grants for old groupsets.
$sth2->execute();
while (my ($uid) = $sth2->fetchrow_array) {
$dbh->do("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES($uid, $gid, 1, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES($uid, $gid, 1, " . GRANT_DIRECT . ")");
}
# Create bug_group_map records for old groupsets.
# Get each bug with the old group bit set.
AddFDef("owner_idle_time", "Time Since Owner Touched", 0);
+# 2004-04-12 - Keep regexp-based group permissions up-to-date - Bug 240325
+if (GetFieldDef("user_group_map", "isderived")) {
+ AddField('user_group_map', 'grant_type', 'tinyint not null default 0');
+ $dbh->do("UPDATE user_group_map SET grant_type = " .
+ "IF(isderived, " . GRANT_DERIVED . ", " .
+ GRANT_DIRECT . ")");
+ $dbh->do("DELETE FROM user_group_map
+ WHERE isbless = 0 AND grant_type != " . GRANT_DIRECT);
+ DropField("user_group_map", "isderived");
+ DropIndexes("user_group_map");
+ $dbh->do("ALTER TABLE user_group_map
+ ADD UNIQUE (user_id, group_id, grant_type, isbless)");
+ # Evaluate regexp-based group memberships
+ my $sth = $dbh->prepare("SELECT profiles.userid, profiles.login_name,
+ groups.id, groups.userregexp
+ FROM profiles, groups
+ WHERE userregexp != ''");
+ $sth->execute();
+ my $sth2 = $dbh->prepare("INSERT IGNORE INTO user_group_map
+ (user_id, group_id, isbless, grant_type)
+ VALUES(?, ?, 0, " . GRANT_REGEXP . ")");
+ while (my ($uid, $login, $gid, $rexp) = $sth->fetchrow_array()) {
+ if ($login =~ m/$rexp/i) {
+ $sth2->execute($uid, $gid);
+ }
+ }
+}
+
+
+
# If you had to change the --TABLE-- definition in any way, then add your
# differential change code *** A B O V E *** this comment.
#
$sth->execute();
while (my ($userid) = $sth->fetchrow_array()) {
$dbh->do("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES ($userid, $id, 0, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES ($userid, $id, 0, " . GRANT_DIRECT . ")");
}
}
$sth->execute();
while (my ($userid) = $sth->fetchrow_array()) {
$dbh->do("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES ($userid, $id, 0, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES ($userid, $id, 0, " . GRANT_DIRECT . ")");
}
}
my ($adminid) = $sth->fetchrow_array();
foreach my $userid (@admins) {
$dbh->do("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES ($userid, $adminid, 0, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES ($userid, $adminid, 0, " . GRANT_DIRECT . ")");
# Existing administrators are made blessers of group "admin"
# but only explitly defined blessers can bless group admin.
# Other groups can be blessed by any admin (by default) or additional
# defined blessers.
$dbh->do("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES ($userid, $adminid, 1, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES ($userid, $adminid, 1, " . GRANT_DIRECT . ")");
}
$sth = $dbh->prepare("SELECT id FROM groups");
$sth->execute();
$sth->execute();
if ( !$sth->fetchrow_array() ) {
$dbh->do("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES ($userid, $group, 0, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES ($userid, $group, 0, " . GRANT_DIRECT . ")");
}
}
# the admin also gets an explicit bless capability for the admin group
$sth->execute();
my ($id) = $sth->fetchrow_array();
$dbh->do("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES ($userid, $id, 1, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES ($userid, $id, 1, " . GRANT_DIRECT . ")");
foreach my $group ( @groups ) {
$dbh->do("INSERT INTO group_group_map
(member_id, grantor_id, isbless)
ChangeFieldType('bugs', 'short_desc', 'mediumtext not null');
}
+# 2004-04-12 - Keep regexp-based group permissions up-to-date - Bug 240325
+# Make sure groups get rederived
+$dbh->do("UPDATE groups SET last_changed = NOW() WHERE name = 'admin'");
+
+
#
# Final checks...
my $action = trim($::FORM{action} || '');
+# RederiveRegexp: update user_group_map with regexp-based grants
+sub RederiveRegexp ($$)
+{
+ my $regexp = shift;
+ my $gid = shift;
+ my $dbh = Bugzilla->dbh;
+ my $sth = $dbh->prepare("SELECT userid, login_name FROM profiles");
+ my $sthadd = $dbh->prepare("INSERT IGNORE INTO user_group_map
+ (user_id, group_id, grant_type, isbless)
+ VALUES (?, ?, ?, 0)");
+ my $sthdel = $dbh->prepare("DELETE FROM user_group_map
+ WHERE user_id = ? AND group_id = ?
+ AND grant_type = ? and isbless = 0");
+ $sth->execute();
+ while (my ($uid, $login) = $sth->fetchrow_array()) {
+ if ($login =~ m/$regexp/i)
+ {
+ $sthadd->execute($uid, $gid, GRANT_REGEXP);
+ } else {
+ $sthdel->execute($uid, $gid, GRANT_REGEXP);
+ }
+ }
+}
+
# TestGroup: check if the group name exists
sub TestGroup ($)
{
CONTROLMAPNA . ", 0 " .
"FROM products");
}
+ RederiveRegexp($regexp, $gid);
print "OK, done.<p>\n";
PutTrailer("<a href=\"editgroups.cgi?action=add\">add</a> another group",
"back to the <a href=\"editgroups.cgi\">group list</a>");
FROM user_group_map, profiles
WHERE user_group_map.user_id = profiles.userid
AND user_group_map.group_id = ?
- AND isderived = 0
+ AND grant_type = ?
AND isbless = 0");
- $sth->execute($gid);
+ $sth->execute($gid, GRANT_DIRECT);
my $sth2 = $dbh->prepare("DELETE FROM user_group_map
WHERE user_id = ?
AND isbless = 0
}
SendSQL("UPDATE groups SET userregexp = " .
SqlQuote($::FORM{"rexp"}) . " WHERE id = $gid");
+ RederiveRegexp($::FORM{"rexp"}, $gid);
}
if (($isbuggroup == 1) && ($::FORM{"oldisactive"} ne $::FORM{"isactive"})) {
$chgs = 1;
if($user ne "") {
print "</TR><TR><TH VALIGN=TOP ALIGN=RIGHT>Group Access:</TH><TD><TABLE><TR>";
SendSQL("SELECT groups.id, groups.name, groups.description, " .
- "COUNT(user_id), " .
- "MAX(isderived) " .
+ "MAX(grant_type = " . GRANT_DIRECT . "), " .
+ "MAX(grant_type = " . GRANT_DERIVED . "), " .
+ "MAX(grant_type = " . GRANT_REGEXP . ") " .
"FROM groups " .
"LEFT JOIN user_group_map " .
"ON user_group_map.group_id = groups.id " .
}
print "<TD COLSPAN=2 ALIGN=LEFT><B>User is a member of these groups</B></TD>\n";
while (MoreSQLData()) {
- my ($groupid, $name, $description, $member, $isderived) = FetchSQLData();
+ my ($groupid, $name, $description, $checked, $isderived, $isregexp) = FetchSQLData();
next if (!$editall && !UserCanBlessGroup($name));
- $isderived = $isderived || 0;
- my $checked = $member - $isderived;
PushGlobalSQLState();
SendSQL("SELECT user_id " .
"FROM user_group_map " .
my $derivedbless = FetchOneColumn();
PopGlobalSQLState();
print "</TR><TR";
- print ' bgcolor=#cccccc' if ($isderived);
+ print ' bgcolor=#cccccc' if ($isderived || $isregexp);
print ">\n";
print "<INPUT TYPE=HIDDEN NAME=\"oldgroup_$groupid\" VALUE=\"$checked\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"oldbless_$groupid\" VALUE=\"$blchecked\">\n";
$checked = ($checked) ? "CHECKED" : "";
print "<TD ALIGN=CENTER>";
print '[' if ($isderived);
+ print '*' if ($isregexp);
print "<INPUT TYPE=CHECKBOX NAME=\"group_$groupid\" $checked VALUE=\"$groupid\">";
print ']' if ($isderived);
+ print '*' if ($isregexp);
print "</TD><TD><B>";
print ucfirst($name) . "</B>: $description</TD>\n";
}
value_quote($disabledtext) . "\">\n";
print "<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"update\">\n";
print "<INPUT TYPE=SUBMIT VALUE=\"Update\">\n";
- print "<BR>User is a member of any groups shown with grey bars and
- marked with brackets surrounding the membership checkbox as a
- result of a regular expression match
- or membership in another group.
- User can bless any group
- marked with brackets surrounding the bless checkbox as a
- result of membership in another group.
+ print "<BR>User is a member of any groups shown with a check or grey bar.
+ A grey bar indicates indirect membership, either derived from other
+ groups (marked with square brackets) or via regular expression
+ (marked with '*').<p>
+ Square brackets around the bless checkbox indicate the ability
+ to bless users (grant them membership in the group) as a result
+ of membership in another group.
<BR>";
print "</FORM>";
WHERE user_id = $thisuserid
AND group_id = $groupid
AND isbless = 0
- AND isderived = 0");
+ AND grant_type = " . GRANT_DIRECT);
if ($::FORM{"group_$groupid"}) {
SendSQL("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES ($thisuserid, $groupid, 0, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES ($thisuserid, $groupid, 0," . GRANT_DIRECT . ")");
print "Added user to group $name<BR>\n";
push(@grpadd, $name);
} else {
WHERE user_id = $thisuserid
AND group_id = $groupid
AND isbless = 1
- AND isderived = 0");
+ AND grant_type = " . GRANT_DIRECT);
if ($::FORM{"bless_$groupid"}) {
SendSQL("INSERT INTO user_group_map
- (user_id, group_id, isbless, isderived)
- VALUES ($thisuserid, $groupid, 1, 0)");
+ (user_id, group_id, isbless, grant_type)
+ VALUES ($thisuserid, $groupid, 1," . GRANT_DIRECT . ")");
print "Granted user permission to bless group $name<BR>\n";
} else {
print "Revoked user's permission to bless group $name<BR>\n";