From 160fad5ce1ca367fa8b76cb653dacaf3bf111a08 Mon Sep 17 00:00:00 2001 From: lpsolit%gmail.com <> Date: Oct 15 2006 05:05:54 +0000 Subject: Bug 281181: [SECURITY] It's way too easy to delete versions/components/milestones etc... - Patch by Frédéric Buclin r=mkanat a=myk --- diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm index dfc7be4..dcf476c 100644 --- a/Bugzilla/Token.pm +++ b/Bugzilla/Token.pm @@ -18,6 +18,7 @@ # Rights Reserved. # # Contributor(s): Myk Melez +# Frédéric Buclin ################################################################################ # Module Initialization @@ -36,6 +37,11 @@ use Bugzilla::Util; use Date::Format; use Date::Parse; +use File::Basename; + +use base qw(Exporter); + +@Bugzilla::Token::EXPORT = qw(issue_session_token check_token_data delete_token); # This module requires that its caller have said "require globals.pl" to import # relevant functions from that script. @@ -132,7 +138,7 @@ sub IssuePasswordToken { Bugzilla::BugMail::MessageToMTA($message); } -sub IssueSessionToken { +sub issue_session_token { # Generates a random token, adds it to the tokens table, and returns # the token to the caller. @@ -223,7 +229,7 @@ sub Cancel { Bugzilla::BugMail::MessageToMTA($message); # Delete the token from the database. - DeleteToken($token); + delete_token($token); } sub DeletePasswordTokens { @@ -258,6 +264,7 @@ sub GetTokenData { my ($token) = @_; return unless defined $token; + $token = clean_text($token); trick_taint($token); my $dbh = Bugzilla->dbh; @@ -267,7 +274,7 @@ sub GetTokenData { WHERE token = ?", undef, $token); } -sub DeleteToken { +sub delete_token { # Deletes specified token my ($token) = @_; @@ -280,6 +287,50 @@ sub DeleteToken { $dbh->bz_unlock_tables(); } +# Given a token, makes sure it comes from the currently logged in user +# and match the expected event. Returns 1 on success, else displays a warning. +# Note: this routine must not be called while tables are locked as it will try +# to lock some tables itself, see CleanTokenTable(). +sub check_token_data { + my ($token, $expected_action) = @_; + my $user = Bugzilla->user; + my $template = Bugzilla->template; + my $cgi = Bugzilla->cgi; + + my ($creator_id, $date, $token_action) = GetTokenData($token); + unless ($creator_id + && $creator_id == $user->id + && $token_action eq $expected_action) + { + # Something is going wrong. Ask confirmation before processing. + # It is possible that someone tried to trick an administrator. + # In this case, we want to know his name! + require Bugzilla::User; + + my $vars = {}; + $vars->{'abuser'} = Bugzilla::User->new($creator_id)->identity; + $vars->{'token_action'} = $token_action; + $vars->{'expected_action'} = $expected_action; + $vars->{'script_name'} = basename($0); + + # Now is a good time to remove old tokens from the DB. + CleanTokenTable(); + + # If no token was found, create a valid token for the given action. + unless ($creator_id) { + $token = issue_session_token($expected_action); + $cgi->param('token', $token); + } + + print $cgi->header(); + + $template->process('admin/confirm-action.html.tmpl', $vars) + || ThrowTemplateError($template->error()); + exit; + } + return 1; +} + ################################################################################ # Internal Functions ################################################################################ diff --git a/editclassifications.cgi b/editclassifications.cgi index 352d781..ac4ed9f 100755 --- a/editclassifications.cgi +++ b/editclassifications.cgi @@ -29,6 +29,7 @@ use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::Config qw($datadir); use Bugzilla::Classification; +use Bugzilla::Token; require "globals.pl"; @@ -68,7 +69,8 @@ ThrowUserError("auth_classification_not_enabled") unless Param("useclassificatio # my $action = trim($cgi->param('action') || ''); my $class_name = trim($cgi->param('classification') || ''); - +my $token = $cgi->param('token'); + # # action='' -> Show nice list of classifications # @@ -88,6 +90,7 @@ unless ($action) { # if ($action eq 'add') { + $vars->{'token'} = issue_session_token('add_classification'); LoadTemplate($action); } @@ -96,7 +99,7 @@ if ($action eq 'add') { # if ($action eq 'new') { - + check_token_data($token, 'add_classification'); $class_name || ThrowUserError("classification_not_specified"); my $classification = @@ -119,7 +122,7 @@ if ($action eq 'new') { unlink "$datadir/versioncache"; $vars->{'classification'} = $class_name; - + delete_token($token); LoadTemplate($action); } @@ -143,7 +146,7 @@ if ($action eq 'del') { } $vars->{'classification'} = $classification; - + $vars->{'token'} = issue_session_token('delete_classification'); LoadTemplate($action); } @@ -152,7 +155,7 @@ if ($action eq 'del') { # if ($action eq 'delete') { - + check_token_data($token, 'delete_classification'); my $classification = Bugzilla::Classification::check_classification($class_name); @@ -176,7 +179,7 @@ if ($action eq 'delete') { unlink "$datadir/versioncache"; $vars->{'classification'} = $classification; - + delete_token($token); LoadTemplate($action); } @@ -192,7 +195,7 @@ if ($action eq 'edit') { Bugzilla::Classification::check_classification($class_name); $vars->{'classification'} = $classification; - + $vars->{'token'} = issue_session_token('edit_classification'); LoadTemplate($action); } @@ -201,7 +204,7 @@ if ($action eq 'edit') { # if ($action eq 'update') { - + check_token_data($token, 'edit_classification'); $class_name || ThrowUserError("classification_not_specified"); my $class_old_name = trim($cgi->param('classificationold') || ''); @@ -240,7 +243,7 @@ if ($action eq 'update') { } $dbh->bz_unlock_tables(); - + delete_token($token); LoadTemplate($action); } @@ -257,26 +260,30 @@ if ($action eq 'reclassify') { WHERE name = ?"); if (defined $cgi->param('add_products')) { + check_token_data($token, 'reclassify_classifications'); if (defined $cgi->param('prodlist')) { foreach my $prod ($cgi->param("prodlist")) { trick_taint($prod); $sth->execute($classification->id, $prod); } } + delete_token($token); } elsif (defined $cgi->param('remove_products')) { + check_token_data($token, 'reclassify_classifications'); if (defined $cgi->param('myprodlist')) { foreach my $prod ($cgi->param("myprodlist")) { trick_taint($prod); $sth->execute(1,$prod); } } + delete_token($token); } my @classifications = Bugzilla::Classification::get_all_classifications; $vars->{'classifications'} = \@classifications; $vars->{'classification'} = $classification; - + $vars->{'token'} = issue_session_token('reclassify_classifications'); LoadTemplate($action); } diff --git a/editcomponents.cgi b/editcomponents.cgi index c65fd31..70ead70 100755 --- a/editcomponents.cgi +++ b/editcomponents.cgi @@ -39,6 +39,7 @@ use Bugzilla::User; use Bugzilla::Product; use Bugzilla::Component; use Bugzilla::Bug; +use Bugzilla::Token; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; @@ -66,6 +67,7 @@ my $product_name = trim($cgi->param('product') || ''); my $comp_name = trim($cgi->param('component') || ''); my $action = trim($cgi->param('action') || ''); my $showbugcounts = (defined $cgi->param('showbugcounts')); +my $token = $cgi->param('token'); # # product = '' -> Show nice list of products @@ -111,7 +113,7 @@ unless ($action) { # if ($action eq 'add') { - + $vars->{'token'} = issue_session_token('add_component'); $vars->{'product'} = $product->name; $template->process("admin/components/create.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -126,7 +128,7 @@ if ($action eq 'add') { # if ($action eq 'new') { - + check_token_data($token, 'add_component'); # Do the user matching Bugzilla::User::match_field ($cgi, { 'initialowner' => { 'type' => 'single' }, @@ -213,6 +215,7 @@ if ($action eq 'new') { $vars->{'name'} = $comp_name; $vars->{'product'} = $product->name; + delete_token($token); $template->process("admin/components/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -229,7 +232,7 @@ if ($action eq 'new') { # if ($action eq 'del') { - + $vars->{'token'} = issue_session_token('delete_component'); $vars->{'comp'} = Bugzilla::Component::check_component($product, $comp_name); @@ -248,7 +251,7 @@ if ($action eq 'del') { # if ($action eq 'delete') { - + check_token_data($token, 'delete_component'); my $component = Bugzilla::Component::check_component($product, $comp_name); @@ -282,6 +285,7 @@ if ($action eq 'delete') { $vars->{'name'} = $component->name; $vars->{'product'} = $product->name; + delete_token($token); $template->process("admin/components/deleted.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -296,7 +300,7 @@ if ($action eq 'delete') { # if ($action eq 'edit') { - + $vars->{'token'} = issue_session_token('edit_component'); $vars->{'comp'} = Bugzilla::Component::check_component($product, $comp_name); @@ -316,7 +320,7 @@ if ($action eq 'edit') { # if ($action eq 'update') { - + check_token_data($token, 'edit_component'); # Do the user matching Bugzilla::User::match_field ($cgi, { 'initialowner' => { 'type' => 'single' }, @@ -405,6 +409,7 @@ if ($action eq 'update') { $vars->{'name'} = $comp_name; $vars->{'product'} = $product->name; + delete_token($token); $template->process("admin/components/updated.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/editflagtypes.cgi b/editflagtypes.cgi index dfef556..6ed20c4 100755 --- a/editflagtypes.cgi +++ b/editflagtypes.cgi @@ -38,6 +38,7 @@ use Bugzilla::Flag; use Bugzilla::FlagType; use Bugzilla::Group; use Bugzilla::Util; +use Bugzilla::Token; my $template = Bugzilla->template; my $vars = {}; @@ -66,11 +67,12 @@ my $component_id; # Determine whether to use the action specified by the user or the default. my $action = $cgi->param('action') || 'list'; +my $token = $cgi->param('token'); my @categoryActions; if (@categoryActions = grep(/^categoryAction-.+/, $cgi->param())) { $categoryActions[0] =~ s/^categoryAction-//; - processCategoryChange($categoryActions[0]); + processCategoryChange($categoryActions[0], $token); exit; } @@ -78,11 +80,11 @@ if ($action eq 'list') { list(); } elsif ($action eq 'enter') { edit(); } elsif ($action eq 'copy') { edit(); } elsif ($action eq 'edit') { edit(); } -elsif ($action eq 'insert') { insert(); } -elsif ($action eq 'update') { update(); } +elsif ($action eq 'insert') { insert($token); } +elsif ($action eq 'update') { update($token); } elsif ($action eq 'confirmdelete') { confirmDelete(); } -elsif ($action eq 'delete') { deleteType(); } -elsif ($action eq 'deactivate') { deactivate(); } +elsif ($action eq 'delete') { deleteType($token); } +elsif ($action eq 'deactivate') { deactivate($token); } else { ThrowCodeError("action_unrecognized", { action => $action }); } @@ -128,9 +130,11 @@ sub edit { $vars->{'last_action'} = $cgi->param('action'); if ($cgi->param('action') eq 'enter' || $cgi->param('action') eq 'copy') { $vars->{'action'} = "insert"; + $vars->{'token'} = issue_session_token('add_flagtype'); } else { $vars->{'action'} = "update"; + $vars->{'token'} = issue_session_token('edit_flagtype'); } # If copying or editing an existing flag type, retrieve it. @@ -168,7 +172,7 @@ sub edit { } sub processCategoryChange { - my $categoryAction = shift; + my ($categoryAction, $token) = @_; validateIsActive(); validateIsRequestable(); validateIsRequesteeble(); @@ -218,7 +222,8 @@ sub processCategoryChange { $type->{'inclusions'} = \%inclusions; $type->{'exclusions'} = \%exclusions; $vars->{'type'} = $type; - + $vars->{'token'} = $token; + # Return the appropriate HTTP response headers. print $cgi->header(); @@ -243,6 +248,8 @@ sub clusion_array_to_hash { } sub insert { + my $token = shift; + check_token_data($token, 'add_flagtype'); my $name = validateName(); my $description = validateDescription(); my $cc_list = validateCCList(); @@ -285,6 +292,7 @@ sub insert { $vars->{'name'} = $cgi->param('name'); $vars->{'message'} = "flag_type_created"; + delete_token($token); # Return the appropriate HTTP response headers. print $cgi->header(); @@ -296,6 +304,8 @@ sub insert { sub update { + my $token = shift; + check_token_data($token, 'edit_flagtype'); my $id = validateID(); my $name = validateName(); my $description = validateDescription(); @@ -368,6 +378,7 @@ sub update { $vars->{'name'} = $cgi->param('name'); $vars->{'message'} = "flag_type_changes_saved"; + delete_token($token); # Return the appropriate HTTP response headers. print $cgi->header(); @@ -390,7 +401,7 @@ sub confirmDelete if ($count > 0) { $vars->{'flag_type'} = Bugzilla::FlagType::get($id); $vars->{'flag_count'} = scalar($count); - + $vars->{'token'} = issue_session_token('delete_flagtype'); # Return the appropriate HTTP response headers. print $cgi->header(); @@ -399,12 +410,15 @@ sub confirmDelete || ThrowTemplateError($template->error()); } else { - deleteType(); + my $token = issue_session_token('delete_flagtype'); + deleteType($token); } } sub deleteType { + my $token = shift; + check_token_data($token, 'delete_flagtype'); my $id = validateID(); my $dbh = Bugzilla->dbh; @@ -423,6 +437,7 @@ sub deleteType { $dbh->bz_unlock_tables(); $vars->{'message'} = "flag_type_deleted"; + delete_token($token); # Return the appropriate HTTP response headers. print $cgi->header(); @@ -434,6 +449,8 @@ sub deleteType { sub deactivate { + my $token = shift; + check_token_data($token, 'delete_flagtype'); my $id = validateID(); validateIsActive(); @@ -445,7 +462,8 @@ sub deactivate { $vars->{'message'} = "flag_type_deactivated"; $vars->{'flag_type'} = Bugzilla::FlagType::get($id); - + delete_token($token); + # Return the appropriate HTTP response headers. print $cgi->header(); diff --git a/editgroups.cgi b/editgroups.cgi index fb0704b..3d228b5 100755 --- a/editgroups.cgi +++ b/editgroups.cgi @@ -34,6 +34,7 @@ use Bugzilla::Constants; use Bugzilla::Config qw(:DEFAULT :admin); use Bugzilla::Group; use Bugzilla::User; +use Bugzilla::Token; require "globals.pl"; my $cgi = Bugzilla->cgi; @@ -51,6 +52,7 @@ $user->in_group('creategroups') object => "groups"}); my $action = trim($cgi->param('action') || ''); +my $token = $cgi->param('token'); # RederiveRegexp: update user_group_map with regexp-based grants sub RederiveRegexp @@ -250,6 +252,7 @@ if ($action eq 'changeform') { $vars->{'isactive'} = $isactive; $vars->{'isbuggroup'} = $isbuggroup; $vars->{'groups'} = \@groups; + $vars->{'token'} = issue_session_token('edit_group'); print $cgi->header(); $template->process("admin/groups/edit.html.tmpl", $vars) @@ -265,6 +268,7 @@ if ($action eq 'changeform') { # if ($action eq 'add') { + $vars->{'token'} = issue_session_token('add_group'); print $cgi->header(); $template->process("admin/groups/create.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -279,6 +283,7 @@ if ($action eq 'add') { # if ($action eq 'new') { + check_token_data($token, 'add_group'); # Check that a not already used group name is given, that # a description is also given and check if the regular # expression is valid (if any). @@ -315,6 +320,7 @@ if ($action eq 'new') { undef, ($gid, CONTROLMAPSHOWN, CONTROLMAPNA)); } RederiveRegexp($regexp, $gid); + delete_token($token); print $cgi->header(); $template->process("admin/groups/created.html.tmpl", $vars) @@ -380,6 +386,7 @@ if ($action eq 'del') { $vars->{'hasproduct'} = $hasproduct; $vars->{'hasflags'} = $hasflags; $vars->{'buglist'} = $buglist; + $vars->{'token'} = issue_session_token('delete_group'); print $cgi->header(); $template->process("admin/groups/delete.html.tmpl", $vars) @@ -393,6 +400,7 @@ if ($action eq 'del') { # if ($action eq 'delete') { + check_token_data($token, 'delete_group'); # Check that an existing group ID is given my $gid = CheckGroupID($cgi->param('group')); my ($name, $isbuggroup) = @@ -475,6 +483,8 @@ if ($action eq 'delete') { $dbh->do('DELETE FROM groups WHERE id = ?', undef, $gid); + delete_token($token); + print $cgi->header(); $template->process("admin/groups/deleted.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -487,6 +497,7 @@ if ($action eq 'delete') { # if ($action eq 'postchanges') { + check_token_data($token, 'edit_group'); # ZLL: Bug 181589: we need to have something to remove explicitly listed users from # groups in order for the conversion to 2.18 groups to work my $action; @@ -508,7 +519,8 @@ if ($action eq 'postchanges') { if ($action == 2) { $vars->{'regexp'} = $regexp; } - + delete_token($token); + print $cgi->header(); $template->process("admin/groups/change.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/editkeywords.cgi b/editkeywords.cgi index e98be63..e008cff 100755 --- a/editkeywords.cgi +++ b/editkeywords.cgi @@ -28,6 +28,7 @@ require "globals.pl"; use Bugzilla; use Bugzilla::Constants; use Bugzilla::Config qw(:DEFAULT $datadir); +use Bugzilla::Token; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; @@ -76,6 +77,7 @@ $user->in_group('editkeywords') object => "keywords"}); my $action = trim($cgi->param('action') || ''); +my $token = $cgi->param('token'); $vars->{'action'} = $action; @@ -101,6 +103,7 @@ if ($action eq "") { if ($action eq 'add') { + $vars->{'token'} = issue_session_token('add_keyword'); print $cgi->header(); $template->process("admin/keywords/create.html.tmpl", $vars) @@ -114,6 +117,7 @@ if ($action eq 'add') { # if ($action eq 'new') { + check_token_data($token, 'add_keyword'); # Cleanups and validity checks my $name = trim($cgi->param('name') || ''); @@ -154,6 +158,7 @@ if ($action eq 'new') { # Make versioncache flush unlink "$datadir/versioncache"; + delete_token($token); print $cgi->header(); @@ -193,6 +198,7 @@ if ($action eq 'edit') { $vars->{'name'} = $name; $vars->{'description'} = $description; $vars->{'bug_count'} = $bugs; + $vars->{'token'} = issue_session_token('edit_keyword'); print $cgi->header(); @@ -208,6 +214,7 @@ if ($action eq 'edit') { # if ($action eq 'update') { + check_token_data($token, 'edit_keyword'); my $id = ValidateKeyID(scalar $cgi->param('id')); my $name = trim($cgi->param('name') || ''); @@ -228,6 +235,7 @@ if ($action eq 'update') { # Make versioncache flush unlink "$datadir/versioncache"; + delete_token($token); print $cgi->header(); @@ -250,10 +258,14 @@ if ($action eq 'delete') { WHERE keywordid = ?', undef, $id); + # We need this token even if there is no bug using this keyword. + $token = issue_session_token('delete_keyword'); + if ($bugs) { $vars->{'bug_count'} = $bugs; $vars->{'keyword_id'} = $id; $vars->{'name'} = $name; + $vars->{'token'} = $token; print $cgi->header(); @@ -263,12 +275,15 @@ if ($action eq 'delete') { exit; } } + # We cannot do this check earlier as we have to check 'reallydelete' first. + check_token_data($token, 'delete_keyword'); $dbh->do('DELETE FROM keywords WHERE keywordid = ?', undef, $id); $dbh->do('DELETE FROM keyworddefs WHERE id = ?', undef, $id); # Make versioncache flush unlink "$datadir/versioncache"; + delete_token($token); print $cgi->header(); diff --git a/editmilestones.cgi b/editmilestones.cgi index c878285..cd2ce8a 100755 --- a/editmilestones.cgi +++ b/editmilestones.cgi @@ -12,7 +12,7 @@ # Matt Masson # # Contributors : Gavin Shelley -# Fr�d�ric Buclin +# Frédéric Buclin # @@ -26,6 +26,7 @@ use Bugzilla::Config qw(:DEFAULT $datadir); use Bugzilla::Product; use Bugzilla::Milestone; use Bugzilla::Bug; +use Bugzilla::Token; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; @@ -54,6 +55,7 @@ my $milestone_name = trim($cgi->param('milestone') || ''); my $sortkey = trim($cgi->param('sortkey') || 0); my $action = trim($cgi->param('action') || ''); my $showbugcounts = (defined $cgi->param('showbugcounts')); +my $token = $cgi->param('token'); # # product = '' -> Show nice list of products @@ -103,7 +105,7 @@ unless ($action) { # if ($action eq 'add') { - + $vars->{'token'} = issue_session_token('add_milestone'); $vars->{'product'} = $product->name; $template->process("admin/milestones/create.html.tmpl", $vars) @@ -119,7 +121,7 @@ if ($action eq 'add') { # if ($action eq 'new') { - + check_token_data($token, 'add_milestone'); $milestone_name || ThrowUserError('milestone_blank_name'); if (length($milestone_name) > 20) { @@ -147,6 +149,7 @@ if ($action eq 'new') { # Make versioncache flush unlink "$datadir/versioncache"; + delete_token($token); $vars->{'name'} = $milestone_name; $vars->{'product'} = $product->name; @@ -179,6 +182,7 @@ if ($action eq 'del') { } $vars->{'bug_count'} = $milestone->bug_count; + $vars->{'token'} = issue_session_token('delete_milestone'); $template->process("admin/milestones/confirm-delete.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -192,7 +196,7 @@ if ($action eq 'del') { # if ($action eq 'delete') { - + check_token_data($token, 'delete_milestone'); my $milestone = Bugzilla::Milestone::check_milestone($product, $milestone_name); @@ -233,6 +237,7 @@ if ($action eq 'delete') { undef, ($product->id, $milestone->name)); unlink "$datadir/versioncache"; + delete_token($token); $template->process("admin/milestones/deleted.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -256,6 +261,7 @@ if ($action eq 'edit') { $vars->{'sortkey'} = $milestone->sortkey; $vars->{'name'} = $milestone->name; $vars->{'product'} = $product->name; + $vars->{'token'} = issue_session_token('edit_milestone'); $template->process("admin/milestones/edit.html.tmpl", $vars) @@ -271,7 +277,7 @@ if ($action eq 'edit') { # if ($action eq 'update') { - + check_token_data($token, 'edit_milestone'); my $milestone_old_name = trim($cgi->param('milestoneold') || ''); my $milestone_old = Bugzilla::Milestone::check_milestone($product, @@ -350,6 +356,7 @@ if ($action eq 'update') { } $dbh->bz_unlock_tables(); + delete_token($token); $vars->{'name'} = $milestone_name; $vars->{'product'} = $product->name; diff --git a/editparams.cgi b/editparams.cgi index 57058e7..bd1b1f5 100755 --- a/editparams.cgi +++ b/editparams.cgi @@ -28,6 +28,7 @@ use lib "."; use Bugzilla::Constants; use Bugzilla::Config qw(:DEFAULT :admin :params $datadir); use Bugzilla::Config::Common; +use Bugzilla::Token; require "globals.pl"; use vars qw(@parampanels); @@ -45,6 +46,7 @@ $user->in_group('tweakparams') object => "parameters"}); my $action = trim($cgi->param('action') || ''); +my $token = $cgi->param('token'); my $current_panel = $cgi->param('section') || 'core'; $current_panel =~ /^([A-Za-z0-9_-]+)$/; $current_panel = $1; @@ -69,6 +71,7 @@ foreach my $panel (@parampanels) { $vars->{panels} = \@panels; if ($action eq 'save' && $current_module) { + check_token_data($token, 'edit_parameters'); my @changes = (); my @module_param_list = "Bugzilla::Config::${current_module}"->get_param_list(); @@ -129,7 +132,10 @@ if ($action eq 'save' && $current_module) { WriteParams(); unlink "$datadir/versioncache"; + delete_token($token); } +$vars->{'token'} = issue_session_token('edit_parameters'); + $template->process("admin/params/editparams.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/editproducts.cgi b/editproducts.cgi index 29b3c36..75597f1 100755 --- a/editproducts.cgi +++ b/editproducts.cgi @@ -41,6 +41,7 @@ use Bugzilla::Config qw(:DEFAULT $datadir); use Bugzilla::Product; use Bugzilla::Classification; use Bugzilla::Milestone; +use Bugzilla::Token; # Shut up misguided -w warnings about "used only once". "use vars" just # doesn't work for me. @@ -72,6 +73,7 @@ my $classification_name = trim($cgi->param('classification') || ''); my $product_name = trim($cgi->param('product') || ''); my $action = trim($cgi->param('action') || ''); my $showbugcounts = (defined $cgi->param('showbugcounts')); +my $token = $cgi->param('token'); # # product = '' -> Show nice list of classifications (if @@ -132,6 +134,8 @@ if ($action eq 'add') { Bugzilla::Classification::check_classification($classification_name); $vars->{'classification'} = $classification; } + $vars->{'token'} = issue_session_token('add_product'); + $template->process("admin/products/create.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -144,7 +148,7 @@ if ($action eq 'add') { # if ($action eq 'new') { - + check_token_data($token, 'add_product'); # Cleanups and validity checks my $classification_id = 1; @@ -307,6 +311,7 @@ if ($action eq 'new') { } # Make versioncache flush unlink "$datadir/versioncache"; + delete_token($token); $vars->{'product'} = $product; @@ -341,6 +346,7 @@ if ($action eq 'del') { } $vars->{'product'} = $product; + $vars->{'token'} = issue_session_token('delete_product'); $template->process("admin/products/confirm-delete.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -352,6 +358,7 @@ if ($action eq 'del') { # if ($action eq 'delete') { + check_token_data($token, 'delete_product'); # First make sure the product name is valid. my $product = Bugzilla::Product::check_product($product_name); @@ -414,6 +421,7 @@ if ($action eq 'delete') { $dbh->bz_unlock_tables(); unlink "$datadir/versioncache"; + delete_token($token); $template->process("admin/products/deleted.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -469,9 +477,9 @@ if ($action eq 'edit' || (!$action && $product_name)) { } } $vars->{'group_controls'} = $group_controls; - $vars->{'product'} = $product; - + $vars->{'token'} = issue_session_token('edit_product'); + $template->process("admin/products/edit.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -483,6 +491,7 @@ if ($action eq 'edit' || (!$action && $product_name)) { # if ($action eq 'updategroupcontrols') { + check_token_data($token, 'edit_group_controls'); # First make sure the product name is valid. my $product = Bugzilla::Product::check_product($product_name); @@ -724,10 +733,10 @@ if ($action eq 'updategroupcontrols') { } $dbh->bz_unlock_tables(); - $vars->{'removed_na'} = \@removed_na; + delete_token($token); + $vars->{'removed_na'} = \@removed_na; $vars->{'added_mandatory'} = \@added_mandatory; - $vars->{'product'} = $product; $template->process("admin/products/groupcontrol/updated.html.tmpl", $vars) @@ -739,7 +748,7 @@ if ($action eq 'updategroupcontrols') { # action='update' -> update the product # if ($action eq 'update') { - + check_token_data($token, 'edit_product'); my $product_old_name = trim($cgi->param('product_old_name') || ''); my $description = trim($cgi->param('description') || ''); my $disallownew = trim($cgi->param('disallownew') || ''); @@ -976,6 +985,7 @@ if ($action eq 'update') { $vars->{'confirmedbugs'} = \@updated_bugs; $vars->{'changer'} = $user->login; } + delete_token($token); $vars->{'old_product'} = $product_old; $vars->{'product'} = $product; @@ -1018,6 +1028,7 @@ if ($action eq 'editgroupcontrols') { $vars->{'product'} = $product; $vars->{'groups'} = $groups; + $vars->{'token'} = issue_session_token('edit_group_controls'); $vars->{'const'} = { 'CONTROLMAPNA' => CONTROLMAPNA, diff --git a/editsettings.cgi b/editsettings.cgi index 231c1ae..e4579f9 100755 --- a/editsettings.cgi +++ b/editsettings.cgi @@ -22,6 +22,7 @@ use lib qw(.); use Bugzilla; use Bugzilla::Constants; use Bugzilla::User::Setting; +use Bugzilla::Token; require "globals.pl"; @@ -79,9 +80,12 @@ $user->in_group('tweakparams') object => "settings"}); my $action = trim($cgi->param('action') || 'load'); +my $token = $cgi->param('token'); if ($action eq 'update') { + check_token_data($token, 'edit_settings'); SaveSettings(); + delete_token($token); $vars->{'changes_saved'} = 1; $template->process("admin/settings/updated.html.tmpl", $vars) @@ -92,6 +96,7 @@ if ($action eq 'update') { if ($action eq 'load') { LoadSettings(); + $vars->{'token'} = issue_session_token('edit_settings'); $template->process("admin/settings/edit.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/editusers.cgi b/editusers.cgi index 3e23d08..36366aa 100755 --- a/editusers.cgi +++ b/editusers.cgi @@ -31,6 +31,7 @@ use Bugzilla::Constants; use Bugzilla::Util; use Bugzilla::Field; use Bugzilla::Group; +use Bugzilla::Token; my $user = Bugzilla->login(LOGIN_REQUIRED); @@ -55,6 +56,7 @@ print $cgi->header(); my $action = $cgi->param('action') || 'search'; my $otherUserID = $cgi->param('userid'); my $otherUserLogin = $cgi->param('user'); +my $token = $cgi->param('token'); # Prefill template vars with data used in all or nearly all templates $vars->{'editusers'} = $editusers; @@ -168,6 +170,8 @@ if ($action eq 'search') { action => "add", object => "users"}); + $vars->{'token'} = issue_session_token('add_user'); + $template->process('admin/users/create.html.tmpl', $vars) || ThrowTemplateError($template->error()); @@ -177,6 +181,7 @@ if ($action eq 'search') { action => "add", object => "users"}); + check_token_data($token, 'add_user'); my $login = $cgi->param('login'); my $password = $cgi->param('password'); my $realname = trim($cgi->param('name') || ''); @@ -212,6 +217,10 @@ if ($action eq 'search') { $dbh->bz_unlock_tables(); userDataToVars($new_user_id); + delete_token($token); + + # We already display the updated page. We have to recreate a token now. + $vars->{'token'} = issue_session_token('edit_user'); $vars->{'message'} = 'account_created'; $template->process('admin/users/edit.html.tmpl', $vars) || ThrowTemplateError($template->error()); @@ -223,6 +232,7 @@ if ($action eq 'search') { ########################################################################### } elsif ($action eq 'update') { + check_token_data($token, 'edit_user'); my $otherUser = check_user($otherUserID, $otherUserLogin); $otherUserID = $otherUser->id; @@ -403,6 +413,7 @@ if ($action eq 'search') { # XXX: userDataToVars may be off when editing ourselves. userDataToVars($otherUserID); + delete_token($token); $vars->{'message'} = 'account_updated'; $vars->{'loginold'} = $loginold; @@ -411,6 +422,9 @@ if ($action eq 'search') { $vars->{'groups_removed_from'} = \@groupsRemovedFrom; $vars->{'groups_granted_rights_to_bless'} = \@groupsGrantedRightsToBless; $vars->{'groups_denied_rights_to_bless'} = \@groupsDeniedRightsToBless; + # We already display the updated page. We have to recreate a token now. + $vars->{'token'} = issue_session_token('edit_user'); + $template->process('admin/users/edit.html.tmpl', $vars) || ThrowTemplateError($template->error()); @@ -484,12 +498,14 @@ if ($action eq 'search') { AND mailto_type = ? }, undef, ($otherUserID, MAILTO_USER)); + $vars->{'token'} = issue_session_token('delete_user'); $template->process('admin/users/confirm-delete.html.tmpl', $vars) || ThrowTemplateError($template->error()); ########################################################################### } elsif ($action eq 'delete') { + check_token_data($token, 'delete_user'); my $otherUser = check_user($otherUserID, $otherUserLogin); $otherUserID = $otherUser->id; @@ -703,6 +719,7 @@ if ($action eq 'search') { $dbh->do('DELETE FROM profiles WHERE userid = ?', undef, $otherUserID); $dbh->bz_unlock_tables(); + delete_token($token); $vars->{'message'} = 'account_deleted'; $vars->{'otheruser'}{'login'} = $otherUser->login; @@ -826,6 +843,7 @@ sub edit_processing { object => "user"}); userDataToVars($otherUser->id); + $vars->{'token'} = issue_session_token('edit_user'); $template->process('admin/users/edit.html.tmpl', $vars) || ThrowTemplateError($template->error()); diff --git a/editvalues.cgi b/editvalues.cgi index 21c7a14..b03fea6 100755 --- a/editvalues.cgi +++ b/editvalues.cgi @@ -27,6 +27,7 @@ use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::Constants; use Bugzilla::Config qw(:DEFAULT :admin :locations); +use Bugzilla::Token; # List of different tables that contain the changeable field values # (the old "enums.") Keep them in alphabetical order by their @@ -116,6 +117,7 @@ my $field = trim($cgi->param('field') || ''); my $value = trim($cgi->param('value') || ''); my $sortkey = trim($cgi->param('sortkey') || '0'); my $action = trim($cgi->param('action') || ''); +my $token = $cgi->param('token'); # Gives the name of the parameter associated with the field # and representing its default value. @@ -175,6 +177,8 @@ if ($action eq 'add') { $vars->{'value'} = $value; $vars->{'field'} = $field; + $vars->{'token'} = issue_session_token('add_field_value'); + $template->process("admin/fieldvalues/create.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -187,6 +191,7 @@ if ($action eq 'add') { # action='new' -> add field value entered in the 'action=add' screen # if ($action eq 'new') { + check_token_data($token, 'add_field_value'); FieldMustExist($field); trick_taint($field); @@ -218,6 +223,7 @@ if ($action eq 'new') { $sth->execute($value, $sortkey); unlink "$datadir/versioncache"; + delete_token($token); $vars->{'value'} = $value; $vars->{'field'} = $field; @@ -248,6 +254,8 @@ if ($action eq 'del') { $vars->{'value'} = $value; $vars->{'field'} = $field; $vars->{'param_name'} = $defaults{$field}; + $vars->{'token'} = issue_session_token('delete_field_value'); + $template->process("admin/fieldvalues/confirm-delete.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -260,6 +268,7 @@ if ($action eq 'del') { # action='delete' -> really delete the field value # if ($action eq 'delete') { + check_token_data($token, 'delete_field_value'); ValueMustExist($field, $value); if ($value eq Param($defaults{$field})) { ThrowUserError('fieldvalue_is_default', {field => $field, @@ -288,6 +297,7 @@ if ($action eq 'delete') { $dbh->bz_unlock_tables(); unlink "$datadir/versioncache"; + delete_token($token); $vars->{'value'} = $value; $vars->{'field'} = $field; @@ -312,6 +322,7 @@ if ($action eq 'edit') { $vars->{'value'} = $value; $vars->{'field'} = $field; + $vars->{'token'} = issue_session_token('edit_field_value'); $template->process("admin/fieldvalues/edit.html.tmpl", $vars) @@ -325,6 +336,7 @@ if ($action eq 'edit') { # action='update' -> update the field value # if ($action eq 'update') { + check_token_data($token, 'edit_field_value'); my $valueold = trim($cgi->param('valueold') || ''); my $sortkeyold = trim($cgi->param('sortkeyold') || '0'); @@ -396,6 +408,7 @@ if ($action eq 'update') { unlink "$datadir/versioncache"; $vars->{'default_value_updated'} = 1; } + delete_token($token); $vars->{'value'} = $value; $vars->{'field'} = $field; diff --git a/editversions.cgi b/editversions.cgi index 4ac83c5..9626c9e 100755 --- a/editversions.cgi +++ b/editversions.cgi @@ -21,7 +21,7 @@ # Contributor(s): Holger Schurig # Terry Weissman # Gavin Shelley -# Fr�d�ric Buclin +# Frédéric Buclin # # # Direct any questions on this source code to @@ -37,6 +37,7 @@ use Bugzilla::Constants; use Bugzilla::Config qw(:DEFAULT $datadir); use Bugzilla::Product; use Bugzilla::Version; +use Bugzilla::Token; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; @@ -63,6 +64,7 @@ my $product_name = trim($cgi->param('product') || ''); my $version_name = trim($cgi->param('version') || ''); my $action = trim($cgi->param('action') || ''); my $showbugcounts = (defined $cgi->param('showbugcounts')); +my $token = $cgi->param('token'); # # product = '' -> Show nice list of products @@ -110,7 +112,7 @@ unless ($action) { # if ($action eq 'add') { - + $vars->{'token'} = issue_session_token('add_version'); $vars->{'product'} = $product->name; $template->process("admin/versions/create.html.tmpl", $vars) @@ -126,7 +128,7 @@ if ($action eq 'add') { # if ($action eq 'new') { - + check_token_data($token, 'add_version'); # Cleanups and validity checks $version_name || ThrowUserError('version_blank_name'); @@ -147,6 +149,7 @@ if ($action eq 'new') { # Make versioncache flush unlink "$datadir/versioncache"; + delete_token($token); $vars->{'name'} = $version_name; $vars->{'product'} = $product->name; @@ -175,6 +178,8 @@ if ($action eq 'del') { $vars->{'bug_count'} = $bugs; $vars->{'name'} = $version->name; $vars->{'product'} = $product->name; + $vars->{'token'} = issue_session_token('delete_version'); + $template->process("admin/versions/confirm-delete.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -189,7 +194,7 @@ if ($action eq 'del') { # if ($action eq 'delete') { - + check_token_data($token, 'delete_version'); my $version = Bugzilla::Version::check_version($product, $version_name); @@ -204,6 +209,7 @@ if ($action eq 'delete') { undef, ($product->id, $version->name)); unlink "$datadir/versioncache"; + delete_token($token); $vars->{'name'} = $version->name; $vars->{'product'} = $product->name; @@ -228,6 +234,7 @@ if ($action eq 'edit') { $vars->{'name'} = $version->name; $vars->{'product'} = $product->name; + $vars->{'token'} = issue_session_token('edit_version'); $template->process("admin/versions/edit.html.tmpl", $vars) @@ -243,7 +250,7 @@ if ($action eq 'edit') { # if ($action eq 'update') { - + check_token_data($token, 'edit_version'); $version_name || ThrowUserError('version_not_specified'); # Remove unprintable characters @@ -288,7 +295,8 @@ if ($action eq 'update') { $vars->{'updated_name'} = 1; } - $dbh->bz_unlock_tables(); + $dbh->bz_unlock_tables(); + delete_token($token); $vars->{'name'} = $version_name; $vars->{'product'} = $product->name; diff --git a/editwhines.cgi b/editwhines.cgi index 8086862..cfa4443 100755 --- a/editwhines.cgi +++ b/editwhines.cgi @@ -33,6 +33,8 @@ require "globals.pl"; use Bugzilla::Constants; use Bugzilla::User; use Bugzilla::Group; +use Bugzilla::Token; + # require the user to have logged in my $user = Bugzilla->login(LOGIN_REQUIRED); @@ -46,7 +48,7 @@ my $vars = {}; my $dbh = Bugzilla->dbh; my $userid = $user->id; - +my $token = $cgi->param('token'); my $sth; # database statement handle # $events is a hash ref, keyed by event id, that stores the active user's @@ -83,6 +85,7 @@ my $can_mail_others = UserInGroup('bz_canusewhineatothers'); # removed, then what was altered. if ($cgi->param('update')) { + check_token_data($token, 'edit_whine'); if ($cgi->param("add_event")) { # we create a new event $sth = $dbh->prepare("INSERT INTO whine_events " . @@ -346,6 +349,7 @@ if ($cgi->param('update')) { } } } + delete_token($token); } $vars->{'mail_others'} = $can_mail_others; @@ -433,6 +437,7 @@ $vars->{'available_queries'} = []; while (my ($query) = $sth->fetchrow_array) { push @{$vars->{'available_queries'}}, $query; } +$vars->{'token'} = issue_session_token('edit_whine'); $template->process("whine/schedule.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/relogin.cgi b/relogin.cgi index 0d772f9..4dbd339 100755 --- a/relogin.cgi +++ b/relogin.cgi @@ -62,7 +62,7 @@ if ($action eq 'prepare-sudo') { } # Keep a temporary record of the user visiting this page - $vars->{'token'} = Bugzilla::Token::IssueSessionToken('sudo_prepared'); + $vars->{'token'} = issue_session_token('sudo_prepared'); # Show the sudo page $vars->{'target_login_default'} = $cgi->param('target_login'); @@ -124,7 +124,7 @@ elsif ($action eq 'begin-sudo') { { target_login => scalar $cgi->param('target_login'), reason => scalar $cgi->param('reason')}); } - Bugzilla::Token::DeleteToken($cgi->param('token')); + delete_token($cgi->param('token')); # Get & verify the target user (the user who we will be impersonating) my $target_user = diff --git a/skins/standard/global.css b/skins/standard/global.css index d313b19..bc60d6f 100644 --- a/skins/standard/global.css +++ b/skins/standard/global.css @@ -160,10 +160,10 @@ body #message { - border: 1px solid red; + border: 1px solid red; - padding: 0.3em; - color: green; + padding: 0.3em; + color: green; } /* header (end) */ @@ -335,3 +335,11 @@ td.tab.spacer } table#flags th, table#flags td { vertical-align: baseline; text-align: left; } + +.throw_error { + background-color: #ff0000; + color: black; + font-size: 120%; + margin: 1em; + padding: 0.5em 1em; +} diff --git a/template/en/default/admin/classifications/add.html.tmpl b/template/en/default/admin/classifications/add.html.tmpl index d6a7c38..a2134e5 100644 --- a/template/en/default/admin/classifications/add.html.tmpl +++ b/template/en/default/admin/classifications/add.html.tmpl @@ -37,6 +37,7 @@
+

Back to the main [% terms.bugs %] page diff --git a/template/en/default/admin/classifications/del.html.tmpl b/template/en/default/admin/classifications/del.html.tmpl index 7f54a18..9fc1b0c 100644 --- a/template/en/default/admin/classifications/del.html.tmpl +++ b/template/en/default/admin/classifications/del.html.tmpl @@ -52,6 +52,7 @@ +

Back to the main [% terms.bugs %] page diff --git a/template/en/default/admin/classifications/edit.html.tmpl b/template/en/default/admin/classifications/edit.html.tmpl index 60ece58..77af7f8 100644 --- a/template/en/default/admin/classifications/edit.html.tmpl +++ b/template/en/default/admin/classifications/edit.html.tmpl @@ -67,6 +67,7 @@ + diff --git a/template/en/default/admin/classifications/reclassify.html.tmpl b/template/en/default/admin/classifications/reclassify.html.tmpl index b89f83d..830a01a 100644 --- a/template/en/default/admin/classifications/reclassify.html.tmpl +++ b/template/en/default/admin/classifications/reclassify.html.tmpl @@ -78,6 +78,7 @@ +

Back to the main [% terms.bugs %] page, diff --git a/template/en/default/admin/components/confirm-delete.html.tmpl b/template/en/default/admin/components/confirm-delete.html.tmpl index 1641884..4ec8d9b 100644 --- a/template/en/default/admin/components/confirm-delete.html.tmpl +++ b/template/en/default/admin/components/confirm-delete.html.tmpl @@ -150,6 +150,7 @@ + [% END %] diff --git a/template/en/default/admin/components/create.html.tmpl b/template/en/default/admin/components/create.html.tmpl index fcb57bb..0e5c924 100644 --- a/template/en/default/admin/components/create.html.tmpl +++ b/template/en/default/admin/components/create.html.tmpl @@ -78,7 +78,7 @@ - + [% PROCESS admin/components/footer.html.tmpl %] diff --git a/template/en/default/admin/components/edit.html.tmpl b/template/en/default/admin/components/edit.html.tmpl index 8b350d9..7fa3748 100644 --- a/template/en/default/admin/components/edit.html.tmpl +++ b/template/en/default/admin/components/edit.html.tmpl @@ -94,6 +94,7 @@ + or + #%] + +[%# INTERFACE: + # abuser: identity of the user who created the (invalid?) token. + # token_action: the action the token was supposed to serve. + # expected_action: the action the user was going to do. + # script_name: the script generating this warning. + #%] + +[% PROCESS "global/field-descs.none.tmpl" %] + +[% PROCESS global/header.html.tmpl title = "Suspicious Action" + style_urls = ['skins/standard/global.css'] %] + +[% IF abuser %] +

+[% ELSE %] +
+ It looks like you didn't come from the right page (you have no valid token for + the [% expected_action FILTER html %] action while processing the + '[% script_name FILTER html%]' script). The reason could be one of:
+
    +
  • You clicked the "Back" button of your web browser after having successfully + submitted changes, which is generally not a good idea (but harmless).
  • +
  • You entered the URL in the address bar of your web browser directly, + which should be safe.
  • +
  • You clicked on a URL which redirected you here without your consent, + in which case this action is much more critical.
  • +
+ Are you sure you want to commit these changes anyway? This may result in + unexpected and undesired results. +
+ +
+ [% PROCESS "global/hidden-fields.html.tmpl" + exclude="^(Bugzilla_login|Bugzilla_password)$" %] + +
+

Or throw away these changes and go back to + [%- script_name FILTER html %].

+[% END %] + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl b/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl index 31deb54..7ee946d 100644 --- a/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl +++ b/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl @@ -111,6 +111,7 @@ + [% END %] diff --git a/template/en/default/admin/fieldvalues/create.html.tmpl b/template/en/default/admin/fieldvalues/create.html.tmpl index a23c8dd..0bec8c2 100644 --- a/template/en/default/admin/fieldvalues/create.html.tmpl +++ b/template/en/default/admin/fieldvalues/create.html.tmpl @@ -42,7 +42,7 @@ - +

diff --git a/template/en/default/admin/fieldvalues/edit.html.tmpl b/template/en/default/admin/fieldvalues/edit.html.tmpl index 58de861..145f6a8 100644 --- a/template/en/default/admin/fieldvalues/edit.html.tmpl +++ b/template/en/default/admin/fieldvalues/edit.html.tmpl @@ -48,8 +48,8 @@ + -

diff --git a/template/en/default/admin/flag-type/confirm-delete.html.tmpl b/template/en/default/admin/flag-type/confirm-delete.html.tmpl index 99dba14..e67412a 100644 --- a/template/en/default/admin/flag-type/confirm-delete.html.tmpl +++ b/template/en/default/admin/flag-type/confirm-delete.html.tmpl @@ -21,18 +21,16 @@ [% PROCESS global/variables.none.tmpl %] -[%# Filter off the name here to be used multiple times below %] -[% name = BLOCK %][% flag_type.name FILTER html %][% END %] +[% title = BLOCK %]Confirm Deletion of Flag Type '[% flag_type.name FILTER html %]'[% END %] -[% PROCESS global/header.html.tmpl - title = "Confirm Deletion of Flag Type '$name'" -%] +[% PROCESS global/header.html.tmpl title = title %]

- There are [% flag_count %] flags of type [% name FILTER html %]. + There are [% flag_count %] flags of type [% flag_type.name FILTER html %]. If you delete this type, those flags will also be deleted. Note that instead of deleting the type you can - deactivate it, + deactivate it, in which case the type and its flags will remain in the database but will not appear in the [% terms.Bugzilla %] UI.

@@ -45,8 +43,8 @@ - - Yes, delete + Yes, delete diff --git a/template/en/default/admin/flag-type/edit.html.tmpl b/template/en/default/admin/flag-type/edit.html.tmpl index 11c951f..e0abf0d 100644 --- a/template/en/default/admin/flag-type/edit.html.tmpl +++ b/template/en/default/admin/flag-type/edit.html.tmpl @@ -63,6 +63,7 @@
+ [% FOREACH category = type.inclusions %] diff --git a/template/en/default/admin/flag-type/list.html.tmpl b/template/en/default/admin/flag-type/list.html.tmpl index 66467d3..a94e59c 100644 --- a/template/en/default/admin/flag-type/list.html.tmpl +++ b/template/en/default/admin/flag-type/list.html.tmpl @@ -59,25 +59,6 @@ Create Flag Type For Attachments

- - [% PROCESS global/footer.html.tmpl %] @@ -97,9 +78,7 @@ [% type.description FILTER html %] Copy - | Delete + | Delete diff --git a/template/en/default/admin/groups/create.html.tmpl b/template/en/default/admin/groups/create.html.tmpl index 8da00a7..18c08fc 100644 --- a/template/en/default/admin/groups/create.html.tmpl +++ b/template/en/default/admin/groups/create.html.tmpl @@ -49,6 +49,7 @@ Insert new group into all existing products.

+

Name is what is used with the UserInGroup() function in any diff --git a/template/en/default/admin/groups/delete.html.tmpl b/template/en/default/admin/groups/delete.html.tmpl index f52ace0..24c0519 100644 --- a/template/en/default/admin/groups/delete.html.tmpl +++ b/template/en/default/admin/groups/delete.html.tmpl @@ -103,6 +103,7 @@

+ Go back to the group list. diff --git a/template/en/default/admin/groups/edit.html.tmpl b/template/en/default/admin/groups/edit.html.tmpl index e317770..f323c60 100644 --- a/template/en/default/admin/groups/edit.html.tmpl +++ b/template/en/default/admin/groups/edit.html.tmpl @@ -214,6 +214,7 @@ + Back to the group list. diff --git a/template/en/default/admin/keywords/confirm-delete.html.tmpl b/template/en/default/admin/keywords/confirm-delete.html.tmpl index cfe8bf7..3329a54 100755 --- a/template/en/default/admin/keywords/confirm-delete.html.tmpl +++ b/template/en/default/admin/keywords/confirm-delete.html.tmpl @@ -46,6 +46,7 @@ + diff --git a/template/en/default/admin/keywords/create.html.tmpl b/template/en/default/admin/keywords/create.html.tmpl index 006b4b3..861c6f1 100755 --- a/template/en/default/admin/keywords/create.html.tmpl +++ b/template/en/default/admin/keywords/create.html.tmpl @@ -47,6 +47,7 @@ +

Edit other keywords.

diff --git a/template/en/default/admin/keywords/edit.html.tmpl b/template/en/default/admin/keywords/edit.html.tmpl index 3809563..16b31da 100755 --- a/template/en/default/admin/keywords/edit.html.tmpl +++ b/template/en/default/admin/keywords/edit.html.tmpl @@ -62,6 +62,7 @@ +

Edit other keywords.

diff --git a/template/en/default/admin/milestones/confirm-delete.html.tmpl b/template/en/default/admin/milestones/confirm-delete.html.tmpl index 61601d1..1eb4e0f 100644 --- a/template/en/default/admin/milestones/confirm-delete.html.tmpl +++ b/template/en/default/admin/milestones/confirm-delete.html.tmpl @@ -91,6 +91,7 @@ + [% PROCESS admin/milestones/footer.html.tmpl %] diff --git a/template/en/default/admin/milestones/create.html.tmpl b/template/en/default/admin/milestones/create.html.tmpl index d8779dd..6e3b4b2 100644 --- a/template/en/default/admin/milestones/create.html.tmpl +++ b/template/en/default/admin/milestones/create.html.tmpl @@ -48,7 +48,7 @@ - +

diff --git a/template/en/default/admin/milestones/edit.html.tmpl b/template/en/default/admin/milestones/edit.html.tmpl index f49cacf..3daf076 100644 --- a/template/en/default/admin/milestones/edit.html.tmpl +++ b/template/en/default/admin/milestones/edit.html.tmpl @@ -56,7 +56,7 @@ - +

diff --git a/template/en/default/admin/params/editparams.html.tmpl b/template/en/default/admin/params/editparams.html.tmpl index 0560cac..5d30906 100644 --- a/template/en/default/admin/params/editparams.html.tmpl +++ b/template/en/default/admin/params/editparams.html.tmpl @@ -99,6 +99,7 @@ [% PROCESS admin/params/common.html.tmpl panel = current_panel %] + diff --git a/template/en/default/admin/products/confirm-delete.html.tmpl b/template/en/default/admin/products/confirm-delete.html.tmpl index 23550f2..5e2cddd 100644 --- a/template/en/default/admin/products/confirm-delete.html.tmpl +++ b/template/en/default/admin/products/confirm-delete.html.tmpl @@ -263,6 +263,7 @@ + diff --git a/template/en/default/admin/products/create.html.tmpl b/template/en/default/admin/products/create.html.tmpl index fd1ed34..5fb7d8b 100644 --- a/template/en/default/admin/products/create.html.tmpl +++ b/template/en/default/admin/products/create.html.tmpl @@ -57,6 +57,7 @@ + diff --git a/template/en/default/admin/products/edit.html.tmpl b/template/en/default/admin/products/edit.html.tmpl index 105ec6e..0371e33 100644 --- a/template/en/default/admin/products/edit.html.tmpl +++ b/template/en/default/admin/products/edit.html.tmpl @@ -132,6 +132,7 @@ versions: + diff --git a/template/en/default/admin/products/groupcontrol/edit.html.tmpl b/template/en/default/admin/products/groupcontrol/edit.html.tmpl index 174d158..32b5e9d 100644 --- a/template/en/default/admin/products/groupcontrol/edit.html.tmpl +++ b/template/en/default/admin/products/groupcontrol/edit.html.tmpl @@ -31,6 +31,7 @@

+ diff --git a/template/en/default/admin/settings/edit.html.tmpl b/template/en/default/admin/settings/edit.html.tmpl index 85663f1..b0b5e55 100644 --- a/template/en/default/admin/settings/edit.html.tmpl +++ b/template/en/default/admin/settings/edit.html.tmpl @@ -85,6 +85,7 @@ page, and the Default Value will automatically apply to everyone. + diff --git a/template/en/default/admin/users/confirm-delete.html.tmpl b/template/en/default/admin/users/confirm-delete.html.tmpl index 68d7078..c52b1a2 100644 --- a/template/en/default/admin/users/confirm-delete.html.tmpl +++ b/template/en/default/admin/users/confirm-delete.html.tmpl @@ -429,6 +429,7 @@ + [% INCLUDE listselectionhiddenfields %]

diff --git a/template/en/default/admin/users/create.html.tmpl b/template/en/default/admin/users/create.html.tmpl index 42aefbd..ffff303 100644 --- a/template/en/default/admin/users/create.html.tmpl +++ b/template/en/default/admin/users/create.html.tmpl @@ -41,6 +41,7 @@

+ [% INCLUDE listselectionhiddenfields %]

diff --git a/template/en/default/admin/users/edit.html.tmpl b/template/en/default/admin/users/edit.html.tmpl index 8f8e669..2d19a06 100644 --- a/template/en/default/admin/users/edit.html.tmpl +++ b/template/en/default/admin/users/edit.html.tmpl @@ -106,6 +106,7 @@ + [% INCLUDE listselectionhiddenfields %]

diff --git a/template/en/default/admin/versions/confirm-delete.html.tmpl b/template/en/default/admin/versions/confirm-delete.html.tmpl index 34ada60..27e8936 100644 --- a/template/en/default/admin/versions/confirm-delete.html.tmpl +++ b/template/en/default/admin/versions/confirm-delete.html.tmpl @@ -93,6 +93,7 @@ + [% END %] diff --git a/template/en/default/admin/versions/create.html.tmpl b/template/en/default/admin/versions/create.html.tmpl index 594bf4f..63f6784 100644 --- a/template/en/default/admin/versions/create.html.tmpl +++ b/template/en/default/admin/versions/create.html.tmpl @@ -42,7 +42,7 @@ - +

diff --git a/template/en/default/admin/versions/edit.html.tmpl b/template/en/default/admin/versions/edit.html.tmpl index ef1fbd2..f5f6453 100644 --- a/template/en/default/admin/versions/edit.html.tmpl +++ b/template/en/default/admin/versions/edit.html.tmpl @@ -47,8 +47,8 @@ + -

diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl index 0440c0a..9c9fa94 100644 --- a/template/en/default/filterexceptions.pl +++ b/template/en/default/filterexceptions.pl @@ -529,7 +529,6 @@ 'admin/flag-type/list.html.tmpl' => [ 'type.id', - 'type.flag_count', ], diff --git a/template/en/default/whine/schedule.html.tmpl b/template/en/default/whine/schedule.html.tmpl index b49f713..b158f5c 100644 --- a/template/en/default/whine/schedule.html.tmpl +++ b/template/en/default/whine/schedule.html.tmpl @@ -82,6 +82,7 @@ + [% FOREACH event = events %]