Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
bugzilla
Commits
f0c76112
Commit
f0c76112
authored
Jul 14, 2006
by
wurblzap%gmail.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 69000: Permit a stored query to be marked "shared" and accessible by other users.
Patch by Marc Schumann <wurblzap@gmail.com>, r=vladd, a=myk
parent
09495a11
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
528 additions
and
72 deletions
+528
-72
GroupSecurity.pm
Bugzilla/Config/GroupSecurity.pm
+8
-0
Schema.pm
Bugzilla/DB/Schema.pm
+28
-1
User.pm
Bugzilla/User.pm
+64
-17
buglist.cgi
buglist.cgi
+71
-18
checksetup.pl
checksetup.pl
+16
-2
using.xml
docs/xml/using.xml
+14
-2
editgroups.cgi
editgroups.cgi
+9
-0
editusers.cgi
editusers.cgi
+26
-3
sanitycheck.cgi
sanitycheck.cgi
+7
-0
global.css
skins/standard/global.css
+0
-5
saved-searches.html.tmpl
template/en/default/account/prefs/saved-searches.html.tmpl
+86
-2
delete.html.tmpl
template/en/default/admin/groups/delete.html.tmpl
+20
-0
groupsecurity.html.tmpl
template/en/default/admin/params/groupsecurity.html.tmpl
+3
-0
confirm-delete.html.tmpl
template/en/default/admin/users/confirm-delete.html.tmpl
+26
-7
filterexceptions.pl
template/en/default/filterexceptions.pl
+8
-1
useful-links.html.tmpl
template/en/default/global/useful-links.html.tmpl
+20
-2
user-error.html.tmpl
template/en/default/global/user-error.html.tmpl
+8
-2
userprefs.cgi
userprefs.cgi
+114
-10
No files found.
Bugzilla/Config/GroupSecurity.pm
View file @
f0c76112
...
...
@@ -79,6 +79,14 @@ sub get_param_list {
},
{
name
=>
'querysharegroup'
,
type
=>
's'
,
choices
=>
\&
_get_all_group_names
,
default
=>
'editbugs'
,
checker
=>
\&
check_group
},
{
name
=>
'usevisibilitygroups'
,
type
=>
'b'
,
default
=>
0
...
...
Bugzilla/DB/Schema.pm
View file @
f0c76112
...
...
@@ -666,9 +666,10 @@ use constant ABSTRACT_SCHEMA => {
namedqueries
=>
{
FIELDS
=>
[
id
=>
{
TYPE
=>
'MEDIUMSERIAL'
,
NOTNULL
=>
1
,
PRIMARYKEY
=>
1
},
userid
=>
{
TYPE
=>
'INT3'
,
NOTNULL
=>
1
},
name
=>
{
TYPE
=>
'varchar(64)'
,
NOTNULL
=>
1
},
linkinfooter
=>
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
},
query
=>
{
TYPE
=>
'MEDIUMTEXT'
,
NOTNULL
=>
1
},
query_type
=>
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
},
],
...
...
@@ -678,6 +679,18 @@ use constant ABSTRACT_SCHEMA => {
],
},
namedqueries_link_in_footer
=>
{
FIELDS
=>
[
namedquery_id
=>
{
TYPE
=>
'INT3'
,
NOTNULL
=>
1
},
user_id
=>
{
TYPE
=>
'INT3'
,
NOTNULL
=>
1
},
],
INDEXES
=>
[
namedqueries_link_in_footer_id_idx
=>
{
FIELDS
=>
[
qw(namedquery_id user_id)
],
TYPE
=>
'UNIQUE'
},
namedqueries_link_in_footer_userid_idx
=>
[
'user_id'
],
],
},
# Authentication
# --------------
...
...
@@ -806,6 +819,20 @@ use constant ABSTRACT_SCHEMA => {
],
},
# This table determines which groups a user must be a member of
# in order to see a named query somebody else shares.
namedquery_group_map
=>
{
FIELDS
=>
[
namedquery_id
=>
{
TYPE
=>
'INT3'
,
NOTNULL
=>
1
},
group_id
=>
{
TYPE
=>
'INT3'
,
NOTNULL
=>
1
},
],
INDEXES
=>
[
namedquery_group_map_namedquery_id_idx
=>
{
FIELDS
=>
[
qw(namedquery_id)
],
TYPE
=>
'UNIQUE'
},
namedquery_group_map_group_id_idx
=>
[
'group_id'
],
],
},
category_group_map
=>
{
FIELDS
=>
[
category_id
=>
{
TYPE
=>
'INT2'
,
NOTNULL
=>
1
},
...
...
Bugzilla/User.pm
View file @
f0c76112
...
...
@@ -204,25 +204,46 @@ sub queries {
return
[]
unless
$self
->
id
;
my
$dbh
=
Bugzilla
->
dbh
;
my
$used_in_whine_ref
=
$dbh
->
select
col_arrayref
(
q{
my
$used_in_whine_ref
=
$dbh
->
select
all_hashref
(
'
SELECT DISTINCT query_name
FROM whine_events we
INNER JOIN whine_queries wq
ON we.id = wq.eventid
WHERE we.owner_userid = ?}
,
undef
,
$self
->
{
id
});
WHERE we.owner_userid = ?'
,
'query_name'
,
undef
,
$self
->
id
);
# If the user is in any group, there may be shared queries to be included.
my
$or_nqgm_group_id_in_usergroups
=
''
;
if
(
$self
->
groups_as_string
)
{
$or_nqgm_group_id_in_usergroups
=
'OR MAX(nqgm.group_id) IN ('
.
$self
->
groups_as_string
.
') '
;
}
my
$queries_ref
=
$dbh
->
selectall_arrayref
(
'
SELECT nq.id, MAX(userid) AS userid, name, query, query_type,
MAX(nqgm.group_id) AS shared_with_group,
COUNT(nql.namedquery_id) AS link_in_footer
FROM namedqueries AS nq
LEFT JOIN namedquery_group_map nqgm
ON nqgm.namedquery_id = nq.id
LEFT JOIN namedqueries_link_in_footer AS nql
ON nql.namedquery_id = nq.id
AND nql.user_id = ? '
.
$dbh
->
sql_group_by
(
'nq.id'
,
'name, query, query_type'
)
.
' HAVING MAX(nq.userid) = ? '
.
$or_nqgm_group_id_in_usergroups
.
' ORDER BY UPPER(name)'
,
{
'Slice'
=>
{}},
$self
->
id
,
$self
->
id
);
my
$queries_ref
=
$dbh
->
selectall_arrayref
(
q{
SELECT name, query, linkinfooter, query_type
FROM namedqueries
WHERE userid = ?
ORDER BY UPPER(name)}
,{
'Slice'
=>
{}},
$self
->
{
id
});
foreach
my
$name
(
@$used_in_whine_ref
)
{
foreach
my
$queries_hash
(
@$queries_ref
)
{
if
(
$queries_hash
->
{
name
}
eq
$name
)
{
$queries_hash
->
{
usedinwhine
}
=
1
;
last
;
# For each query, determine whether it's being used in a whine.
if
(
exists
(
$$used_in_whine_ref
{
$queries_hash
->
{
'name'
}}))
{
$queries_hash
->
{
'usedinwhine'
}
=
1
;
}
# For shared queries, provide the sharer's user object.
if
(
$queries_hash
->
{
'userid'
}
!=
$self
->
id
)
{
$queries_hash
->
{
'user'
}
=
new
Bugzilla::
User
(
$queries_hash
->
{
'userid'
});
}
}
$self
->
{
queries
}
=
$queries_ref
;
...
...
@@ -660,6 +681,24 @@ sub visible_groups_as_string {
return
join
(
', '
,
@
{
$self
->
visible_groups_inherited
()});
}
# This function defines the groups a user may share a query with.
# More restrictive sites may want to build this reference to a list of group IDs
# from bless_groups instead of mirroring visible_groups_inherited, perhaps.
sub
queryshare_groups
{
my
$self
=
shift
;
if
(
$self
->
in_group
(
Bugzilla
->
params
->
{
'querysharegroup'
}))
{
return
$self
->
visible_groups_inherited
();
}
else
{
return
[]
;
}
}
sub
queryshare_groups_as_string
{
my
$self
=
shift
;
return
join
(
', '
,
@
{
$self
->
queryshare_groups
()});
}
sub
derive_regexp_groups
{
my
(
$self
)
=
@_
;
...
...
@@ -734,8 +773,8 @@ sub can_bless {
}
# Otherwise, we're checking a specific group
my
$group_
name
=
shift
;
return
(
grep
{
$$_
{
'
name'
}
eq
$group_name
}
(
@
{
$self
->
bless_groups
}))
?
1
:
0
;
my
$group_
id
=
shift
;
return
(
grep
{
$$_
{
'
id'
}
eq
$group_id
}
(
@
{
$self
->
bless_groups
}))
?
1
:
0
;
}
sub
flatten_group_membership
{
...
...
@@ -1576,12 +1615,20 @@ Should only be called by C<Bugzilla::Auth::login>, for the most part.
=item C<queries>
Returns an array of the user's named queries, sorted in a case-insensitive
order by name. Each entry is a hash with
thre
e keys:
order by name. Each entry is a hash with
fiv
e keys:
=over
=item *
id - The ID of the query
=item *
userid - The query owner's user ID
=item *
name - The name of the query
=item *
...
...
@@ -1590,7 +1637,7 @@ query - The text for the query
=item *
link
in
footer - Whether or not the query should be displayed in the footer.
link
_in_
footer - Whether or not the query should be displayed in the footer.
=back
...
...
@@ -1783,7 +1830,7 @@ When called with no arguments:
Returns C<1> if the user can bless at least one group, returns C<0> otherwise.
When called with one argument:
Returns C<1> if the user can bless the group with that
name
, returns
Returns C<1> if the user can bless the group with that
id
, returns
C<0> otherwise.
=item C<wants_bug_mail>
...
...
buglist.cgi
View file @
f0c76112
...
...
@@ -203,18 +203,42 @@ sub DiffDate {
}
sub
LookupNamedQuery
{
my
(
$name
)
=
@_
;
my
(
$name
,
$sharer_id
)
=
@_
;
my
$user
=
Bugzilla
->
login
(
LOGIN_REQUIRED
);
my
$dbh
=
Bugzilla
->
dbh
;
# $name is safe -- we only use it below in a SELECT placeholder and then
# in error messages (which are always HTML-filtered).
my
$owner_id
;
# $name and $sharer_id are safe -- we only use them below in SELECT
# placeholders and then in error messages (which are always HTML-filtered).
$name
||
ThrowUserError
(
"query_name_missing"
);
trick_taint
(
$name
);
my
$result
=
$dbh
->
selectrow_array
(
"SELECT query FROM namedqueries"
.
" WHERE userid = ? AND name = ?"
,
undef
,
(
$user
->
id
,
$name
));
if
(
$sharer_id
)
{
trick_taint
(
$sharer_id
);
$owner_id
=
$sharer_id
;
}
else
{
$owner_id
=
$user
->
id
;
}
my
(
$id
,
$result
)
=
$dbh
->
selectrow_array
(
'SELECT id, query
FROM namedqueries
WHERE userid = ? AND name = ?'
,
undef
,
(
$owner_id
,
$name
));
defined
(
$result
)
||
ThrowUserError
(
"missing_query"
,
{
'queryname'
=>
$name
,
'sharer_id'
=>
$sharer_id
});
if
(
$sharer_id
)
{
my
$group
=
$dbh
->
selectrow_array
(
'SELECT group_id
FROM namedquery_group_map
WHERE namedquery_id = ?'
,
undef
,
$id
);
if
(
!
grep
{
$_
==
$group
}
values
(
%
{
$user
->
groups
()}))
{
ThrowUserError
(
"missing_query"
,
{
'queryname'
=>
$name
,
'sharer_id'
=>
$sharer_id
});
}
}
defined
(
$result
)
||
ThrowUserError
(
"missing_query"
,
{
'queryname'
=>
$name
});
$result
||
ThrowUserError
(
"buglist_parameters_required"
,
{
'queryname'
=>
$name
});
...
...
@@ -265,7 +289,8 @@ sub InsertNamedQuery {
# it when we display it to the user.
trick_taint
(
$query
);
$dbh
->
bz_lock_tables
(
'namedqueries WRITE'
);
$dbh
->
bz_lock_tables
(
'namedqueries WRITE'
,
'namedqueries_link_in_footer WRITE'
);
my
$result
=
$dbh
->
selectrow_array
(
"SELECT userid FROM namedqueries"
.
" WHERE userid = ? AND name = ?"
...
...
@@ -273,15 +298,22 @@ sub InsertNamedQuery {
if
(
$result
)
{
$query_existed_before
=
1
;
$dbh
->
do
(
"UPDATE namedqueries"
.
" SET query = ?,
linkinfooter = ?,
query_type = ?"
.
" SET query = ?, query_type = ?"
.
" WHERE userid = ? AND name = ?"
,
undef
,
(
$query
,
$
link_in_footer
,
$
query_type
,
$userid
,
$query_name
));
,
undef
,
(
$query
,
$query_type
,
$userid
,
$query_name
));
}
else
{
$query_existed_before
=
0
;
$dbh
->
do
(
"INSERT INTO namedqueries"
.
" (userid, name, query, linkinfooter, query_type)"
.
" VALUES (?, ?, ?, ?, ?)"
,
undef
,
(
$userid
,
$query_name
,
$query
,
$link_in_footer
,
$query_type
));
.
" (userid, name, query, query_type)"
.
" VALUES (?, ?, ?, ?)"
,
undef
,
(
$userid
,
$query_name
,
$query
,
$query_type
));
if
(
$link_in_footer
)
{
$dbh
->
do
(
'INSERT INTO namedqueries_link_in_footer
(namedquery_id, user_id)
VALUES (?, ?)'
,
undef
,
(
$dbh
->
bz_last_key
(
'namedqueries'
,
'id'
),
$userid
));
}
}
$dbh
->
bz_unlock_tables
();
...
...
@@ -373,9 +405,15 @@ if ($cgi->param('cmdtype') eq "dorem" && $cgi->param('remaction') =~ /^run/) {
# Take appropriate action based on user's request.
if
(
$cgi
->
param
(
'cmdtype'
)
eq
"dorem"
)
{
if
(
$cgi
->
param
(
'remaction'
)
eq
"run"
)
{
$buffer
=
LookupNamedQuery
(
scalar
$cgi
->
param
(
"namedcmd"
));
$buffer
=
LookupNamedQuery
(
scalar
$cgi
->
param
(
"namedcmd"
),
scalar
$cgi
->
param
(
'sharer_id'
));
# If this is the user's own query, remember information about it
# so that it can be modified easily.
if
(
!
$cgi
->
param
(
'sharer_id'
)
||
$cgi
->
param
(
'sharer_id'
)
==
Bugzilla
->
user
->
id
)
{
$vars
->
{
'searchname'
}
=
$cgi
->
param
(
'namedcmd'
);
$vars
->
{
'searchtype'
}
=
"saved"
;
}
$params
=
new
Bugzilla::
CGI
(
$buffer
);
$order
=
$params
->
param
(
'order'
)
||
$order
;
...
...
@@ -415,9 +453,24 @@ if ($cgi->param('cmdtype') eq "dorem") {
}
# If we are here, then we can safely remove the saved search
$dbh
->
do
(
"DELETE FROM namedqueries"
.
" WHERE userid = ? AND name = ?"
,
undef
,
(
$user
->
id
,
$qname
));
my
(
$query_id
)
=
$dbh
->
selectrow_array
(
'SELECT id FROM namedqueries
WHERE userid = ?
AND name = ?'
,
undef
,
(
$user
->
id
,
$qname
));
if
(
!
$query_id
)
{
# The user has no query of this name. Play along.
}
else
{
$dbh
->
do
(
'DELETE FROM namedqueries
WHERE id = ?'
,
undef
,
$query_id
);
$dbh
->
do
(
'DELETE FROM namedqueries_link_in_footer
WHERE namedquery_id = ?'
,
undef
,
$query_id
);
$dbh
->
do
(
'DELETE FROM namedquery_group_map
WHERE namedquery_id = ?'
,
undef
,
$query_id
);
}
# Now reset the cached queries
$user
->
flush_queries_cache
();
...
...
@@ -425,7 +478,7 @@ if ($cgi->param('cmdtype') eq "dorem") {
print
$cgi
->
header
();
# Generate and return the UI (HTML page) from the appropriate template.
$vars
->
{
'message'
}
=
"buglist_query_gone"
;
$vars
->
{
'namedcmd'
}
=
$
cgi
->
param
(
'namedcmd'
)
;
$vars
->
{
'namedcmd'
}
=
$
qname
;
$vars
->
{
'url'
}
=
"query.cgi"
;
$template
->
process
(
"global/message.html.tmpl"
,
$vars
)
||
ThrowTemplateError
(
$template
->
error
());
...
...
checksetup.pl
View file @
f0c76112
...
...
@@ -2319,8 +2319,6 @@ if (!$dbh->bz_index_info('profiles', 'profiles_login_name_idx') ||
$dbh
->
bz_add_column
(
'profiles'
,
'mybugslink'
,
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
,
DEFAULT
=>
'TRUE'
});
$dbh
->
bz_add_column
(
'namedqueries'
,
'linkinfooter'
,
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
},
0
);
my
$comp_init_owner
=
$dbh
->
bz_column_info
(
'components'
,
'initialowner'
);
if
(
$comp_init_owner
&&
$comp_init_owner
->
{
TYPE
}
eq
'TINYTEXT'
)
{
...
...
@@ -4369,6 +4367,22 @@ if (-e "$datadir/versioncache") {
unlink
"$datadir/versioncache"
;
}
# 2006-07-01 wurblzap@gmail.com -- Bug 69000
$dbh
->
bz_add_column
(
'namedqueries'
,
'id'
,
{
TYPE
=>
'MEDIUMSERIAL'
,
NOTNULL
=>
1
,
PRIMARYKEY
=>
1
});
if
(
$dbh
->
bz_column_info
(
"namedqueries"
,
"linkinfooter"
))
{
# Move link-in-footer information into a table of its own.
my
$sth_read
=
$dbh
->
prepare
(
'SELECT id, userid
FROM namedqueries
WHERE linkinfooter = 1'
);
my
$sth_write
=
$dbh
->
prepare
(
'INSERT INTO namedqueries_link_in_footer
(namedquery_id, user_id) VALUES (?, ?)'
);
$sth_read
->
execute
();
while
(
my
(
$id
,
$userid
)
=
$sth_read
->
fetchrow_array
())
{
$sth_write
->
execute
(
$id
,
$userid
);
}
$dbh
->
bz_drop_column
(
"namedqueries"
,
"linkinfooter"
);
}
# If you had to change the --TABLE-- definition in any way, then add your
# differential change code *** A B O V E *** this comment.
...
...
docs/xml/using.xml
View file @
f0c76112
...
...
@@ -345,8 +345,20 @@
returns bugs where the content of the field matches any one of the selected
values. If none is selected, then the field can take any value.
</para>
<para>
Once you've run a search, you can save it as a Saved Search, which
appears in the page footer.
</para>
<para>
Once you've run a search, you can save it as a Saved Search, which
appears in the page footer.
On the Saved Searches tab of your User Preferences page (the Prefs link
in Bugzilla's footer), members of the group defined in the
querysharegroup parameter can share such Saved Searches with user groups
so that other users may use them.
At the same place, you can see Saved Searches other users are sharing, and
have them show up in your personal Bugzilla footer along with your own
Saved Searches.
If somebody is sharing a Search with a group she or he is allowed to
<xref
linkend=
"groups"
>
assign users to
</a>
, it will show up in the
group's direct members' footers by default.
</para>
<section
id=
"boolean"
>
<title>
Boolean Charts
</title>
...
...
editgroups.cgi
View file @
f0c76112
...
...
@@ -358,6 +358,12 @@ if ($action eq 'del') {
WHERE group_id IN ($grouplist) AND isbless = 0 "
.
$dbh
->
sql_limit
(
1
))
||
0
;
my
(
$shared_queries
)
=
$dbh
->
selectrow_array
(
'SELECT COUNT(*)
FROM namedquery_group_map
WHERE group_id = ?'
,
undef
,
$gid
);
my
$bug_ids
=
$dbh
->
selectcol_arrayref
(
'SELECT bug_id FROM bug_group_map
WHERE group_id = ?'
,
undef
,
$gid
);
...
...
@@ -379,6 +385,7 @@ if ($action eq 'del') {
$vars
->
{
'hasbugs'
}
=
$hasbugs
;
$vars
->
{
'hasproduct'
}
=
$hasproduct
;
$vars
->
{
'hasflags'
}
=
$hasflags
;
$vars
->
{
'shared_queries'
}
=
$shared_queries
;
$vars
->
{
'buglist'
}
=
$buglist
;
print
$cgi
->
header
();
...
...
@@ -462,6 +469,8 @@ if ($action eq 'delete') {
$dbh
->
do
(
'UPDATE flagtypes SET request_group_id = ?
WHERE request_group_id = ?'
,
undef
,
(
undef
,
$gid
));
$dbh
->
do
(
'DELETE FROM namedquery_group_map WHERE group_id = ?'
,
undef
,
$gid
);
$dbh
->
do
(
'DELETE FROM user_group_map WHERE group_id = ?'
,
undef
,
$gid
);
$dbh
->
do
(
'DELETE FROM group_group_map
...
...
editusers.cgi
View file @
f0c76112
...
...
@@ -460,9 +460,18 @@ if ($action eq 'search') {
$vars
->
{
'longdescs'
}
=
$dbh
->
selectrow_array
(
'SELECT COUNT(*) FROM longdescs WHERE who = ?'
,
undef
,
$otherUserID
);
$vars
->
{
'namedqueries'
}
=
$dbh
->
selectrow_array
(
'SELECT COUNT(*) FROM namedqueries WHERE userid = ?'
,
undef
,
$otherUserID
);
$vars
->
{
'namedqueries'
}
=
$dbh
->
selectcol_arrayref
(
'SELECT id FROM namedqueries WHERE userid = ?'
,
undef
,
$otherUserID
);
if
(
@
{
$vars
->
{
'namedqueries'
}})
{
$vars
->
{
'namedquery_group_map'
}
=
$dbh
->
selectrow_array
(
'SELECT COUNT(*) FROM namedquery_group_map WHERE namedquery_id IN'
.
' ('
.
join
(
', '
,
@
{
$vars
->
{
'namedqueries'
}})
.
')'
);
}
else
{
$vars
->
{
'namedquery_group_map'
}
=
0
;
}
$vars
->
{
'profile_setting'
}
=
$dbh
->
selectrow_array
(
'SELECT COUNT(*) FROM profile_setting WHERE user_id = ?'
,
undef
,
$otherUserID
);
...
...
@@ -525,6 +534,8 @@ if ($action eq 'search') {
'flagtypes READ'
,
'cc WRITE'
,
'namedqueries WRITE'
,
'namedqueries_link_in_footer WRITE'
,
'namedquery_group_map WRITE'
,
'tokens WRITE'
,
'votes WRITE'
,
'watch WRITE'
,
...
...
@@ -545,6 +556,12 @@ if ($action eq 'search') {
Bugzilla
->
logout_user
(
$otherUser
);
# Get the named query list so we can delete namedquery_group_map entries.
my
$namedqueries_as_string
=
join
(
', '
,
$dbh
->
selectcol_arrayref
(
'SELECT id FROM namedqueries WHERE userid = ?'
,
undef
,
$otherUserID
));
# Get the timestamp for LogActivityEntry.
my
$timestamp
=
$dbh
->
selectrow_array
(
'SELECT NOW()'
);
...
...
@@ -589,6 +606,12 @@ if ($action eq 'search') {
$otherUserID
);
$dbh
->
do
(
'DELETE FROM logincookies WHERE userid = ?'
,
undef
,
$otherUserID
);
$dbh
->
do
(
'DELETE FROM namedqueries WHERE userid = ?'
,
undef
,
$otherUserID
);
$dbh
->
do
(
'DELETE FROM namedqueries_link_in_footer WHERE user_id = ?'
,
undef
,
$otherUserID
);
if
(
$namedqueries_as_string
)
{
$dbh
->
do
(
'DELETE FROM namedquery_group_map WHERE namedquery_id IN '
.
"($namedqueries_as_string)"
);
}
$dbh
->
do
(
'DELETE FROM profile_setting WHERE user_id = ?'
,
undef
,
$otherUserID
);
$dbh
->
do
(
'DELETE FROM profiles_activity WHERE userid = ? OR who = ?'
,
undef
,
...
...
sanitycheck.cgi
View file @
f0c76112
...
...
@@ -418,8 +418,14 @@ CrossCheck("groups", "id",
[
"group_group_map"
,
"grantor_id"
],
[
"group_group_map"
,
"member_id"
],
[
"group_control_map"
,
"group_id"
],
[
"namedquery_group_map"
,
"group_id"
],
[
"user_group_map"
,
"group_id"
]);
CrossCheck
(
"namedqueries"
,
"id"
,
[
"namedqueries_link_in_footer"
,
"namedquery_id"
],
[
"namedquery_group_map"
,
"namedquery_id"
],
);
CrossCheck
(
"profiles"
,
"userid"
,
[
'profiles_activity'
,
'userid'
],
[
'profiles_activity'
,
'who'
],
...
...
@@ -438,6 +444,7 @@ CrossCheck("profiles", "userid",
[
"longdescs"
,
"who"
,
"bug_id"
],
[
"logincookies"
,
"userid"
],
[
"namedqueries"
,
"userid"
],
[
"namedqueries_link_in_footer"
,
"user_id"
],
[
'series'
,
'creator'
,
'series_id'
,
[
'0'
]],
[
"watch"
,
"watcher"
],
[
"watch"
,
"watched"
],
...
...
skins/standard/global.css
View file @
f0c76112
...
...
@@ -128,11 +128,6 @@ body
display
:
inline
;
}
#footer
span
{
display
:
block
;
}
#footer
.btn
,
#footer
.txt
{
font-size
:
0.8em
;
...
...
template/en/default/account/prefs/saved-searches.html.tmpl
View file @
f0c76112
...
...
@@ -19,6 +19,13 @@
# Contributor(s): Gervase Markham <gerv@gerv.net>
#%]
[%# INTERFACE:
# queries: list of the named queries visible to the user, both own and shared
# by others. Cleaned-up result of Bugzilla::User::queries.
# queryshare_groups: list of groups the user may share queries with
# (id, name).
#%]
<p>Your saved searches are as follows:</p>
<blockquote>
...
...
@@ -40,6 +47,17 @@
Show in
Footer
</th>
[% querysharegroup_regexp = '^' _ Param('querysharegroup') _ '$' %]
[% may_share = user.groups.keys.grep($querysharegroup_regexp).size %]
[% IF may_share %]
<th>
Share With
a Group
[% UNLESS queryshare_groups.size %]
(there are no groups you may share queries with)
[% END %]
</th>
[% END %]
</tr>
<tr>
<td>My Bugs</td>
...
...
@@ -59,8 +77,12 @@
value="1"
[% " checked" IF user.showmybugslink %]>
</td>
<td>
—
</td>
</tr>
[% FOREACH q = queries %]
[% NEXT UNLESS q.userid == user.id %]
<tr>
<td>[% q.name FILTER html %]</td>
<td>
...
...
@@ -79,9 +101,71 @@
</td>
<td align="center">
<input type="checkbox"
name="linkinfooter_[% q.name FILTER html %]"
name="link_in_footer_[% q.id FILTER html %]"
value="1"
[% " checked" IF q.link_in_footer %]>
</td>
<td>
[% IF queryshare_groups.size %]
<select name="share_[% q.id FILTER html %]">
<option value="">Don't share</option>
[% FOREACH group = queryshare_groups %]
<option value="[% group.id %]"
[% ' selected="selected"' IF q.shared_with_group == group.id %]>[% group.name FILTER html %]</option>
[% END %]
</select>
[% ELSE %]
—
[% END %]
</td>
</tr>
[% END %]
</table>
</blockquote>
<p>You may use these searches saved and shared by others:</p>
<blockquote>
<table border="1" cellpadding="3">
<tr>
<th>
Search
</th>
<th>
Shared By
</th>
<th>
Run
</th>
<th>
Show in
Footer
</th>
</tr>
[% found_shared_query = 0 %]
[% FOREACH q = queries %]
[% NEXT IF q.userid == user.id %]
[% found_shared_query = 1 %]
<tr>
<td>[% q.name FILTER html %]</td>
<td>[% q.user.identity FILTER html %]</td>
<td>
<a href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd=
[% q.name FILTER url_quote %]&sharer_id=
[% q.userid FILTER url_quote %]">Run</a>
</td>
<td align="center">
<input type="checkbox"
name="link_in_footer_[% q.id FILTER html %]"
value="1"
[% " checked" IF q.linkinfooter %]>
[% " checked" IF q.link_in_footer %]>
</td>
</tr>
[% END %]
[% IF !found_shared_query %]
<tr>
<td colspan="4" style="text-align: center">
<None>
</td>
</tr>
[% END %]
...
...
template/en/default/admin/groups/delete.html.tmpl
View file @
f0c76112
...
...
@@ -30,6 +30,7 @@
# hasbugs: boolean int. True if the group includes bugs in it.
# hasproduct: boolean int. True if the group is binded to a product.
# hasflags: boolean int. True if the group is used by a flag type.
# shared_queries: int. Number of saved searches being shared with this group.
# buglist: string. The list of bugs included in this group.
#%]
...
...
@@ -92,6 +93,25 @@
flag types from this group for me.</p>
[% END %]
[% IF shared_queries %]
<p>
<b>There
[% IF shared_queries > 1 %]
are [% shared_queries %] saved searches
[% ELSE %]
is a saved search
[% END %]
being shared with this group.</b>
If you delete this group,
[% IF shared_queries > 1 %]
these saved searches
[% ELSE %]
this saved search
[% END %]
will fall back to being private again.
</p>
[% END %]
<h2>Confirmation</h2>
<p>Do you really want to delete this group?</p>
...
...
template/en/default/admin/params/groupsecurity.html.tmpl
View file @
f0c76112
...
...
@@ -46,6 +46,9 @@
timetrackinggroup => "The name of the group of users who can see/change time tracking " _
"information.",
querysharegroup => "The name of the group of users who can share their " _
"saved searches with others.",
usevisibilitygroups => "Do you wish to restrict visibility of users to members of " _
"specific groups?",
...
...
template/en/default/admin/users/confirm-delete.html.tmpl
View file @
f0c76112
...
...
@@ -31,7 +31,8 @@
# flags.requestee: number of flags the viewed user is being asked for
# flags.setter: number of flags the viewed user has set
# longdescs: number of bug comments the viewed user has written
# namedqueries: number of named queries the user has created
# namedqueries: array of IDs of named queries the user has created
# namedquery_group_map: number of named queries the user has shared
# profiles_activity: number of named queries the user has created
# series: number of series the viewed user has created
# votes: number of bugs the viewed user has voted on
...
...
@@ -301,17 +302,35 @@
[% IF namedqueries %]
<li>
[% otheruser.login FILTER html %] has
[% IF namedqueries == 1 %]
a
named query
[% IF namedqueries
.size
== 1 %]
a
[% 'shared' IF namedquery_group_map %] named search
[% ELSE %]
[%+ namedqueries
%] named queri
es
[%+ namedqueries
.size %] named search
es
[% END %].
[% IF namedqueries == 1 %]
This named
query
[% IF namedqueries
.size
== 1 %]
This named
search
[% ELSE %]
These named
queri
es
These named
search
es
[% END %]
will be deleted along with the user account.
[% IF namedquery_group_map %]
[% IF namedqueries.size > 1 %]
Of these,
[% IF namedquery_group_map > 1 %]
[%+ namedquery_group_map FILTER html %] are
[% ELSE %]
one is
[% END %]
shared.
[% END %]
Other users will not be able to use
[% IF namedquery_group_map > 1 %]
these shared named searches
[% ELSE %]
this shared named search
[% END %]
any more.
[% END %]
</li>
[% END %]
[% IF profile_setting %]
...
...
template/en/default/filterexceptions.pl
View file @
f0c76112
...
...
@@ -545,6 +545,10 @@
'comp.bug_count'
],
'admin/groups/delete.html.tmpl'
=>
[
'shared_queries'
],
'admin/users/confirm-delete.html.tmpl'
=>
[
'andstring'
,
'responsibilityterms.$responsibility'
,
...
...
@@ -554,7 +558,6 @@
'flags.requestee'
,
'flags.setter'
,
'longdescs'
,
'namedqueries'
,
'votes'
,
'series'
,
'watch.watched'
,
...
...
@@ -600,6 +603,10 @@
'current_tab.name'
,
],
'account/prefs/saved-searches.html.tmpl'
=>
[
'group.id'
,
],
'account/prefs/settings.html.tmpl'
=>
[
'name'
,
'default_name'
...
...
template/en/default/global/useful-links.html.tmpl
View file @
f0c76112
...
...
@@ -18,6 +18,7 @@
#
# Contributor(s): Gervase Markham <gerv@gerv.net>
# Svetlana Harisova <light@rathedg.com>
# Marc Schumann <wurblzap@gmail.com>
#%]
[%# Migration note: this whole file corresponds to the old %commandmenu%
...
...
@@ -78,9 +79,26 @@
[% END %]
[% FOREACH q = user.queries %]
[% IF q.linkinfooter %]
[% NEXT IF q.userid != user.id %]
[% IF q.link_in_footer %]
[% " | " IF print_pipe %]
<a href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]">[% q.name FILTER html FILTER no_break %]</a>
<a href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd=
[% q.name FILTER url_quote %]">[% q.name FILTER html FILTER no_break %]</a>
[% print_pipe = 1 %]
[% END %]
[% END %]
[% " <br> " IF print_pipe %]
[% print_pipe = 0 %]
[% FOREACH q = user.queries %]
[% NEXT IF q.userid == user.id %]
[% IF q.link_in_footer %]
[% " | " IF print_pipe %]
<a href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd=
[% q.name FILTER url_quote %]&sharer_id=
[% q.userid FILTER url_quote %]"
class="shared"
title="Shared by [% q.user.identity FILTER html %]">[% q.name FILTER html FILTER no_break %]</a>
[% print_pipe = 1 %]
[% END %]
[% END %]
...
...
template/en/default/global/user-error.html.tmpl
View file @
f0c76112
...
...
@@ -920,8 +920,14 @@
[% ELSIF error == "missing_query" %]
[% title = "Missing Search" %]
The search named <em>[% queryname FILTER html %]</em> does not
exist.
[% docslinks = {'query.html' => "Searching for $terms.bugs",
'list.html' => "$terms.Bug lists"} %]
The search named <em>[% queryname FILTER html %]</em>
[% IF sharer_id %]
has not been made visible to you.
[% ELSE %]
does not exist.
[% END %]
[% ELSIF error == "move_bugs_disabled" %]
[% title = BLOCK %][% terms.Bug %] Moving Disabled[% END %]
...
...
userprefs.cgi
View file @
f0c76112
...
...
@@ -351,11 +351,12 @@ sub DoPermissions {
my
(
$nam
,
$desc
)
=
@$group
;
push
(
@has_bits
,
{
"desc"
=>
$desc
,
"name"
=>
$nam
});
}
$groups
=
$dbh
->
selectall_arrayref
(
"SELECT DISTINCT name, description FROM groups ORDER BY name"
);
$groups
=
$dbh
->
selectall_arrayref
(
'SELECT DISTINCT id, name, description
FROM groups
ORDER BY name'
);
foreach
my
$group
(
@$groups
)
{
my
(
$nam
,
$desc
)
=
@$group
;
if
(
$user
->
can_bless
(
$
nam
))
{
my
(
$
group_id
,
$
nam
,
$desc
)
=
@$group
;
if
(
$user
->
can_bless
(
$
group_id
))
{
push
(
@set_bits
,
{
"desc"
=>
$desc
,
"name"
=>
$nam
});
}
}
...
...
@@ -370,6 +371,7 @@ sub DoPermissions {
sub
DoSavedSearches
{
# 2004-12-13 - colin.ogilvie@gmail.com, bug 274397
# Need to work around the possibly missing query_format=advanced
my
$dbh
=
Bugzilla
->
dbh
;
my
$user
=
Bugzilla
->
user
;
my
@queries
=
@
{
$user
->
queries
};
...
...
@@ -391,6 +393,12 @@ sub DoSavedSearches {
push
@newqueries
,
$q
;
}
$vars
->
{
'queries'
}
=
\
@newqueries
;
if
(
$user
->
queryshare_groups_as_string
)
{
$vars
->
{
'queryshare_groups'
}
=
$dbh
->
selectall_arrayref
(
'SELECT id, name FROM groups WHERE id IN '
.
'('
.
$user
->
queryshare_groups_as_string
.
')'
,
{
'Slice'
=>
{}});
}
}
sub
SaveSavedSearches
{
...
...
@@ -398,18 +406,114 @@ sub SaveSavedSearches {
my
$dbh
=
Bugzilla
->
dbh
;
my
$user
=
Bugzilla
->
user
;
# We'll need this in a loop, so do the call once.
my
$user_id
=
$user
->
id
;
my
@queries
=
@
{
$user
->
queries
};
my
$sth
=
$dbh
->
prepare
(
"UPDATE namedqueries SET linkinfooter = ?
WHERE userid = ?
AND name = ?"
);
my
$sth_check_nl
=
$dbh
->
prepare
(
'SELECT COUNT(*)
FROM namedqueries_link_in_footer
WHERE namedquery_id = ?
AND user_id = ?'
);
my
$sth_insert_nl
=
$dbh
->
prepare
(
'INSERT INTO namedqueries_link_in_footer
(namedquery_id, user_id)
VALUES (?, ?)'
);
my
$sth_delete_nl
=
$dbh
->
prepare
(
'DELETE FROM namedqueries_link_in_footer
WHERE namedquery_id = ?
AND user_id = ?'
);
my
$sth_check_ngm
=
$dbh
->
prepare
(
'SELECT COUNT(*)
FROM namedquery_group_map
WHERE namedquery_id = ?'
);
my
$sth_insert_ngm
=
$dbh
->
prepare
(
'INSERT INTO namedquery_group_map
(namedquery_id, group_id)
VALUES (?, ?)'
);
my
$sth_update_ngm
=
$dbh
->
prepare
(
'UPDATE namedquery_group_map
SET group_id = ?
WHERE namedquery_id = ?'
);
my
$sth_delete_ngm
=
$dbh
->
prepare
(
'DELETE FROM namedquery_group_map
WHERE namedquery_id = ?'
);
my
$sth_direct_group_members
=
$dbh
->
prepare
(
'SELECT user_id
FROM user_group_map
WHERE group_id = ?
AND isbless = '
.
GROUP_MEMBERSHIP
.
'
AND grant_type = '
.
GRANT_DIRECT
);
foreach
my
$q
(
@queries
)
{
my
$linkinfooter
=
defined
(
$cgi
->
param
(
"linkinfooter_$q->{'name'}"
))
?
1
:
0
;
$sth
->
execute
(
$linkinfooter
,
$user
->
id
,
$q
->
{
'name'
});
# Update namedqueries_link_in_footer.
$sth_check_nl
->
execute
(
$q
->
{
'id'
},
$user_id
);
my
(
$link_in_footer_entries
)
=
$sth_check_nl
->
fetchrow_array
();
if
(
defined
(
$cgi
->
param
(
"link_in_footer_$q->{'id'}"
)))
{
if
(
$link_in_footer_entries
==
0
)
{
$sth_insert_nl
->
execute
(
$q
->
{
'id'
},
$user_id
);
}
}
else
{
if
(
$link_in_footer_entries
>
0
)
{
$sth_delete_nl
->
execute
(
$q
->
{
'id'
},
$user_id
);
}
}
# For user's own queries, update namedquery_group_map.
if
(
$q
->
{
'userid'
}
==
$user_id
)
{
my
(
$group_id
,
$group_map_entries
);
if
(
$user
->
in_group
(
Bugzilla
->
params
->
{
'querysharegroup'
}))
{
$sth_check_ngm
->
execute
(
$q
->
{
'id'
});
(
$group_map_entries
)
=
$sth_check_ngm
->
fetchrow_array
();
$group_id
=
$cgi
->
param
(
"share_$q->{'id'}"
)
||
''
;
}
if
(
$group_id
)
{
if
(
grep
(
/^\Q$group_id\E$/
,
@
{
$user
->
queryshare_groups
()}))
{
# $group_id is now definitely a valid ID of a group the
# user can see, so we can trick_taint.
trick_taint
(
$group_id
);
if
(
$group_map_entries
==
0
)
{
$sth_insert_ngm
->
execute
(
$q
->
{
'id'
},
$group_id
);
}
else
{
$sth_update_ngm
->
execute
(
$group_id
,
$q
->
{
'id'
});
}
# If we're sharing our query with a group we can bless,
# we're subscribing direct group members to our search
# automatically. Otherwise, the group members need to
# opt in. This behaviour is deemed most likely to fit
# users' needs.
if
(
$user
->
can_bless
(
$group_id
))
{
$sth_direct_group_members
->
execute
(
$group_id
);
my
$user_id
;
while
(
$user_id
=
$sth_direct_group_members
->
fetchrow_array
())
{
next
if
$user_id
==
$user
->
id
;
$sth_check_nl
->
execute
(
$q
->
{
'id'
},
$user_id
);
my
(
$already_shown_in_footer
)
=
$sth_check_nl
->
fetchrow_array
();
if
(
!
$already_shown_in_footer
)
{
$sth_insert_nl
->
execute
(
$q
->
{
'id'
},
$user_id
);
}
}
}
}
else
{
# In the unlikely case somebody removed visibility to the
# group in the meantime, don't modify sharing.
}
}
else
{
if
(
$group_map_entries
>
0
)
{
$sth_delete_ngm
->
execute
(
$q
->
{
'id'
});
}
# Don't remove namedqueries_link_in_footer entries for users
# subscribing to the shared query. The idea is that they will
# probably want to be subscribers again should the sharing
# user choose to share the query again.
}
}
}
$user
->
flush_queries_cache
;
# Update profiles.mybugslink.
my
$showmybugslink
=
defined
(
$cgi
->
param
(
"showmybugslink"
))
?
1
:
0
;
$dbh
->
do
(
"UPDATE profiles SET mybugslink = ? WHERE userid = ?"
,
undef
,
(
$showmybugslink
,
$user
->
id
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment