From 81d0ccc2e1c88cb70bfb9b32ba8ac47798fe3125 Mon Sep 17 00:00:00 2001 From: "bzrmirror%bugzilla.org" Date: Wed, 3 Dec 2014 22:39:24 +0000 Subject: [PATCH] Merge branch 'master' of ssh://git.mozilla.org/bugzilla/bugzilla into docs-relicensing (except some changes not merged; will do them later) Conflicts: docs/en/rst/administration.rst docs/en/rst/installation.rst docs/en/rst/using.rst git-svn-id: svn://10.0.0.236/trunk@265740 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/webtools/bugzilla/.bzrrev | 2 +- mozilla/webtools/bugzilla/.gitrev | 2 +- mozilla/webtools/bugzilla/.htaccess | 1 + mozilla/webtools/bugzilla/.travis.yml | 31 +- mozilla/webtools/bugzilla/Bugzilla.pm | 29 +- .../webtools/bugzilla/Bugzilla/Attachment.pm | 45 +- .../Bugzilla/Attachment/PatchReader.pm | 87 +-- mozilla/webtools/bugzilla/Bugzilla/Auth.pm | 5 +- .../webtools/bugzilla/Bugzilla/Auth/Login.pm | 2 + .../bugzilla/Bugzilla/Auth/Login/APIKey.pm | 53 ++ .../bugzilla/Bugzilla/Auth/Login/CGI.pm | 1 + .../bugzilla/Bugzilla/Auth/Login/Cookie.pm | 18 +- .../bugzilla/Bugzilla/Auth/Login/Env.pm | 2 +- .../bugzilla/Bugzilla/Auth/Login/Stack.pm | 1 + .../bugzilla/Bugzilla/Auth/Persist/Cookie.pm | 2 + .../webtools/bugzilla/Bugzilla/Auth/Verify.pm | 2 + .../bugzilla/Bugzilla/Auth/Verify/DB.pm | 18 +- .../bugzilla/Bugzilla/Auth/Verify/LDAP.pm | 1 + .../bugzilla/Bugzilla/Auth/Verify/RADIUS.pm | 1 + .../bugzilla/Bugzilla/Auth/Verify/Stack.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Bug.pm | 197 +++++-- mozilla/webtools/bugzilla/Bugzilla/BugMail.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/BugUrl.pm | 1 + .../bugzilla/Bugzilla/BugUrl/Bugzilla.pm | 1 + .../Bugzilla/BugUrl/Bugzilla/Local.pm | 1 + .../bugzilla/Bugzilla/BugUrl/Debian.pm | 1 + .../bugzilla/Bugzilla/BugUrl/GitHub.pm | 5 +- .../bugzilla/Bugzilla/BugUrl/Google.pm | 1 + .../webtools/bugzilla/Bugzilla/BugUrl/JIRA.pm | 1 + .../bugzilla/Bugzilla/BugUrl/Launchpad.pm | 1 + .../bugzilla/Bugzilla/BugUrl/MantisBT.pm | 1 + .../bugzilla/Bugzilla/BugUrl/SourceForge.pm | 1 + .../webtools/bugzilla/Bugzilla/BugUrl/Trac.pm | 1 + .../bugzilla/Bugzilla/BugUserLastVisit.pm | 10 + mozilla/webtools/bugzilla/Bugzilla/CGI.pm | 17 +- mozilla/webtools/bugzilla/Bugzilla/Chart.pm | 8 +- .../bugzilla/Bugzilla/Classification.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Comment.pm | 19 + .../bugzilla/Bugzilla/Comment/TagWeights.pm | 1 + .../webtools/bugzilla/Bugzilla/Component.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Config.pm | 128 +++-- .../bugzilla/Bugzilla/Config/Admin.pm | 1 + .../bugzilla/Bugzilla/Config/Advanced.pm | 1 + .../bugzilla/Bugzilla/Config/Attachment.pm | 9 + .../webtools/bugzilla/Bugzilla/Config/Auth.pm | 10 +- .../bugzilla/Bugzilla/Config/BugChange.pm | 1 + .../bugzilla/Bugzilla/Config/BugFields.pm | 1 + .../bugzilla/Bugzilla/Config/Common.pm | 32 +- .../webtools/bugzilla/Bugzilla/Config/Core.pm | 1 + .../Bugzilla/Config/DependencyGraph.pm | 1 + .../bugzilla/Bugzilla/Config/General.pm | 1 + .../bugzilla/Bugzilla/Config/GroupSecurity.pm | 1 + .../webtools/bugzilla/Bugzilla/Config/LDAP.pm | 1 + .../webtools/bugzilla/Bugzilla/Config/MTA.pm | 15 +- .../bugzilla/Bugzilla/Config/Memcached.pm | 1 + .../bugzilla/Bugzilla/Config/PatchViewer.pm | 52 -- .../bugzilla/Bugzilla/Config/Query.pm | 1 + .../bugzilla/Bugzilla/Config/RADIUS.pm | 1 + .../bugzilla/Bugzilla/Config/ShadowDB.pm | 1 + .../bugzilla/Bugzilla/Config/UserMatch.pm | 1 + .../webtools/bugzilla/Bugzilla/Constants.pm | 16 +- mozilla/webtools/bugzilla/Bugzilla/DB.pm | 21 +- .../webtools/bugzilla/Bugzilla/DB/Mysql.pm | 9 +- .../webtools/bugzilla/Bugzilla/DB/Oracle.pm | 2 + mozilla/webtools/bugzilla/Bugzilla/DB/Pg.pm | 4 + .../webtools/bugzilla/Bugzilla/DB/Schema.pm | 54 +- .../bugzilla/Bugzilla/DB/Schema/Mysql.pm | 1 + .../bugzilla/Bugzilla/DB/Schema/Oracle.pm | 1 + .../bugzilla/Bugzilla/DB/Schema/Pg.pm | 1 + .../bugzilla/Bugzilla/DB/Schema/Sqlite.pm | 1 + .../webtools/bugzilla/Bugzilla/DB/Sqlite.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Error.pm | 1 + .../webtools/bugzilla/Bugzilla/Extension.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Field.pm | 1 + .../bugzilla/Bugzilla/Field/Choice.pm | 1 + .../Bugzilla/Field/ChoiceInterface.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Flag.pm | 145 ++++- .../webtools/bugzilla/Bugzilla/FlagType.pm | 20 +- mozilla/webtools/bugzilla/Bugzilla/Group.pm | 7 +- mozilla/webtools/bugzilla/Bugzilla/Hook.pm | 4 +- mozilla/webtools/bugzilla/Bugzilla/Install.pm | 3 + .../bugzilla/Bugzilla/Install/CPAN.pm | 1 + .../webtools/bugzilla/Bugzilla/Install/DB.pm | 48 +- .../bugzilla/Bugzilla/Install/Filesystem.pm | 28 +- .../bugzilla/Bugzilla/Install/Localconfig.pm | 5 +- .../bugzilla/Bugzilla/Install/Requirements.pm | 39 +- .../bugzilla/Bugzilla/Install/Util.pm | 1 + .../webtools/bugzilla/Bugzilla/Job/BugMail.pm | 1 + .../webtools/bugzilla/Bugzilla/Job/Mailer.pm | 1 + .../webtools/bugzilla/Bugzilla/JobQueue.pm | 1 + .../bugzilla/Bugzilla/JobQueue/Runner.pm | 6 +- mozilla/webtools/bugzilla/Bugzilla/Keyword.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Mailer.pm | 122 ++-- .../webtools/bugzilla/Bugzilla/Markdown.pm | 520 ++++++++++++++++++ .../webtools/bugzilla/Bugzilla/Memcached.pm | 14 +- mozilla/webtools/bugzilla/Bugzilla/Migrate.pm | 1 + .../bugzilla/Bugzilla/Migrate/Gnats.pm | 1 + .../webtools/bugzilla/Bugzilla/Milestone.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Object.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Product.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/RNG.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Report.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Search.pm | 35 +- .../bugzilla/Bugzilla/Search/Clause.pm | 1 + .../bugzilla/Bugzilla/Search/ClauseGroup.pm | 1 + .../bugzilla/Bugzilla/Search/Condition.pm | 1 + .../bugzilla/Bugzilla/Search/Quicksearch.pm | 3 +- .../bugzilla/Bugzilla/Search/Recent.pm | 1 + .../bugzilla/Bugzilla/Search/Saved.pm | 1 + .../{Send => Sender/Transport}/Sendmail.pm | 48 +- mozilla/webtools/bugzilla/Bugzilla/Series.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Status.pm | 1 + .../webtools/bugzilla/Bugzilla/Template.pm | 129 ++++- .../bugzilla/Bugzilla/Template/Context.pm | 1 + .../Bugzilla/Template/Plugin/Bugzilla.pm | 1 + .../bugzilla/Bugzilla/Template/Plugin/Hook.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Token.pm | 26 +- mozilla/webtools/bugzilla/Bugzilla/Update.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/User.pm | 50 +- .../webtools/bugzilla/Bugzilla/User/APIKey.pm | 155 ++++++ .../bugzilla/Bugzilla/User/Setting.pm | 42 +- .../bugzilla/Bugzilla/User/Setting/Lang.pm | 1 + .../bugzilla/Bugzilla/User/Setting/Skin.pm | 1 + .../Bugzilla/User/Setting/Timezone.pm | 1 + .../webtools/bugzilla/Bugzilla/UserAgent.pm | 1 + mozilla/webtools/bugzilla/Bugzilla/Util.pm | 22 +- mozilla/webtools/bugzilla/Bugzilla/Version.pm | 1 + .../webtools/bugzilla/Bugzilla/WebService.pm | 39 +- .../bugzilla/Bugzilla/WebService/Bug.pm | 216 ++++++-- .../Bugzilla/WebService/BugUserLastVisit.pm | 16 +- .../bugzilla/Bugzilla/WebService/Bugzilla.pm | 1 + .../Bugzilla/WebService/Classification.pm | 1 + .../bugzilla/Bugzilla/WebService/Component.pm | 149 +++++ .../bugzilla/Bugzilla/WebService/Constants.pm | 14 +- .../bugzilla/Bugzilla/WebService/FlagType.pm | 1 + .../bugzilla/Bugzilla/WebService/Group.pm | 5 +- .../bugzilla/Bugzilla/WebService/Product.pm | 1 + .../bugzilla/Bugzilla/WebService/Server.pm | 1 + .../Bugzilla/WebService/Server/JSONRPC.pm | 5 +- .../Bugzilla/WebService/Server/REST.pm | 35 +- .../WebService/Server/REST/Resources/Bug.pm | 6 + .../Server/REST/Resources/Bugzilla.pm | 1 + .../Server/REST/Resources/Classification.pm | 1 + .../Server/REST/Resources/Component.pm | 48 ++ .../Server/REST/Resources/FlagType.pm | 1 + .../WebService/Server/REST/Resources/Group.pm | 1 + .../Server/REST/Resources/Product.pm | 1 + .../WebService/Server/REST/Resources/User.pm | 1 + .../Bugzilla/WebService/Server/XMLRPC.pm | 4 + .../bugzilla/Bugzilla/WebService/User.pm | 17 +- .../bugzilla/Bugzilla/WebService/Util.pm | 6 + mozilla/webtools/bugzilla/Bugzilla/Whine.pm | 1 + .../webtools/bugzilla/Bugzilla/Whine/Query.pm | 1 + .../bugzilla/Bugzilla/Whine/Schedule.pm | 1 + mozilla/webtools/bugzilla/admin.cgi | 4 +- mozilla/webtools/bugzilla/attachment.cgi | 156 +++--- mozilla/webtools/bugzilla/buglist.cgi | 46 +- mozilla/webtools/bugzilla/chart.cgi | 4 +- mozilla/webtools/bugzilla/checksetup.pl | 10 +- .../bugzilla/clean-bug-user-last-visit.pl | 2 +- mozilla/webtools/bugzilla/colchange.cgi | 4 +- mozilla/webtools/bugzilla/collectstats.pl | 4 +- mozilla/webtools/bugzilla/config.cgi | 4 +- mozilla/webtools/bugzilla/contrib/Bugzilla.pm | 1 + mozilla/webtools/bugzilla/contrib/README | 4 + .../bugzilla/contrib/bz_webservice_demo.pl | 5 +- mozilla/webtools/bugzilla/contrib/bzdbcopy.pl | 5 +- mozilla/webtools/bugzilla/contrib/console.pl | 6 +- .../bugzilla/contrib/convert-workflow.pl | 5 +- .../bugzilla/contrib/extension-convert.pl | 8 +- mozilla/webtools/bugzilla/contrib/fixperms.pl | 4 +- .../webtools/bugzilla/contrib/merge-users.pl | 13 +- .../bugzilla/contrib/mysqld-watcher.pl | 4 +- mozilla/webtools/bugzilla/contrib/recode.pl | 5 +- mozilla/webtools/bugzilla/contrib/replyrc | 30 + .../webtools/bugzilla/contrib/sendbugmail.pl | 4 +- .../bugzilla/contrib/sendunsentbugmail.pl | 4 +- mozilla/webtools/bugzilla/contrib/syncLDAP.pl | 4 +- mozilla/webtools/bugzilla/createaccount.cgi | 4 +- .../webtools/bugzilla/describecomponents.cgi | 4 +- .../webtools/bugzilla/describekeywords.cgi | 4 +- .../bugzilla/docs/en/rst/about/index.rst | 8 +- mozilla/webtools/bugzilla/duplicates.cgi | 4 +- .../webtools/bugzilla/editclassifications.cgi | 4 +- mozilla/webtools/bugzilla/editcomponents.cgi | 4 +- mozilla/webtools/bugzilla/editfields.cgi | 4 +- mozilla/webtools/bugzilla/editflagtypes.cgi | 25 +- mozilla/webtools/bugzilla/editgroups.cgi | 11 +- mozilla/webtools/bugzilla/editkeywords.cgi | 4 +- mozilla/webtools/bugzilla/editmilestones.cgi | 4 +- mozilla/webtools/bugzilla/editparams.cgi | 4 +- mozilla/webtools/bugzilla/editproducts.cgi | 4 +- mozilla/webtools/bugzilla/editsettings.cgi | 5 +- mozilla/webtools/bugzilla/editusers.cgi | 8 +- mozilla/webtools/bugzilla/editvalues.cgi | 8 +- mozilla/webtools/bugzilla/editversions.cgi | 4 +- mozilla/webtools/bugzilla/editwhines.cgi | 4 +- mozilla/webtools/bugzilla/editworkflow.cgi | 4 +- mozilla/webtools/bugzilla/email_in.pl | 2 +- mozilla/webtools/bugzilla/enter_bug.cgi | 4 +- .../bugzilla/extensions/BmpConvert/Config.pm | 2 + .../extensions/BmpConvert/Extension.pm | 2 + .../bugzilla/extensions/Example/Config.pm | 2 + .../bugzilla/extensions/Example/Extension.pm | 2 + .../extensions/Example/lib/Auth/Login.pm | 2 + .../extensions/Example/lib/Auth/Verify.pm | 2 + .../hook/search/tabs-search_tabs.html.tmpl | 6 +- .../bugzilla/extensions/MoreBugUrl/Config.pm | 1 + .../extensions/MoreBugUrl/Extension.pm | 2 + .../extensions/MoreBugUrl/lib/BitBucket.pm | 2 + .../MoreBugUrl/lib/GetSatisfaction.pm | 2 + .../bugzilla/extensions/MoreBugUrl/lib/PHP.pm | 2 + .../bugzilla/extensions/MoreBugUrl/lib/RT.pm | 2 + .../extensions/MoreBugUrl/lib/Redmine.pm | 2 + .../extensions/MoreBugUrl/lib/ReviewBoard.pm | 2 + .../extensions/MoreBugUrl/lib/Rietveld.pm | 2 + .../extensions/MoreBugUrl/lib/Savane.pm | 2 + .../bugzilla/extensions/OldBugMove/Config.pm | 2 + .../extensions/OldBugMove/Extension.pm | 2 + .../extensions/OldBugMove/lib/Params.pm | 1 + .../bugzilla/extensions/Voting/Config.pm | 1 + .../bugzilla/extensions/Voting/Extension.pm | 2 + .../webtools/bugzilla/extensions/create.pl | 4 +- mozilla/webtools/bugzilla/importxml.pl | 3 +- mozilla/webtools/bugzilla/index.cgi | 4 +- mozilla/webtools/bugzilla/install-module.pl | 2 +- mozilla/webtools/bugzilla/jobqueue.pl | 18 +- mozilla/webtools/bugzilla/js/bug.js | 10 +- .../webtools/bugzilla/js/comment-tagging.js | 19 +- mozilla/webtools/bugzilla/js/field.js | 63 ++- mozilla/webtools/bugzilla/jsonrpc.cgi | 4 +- mozilla/webtools/bugzilla/migrate.pl | 4 +- mozilla/webtools/bugzilla/mod_perl.pl | 4 +- mozilla/webtools/bugzilla/page.cgi | 4 +- mozilla/webtools/bugzilla/post_bug.cgi | 14 +- mozilla/webtools/bugzilla/process_bug.cgi | 48 +- mozilla/webtools/bugzilla/query.cgi | 4 +- mozilla/webtools/bugzilla/quips.cgi | 4 +- mozilla/webtools/bugzilla/relogin.cgi | 35 +- mozilla/webtools/bugzilla/report.cgi | 4 +- mozilla/webtools/bugzilla/reports.cgi | 4 +- mozilla/webtools/bugzilla/request.cgi | 4 +- mozilla/webtools/bugzilla/rest.cgi | 4 +- mozilla/webtools/bugzilla/runtests.pl | 4 +- mozilla/webtools/bugzilla/sanitycheck.cgi | 4 +- mozilla/webtools/bugzilla/sanitycheck.pl | 4 +- mozilla/webtools/bugzilla/search_plugin.cgi | 4 +- mozilla/webtools/bugzilla/show_activity.cgi | 4 +- mozilla/webtools/bugzilla/show_bug.cgi | 4 +- .../webtools/bugzilla/showdependencygraph.cgi | 4 +- .../webtools/bugzilla/showdependencytree.cgi | 4 +- .../webtools/bugzilla/skins/standard/bug.css | 4 +- .../bugzilla/skins/standard/global.css | 17 +- mozilla/webtools/bugzilla/summarize_time.cgi | 4 +- mozilla/webtools/bugzilla/t/001compile.t | 6 +- mozilla/webtools/bugzilla/t/002goodperl.t | 102 ++-- mozilla/webtools/bugzilla/t/003safesys.t | 4 +- mozilla/webtools/bugzilla/t/004template.t | 5 +- mozilla/webtools/bugzilla/t/005whitespace.t | 2 + mozilla/webtools/bugzilla/t/006spellcheck.t | 45 +- mozilla/webtools/bugzilla/t/007util.t | 8 +- mozilla/webtools/bugzilla/t/008filter.t | 12 +- mozilla/webtools/bugzilla/t/009bugwords.t | 2 + mozilla/webtools/bugzilla/t/010dependencies.t | 3 + mozilla/webtools/bugzilla/t/011pod.t | 6 +- mozilla/webtools/bugzilla/t/012throwables.t | 3 + mozilla/webtools/bugzilla/t/013dbschema.t | 3 + mozilla/webtools/bugzilla/t/Support/Files.pm | 18 +- .../webtools/bugzilla/t/Support/Systemexec.pm | 5 + .../webtools/bugzilla/t/Support/Templates.pm | 35 +- .../account/auth/login-small.html.tmpl | 3 + .../en/default/account/prefs/apikey.html.tmpl | 84 +++ .../en/default/account/prefs/prefs.html.tmpl | 5 +- .../en/default/admin/groups/list.html.tmpl | 3 +- .../default/admin/params/attachment.html.tmpl | 28 +- .../en/default/admin/params/auth.html.tmpl | 6 + .../en/default/admin/params/mta.html.tmpl | 12 +- .../admin/params/patchviewer.html.tmpl | 51 -- .../en/default/admin/products/edit.html.tmpl | 6 +- .../admin/users/responsibilities.html.tmpl | 14 +- .../en/default/attachment/diff-file.html.tmpl | 18 +- .../default/attachment/diff-header.html.tmpl | 32 +- .../template/en/default/bug/comment.html.tmpl | 12 +- .../en/default/bug/comments.html.tmpl | 56 +- .../template/en/default/bug/edit.html.tmpl | 134 +++-- .../en/default/bug/field-label.html.tmpl | 11 +- .../template/en/default/bug/link.html.tmpl | 4 +- .../en/default/bug/process/midair.html.tmpl | 1 + .../en/default/bug/show-header.html.tmpl | 8 +- .../en/default/bug/show-multiple.html.tmpl | 7 +- .../template/en/default/config.rdf.tmpl | 14 +- .../en/default/email/bugmail.html.tmpl | 2 +- .../en/default/email/flagmail.txt.tmpl | 13 +- .../en/default/email/new-api-key.txt.tmpl | 33 ++ .../en/default/extensions/config.pm.tmpl | 1 + .../en/default/extensions/extension.pm.tmpl | 2 + .../en/default/extensions/util.pm.tmpl | 2 + .../template/en/default/filterexceptions.pl | 9 +- .../template/en/default/flag/list.html.tmpl | 13 + .../global/choose-classification.html.tmpl | 4 +- .../default/global/choose-product.html.tmpl | 4 +- .../en/default/global/header.html.tmpl | 50 +- .../en/default/global/messages.html.tmpl | 2 +- .../en/default/global/setting-descs.none.tmpl | 3 +- .../default/global/site-navigation.html.tmpl | 75 --- .../en/default/global/user-error.html.tmpl | 45 +- .../en/default/list/change-columns.html.tmpl | 2 +- .../en/default/list/edit-multiple.html.tmpl | 7 + .../template/en/default/list/list.html.tmpl | 54 +- .../en/default/pages/linked.html.tmpl | 4 +- .../en/default/pages/markdown.html.tmpl | 265 +++++++++ .../en/default/pages/release-notes.html.tmpl | 6 +- .../en/default/reports/create-chart.html.tmpl | 2 + .../en/default/reports/report-table.csv.tmpl | 8 +- .../default/search/boolean-charts.html.tmpl | 10 +- .../search/search-report-select.html.tmpl | 2 +- .../default/search/search-specific.html.tmpl | 2 +- .../template/en/default/setup/strings.txt.pl | 6 +- mozilla/webtools/bugzilla/testagent.cgi | 3 +- mozilla/webtools/bugzilla/testserver.pl | 6 +- mozilla/webtools/bugzilla/token.cgi | 11 +- mozilla/webtools/bugzilla/userprefs.cgi | 66 ++- mozilla/webtools/bugzilla/votes.cgi | 4 +- mozilla/webtools/bugzilla/whine.pl | 4 +- mozilla/webtools/bugzilla/whineatnews.pl | 4 +- mozilla/webtools/bugzilla/xmlrpc.cgi | 4 +- 326 files changed, 4095 insertions(+), 1250 deletions(-) create mode 100644 mozilla/webtools/bugzilla/Bugzilla/Auth/Login/APIKey.pm delete mode 100644 mozilla/webtools/bugzilla/Bugzilla/Config/PatchViewer.pm create mode 100644 mozilla/webtools/bugzilla/Bugzilla/Markdown.pm rename mozilla/webtools/bugzilla/Bugzilla/{Send => Sender/Transport}/Sendmail.pm (64%) create mode 100644 mozilla/webtools/bugzilla/Bugzilla/User/APIKey.pm create mode 100644 mozilla/webtools/bugzilla/Bugzilla/WebService/Component.pm create mode 100644 mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Component.pm create mode 100644 mozilla/webtools/bugzilla/contrib/replyrc create mode 100644 mozilla/webtools/bugzilla/template/en/default/account/prefs/apikey.html.tmpl delete mode 100644 mozilla/webtools/bugzilla/template/en/default/admin/params/patchviewer.html.tmpl create mode 100644 mozilla/webtools/bugzilla/template/en/default/email/new-api-key.txt.tmpl delete mode 100644 mozilla/webtools/bugzilla/template/en/default/global/site-navigation.html.tmpl create mode 100644 mozilla/webtools/bugzilla/template/en/default/pages/markdown.html.tmpl diff --git a/mozilla/webtools/bugzilla/.bzrrev b/mozilla/webtools/bugzilla/.bzrrev index c7a8e5bda0d..c7adcab7358 100644 --- a/mozilla/webtools/bugzilla/.bzrrev +++ b/mozilla/webtools/bugzilla/.bzrrev @@ -1 +1 @@ -9266 \ No newline at end of file +9267 \ No newline at end of file diff --git a/mozilla/webtools/bugzilla/.gitrev b/mozilla/webtools/bugzilla/.gitrev index b3b19be0092..7c495dfea87 100644 --- a/mozilla/webtools/bugzilla/.gitrev +++ b/mozilla/webtools/bugzilla/.gitrev @@ -1 +1 @@ -e9ee9a524159ccfd809efccdb385e7796c82e2f8 \ No newline at end of file +48a0dcaa94832f4f2ca998ac8dbca3187a2b5e24 \ No newline at end of file diff --git a/mozilla/webtools/bugzilla/.htaccess b/mozilla/webtools/bugzilla/.htaccess index f8611f81ddc..7ef20d8b69a 100644 --- a/mozilla/webtools/bugzilla/.htaccess +++ b/mozilla/webtools/bugzilla/.htaccess @@ -29,5 +29,6 @@ Options -Indexes RewriteEngine On + RewriteOptions inherit RewriteRule ^rest/(.*)$ rest.cgi/$1 [NE] diff --git a/mozilla/webtools/bugzilla/.travis.yml b/mozilla/webtools/bugzilla/.travis.yml index 1ed35cae34f..eed86e0a300 100644 --- a/mozilla/webtools/bugzilla/.travis.yml +++ b/mozilla/webtools/bugzilla/.travis.yml @@ -8,7 +8,10 @@ perl: env: - TEST_SUITE=sanity - TEST_SUITE=docs - - TEST_SUITE=checksetup DB=mysql + - TEST_SUITE=webservices DB=mysql + - TEST_SUITE=selenium DB=mysql + - TEST_SUITE=webservices DB=pg + - TEST_SUITE=selenium DB=pg matrix: exclude: @@ -19,14 +22,32 @@ matrix: - perl: 5.14 env: TEST_SUITE=docs - perl: 5.10 - env: TEST_SUITE=checksetup DB=mysql + env: TEST_SUITE=webservices DB=mysql + - perl: 5.10 + env: TEST_SUITE=webservices DB=pg + - perl: 5.10 + env: TEST_SUITE=selenium DB=mysql + - perl: 5.10 + env: TEST_SUITE=selenium DB=pg - perl: 5.12 - env: TEST_SUITE=checksetup DB=mysql + env: TEST_SUITE=webservices DB=mysql + - perl: 5.12 + env: TEST_SUITE=webservices DB=pg + - perl: 5.12 + env: TEST_SUITE=selenium DB=mysql + - perl: 5.12 + env: TEST_SUITE=selenium DB=pg - perl: 5.14 - env: TEST_SUITE=checksetup DB=mysql + env: TEST_SUITE=webservices DB=mysql + - perl: 5.14 + env: TEST_SUITE=webservices DB=pg + - perl: 5.14 + env: TEST_SUITE=selenium DB=mysql + - perl: 5.14 + env: TEST_SUITE=selenium DB=pg before_install: - - git clone https://github.com/bugzilla/qa.git -b 4.4 qa + - git clone https://github.com/bugzilla/qa.git -b master qa install: true diff --git a/mozilla/webtools/bugzilla/Bugzilla.pm b/mozilla/webtools/bugzilla/Bugzilla.pm index 271bd894bcf..048e72d4818 100644 --- a/mozilla/webtools/bugzilla/Bugzilla.pm +++ b/mozilla/webtools/bugzilla/Bugzilla.pm @@ -9,6 +9,7 @@ package Bugzilla; use 5.10.1; use strict; +use warnings; # We want any compile errors to get to the browser, if possible. BEGIN { @@ -121,8 +122,8 @@ sub init_page { # # This code must go here. It cannot go anywhere in Bugzilla::CGI, because # it uses Template, and that causes various dependency loops. - if (Bugzilla->params->{"shutdownhtml"} - && !grep { $_ eq $script } SHUTDOWNHTML_EXEMPT) + if (!grep { $_ eq $script } SHUTDOWNHTML_EXEMPT + and Bugzilla->params->{'shutdownhtml'}) { # Allow non-cgi scripts to exit silently (without displaying any # message), if desired. At this point, no DBI call has been made @@ -396,6 +397,13 @@ sub logout_request { # there. Don't rely on it: use Bugzilla->user->login instead! } +sub markdown { + return if !Bugzilla->feature('markdown'); + + require Bugzilla::Markdown; + return $_[0]->request_cache->{markdown} ||= Bugzilla::Markdown->new(); +} + sub job_queue { require Bugzilla::JobQueue; return $_[0]->request_cache->{job_queue} ||= Bugzilla::JobQueue->new(); @@ -651,13 +659,16 @@ sub memcached { # Per-process cleanup. Note that this is a plain subroutine, not a method, # so we don't have $class available. sub _cleanup { - my $main = Bugzilla->request_cache->{dbh_main}; - my $shadow = Bugzilla->request_cache->{dbh_shadow}; + my $cache = Bugzilla->request_cache; + my $main = $cache->{dbh_main}; + my $shadow = $cache->{dbh_shadow}; foreach my $dbh ($main, $shadow) { next if !$dbh; $dbh->bz_rollback_transaction() if $dbh->bz_in_transaction; $dbh->disconnect; } + my $smtp = $cache->{smtp}; + $smtp->disconnect if $smtp; clear_request_cache(); # These are both set by CGI.pm but need to be undone so that @@ -933,9 +944,9 @@ Change the database object to refer to the main database. =item C -The current Parameters of Bugzilla, as a hashref. If C -does not exist, then we return an empty hashref. If C -is unreadable or is not valid perl, we C. +The current Parameters of Bugzilla, as a hashref. If C +does not exist, then we return an empty hashref. If C +is unreadable or is not valid, we C. =item C @@ -943,6 +954,10 @@ Returns the local timezone of the Bugzilla installation, as a DateTime::TimeZone object. This detection is very time consuming, so we cache this information for future references. +=item C + +The current L object, to be used for Markdown rendering. + =item C Returns a L that you can use for queueing jobs. diff --git a/mozilla/webtools/bugzilla/Bugzilla/Attachment.pm b/mozilla/webtools/bugzilla/Bugzilla/Attachment.pm index 19c10c8fea6..e165b139e60 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Attachment.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Attachment.pm @@ -9,6 +9,7 @@ package Bugzilla::Attachment; use 5.10.1; use strict; +use warnings; =head1 NAME @@ -307,7 +308,8 @@ sub is_viewable { =item C -the content of the attachment +Returns the content of the attachment. +As a side-effect, sets $self->is_on_filesystem. =back @@ -324,10 +326,16 @@ sub data { undef, $self->id); + # Setting the property here is cheap, as opposed to making an extra + # query later, and hitting the filesystem to see if the file is + # still there. + $self->{is_on_filesystem} = 0; # If there's no attachment data in the database, the attachment is stored # in a local file, so retrieve it from there. if (length($self->{data}) == 0) { if (open(AH, $self->_get_local_filename())) { + # file is actually on disk. + $self->{is_on_filesystem} = 1; local $/; binmode AH; $self->{data} = ; @@ -340,9 +348,36 @@ sub data { =over +=item C + +Returns true if the attachment is stored on disk (via maxlocalattachment +parameter), as opposed to in the database. + +=back + +=cut + +# When the attachment is on the filesystem, you can let the backend +# (nginx, apache, lighttpd) serve it for you if it supports the X-Sendfile +# feature. This means that the attachment CGI script may have a reduced +# footprint. e.g. bug 906010 and bug 1073241. + +sub is_on_filesystem { + my $self = shift; + return $self->{is_on_filesystem} if exists $self->{is_on_filesystem}; + # In order to serve an attachment, you also send the datasize in the + # content-length header. Making additional queries which are exactly + # the same as found in the datasize code path is just wasteful. + my $datasize = $self->datasize; + return $self->{is_on_filesystem}; +} + +=over + =item C -the length (in bytes) of the attachment content +Returns the length (in bytes) of the attachment content. +As a side-effect, sets $self->is_on_filesystem. =back @@ -369,11 +404,17 @@ sub datasize { WHERE id = ?", undef, $self->id) || 0; + # Setting the property here is cheap, as opposed to making an extra + # query later, and hitting the filesystem to see if the file is + # still there. + $self->{is_on_filesystem} = 0; # If there's no attachment data in the database, either the attachment # is stored in a local file, and so retrieve its size from the file, # or the attachment has been deleted. unless ($self->{datasize}) { if (open(AH, $self->_get_local_filename())) { + # file is actually on disk. + $self->{is_on_filesystem} = 1; binmode AH; $self->{datasize} = (stat(AH))[7]; close(AH); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Attachment/PatchReader.pm b/mozilla/webtools/bugzilla/Bugzilla/Attachment/PatchReader.pm index c2ef53a65f2..d0e22122028 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Attachment/PatchReader.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Attachment/PatchReader.pm @@ -9,6 +9,7 @@ package Bugzilla::Attachment::PatchReader; use 5.10.1; use strict; +use warnings; use Config; use IO::Select; @@ -22,17 +23,18 @@ use Bugzilla::Util; use constant PERLIO_IS_ENABLED => $Config{useperlio}; sub process_diff { - my ($attachment, $format, $context) = @_; + my ($attachment, $format) = @_; my $dbh = Bugzilla->dbh; my $cgi = Bugzilla->cgi; my $lc = Bugzilla->localconfig; my $vars = {}; - my ($reader, $last_reader) = setup_patch_readers(undef, $context); + require PatchReader::Raw; + my $reader = new PatchReader::Raw; if ($format eq 'raw') { require PatchReader::DiffPrinter::raw; - $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw()); + $reader->sends_data_to(new PatchReader::DiffPrinter::raw()); # Actually print out the patch. print $cgi->header(-type => 'text/plain'); disable_utf8(); @@ -70,7 +72,7 @@ sub process_diff { $vars->{'description'} = $attachment->description; $vars->{'other_patches'} = \@other_patches; - setup_template_patch_reader($last_reader, $format, $context, $vars); + setup_template_patch_reader($reader, $vars); # The patch is going to be displayed in a HTML page and if the utf8 # param is enabled, we have to encode attachment data as utf8. if (Bugzilla->params->{'utf8'}) { @@ -82,11 +84,13 @@ sub process_diff { } sub process_interdiff { - my ($old_attachment, $new_attachment, $format, $context) = @_; + my ($old_attachment, $new_attachment, $format) = @_; my $cgi = Bugzilla->cgi; my $lc = Bugzilla->localconfig; my $vars = {}; + require PatchReader::Raw; + # Encode attachment data as utf8 if it's going to be displayed in a HTML # page using the UTF-8 encoding. if ($format ne 'raw' && Bugzilla->params->{'utf8'}) { @@ -176,10 +180,11 @@ sub process_interdiff { $warning = 'interdiff3'; } - my ($reader, $last_reader) = setup_patch_readers("", $context); + my $reader = new PatchReader::Raw; + if ($format eq 'raw') { require PatchReader::DiffPrinter::raw; - $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw()); + $reader->sends_data_to(new PatchReader::DiffPrinter::raw()); # Actually print out the patch. print $cgi->header(-type => 'text/plain'); disable_utf8(); @@ -192,7 +197,7 @@ sub process_interdiff { $vars->{'newid'} = $new_attachment->id; $vars->{'new_desc'} = $new_attachment->description; - setup_template_patch_reader($last_reader, $format, $context, $vars); + setup_template_patch_reader($reader, $vars); } $reader->iterate_string('interdiff #' . $old_attachment->id . ' #' . $new_attachment->id, $stdout); @@ -207,7 +212,6 @@ sub get_unified_diff { # Bring in the modules we need. require PatchReader::Raw; - require PatchReader::FixPatchRoot; require PatchReader::DiffPrinter::raw; require PatchReader::PatchInfoGrabber; require File::Temp; @@ -219,14 +223,6 @@ sub get_unified_diff { my $reader = new PatchReader::Raw; my $last_reader = $reader; - # Fixes patch root (makes canonical if possible). - if (Bugzilla->params->{'cvsroot'}) { - my $fix_patch_root = - new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'}); - $last_reader->sends_data_to($fix_patch_root); - $last_reader = $fix_patch_root; - } - # Grabs the patch file info. my $patch_info_grabber = new PatchReader::PatchInfoGrabber(); $last_reader->sends_data_to($patch_info_grabber); @@ -273,46 +269,8 @@ sub warn_if_interdiff_might_fail { return undef; } -sub setup_patch_readers { - my ($diff_root, $context) = @_; - - # Parameters: - # format=raw|html - # context=patch|file|0-n - # collapsed=0|1 - # headers=0|1 - - # Define the patch readers. - # The reader that reads the patch in (whatever its format). - require PatchReader::Raw; - my $reader = new PatchReader::Raw; - my $last_reader = $reader; - # Fix the patch root if we have a cvs root. - if (Bugzilla->params->{'cvsroot'}) { - require PatchReader::FixPatchRoot; - $last_reader->sends_data_to(new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'})); - $last_reader->sends_data_to->diff_root($diff_root) if defined($diff_root); - $last_reader = $last_reader->sends_data_to; - } - - # Add in cvs context if we have the necessary info to do it - if ($context ne 'patch' && Bugzilla->localconfig->{cvsbin} - && Bugzilla->params->{'cvsroot_get'}) - { - require PatchReader::AddCVSContext; - # We need to set $cvsbin as global, because PatchReader::CVSClient - # needs it in order to find 'cvs'. - $main::cvsbin = Bugzilla->localconfig->{cvsbin}; - $last_reader->sends_data_to( - new PatchReader::AddCVSContext($context, Bugzilla->params->{'cvsroot_get'})); - $last_reader = $last_reader->sends_data_to; - } - - return ($reader, $last_reader); -} - sub setup_template_patch_reader { - my ($last_reader, $format, $context, $vars) = @_; + my ($last_reader, $vars) = @_; my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; @@ -327,22 +285,15 @@ sub setup_template_patch_reader { } $vars->{'collapsed'} = $cgi->param('collapsed'); - $vars->{'context'} = $context; - $vars->{'do_context'} = Bugzilla->localconfig->{cvsbin} - && Bugzilla->params->{'cvsroot_get'} && !$vars->{'newid'}; # Print everything out. print $cgi->header(-type => 'text/html'); $last_reader->sends_data_to(new PatchReader::DiffPrinter::template($template, - "attachment/diff-header.$format.tmpl", - "attachment/diff-file.$format.tmpl", - "attachment/diff-footer.$format.tmpl", - { %{$vars}, - bonsai_url => Bugzilla->params->{'bonsai_url'}, - lxr_url => Bugzilla->params->{'lxr_url'}, - lxr_root => Bugzilla->params->{'lxr_root'}, - })); + 'attachment/diff-header.html.tmpl', + 'attachment/diff-file.html.tmpl', + 'attachment/diff-footer.html.tmpl', + $vars)); } 1; @@ -363,6 +314,4 @@ __END__ =item process_interdiff -=item setup_patch_readers - =back diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth.pm index 42e4ee784f2..c830f0506d7 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth.pm @@ -9,6 +9,8 @@ package Bugzilla::Auth; use 5.10.1; use strict; +use warnings; + use fields qw( _info_getter _verifier @@ -30,7 +32,7 @@ sub new { my $self = fields::new($class); $params ||= {}; - $params->{Login} ||= Bugzilla->params->{'user_info_class'} . ',Cookie'; + $params->{Login} ||= Bugzilla->params->{'user_info_class'} . ',Cookie,APIKey'; $params->{Verify} ||= Bugzilla->params->{'user_verify_class'}; $self->{_info_getter} = new Bugzilla::Auth::Login::Stack($params->{Login}); @@ -44,7 +46,6 @@ sub new { sub login { my ($self, $type) = @_; - my $dbh = Bugzilla->dbh; # Get login info from the cookie, form, environment variables, etc. my $login_info = $self->{_info_getter}->get_login_info(); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login.pm index 33d63a425cd..a5f08977719 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login.pm @@ -9,6 +9,8 @@ package Bugzilla::Auth::Login; use 5.10.1; use strict; +use warnings; + use fields qw(); # Determines whether or not a user can logout. It's really a subroutine, diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/APIKey.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/APIKey.pm new file mode 100644 index 00000000000..63e35578af4 --- /dev/null +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/APIKey.pm @@ -0,0 +1,53 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Auth::Login::APIKey; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::Auth::Login); + +use Bugzilla::Constants; +use Bugzilla::User::APIKey; +use Bugzilla::Util; +use Bugzilla::Error; + +use constant requires_persistence => 0; +use constant requires_verification => 0; +use constant can_login => 0; +use constant can_logout => 0; + +# This method is only available to web services. An API key can never +# be used to authenticate a Web request. +sub get_login_info { + my ($self) = @_; + my $params = Bugzilla->input_params; + my ($user_id, $login_cookie); + + my $api_key_text = trim(delete $params->{'Bugzilla_api_key'}); + if (!i_am_webservice() || !$api_key_text) { + return { failure => AUTH_NODATA }; + } + + my $api_key = Bugzilla::User::APIKey->new({ name => $api_key_text }); + + if (!$api_key or $api_key->api_key ne $api_key_text) { + # The second part checks the correct capitalisation. Silly MySQL + ThrowUserError("api_key_not_valid"); + } + elsif ($api_key->revoked) { + ThrowUserError('api_key_revoked'); + } + + $api_key->update_last_used(); + + return { user_id => $api_key->user_id }; +} + +1; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/CGI.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/CGI.pm index 76b82804a69..6003d62a5bd 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/CGI.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/CGI.pm @@ -9,6 +9,7 @@ package Bugzilla::Auth::Login::CGI; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Auth::Login); use constant user_can_create_account => 1; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Cookie.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Cookie.pm index 29e2310a0a0..c09f08d24d1 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Cookie.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Cookie.pm @@ -9,13 +9,15 @@ package Bugzilla::Auth::Login::Cookie; use 5.10.1; use strict; +use warnings; use base qw(Bugzilla::Auth::Login); use fields qw(_login_token); use Bugzilla::Constants; -use Bugzilla::Util; use Bugzilla::Error; +use Bugzilla::Token; +use Bugzilla::Util; use List::Util qw(first); @@ -49,6 +51,20 @@ sub get_login_info { @{$cgi->{'Bugzilla_cookie_list'}}; $user_id = $cookie->value if $cookie; } + + # If the call is for a web service, and an api token is provided, check + # it is valid. + if (i_am_webservice() && Bugzilla->input_params->{Bugzilla_api_token}) { + my $api_token = Bugzilla->input_params->{Bugzilla_api_token}; + my ($token_user_id, undef, undef, $token_type) + = Bugzilla::Token::GetTokenData($api_token); + if (!defined $token_type + || $token_type ne 'api_token' + || $user_id != $token_user_id) + { + ThrowUserError('auth_invalid_token', { token => $api_token }); + } + } } # If no cookies were provided, we also look for a login token diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Env.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Env.pm index 51261e6b9b1..653df2bb390 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Env.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Env.pm @@ -9,6 +9,7 @@ package Bugzilla::Auth::Login::Env; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Auth::Login); @@ -24,7 +25,6 @@ use constant extern_id_used => 1; sub get_login_info { my ($self) = @_; - my $dbh = Bugzilla->dbh; my $env_id = $ENV{Bugzilla->params->{"auth_env_id"}} || ''; my $env_email = $ENV{Bugzilla->params->{"auth_env_email"}} || ''; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Stack.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Stack.pm index ad5598576a8..dc35998e4f9 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Stack.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Login/Stack.pm @@ -9,6 +9,7 @@ package Bugzilla::Auth::Login::Stack; use 5.10.1; use strict; +use warnings; use base qw(Bugzilla::Auth::Login); use fields qw( diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Persist/Cookie.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Persist/Cookie.pm index 6f4eac96d25..2d1291f3b90 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Persist/Cookie.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Persist/Cookie.pm @@ -9,6 +9,8 @@ package Bugzilla::Auth::Persist::Cookie; use 5.10.1; use strict; +use warnings; + use fields qw(); use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify.pm index ecb64e22a74..e44fb06aef9 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify.pm @@ -9,6 +9,8 @@ package Bugzilla::Auth::Verify; use 5.10.1; use strict; +use warnings; + use fields qw(); use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/DB.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/DB.pm index d4a4674d3c4..28a9310c97c 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/DB.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/DB.pm @@ -9,6 +9,7 @@ package Bugzilla::Auth::Verify::DB; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Auth::Verify); @@ -55,10 +56,19 @@ sub check_credentials { }; } - # Force the user to type a longer password if it's too short. - if (length($password) < USER_PASSWORD_MIN_LENGTH) { - return { failure => AUTH_ERROR, user_error => 'password_current_too_short', - details => { locked_user => $user } }; + # Force the user to change their password if it does not meet the current + # criteria. This should usually only happen if the criteria has changed. + if (Bugzilla->usage_mode == USAGE_MODE_BROWSER && + Bugzilla->params->{password_check_on_login}) + { + my $check = validate_password_check($password); + if ($check) { + return { + failure => AUTH_ERROR, + user_error => $check, + details => { locked_user => $user } + } + } } # The user's credentials are okay, so delete any outstanding diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/LDAP.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/LDAP.pm index c113124f1d4..e37f557939b 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/LDAP.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/LDAP.pm @@ -9,6 +9,7 @@ package Bugzilla::Auth::Verify::LDAP; use 5.10.1; use strict; +use warnings; use base qw(Bugzilla::Auth::Verify); use fields qw( diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/RADIUS.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/RADIUS.pm index e5157c68f4c..283d9b46614 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/RADIUS.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/RADIUS.pm @@ -9,6 +9,7 @@ package Bugzilla::Auth::Verify::RADIUS; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Auth::Verify); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/Stack.pm b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/Stack.pm index 52c449e22f9..3e5db3cecbb 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/Stack.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Auth/Verify/Stack.pm @@ -9,6 +9,7 @@ package Bugzilla::Auth::Verify::Stack; use 5.10.1; use strict; +use warnings; use base qw(Bugzilla::Auth::Verify); use fields qw( diff --git a/mozilla/webtools/bugzilla/Bugzilla/Bug.pm b/mozilla/webtools/bugzilla/Bugzilla/Bug.pm index b762a65003f..aec7c1e82d0 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Bug.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Bug.pm @@ -9,6 +9,7 @@ package Bugzilla::Bug; use 5.10.1; use strict; +use warnings; use Bugzilla::Attachment; use Bugzilla::Constants; @@ -48,7 +49,7 @@ use parent qw(Bugzilla::Object Exporter); use constant DB_TABLE => 'bugs'; use constant ID_FIELD => 'bug_id'; -use constant NAME_FIELD => 'alias'; +use constant NAME_FIELD => 'bug_id'; use constant LIST_ORDER => ID_FIELD; # Bugs have their own auditing table, bugs_activity. use constant AUDIT_CREATES => 0; @@ -64,7 +65,6 @@ sub DB_COLUMNS { my @custom_names = map {$_->name} @custom; my @columns = (qw( - alias assigned_to bug_file_loc bug_id @@ -207,7 +207,6 @@ sub UPDATE_COLUMNS { Bugzilla->active_custom_fields; my @custom_names = map {$_->name} @custom; my @columns = qw( - alias assigned_to bug_file_loc bug_severity @@ -313,11 +312,20 @@ sub new { # If we get something that looks like a word (not a number), # make it the "name" param. if (!defined $param - || (!ref($param) && $param =~ /\D/) - || (ref($param) && $param->{id} =~ /\D/)) + || (!ref($param) && $param !~ /^\d+$/) + || (ref($param) && $param->{id} !~ /^\d+$/)) { if ($param) { - $param = { name => ref($param) ? $param->{id} : $param, + my $alias = ref($param) ? $param->{id} : $param; + my $bug_id = bug_alias_to_id($alias); + if (! $bug_id) { + my $error_self = {}; + bless $error_self, $class; + $error_self->{'bug_id'} = $alias; + $error_self->{'error'} = 'InvalidBugId'; + return $error_self; + } + $param = { id => $bug_id, cache => ref($param) ? $param->{cache} : 0 }; } else { @@ -547,6 +555,9 @@ sub _preload_referenced_bugs { foreach my $bug (@$referenced_bugs) { $bug->object_cache_set(); } + + # preload bug visibility + Bugzilla->user->visible_bugs(\@referenced_bug_ids); } sub possible_duplicates { @@ -683,18 +694,22 @@ sub create { unless defined $params->{rep_platform}; # Make sure a comment is always defined. $params->{comment} = '' unless defined $params->{comment}; + $params->{is_markdown} = 0 + unless defined $params->{is_markdown} && $params->{is_markdown} eq '1'; $class->check_required_create_fields($params); $params = $class->run_create_validators($params); # These are not a fields in the bugs table, so we don't pass them to # insert_create_data. + my $bug_aliases = delete $params->{alias}; my $cc_ids = delete $params->{cc}; my $groups = delete $params->{groups}; my $depends_on = delete $params->{dependson}; my $blocked = delete $params->{blocked}; my $keywords = delete $params->{keywords}; my $creation_comment = delete $params->{comment}; + my $is_markdown = delete $params->{is_markdown}; my $see_also = delete $params->{see_also}; # We don't want the bug to appear in the system until it's correctly @@ -782,11 +797,19 @@ sub create { # We now have a bug id so we can fill this out $creation_comment->{'bug_id'} = $bug->id; + $creation_comment->{'is_markdown'} = $is_markdown; # Insert the comment. We always insert a comment on bug creation, # but sometimes it's blank. Bugzilla::Comment->insert_create_data($creation_comment); + # Set up aliases + my $sth_aliases = $dbh->prepare('INSERT INTO bugs_aliases (alias, bug_id) VALUES (?, ?)'); + foreach my $alias (@$bug_aliases) { + trick_taint($alias); + $sth_aliases->execute($alias, $bug->bug_id); + } + Bugzilla::Hook::process('bug_end_of_create', { bug => $bug, timestamp => $timestamp, }); @@ -906,7 +929,26 @@ sub update { my $added_names = join(', ', (map {$_->login} @$added_users)); $changes->{cc} = [$removed_names, $added_names]; } - + + # Aliases + my $old_aliases = $old_bug->alias; + my $new_aliases = $self->alias; + my ($removed_aliases, $added_aliases) = diff_arrays($old_aliases, $new_aliases); + + foreach my $alias (@$removed_aliases) { + $dbh->do('DELETE FROM bugs_aliases WHERE bug_id = ? AND alias = ?', + undef, $self->id, $alias); + } + foreach my $alias (@$added_aliases) { + trick_taint($alias); + $dbh->do('INSERT INTO bugs_aliases (bug_id, alias) VALUES (?,?)', + undef, $self->id, $alias); + } + # If any changes were found, record it in the activity log + if (scalar @$removed_aliases || scalar @$added_aliases) { + $changes->{alias} = [join(', ', @$removed_aliases), join(', ', @$added_aliases)]; + } + # Keywords my @old_kw_ids = map { $_->id } @{$old_bug->keyword_objects}; my @new_kw_ids = map { $_->id } @{$self->keyword_objects}; @@ -988,12 +1030,6 @@ sub update { join(', ', @added_names)]; } - # Flags - my ($removed, $added) = Bugzilla::Flag->update_flags($self, $old_bug, $delta_ts); - if ($removed || $added) { - $changes->{'flagtypes.name'} = [$removed, $added]; - } - # Comments foreach my $comment (@{$self->{added_comments} || []}) { # Override the Comment's timestamp to be identical to the update @@ -1016,6 +1052,9 @@ sub update { $user->id, $delta_ts, $comment->id); } + # Clear the cache of comments + delete $self->{comments}; + # Insert the values into the multiselect value tables my @multi_selects = grep {$_->type == FIELD_TYPE_MULTI_SELECT} Bugzilla->active_custom_fields; @@ -1048,6 +1087,12 @@ sub update { join(', ', map { $_->name } @$added_see)]; } + # Flags + my ($removed, $added) = Bugzilla::Flag->update_flags($self, $old_bug, $delta_ts); + if ($removed || $added) { + $changes->{'flagtypes.name'} = [$removed, $added]; + } + $_->update foreach @{ $self->{_update_ref_bugs} || [] }; delete $self->{_update_ref_bugs}; @@ -1095,6 +1140,13 @@ sub update { $self->update_user_last_visit($user, $delta_ts); } + # If a user is no longer involved, remove their last visit entry + my $last_visits = + Bugzilla::BugUserLastVisit->match({ bug_id => $self->id }); + foreach my $lv (@$last_visits) { + $lv->remove_from_db() unless $lv->user->is_involved_in_bug($self); + } + # Update bug ignore data if user wants to ignore mail for this bug if (exists $self->{'bug_ignored'}) { my $bug_ignored_changed; @@ -1310,32 +1362,38 @@ sub _send_bugmail { ##################################################################### sub _check_alias { - my ($invocant, $alias) = @_; - $alias = trim($alias); - return undef if (!$alias); + my ($invocant, $aliases) = @_; + $aliases = ref $aliases ? $aliases : [split(/[\s,]+/, $aliases)]; - # Make sure the alias isn't too long. - if (length($alias) > 20) { - ThrowUserError("alias_too_long"); - } - # Make sure the alias isn't just a number. - if ($alias =~ /^\d+$/) { - ThrowUserError("alias_is_numeric", { alias => $alias }); - } - # Make sure the alias has no commas or spaces. - if ($alias =~ /[, ]/) { - ThrowUserError("alias_has_comma_or_space", { alias => $alias }); - } - # Make sure the alias is unique, or that it's already our alias. - my $other_bug = new Bugzilla::Bug($alias); - if (!$other_bug->{error} - && (!ref $invocant || $other_bug->id != $invocant->id)) - { - ThrowUserError("alias_in_use", { alias => $alias, - bug_id => $other_bug->id }); + # Remove empty aliases + @$aliases = grep { $_ } @$aliases; + + foreach my $alias (@$aliases) { + $alias = trim($alias); + + # Make sure the alias isn't too long. + if (length($alias) > 40) { + ThrowUserError("alias_too_long"); + } + # Make sure the alias isn't just a number. + if ($alias =~ /^\d+$/) { + ThrowUserError("alias_is_numeric", { alias => $alias }); + } + # Make sure the alias has no commas or spaces. + if ($alias =~ /[, ]/) { + ThrowUserError("alias_has_comma_or_space", { alias => $alias }); + } + # Make sure the alias is unique, or that it's already our alias. + my $other_bug = new Bugzilla::Bug($alias); + if (!$other_bug->{error} + && (!ref $invocant || $other_bug->id != $invocant->id)) + { + ThrowUserError("alias_in_use", { alias => $alias, + bug_id => $other_bug->id }); + } } - return $alias; + return $aliases; } sub _check_assigned_to { @@ -2372,7 +2430,15 @@ sub set_all { # there are lots of things that want to check if we added a comment. $self->add_comment($params->{'comment'}->{'body'}, { isprivate => $params->{'comment'}->{'is_private'}, - work_time => $params->{'work_time'} }); + work_time => $params->{'work_time'}, + is_markdown => $params->{'comment'}->{'is_markdown'} }); + } + + if (exists $params->{alias} && $params->{alias}{set}) { + $params->{alias} = { + add => $params->{alias}{set}, + remove => $self->alias, + }; } my %normal_set_all; @@ -2399,6 +2465,7 @@ sub set_all { } $self->_add_remove($params, 'cc'); + $self->_add_remove($params, 'alias'); # Theoretically you could move a product without ever specifying # a new assignee or qa_contact, or adding/removing any CCs. So, @@ -2415,14 +2482,13 @@ sub _add_remove { my ($self, $params, $name) = @_; my @add = @{ $params->{$name}->{add} || [] }; my @remove = @{ $params->{$name}->{remove} || [] }; - $name =~ s/s$//; + $name =~ s/s$// if $name ne 'alias'; my $add_method = "add_$name"; my $remove_method = "remove_$name"; $self->$add_method($_) foreach @add; $self->$remove_method($_) foreach @remove; } -sub set_alias { $_[0]->set('alias', $_[1]); } sub set_assigned_to { my ($self, $value) = @_; $self->set('assigned_to', $value); @@ -2839,6 +2905,21 @@ sub remove_cc { @$cc_users = grep { $_->id != $user->id } @$cc_users; } +sub add_alias { + my ($self, $alias) = @_; + return if !$alias; + my $aliases = $self->_check_alias($alias); + $alias = $aliases->[0]; + my $bug_aliases = $self->alias; + push(@$bug_aliases, $alias) if !grep($_ eq $alias, @$bug_aliases); +} + +sub remove_alias { + my ($self, $alias) = @_; + my $bug_aliases = $self->alias; + @$bug_aliases = grep { $_ ne $alias } @$bug_aliases; +} + # $bug->add_comment("comment", {isprivate => 1, work_time => 10.5, # type => CMT_NORMAL, extra_data => $data}); sub add_comment { @@ -3166,7 +3247,6 @@ sub tags { # These are accessors that don't need to access the database. # Keep them in alphabetical order. -sub alias { return $_[0]->{alias} } sub bug_file_loc { return $_[0]->{bug_file_loc} } sub bug_id { return $_[0]->{bug_id} } sub bug_severity { return $_[0]->{bug_severity} } @@ -3276,6 +3356,24 @@ sub actual_time { return $self->{'actual_time'}; } +sub alias { + my ($self) = @_; + return $self->{'alias'} if exists $self->{'alias'}; + return [] if $self->{'error'}; + + my $dbh = Bugzilla->dbh; + $self->{'alias'} = $dbh->selectcol_arrayref( + q{SELECT alias + FROM bugs_aliases + WHERE bug_id = ? + ORDER BY alias}, + undef, $self->bug_id); + + $self->{'alias'} = [] if !scalar(@{$self->{'alias'}}); + + return $self->{'alias'}; +} + sub any_flags_requesteeble { my ($self) = @_; return $self->{'any_flags_requesteeble'} @@ -3853,6 +3951,11 @@ sub choices { my @resolutions = grep($_->name, @{ $resolution_field->legal_values }); $choices{'resolution'} = \@resolutions; + foreach my $key (keys %choices) { + my $value = $self->$key; + $choices{$key} = [grep { $_->is_active || $_->name eq $value } @{ $choices{$key} }]; + } + $self->{'choices'} = \%choices; return $self->{'choices'}; } @@ -3867,7 +3970,7 @@ sub bug_alias_to_id { my $dbh = Bugzilla->dbh; trick_taint($alias); return $dbh->selectrow_array( - "SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias); + "SELECT bug_id FROM bugs_aliases WHERE alias = ?", undef, $alias); } ##################################################################### @@ -4496,6 +4599,16 @@ __END__ Ensures the accessors for custom fields are always created. +=item C + +Adds an alias to the internal respresentation of the bug. You will need to +call L to make the changes permanent. + +=item C + +Removes an alias from the internal respresentation of the bug. You will need to +call L to make the changes permanent. + =item C Creates or updates a L for this bug and the supplied @@ -4663,8 +4776,6 @@ $user, the timestamp given as $last_visit. =item remove_group -=item set_alias - =item set_dup_id =item set_target_milestone diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugMail.pm b/mozilla/webtools/bugzilla/Bugzilla/BugMail.pm index d66df579dca..8b4219787d5 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugMail.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugMail.pm @@ -9,6 +9,7 @@ package Bugzilla::BugMail; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; use Bugzilla::User; diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl.pm index 39b985d290d..1e836ca1e8e 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Bugzilla.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Bugzilla.pm index db132eefff1..402ff1509b4 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Bugzilla.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Bugzilla.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::Bugzilla; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Bugzilla/Local.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Bugzilla/Local.pm index 7381d561030..7b9cb6a4fa5 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Bugzilla/Local.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Bugzilla/Local.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::Bugzilla::Local; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl::Bugzilla); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Debian.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Debian.pm index 97ad4b5456d..2b611aa57bd 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Debian.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Debian.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::Debian; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/GitHub.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/GitHub.pm index 2c35bfb0827..f14f1d6b05c 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/GitHub.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/GitHub.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::GitHub; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl); @@ -21,8 +22,10 @@ sub should_handle { # GitHub issue URLs have only one form: # https://github.com/USER_OR_TEAM_OR_ORGANIZATION_NAME/REPOSITORY_NAME/issues/111 + # GitHub pull request URLs have only one form: + # https://github.com/USER_OR_TEAM_OR_ORGANIZATION_NAME/REPOSITORY_NAME/pull/111 return (lc($uri->authority) eq 'github.com' - and $uri->path =~ m|^/[^/]+/[^/]+/issues/\d+$|) ? 1 : 0; + and $uri->path =~ m!^/[^/]+/[^/]+/(?:issues|pull)/\d+$!) ? 1 : 0; } sub _check_value { diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Google.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Google.pm index dd9ab7ff4b0..71a9c46fb52 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Google.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Google.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::Google; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/JIRA.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/JIRA.pm index e358ff43940..e9d2a2d2a6c 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/JIRA.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/JIRA.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::JIRA; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Launchpad.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Launchpad.pm index 3409cbe19fb..0362747a245 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Launchpad.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Launchpad.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::Launchpad; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/MantisBT.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/MantisBT.pm index 8dffabcbebc..60d3b578ef8 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/MantisBT.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/MantisBT.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::MantisBT; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/SourceForge.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/SourceForge.pm index 630b97d7a7d..acba0df28b7 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/SourceForge.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/SourceForge.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::SourceForge; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Trac.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Trac.pm index edb18e8fd2c..fe74abf33d3 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Trac.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUrl/Trac.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUrl::Trac; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::BugUrl); diff --git a/mozilla/webtools/bugzilla/Bugzilla/BugUserLastVisit.pm b/mozilla/webtools/bugzilla/Bugzilla/BugUserLastVisit.pm index c4acfa56b25..d043b121abd 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/BugUserLastVisit.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/BugUserLastVisit.pm @@ -9,6 +9,7 @@ package Bugzilla::BugUserLastVisit; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); @@ -38,6 +39,13 @@ sub bug_id { return $_[0]->{bug_id} } sub user_id { return $_[0]->{user_id} } sub last_visit_ts { return $_[0]->{last_visit_ts} } +sub user { + my $self = shift; + + $self->{user} //= Bugzilla::User->new({ id => $self->user_id, cache => 1 }); + return $self->{user}; +} + 1; __END__ @@ -80,4 +88,6 @@ listed below. =item C +=item C + =back diff --git a/mozilla/webtools/bugzilla/Bugzilla/CGI.pm b/mozilla/webtools/bugzilla/Bugzilla/CGI.pm index 656c462b712..0b8a4869727 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/CGI.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/CGI.pm @@ -9,6 +9,7 @@ package Bugzilla::CGI; use 5.10.1; use strict; +use warnings; use parent qw(CGI); @@ -361,6 +362,7 @@ sub header { sub param { my $self = shift; + local $CGI::LIST_CONTEXT_WARN = 0; # When we are just requesting the value of a parameter... if (scalar(@_) == 1) { @@ -372,10 +374,7 @@ sub param { if (!scalar(@result) && $self->request_method && $self->request_method eq 'POST') { - # Some servers fail to set the QUERY_STRING parameter, which - # causes undef issues - $ENV{'QUERY_STRING'} = '' unless exists $ENV{'QUERY_STRING'}; - @result = $self->SUPER::url_param(@_); + @result = $self->url_param(@_); } # Fix UTF-8-ness of input parameters. @@ -400,6 +399,14 @@ sub param { return $self->SUPER::param(@_); } +sub url_param { + my $self = shift; + # Some servers fail to set the QUERY_STRING parameter, which + # causes undef issues + $ENV{'QUERY_STRING'} //= ''; + return $self->SUPER::url_param(@_); +} + sub _fix_utf8 { my $input = shift; # The is_utf8 is here in case CGI gets smart about utf8 someday. @@ -731,6 +738,8 @@ L, L =item param +=item url_param + =item header =back diff --git a/mozilla/webtools/bugzilla/Bugzilla/Chart.pm b/mozilla/webtools/bugzilla/Bugzilla/Chart.pm index 0329b9a0cf3..3c69006aac4 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Chart.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Chart.pm @@ -15,6 +15,7 @@ package Bugzilla::Chart; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; use Bugzilla::Util; @@ -95,10 +96,9 @@ sub init { if ($self->{'datefrom'} && $self->{'dateto'} && $self->{'datefrom'} > $self->{'dateto'}) { - ThrowUserError("misarranged_dates", - {'datefrom' => $cgi->param('datefrom'), - 'dateto' => $cgi->param('dateto')}); - } + ThrowUserError('misarranged_dates', { 'datefrom' => scalar $cgi->param('datefrom'), + 'dateto' => scalar $cgi->param('dateto') }); + } } # Alter Chart so that the selected series are added to it. diff --git a/mozilla/webtools/bugzilla/Bugzilla/Classification.pm b/mozilla/webtools/bugzilla/Bugzilla/Classification.pm index 0ae548bb687..09f71baaf12 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Classification.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Classification.pm @@ -9,6 +9,7 @@ package Bugzilla::Classification; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Field; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Comment.pm b/mozilla/webtools/bugzilla/Bugzilla/Comment.pm index 238770d5720..3dabe67028d 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Comment.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Comment.pm @@ -9,6 +9,7 @@ package Bugzilla::Comment; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); @@ -42,6 +43,7 @@ use constant DB_COLUMNS => qw( already_wrapped type extra_data + is_markdown ); use constant UPDATE_COLUMNS => qw( @@ -64,6 +66,7 @@ use constant VALIDATORS => { work_time => \&_check_work_time, thetext => \&_check_thetext, isprivate => \&_check_isprivate, + is_markdown => \&Bugzilla::Object::check_boolean, extra_data => \&_check_extra_data, type => \&_check_type, }; @@ -176,6 +179,7 @@ sub body { return $_[0]->{'thetext'}; } sub bug_id { return $_[0]->{'bug_id'}; } sub creation_ts { return $_[0]->{'bug_when'}; } sub is_private { return $_[0]->{'isprivate'}; } +sub is_markdown { return $_[0]->{'is_markdown'}; } sub work_time { # Work time is returned as a string (see bug 607909) return 0 if $_[0]->{'work_time'} + 0 == 0; @@ -273,6 +277,7 @@ sub body_full { sub set_is_private { $_[0]->set('isprivate', $_[1]); } sub set_type { $_[0]->set('type', $_[1]); } sub set_extra_data { $_[0]->set('extra_data', $_[1]); } +sub set_is_markdown { $_[0]->set('is_markdown', $_[1]); } sub add_tag { my ($self, $tag) = @_; @@ -521,6 +526,10 @@ C Time spent as related to this comment. C Comment is marked as private. +=item C + +C Whether this comment needs L rendering to be applied. + =item C If this comment is stored in the database word-wrapped, this will be C<1>. @@ -616,6 +625,16 @@ A string, the full text of the comment as it would be displayed to an end-user. =cut +=head2 Modifiers + +=over + +=item C + +Sets whether this comment needs L rendering to be applied. + +=back + =head1 B =over diff --git a/mozilla/webtools/bugzilla/Bugzilla/Comment/TagWeights.pm b/mozilla/webtools/bugzilla/Bugzilla/Comment/TagWeights.pm index f1a220a47f8..7dba53e34c0 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Comment/TagWeights.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Comment/TagWeights.pm @@ -9,6 +9,7 @@ package Bugzilla::Comment::TagWeights; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Component.pm b/mozilla/webtools/bugzilla/Bugzilla/Component.pm index 3d56cc8c265..9bc0a449314 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Component.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Component.pm @@ -9,6 +9,7 @@ package Bugzilla::Component; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config.pm b/mozilla/webtools/bugzilla/Bugzilla/Config.pm index 5d9a8061c91..fdbedbdc044 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config.pm @@ -9,12 +9,19 @@ package Bugzilla::Config; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); +use autodie qw(:default); + use Bugzilla::Constants; use Bugzilla::Hook; -use Data::Dumper; +use Bugzilla::Util qw(trick_taint); + +use JSON::XS; +use File::Slurp; use File::Temp; +use File::Basename; # Don't export localvars by default - people should have to explicitly # ask for it, as a (probably futile) attempt to stop code using it @@ -91,8 +98,35 @@ sub SetParam { sub update_params { my ($params) = @_; my $answer = Bugzilla->installation_answers; + my $datadir = bz_locations()->{'datadir'}; + my $param; + + # If the old data/params file using Data::Dumper output still exists, + # read it. It will be deleted once the parameters are stored in the new + # data/params.json file. + my $old_file = "$datadir/params"; + + if (-e $old_file) { + require Safe; + my $s = new Safe; + + $s->rdo($old_file); + die "Error reading $old_file: $!" if $!; + die "Error evaluating $old_file: $@" if $@; + + # Now read the param back out from the sandbox. + $param = \%{ $s->varglob('param') }; + } + else { + # Rename params.js to params.json if checksetup.pl + # was executed with an earlier version of this change + rename "$old_file.js", "$old_file.json" + if -e "$old_file.js" && !-e "$old_file.json"; + + # Read the new data/params.json file. + $param = read_param_file(); + } - my $param = read_param_file(); my %new_params; # If we didn't return any param values, then this is a new installation. @@ -151,16 +185,19 @@ sub update_params { } # Old mail_delivery_method choices contained no uppercase characters - if (exists $param->{'mail_delivery_method'} - && $param->{'mail_delivery_method'} !~ /[A-Z]/) { - my $method = $param->{'mail_delivery_method'}; - my %translation = ( - 'sendmail' => 'Sendmail', - 'smtp' => 'SMTP', - 'qmail' => 'Qmail', - 'testfile' => 'Test', - 'none' => 'None'); - $param->{'mail_delivery_method'} = $translation{$method}; + my $mta = $param->{'mail_delivery_method'}; + if ($mta) { + if ($mta !~ /[A-Z]/) { + my %translation = ( + 'sendmail' => 'Sendmail', + 'smtp' => 'SMTP', + 'qmail' => 'Qmail', + 'testfile' => 'Test', + 'none' => 'None'); + $param->{'mail_delivery_method'} = $translation{$mta}; + } + # This will force the parameter to be reset to its default value. + delete $param->{'mail_delivery_method'} if $param->{'mail_delivery_method'} eq 'Qmail'; } # Convert the old "ssl" parameter to the new "ssl_redirect" parameter. @@ -210,7 +247,6 @@ sub update_params { } # Write any old parameters to old-params.txt - my $datadir = bz_locations()->{'datadir'}; my $old_param_file = "$datadir/old-params.txt"; if (scalar(keys %oldparams)) { my $op_file = new IO::File($old_param_file, '>>', 0600) @@ -220,12 +256,9 @@ sub update_params { " and so have been\nmoved from your parameters file into", " $old_param_file:\n"; - local $Data::Dumper::Terse = 1; - local $Data::Dumper::Indent = 0; - my $comma = ""; foreach my $item (keys %oldparams) { - print $op_file "\n\n$item:\n" . Data::Dumper->Dump([$oldparams{$item}]) . "\n"; + print $op_file "\n\n$item:\n" . $oldparams{$item} . "\n"; print "${comma}$item"; $comma = ", "; } @@ -256,6 +289,11 @@ sub update_params { write_params($param); + if (-e $old_file) { + unlink $old_file; + say "$old_file has been converted into $old_file.json, using the JSON format."; + } + # Return deleted params and values so that checksetup.pl has a chance # to convert old params to new data. return %oldparams; @@ -264,22 +302,10 @@ sub update_params { sub write_params { my ($param_data) = @_; $param_data ||= Bugzilla->params; + my $param_file = bz_locations()->{'datadir'} . '/params.json'; - my $datadir = bz_locations()->{'datadir'}; - my $param_file = "$datadir/params"; - - local $Data::Dumper::Sortkeys = 1; - - my ($fh, $tmpname) = File::Temp::tempfile('params.XXXXX', - DIR => $datadir ); - - print $fh (Data::Dumper->Dump([$param_data], ['*param'])) - || die "Can't write param file: $!"; - - close $fh; - - rename $tmpname, $param_file - or die "Can't rename $tmpname to $param_file: $!"; + my $json_data = JSON::XS->new->canonical->pretty->encode($param_data); + write_file($param_file, { binmode => ':utf8', atomic => 1 }, \$json_data); # It's not common to edit parameters and loading # Bugzilla::Install::Filesystem is slow. @@ -293,21 +319,23 @@ sub write_params { sub read_param_file { my %params; - my $datadir = bz_locations()->{'datadir'}; - if (-e "$datadir/params") { - # Note that checksetup.pl sets file permissions on '$datadir/params' + my $file = bz_locations()->{'datadir'} . '/params.json'; - # Using Safe mode is _not_ a guarantee of safety if someone does - # manage to write to the file. However, it won't hurt... - # See bug 165144 for not needing to eval this at all - my $s = new Safe; + if (-e $file) { + my $data; + read_file($file, binmode => ':utf8', buf_ref => \$data); - $s->rdo("$datadir/params"); - die "Error reading $datadir/params: $!" if $!; - die "Error evaluating $datadir/params: $@" if $@; - - # Now read the param back out from the sandbox - %params = %{$s->varglob('param')}; + # If params.json has been manually edited and e.g. some quotes are + # missing, we don't want JSON::XS to leak the content of the file + # to all users in its error message, so we have to eval'uate it. + %params = eval { %{JSON::XS->new->decode($data)} }; + if ($@) { + my $error_msg = (basename($0) eq 'checksetup.pl') ? + $@ : 'run checksetup.pl to see the details.'; + die "Error parsing $file: $error_msg"; + } + # JSON::XS doesn't detaint data for us. + trick_taint($params{$_}) foreach keys %params; } elsif ($ENV{'SERVER_SOFTWARE'}) { # We're in a CGI, but the params file doesn't exist. We can't @@ -317,7 +345,7 @@ sub read_param_file { # so that the user sees the error. require CGI::Carp; CGI::Carp->import('fatalsToBrowser'); - die "The $datadir/params file does not exist." + die "The $file file does not exist." . ' You probably need to run checksetup.pl.', } return \%params; @@ -373,7 +401,7 @@ specified. Description: Writes the parameters to disk. Params: C<$params> (optional) - A hashref to write to the disk - instead of Cparams>. Used only by + instead of Cparams>. Used only by C. Returns: nothing @@ -381,12 +409,12 @@ Returns: nothing =item C Description: Most callers should never need this. This is used - by Cparams> to directly read C<$datadir/params> - and load it into memory. Use Cparams> instead. + by Cparams> to directly read C<$datadir/params.json> + and load it into memory. Use Cparams> instead. Params: none -Returns: A hashref containing the current params in C<$datadir/params>. +Returns: A hashref containing the current params in C<$datadir/params.json>. =item C diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/Admin.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/Admin.pm index 97f8ea390de..41d92929852 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/Admin.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/Admin.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::Admin; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/Advanced.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/Advanced.pm index eec2816d26d..8356c33610e 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/Advanced.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/Advanced.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::Advanced; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/Attachment.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/Attachment.pm index f31e57254ab..5bf8542936c 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/Attachment.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/Attachment.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::Attachment; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; @@ -36,6 +37,14 @@ sub get_param_list { default => 0 }, + { + name => 'xsendfile_header', + type => 's', + choices => ['off', 'X-Sendfile', 'X-Accel-Redirect', 'X-LIGHTTPD-send-file'], + default => 'off', + checker => \&check_multi + }, + { name => 'maxattachmentsize', type => 't', diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/Auth.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/Auth.pm index 699881122eb..78d719b15d3 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/Auth.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/Auth.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::Auth; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; @@ -113,7 +114,14 @@ sub get_param_list { 'letters_numbers_specialchars' ], default => 'no_constraints', checker => \&check_multi - } ); + }, + + { + name => 'password_check_on_login', + type => 'b', + default => '1' + }, + ); return @param_list; } diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/BugChange.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/BugChange.pm index 53fc68d00c8..0acdc0ce49c 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/BugChange.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/BugChange.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::BugChange; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; use Bugzilla::Status; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/BugFields.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/BugFields.pm index 39c43cb9235..ef2faa64b64 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/BugFields.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/BugFields.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::BugFields; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; use Bugzilla::Field; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/Common.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/Common.pm index e9e993396c9..fe6a2c2c0aa 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/Common.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/Common.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::Common; use 5.10.1; use strict; +use warnings; use Email::Address; use Socket; @@ -28,7 +29,7 @@ use parent qw(Exporter); check_mail_delivery_method check_notification check_utf8 check_bug_status check_smtp_auth check_theschwartz_available check_maxattachmentsize check_email check_smtp_ssl - check_comment_taggers_group + check_comment_taggers_group check_smtp_server ); # Checking functions for the various values @@ -341,6 +342,33 @@ sub check_notification { return ""; } +sub check_smtp_server { + my $host = shift; + my $port; + + if ($host =~ /:/) { + ($host, $port) = split(/:/, $host, 2); + unless ($port && detaint_natural($port)) { + return "Invalid port. It must be an integer (typically 25, 465 or 587)"; + } + } + trick_taint($host); + # Let's first try to connect using SSL. If this fails, we fall back to + # an unencrypted connection. + foreach my $method (['Net::SMTP::SSL', 465], ['Net::SMTP', 25]) { + my ($class, $default_port) = @$method; + next if $class eq 'Net::SMTP::SSL' && !Bugzilla->feature('smtp_ssl'); + eval "require $class"; + my $smtp = $class->new($host, Port => $port || $default_port, Timeout => 5); + if ($smtp) { + # The connection works! + $smtp->quit; + return ''; + } + } + return "Cannot connect to $host" . ($port ? " using port $port" : ""); +} + sub check_smtp_auth { my $username = shift; if ($username and !Bugzilla->feature('smtp_auth')) { @@ -497,6 +525,8 @@ valid group is provided. =item check_shadowdb +=item check_smtp_server + =item check_smtp_auth =item check_url diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/Core.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/Core.pm index faf86c56736..654e569ba1b 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/Core.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/Core.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::Core; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/DependencyGraph.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/DependencyGraph.pm index 51836405cd3..a9b8598df84 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/DependencyGraph.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/DependencyGraph.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::DependencyGraph; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/General.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/General.pm index a401e98edd6..5efaa6f6c2a 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/General.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/General.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::General; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/GroupSecurity.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/GroupSecurity.pm index 076f841fddb..e827834a0b1 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/GroupSecurity.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/GroupSecurity.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::GroupSecurity; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; use Bugzilla::Group; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/LDAP.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/LDAP.pm index 4a46f40d2cc..0bc8240dfde 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/LDAP.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/LDAP.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::LDAP; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/MTA.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/MTA.pm index 2f4af72f4e6..467bdab3f93 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/MTA.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/MTA.pm @@ -9,15 +9,9 @@ package Bugzilla::Config::MTA; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; -# Return::Value 1.666002 pollutes the error log with warnings about this -# deprecated module. We have to set NO_CLUCK = 1 before loading Email::Send -# to disable these warnings. -BEGIN { - $Return::Value::NO_CLUCK = 1; -} -use Email::Send; our $sortkey = 1200; @@ -27,9 +21,7 @@ sub get_param_list { { name => 'mail_delivery_method', type => 's', - # Bugzilla is not ready yet to send mails to newsgroups, and 'IO' - # is of no use for now as we already have our own 'Test' mode. - choices => [grep {$_ ne 'NNTP' && $_ ne 'IO'} Email::Send->new()->all_mailers(), 'None'], + choices => ['Sendmail', 'SMTP', 'Test', 'None'], default => 'Sendmail', checker => \&check_mail_delivery_method }, @@ -50,7 +42,8 @@ sub get_param_list { { name => 'smtpserver', type => 't', - default => 'localhost' + default => 'localhost', + checker => \&check_smtp_server }, { name => 'smtp_username', diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/Memcached.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/Memcached.pm index 08d8ce0e7c4..292803d8647 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/Memcached.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/Memcached.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::Memcached; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/PatchViewer.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/PatchViewer.pm deleted file mode 100644 index 2005e4c4a1c..00000000000 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/PatchViewer.pm +++ /dev/null @@ -1,52 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Config::PatchViewer; - -use 5.10.1; -use strict; - -use Bugzilla::Config::Common; - -our $sortkey = 1300; - -sub get_param_list { - my $class = shift; - my @param_list = ( - { - name => 'cvsroot', - type => 't', - default => '', - }, - - { - name => 'cvsroot_get', - type => 't', - default => '', - }, - - { - name => 'bonsai_url', - type => 't', - default => '' - }, - - { - name => 'lxr_url', - type => 't', - default => '' - }, - - { - name => 'lxr_root', - type => 't', - default => '', - } ); - return @param_list; -} - -1; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/Query.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/Query.pm index c7b33f620b1..f18bb90df19 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/Query.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/Query.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::Query; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/RADIUS.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/RADIUS.pm index 17fbdd7ddfd..8e30b07a988 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/RADIUS.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/RADIUS.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::RADIUS; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/ShadowDB.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/ShadowDB.pm index 65c572980ff..5dbbb5202a1 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/ShadowDB.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/ShadowDB.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::ShadowDB; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Config/UserMatch.pm b/mozilla/webtools/bugzilla/Bugzilla/Config/UserMatch.pm index 53fb5136fbd..3f74a7c44e6 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Config/UserMatch.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Config/UserMatch.pm @@ -9,6 +9,7 @@ package Bugzilla::Config::UserMatch; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Constants.pm b/mozilla/webtools/bugzilla/Bugzilla/Constants.pm index d22eed063c9..4c1f1100367 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Constants.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Constants.pm @@ -9,6 +9,7 @@ package Bugzilla::Constants; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); @@ -25,6 +26,8 @@ use Memoize; bz_locations + CONCATENATE_ASSETS + IS_NULL NOT_NULL @@ -190,6 +193,8 @@ use Memoize; AUDIT_REMOVE MOST_FREQUENT_THRESHOLD + + MARKDOWN_TAB_WIDTH ); @Bugzilla::Constants::EXPORT_OK = qw(contenttypes); @@ -197,7 +202,7 @@ use Memoize; # CONSTANTS # # Bugzilla version -use constant BUGZILLA_VERSION => "4.5.4+"; +use constant BUGZILLA_VERSION => "4.5.6+"; # A base link to the current REST Documentation. We place it here # as it will need to be updated to whatever the current release is. @@ -207,6 +212,11 @@ use constant REST_DOC => "http://www.bugzilla.org/docs/tip/en/html/api/"; use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml'; use constant LOCAL_FILE => 'bugzilla-update.xml'; # Relative to datadir. +# When true CSS and JavaScript assets will be concatanted and minified at +# run-time, to reduce the number of requests required to render a page. +# Setting this to a false value can help debugging. +use constant CONCATENATE_ASSETS => 1; + # These are unique values that are unlikely to match a string or a number, # to be used in criteria for match() functions and other things. They start # and end with spaces because most Bugzilla stuff has trim() called on it, @@ -627,6 +637,10 @@ use constant AUDIT_REMOVE => '__remove__'; # on the "Most frequently reported bugs" page. use constant MOST_FREQUENT_THRESHOLD => 2; +# The number of spaces used to represent each tab character +# by Markdown engine +use constant MARKDOWN_TAB_WIDTH => 2; + sub bz_locations { # Force memoize() to re-compute data per project, to avoid # sharing the same data across different installations. diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB.pm b/mozilla/webtools/bugzilla/Bugzilla/DB.pm index df84d9c79af..9f3ed0f494d 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB.pm @@ -9,6 +9,7 @@ package Bugzilla::DB; use 5.10.1; use strict; +use warnings; use DBI; @@ -16,6 +17,7 @@ use DBI; use parent -norequire, qw(DBI::db); use Bugzilla::Constants; +use Bugzilla::Mailer; use Bugzilla::Install::Requirements; use Bugzilla::Install::Util qw(install_string); use Bugzilla::Install::Localconfig; @@ -113,7 +115,6 @@ sub connect_shadow { } sub connect_main { - my $lc = Bugzilla->localconfig; return _connect(Bugzilla->localconfig); } @@ -579,8 +580,11 @@ sub bz_add_column { my $current_def = $self->bz_column_info($table, $name); if (!$current_def) { + # REFERENCES need to happen later and not be created right away + my $trimmed_def = dclone($new_def); + delete $trimmed_def->{REFERENCES}; my @statements = $self->_bz_real_schema->get_add_column_ddl( - $table, $name, $new_def, + $table, $name, $trimmed_def, defined $init_value ? $self->quote($init_value) : undef); print get_text('install_column_add', { column => $name, table => $table }) . "\n" @@ -594,14 +598,14 @@ sub bz_add_column { # column exists there and has a REFERENCES item. # bz_setup_foreign_keys will then add this FK at the end of # Install::DB. - my $col_abstract = + my $col_abstract = $self->_bz_schema->get_column_abstract($table, $name); if (exists $col_abstract->{REFERENCES}) { my $new_fk = dclone($col_abstract->{REFERENCES}); $new_fk->{created} = 0; $new_def->{REFERENCES} = $new_fk; } - + $self->_bz_real_schema->set_column($table, $name, $new_def); $self->_bz_store_real_schema; } @@ -1209,12 +1213,13 @@ sub bz_start_transaction { sub bz_commit_transaction { my ($self) = @_; - + if ($self->{private_bz_transaction_count} > 1) { $self->{private_bz_transaction_count}--; } elsif ($self->bz_in_transaction) { $self->commit(); $self->{private_bz_transaction_count} = 0; + Bugzilla::Mailer->send_staged_mail(); } else { ThrowCodeError('not_in_transaction'); } @@ -2315,7 +2320,11 @@ values to. =item C<$name> - the name of the new column -=item C<\%definition> - Abstract column definition for the new column +=item C<$definition> - A hashref abstract column definition for the new column. +Note, if a C definition is included to create a foreign key +relationship, it will be created later instead of when the column is added. +Normally foreign keys are added by C at the end all at the same +time. =item C<$init_value> (optional) - An initial value to set the column to. Required if your column is NOT NULL and has no DEFAULT set. diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Mysql.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Mysql.pm index 28df1f0e85d..ae158e0f681 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB/Mysql.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Mysql.pm @@ -23,6 +23,7 @@ package Bugzilla::DB::Mysql; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::DB); @@ -85,17 +86,18 @@ sub new { $self->{private_bz_dsn} = $dsn; bless ($self, $class); - - # Bug 321645 - disable MySQL strict mode, if set + + # Check for MySQL modes. my ($var, $sql_mode) = $self->selectrow_array( "SHOW VARIABLES LIKE 'sql\\_mode'"); + # Disable ANSI and strict modes, else Bugzilla will crash. if ($sql_mode) { # STRICT_TRANS_TABLE or STRICT_ALL_TABLES enable MySQL strict mode, # causing bug 321645. TRADITIONAL sets these modes (among others) as # well, so it has to be stipped as well my $new_sql_mode = - join(",", grep {$_ !~ /^STRICT_(?:TRANS|ALL)_TABLES|TRADITIONAL$/} + join(",", grep {$_ !~ /^(?:ANSI|STRICT_(?:TRANS|ALL)_TABLES|TRADITIONAL)$/} split(/,/, $sql_mode)); if ($sql_mode ne $new_sql_mode) { @@ -292,7 +294,6 @@ sub _bz_get_initial_schema { sub bz_check_server_version { my $self = shift; - my $lc = Bugzilla->localconfig; if (lc(Bugzilla->localconfig->{db_name}) eq 'mysql') { die "It is not safe to run Bugzilla inside a database named 'mysql'.\n" . " Please pick a different value for \$db_name in localconfig.\n"; diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Oracle.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Oracle.pm index 23474fe15e5..7424019ac7f 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB/Oracle.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Oracle.pm @@ -23,6 +23,7 @@ package Bugzilla::DB::Oracle; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::DB); @@ -721,6 +722,7 @@ package Bugzilla::DB::Oracle::st; use 5.10.1; use strict; +use warnings; use parent -norequire, qw(DBI::st); diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Pg.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Pg.pm index 165eea559aa..4ec95725de8 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB/Pg.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Pg.pm @@ -23,6 +23,7 @@ package Bugzilla::DB::Pg; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; use Bugzilla::Version; @@ -230,6 +231,9 @@ sub bz_setup_database { my $self = shift; $self->SUPER::bz_setup_database(@_); + my ($has_plpgsql) = $self->selectrow_array("SELECT COUNT(*) FROM pg_language WHERE lanname = 'plpgsql'"); + $self->do('CREATE LANGUAGE plpgsql') unless $has_plpgsql; + # Custom Functions # -Copyright © 2013 Joshua D. Burns (JDBurnZ) and Message In Action LLC diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema.pm index 632ab639b83..ebe2cb4264a 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema.pm @@ -17,6 +17,7 @@ package Bugzilla::DB::Schema; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; use Bugzilla::Hook; @@ -277,11 +278,8 @@ use constant ABSTRACT_SCHEMA => { remaining_time => {TYPE => 'decimal(7,2)', NOTNULL => 1, DEFAULT => '0'}, deadline => {TYPE => 'DATETIME'}, - alias => {TYPE => 'varchar(20)'}, ], INDEXES => [ - bugs_alias_idx => {FIELDS => ['alias'], - TYPE => 'UNIQUE'}, bugs_assigned_to_idx => ['assigned_to'], bugs_creation_ts_idx => ['creation_ts'], bugs_delta_ts_idx => ['delta_ts'], @@ -358,6 +356,21 @@ use constant ABSTRACT_SCHEMA => { ], }, + bugs_aliases => { + FIELDS => [ + alias => {TYPE => 'varchar(40)', NOTNULL => 1}, + bug_id => {TYPE => 'INT3', + REFERENCES => {TABLE => 'bugs', + COLUMN => 'bug_id', + DELETE => 'CASCADE'}}, + ], + INDEXES => [ + bugs_aliases_bug_id_idx => ['bug_id'], + bugs_aliases_alias_idx => {FIELDS => ['alias'], + TYPE => 'UNIQUE'}, + ], + }, + cc => { FIELDS => [ bug_id => {TYPE => 'INT3', NOTNULL => 1, @@ -397,7 +410,8 @@ use constant ABSTRACT_SCHEMA => { DEFAULT => 'FALSE'}, type => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '0'}, - extra_data => {TYPE => 'varchar(255)'} + extra_data => {TYPE => 'varchar(255)'}, + is_markdown => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'} ], INDEXES => [ longdescs_bug_id_idx => [qw(bug_id work_time)], @@ -1177,7 +1191,7 @@ use constant ABSTRACT_SCHEMA => { issuedate => {TYPE => 'DATETIME', NOTNULL => 1} , token => {TYPE => 'varchar(16)', NOTNULL => 1, PRIMARYKEY => 1}, - tokentype => {TYPE => 'varchar(8)', NOTNULL => 1} , + tokentype => {TYPE => 'varchar(16)', NOTNULL => 1} , eventdata => {TYPE => 'TINYTEXT'}, ], INDEXES => [ @@ -1616,6 +1630,16 @@ use constant ABSTRACT_SCHEMA => { ], }, + # BUGMAIL + # ------- + + mail_staging => { + FIELDS => [ + id => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1}, + message => {TYPE => 'LONGBLOB', NOTNULL => 1}, + ], + }, + # THESCHWARTZ TABLES # ------------------ # Note: In the standard TheSchwartz schema, most integers are unsigned, @@ -1733,6 +1757,26 @@ use constant ABSTRACT_SCHEMA => { bug_user_last_visit_last_visit_ts_idx => ['last_visit_ts'], ], }, + + user_api_keys => { + FIELDS => [ + id => {TYPE => 'INTSERIAL', NOTNULL => 1, + PRIMARYKEY => 1}, + user_id => {TYPE => 'INT3', NOTNULL => 1, + REFERENCES => {TABLE => 'profiles', + COLUMN => 'userid', + DELETE => 'CASCADE'}}, + api_key => {TYPE => 'VARCHAR(40)', NOTNULL => 1}, + description => {TYPE => 'VARCHAR(255)'}, + revoked => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 'FALSE'}, + last_used => {TYPE => 'DATETIME'}, + ], + INDEXES => [ + user_api_keys_api_key_idx => {FIELDS => ['api_key'], TYPE => 'UNIQUE'}, + user_api_keys_user_id_idx => ['user_id'], + ], + }, }; # Foreign Keys are added in Bugzilla::DB::bz_add_field_tables diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Mysql.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Mysql.pm index 9d634243f83..0195fcb06c0 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Mysql.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Mysql.pm @@ -15,6 +15,7 @@ package Bugzilla::DB::Schema::Mysql; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Oracle.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Oracle.pm index 1554a0fe198..8fb5479b1d1 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Oracle.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Oracle.pm @@ -15,6 +15,7 @@ package Bugzilla::DB::Schema::Oracle; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::DB::Schema); use Carp qw(confess); diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Pg.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Pg.pm index fa784ef7d4d..55a93227282 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Pg.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Pg.pm @@ -15,6 +15,7 @@ package Bugzilla::DB::Schema::Pg; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::DB::Schema); use Storable qw(dclone); diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Sqlite.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Sqlite.pm index b29d7da2258..ccdbfd8aaa0 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Sqlite.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema/Sqlite.pm @@ -9,6 +9,7 @@ package Bugzilla::DB::Schema::Sqlite; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::DB::Schema); diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Sqlite.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Sqlite.pm index cffe3b65c7f..ddafc169622 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/DB/Sqlite.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Sqlite.pm @@ -9,6 +9,7 @@ package Bugzilla::DB::Sqlite; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::DB); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Error.pm b/mozilla/webtools/bugzilla/Bugzilla/Error.pm index 37b28095a40..05a7ce7b3a7 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Error.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Error.pm @@ -9,6 +9,7 @@ package Bugzilla::Error; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Extension.pm b/mozilla/webtools/bugzilla/Bugzilla/Extension.pm index 53bf6cd6633..17193f1b677 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Extension.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Extension.pm @@ -9,6 +9,7 @@ package Bugzilla::Extension; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Error; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Field.pm b/mozilla/webtools/bugzilla/Bugzilla/Field.pm index e72a9429343..761f7b94e98 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Field.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Field.pm @@ -59,6 +59,7 @@ package Bugzilla::Field; use 5.10.1; use strict; +use warnings; use parent qw(Exporter Bugzilla::Object); @Bugzilla::Field::EXPORT = qw(check_field get_field_id get_legal_field_values); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Field/Choice.pm b/mozilla/webtools/bugzilla/Bugzilla/Field/Choice.pm index 6f730072fbf..a66f69cee7a 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Field/Choice.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Field/Choice.pm @@ -9,6 +9,7 @@ package Bugzilla::Field::Choice; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Field/ChoiceInterface.pm b/mozilla/webtools/bugzilla/Bugzilla/Field/ChoiceInterface.pm index f7f5e3b7330..634d36ad127 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Field/ChoiceInterface.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Field/ChoiceInterface.pm @@ -9,6 +9,7 @@ package Bugzilla::Field::ChoiceInterface; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Error; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Flag.pm b/mozilla/webtools/bugzilla/Bugzilla/Flag.pm index ff9d236db6c..50474b8855f 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Flag.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Flag.pm @@ -9,6 +9,7 @@ package Bugzilla::Flag; use 5.10.1; use strict; +use warnings; =head1 NAME @@ -453,14 +454,15 @@ sub create { sub update { my $self = shift; my $dbh = Bugzilla->dbh; - my $timestamp = shift || $dbh->selectrow_array('SELECT NOW()'); + my $timestamp = shift || $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); my $changes = $self->SUPER::update(@_); if (scalar(keys %$changes)) { $dbh->do('UPDATE flags SET modification_date = ? WHERE id = ?', undef, ($timestamp, $self->id)); - $self->{'modification_date'} = format_time($timestamp, '%Y.%m.%d %T'); + $self->{'modification_date'} = + format_time($timestamp, '%Y.%m.%d %T', Bugzilla->local_timezone); Bugzilla->memcached->clear({ table => 'flags', id => $self->id }); } return $changes; @@ -931,6 +933,117 @@ sub extract_flags_from_cgi { =over +=item C + +Checks whether or not there are new flags to create and returns an +array of hashes. This array is then passed to Flag::create(). This differs +from the previous sub-routine as it is called for changing multiple bugs + +=back + +=cut + +sub multi_extract_flags_from_cgi { + my ($class, $bug, $vars, $skip) = @_; + my $cgi = Bugzilla->cgi; + + my $match_status = Bugzilla::User::match_field({ + '^requestee(_type)?-(\d+)$' => { 'type' => 'multi' }, + }, undef, $skip); + + $vars->{'match_field'} = 'requestee'; + if ($match_status == USER_MATCH_FAILED) { + $vars->{'message'} = 'user_match_failed'; + } + elsif ($match_status == USER_MATCH_MULTIPLE) { + $vars->{'message'} = 'user_match_multiple'; + } + + # Extract a list of flag type IDs from field names. + my @flagtype_ids = map(/^flag_type-(\d+)$/ ? $1 : (), $cgi->param()); + + my (@new_flags, @flags); + + # Get a list of active flag types available for this product/component. + my $flag_types = Bugzilla::FlagType::match( + { 'product_id' => $bug->{'product_id'}, + 'component_id' => $bug->{'component_id'}, + 'is_active' => 1 }); + + foreach my $flagtype_id (@flagtype_ids) { + # Checks if there are unexpected flags for the product/component. + if (!scalar(grep { $_->id == $flagtype_id } @$flag_types)) { + $vars->{'message'} = 'unexpected_flag_types'; + last; + } + } + + foreach my $flag_type (@$flag_types) { + my $type_id = $flag_type->id; + + # Bug flags are only valid for bugs + next unless ($flag_type->target_type eq 'bug'); + + # We are only interested in flags the user tries to create. + next unless scalar(grep { $_ == $type_id } @flagtype_ids); + + # Get the flags of this type already set for this bug. + my $current_flags = $class->match( + { 'type_id' => $type_id, + 'target_type' => 'bug', + 'bug_id' => $bug->bug_id }); + + # We will update existing flags (instead of creating new ones) + # if the flag exists and the user has not chosen the 'always add' + # option + my $update = scalar(@$current_flags) && ! $cgi->param("flags_add-$type_id"); + + my $status = $cgi->param("flag_type-$type_id"); + trick_taint($status); + + my @logins = $cgi->param("requestee_type-$type_id"); + if ($status eq "?" && scalar(@logins)) { + foreach my $login (@logins) { + if ($update) { + foreach my $current_flag (@$current_flags) { + push (@flags, { id => $current_flag->id, + status => $status, + requestee => $login, + skip_roe => $skip }); + } + } + else { + push (@new_flags, { type_id => $type_id, + status => $status, + requestee => $login, + skip_roe => $skip }); + } + + last unless $flag_type->is_multiplicable; + } + } + else { + if ($update) { + foreach my $current_flag (@$current_flags) { + push (@flags, { id => $current_flag->id, + status => $status }); + } + } + else { + push (@new_flags, { type_id => $type_id, + status => $status }); + } + } + } + + # Return the list of flags to update and/or to create. + return (\@flags, \@new_flags); +} + +=pod + +=over + =item C Sends an email notification about a flag being created, fulfilled @@ -1011,18 +1124,32 @@ sub notify { $default_lang = Bugzilla::User->new()->setting('lang'); } + # Get comments on the bug + my $all_comments = $bug->comments({ after => $bug->lastdiffed }); + @$all_comments = grep { $_->type || $_->body =~ /\S/ } @$all_comments; + + # Get public only comments + my $public_comments = [ grep { !$_->is_private } @$all_comments ]; + foreach my $to (keys %recipients) { # Add threadingmarker to allow flag notification emails to be the # threaded similar to normal bug change emails. my $thread_user_id = $recipients{$to} ? $recipients{$to}->id : 0; - my $vars = { 'flag' => $flag, - 'old_flag' => $old_flag, - 'to' => $to, - 'date' => $timestamp, - 'bug' => $bug, - 'attachment' => $attachment, - 'threadingmarker' => build_thread_marker($bug->id, $thread_user_id) }; + # We only want to show private comments to users in the is_insider group + my $comments = $recipients{$to} && $recipients{$to}->is_insider + ? $all_comments : $public_comments; + + my $vars = { + flag => $flag, + old_flag => $old_flag, + to => $to, + date => $timestamp, + bug => $bug, + attachment => $attachment, + threadingmarker => build_thread_marker($bug->id, $thread_user_id), + new_comments => $comments, + }; my $lang = $recipients{$to} ? $recipients{$to}->setting('lang') : $default_lang; diff --git a/mozilla/webtools/bugzilla/Bugzilla/FlagType.pm b/mozilla/webtools/bugzilla/Bugzilla/FlagType.pm index 34973684af3..72b3f64c1fb 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/FlagType.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/FlagType.pm @@ -9,6 +9,7 @@ package Bugzilla::FlagType; use 5.10.1; use strict; +use warnings; =head1 NAME @@ -40,6 +41,7 @@ use Bugzilla::Util; use Bugzilla::Group; use Email::Address; +use List::MoreUtils qw(uniq); use parent qw(Bugzilla::Object); @@ -378,8 +380,6 @@ sub set_clusions { if (!$products{$prod_id}) { $params->{id} = $prod_id; $products{$prod_id} = Bugzilla::Product->check($params); - $user->in_group('editcomponents', $prod_id) - || ThrowUserError('product_access_denied', $params); } $prod_name = $products{$prod_id}->name; @@ -405,6 +405,22 @@ sub set_clusions { $clusions{"$prod_name:$comp_name"} = "$prod_id:$comp_id"; $clusions_as_hash{$prod_id}->{$comp_id} = 1; } + + # Check the user has the editcomponent permission on products that are changing + if (! $user->in_group('editcomponents')) { + my $current_clusions = $self->$category; + my ($removed, $added) + = diff_arrays([ values %$current_clusions ], [ values %clusions ]); + my @changed_product_ids + = uniq map { substr($_, 0, index($_, ':')) } @$removed, @$added; + foreach my $product_id (@changed_product_ids) { + $user->in_group('editcomponents', $product_id) + || ThrowUserError('product_access_denied', + { name => $products{$product_id}->name }); + } + } + + # Set the changes $self->{$category} = \%clusions; $self->{"${category}_as_hash"} = \%clusions_as_hash; $self->{"_update_$category"} = 1; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Group.pm b/mozilla/webtools/bugzilla/Bugzilla/Group.pm index 965fa226f9d..07b78e3663b 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Group.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Group.pm @@ -9,6 +9,7 @@ package Bugzilla::Group; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); @@ -55,8 +56,10 @@ use constant UPDATE_COLUMNS => qw( ); # Parameters that are lists of groups. -use constant GROUP_PARAMS => qw(chartgroup insidergroup timetrackinggroup - querysharegroup); +use constant GROUP_PARAMS => qw( + chartgroup comment_taggers_group debug_group insidergroup + querysharegroup timetrackinggroup +); ############################### #### Accessors ###### diff --git a/mozilla/webtools/bugzilla/Bugzilla/Hook.pm b/mozilla/webtools/bugzilla/Bugzilla/Hook.pm index 5e4114398f4..2904acba143 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Hook.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Hook.pm @@ -9,6 +9,7 @@ package Bugzilla::Hook; use 5.10.1; use strict; +use warnings; sub process { my ($name, $args) = @_; @@ -1032,9 +1033,6 @@ Params: =item C - The C object that's about to be sent. -=item C - An arrayref that's passed as C to -L. - =back =head2 object_before_create diff --git a/mozilla/webtools/bugzilla/Bugzilla/Install.pm b/mozilla/webtools/bugzilla/Bugzilla/Install.pm index 41f88d70b32..5a2266e36fb 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Install.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Install.pm @@ -17,6 +17,7 @@ package Bugzilla::Install; use 5.10.1; use strict; +use warnings; use Bugzilla::Component; use Bugzilla::Config qw(:admin); @@ -89,6 +90,8 @@ sub SETTINGS { bugmail_new_prefix => { options => ['on', 'off'], default => 'on' }, # 2013-07-26 joshi_sunil@in.com -- Bug 669535 possible_duplicates => { options => ['on', 'off'], default => 'on' }, + # 2014-05-24 koosha.khajeh@gmail.com -- Bug 1014164 + use_markdown => { options => ['on', 'off'], default => 'on' }, } }; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Install/CPAN.pm b/mozilla/webtools/bugzilla/Bugzilla/Install/CPAN.pm index ba301863d9b..19f14319083 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Install/CPAN.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Install/CPAN.pm @@ -9,6 +9,7 @@ package Bugzilla::Install::CPAN; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); our @EXPORT = qw( diff --git a/mozilla/webtools/bugzilla/Bugzilla/Install/DB.pm b/mozilla/webtools/bugzilla/Bugzilla/Install/DB.pm index 9e197a90711..ab02fe41db3 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Install/DB.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Install/DB.pm @@ -12,6 +12,7 @@ package Bugzilla::Install::DB; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Hook; @@ -272,10 +273,6 @@ sub update_table_definitions { $dbh->bz_add_column('attachments', 'isprivate', {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); - $dbh->bz_add_column("bugs", "alias", {TYPE => "varchar(20)"}); - $dbh->bz_add_index('bugs', 'bugs_alias_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(alias)]}); - _move_quips_into_db(); $dbh->bz_drop_column("namedqueries", "watchfordiffs"); @@ -719,6 +716,20 @@ sub update_table_definitions { 'bug_user_last_visit_last_visit_ts_idx', ['last_visit_ts']); + # 2014-07-14 sgreen@redhat.com - Bug 726696 + $dbh->bz_alter_column('tokens', 'tokentype', + {TYPE => 'varchar(16)', NOTNULL => 1}); + + # 2014-07-27 LpSolit@gmail.com - Bug 1044561 + _fix_user_api_keys_indexes(); + + # 2014-08-11 sgreen@redhat.com - Bug 1012506 + _update_alias(); + + # 2014-08-14 koosha.khajeh@gmail.com - Bug 330707 + $dbh->bz_add_column('longdescs', 'is_markdown', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + ################################################################ # New --TABLE-- changes should go *** A B O V E *** this point # ################################################################ @@ -2550,7 +2561,7 @@ sub _fix_whine_queries_title_and_op_sys_value { undef, "Other", "other"); if (Bugzilla->params->{'defaultopsys'} eq 'other') { # We can't actually fix the param here, because WriteParams() will - # make $datadir/params unwriteable to the webservergroup. + # make $datadir/params.json unwriteable to the webservergroup. # It's too much of an ugly hack to copy the permission-fixing code # down to here. (It would create more potential future bugs than # it would solve problems.) @@ -3877,6 +3888,33 @@ sub _fix_components_primary_key { } } +sub _fix_user_api_keys_indexes { + my $dbh = Bugzilla->dbh; + + if ($dbh->bz_index_info('user_api_keys', 'user_api_keys_key')) { + $dbh->bz_drop_index('user_api_keys', 'user_api_keys_key'); + $dbh->bz_add_index('user_api_keys', 'user_api_keys_api_key_idx', + { FIELDS => ['api_key'], TYPE => 'UNIQUE' }); + } + if ($dbh->bz_index_info('user_api_keys', 'user_api_keys_user_id')) { + $dbh->bz_drop_index('user_api_keys', 'user_api_keys_user_id'); + $dbh->bz_add_index('user_api_keys', 'user_api_keys_user_id_idx', ['user_id']); + } +} + +sub _update_alias { + my $dbh = Bugzilla->dbh; + return unless $dbh->bz_column_info('bugs', 'alias'); + + # We need to move the aliases from the bugs table to the bugs_aliases table + $dbh->do(q{ + INSERT INTO bugs_aliases (bug_id, alias) + SELECT bug_id, alias FROM bugs WHERE alias IS NOT NULL + }); + + $dbh->bz_drop_column('bugs', 'alias'); +} + 1; __END__ diff --git a/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm b/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm index d980a219947..061ca53c724 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Install/Filesystem.pm @@ -17,6 +17,7 @@ package Bugzilla::Install::Filesystem; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Error; @@ -30,6 +31,7 @@ use File::Path; use File::Basename; use File::Copy qw(move); use File::Spec; +use File::Slurp; use IO::File; use POSIX (); @@ -170,7 +172,7 @@ sub FILESYSTEM { 'docs/style.css' => { perms => WS_SERVE }, 'docs/*/rel_notes.txt' => { perms => WS_SERVE }, 'docs/*/README.docs' => { perms => OWNER_WRITE }, - "$datadir/params" => { perms => CGI_WRITE }, + "$datadir/params.json" => { perms => CGI_WRITE }, "$datadir/old-params.txt" => { perms => OWNER_WRITE }, "$extensionsdir/create.pl" => { perms => OWNER_EXECUTE }, "$extensionsdir/*/*.pl" => { perms => WS_EXECUTE }, @@ -366,7 +368,7 @@ EOT "$assetsdir/.htaccess" => { perms => WS_SERVE, contents => < + Allow from all @@ -409,6 +411,7 @@ sub update_filesystem { my $datadir = bz_locations->{'datadir'}; my $graphsdir = bz_locations->{'graphsdir'}; + my $assetsdir = bz_locations->{'assetsdir'}; # If the graphs/ directory doesn't exist, we're upgrading from # a version old enough that we need to update the $datadir/mining # format. @@ -449,6 +452,13 @@ sub update_filesystem { _rename_file($oldparamsfile, "$datadir/$oldparamsfile"); } + # Remove old assets htaccess file to force recreation with correct values. + if (-e "$assetsdir/.htaccess") { + if (read_file("$assetsdir/.htaccess") =~ //) { + unlink("$assetsdir/.htaccess"); + } + } + _create_files(%files); if ($params->{index_html}) { _create_files(%{$fs->{index_html}}); @@ -492,7 +502,7 @@ EOT _remove_empty_css_files(); _convert_single_file_skins(); - _remove_dynamic_css_files(); + _remove_dynamic_assets(); } sub _remove_empty_css_files { @@ -537,10 +547,14 @@ sub _convert_single_file_skins { } } -# delete all automatically generated css files to force recreation at the next -# request. -sub _remove_dynamic_css_files { - foreach my $file (glob(bz_locations()->{assetsdir} . '/*.css')) { +# delete all automatically generated css/js files to force recreation at the +# next request. +sub _remove_dynamic_assets { + my @files = ( + glob(bz_locations()->{assetsdir} . '/*.css'), + glob(bz_locations()->{assetsdir} . '/*.js'), + ); + foreach my $file (@files) { unlink($file); } diff --git a/mozilla/webtools/bugzilla/Bugzilla/Install/Localconfig.pm b/mozilla/webtools/bugzilla/Bugzilla/Install/Localconfig.pm index 71a9c6ae089..7f473cc77f2 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Install/Localconfig.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Install/Localconfig.pm @@ -17,6 +17,7 @@ package Bugzilla::Install::Localconfig; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Install::Util qw(bin_loc install_string); @@ -99,10 +100,6 @@ use constant LOCALCONFIG_VARS => ( name => 'index_html', default => 0, }, - { - name => 'cvsbin', - default => sub { bin_loc('cvs') }, - }, { name => 'interdiffbin', default => sub { bin_loc('interdiff') }, diff --git a/mozilla/webtools/bugzilla/Bugzilla/Install/Requirements.pm b/mozilla/webtools/bugzilla/Bugzilla/Install/Requirements.pm index d9e49017d1c..db3d7b02862 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Install/Requirements.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Install/Requirements.pm @@ -15,6 +15,7 @@ package Bugzilla::Install::Requirements; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Install::Util qw(install_string bin_loc @@ -22,13 +23,6 @@ use Bugzilla::Install::Util qw(install_string bin_loc use List::Util qw(max); use Term::ANSIColor; -# Return::Value 1.666002 pollutes the error log with warnings about this -# deprecated module. We have to set NO_CLUCK = 1 before loading Email::Send -# in have_vers() to disable these warnings. -BEGIN { - $Return::Value::NO_CLUCK = 1; -} - use parent qw(Exporter); our @EXPORT = qw( REQUIRED_MODULES @@ -130,12 +124,11 @@ sub REQUIRED_MODULES { module => 'Template', version => '2.24' }, - # 2.04 implement the "Test" method (to write to data/mailer.testfile). + # 1.300011 has a debug mode for SMTP and automatically pass -i to sendmail. { - package => 'Email-Send', - module => 'Email::Send', - version => ON_WINDOWS ? '2.16' : '2.04', - blacklist => ['^2\.196$'] + package => 'Email-Sender', + module => 'Email::Sender', + version => '1.300011', }, { package => 'Email-MIME', @@ -165,6 +158,12 @@ sub REQUIRED_MODULES { module => 'File::Slurp', version => '9999.13', }, + { + package => 'JSON-XS', + module => 'JSON::XS', + # 2.0 is the first version that will work with JSON::RPC. + version => '2.01', + }, ); if (ON_WINDOWS) { @@ -297,13 +296,6 @@ sub OPTIONAL_MODULES { version => 0, feature => ['jsonrpc', 'rest'], }, - { - package => 'JSON-XS', - module => 'JSON::XS', - # 2.0 is the first version that will work with JSON::RPC. - version => '2.0', - feature => ['jsonrpc_faster'], - }, { package => 'Test-Taint', module => 'Test::Taint', @@ -404,6 +396,14 @@ sub OPTIONAL_MODULES { version => '0', feature => ['memcached'], }, + + # Markdown + { + package => 'Text-Markdown', + module => 'Text::Markdown', + version => '1.0.26', + feature => ['markdown'], + } ); my $extra_modules = _get_extension_requirements('OPTIONAL_MODULES'); @@ -427,6 +427,7 @@ use constant FEATURE_FILES => ( 'Bugzilla/JobQueue/*', 'jobqueue.pl'], patch_viewer => ['Bugzilla/Attachment/PatchReader.pm'], updates => ['Bugzilla/Update.pm'], + markdown => ['Bugzilla/Markdown.pm'], memcached => ['Bugzilla/Memcache.pm'], ); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Install/Util.pm b/mozilla/webtools/bugzilla/Bugzilla/Install/Util.pm index 66ea7169ea0..c05037061f9 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Install/Util.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Install/Util.pm @@ -13,6 +13,7 @@ package Bugzilla::Install::Util; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Job/BugMail.pm b/mozilla/webtools/bugzilla/Bugzilla/Job/BugMail.pm index 9c176b005f3..e0b7f54482e 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Job/BugMail.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Job/BugMail.pm @@ -9,6 +9,7 @@ package Bugzilla::Job::BugMail; use 5.10.1; use strict; +use warnings; use Bugzilla::BugMail; BEGIN { eval "use parent qw(Bugzilla::Job::Mailer)"; } diff --git a/mozilla/webtools/bugzilla/Bugzilla/Job/Mailer.pm b/mozilla/webtools/bugzilla/Bugzilla/Job/Mailer.pm index 8fce80dd01c..cd1c23445a2 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Job/Mailer.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Job/Mailer.pm @@ -9,6 +9,7 @@ package Bugzilla::Job::Mailer; use 5.10.1; use strict; +use warnings; use Bugzilla::Mailer; BEGIN { eval "use parent qw(TheSchwartz::Worker)"; } diff --git a/mozilla/webtools/bugzilla/Bugzilla/JobQueue.pm b/mozilla/webtools/bugzilla/Bugzilla/JobQueue.pm index 4ff5750da80..d5ceda8e9fa 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/JobQueue.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/JobQueue.pm @@ -9,6 +9,7 @@ package Bugzilla::JobQueue; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Error; diff --git a/mozilla/webtools/bugzilla/Bugzilla/JobQueue/Runner.pm b/mozilla/webtools/bugzilla/Bugzilla/JobQueue/Runner.pm index a0d6a77cb5d..2367f8d77e6 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/JobQueue/Runner.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/JobQueue/Runner.pm @@ -13,6 +13,7 @@ package Bugzilla::JobQueue::Runner; use 5.10.1; use strict; +use warnings; use Cwd qw(abs_path); use File::Basename; @@ -79,6 +80,7 @@ sub gd_more_opt { return ( 'pidfile=s' => \$self->{gd_args}{pidfile}, 'n=s' => \$self->{gd_args}{progname}, + 'j=s@' => \$self->{gd_args}{job_name}, ); } @@ -209,10 +211,12 @@ sub gd_run { sub _do_work { my ($self, $fn) = @_; + my @job_name = @{ $self->{gd_args}{job_name} // [] }; my $jq = Bugzilla->job_queue(); $jq->set_verbose($self->{debug}); $jq->set_pidfile($self->{gd_pidfile}); - foreach my $module (values %{ Bugzilla::JobQueue->job_map() }) { + while (my ($key, $module) = each %{ Bugzilla::JobQueue->job_map() }) { + next if @job_name and ! grep { $_ eq $key } @job_name; eval "use $module"; $jq->can_do($module); } diff --git a/mozilla/webtools/bugzilla/Bugzilla/Keyword.pm b/mozilla/webtools/bugzilla/Bugzilla/Keyword.pm index a8c098854a3..afa93e1e9ad 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Keyword.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Keyword.pm @@ -9,6 +9,7 @@ package Bugzilla::Keyword; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Mailer.pm b/mozilla/webtools/bugzilla/Bugzilla/Mailer.pm index b60ddb72e5f..4447d404620 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Mailer.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Mailer.pm @@ -9,6 +9,7 @@ package Bugzilla::Mailer; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); @Bugzilla::Mailer::EXPORT = qw(MessageToMTA build_thread_marker); @@ -22,22 +23,20 @@ use Date::Format qw(time2str); use Encode qw(encode); use Encode::MIME::Header; -use Email::Address; use Email::MIME; -# Return::Value 1.666002 pollutes the error log with warnings about this -# deprecated module. We have to set NO_CLUCK = 1 before loading Email::Send -# to disable these warnings. -BEGIN { - $Return::Value::NO_CLUCK = 1; -} -use Email::Send; +use Email::Sender::Simple qw(sendmail); +use Email::Sender::Transport::SMTP::Persistent; +use Bugzilla::Sender::Transport::Sendmail; sub MessageToMTA { my ($msg, $send_now) = (@_); my $method = Bugzilla->params->{'mail_delivery_method'}; return if $method eq 'None'; - if (Bugzilla->params->{'use_mailer_queue'} and !$send_now) { + if (Bugzilla->params->{'use_mailer_queue'} + && ! $send_now + && ! Bugzilla->dbh->bz_in_transaction() + ) { Bugzilla->job_queue->insert('send_mail', { msg => $msg }); return; } @@ -51,12 +50,22 @@ sub MessageToMTA { # Email::MIME doesn't do this for us. We use \015 (CR) and \012 (LF) # directly because Perl translates "\n" depending on what platform # you're running on. See http://perldoc.perl.org/perlport.html#Newlines - # We check for multiple CRs because of this Template-Toolkit bug: - # https://rt.cpan.org/Ticket/Display.html?id=43345 $msg =~ s/(?:\015+)?\012/\015\012/msg; $email = new Email::MIME($msg); } + # If we're called from within a transaction, we don't want to send the + # email immediately, in case the transaction is rolled back. Instead we + # insert it into the mail_staging table, and bz_commit_transaction calls + # send_staged_mail() after the transaction is committed. + if (! $send_now && Bugzilla->dbh->bz_in_transaction()) { + # The e-mail string may contain tainted values. + my $string = $email->as_string; + trick_taint($string); + Bugzilla->dbh->do("INSERT INTO mail_staging (message) VALUES(?)", undef, $string); + return; + } + # We add this header to uniquely identify all email that we # send as coming from this Bugzilla installation. # @@ -64,7 +73,7 @@ sub MessageToMTA { # *always* be the same for this Bugzilla, in every email, # even if the admin changes the "ssl_redirect" parameter some day. $email->header_set('X-Bugzilla-URL', Bugzilla->params->{'urlbase'}); - + # We add this header to mark the mail as "auto-generated" and # thus to hopefully avoid auto replies. $email->header_set('Auto-Submitted', 'auto-generated'); @@ -92,21 +101,14 @@ sub MessageToMTA { my $from = $email->header('From'); - my ($hostname, @args); - my $mailer_class = $method; + my $hostname; + my $transport; if ($method eq "Sendmail") { - $mailer_class = 'Bugzilla::Send::Sendmail'; if (ON_WINDOWS) { - $Email::Send::Sendmail::SENDMAIL = SENDMAIL_EXE; + $transport = Bugzilla::Sender::Transport::Sendmail->new({ sendmail => SENDMAIL_EXE }); } - push @args, "-i"; - # We want to make sure that we pass *only* an email address. - if ($from) { - my ($email_obj) = Email::Address->parse($from); - if ($email_obj) { - my $from_email = $email_obj->address; - push(@args, "-f$from_email") if $from_email; - } + else { + $transport = Bugzilla::Sender::Transport::Sendmail->new(); } } else { @@ -125,16 +127,19 @@ sub MessageToMTA { } if ($method eq "SMTP") { - push @args, Host => Bugzilla->params->{"smtpserver"}, - username => Bugzilla->params->{"smtp_username"}, - password => Bugzilla->params->{"smtp_password"}, - Hello => $hostname, - ssl => Bugzilla->params->{'smtp_ssl'}, - Debug => Bugzilla->params->{'smtp_debug'}; + my ($host, $port) = split(/:/, Bugzilla->params->{'smtpserver'}, 2); + $transport = Bugzilla->request_cache->{smtp} //= + Email::Sender::Transport::SMTP::Persistent->new({ + host => $host, + defined($port) ? (port => $port) : (), + sasl_username => Bugzilla->params->{'smtp_username'}, + sasl_password => Bugzilla->params->{'smtp_password'}, + helo => $hostname, + ssl => Bugzilla->params->{'smtp_ssl'}, + debug => Bugzilla->params->{'smtp_debug'} }); } - Bugzilla::Hook::process('mailer_before_send', - { email => $email, mailer_args => \@args }); + Bugzilla::Hook::process('mailer_before_send', { email => $email }); return if $email->header('to') eq ''; @@ -169,13 +174,12 @@ sub MessageToMTA { close TESTFILE; } else { - # This is useful for both Sendmail and Qmail, so we put it out here. + # This is useful for Sendmail, so we put it out here. local $ENV{PATH} = SENDMAIL_PATH; - my $mailer = Email::Send->new({ mailer => $mailer_class, - mailer_args => \@args }); - my $retval = $mailer->send($email); - ThrowCodeError('mail_send_error', { msg => $retval, mail => $email }) - if !$retval; + eval { sendmail($email, { transport => $transport }) }; + if ($@) { + ThrowCodeError('mail_send_error', { msg => $@->message, mail => $email }); + } } } @@ -208,14 +212,50 @@ sub build_thread_marker { return $threadingmarker; } +sub send_staged_mail { + my $dbh = Bugzilla->dbh; + my @ids; + my $emails + = $dbh->selectall_arrayref("SELECT id, message FROM mail_staging"); + + foreach my $row (@$emails) { + MessageToMTA($row->[1]); + push(@ids, $row->[0]); + } + + if (@ids) { + $dbh->do("DELETE FROM mail_staging WHERE " . $dbh->sql_in('id', \@ids)); + } +} + 1; -=head1 B +__END__ + +=head1 NAME + +Bugzilla::Mailer - Provides methods for sending email + +=head1 METHODS =over -=item build_thread_marker +=item C -=item MessageToMTA +Sends the passed message to the mail transfer agent. + +The actual behaviour depends on a number of factors: if called from within a +database transaction, the message will be staged and sent when the transaction +is committed. If email queueing is enabled, the message will be sent to +TheSchwartz job queue where it will be processed by the jobqueue daemon, else +the message is sent immediately. + +=item C + +Builds header suitable for use as a threading marker in email notifications. + +=item C + +Sends all staged messages -- called after a database transaction is committed. =back diff --git a/mozilla/webtools/bugzilla/Bugzilla/Markdown.pm b/mozilla/webtools/bugzilla/Bugzilla/Markdown.pm new file mode 100644 index 00000000000..353c2ff6aef --- /dev/null +++ b/mozilla/webtools/bugzilla/Bugzilla/Markdown.pm @@ -0,0 +1,520 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Markdown; + +use 5.10.1; +use strict; +use warnings; + +use Bugzilla::Constants; +use Bugzilla::Template; + +use Digest::MD5 qw(md5_hex); + +use parent qw(Text::Markdown); + +@Bugzilla::Markdown::EXPORT = qw(new); + +# Regex to match balanced [brackets]. See Friedl's +# "Mastering Regular Expressions", 2nd Ed., pp. 328-331. +our ($g_nested_brackets, $g_nested_parens); +$g_nested_brackets = qr{ + (?> # Atomic matching + [^\[\]]+ # Anything other than brackets + | + \[ + (??{ $g_nested_brackets }) # Recursive set of nested brackets + \] + )* +}x; +# Doesn't allow for whitespace, because we're using it to match URLs: +$g_nested_parens = qr{ + (?> # Atomic matching + [^()\s]+ # Anything other than parens or whitespace + | + \( + (??{ $g_nested_parens }) # Recursive set of nested brackets + \) + )* +}x; + +our %g_escape_table; +foreach my $char (split //, '\\`*_{}[]()>#+-.!~') { + $g_escape_table{$char} = md5_hex($char); +} +$g_escape_table{'<'} = md5_hex('<'); + +sub new { + my $invocant = shift; + my $class = ref $invocant || $invocant; + return $class->SUPER::new(tab_width => MARKDOWN_TAB_WIDTH, + # Bugzilla uses HTML not XHTML + empty_element_suffix => '>'); +} + +sub markdown { + my $self = shift; + my $text = shift; + my $user = Bugzilla->user; + + if ($user->settings->{use_markdown}->{is_enabled} + && $user->setting('use_markdown') eq 'on') + { + return $self->SUPER::markdown($text, @_); + } + + return Bugzilla::Template::quoteUrls($text); +} + +sub _Markdown { + my $self = shift; + my $text = shift; + + $text = Bugzilla::Template::quoteUrls($text, undef, undef, undef, undef, 1); + + return $self->SUPER::_Markdown($text, @_); +} + +sub _RunSpanGamut { + # These are all the transformations that occur *within* block-level + # tags like paragraphs, headers, and list items. + + my ($self, $text) = @_; + + $text = $self->_DoCodeSpans($text); + $text = $self->_EscapeSpecialCharsWithinTagAttributes($text); + $text = $self->_EscapeSpecialChars($text); + + $text = $self->_DoAnchors($text); + + # Strikethroughs is Bugzilla's extension + $text = $self->_DoStrikethroughs($text); + + $text = $self->_DoAutoLinks($text); + $text = $self->_EncodeAmpsAndAngles($text); + $text = $self->_DoItalicsAndBold($text); + + $text =~ s/\n/{empty_element_suffix}\n/g; + + return $text; +} + +# Override to check for HTML-escaped <>" chars. +sub _StripLinkDefinitions { +# +# Strips link definitions from text, stores the URLs and titles in +# hash references. +# + my ($self, $text) = @_; + my $less_than_tab = $self->{tab_width} - 1; + + # Link defs are in the form: ^[id]: url "optional title" + while ($text =~ s{ + ^[ ]{0,$less_than_tab}\[(.+)\]: # id = \$1 + [ \t]* + \n? # maybe *one* newline + [ \t]* + (?:<)?\2(?:>)? # url = \$2 + [ \t]* + \n? # maybe one newline + [ \t]* + (?: + (?<=\s) # lookbehind for whitespace + (?:"|\() + (.+?) # title = \$3 + (?:"|\)) + [ \t]* + )? # title is optional + (?:\n+|\Z) + }{}omx) { + $self->{_urls}{lc $1} = $self->_EncodeAmpsAndAngles( $2 ); # Link IDs are case-insensitive + if ($3) { + $self->{_titles}{lc $1} = $3; + $self->{_titles}{lc $1} =~ s/"/"/g; + } + + } + + return $text; +} + +# We need to look for HTML-escaped '<' and '>' (i.e. < and >). +# We also remove Email linkification from the original implementation +# as it is already done in Bugzilla's quoteUrls(). +sub _DoAutoLinks { + my ($self, $text) = @_; + + $text =~ s{(?:<|<)((?:https?|ftp):[^'">\s]+?)(?:>|>)}{$1}gi; + return $text; +} + +# The main reasons for overriding this method are +# resolving URL conflicts with Bugzilla's quoteUrls() +# and also changing '"' to '"' in regular expressions wherever needed. +sub _DoAnchors { +# +# Turn Markdown link shortcuts into tags. +# + my ($self, $text) = @_; + + # We revert linkifications of non-email links and only + # those links whose URL and title are the same because + # this way we can be sure that link is generated by quoteUrls() + $text =~ s@\1@$1@xmg; + + # + # First, handle reference-style links: [link text] [id] + # + $text =~ s{ + ( # wrap whole match in $1 + \[ + ($g_nested_brackets) # link text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + ) + }{ + my $whole_match = $1; + my $link_text = $2; + my $link_id = lc $3; + + if ($link_id eq "") { + $link_id = lc $link_text; # for shortcut links like [this][]. + } + + $link_id =~ s{[ ]*\n}{ }g; # turn embedded newlines into spaces + + $self->_GenerateAnchor($whole_match, $link_text, $link_id); + }xsge; + + # + # Next, inline-style links: [link text](url "optional title") + # + $text =~ s{ + ( # wrap whole match in $1 + \[ + ($g_nested_brackets) # link text = $2 + \] + \( # literal paren + [ \t]* + ($g_nested_parens) # href = $3 + [ \t]* + ( # $4 + ("|') # quote char = $5 + (.*?) # Title = $6 + \5 # matching quote + [ \t]* # ignore any spaces/tabs between closing quote and ) + )? # title is optional + \) + ) + }{ + my $result; + my $whole_match = $1; + my $link_text = $2; + my $url = $3; + my $title = $6; + + # Remove Bugzilla quoteUrls() linkification + if ($url =~ /^a href="/ && $url =~ m|]+>//; + $url =~ s@_GenerateAnchor($whole_match, $link_text, undef, $url, $title); + }xsge; + + # + # Last, handle reference-style shortcuts: [link text] + # These must come last in case you've also got [link test][1] + # or [link test](/foo) + # + $text =~ s{ + ( # wrap whole match in $1 + \[ + ([^\[\]]+) # link text = $2; can't contain '[' or ']' + \] + ) + }{ + my $result; + my $whole_match = $1; + my $link_text = $2; + (my $link_id = lc $2) =~ s{[ ]*\n}{ }g; # lower-case and turn embedded newlines into spaces + + $self->_GenerateAnchor($whole_match, $link_text, $link_id); + }xsge; + + return $text; +} + +# The purpose of overriding this function is to add support +# for a Github Flavored Markdown (GFM) feature called 'Multiple +# underscores in words'. The standard markdown specification +# specifies the underscore for making the text emphasized/bold. +# However, some variable names in programming languages contain underscores +# and we do not want a part of those variables to look emphasized/bold. +# Instead, we render them as the way they originally are. +sub _DoItalicsAndBold { + my ($self, $text) = @_; + + # Handle at beginning of lines: + $text =~ s{ (^__ (?=\S) (.+?[*_]*) (?<=\S) __ (?!\S)) } + { + my $result = _has_multiple_underscores($2) ? $1 : "$2"; + $result; + }gsxe; + + $text =~ s{ ^\*\* (?=\S) (.+?[*_]*) (?<=\S) \*\* }{$1}gsx; + + $text =~ s{ (^_ (?=\S) (.+?) (?<=\S) _ (?!\S)) } + { + my $result = _has_multiple_underscores($2) ? $1 : "$2"; + $result; + }gsxe; + + $text =~ s{ ^\* (?=\S) (.+?) (?<=\S) \* }{$1}gsx; + + # must go first: + $text =~ s{ ( (?<=\W) __ (?=\S) (.+?[*_]*) (?<=\S) __ (?!\S) ) } + { + my $result = _has_multiple_underscores($2) ? $1 : "$2"; + $result; + }gsxe; + + + $text =~ s{ (?<=\W) \*\* (?=\S) (.+?[*_]*) (?<=\S) \*\* }{$1}gsx; + + $text =~ s{ ( (?<=\W) _ (?=\S) (.+?) (?<=\S) _ (?!\S) ) } + { + my $result = _has_multiple_underscores($2) ? $1 : "$2"; + $result; + }gsxe; + + $text =~ s{ (?<=\W) \* (?=\S) (.+?) (?<=\S) \* }{$1}gsx; + + # And now, a second pass to catch nested strong and emphasis special cases + $text =~ s{ ( (?<=\W) __ (?=\S) (.+?[*_]*) (?<=\S) __ (\S*) ) } + { + my $result = _has_multiple_underscores($3) ? $1 : "$2$3"; + $result; + }gsxe; + + $text =~ s{ (?<=\W) \*\* (?=\S) (.+?[*_]*) (?<=\S) \*\* }{$1}gsx; + $text =~ s{ ( (?<=\W) _ (?=\S) (.+?) (?<=\S) _ (\S*) ) } + { + my $result = _has_multiple_underscores($3) ? $1 : "$2$3"; + $result; + }gsxe; + + $text =~ s{ (?<=\W) \* (?=\S) (.+?) (?<=\S) \* }{$1}gsx; + + return $text; +} + +sub _DoStrikethroughs { + my ($self, $text) = @_; + + $text =~ s{ ^ ~~ (?=\S) ([^~]+?) (?<=\S) ~~ (?!~) }{$1}gsx; + $text =~ s{ (?<=_|[^~\w]) ~~ (?=\S) ([^~]+?) (?<=\S) ~~ (?!~) }{$1}gsx; + + return $text; +} + +# The original _DoCodeSpans() uses the 's' modifier in its regex +# which prevents _DoCodeBlocks() to match GFM fenced code blocks. +# We copy the code from the original implementation and remove the +# 's' modifier from it. +sub _DoCodeSpans { + my ($self, $text) = @_; + + $text =~ s@ + (?_EncodeCode($c); + "$c"; + @egx; + + return $text; +} + +# Override to add GFM Fenced Code Blocks +sub _DoCodeBlocks { + my ($self, $text) = @_; + + $text =~ s{ + ^ `{3,} [\s\t]* \n + ( # $1 = the entire code block + (?: .* \n+)+? + ) + `{3,} [\s\t]* $ + }{ + my $codeblock = $1; + my $result; + + $codeblock = $self->_EncodeCode($codeblock); + $codeblock = $self->_Detab($codeblock); + $codeblock =~ s/\n\z//; # remove the trailing newline + + $result = "\n\n
" . $codeblock . "
\n\n"; + $result; + }egmx; + + # And now do the standard code blocks + $text = $self->SUPER::_DoCodeBlocks($text); + + return $text; +} + +sub _DoBlockQuotes { + my ($self, $text) = @_; + + $text =~ s{ + ( # Wrap whole match in $1 + (?: + ^[ \t]*>[ \t]? # '>' at the start of a line + .+\n # rest of the first line + (?:.+\n)* # subsequent consecutive lines + \n* # blanks + )+ + ) + }{ + my $bq = $1; + $bq =~ s/^[ \t]*>[ \t]?//gm; # trim one level of quoting + $bq =~ s/^[ \t]+$//mg; # trim whitespace-only lines + $bq = $self->_RunBlockGamut($bq, {wrap_in_p_tags => 1}); # recurse + $bq =~ s/^/ /mg; + # These leading spaces screw with
 content, so we need to fix that:
+            $bq =~ s{(\s*
.+?
)}{ + my $pre = $1; + $pre =~ s/^ //mg; + $pre; + }egs; + "
\n$bq\n
\n\n"; + }egmx; + + return $text; +} + +sub _EncodeCode { + my ($self, $text) = @_; + + # We need to unescape the escaped HTML characters in code blocks. + # These are the reverse of the escapings done in Bugzilla::Util::html_quote() + $text =~ s/<//g; + $text =~ s/"/"/g; + $text =~ s/@/@/g; + # '&' substitution must be the last one, otherwise a literal like '>' + # will turn to '>' because '&' is already changed to '&' in Bugzilla::Util::html_quote(). + # In other words, html_quote() will change '>' to '&gt;' and then we will + # change '&gt' -> '>' -> '>' if we write this substitution as the first one. + $text =~ s/&/&/g; + $text =~ s{ \1 }{$1}xmgi; + $text = $self->SUPER::_EncodeCode($text); + $text =~ s/~/$g_escape_table{'~'}/go; + # Encode '<' to prevent URLs from getting linkified in code spans + $text =~ s/</$g_escape_table{'<'}/go; + + return $text; +} + +sub _EncodeBackslashEscapes { + my ($self, $text) = @_; + + $text = $self->SUPER::_EncodeBackslashEscapes($text); + $text =~ s/\\~/$g_escape_table{'~'}/go; + + return $text; +} + +sub _UnescapeSpecialChars { + my ($self, $text) = @_; + + $text = $self->SUPER::_UnescapeSpecialChars($text); + $text =~ s/$g_escape_table{'~'}/~/go; + $text =~ s/$g_escape_table{'<'}/</go; + + return $text; +} + +# Check if the passed string is of the form multiple_underscores_in_a_word. +# To check that, we first need to make sure that the string does not contain +# any white-space. Then, if the string is composed of non-space chunks which +# are bound together with underscores, the string has the desired form. +sub _has_multiple_underscores { + my $string = shift; + return 0 unless defined($string) && length($string); + return 0 if $string =~ /[\t\s]+/; + return 1 if scalar (split /_/, $string) > 1; + return 0; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Markdown - Generates HTML output from structured plain-text input. + +=head1 SYNOPSIS + + use Bugzilla::Markdown; + + my $markdown = Bugzilla::Markdown->new(); + print $markdown->markdown($text); + +=head1 DESCRIPTION + +Bugzilla::Markdown implements a Markdown engine that produces +an HTML-based output from a given plain-text input. + +The majority of the implementation is done by C +CPAN module. It also applies the linkifications done in L +to the input resulting in an output which is a combination of both Markdown +structures and those defined by Bugzilla itself. + +=head2 Accessors + +=over + +=item C + +C Produces an HTML-based output string based on the structures +and format defined in the given plain-text input. + +=over + +=item B + +=over + +=item C + +C A plain-text string which includes Markdown structures. + +=back + +=back + +=back diff --git a/mozilla/webtools/bugzilla/Bugzilla/Memcached.pm b/mozilla/webtools/bugzilla/Bugzilla/Memcached.pm index 1464b6c003e..df90fef9342 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Memcached.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Memcached.pm @@ -254,10 +254,13 @@ sub _get { elsif (ref($value) eq 'ARRAY') { foreach my $value (@$value) { next unless defined $value; - # arrays of hashes are common + # arrays of hashes and arrays are common if (ref($value) eq 'HASH') { _detaint_hashref($value); } + elsif (ref($value) eq 'ARRAY') { + _detaint_arrayref($value); + } elsif (!ref($value)) { trick_taint($value); } @@ -278,6 +281,15 @@ sub _detaint_hashref { } } +sub _detaint_arrayref { + my ($arrayref) = @_; + foreach my $value (@$arrayref) { + if (defined($value) && !ref($value)) { + trick_taint($value); + } + } +} + sub _delete { my ($self, $key) = @_; $key = $self->_encode_key($key) diff --git a/mozilla/webtools/bugzilla/Bugzilla/Migrate.pm b/mozilla/webtools/bugzilla/Bugzilla/Migrate.pm index 2763ecb2bd4..0731d4fedf9 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Migrate.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Migrate.pm @@ -9,6 +9,7 @@ package Bugzilla::Migrate; use 5.10.1; use strict; +use warnings; use Bugzilla::Attachment; use Bugzilla::Bug qw(LogActivityEntry); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Migrate/Gnats.pm b/mozilla/webtools/bugzilla/Bugzilla/Migrate/Gnats.pm index 2778d28cc8a..5feda4b8db3 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Migrate/Gnats.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Migrate/Gnats.pm @@ -9,6 +9,7 @@ package Bugzilla::Migrate::Gnats; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Migrate); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Milestone.pm b/mozilla/webtools/bugzilla/Bugzilla/Milestone.pm index 83438e7c683..cf7e3e35f18 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Milestone.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Milestone.pm @@ -9,6 +9,7 @@ package Bugzilla::Milestone; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Object.pm b/mozilla/webtools/bugzilla/Bugzilla/Object.pm index f2080363299..8f25e2b20c2 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Object.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Object.pm @@ -9,6 +9,7 @@ package Bugzilla::Object; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Hook; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Product.pm b/mozilla/webtools/bugzilla/Bugzilla/Product.pm index 3d4de7430aa..30ebc7c6cd5 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Product.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Product.pm @@ -9,6 +9,7 @@ package Bugzilla::Product; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/RNG.pm b/mozilla/webtools/bugzilla/Bugzilla/RNG.pm index 14b83167222..96e442fa032 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/RNG.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/RNG.pm @@ -9,6 +9,7 @@ package Bugzilla::RNG; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); use Bugzilla::Constants qw(ON_WINDOWS); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Report.pm b/mozilla/webtools/bugzilla/Bugzilla/Report.pm index fe2b826614f..10af2ea9efc 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Report.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Report.pm @@ -9,6 +9,7 @@ package Bugzilla::Report; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Search.pm b/mozilla/webtools/bugzilla/Bugzilla/Search.pm index 036e0a60581..0395d08eefb 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Search.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Search.pm @@ -9,6 +9,7 @@ package Bugzilla::Search; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); @Bugzilla::Search::EXPORT = qw( @@ -264,7 +265,7 @@ use constant OPERATOR_FIELD_OVERRIDE => { }, # General Bug Fields - alias => { _non_changed => \&_nullable }, + alias => { _non_changed => \&_alias_nonchanged }, 'attach_data.thedata' => MULTI_SELECT_OVERRIDE, # We check all attachment fields against this. attachments => MULTI_SELECT_OVERRIDE, @@ -455,6 +456,10 @@ sub COLUMN_JOINS { . ' FROM longdescs GROUP BY bug_id)', join => 'INNER', }, + alias => { + table => 'bugs_aliases', + as => 'map_alias', + }, assigned_to => { from => 'assigned_to', to => 'userid', @@ -585,6 +590,7 @@ sub COLUMNS { # like "bugs.bug_id". my $total_time = "(map_actual_time.total + bugs.remaining_time)"; my %special_sql = ( + alias => $dbh->sql_group_concat('DISTINCT map_alias.alias'), deadline => $dbh->sql_date_format('bugs.deadline', '%Y-%m-%d'), actual_time => 'map_actual_time.total', @@ -755,7 +761,7 @@ sub data { my @orig_fields = $self->_input_columns; my $all_in_bugs_table = 1; foreach my $field (@orig_fields) { - next if $self->COLUMNS->{$field}->{name} =~ /^bugs\.\w+$/; + next if ($self->COLUMNS->{$field}->{name} // $field) =~ /^bugs\.\w+$/; $self->{fields} = ['bug_id']; $all_in_bugs_table = 0; last; @@ -1007,10 +1013,16 @@ sub _sql_select { my ($self) = @_; my @sql_fields; foreach my $column ($self->_display_columns) { - my $alias = $column; - # Aliases cannot contain dots in them. We convert them to underscores. - $alias =~ s/\./_/g; - my $sql = $self->COLUMNS->{$column}->{name} . " AS $alias"; + my $sql = $self->COLUMNS->{$column}->{name} // ''; + if ($sql) { + my $alias = $column; + # Aliases cannot contain dots in them. We convert them to underscores. + $alias =~ tr/./_/; + $sql .= " AS $alias"; + } + else { + $sql = $column; + } push(@sql_fields, $sql); } return @sql_fields; @@ -1387,7 +1399,7 @@ sub _sql_group_by { my @extra_group_by; foreach my $column ($self->_select_columns) { next if $self->_skip_group_by->{$column}; - my $sql = $self->COLUMNS->{$column}->{name}; + my $sql = $self->COLUMNS->{$column}->{name} // $column; push(@extra_group_by, $sql); } @@ -2726,6 +2738,15 @@ sub _product_nonchanged { "products.id", "products", $term); } +sub _alias_nonchanged { + my ($self, $args) = @_; + + $args->{full_field} = "bugs_aliases.alias"; + $self->_do_operator_function($args); + $args->{term} = build_subselect("bugs.bug_id", + "bugs_aliases.bug_id", "bugs_aliases", $args->{term}); +} + sub _classification_nonchanged { my ($self, $args) = @_; my $joins = $args->{joins}; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Search/Clause.pm b/mozilla/webtools/bugzilla/Bugzilla/Search/Clause.pm index 9d3d690a393..1d7872c7857 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Search/Clause.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Search/Clause.pm @@ -9,6 +9,7 @@ package Bugzilla::Search::Clause; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; use Bugzilla::Search::Condition qw(condition); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Search/ClauseGroup.pm b/mozilla/webtools/bugzilla/Bugzilla/Search/ClauseGroup.pm index eb306525c2b..590c737fad0 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Search/ClauseGroup.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Search/ClauseGroup.pm @@ -9,6 +9,7 @@ package Bugzilla::Search::ClauseGroup; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Search::Clause); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Search/Condition.pm b/mozilla/webtools/bugzilla/Bugzilla/Search/Condition.pm index eab4ab79d24..306a63eed3c 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Search/Condition.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Search/Condition.pm @@ -9,6 +9,7 @@ package Bugzilla::Search::Condition; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); our @EXPORT_OK = qw(condition); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Search/Quicksearch.pm b/mozilla/webtools/bugzilla/Bugzilla/Search/Quicksearch.pm index 98e8a648274..830177f8b51 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Search/Quicksearch.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Search/Quicksearch.pm @@ -9,6 +9,7 @@ package Bugzilla::Search::Quicksearch; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; use Bugzilla::Constants; @@ -321,7 +322,7 @@ sub _handle_alias { my $alias = $1; # We use this direct SQL because we want quicksearch to be VERY fast. my $bug_id = Bugzilla->dbh->selectrow_array( - q{SELECT bug_id FROM bugs WHERE alias = ?}, undef, $alias); + q{SELECT bug_id FROM bugs_aliases WHERE alias = ?}, undef, $alias); # If the user cannot see the bug or if we are using a webservice, # do not resolve its alias. if ($bug_id && Bugzilla->user->can_see_bug($bug_id) && !i_am_webservice()) { diff --git a/mozilla/webtools/bugzilla/Bugzilla/Search/Recent.pm b/mozilla/webtools/bugzilla/Bugzilla/Search/Recent.pm index cc1c3c582e8..e774c7fe059 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Search/Recent.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Search/Recent.pm @@ -9,6 +9,7 @@ package Bugzilla::Search::Recent; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Search/Saved.pm b/mozilla/webtools/bugzilla/Bugzilla/Search/Saved.pm index 2e4c4a33617..50a9cdd6721 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Search/Saved.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Search/Saved.pm @@ -9,6 +9,7 @@ package Bugzilla::Search::Saved; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Send/Sendmail.pm b/mozilla/webtools/bugzilla/Bugzilla/Sender/Transport/Sendmail.pm similarity index 64% rename from mozilla/webtools/bugzilla/Bugzilla/Send/Sendmail.pm rename to mozilla/webtools/bugzilla/Bugzilla/Sender/Transport/Sendmail.pm index 9496ff97cf9..49f00777fc1 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Send/Sendmail.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Sender/Transport/Sendmail.pm @@ -5,57 +5,49 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. -package Bugzilla::Send::Sendmail; +package Bugzilla::Sender::Transport::Sendmail; use 5.10.1; use strict; +use warnings; -use parent qw(Email::Send::Sendmail); +use parent qw(Email::Sender::Transport::Sendmail); -use Return::Value; -use Symbol qw(gensym); +use Email::Sender::Failure; -sub send { - my ($class, $message, @args) = @_; - my $mailer = $class->_find_sendmail; +sub send_email { + my ($self, $email, $envelope) = @_; - return failure "Couldn't find 'sendmail' executable in your PATH" - ." and Email::Send::Sendmail::SENDMAIL is not set" - unless $mailer; + my $pipe = $self->_sendmail_pipe($envelope); - return failure "Found $mailer but cannot execute it" - unless -x $mailer; - - local $SIG{'CHLD'} = 'DEFAULT'; + my $string = $email->as_string; + $string =~ s/\x0D\x0A/\x0A/g unless $^O eq 'MSWin32'; - my $pipe = gensym; + print $pipe $string + or Email::Sender::Failure->throw("couldn't send message to sendmail: $!"); - open($pipe, "| $mailer -t -oi @args") - || return failure "Error executing $mailer: $!"; - print($pipe $message->as_string) - || return failure "Error printing via pipe to $mailer: $!"; unless (close $pipe) { - return failure "error when closing pipe to $mailer: $!" if $!; + Email::Sender::Failure->throw("error when closing pipe to sendmail: $!") if $!; my ($error_message, $is_transient) = _map_exitcode($? >> 8); if (Bugzilla->params->{'use_mailer_queue'}) { # Return success for errors which are fatal so Bugzilla knows to - # remove them from the queue + # remove them from the queue. if ($is_transient) { - return failure "error when closing pipe to $mailer: $error_message"; + Email::Sender::Failure->throw("error when closing pipe to sendmail: $error_message"); } else { - warn "error when closing pipe to $mailer: $error_message\n"; - return success; + warn "error when closing pipe to sendmail: $error_message\n"; + return $self->success; } } else { - return failure "error when closing pipe to $mailer: $error_message"; + Email::Sender::Failure->throw("error when closing pipe to sendmail: $error_message"); } } - return success; + return $self->success; } sub _map_exitcode { # Returns (error message, is_transient) - # from the sendmail source (sendmail/sysexit.h) + # from the sendmail source (sendmail/sysexits.h) my $code = shift; if ($code == 64) { return ("Command line usage error (EX_USAGE)", 1); @@ -98,6 +90,6 @@ sub _map_exitcode { =over -=item send +=item send_email =back diff --git a/mozilla/webtools/bugzilla/Bugzilla/Series.pm b/mozilla/webtools/bugzilla/Bugzilla/Series.pm index 6c11f5dbcfd..22202c6f18d 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Series.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Series.pm @@ -16,6 +16,7 @@ package Bugzilla::Series; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; use Bugzilla::Util; diff --git a/mozilla/webtools/bugzilla/Bugzilla/Status.pm b/mozilla/webtools/bugzilla/Bugzilla/Status.pm index 1f8862a36a0..27551021604 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Status.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Status.pm @@ -9,6 +9,7 @@ package Bugzilla::Status; use 5.10.1; use strict; +use warnings; # This subclasses Bugzilla::Field::Choice instead of implementing # ChoiceInterface, because a bug status literally is a special type diff --git a/mozilla/webtools/bugzilla/Bugzilla/Template.pm b/mozilla/webtools/bugzilla/Bugzilla/Template.pm index 8fe50fa4f8b..7ce1be72bc6 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Template.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Template.pm @@ -10,6 +10,7 @@ package Bugzilla::Template; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::WebService::Constants; @@ -147,10 +148,11 @@ sub get_format { # If you want to modify this routine, read the comments carefully sub quoteUrls { - my ($text, $bug, $comment, $user, $bug_link_func) = @_; + my ($text, $bug, $comment, $user, $bug_link_func, $for_markdown) = @_; return $text unless $text; $user ||= Bugzilla->user; $bug_link_func ||= \&get_bug_link; + $for_markdown ||= 0; # We use /g for speed, but uris can have other things inside them # (http://foo/bug#3 for example). Filtering that out filters valid @@ -221,10 +223,11 @@ sub quoteUrls { $text = html_quote($text); - # Color quoted text - $text =~ s~^(>.+)$~$1~mg; - $text =~ s~\n~\n~g; - + unless ($for_markdown) { + # Color quoted text + $text =~ s~^(>.+)$~$1~mg; + $text =~ s~\n~\n~g; + } # mailto: # Use | so that $1 is defined regardless # @ is the encoded '@' character. @@ -262,28 +265,23 @@ sub quoteUrls { my $bugs_re = qr/\Q$bugs_word\E$s*\#?$s* \d+(?:$s*,$s*\#?$s*\d+)+/ix; - while ($text =~ m/($bugs_re)/g) { - my $offset = $-[0]; - my $length = $+[0] - $-[0]; - my $match = $1; + $text =~ s{($bugs_re)}{ + my $match = $1; $match =~ s/((?:#$s*)?(\d+))/$bug_link_func->($2, $1);/eg; - # Replace the old string with the linkified one. - substr($text, $offset, $length) = $match; - } + $match; + }eg; my $comments_word = template_var('terms')->{comments}; my $comments_re = qr/(?:comments|\Q$comments_word\E)$s*\#?$s* \d+(?:$s*,$s*\#?$s*\d+)+/ix; - while ($text =~ m/($comments_re)/g) { - my $offset = $-[0]; - my $length = $+[0] - $-[0]; - my $match = $1; + $text =~ s{($comments_re)}{ + my $match = $1; $match =~ s|((?:#$s*)?(\d+))|$1|g; - substr($text, $offset, $length) = $match; - } + $match; + }eg; # Old duplicate markers. These don't use $bug_word because they are old # and were never customizable. @@ -534,7 +532,7 @@ sub _concatenate_css { write_file($file, $content); } - $file =~ s/^\Q$cgi_path\E\///; + $file =~ s/^\Q$cgi_path\E\///o; return mtime_filter($file); } @@ -547,6 +545,55 @@ sub _css_url_rewrite { return 'url(../../' . dirname($source) . '/' . $url . ')'; } +sub _concatenate_js { + return @_ unless CONCATENATE_ASSETS; + my ($sources) = @_; + return [] unless $sources; + $sources = ref($sources) ? $sources : [ $sources ]; + + my %files = + map { + (my $file = $_) =~ s/(^[^\?]+)\?.+/$1/; + $_ => $file; + } @$sources; + + my $cgi_path = bz_locations()->{cgi_path}; + my $skins_path = bz_locations()->{assetsdir}; + + # build minified files + my @minified; + foreach my $source (@$sources) { + next unless -e "$cgi_path/$files{$source}"; + my $file = $skins_path . '/' . md5_hex($source) . '.js'; + if (!-e $file) { + my $content = read_file("$cgi_path/$files{$source}"); + + # minimal minification + $content =~ s#/\*.*?\*/##sg; # block comments + $content =~ s#(^ +| +$)##gm; # leading/trailing spaces + $content =~ s#^//.+$##gm; # single line comments + $content =~ s#\n{2,}#\n#g; # blank lines + $content =~ s#(^\s+|\s+$)##g; # whitespace at the start/end of file + + write_file($file, ";/* $files{$source} */\n" . $content . "\n"); + } + push @minified, $file; + } + + # concat files + my $file = $skins_path . '/' . md5_hex(join(' ', @$sources)) . '.js'; + if (!-e $file) { + my $content = ''; + foreach my $source (@minified) { + $content .= read_file($source); + } + write_file($file, $content); + } + + $file =~ s/^\Q$cgi_path\E\///o; + return [ $file ]; +} + # YUI dependency resolution sub yui_resolve_deps { my ($yui, $yui_deps) = @_; @@ -611,6 +658,21 @@ $Template::Stash::LIST_OPS->{ clone } = return [@$list]; }; +# Allow us to sort the list of fields correctly +$Template::Stash::LIST_OPS->{ sort_by_field_name } = + sub { + sub field_name { + if ($_[0] eq 'noop') { + # Sort --- first + return ''; + } + # Otherwise sort by field_desc or description + return $_[1]{$_[0]} || $_[0]; + } + my ($list, $field_desc) = @_; + return [ sort { lc field_name($a, $field_desc) cmp lc field_name($b, $field_desc) } @$list ]; + }; + # Allow us to still get the scalar if we use the list operation ".0" on it, # as we often do for defaults in query.cgi and other places. $Template::Stash::SCALAR_OPS->{ 0 } = @@ -796,6 +858,24 @@ sub create { 1 ], + markdown => [ sub { + my ($context, $bug, $comment, $user) = @_; + return sub { + my $text = shift; + return unless $text; + + if (Bugzilla->feature('markdown') + && ((ref($comment) eq 'HASH' && $comment->{is_markdown}) + || (ref($comment) eq 'Bugzilla::Comment' && $comment->is_markdown))) + { + return Bugzilla->markdown->markdown($text); + } + return quoteUrls($text, $bug, $comment, $user); + }; + }, + 1 + ], + bug_link => [ sub { my ($context, $bug, $options) = @_; return sub { @@ -812,10 +892,12 @@ sub create { }, # In CSV, quotes are doubled, and any value containing a quote or a - # comma is enclosed in quotes. + # comma is enclosed in quotes. If a field starts with an equals + # sign, it is proceed by a space. csv => sub { my ($var) = @_; + $var = ' ' . $var if substr($var, 0, 1) eq '='; $var =~ s/\"/\"\"/g; if ($var !~ /^-?(\d+\.)?\d*$/) { $var = "\"$var\""; @@ -1001,6 +1083,12 @@ sub create { return $cookie ? issue_hash_token(['login_request', $cookie]) : ''; }, + 'get_api_token' => sub { + return '' unless Bugzilla->user->id; + my $cache = Bugzilla->request_cache; + return $cache->{api_token} //= issue_api_token(); + }, + # A way for all templates to get at Field data, cached. 'bug_fields' => sub { my $cache = Bugzilla->request_cache; @@ -1019,6 +1107,7 @@ sub create { 'css_files' => \&css_files, yui_resolve_deps => \&yui_resolve_deps, + concatenate_js => \&_concatenate_js, # All classifications (sorted by sortkey, name) 'all_classifications' => sub { diff --git a/mozilla/webtools/bugzilla/Bugzilla/Template/Context.pm b/mozilla/webtools/bugzilla/Bugzilla/Template/Context.pm index 1e75d1d6f1a..470e6a9ee1f 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Template/Context.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Template/Context.pm @@ -10,6 +10,7 @@ package Bugzilla::Template::Context; use 5.10.1; use strict; +use warnings; use parent qw(Template::Context); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Template/Plugin/Bugzilla.pm b/mozilla/webtools/bugzilla/Bugzilla/Template/Plugin/Bugzilla.pm index f0de2ed4d18..806dd903b68 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Template/Plugin/Bugzilla.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Template/Plugin/Bugzilla.pm @@ -9,6 +9,7 @@ package Bugzilla::Template::Plugin::Bugzilla; use 5.10.1; use strict; +use warnings; use parent qw(Template::Plugin); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Template/Plugin/Hook.pm b/mozilla/webtools/bugzilla/Bugzilla/Template/Plugin/Hook.pm index 19260f0057f..669c77614ce 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Template/Plugin/Hook.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Template/Plugin/Hook.pm @@ -9,6 +9,7 @@ package Bugzilla::Template::Plugin::Hook; use 5.10.1; use strict; +use warnings; use parent qw(Template::Plugin); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Token.pm b/mozilla/webtools/bugzilla/Bugzilla/Token.pm index 5352638682b..24ffad3c34a 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Token.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Token.pm @@ -9,6 +9,7 @@ package Bugzilla::Token; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; use Bugzilla::Error; @@ -23,13 +24,28 @@ use Digest::SHA qw(hmac_sha256_base64); use parent qw(Exporter); -@Bugzilla::Token::EXPORT = qw(issue_session_token check_token_data delete_token +@Bugzilla::Token::EXPORT = qw(issue_api_token issue_session_token + check_token_data delete_token issue_hash_token check_hash_token); ################################################################################ # Public Functions ################################################################################ +# Create a token used for internal API authentication +sub issue_api_token { + # Generates a random token, adds it to the tokens table if one does not + # already exist, and returns the token to the caller. + my $dbh = Bugzilla->dbh; + my $user = Bugzilla->user; + my ($token) = $dbh->selectrow_array(" + SELECT token FROM tokens + WHERE userid = ? AND tokentype = 'api_token' + AND (" . $dbh->sql_date_math('issuedate', '+', (MAX_TOKEN_AGE * 24 - 12), 'HOUR') . ") > NOW()", + undef, $user->id); + return $token // _create_token($user->id, 'api_token', ''); +} + # Creates and sends a token to create a new user account. # It assumes that the login has the correct format and is not already in use. sub issue_new_user_account_token { @@ -466,6 +482,14 @@ Bugzilla::Token - Provides different routines to manage tokens. =over +=item C + + Description: Creates a token that can be used for API calls on the web page. + + Params: None. + + Returns: The token. + =item C Description: Creates and sends a token per email to the email address diff --git a/mozilla/webtools/bugzilla/Bugzilla/Update.pm b/mozilla/webtools/bugzilla/Bugzilla/Update.pm index 6a101219956..72a7108a8e3 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Update.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Update.pm @@ -9,6 +9,7 @@ package Bugzilla::Update; use 5.10.1; use strict; +use warnings; use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/Bugzilla/User.pm b/mozilla/webtools/bugzilla/Bugzilla/User.pm index 3efe02633f9..fa267436618 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/User.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/User.pm @@ -9,6 +9,7 @@ package Bugzilla::User; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; use Bugzilla::Util; @@ -31,7 +32,7 @@ use URI::QueryParam; use parent qw(Bugzilla::Object Exporter); @Bugzilla::User::EXPORT = qw(is_available_username - login_to_id validate_password + login_to_id validate_password validate_password_check USER_MATCH_MULTIPLE USER_MATCH_FAILED USER_MATCH_SUCCESS MATCH_SKIP_CONFIRM ); @@ -631,6 +632,14 @@ sub is_bug_ignored { return (grep {$_->{'id'} == $bug_id} @{$self->bugs_ignored}) ? 1 : 0; } +sub use_markdown { + my ($self, $comment) = @_; + return Bugzilla->feature('markdown') + && $self->settings->{use_markdown}->{is_enabled} + && $self->settings->{use_markdown}->{value} eq 'on' + && (!defined $comment || $comment->is_markdown); +} + ########################## # Saved Recent Bug Lists # ########################## @@ -2448,29 +2457,35 @@ sub login_to_id { } sub validate_password { + my $check = validate_password_check(@_); + ThrowUserError($check) if $check; + return 1; +} + +sub validate_password_check { my ($password, $matchpassword) = @_; if (length($password) < USER_PASSWORD_MIN_LENGTH) { - ThrowUserError('password_too_short'); + return 'password_too_short'; } elsif ((defined $matchpassword) && ($password ne $matchpassword)) { - ThrowUserError('passwords_dont_match'); + return 'passwords_dont_match'; } - + my $complexity_level = Bugzilla->params->{password_complexity}; if ($complexity_level eq 'letters_numbers_specialchars') { - ThrowUserError('password_not_complex') + return 'password_not_complex' if ($password !~ /[[:alpha:]]/ || $password !~ /\d/ || $password !~ /[[:punct:]]/); } elsif ($complexity_level eq 'letters_numbers') { - ThrowUserError('password_not_complex') + return 'password_not_complex' if ($password !~ /[[:lower:]]/ || $password !~ /[[:upper:]]/ || $password !~ /\d/); } elsif ($complexity_level eq 'mixed_letters') { - ThrowUserError('password_not_complex') + return 'password_not_complex' if ($password !~ /[[:lower:]]/ || $password !~ /[[:upper:]]/); } # Having done these checks makes us consider the password untainted. trick_taint($_[0]); - return 1; + return; } @@ -2616,6 +2631,12 @@ C The current summary of the bug. Returns true if the user does not want email notifications for the specified bug ID, else returns false. +=item C + +Returns true if the user has set their preferences to use Markdown +for rendering comments. If an optional C object is passed +then it returns true if the comment has markdown enabled. + =back =head2 Saved Recent Bug Lists @@ -3141,12 +3162,23 @@ if you need more information about the user than just their ID. =item C Returns true if a password is valid (i.e. meets Bugzilla's -requirements for length and content), else returns false. +requirements for length and content), else throws an error. Untaints C<$passwd1> if successful. If a second password is passed in, this function also verifies that the two passwords match. +=item C + +This sub routine is similair to C, except that it allows +the calling code to handle its own errors. + +Returns undef and untaints C<$passwd1> if a password is valid (i.e. meets +Bugzilla's requirements for length and content), else returns the error. + +If a second password is passed in, this function also verifies that +the two passwords match. + =item C =over diff --git a/mozilla/webtools/bugzilla/Bugzilla/User/APIKey.pm b/mozilla/webtools/bugzilla/Bugzilla/User/APIKey.pm new file mode 100644 index 00000000000..d268a0a93c4 --- /dev/null +++ b/mozilla/webtools/bugzilla/Bugzilla/User/APIKey.pm @@ -0,0 +1,155 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::User::APIKey; + +use 5.10.1; +use strict; +use warnings; + +use parent qw(Bugzilla::Object); + +use Bugzilla::User; +use Bugzilla::Util qw(generate_random_password trim); + +##################################################################### +# Overriden Constants that are used as methods +##################################################################### + +use constant DB_TABLE => 'user_api_keys'; +use constant DB_COLUMNS => qw( + id + user_id + api_key + description + revoked + last_used +); + +use constant UPDATE_COLUMNS => qw(description revoked last_used); +use constant VALIDATORS => { + api_key => \&_check_api_key, + description => \&_check_description, + revoked => \&Bugzilla::Object::check_boolean, +}; +use constant LIST_ORDER => 'id'; +use constant NAME_FIELD => 'api_key'; + +# turn off auditing and exclude these objects from memcached +use constant { AUDIT_CREATES => 0, + AUDIT_UPDATES => 0, + AUDIT_REMOVES => 0, + USE_MEMCACHED => 0 }; + +# Accessors +sub id { return $_[0]->{id} } +sub user_id { return $_[0]->{user_id} } +sub api_key { return $_[0]->{api_key} } +sub description { return $_[0]->{description} } +sub revoked { return $_[0]->{revoked} } +sub last_used { return $_[0]->{last_used} } + +# Helpers +sub user { + my $self = shift; + $self->{user} //= Bugzilla::User->new({name => $self->user_id, cache => 1}); + return $self->{user}; +} + +sub update_last_used { + my $self = shift; + my $timestamp = shift + || Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); + $self->set('last_used', $timestamp); + $self->update; +} + +# Setters +sub set_description { $_[0]->set('description', $_[1]); } +sub set_revoked { $_[0]->set('revoked', $_[1]); } + +# Validators +sub _check_api_key { return generate_random_password(40); } +sub _check_description { return trim($_[1]) || ''; } +1; + +__END__ + +=head1 NAME + +Bugzilla::User::APIKey - Model for an api key belonging to a user. + +=head1 SYNOPSIS + + use Bugzilla::User::APIKey; + + my $api_key = Bugzilla::User::APIKey->new($id); + my $api_key = Bugzilla::User::APIKey->new({ name => $api_key }); + + # Class Functions + $user_api_key = Bugzilla::User::APIKey->create({ + description => $description, + }); + +=head1 DESCRIPTION + +This package handles Bugzilla User::APIKey. + +C is an implementation of L, and +thus provides all the methods of L in addition to the methods +listed below. + +=head1 METHODS + +=head2 Accessor Methods + +=over + +=item C + +The internal id of the api key. + +=item C + +The Bugzilla::User object that this api key belongs to. + +=item C + +The user id that this api key belongs to. + +=item C + +The API key, which is a random string. + +=item C + +An optional string that lets the user describe what a key is used for. +For example: "Dashboard key", "Application X key". + +=item C + +If true, this api key cannot be used. + +=item C + +The date that this key was last used. undef if never used. + +=item C + +Updates the last used value to the current timestamp. This is updated even +if the RPC call resulted in an error. It is not updated when the description +or the revoked flag is changed. + +=item C + +Sets the new description + +=item C + +Sets the revoked flag + +=back diff --git a/mozilla/webtools/bugzilla/Bugzilla/User/Setting.pm b/mozilla/webtools/bugzilla/Bugzilla/User/Setting.pm index 451e946f774..ea3bbfb5423 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/User/Setting.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/User/Setting.pm @@ -10,13 +10,18 @@ package Bugzilla::User::Setting; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); # Module stuff -@Bugzilla::User::Setting::EXPORT = qw(get_all_settings get_defaults - add_setting); +@Bugzilla::User::Setting::EXPORT = qw( + get_all_settings + get_defaults + add_setting + clear_settings_cache +); use Bugzilla::Error; use Bugzilla::Util qw(trick_taint get_text); @@ -159,15 +164,20 @@ sub get_all_settings { my $settings = {}; my $dbh = Bugzilla->dbh; - my $rows = $dbh->selectall_arrayref( - q{SELECT name, default_value, is_enabled, setting_value, subclass - FROM setting - LEFT JOIN profile_setting - ON setting.name = profile_setting.setting_name - AND profile_setting.user_id = ?}, undef, ($user_id)); + my $cache_key = "user_settings.$user_id"; + my $rows = Bugzilla->memcached->get_config({ key => $cache_key }); + if (!$rows) { + $rows = $dbh->selectall_arrayref( + q{SELECT name, default_value, is_enabled, setting_value, subclass + FROM setting + LEFT JOIN profile_setting + ON setting.name = profile_setting.setting_name + AND profile_setting.user_id = ?}, undef, ($user_id)); + Bugzilla->memcached->set_config({ key => $cache_key, data => $rows }); + } foreach my $row (@$rows) { - my ($name, $default_value, $is_enabled, $value, $subclass) = @$row; + my ($name, $default_value, $is_enabled, $value, $subclass) = @$row; my $is_default; @@ -179,13 +189,18 @@ sub get_all_settings { } $settings->{$name} = new Bugzilla::User::Setting( - $name, $user_id, $is_enabled, + $name, $user_id, $is_enabled, $default_value, $value, $is_default, $subclass); } return $settings; } +sub clear_settings_cache { + my ($user_id) = @_; + Bugzilla->memcached->clear_config({ key => "user_settings.$user_id" }); +} + sub get_defaults { my ($user_id) = @_; my $dbh = Bugzilla->dbh; @@ -368,6 +383,13 @@ Params: C<$setting_name> - string - the name of the setting C<$is_enabled> - boolean - if false, all users must use the global default Returns: nothing +=item C + +Description: Clears cached settings data for the specified user. Must be + called after updating any user's setting. +Params: C<$user_id> - integer - the user id. +Returns: nothing + =begin private =item C<_setting_exists> diff --git a/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Lang.pm b/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Lang.pm index 4465185e3ff..d980b7a92e0 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Lang.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Lang.pm @@ -9,6 +9,7 @@ package Bugzilla::User::Setting::Lang; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::User::Setting); diff --git a/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Skin.pm b/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Skin.pm index 1e4e95a03e3..7b0688c0c83 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Skin.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Skin.pm @@ -10,6 +10,7 @@ package Bugzilla::User::Setting::Skin; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::User::Setting); diff --git a/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Timezone.pm b/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Timezone.pm index 848fa418f8b..8959d1ddace 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Timezone.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/User/Setting/Timezone.pm @@ -9,6 +9,7 @@ package Bugzilla::User::Setting::Timezone; use 5.10.1; use strict; +use warnings; use DateTime::TimeZone; diff --git a/mozilla/webtools/bugzilla/Bugzilla/UserAgent.pm b/mozilla/webtools/bugzilla/Bugzilla/UserAgent.pm index 4e685cacc75..963e3051139 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/UserAgent.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/UserAgent.pm @@ -9,6 +9,7 @@ package Bugzilla::UserAgent; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); our @EXPORT = qw(detect_platform detect_op_sys); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Util.pm b/mozilla/webtools/bugzilla/Bugzilla/Util.pm index 4f0711b7e0c..670f5f8f28b 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Util.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Util.pm @@ -9,6 +9,7 @@ package Bugzilla::Util; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); @Bugzilla::Util::EXPORT = qw(trick_taint detaint_natural detaint_signed @@ -551,9 +552,14 @@ sub datetime_from { # In the database, this is the "0" date. return undef if $date =~ /^0000/; - # strptime($date) returns an empty array if $date has an invalid - # date format. - my @time = strptime($date); + my @time; + # Most dates will be in this format, avoid strptime's generic parser + if ($date =~ /^(\d{4})[\.-](\d{2})[\.-](\d{2})(?: (\d{2}):(\d{2}):(\d{2}))?$/) { + @time = ($6, $5, $4, $3, $2 - 1, $1 - 1900, undef); + } + else { + @time = strptime($date); + } unless (scalar @time) { # If an unknown timezone is passed (such as MSK, for Moskow), @@ -565,10 +571,14 @@ sub datetime_from { return undef if !@time; - # strptime() counts years from 1900, and months from 0 (January). - # We have to fix both values. + # strptime() counts years from 1900, except if they are older than 1901 + # in which case it returns the full year (so 1890 -> 1890, but 1984 -> 84, + # and 3790 -> 1890). We make a guess and assume that 1100 <= year < 3000. + $time[5] += 1900 if $time[5] < 1100; + my %args = ( - year => $time[5] + 1900, + year => $time[5], + # Months start from 0 (January). month => $time[4] + 1, day => $time[3], hour => $time[2], diff --git a/mozilla/webtools/bugzilla/Bugzilla/Version.pm b/mozilla/webtools/bugzilla/Bugzilla/Version.pm index c6b178a8ab9..4b332ff2bc9 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Version.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Version.pm @@ -9,6 +9,7 @@ package Bugzilla::Version; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object Exporter); diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService.pm index 1dc04c1f6c9..1bdeb49d1f6 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService.pm @@ -11,6 +11,7 @@ package Bugzilla::WebService; use 5.10.1; use strict; +use warnings; use Bugzilla::WebService::Server; @@ -134,14 +135,22 @@ how this is implemented for those frontends. =head1 LOGGING IN -There are various ways to log in: +Some methods do not require you to log in. An example of this is Bug.get. +However, authenticating yourself allows you to see non public information. For +example, a bug that is not publicly visible. + +There are two ways to authenticate yourself: =over -=item C +=item C -You can use L to log in as a Bugzilla -user. This issues a token that you must then use in future calls. +B + +You can specify C as an argument to any WebService method, and +you will be logged in as that user if the key is correct, and has not been +revoked. You can set up an API key by using the 'API Key' tab in the +Preferences pages. =item C and C @@ -164,15 +173,29 @@ then your login will only be valid for your IP address. =back The C option is only used when you have also -specified C and C. +specified C and C. This value will be +deprecated in the release after Bugzilla 5.0 and you will be required to +pass the Bugzilla_login and Bugzilla_password for every call. For REST, you may also use the C and C variable names instead of C and C as a convenience. You may also use C instead of C. +=back + +There are also two deprecreated methods of authentications. This will be +removed in the version after Bugzilla 5.0. + +=over + +=item C + +You can use L to log in as a Bugzilla +user. This issues a token that you must then use in future calls. + =item C -B +B You can specify C as argument to any WebService method, and you will be logged in as that user if the token is correct. This is @@ -292,7 +315,7 @@ hashes. Some RPC calls support specifying sub fields. If an RPC call states that it support sub field restrictions, you can restrict what information is -returned within the first field. For example, if you call Products.get +returned within the first field. For example, if you call Product.get with an include_fields of components.name, then only the component name would be returned (and nothing else). You can include the main field, and exclude a sub field. @@ -367,6 +390,8 @@ objects. =item L +=item L + =item L =item L diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Bug.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Bug.pm index 0346511a943..f50bb6aee36 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Bug.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Bug.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Bug; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::WebService); @@ -330,7 +331,9 @@ sub render_comment { Bugzilla->switch_to_shadow_db(); my $bug = $params->{id} ? Bugzilla::Bug->check($params->{id}) : undef; - my $tmpl = '[% text FILTER quoteUrls(bug) %]'; + my $markdown = $params->{markdown} ? 1 : 0; + my $tmpl = $markdown ? '[% text FILTER markdown(bug, { is_markdown => 1 }) %]' : '[% text FILTER markdown(bug) %]'; + my $html; my $template = Bugzilla->template; $template->process( @@ -349,15 +352,16 @@ sub _translate_comment { : undef; my $comment_hash = { - id => $self->type('int', $comment->id), - bug_id => $self->type('int', $comment->bug_id), - creator => $self->type('email', $comment->author->login), - time => $self->type('dateTime', $comment->creation_ts), + id => $self->type('int', $comment->id), + bug_id => $self->type('int', $comment->bug_id), + creator => $self->type('email', $comment->author->login), + time => $self->type('dateTime', $comment->creation_ts), creation_time => $self->type('dateTime', $comment->creation_ts), - is_private => $self->type('boolean', $comment->is_private), - text => $self->type('string', $comment->body_full), + is_private => $self->type('boolean', $comment->is_private), + is_markdown => $self->type('boolean', $comment->is_markdown), + text => $self->type('string', $comment->body_full), attachment_id => $self->type('int', $attach_id), - count => $self->type('int', $comment->count), + count => $self->type('int', $comment->count), }; # Don't load comment tags unless enabled @@ -467,7 +471,7 @@ sub history { # alias is returned in case users passes a mixture of ids and aliases # then they get to know which bug activity relates to which value # they passed - $item{alias} = $self->type('string', $bug->alias); + $item{alias} = [ map { $self->type('string', $_) } @{ $bug->alias } ]; push(@return, \%item); } @@ -631,6 +635,16 @@ sub update { # called using those field names. delete $values{dependencies}; + # For backwards compatibility, treat alias string or array as a set action + if (exists $values{alias}) { + if (not ref $values{alias}) { + $values{alias} = { set => [ $values{alias} ] }; + } + elsif (ref $values{alias} eq 'ARRAY') { + $values{alias} = { set => $values{alias} }; + } + } + my $flags = delete $values{flags}; foreach my $bug (@bugs) { @@ -668,7 +682,7 @@ sub update { # alias is returned in case users pass a mixture of ids and aliases, # so that they can know which set of changes relates to which value # they passed. - $hash{alias} = $self->type('string', $bug->alias); + $hash{alias} = [ map { $self->type('string', $_) } @{ $bug->alias } ]; my %changes = %{ $all_changes{$bug->id} }; foreach my $field (keys %changes) { @@ -811,10 +825,20 @@ sub add_attachment { $attachment->update($timestamp); my $comment = $params->{comment} || ''; - $attachment->bug->add_comment($comment, - { isprivate => $attachment->isprivate, - type => CMT_ATTACHMENT_CREATED, - extra_data => $attachment->id }); + + my $is_markdown = 0; + if (ref $params->{comment} eq 'HASH') { + $is_markdown = $params->{comment}->{is_markdown}; + $comment = $params->{comment}->{body}; + } + + ThrowUserError('markdown_disabled') if $is_markdown && !_is_markdown_enabled(); + + $attachment->bug->add_comment($comment, + { is_markdown => $is_markdown, + isprivate => $attachment->isprivate, + type => CMT_ATTACHMENT_CREATED, + extra_data => $attachment->id }); push(@created, $attachment); } $_->bug->update($timestamp) foreach @created; @@ -860,6 +884,14 @@ sub update_attachment { my $flags = delete $params->{flags}; my $comment = delete $params->{comment}; + my $is_markdown = 0; + + if (ref $comment eq 'HASH') { + $is_markdown = $comment->{is_markdown}; + $comment = $comment->{body}; + } + + ThrowUserError('markdown_disabled') if $is_markdown && !_is_markdown_enabled(); # Update the values foreach my $attachment (@attachments) { @@ -879,9 +911,10 @@ sub update_attachment { if ($comment = trim($comment)) { $attachment->bug->add_comment($comment, - { isprivate => $attachment->isprivate, - type => CMT_ATTACHMENT_UPDATED, - extra_data => $attachment->id }); + { is_markdown => $is_markdown, + isprivate => $attachment->isprivate, + type => CMT_ATTACHMENT_UPDATED, + extra_data => $attachment->id }); } $changes = translate($changes, ATTACHMENT_MAPPED_RETURNS); @@ -938,9 +971,13 @@ sub add_comment { if (defined $params->{private}) { $params->{is_private} = delete $params->{private}; } + + ThrowUserError('markdown_disabled') if $params->{is_markdown} && !_is_markdown_enabled(); + # Append comment - $bug->add_comment($comment, { isprivate => $params->{is_private}, - work_time => $params->{work_time} }); + $bug->add_comment($comment, { isprivate => $params->{is_private}, + is_markdown => $params->{is_markdown}, + work_time => $params->{work_time} }); # Capture the call to bug->update (which creates the new comment) in # a transaction so we're sure to get the correct comment_id. @@ -1135,7 +1172,11 @@ sub search_comment_tags { my $query = $params->{query}; $query // ThrowCodeError('param_required', { param => 'query' }); - my $limit = detaint_natural($params->{limit}) || 7; + my $limit = $params->{limit} || 7; + detaint_natural($limit) + || ThrowCodeError('param_must_be_numeric', { param => 'limit', + function => 'Bug.search_comment_tags' }); + my $tags = Bugzilla::Comment::TagWeights->match({ WHERE => { @@ -1162,14 +1203,11 @@ sub _bug_to_hash { # A bug attribute is "basic" if it doesn't require an additional # database call to get the info. my %item = %{ filter $params, { - alias => $self->type('string', $bug->alias), - creation_time => $self->type('dateTime', $bug->creation_ts), # No need to format $bug->deadline specially, because Bugzilla::Bug # already does it for us. deadline => $self->type('string', $bug->deadline), id => $self->type('int', $bug->bug_id), is_confirmed => $self->type('boolean', $bug->everconfirmed), - last_change_time => $self->type('dateTime', $bug->delta_ts), op_sys => $self->type('string', $bug->op_sys), platform => $self->type('string', $bug->rep_platform), priority => $self->type('string', $bug->priority), @@ -1183,9 +1221,11 @@ sub _bug_to_hash { whiteboard => $self->type('string', $bug->status_whiteboard), } }; - # First we handle any fields that require extra SQL calls. - # We don't do the SQL calls at all if the filter would just - # eliminate them anyway. + # First we handle any fields that require extra work (such as date parsing + # or SQL calls). + if (filter_wants $params, 'alias') { + $item{alias} = [ map { $self->type('string', $_) } @{ $bug->alias } ]; + } if (filter_wants $params, 'assigned_to') { $item{'assigned_to'} = $self->type('email', $bug->assigned_to->login); $item{'assigned_to_detail'} = $self->_user_to_hash($bug->assigned_to, $params, undef, 'assigned_to'); @@ -1205,6 +1245,9 @@ sub _bug_to_hash { $item{'cc'} = \@cc; $item{'cc_detail'} = [ map { $self->_user_to_hash($_, $params, undef, 'cc') } @{ $bug->cc_users } ]; } + if (filter_wants $params, 'creation_time') { + $item{'creation_time'} = $self->type('dateTime', $bug->creation_ts); + } if (filter_wants $params, 'creator') { $item{'creator'} = $self->type('email', $bug->reporter->login); $item{'creator_detail'} = $self->_user_to_hash($bug->reporter, $params, undef, 'creator'); @@ -1229,6 +1272,9 @@ sub _bug_to_hash { @{ $bug->keyword_objects }; $item{'keywords'} = \@keywords; } + if (filter_wants $params, 'last_change_time') { + $item{'last_change_time'} = $self->type('dateTime', $bug->delta_ts); + } if (filter_wants $params, 'product') { $item{product} = $self->type('string', $bug->product); } @@ -1379,6 +1425,14 @@ sub _add_update_tokens { } } +sub _is_markdown_enabled { + my $user = Bugzilla->user; + + return Bugzilla->feature('markdown') + && $user->settings->{use_markdown}->{is_enabled} + && $user->setting('use_markdown') eq 'on'; +} + 1; __END__ @@ -1482,6 +1536,12 @@ C The number of the fieldtype. The following values are defined: =item C<7> Bug URLs ("See Also") +=item C<8> Keywords + +=item C<9> Date + +=item C<10> Integer value + =back =item C @@ -2050,6 +2110,10 @@ may be deprecated and removed in a future release. C True if this comment is private (only visible to a certain group called the "insidergroup"), False otherwise. +=item is_markdown + +C True if this comment needs Markdown processing, false otherwise. + =back =item B @@ -2167,7 +2231,8 @@ in the return value. =item C -C The unique alias of this bug. +C of Cs The unique aliases of this bug. An empty array will be +returned if this bug has no aliases. =item C @@ -2612,7 +2677,8 @@ C The numeric id of the bug. =item alias -C The alias of this bug. If there is no alias, this will be undef. +C of Cs The unique aliases of this bug. An empty array will be +returned if this bug has no aliases. =item history @@ -2795,7 +2861,8 @@ just reuse the query parameter portion in the REST call itself. =item C -C The unique alias for this bug. +C of Cs The unique aliases of this bug. An empty array will be +returned if this bug has no aliases. =item C @@ -3052,7 +3119,7 @@ in by the developer, compared to the developer's other bugs. =item C (string) B - How severe the bug is. -=item C (string) - A brief alias for the bug that can be used +=item C (array) - A brief alias for the bug that can be used instead of a bug number when accessing this bug. Must be unique in all of this Bugzilla. @@ -3064,6 +3131,9 @@ don't want it to be assigned to the component owner. =item C (boolean) - If set to true, the description is private, otherwise it is assumed to be public. +=item C (boolean) - If set to true, the description +has Markdown structures, otherwise it is a normal text. + =item C (array) - An array of group names to put this bug into. You can see valid group names on the Permissions tab of the Preferences screen, or, if you are an administrator, @@ -3219,6 +3289,8 @@ Bugzilla B<4.4>. =item REST API call added in Bugzilla B<5.0>. +=item C option added in Bugzilla B<5.0>. + =back =back @@ -3278,7 +3350,21 @@ C or C. =item C -C A comment to add along with this attachment. +C or hash. A comment to add along with this attachment. If C +is a hash, it has the following keys: + +=over + +=item C + +C The body of the comment. + +=item C + +C If set to true, the comment has Markdown structures; otherwise, it +is an ordinary text. + +=back =item C @@ -3356,6 +3442,10 @@ the type id value to update or add a flag. The flag type is inactive and cannot be used to create new flags. +=item 140 (Markdown Disabled) + +You tried to set the C flag of the comment to true but the Markdown feature is not enabled. + =item 600 (Attachment Too Large) You tried to attach a file that was larger than Bugzilla will accept. @@ -3391,6 +3481,8 @@ You set the "data" field to an empty string. =item REST API call added in Bugzilla B<5.0>. +=item C added in Bugzilla B<5.0>. + =back =back @@ -3437,7 +3529,21 @@ attachment. =item C -C An optional comment to add to the attachment's bug. +C or hash: An optional comment to add to the attachment's bug. If C is +a hash, it has the following keys: + +=over + +=item C + +C The body of the comment to be added. + +=item C + +C If set to true, the comment has Markdown structures; otherwise it is a normal +text. + +=back =item C @@ -3586,6 +3692,11 @@ the type id value to update or add a flag. The flag type is inactive and cannot be used to create new flags. +=item 140 (Markdown Disabled) + +You tried to set the C flag of the C to true but Markdown feature is +not enabled. + =item 601 (Invalid MIME Type) You specified a C argument that was blank, not a valid @@ -3646,6 +3757,9 @@ you did not set the C parameter. =item C (boolean) - If set to true, the comment is private, otherwise it is assumed to be public. +=item C (boolean) - If set to true, the comment has Markdown +structures, otherwise it is a normal text. + =item C (double) - Adds this many hours to the "Hours Worked" on the bug. If you are not in the time tracking group, this value will be ignored. @@ -3687,6 +3801,11 @@ You tried to add a private comment, but don't have the necessary rights. You tried to add a comment longer than the maximum allowed length (65,535 characters). +=item 140 (Markdown Disabled) + +You tried to set the C flag to true but the Markdown feature +is not enabled. + =back =item B @@ -3709,6 +3828,8 @@ code of 32000. =item REST API call added in Bugzilla B<5.0>. +=item C option added in Bugzilla B<5.0>. + =back =back @@ -3753,9 +3874,29 @@ bugs you are updating. =item C -(string) The alias of the bug. You can only set this if you are modifying -a single bug. If there is more than one bug specified in C, passing in -a value for C will cause an error to be thrown. +C These specify the aliases of a bug that can be used instead of a bug +number when acessing this bug. To set these, you should pass a hash as the +value. The hash may contain the following fields: + +=over + +=item C An array of Cs. Aliases to add to this field. + +=item C An array of Cs. Aliases to remove from this field. +If the aliases are not already in the field, they will be ignored. + +=item C An array of Cs. An exact set of aliases to set this +field to, overriding the current value. If you specify C, then C +and C will be ignored. + +=back + +You can only set this if you are modifying a single bug. If there is more +than one bug specified in C, passing in a value for C will cause +an error to be thrown. + +For backwards compatibility, you can also specify a single string. This will +be treated as if you specified the set key above. =item C @@ -4074,7 +4215,8 @@ C The id of the bug that was updated. =item C -C The alias of the bug that was updated, if this bug has an alias. +C of Cs The aliases of the bug that was updated, if this bug +has any alias. =item C @@ -4108,7 +4250,7 @@ Here's an example of what a return value might look like: bugs => [ { id => 123, - alias => 'foo', + alias => [ 'foo' ], last_change_time => '2010-01-01T12:34:56', changes => { status => { diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/BugUserLastVisit.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/BugUserLastVisit.pm index 71b637fef65..a29d2633b83 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/BugUserLastVisit.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/BugUserLastVisit.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::BugUserLastVisit; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::WebService); @@ -68,10 +69,10 @@ sub get { $user->visible_bugs([grep /^[0-9]$/, @$ids]); } - my @last_visits = @{ $user->last_visits }; + my @last_visits = @{ $user->last_visited }; if ($ids) { - # remove bugs that we arn't interested in if ids is passed in. + # remove bugs that we are not interested in if ids is passed in. my %id_set = map { ($_ => 1) } @$ids; @last_visits = grep { $id_set{ $_->bug_id } } @last_visits; } @@ -166,20 +167,13 @@ B =item B -Get the last visited timestamp for one or more specified bug ids or get a -list of the last 20 visited bugs and their timestamps. +Get the last visited timestamp for one or more specified bug ids. =item B To return the last visited timestamp for a single bug id: -GET /rest/bug_visit/ - -To return more than one bug timestamp or the last 20: - -GET /rest/bug_visit - -The returned data format is the same as below. + GET /rest/bug_user_last_visit/ =item B diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Bugzilla.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Bugzilla.pm index 6b5f9844ffc..8333f99c480 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Bugzilla.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Bugzilla.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Bugzilla; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::WebService); use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Classification.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Classification.pm index bbc967ce7ac..8e1b3ae8a6e 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Classification.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Classification.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Classification; use 5.10.1; use strict; +use warnings; use parent qw (Bugzilla::WebService); diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Component.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Component.pm new file mode 100644 index 00000000000..893e244b892 --- /dev/null +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Component.pm @@ -0,0 +1,149 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::WebService::Component; + +use 5.10.1; +use strict; +use warnings; + +use base qw(Bugzilla::WebService); + +use Bugzilla::Component; +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::WebService::Constants; +use Bugzilla::WebService::Util qw(translate params_to_objects validate); + +use constant MAPPED_FIELDS => { + default_assignee => 'initialowner', + default_qa_contact => 'initialqacontact', + default_cc => 'initial_cc', + is_open => 'isactive', +}; + +sub create { + my ($self, $params) = @_; + + my $user = Bugzilla->login(LOGIN_REQUIRED); + + $user->in_group('editcomponents') + || scalar @{ $user->get_products_by_permission('editcomponents') } + || ThrowUserError('auth_failure', { group => 'editcomponents', + action => 'edit', + object => 'components' }); + + my $product = $user->check_can_admin_product($params->{product}); + + # Translate the fields + my $values = translate($params, MAPPED_FIELDS); + $values->{product} = $product; + + # Create the component and return the newly created id. + my $component = Bugzilla::Component->create($values); + return { id => $self->type('int', $component->id) }; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Webservice::Component - The Component API + +=head1 DESCRIPTION + +This part of the Bugzilla API allows you to deal with the available product components. +You will be able to get information about them as well as manipulate them. + +=head1 METHODS + +See L for a description of how parameters are passed, +and what B, B, and B mean. + +=head1 Component Creation and Modification + +=head2 create + +B + +=over + +=item B + +This allows you to create a new component in Bugzilla. + +=item B + +Some params must be set, or an error will be thrown. These params are +marked B. + +=over + +=item C + +B C The name of the new component. + +=item C + +B C The name of the product that the component must be +added to. This product must already exist, and the user have the necessary +permissions to edit components for it. + +=item C + +B C The description of the new component. + +=item C + +B C The login name of the default assignee of the component. + +=item C + +C An array of strings with each element representing one login name of the default CC list. + +=item C + +C The login name of the default QA contact for the component. + +=item C + +C 1 if you want to enable the component for bug creations. 0 otherwise. Default is 1. + +=back + +=item B + +A hash with one key: C. This will represent the ID of the newly-added +component. + +=item B + +=over + +=item 304 (Authorization Failure) + +You are not authorized to create a new component. + +=item 1200 (Component already exists) + +The name that you specified for the new component already exists in the +specified product. + +=back + +=item B + +=over + +=item Added in Bugzilla B<5.0>. + +=back + +=back + diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Constants.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Constants.pm index 2c21de15e8e..db50611cbf6 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Constants.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Constants.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Constants; use 5.10.1; use strict; +use warnings; use parent qw(Exporter); @@ -100,6 +101,7 @@ use constant WS_ERROR_CODE => { comment_id_invalid => 111, comment_too_long => 114, comment_invalid_isprivate => 117, + markdown_disabled => 140, # Comment tagging comment_tag_disabled => 125, comment_tag_invalid => 126, @@ -141,7 +143,11 @@ use constant WS_ERROR_CODE => { auth_invalid_email => 302, extern_id_conflict => -303, auth_failure => 304, - password_current_too_short => 305, + password_too_short => 305, + password_not_complex => 305, + api_key_not_valid => 306, + api_key_revoked => 306, + auth_invalid_token => 307, # Except, historically, AUTH_NODATA, which is 410. login_required => 410, @@ -200,6 +206,11 @@ use constant WS_ERROR_CODE => { flag_type_sortkey_invalid => 1104, flag_type_not_editable => 1105, + # Component errors are 1200-1300 + component_already_exists => 1200, + component_is_last => 1201, + component_has_bugs => 1202, + # Errors thrown by the WebService itself. The ones that are negative # conform to http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php xmlrpc_invalid_value => -32600, @@ -279,6 +290,7 @@ sub WS_DISPATCH { 'Bugzilla' => 'Bugzilla::WebService::Bugzilla', 'Bug' => 'Bugzilla::WebService::Bug', 'Classification' => 'Bugzilla::WebService::Classification', + 'Component' => 'Bugzilla::WebService::Component', 'FlagType' => 'Bugzilla::WebService::FlagType', 'Group' => 'Bugzilla::WebService::Group', 'Product' => 'Bugzilla::WebService::Product', diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/FlagType.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/FlagType.pm index b6b8aba8938..cf654e6592d 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/FlagType.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/FlagType.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::FlagType; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::WebService); use Bugzilla::Component; diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Group.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Group.pm index d24d0539b0b..d0ee6fdbad9 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Group.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Group.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Group; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::WebService); use Bugzilla::Constants; @@ -101,8 +102,8 @@ sub get { # Reject access if there is no sense in continuing. my $user = Bugzilla->user; - my $all_groups = $user->in_group('edituser') || $user->in_group('creategroups'); - if (!$all_groups && ! scalar(@{$user->bless_groups})) { + my $all_groups = $user->in_group('editusers') || $user->in_group('creategroups'); + if (!$all_groups && !$user->can_bless) { ThrowUserError('group_cannot_view'); } diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Product.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Product.pm index 2def7788633..0e78836bf1a 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Product.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Product.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Product; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::WebService); use Bugzilla::Product; diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server.pm index 89cb1a130ac..7950c7a3b92 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server; use 5.10.1; use strict; +use warnings; use Bugzilla::Error; use Bugzilla::Util qw(datetime_from); diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/JSONRPC.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/JSONRPC.pm index 5290caa5d08..6cda4748055 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/JSONRPC.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/JSONRPC.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::JSONRPC; use 5.10.1; use strict; +use warnings; use Bugzilla::WebService::Server; BEGIN { @@ -80,7 +81,9 @@ sub response { # Implement JSONP. if (my $callback = $self->_bz_callback) { my $content = $response->content; - $response->content("$callback($content)"); + # Prepend the JSONP response with /**/ in order to protect + # against possible encoding attacks (e.g., affecting Flash). + $response->content("/**/$callback($content)"); } # Use $cgi->header properly instead of just printing text directly. diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST.pm index 2f1b80c45d5..83a796daf08 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::REST; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::WebService::Server::JSONRPC); @@ -23,6 +24,7 @@ use Bugzilla::WebService::Util qw(taint_data fix_credentials); use Bugzilla::WebService::Server::REST::Resources::Bug; use Bugzilla::WebService::Server::REST::Resources::Bugzilla; use Bugzilla::WebService::Server::REST::Resources::Classification; +use Bugzilla::WebService::Server::REST::Resources::Component; use Bugzilla::WebService::Server::REST::Resources::FlagType; use Bugzilla::WebService::Server::REST::Resources::Group; use Bugzilla::WebService::Server::REST::Resources::Product; @@ -335,11 +337,28 @@ sub _retrieve_json_params { my $params = {}; %{$params} = %{ Bugzilla->input_params }; - # First add any params we were able to pull out of the path - # based on the resource regexp - %{$params} = (%{$params}, %{$self->bz_rest_params}) if $self->bz_rest_params; + # First add any parameters we were able to pull out of the path + # based on the resource regexp and combine with the normal URL + # parameters. + if (my $rest_params = $self->bz_rest_params) { + foreach my $param (keys %$rest_params) { + if (!exists $params->{$param}) { + $params->{$param} = $rest_params->{$param}; + next; + } + my @values = ref $rest_params->{$param} + ? @{ $rest_params->{$param} } + : ($rest_params->{$param}); + if (ref $params->{$param}) { + push(@{ $params->{$param} }, @values); + } + else { + $params->{$param} = [ $params->{$param}, @values ]; + } + } + } - # Merge any additional query key/values with $obj->{params} if not a GET request + # Merge any additional query key/values from the request body if non-GET. # We do this manually cause CGI.pm doesn't understand JSON strings. if ($self->request->method ne 'GET') { my $extra_params = {}; @@ -350,14 +369,6 @@ sub _retrieve_json_params { ThrowUserError('json_rpc_invalid_params', { err_msg => $@ }); } } - - # Allow parameters in the query string if request was not GET. - # Note: query string parameters will override any matching params - # also specified in the request body. - foreach my $param ($self->cgi->url_param()) { - $extra_params->{$param} = $self->cgi->url_param($param); - } - %{$params} = (%{$params}, %{$extra_params}) if %{$extra_params}; } diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Bug.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Bug.pm index 7ab111d86ce..3fa8b65cf5d 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Bug.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Bug.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::REST::Resources::Bug; use 5.10.1; use strict; +use warnings; use Bugzilla::WebService::Constants; use Bugzilla::WebService::Bug; @@ -28,6 +29,11 @@ sub _rest_resources { status_code => STATUS_CREATED } }, + qr{^/bug/$}, { + GET => { + method => 'get' + } + }, qr{^/bug/([^/]+)$}, { GET => { method => 'get', diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Bugzilla.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Bugzilla.pm index 1c86f77bce3..a8f3f9330ed 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Bugzilla.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Bugzilla.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::REST::Resources::Bugzilla; use 5.10.1; use strict; +use warnings; use Bugzilla::WebService::Constants; use Bugzilla::WebService::Bugzilla; diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Classification.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Classification.pm index 2bbc05c72c8..3f8d32a0361 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Classification.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Classification.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::REST::Resources::Classification; use 5.10.1; use strict; +use warnings; use Bugzilla::WebService::Constants; use Bugzilla::WebService::Classification; diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Component.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Component.pm new file mode 100644 index 00000000000..198c0933294 --- /dev/null +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Component.pm @@ -0,0 +1,48 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::WebService::Server::REST::Resources::Component; + +use 5.10.1; +use strict; +use warnings; + +use Bugzilla::WebService::Constants; +use Bugzilla::WebService::Component; + +use Bugzilla::Error; + +BEGIN { + *Bugzilla::WebService::Component::rest_resources = \&_rest_resources; +}; + +sub _rest_resources { + my $rest_resources = [ + qr{^/component$}, { + POST => { + method => 'create', + success_code => STATUS_CREATED + } + }, + ]; + return $rest_resources; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Webservice::Server::REST::Resources::Component - The Component REST API + +=head1 DESCRIPTION + +This part of the Bugzilla REST API allows you create Components. + +See L for more details on how to use this +part of the REST API. diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/FlagType.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/FlagType.pm index 1de5b126453..21dad0f73a8 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/FlagType.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/FlagType.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::REST::Resources::FlagType; use 5.10.1; use strict; +use warnings; use Bugzilla::WebService::Constants; use Bugzilla::WebService::FlagType; diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Group.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Group.pm index 62f8af6dd62..b052e384b47 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Group.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Group.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::REST::Resources::Group; use 5.10.1; use strict; +use warnings; use Bugzilla::WebService::Constants; use Bugzilla::WebService::Group; diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Product.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Product.pm index fef7c6174c9..607b94b538a 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Product.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/Product.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::REST::Resources::Product; use 5.10.1; use strict; +use warnings; use Bugzilla::WebService::Constants; use Bugzilla::WebService::Product; diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/User.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/User.pm index 539a9313a52..a83109e7370 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/User.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/REST/Resources/User.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::REST::Resources::User; use 5.10.1; use strict; +use warnings; use Bugzilla::WebService::Constants; use Bugzilla::WebService::User; diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/XMLRPC.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/XMLRPC.pm index 40c66a8f95b..8f9070ae76b 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/XMLRPC.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Server/XMLRPC.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Server::XMLRPC; use 5.10.1; use strict; +use warnings; use XMLRPC::Transport::HTTP; use Bugzilla::WebService::Server; @@ -107,6 +108,7 @@ package Bugzilla::XMLRPC::Deserializer; use 5.10.1; use strict; +use warnings; # We can't use "use parent" because XMLRPC::Serializer doesn't return # a true value. @@ -205,6 +207,7 @@ package Bugzilla::XMLRPC::SOM; use 5.10.1; use strict; +use warnings; use XMLRPC::Lite; our @ISA = qw(XMLRPC::SOM); @@ -231,6 +234,7 @@ package Bugzilla::XMLRPC::Serializer; use 5.10.1; use strict; +use warnings; use Scalar::Util qw(blessed reftype); # We can't use "use parent" because XMLRPC::Serializer doesn't return diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/User.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/User.pm index f05b2b247f8..4c8af7f6c2d 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/User.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/User.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::User; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::WebService); @@ -432,9 +433,13 @@ where applicable. =head1 Logging In and Out +These method are now deprecated, and will be removed in the release after +Bugzilla 5.0. The correct way of use these REST and RPC calls is noted in +L + =head2 login -B +B =over @@ -499,7 +504,9 @@ creates a login cookie. =item C was added in Bugzilla B<5.0>. -=item C was added in Bugzilla B<5.0>. +=item C was added in Bugzilla B<4.4.3>. + +=item This function will be removed in the release after Bugzilla 5.0, in favour of API keys. =back @@ -507,7 +514,7 @@ creates a login cookie. =head2 logout -B +B =over @@ -525,7 +532,7 @@ Log out the user. Does nothing if there is no user logged in. =head2 valid_login -B +B =over @@ -563,6 +570,8 @@ for the provided username. =item Added in Bugzilla B<5.0>. +=item This function will be removed in the release after Bugzilla 5.0, in favour of API keys. + =back =back diff --git a/mozilla/webtools/bugzilla/Bugzilla/WebService/Util.pm b/mozilla/webtools/bugzilla/Bugzilla/WebService/Util.pm index 26558fc6ac0..e2bc780026b 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/WebService/Util.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/WebService/Util.pm @@ -9,6 +9,7 @@ package Bugzilla::WebService::Util; use 5.10.1; use strict; +use warnings; use Bugzilla::Flag; use Bugzilla::FlagType; @@ -268,6 +269,11 @@ sub fix_credentials { $params->{'Bugzilla_login'} = $params->{'login'}; $params->{'Bugzilla_password'} = $params->{'password'}; } + # Allow user to pass api_key=12345678 as a convenience which becomes + # "Bugzilla_api_key" which is what the auth code looks for. + if (exists $params->{api_key}) { + $params->{Bugzilla_api_key} = delete $params->{api_key}; + } # Allow user to pass token=12345678 as a convenience which becomes # "Bugzilla_token" which is what the auth code looks for. if (exists $params->{'token'}) { diff --git a/mozilla/webtools/bugzilla/Bugzilla/Whine.pm b/mozilla/webtools/bugzilla/Bugzilla/Whine.pm index 488127dfa9d..eeaea6da4e0 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Whine.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Whine.pm @@ -9,6 +9,7 @@ package Bugzilla::Whine; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Whine/Query.pm b/mozilla/webtools/bugzilla/Bugzilla/Whine/Query.pm index a4fd54539a5..b2a2c9e0734 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Whine/Query.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Whine/Query.pm @@ -9,6 +9,7 @@ package Bugzilla::Whine::Query; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/Bugzilla/Whine/Schedule.pm b/mozilla/webtools/bugzilla/Bugzilla/Whine/Schedule.pm index f16c629af48..11f0bf16f1f 100644 --- a/mozilla/webtools/bugzilla/Bugzilla/Whine/Schedule.pm +++ b/mozilla/webtools/bugzilla/Bugzilla/Whine/Schedule.pm @@ -9,6 +9,7 @@ package Bugzilla::Whine::Schedule; use 5.10.1; use strict; +use warnings; use parent qw(Bugzilla::Object); diff --git a/mozilla/webtools/bugzilla/admin.cgi b/mozilla/webtools/bugzilla/admin.cgi index 70a6aa20ec8..1dc9b2c1bd3 100755 --- a/mozilla/webtools/bugzilla/admin.cgi +++ b/mozilla/webtools/bugzilla/admin.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/attachment.cgi b/mozilla/webtools/bugzilla/attachment.cgi index 94510fb190f..61e6f58d8df 100755 --- a/mozilla/webtools/bugzilla/attachment.cgi +++ b/mozilla/webtools/bugzilla/attachment.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; @@ -24,6 +26,7 @@ use Bugzilla::Attachment::PatchReader; use Bugzilla::Token; use Encode qw(encode find_encoding); +use Cwd qw(realpath); # For most scripts we don't make $cgi and $template global variables. But # when preparing Bugzilla for mod_perl, this script used these @@ -188,19 +191,6 @@ sub validateFormat { return $format; } -# Validates context of a diff/interdiff. Will throw an error if the context -# is not number, "file" or "patch". Returns the validated, detainted context. -sub validateContext -{ - my $context = $cgi->param('context') || "patch"; - if ($context ne "file" && $context ne "patch") { - detaint_natural($context) - || ThrowUserError("invalid_context", { context => $cgi->param('context') }); - } - - return $context; -} - # Gets the attachment object(s) generated by validateID, while ensuring # attachbase and token authentication is used when required. sub get_attachment { @@ -372,9 +362,24 @@ sub view { } } } + my $sendfile_header = {}; + my $sendfile_param = Bugzilla->params->{'xsendfile_header'}; + if ($attachment->is_on_filesystem && $sendfile_param ne 'off') { + # attachment is on filesystem and Admin turned on feature. + # This means we can let webserver handle the request and stream the file + # for us. This is called the X-Sendfile feature. see bug 1073264. + my $attachment_path = realpath($attachment->_get_local_filename()); + $sendfile_header->{$sendfile_param} = $attachment_path; + } print $cgi->header(-type=>"$contenttype; name=\"$filename\"", -content_disposition=> "$disposition; filename=\"$filename\"", - -content_length => $attachment->datasize); + -content_length => $attachment->datasize, + %$sendfile_header); + if ($attachment->is_on_filesystem && $sendfile_param ne 'off') { + # in case of X-Sendfile, we do not print the data. + # that is handled directly by the webserver. + return; + } disable_utf8(); print $attachment->data; } @@ -389,17 +394,15 @@ sub interdiff { $old_attachment = validateID('oldid'); $new_attachment = validateID('newid'); } - my $context = validateContext(); Bugzilla::Attachment::PatchReader::process_interdiff( - $old_attachment, $new_attachment, $format, $context); + $old_attachment, $new_attachment, $format); } sub diff { # Retrieve and validate parameters my $format = validateFormat('html', 'raw'); my $attachment = $format eq 'raw' ? get_attachment() : validateID(); - my $context = validateContext(); # If it is not a patch, view normally. if (!$attachment->ispatch) { @@ -407,7 +410,7 @@ sub diff { return; } - Bugzilla::Attachment::PatchReader::process_diff($attachment, $format, $context); + Bugzilla::Attachment::PatchReader::process_diff($attachment, $format); } # Display all attachments for a given bug in a series of IFRAMEs within one @@ -513,13 +516,14 @@ sub insert { # Get the filehandle of the attachment. my $data_fh = $cgi->upload('data'); + my $attach_text = $cgi->param('attach_text'); my $attachment = Bugzilla::Attachment->create( {bug => $bug, creation_ts => $timestamp, - data => scalar $cgi->param('attach_text') || $data_fh, + data => $attach_text || $data_fh, description => scalar $cgi->param('description'), - filename => $cgi->param('attach_text') ? "file_$bugid.txt" : scalar $cgi->upload('data'), + filename => $attach_text ? "file_$bugid.txt" : $data_fh, ispatch => scalar $cgi->param('ispatch'), isprivate => scalar $cgi->param('isprivate'), mimetype => $content_type, @@ -536,7 +540,6 @@ sub insert { my ($flags, $new_flags) = Bugzilla::Flag->extract_flags_from_cgi( $bug, $attachment, $vars, SKIP_REQUESTEE_ON_ERROR); $attachment->set_flags($flags, $new_flags); - $attachment->update($timestamp); # Insert a comment about the new attachment into the database. my $comment = $cgi->param('comment'); @@ -545,45 +548,50 @@ sub insert { type => CMT_ATTACHMENT_CREATED, extra_data => $attachment->id }); - # Assign the bug to the user, if they are allowed to take it - my $owner = ""; - if ($cgi->param('takebug') && $user->in_group('editbugs', $bug->product_id)) { - # When taking a bug, we have to follow the workflow. - my $bug_status = $cgi->param('bug_status') || ''; - ($bug_status) = grep {$_->name eq $bug_status} @{$bug->status->can_change_to}; + # Assign the bug to the user, if they are allowed to take it + my $owner = ""; + if ($cgi->param('takebug') && $user->in_group('editbugs', $bug->product_id)) { + # When taking a bug, we have to follow the workflow. + my $bug_status = $cgi->param('bug_status') || ''; + ($bug_status) = grep { $_->name eq $bug_status } + @{ $bug->status->can_change_to }; - if ($bug_status && $bug_status->is_open - && ($bug_status->name ne 'UNCONFIRMED' - || $bug->product_obj->allows_unconfirmed)) - { - $bug->set_bug_status($bug_status->name); - $bug->clear_resolution(); - } - # Make sure the person we are taking the bug from gets mail. - $owner = $bug->assigned_to->login; - $bug->set_assigned_to($user); - } + if ($bug_status && $bug_status->is_open + && ($bug_status->name ne 'UNCONFIRMED' + || $bug->product_obj->allows_unconfirmed)) + { + $bug->set_bug_status($bug_status->name); + $bug->clear_resolution(); + } + # Make sure the person we are taking the bug from gets mail. + $owner = $bug->assigned_to->login; + $bug->set_assigned_to($user); + } - $bug->add_cc($user) if $cgi->param('addselfcc'); - $bug->update($timestamp); + $bug->add_cc($user) if $cgi->param('addselfcc'); + $bug->update($timestamp); - $dbh->bz_commit_transaction; + # We have to update the attachment after updating the bug, to ensure new + # comments are available. + $attachment->update($timestamp); - # Define the variables and functions that will be passed to the UI template. - $vars->{'attachment'} = $attachment; - # We cannot reuse the $bug object as delta_ts has eventually been updated - # since the object was created. - $vars->{'bugs'} = [new Bugzilla::Bug($bugid)]; - $vars->{'header_done'} = 1; - $vars->{'contenttypemethod'} = $cgi->param('contenttypemethod'); + $dbh->bz_commit_transaction; - my $recipients = { 'changer' => $user, 'owner' => $owner }; - $vars->{'sent_bugmail'} = Bugzilla::BugMail::Send($bugid, $recipients); + # Define the variables and functions that will be passed to the UI template. + $vars->{'attachment'} = $attachment; + # We cannot reuse the $bug object as delta_ts has eventually been updated + # since the object was created. + $vars->{'bugs'} = [new Bugzilla::Bug($bugid)]; + $vars->{'header_done'} = 1; + $vars->{'contenttypemethod'} = $cgi->param('contenttypemethod'); - print $cgi->header(); - # Generate and return the UI (HTML page) from the appropriate template. - $template->process("attachment/created.html.tmpl", $vars) - || ThrowTemplateError($template->error()); + my $recipients = { 'changer' => $user, 'owner' => $owner }; + $vars->{'sent_bugmail'} = Bugzilla::BugMail::Send($bugid, $recipients); + + print $cgi->header(); + # Generate and return the UI (HTML page) from the appropriate template. + $template->process("attachment/created.html.tmpl", $vars) + || ThrowTemplateError($template->error()); } # Displays a form for editing attachment properties. @@ -591,25 +599,25 @@ sub insert { # is private and the user does not belong to the insider group. # Validations are done later when the user submits changes. sub edit { - my $attachment = validateID(); + my $attachment = validateID(); - my $bugattachments = - Bugzilla::Attachment->get_attachments_by_bug($attachment->bug); + my $bugattachments = + Bugzilla::Attachment->get_attachments_by_bug($attachment->bug); - my $any_flags_requesteeble = - grep { $_->is_requestable && $_->is_requesteeble } @{$attachment->flag_types}; - # Useful in case a flagtype is no longer requestable but a requestee - # has been set before we turned off that bit. - $any_flags_requesteeble ||= grep { $_->requestee_id } @{$attachment->flags}; - $vars->{'any_flags_requesteeble'} = $any_flags_requesteeble; - $vars->{'attachment'} = $attachment; - $vars->{'attachments'} = $bugattachments; + my $any_flags_requesteeble = grep { $_->is_requestable && $_->is_requesteeble } + @{ $attachment->flag_types }; + # Useful in case a flagtype is no longer requestable but a requestee + # has been set before we turned off that bit. + $any_flags_requesteeble ||= grep { $_->requestee_id } @{ $attachment->flags }; + $vars->{'any_flags_requesteeble'} = $any_flags_requesteeble; + $vars->{'attachment'} = $attachment; + $vars->{'attachments'} = $bugattachments; - print $cgi->header(); + print $cgi->header(); - # Generate and return the UI (HTML page) from the appropriate template. - $template->process("attachment/edit.html.tmpl", $vars) - || ThrowTemplateError($template->error()); + # Generate and return the UI (HTML page) from the appropriate template. + $template->process("attachment/edit.html.tmpl", $vars) + || ThrowTemplateError($template->error()); } # Updates an attachment record. Only users with "editbugs" privileges, @@ -711,6 +719,11 @@ sub update { # Figure out when the changes were made. my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); + # Commit the comment, if any. + # This has to happen before updating the attachment, to ensure new comments + # are available to $attachment->update. + $bug->update($timestamp); + if ($can_edit) { my $changes = $attachment->update($timestamp); # If there are changes, we updated delta_ts in the DB. We have to @@ -718,9 +731,6 @@ sub update { $bug->{delta_ts} = $timestamp if scalar(keys %$changes); } - # Commit the comment, if any. - $bug->update($timestamp); - # Commit the transaction now that we are finished updating the database. $dbh->bz_commit_transaction(); diff --git a/mozilla/webtools/bugzilla/buglist.cgi b/mozilla/webtools/bugzilla/buglist.cgi index d88939171fd..daee34c9bc6 100755 --- a/mozilla/webtools/bugzilla/buglist.cgi +++ b/mozilla/webtools/bugzilla/buglist.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; @@ -279,6 +281,37 @@ sub GetGroups { return [values %legal_groups]; } +sub _get_common_flag_types { + my $component_ids = shift; + my $user = Bugzilla->user; + + # Get all the different components in the bug list + my $components = Bugzilla::Component->new_from_list($component_ids); + my %flag_types; + my @flag_types_ids; + foreach my $component (@$components) { + foreach my $flag_type (@{$component->flag_types->{'bug'}}) { + push @flag_types_ids, $flag_type->id; + $flag_types{$flag_type->id} = $flag_type; + } + } + + # We only want flags that appear in all components + my %common_flag_types; + foreach my $id (keys %flag_types) { + my $flag_type_count = scalar grep { $_ == $id } @flag_types_ids; + $common_flag_types{$id} = $flag_types{$id} + if $flag_type_count == scalar @$components; + } + + # We only show flags that a user can request. + my @show_flag_types + = grep { $user->can_request_flag($_) } values %common_flag_types; + my $any_flags_requesteeble = grep { $_->is_requesteeble } @show_flag_types; + + return(\@show_flag_types, $any_flags_requesteeble); +} + ################################################################################ # Command Execution ################################################################################ @@ -508,7 +541,6 @@ if (grep('relevance', @displaycolumns) && !$fulltext) { @displaycolumns = grep($_ ne 'relevance', @displaycolumns); } - ################################################################################ # Select Column Determination ################################################################################ @@ -549,6 +581,7 @@ foreach my $col (@displaycolumns) { # has for modifying the bugs. if ($dotweak) { push(@selectcolumns, "bug_status") if !grep($_ eq 'bug_status', @selectcolumns); + push(@selectcolumns, "bugs.component_id"); } if ($format->{'extension'} eq 'ics') { @@ -751,9 +784,10 @@ my $time_info = { 'estimated_time' => 0, 'time_present' => ($estimated_time || $remaining_time || $actual_time || $percentage_complete), }; - + my $bugowners = {}; my $bugproducts = {}; +my $bugcomponentids = {}; my $bugcomponents = {}; my $bugstatuses = {}; my @bugidlist; @@ -787,6 +821,7 @@ foreach my $row (@$data) { # Record the assignee, product, and status in the big hashes of those things. $bugowners->{$bug->{'assigned_to'}} = 1 if $bug->{'assigned_to'}; $bugproducts->{$bug->{'product'}} = 1 if $bug->{'product'}; + $bugcomponentids->{$bug->{'bugs.component_id'}} = 1 if $bug->{'bugs.component_id'}; $bugcomponents->{$bug->{'component'}} = 1 if $bug->{'component'}; $bugstatuses->{$bug->{'bug_status'}} = 1 if $bug->{'bug_status'}; @@ -910,7 +945,7 @@ if (scalar(@products) == 1) { # This is used in the "Zarroo Boogs" case. elsif (my @product_input = $cgi->param('product')) { if (scalar(@product_input) == 1 and $product_input[0] ne '') { - $one_product = Bugzilla::Product->new({ name => $cgi->param('product'), cache => 1 }); + $one_product = Bugzilla::Product->new({ name => $product_input[0], cache => 1 }); } } # We only want the template to use it if the user can actually @@ -954,6 +989,9 @@ if ($dotweak && scalar @bugs) { $vars->{'severities'} = get_legal_field_values('bug_severity'); $vars->{'resolutions'} = get_legal_field_values('resolution'); + ($vars->{'flag_types'}, $vars->{any_flags_requesteeble}) + = _get_common_flag_types([keys %$bugcomponentids]); + # Convert bug statuses to their ID. my @bug_statuses = map {$dbh->quote($_)} keys %$bugstatuses; my $bug_status_ids = diff --git a/mozilla/webtools/bugzilla/chart.cgi b/mozilla/webtools/bugzilla/chart.cgi index 015077650f0..96ac9e1cf70 100755 --- a/mozilla/webtools/bugzilla/chart.cgi +++ b/mozilla/webtools/bugzilla/chart.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -29,6 +29,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/checksetup.pl b/mozilla/webtools/bugzilla/checksetup.pl index 145faf04e30..50ca8bda878 100755 --- a/mozilla/webtools/bugzilla/checksetup.pl +++ b/mozilla/webtools/bugzilla/checksetup.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,8 +12,10 @@ # Initialization ###################################################################### -use strict; use 5.10.1; +use strict; +use warnings; + use File::Basename; use Getopt::Long qw(:config bundling); use Pod::Usage; @@ -107,7 +109,7 @@ my $lc_hash = Bugzilla->localconfig; # At this point, localconfig is defined and is readable. So we know # everything we need to create the DB. We have to create it early, -# because some data required to populate data/params is stored in the DB. +# because some data required to populate data/params.json is stored in the DB. Bugzilla::DB::bz_check_requirements(!$silent); Bugzilla::DB::bz_create_database() if $lc_hash->{'db_check'}; @@ -362,7 +364,7 @@ L. =item 9 -Updates the system parameters (stored in F), using +Updates the system parameters (stored in F), using L. =item 10 diff --git a/mozilla/webtools/bugzilla/clean-bug-user-last-visit.pl b/mozilla/webtools/bugzilla/clean-bug-user-last-visit.pl index 9884b7c48fb..57486bfed8e 100644 --- a/mozilla/webtools/bugzilla/clean-bug-user-last-visit.pl +++ b/mozilla/webtools/bugzilla/clean-bug-user-last-visit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/mozilla/webtools/bugzilla/colchange.cgi b/mozilla/webtools/bugzilla/colchange.cgi index 66b661e5a91..77d9f11eef1 100755 --- a/mozilla/webtools/bugzilla/colchange.cgi +++ b/mozilla/webtools/bugzilla/colchange.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/collectstats.pl b/mozilla/webtools/bugzilla/collectstats.pl index 330fae5b39f..3473c9e7189 100755 --- a/mozilla/webtools/bugzilla/collectstats.pl +++ b/mozilla/webtools/bugzilla/collectstats.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Getopt::Long qw(:config bundling); diff --git a/mozilla/webtools/bugzilla/config.cgi b/mozilla/webtools/bugzilla/config.cgi index 02f95472625..56a9a3f8a18 100755 --- a/mozilla/webtools/bugzilla/config.cgi +++ b/mozilla/webtools/bugzilla/config.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/contrib/Bugzilla.pm b/mozilla/webtools/bugzilla/contrib/Bugzilla.pm index fbae60de4a3..31e0a0f6d0b 100644 --- a/mozilla/webtools/bugzilla/contrib/Bugzilla.pm +++ b/mozilla/webtools/bugzilla/contrib/Bugzilla.pm @@ -6,6 +6,7 @@ package Bugzilla; use 5.10.1; use strict; +use warnings; ####################################################################### # The goal of this tiny module is to let Bugzilla packagers of # diff --git a/mozilla/webtools/bugzilla/contrib/README b/mozilla/webtools/bugzilla/contrib/README index f8206292523..f0d83086a24 100644 --- a/mozilla/webtools/bugzilla/contrib/README +++ b/mozilla/webtools/bugzilla/contrib/README @@ -33,6 +33,10 @@ bz_webservice_demo.pl -- An example script that demonstrates how to talk to recode.pl -- Script to convert a database from one encoding (or multiple encodings) to UTF-8. + replyrc -- A config file for Reply (a perl shell) that loads + Bugzilla, extensions and provides a few utility + functions for manipulating Bugzilla data. + sendbugmail.pl -- This script is a drop-in replacement for the 'processmail' script which used to be shipped with Bugzilla, but was replaced by the diff --git a/mozilla/webtools/bugzilla/contrib/bz_webservice_demo.pl b/mozilla/webtools/bugzilla/contrib/bz_webservice_demo.pl index 8850d642ad3..af8c253084f 100755 --- a/mozilla/webtools/bugzilla/contrib/bz_webservice_demo.pl +++ b/mozilla/webtools/bugzilla/contrib/bz_webservice_demo.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,7 +18,10 @@ C for detailed help =cut +use 5.10.1; use strict; +use warnings; + use lib qw(lib); use Getopt::Long; use Pod::Usage; diff --git a/mozilla/webtools/bugzilla/contrib/bzdbcopy.pl b/mozilla/webtools/bugzilla/contrib/bzdbcopy.pl index f50002e85c2..fcdbefd56d3 100755 --- a/mozilla/webtools/bugzilla/contrib/bzdbcopy.pl +++ b/mozilla/webtools/bugzilla/contrib/bzdbcopy.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,10 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. +use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/contrib/console.pl b/mozilla/webtools/bugzilla/contrib/console.pl index dbd514ebdfb..fe2342cd9b0 100644 --- a/mozilla/webtools/bugzilla/contrib/console.pl +++ b/mozilla/webtools/bugzilla/contrib/console.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,6 +6,8 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. +use warnings; + use File::Basename; BEGIN { chdir dirname($0) . "/.."; } use lib qw(. lib); @@ -51,7 +53,7 @@ sub d { # p: print as a single string (normal behavior puts list items on separate lines) sub p { - local $^W=0; # suppress possible undefined var message + no warnings; # suppress possible undefined var message print(@_, "\n"); return (); } diff --git a/mozilla/webtools/bugzilla/contrib/convert-workflow.pl b/mozilla/webtools/bugzilla/contrib/convert-workflow.pl index 8f76dac7f6d..d9bffb7bbed 100644 --- a/mozilla/webtools/bugzilla/contrib/convert-workflow.pl +++ b/mozilla/webtools/bugzilla/contrib/convert-workflow.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,10 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. +use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/contrib/extension-convert.pl b/mozilla/webtools/bugzilla/contrib/extension-convert.pl index 4e24b614ac8..91a77b83943 100644 --- a/mozilla/webtools/bugzilla/contrib/extension-convert.pl +++ b/mozilla/webtools/bugzilla/contrib/extension-convert.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,8 +6,10 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. +use 5.10.1; use strict; use warnings; + use lib qw(. lib); use Bugzilla; @@ -68,6 +70,8 @@ my ($modules, $subs) = code_files_to_subroutines($to_dir); my $config_pm = < '$extension_name'; $install_requirements __PACKAGE__->NAME; @@ -76,6 +80,8 @@ END my $extension_pm = <selectcol_arrayref(" SELECT earlier.id FROM bug_user_last_visit as earlier INNER JOIN bug_user_last_visit as later - ON (earlier.user_id != later.user_id AND earlier.last_visit_ts < later.last_visit_ts + ON (earlier.user_id != later.user_id + AND earlier.last_visit_ts < later.last_visit_ts AND earlier.bug_id = later.bug_id) WHERE (earlier.user_id = ? OR earlier.user_id = ?) AND (later.user_id = ? OR later.user_id = ?)", undef, $old_id, $new_id, $old_id, $new_id); -$dbh->do("DELETE FROM bug_user_last_visit WHERE " . $dbh->sql_in('id', $dupe_ids)); + +if (@$dupe_ids) { + $dbh->do("DELETE FROM bug_user_last_visit WHERE " . + $dbh->sql_in('id', $dupe_ids)); +} # Migrate records from old user to new user. foreach my $table (keys %changes) { diff --git a/mozilla/webtools/bugzilla/contrib/mysqld-watcher.pl b/mozilla/webtools/bugzilla/contrib/mysqld-watcher.pl index 08a87b5fe73..be93dcbb5df 100755 --- a/mozilla/webtools/bugzilla/contrib/mysqld-watcher.pl +++ b/mozilla/webtools/bugzilla/contrib/mysqld-watcher.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -9,7 +9,9 @@ # mysqld-watcher.pl - a script that watches the running instance of # mysqld and kills off any long-running SELECTs against the shadow_db # +use 5.10.1; use strict; +use warnings; # some configurables: diff --git a/mozilla/webtools/bugzilla/contrib/recode.pl b/mozilla/webtools/bugzilla/contrib/recode.pl index de204f15568..e6da47b924a 100755 --- a/mozilla/webtools/bugzilla/contrib/recode.pl +++ b/mozilla/webtools/bugzilla/contrib/recode.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,10 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. +use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/contrib/replyrc b/mozilla/webtools/bugzilla/contrib/replyrc new file mode 100644 index 00000000000..2c5541e4c8f --- /dev/null +++ b/mozilla/webtools/bugzilla/contrib/replyrc @@ -0,0 +1,30 @@ +# This is a config file for Reply, +# which is a cpan distribution. You can install it with "cpan Reply" or "cpanm Reply". +# To use this config file, either copy as ~/.replyrc or run the following command: +# reply --cfg `pwd`/contrib/replyrc + +script_line1 = use strict; +script_line2 = use warnings; +script_line3 = use v5.10; +script_line4 = use Bugzilla; +script_line5 = Bugzilla->extensions; 1; +script_line6 = sub filter { Bugzilla->template->{SERVICE}->{CONTEXT}->{CONFIG}->{FILTERS}->{$_[0]} } +script_line7 = sub b { Bugzilla::Bug->new(@_) } +script_line8 = sub u { Bugzilla::User->new(@_) } +script_line9 = sub f { Bugzilla::Field->new(@_) } + +[Interrupt] +[FancyPrompt] +[DataDumper] +[Colors] +[ReadLine] +[Hints] +[Packages] +[LexicalPersistence] +[ResultCache] +[Autocomplete::Packages] +[Autocomplete::Lexicals] +[Autocomplete::Functions] +[Autocomplete::Globals] +[Autocomplete::Methods] +[Autocomplete::Commands] diff --git a/mozilla/webtools/bugzilla/contrib/sendbugmail.pl b/mozilla/webtools/bugzilla/contrib/sendbugmail.pl index da0eafd30f0..223d91f6c6d 100755 --- a/mozilla/webtools/bugzilla/contrib/sendbugmail.pl +++ b/mozilla/webtools/bugzilla/contrib/sendbugmail.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/contrib/sendunsentbugmail.pl b/mozilla/webtools/bugzilla/contrib/sendunsentbugmail.pl index 47455413562..b9034aa8de2 100755 --- a/mozilla/webtools/bugzilla/contrib/sendunsentbugmail.pl +++ b/mozilla/webtools/bugzilla/contrib/sendunsentbugmail.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/contrib/syncLDAP.pl b/mozilla/webtools/bugzilla/contrib/syncLDAP.pl index 6ad96477bbe..f618624ec31 100755 --- a/mozilla/webtools/bugzilla/contrib/syncLDAP.pl +++ b/mozilla/webtools/bugzilla/contrib/syncLDAP.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,9 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. +use 5.10.1; use strict; +use warnings; use lib qw(. lib); diff --git a/mozilla/webtools/bugzilla/createaccount.cgi b/mozilla/webtools/bugzilla/createaccount.cgi index c9516ab00fc..21d6cc8db34 100755 --- a/mozilla/webtools/bugzilla/createaccount.cgi +++ b/mozilla/webtools/bugzilla/createaccount.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/describecomponents.cgi b/mozilla/webtools/bugzilla/describecomponents.cgi index db8260b5d47..f74dc75f43b 100755 --- a/mozilla/webtools/bugzilla/describecomponents.cgi +++ b/mozilla/webtools/bugzilla/describecomponents.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/describekeywords.cgi b/mozilla/webtools/bugzilla/describekeywords.cgi index 2147ac47dc0..31bf0c13e11 100755 --- a/mozilla/webtools/bugzilla/describekeywords.cgi +++ b/mozilla/webtools/bugzilla/describekeywords.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/docs/en/rst/about/index.rst b/mozilla/webtools/bugzilla/docs/en/rst/about/index.rst index 3c0d19ca5ef..985f09a7461 100644 --- a/mozilla/webtools/bugzilla/docs/en/rst/about/index.rst +++ b/mozilla/webtools/bugzilla/docs/en/rst/about/index.rst @@ -46,7 +46,7 @@ Document Conventions This document uses the following conventions: -.. warning:: This is a warning—something you should be aware of. +.. warning:: This is a warning - something you should be aware of. .. note:: This is just a note, for your information. @@ -68,7 +68,7 @@ This documentation is maintained in `reStructured Text `_ format using the `Sphinx `_ documentation system. It has -recently been rewritten, so it undoubtedly has bugs. Please file any you find, in +recently been rewritten, so undoubtedly has bugs. Please file any you find, in the `Bugzilla Documentation `_ component in Mozilla's installation of Bugzilla. If you also want to make a @@ -83,7 +83,7 @@ License Bugzilla is `free `_ and `open source `_ software, which means (among other -things) that you can download it, install it, and run it for any purpose +things) that you can download it, install it and run it for any purpose whatsoever without the need for license or payment. Isn't that refreshing? Bugzilla's code is made available under the @@ -91,7 +91,7 @@ Bugzilla's code is made available under the specifically the variant which is Incompatible with Secondary Licenses. However, again, if you only want to install and run Bugzilla, you don't need to worry about that; it's only relevant if you redistribute the code or any -changes you make. +changes you make. Bugzilla's documentation is made available under the `Creative Commons CC-BY-SA International License 4.0 diff --git a/mozilla/webtools/bugzilla/duplicates.cgi b/mozilla/webtools/bugzilla/duplicates.cgi index beac9c37e35..c1bf036be32 100755 --- a/mozilla/webtools/bugzilla/duplicates.cgi +++ b/mozilla/webtools/bugzilla/duplicates.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editclassifications.cgi b/mozilla/webtools/bugzilla/editclassifications.cgi index b743433b735..b06ce27ad9e 100755 --- a/mozilla/webtools/bugzilla/editclassifications.cgi +++ b/mozilla/webtools/bugzilla/editclassifications.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -9,6 +9,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editcomponents.cgi b/mozilla/webtools/bugzilla/editcomponents.cgi index 4423931fe31..7442365f35a 100755 --- a/mozilla/webtools/bugzilla/editcomponents.cgi +++ b/mozilla/webtools/bugzilla/editcomponents.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editfields.cgi b/mozilla/webtools/bugzilla/editfields.cgi index 5ac9dcccec3..e8351bdd697 100755 --- a/mozilla/webtools/bugzilla/editfields.cgi +++ b/mozilla/webtools/bugzilla/editfields.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editflagtypes.cgi b/mozilla/webtools/bugzilla/editflagtypes.cgi index 73ef1e52802..d848d250a54 100755 --- a/mozilla/webtools/bugzilla/editflagtypes.cgi +++ b/mozilla/webtools/bugzilla/editflagtypes.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; @@ -39,23 +41,24 @@ my @products = @{$vars->{products}}; my $action = $cgi->param('action') || 'list'; my $token = $cgi->param('token'); -my $product = $cgi->param('product'); -my $component = $cgi->param('component'); +my $prod_name = $cgi->param('product'); +my $comp_name = $cgi->param('component'); my $flag_id = $cgi->param('id'); -if ($product) { +my ($product, $component); + +if ($prod_name) { # Make sure the user is allowed to view this product name. # Users with global editcomponents privs can see all product names. - ($product) = grep { lc($_->name) eq lc($product) } @products; - $product || ThrowUserError('product_access_denied', { name => $cgi->param('product') }); + ($product) = grep { lc($_->name) eq lc($prod_name) } @products; + $product || ThrowUserError('product_access_denied', { name => $prod_name }); } -if ($component) { - ($product && $product->id) - || ThrowUserError('flag_type_component_without_product'); - ($component) = grep { lc($_->name) eq lc($component) } @{$product->components}; +if ($comp_name) { + $product || ThrowUserError('flag_type_component_without_product'); + ($component) = grep { lc($_->name) eq lc($comp_name) } @{$product->components}; $component || ThrowUserError('product_unknown_component', { product => $product->name, - comp => $cgi->param('component') }); + comp => $comp_name }); } # If 'categoryAction' is set, it has priority over 'action'. diff --git a/mozilla/webtools/bugzilla/editgroups.cgi b/mozilla/webtools/bugzilla/editgroups.cgi index 87c44f03c5f..287ac11142a 100755 --- a/mozilla/webtools/bugzilla/editgroups.cgi +++ b/mozilla/webtools/bugzilla/editgroups.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; @@ -20,9 +22,6 @@ use Bugzilla::Product; use Bugzilla::User; use Bugzilla::Token; -use constant SPECIAL_GROUPS => ('chartgroup', 'insidergroup', - 'timetrackinggroup', 'querysharegroup'); - my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; @@ -225,7 +224,7 @@ if ($action eq 'new') { if ($action eq 'del') { # Check that an existing group ID is given - my $group = Bugzilla::Group->check({ id => $cgi->param('group') }); + my $group = Bugzilla::Group->check({ id => scalar $cgi->param('group') }); $group->check_remove({ test_only => 1 }); $vars->{'shared_queries'} = $dbh->selectrow_array('SELECT COUNT(*) @@ -249,7 +248,7 @@ if ($action eq 'del') { if ($action eq 'delete') { check_token_data($token, 'delete_group'); # Check that an existing group ID is given - my $group = Bugzilla::Group->check({ id => $cgi->param('group') }); + my $group = Bugzilla::Group->check({ id => scalar $cgi->param('group') }); $vars->{'name'} = $group->name; $group->remove_from_db({ remove_from_users => scalar $cgi->param('removeusers'), diff --git a/mozilla/webtools/bugzilla/editkeywords.cgi b/mozilla/webtools/bugzilla/editkeywords.cgi index 5a7f6643b1a..41496f36229 100755 --- a/mozilla/webtools/bugzilla/editkeywords.cgi +++ b/mozilla/webtools/bugzilla/editkeywords.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editmilestones.cgi b/mozilla/webtools/bugzilla/editmilestones.cgi index 927c1a9d1b6..e20e623fb9d 100755 --- a/mozilla/webtools/bugzilla/editmilestones.cgi +++ b/mozilla/webtools/bugzilla/editmilestones.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editparams.cgi b/mozilla/webtools/bugzilla/editparams.cgi index 3486d70612f..ae569c2eb4b 100755 --- a/mozilla/webtools/bugzilla/editparams.cgi +++ b/mozilla/webtools/bugzilla/editparams.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editproducts.cgi b/mozilla/webtools/bugzilla/editproducts.cgi index 77d112f46a6..f2526575ebb 100755 --- a/mozilla/webtools/bugzilla/editproducts.cgi +++ b/mozilla/webtools/bugzilla/editproducts.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editsettings.cgi b/mozilla/webtools/bugzilla/editsettings.cgi index bf5e2025b2d..b10a497ba5b 100755 --- a/mozilla/webtools/bugzilla/editsettings.cgi +++ b/mozilla/webtools/bugzilla/editsettings.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; @@ -53,6 +55,7 @@ if ($action eq 'update') { } $vars->{'message'} = 'default_settings_updated'; $vars->{'changes_saved'} = $changed; + Bugzilla->memcached->clear_config(); delete_token($token); } diff --git a/mozilla/webtools/bugzilla/editusers.cgi b/mozilla/webtools/bugzilla/editusers.cgi index 5eb49d1396c..a38195a4b87 100755 --- a/mozilla/webtools/bugzilla/editusers.cgi +++ b/mozilla/webtools/bugzilla/editusers.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; @@ -647,7 +649,9 @@ sub check_user { sub mirrorListSelectionValues { my $cgi = Bugzilla->cgi; if (defined($cgi->param('matchtype'))) { - foreach ('matchvalue', 'matchstr', 'matchtype', 'grouprestrict', 'groupid') { + foreach ('matchvalue', 'matchstr', 'matchtype', + 'grouprestrict', 'groupid', 'is_enabled') + { $vars->{'listselectionvalues'}{$_} = $cgi->param($_); } } diff --git a/mozilla/webtools/bugzilla/editvalues.cgi b/mozilla/webtools/bugzilla/editvalues.cgi index 5bceed761ba..48775fc52a0 100755 --- a/mozilla/webtools/bugzilla/editvalues.cgi +++ b/mozilla/webtools/bugzilla/editvalues.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,12 +6,10 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. -# This is a script to edit the values of fields that have drop-down -# or select boxes. It is largely a copy of editmilestones.cgi, but -# with some cleanup. - use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editversions.cgi b/mozilla/webtools/bugzilla/editversions.cgi index 2dce7bd0a2b..674a20b7e9c 100755 --- a/mozilla/webtools/bugzilla/editversions.cgi +++ b/mozilla/webtools/bugzilla/editversions.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editwhines.cgi b/mozilla/webtools/bugzilla/editwhines.cgi index 84a97b87768..b11c44949c1 100755 --- a/mozilla/webtools/bugzilla/editwhines.cgi +++ b/mozilla/webtools/bugzilla/editwhines.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,6 +12,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/editworkflow.cgi b/mozilla/webtools/bugzilla/editworkflow.cgi index 68cd984586c..71b14af7786 100755 --- a/mozilla/webtools/bugzilla/editworkflow.cgi +++ b/mozilla/webtools/bugzilla/editworkflow.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/email_in.pl b/mozilla/webtools/bugzilla/email_in.pl index 03db450f7a4..ae4c42bde5f 100755 --- a/mozilla/webtools/bugzilla/email_in.pl +++ b/mozilla/webtools/bugzilla/email_in.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/mozilla/webtools/bugzilla/enter_bug.cgi b/mozilla/webtools/bugzilla/enter_bug.cgi index baf5d78339d..3f22fe4b840 100755 --- a/mozilla/webtools/bugzilla/enter_bug.cgi +++ b/mozilla/webtools/bugzilla/enter_bug.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,6 +18,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/extensions/BmpConvert/Config.pm b/mozilla/webtools/bugzilla/extensions/BmpConvert/Config.pm index 91808bc4b7a..4984f19a9d7 100644 --- a/mozilla/webtools/bugzilla/extensions/BmpConvert/Config.pm +++ b/mozilla/webtools/bugzilla/extensions/BmpConvert/Config.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::BmpConvert; use 5.10.1; use strict; +use warnings; + use constant NAME => 'BmpConvert'; use constant REQUIRED_MODULES => [ { diff --git a/mozilla/webtools/bugzilla/extensions/BmpConvert/Extension.pm b/mozilla/webtools/bugzilla/extensions/BmpConvert/Extension.pm index eb634f4a127..b8201f106df 100644 --- a/mozilla/webtools/bugzilla/extensions/BmpConvert/Extension.pm +++ b/mozilla/webtools/bugzilla/extensions/BmpConvert/Extension.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::BmpConvert; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::Extension); use Image::Magick; diff --git a/mozilla/webtools/bugzilla/extensions/Example/Config.pm b/mozilla/webtools/bugzilla/extensions/Example/Config.pm index 13635dc7f5a..e7782ef6ced 100644 --- a/mozilla/webtools/bugzilla/extensions/Example/Config.pm +++ b/mozilla/webtools/bugzilla/extensions/Example/Config.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::Example; use 5.10.1; use strict; +use warnings; + use constant NAME => 'Example'; use constant REQUIRED_MODULES => [ { diff --git a/mozilla/webtools/bugzilla/extensions/Example/Extension.pm b/mozilla/webtools/bugzilla/extensions/Example/Extension.pm index c9449d8b0a0..256589dab08 100644 --- a/mozilla/webtools/bugzilla/extensions/Example/Extension.pm +++ b/mozilla/webtools/bugzilla/extensions/Example/Extension.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::Example; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::Extension); use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/extensions/Example/lib/Auth/Login.pm b/mozilla/webtools/bugzilla/extensions/Example/lib/Auth/Login.pm index c1cfe62cc95..15c58a881e4 100644 --- a/mozilla/webtools/bugzilla/extensions/Example/lib/Auth/Login.pm +++ b/mozilla/webtools/bugzilla/extensions/Example/lib/Auth/Login.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::Example::Auth::Login; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::Auth::Login); use constant user_can_create_account => 0; use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/extensions/Example/lib/Auth/Verify.pm b/mozilla/webtools/bugzilla/extensions/Example/lib/Auth/Verify.pm index df5059a05f4..49fd9fbb783 100644 --- a/mozilla/webtools/bugzilla/extensions/Example/lib/Auth/Verify.pm +++ b/mozilla/webtools/bugzilla/extensions/Example/lib/Auth/Verify.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::Example::Auth::Verify; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::Auth::Verify); use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/extensions/Example/template/en/default/hook/search/tabs-search_tabs.html.tmpl b/mozilla/webtools/bugzilla/extensions/Example/template/en/default/hook/search/tabs-search_tabs.html.tmpl index c40cb6e5e1f..bf522f7dd02 100644 --- a/mozilla/webtools/bugzilla/extensions/Example/template/en/default/hook/search/tabs-search_tabs.html.tmpl +++ b/mozilla/webtools/bugzilla/extensions/Example/template/en/default/hook/search/tabs-search_tabs.html.tmpl @@ -6,8 +6,8 @@ # defined by the Mozilla Public License, v. 2.0. #%] -[% - tabs.push ({ name => 'newsearch', label => "New Search", - link => "query.cgi?format=newsearch" }) +[% + tabs.push({ name => 'newsearch', label => "New Search", + link => "query.cgi?format=newsearch" }) %] diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/Config.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/Config.pm index 1e62306c431..e0eac5f8a82 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/Config.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/Config.pm @@ -9,6 +9,7 @@ package Bugzilla::Extension::MoreBugUrl; use 5.10.1; use strict; +use warnings; use constant NAME => 'MoreBugUrl'; diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/Extension.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/Extension.pm index ed0fe7b1f7c..18507f8d1e5 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/Extension.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/Extension.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::MoreBugUrl; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::Extension); use constant MORE_SUB_CLASSES => qw( diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/BitBucket.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/BitBucket.pm index fbb7be1a127..dcc85992d69 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/BitBucket.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/BitBucket.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::MoreBugUrl::BitBucket; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::BugUrl); ############################### diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/GetSatisfaction.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/GetSatisfaction.pm index 75d5ece3975..74951735bf9 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/GetSatisfaction.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/GetSatisfaction.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::MoreBugUrl::GetSatisfaction; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::BugUrl); ############################### diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/PHP.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/PHP.pm index ea090e8652b..6f201d7b1f0 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/PHP.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/PHP.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::MoreBugUrl::PHP; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::BugUrl); ############################### diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/RT.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/RT.pm index a1ca6fd8856..acb90cf396a 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/RT.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/RT.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::MoreBugUrl::RT; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::BugUrl); ############################### diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Redmine.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Redmine.pm index a1c1382ce30..57a07123945 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Redmine.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Redmine.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::MoreBugUrl::Redmine; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::BugUrl); ############################### diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/ReviewBoard.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/ReviewBoard.pm index 08128353fcf..af5ff068418 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/ReviewBoard.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/ReviewBoard.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::MoreBugUrl::ReviewBoard; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::BugUrl); ############################### diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Rietveld.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Rietveld.pm index a8bccba0884..a4bf08492fe 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Rietveld.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Rietveld.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::MoreBugUrl::Rietveld; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::BugUrl); ############################### diff --git a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Savane.pm b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Savane.pm index a8a439b415e..efda1fa4f54 100644 --- a/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Savane.pm +++ b/mozilla/webtools/bugzilla/extensions/MoreBugUrl/lib/Savane.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::MoreBugUrl::Savane; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::BugUrl); ############################### diff --git a/mozilla/webtools/bugzilla/extensions/OldBugMove/Config.pm b/mozilla/webtools/bugzilla/extensions/OldBugMove/Config.pm index a42567feeca..681cbae2df5 100644 --- a/mozilla/webtools/bugzilla/extensions/OldBugMove/Config.pm +++ b/mozilla/webtools/bugzilla/extensions/OldBugMove/Config.pm @@ -9,5 +9,7 @@ package Bugzilla::Extension::OldBugMove; use 5.10.1; use strict; +use warnings; + use constant NAME => 'OldBugMove'; __PACKAGE__->NAME; diff --git a/mozilla/webtools/bugzilla/extensions/OldBugMove/Extension.pm b/mozilla/webtools/bugzilla/extensions/OldBugMove/Extension.pm index b58ffe883be..375707fd229 100644 --- a/mozilla/webtools/bugzilla/extensions/OldBugMove/Extension.pm +++ b/mozilla/webtools/bugzilla/extensions/OldBugMove/Extension.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::OldBugMove; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::Extension); use Bugzilla::Constants; use Bugzilla::Error; diff --git a/mozilla/webtools/bugzilla/extensions/OldBugMove/lib/Params.pm b/mozilla/webtools/bugzilla/extensions/OldBugMove/lib/Params.pm index c922e1faf82..05e3ed2773b 100644 --- a/mozilla/webtools/bugzilla/extensions/OldBugMove/lib/Params.pm +++ b/mozilla/webtools/bugzilla/extensions/OldBugMove/lib/Params.pm @@ -9,6 +9,7 @@ package Bugzilla::Extension::OldBugMove::Params; use 5.10.1; use strict; +use warnings; use Bugzilla::Config::Common; diff --git a/mozilla/webtools/bugzilla/extensions/Voting/Config.pm b/mozilla/webtools/bugzilla/extensions/Voting/Config.pm index 812ede60f87..97c44933e2a 100644 --- a/mozilla/webtools/bugzilla/extensions/Voting/Config.pm +++ b/mozilla/webtools/bugzilla/extensions/Voting/Config.pm @@ -9,6 +9,7 @@ package Bugzilla::Extension::Voting; use 5.10.1; use strict; +use warnings; use constant NAME => 'Voting'; diff --git a/mozilla/webtools/bugzilla/extensions/Voting/Extension.pm b/mozilla/webtools/bugzilla/extensions/Voting/Extension.pm index e54a2aab0f8..8009f16bbcc 100644 --- a/mozilla/webtools/bugzilla/extensions/Voting/Extension.pm +++ b/mozilla/webtools/bugzilla/extensions/Voting/Extension.pm @@ -9,6 +9,8 @@ package Bugzilla::Extension::Voting; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::Extension); use Bugzilla::Bug; diff --git a/mozilla/webtools/bugzilla/extensions/create.pl b/mozilla/webtools/bugzilla/extensions/create.pl index e2d3321b195..d4256694bca 100644 --- a/mozilla/webtools/bugzilla/extensions/create.pl +++ b/mozilla/webtools/bugzilla/extensions/create.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/importxml.pl b/mozilla/webtools/bugzilla/importxml.pl index 05d86353023..8750c63a110 100755 --- a/mozilla/webtools/bugzilla/importxml.pl +++ b/mozilla/webtools/bugzilla/importxml.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,6 +12,7 @@ use 5.10.1; use strict; +use warnings; ##################################################################### # diff --git a/mozilla/webtools/bugzilla/index.cgi b/mozilla/webtools/bugzilla/index.cgi index 032c6c371ab..15d34451d51 100755 --- a/mozilla/webtools/bugzilla/index.cgi +++ b/mozilla/webtools/bugzilla/index.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/install-module.pl b/mozilla/webtools/bugzilla/install-module.pl index a7359917de6..365f10bbfa9 100755 --- a/mozilla/webtools/bugzilla/install-module.pl +++ b/mozilla/webtools/bugzilla/install-module.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/mozilla/webtools/bugzilla/jobqueue.pl b/mozilla/webtools/bugzilla/jobqueue.pl index d538e478469..85818033475 100755 --- a/mozilla/webtools/bugzilla/jobqueue.pl +++ b/mozilla/webtools/bugzilla/jobqueue.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,7 @@ use 5.10.1; use strict; +use warnings; use Cwd qw(abs_path); use File::Basename; @@ -32,13 +33,14 @@ jobqueue.pl - Runs jobs in the background for Bugzilla. ./jobqueue.pl [OPTIONS] COMMAND OPTIONS: - -f Run in the foreground (don't detach) - -d Output a lot of debugging information - -p file Specify the file where jobqueue.pl should store its current - process id. Defaults to F. - -n name What should this process call itself in the system log? - Defaults to the full path you used to invoke the script. - + -f Run in the foreground (don't detach) + -d Output a lot of debugging information + -p file Specify the file where jobqueue.pl should store its current + process id. Defaults to F. + -n name What should this process call itself in the system log? + Defaults to the full path you used to invoke the script. + -j job-name The name of jobs to process. Can be specified multiple times. + If not specified, all job types will be processed. COMMANDS: start Starts a new jobqueue daemon if there isn't one running already stop Stops a running jobqueue daemon diff --git a/mozilla/webtools/bugzilla/js/bug.js b/mozilla/webtools/bugzilla/js/bug.js index abefbb22d58..f0bf68a3028 100644 --- a/mozilla/webtools/bugzilla/js/bug.js +++ b/mozilla/webtools/bugzilla/js/bug.js @@ -22,6 +22,7 @@ YAHOO.bugzilla.dupTable = { method : "Bug.possible_duplicates", id : YAHOO.bugzilla.dupTable.counter, params : { + Bugzilla_api_token: BUGZILLA.api_token, product : product_name, summary : summary_field.value, limit : 7, @@ -199,7 +200,10 @@ function set_assign_to(use_qa_contact) { var args = JSON.stringify({ version: "1.1", method: 'BugUserLastVisit.update', - params: { ids: bug_id }, + params: { + Bugzilla_api_token: BUGZILLA.api_token, + ids: bug_id + }, }); var callbacks = { failure: function(res) { @@ -218,7 +222,9 @@ function set_assign_to(use_qa_contact) { var args = JSON.stringify({ version: "1.1", method: 'BugUserLastVisit.get', - params: { }, + params: { + Bugzilla_api_token: BUGZILLA.api_token + }, }); var callbacks = { success: function(res) { done(JSON.parse(res.responseText)) }, diff --git a/mozilla/webtools/bugzilla/js/comment-tagging.js b/mozilla/webtools/bugzilla/js/comment-tagging.js index 035d05b0b73..b6f02f00efd 100644 --- a/mozilla/webtools/bugzilla/js/comment-tagging.js +++ b/mozilla/webtools/bugzilla/js/comment-tagging.js @@ -20,6 +20,10 @@ YAHOO.bugzilla.commentTagging = { can_edit : false, pending : {}, + label : '', + min_len_error: '', + max_len_error: '', + init : function(can_edit) { this.can_edit = can_edit; this.ctag_div = Dom.get('bz_ctag_div'); @@ -48,9 +52,14 @@ YAHOO.bugzilla.commentTagging = { YAHOO.bugzilla.commentTagging.counter = YAHOO.bugzilla.commentTagging.counter + 1; YAHOO.util.Connect.setDefaultPostHeader('application/json', true); return YAHOO.lang.JSON.stringify({ + version: "1.1", method : "Bug.search_comment_tags", id : YAHOO.bugzilla.commentTagging.counter, - params : [ { query : query, limit : 10 } ] + params : { + Bugzilla_api_token: BUGZILLA.api_token, + query : query, + limit : 10 + } }); }; ac.minQueryLength = this.min_len; @@ -181,7 +190,7 @@ YAHOO.bugzilla.commentTagging = { tags.sort(); if (tags.length) { var div = document.createElement('div'); - div.appendChild(document.createTextNode('Comment Tags:')); + div.appendChild(document.createTextNode(this.label)); var ul = document.createElement('ul'); ul.id = 'comment_tags_collapse_expand'; div.appendChild(ul); @@ -256,9 +265,9 @@ YAHOO.bugzilla.commentTagging = { if (tag == '') continue; if (tag.length < YAHOO.bugzilla.commentTagging.min_len) - throw new Error("Comment tags must be at least " + this.min_len + " characters."); + throw new Error(this.min_len_error) if (tag.length > YAHOO.bugzilla.commentTagging.max_len) - throw new Error("Comment tags cannot be longer than " + this.min_len + " characters."); + throw new Error(this.max_len_error) // append new tag if (bz_isValueInArrayIgnoreCase(tags, tag)) continue; @@ -327,6 +336,7 @@ YAHOO.bugzilla.commentTagging = { version: "1.1", method: 'Bug.comments', params: { + Bugzilla_api_token: BUGZILLA.api_token, comment_ids: [ comment_id ], include_fields: [ 'tags' ] } @@ -359,6 +369,7 @@ YAHOO.bugzilla.commentTagging = { version: "1.1", method: 'Bug.update_comment_tags', params: { + Bugzilla_api_token: BUGZILLA.api_token, comment_id: comment_id, add: add, remove: remove diff --git a/mozilla/webtools/bugzilla/js/field.js b/mozilla/webtools/bugzilla/js/field.js index 892c8669f6c..c24603988f0 100644 --- a/mozilla/webtools/bugzilla/js/field.js +++ b/mozilla/webtools/bugzilla/js/field.js @@ -46,10 +46,14 @@ function validateEnterBug(theform) { _errorFor(attach_desc, 'attach_desc'); focus_me = attach_desc; } - var check_description = status_comment_required[bug_status.value]; - if (check_description && YAHOO.lang.trim(description.value) == '') { - _errorFor(description, 'description'); - focus_me = description; + // bug_status can be undefined if the bug_status field is not editable by + // the currently logged in user. + if (bug_status) { + var check_description = status_comment_required[bug_status.value]; + if (check_description && YAHOO.lang.trim(description.value) == '') { + _errorFor(description, 'description'); + focus_me = description; + } } if (YAHOO.lang.trim(short_desc.value) == '') { _errorFor(short_desc); @@ -295,7 +299,7 @@ function checkForChangedFieldValues(e, ContainerInputArray ) { if ( el ) { if ( !ContainerInputArray[4] && (el.value != ContainerInputArray[3] - || (el.value == "" && el.id != "alias" && el.id != "qa_contact")) ) + || (el.value == "" && el.id != "qa_contact")) ) { unhide = true; } @@ -316,17 +320,6 @@ function checkForChangedFieldValues(e, ContainerInputArray ) { } -function hideAliasAndSummary(short_desc_value, alias_value) { - // check the short desc field - hideEditableField( 'summary_alias_container','summary_alias_input', - 'editme_action','short_desc', short_desc_value); - // check that the alias hasn't changed - var bz_alias_check_array = new Array('summary_alias_container', - 'summary_alias_input', 'alias', alias_value); - YAHOO.util.Event.addListener( window, 'load', checkForChangedFieldValues, - bz_alias_check_array); -} - function showPeopleOnChange( field_id_list ) { for(var i = 0; i < field_id_list.length; i++) { YAHOO.util.Event.addListener( field_id_list[i],'change', showEditableField, @@ -825,6 +818,7 @@ YAHOO.bugzilla.userAutocomplete = { method : "User.get", id : YAHOO.bugzilla.userAutocomplete.counter, params : [ { + Bugzilla_api_token: BUGZILLA.api_token, match : [ decodeURIComponent(enteredText) ], include_fields : [ "name", "real_name" ] } ] @@ -989,17 +983,33 @@ function initDirtyFieldTracking() { */ var last_comment_text = ''; +var last_markdown_cb_value = null; +var comment_textarea_width = null; +var comment_textarea_height = null; -function show_comment_preview(bug_id) { +function refresh_markdown_preview (bug_id) { + if (!YAHOO.util.Dom.hasClass('comment_preview_tab', 'active_comment_tab')) + return; + show_comment_preview(bug_id, 1); +} + +function show_comment_preview(bug_id, refresh) { var Dom = YAHOO.util.Dom; var comment = document.getElementById('comment'); var preview = document.getElementById('comment_preview'); + var markdown_cb = document.getElementById('use_markdown'); if (!comment || !preview) return; - if (Dom.hasClass('comment_preview_tab', 'active_comment_tab')) return; + if (Dom.hasClass('comment_preview_tab', 'active_comment_tab') && !refresh) + return; - preview.style.width = (comment.clientWidth - 4) + 'px'; - preview.style.height = comment.offsetHeight + 'px'; + if (!comment_textarea_width) { + comment_textarea_width = (comment.clientWidth - 4) + 'px'; + comment_textarea_height = comment.offsetHeight + 'px'; + } + + preview.style.width = comment_textarea_width; + preview.style.height = comment_textarea_height; var comment_tab = document.getElementById('comment_tab'); Dom.addClass(comment, 'bz_default_hidden'); @@ -1013,7 +1023,7 @@ function show_comment_preview(bug_id) { Dom.addClass('comment_preview_error', 'bz_default_hidden'); - if (last_comment_text == comment.value) + if (last_comment_text == comment.value && last_markdown_cb_value == markdown_cb.checked) return; Dom.addClass('comment_preview_text', 'bz_default_hidden'); @@ -1033,7 +1043,14 @@ function show_comment_preview(bug_id) { document.getElementById('comment_preview_text').innerHTML = data.result.html; Dom.addClass('comment_preview_loading', 'bz_default_hidden'); Dom.removeClass('comment_preview_text', 'bz_default_hidden'); + if (markdown_cb.checked) { + Dom.removeClass('comment_preview_text', 'comment_preview_pre'); + } + else { + Dom.addClass('comment_preview_text', 'comment_preview_pre'); + } last_comment_text = comment.value; + last_markdown_cb_value = markdown_cb.checked; } }, failure: function(res) { @@ -1047,8 +1064,10 @@ function show_comment_preview(bug_id) { version: "1.1", method: 'Bug.render_comment', params: { + Bugzilla_api_token: BUGZILLA.api_token, id: bug_id, - text: comment.value + text: comment.value, + markdown: (markdown_cb != null) && markdown_cb.checked ? 1 : 0 } }) ); diff --git a/mozilla/webtools/bugzilla/jsonrpc.cgi b/mozilla/webtools/bugzilla/jsonrpc.cgi index 0b56d57c192..2c93585b091 100755 --- a/mozilla/webtools/bugzilla/jsonrpc.cgi +++ b/mozilla/webtools/bugzilla/jsonrpc.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/migrate.pl b/mozilla/webtools/bugzilla/migrate.pl index 0ce85fa154e..eb2a84b59bc 100644 --- a/mozilla/webtools/bugzilla/migrate.pl +++ b/mozilla/webtools/bugzilla/migrate.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use File::Basename; BEGIN { chdir dirname($0); } use lib qw(. lib); diff --git a/mozilla/webtools/bugzilla/mod_perl.pl b/mozilla/webtools/bugzilla/mod_perl.pl index 572bcc7f972..bdce744ca1c 100755 --- a/mozilla/webtools/bugzilla/mod_perl.pl +++ b/mozilla/webtools/bugzilla/mod_perl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -112,6 +112,7 @@ package Bugzilla::ModPerl::ResponseHandler; use 5.10.1; use strict; +use warnings; use parent qw(ModPerl::Registry); use Bugzilla; @@ -148,6 +149,7 @@ package Bugzilla::ModPerl::CleanupHandler; use 5.10.1; use strict; +use warnings; use Apache2::Const -compile => qw(OK); diff --git a/mozilla/webtools/bugzilla/page.cgi b/mozilla/webtools/bugzilla/page.cgi index a2aa9d883c0..b60ce8bdee3 100755 --- a/mozilla/webtools/bugzilla/page.cgi +++ b/mozilla/webtools/bugzilla/page.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -15,6 +15,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/post_bug.cgi b/mozilla/webtools/bugzilla/post_bug.cgi index 782bb22939f..9da8faec15a 100755 --- a/mozilla/webtools/bugzilla/post_bug.cgi +++ b/mozilla/webtools/bugzilla/post_bug.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; @@ -116,6 +118,7 @@ foreach my $field (qw(cc groups)) { $bug_params{$field} = [$cgi->param($field)]; } $bug_params{'comment'} = $comment; +$bug_params{'is_markdown'} = $cgi->param('use_markdown'); my @multi_selects = grep {$_->type == FIELD_TYPE_MULTI_SELECT && $_->enter_bug} Bugzilla->active_custom_fields; @@ -149,7 +152,10 @@ if (defined $cgi->param('version')) { # after the bug is filed. # Add an attachment if requested. -if (defined($cgi->upload('data')) || $cgi->param('attach_text')) { +my $data_fh = $cgi->upload('data'); +my $attach_text = $cgi->param('attach_text'); + +if ($data_fh || $attach_text) { $cgi->param('isprivate', $cgi->param('comment_is_private')); # Must be called before create() as it may alter $cgi->param('ispatch'). @@ -164,9 +170,9 @@ if (defined($cgi->upload('data')) || $cgi->param('attach_text')) { $attachment = Bugzilla::Attachment->create( {bug => $bug, creation_ts => $timestamp, - data => scalar $cgi->param('attach_text') || $cgi->upload('data'), + data => $attach_text || $data_fh, description => scalar $cgi->param('description'), - filename => $cgi->param('attach_text') ? "file_$id.txt" : scalar $cgi->upload('data'), + filename => $attach_text ? "file_$id.txt" : $data_fh, ispatch => scalar $cgi->param('ispatch'), isprivate => scalar $cgi->param('isprivate'), mimetype => $content_type, diff --git a/mozilla/webtools/bugzilla/process_bug.cgi b/mozilla/webtools/bugzilla/process_bug.cgi index 389ee18d18e..b3d9799602a 100755 --- a/mozilla/webtools/bugzilla/process_bug.cgi +++ b/mozilla/webtools/bugzilla/process_bug.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,20 +6,10 @@ # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. -# Implementation notes for this file: -# -# 1) the 'id' form parameter is validated early on, and if it is not a valid -# bugid an error will be reported, so it is OK for later code to simply check -# for a defined form 'id' value, and it can assume a valid bugid. -# -# 2) If the 'id' form parameter is not defined (after the initial validation), -# then we are processing multiple bugs, and @idlist will contain the ids. -# -# 3) If we are processing just the one id, then it is stored in @idlist for -# later processing. - use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; @@ -243,9 +233,13 @@ if (should_set('keywords')) { $set_all_fields{keywords}->{$action} = $cgi->param('keywords'); } if (should_set('comment')) { + my $is_markdown = ($user->use_markdown + && $cgi->param('use_markdown') eq '1') ? 1 : 0; + $set_all_fields{comment} = { - body => scalar $cgi->param('comment'), - is_private => scalar $cgi->param('comment_is_private'), + body => scalar $cgi->param('comment'), + is_private => scalar $cgi->param('comment_is_private'), + is_markdown => $is_markdown, }; } if (should_set('see_also')) { @@ -299,8 +293,17 @@ if (defined $cgi->param('newcc') if (defined $cgi->param('id')) { # Since aliases are unique (like bug numbers), they can only be changed # for one bug at a time. - if (defined $cgi->param('alias')) { - $set_all_fields{alias} = $cgi->param('alias'); + if (defined $cgi->param('newalias') || defined $cgi->param('removealias')) { + my @alias_add = split /[, ]+/, $cgi->param('newalias'); + + # We came from bug_form which uses a select box to determine what + # aliases need to be removed... + my @alias_remove = (); + if ($cgi->param('removealias') && $cgi->param('alias')) { + @alias_remove = $cgi->param('alias'); + } + + $set_all_fields{alias} = { add => \@alias_add, remove => \@alias_remove }; } } @@ -355,6 +358,17 @@ if (defined $cgi->param('id')) { $first_bug->add_tag($_) foreach @$tags_added; } } +else { + # Update flags on multiple bugs. The cgi params are slightly different + # than on a single bug, so we need to call a different sub. We also + # need to call this per bug, since we might be updating a flag in one + # bug, but adding it to a second bug + foreach my $b (@bug_objects) { + my ($flags, $new_flags) + = Bugzilla::Flag->multi_extract_flags_from_cgi($b, $vars); + $b->set_flags($flags, $new_flags); + } +} ############################## # Do Actual Database Updates # diff --git a/mozilla/webtools/bugzilla/query.cgi b/mozilla/webtools/bugzilla/query.cgi index 620cf2737d7..faf670d231c 100755 --- a/mozilla/webtools/bugzilla/query.cgi +++ b/mozilla/webtools/bugzilla/query.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/quips.cgi b/mozilla/webtools/bugzilla/quips.cgi index 03fd49548d0..b2790be548f 100755 --- a/mozilla/webtools/bugzilla/quips.cgi +++ b/mozilla/webtools/bugzilla/quips.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/relogin.cgi b/mozilla/webtools/bugzilla/relogin.cgi index 0c1cb9ad638..6f0c970f1fb 100755 --- a/mozilla/webtools/bugzilla/relogin.cgi +++ b/mozilla/webtools/bugzilla/relogin.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; @@ -85,19 +87,21 @@ elsif ($action eq 'begin-sudo') { { $credentials_provided = 1; } - + # Next, log in the user my $user = Bugzilla->login(LOGIN_REQUIRED); - + + my $target_login = $cgi->param('target_login'); + my $reason = $cgi->param('reason') || ''; + # At this point, the user is logged in. However, if they used a method # where they could have provided a username/password (i.e. CGI), but they # did not provide a username/password, then throw an error. if ($user->authorizer->can_login && !$credentials_provided) { ThrowUserError('sudo_password_required', - { target_login => $cgi->param('target_login'), - reason => $cgi->param('reason')}); + { target_login => $target_login, reason => $reason }); } - + # The user must be in the 'bz_sudoers' group unless ($user->in_group('bz_sudoers')) { ThrowUserError('auth_failure', { group => 'bz_sudoers', @@ -121,30 +125,22 @@ elsif ($action eq 'begin-sudo') { && ($token_data eq 'sudo_prepared')) { ThrowUserError('sudo_preparation_required', - { target_login => scalar $cgi->param('target_login'), - reason => scalar $cgi->param('reason')}); + { target_login => $target_login, reason => $reason }); } delete_token($cgi->param('token')); # Get & verify the target user (the user who we will be impersonating) - my $target_user = - new Bugzilla::User({ name => $cgi->param('target_login') }); + my $target_user = new Bugzilla::User({ name => $target_login }); unless (defined($target_user) && $target_user->id && $user->can_see_user($target_user)) { - ThrowUserError('user_match_failed', - { 'name' => $cgi->param('target_login') } - ); + ThrowUserError('user_match_failed', { name => $target_login }); } if ($target_user->in_group('bz_sudo_protect')) { ThrowUserError('sudo_protected', { login => $target_user->login }); } - # If we have a reason passed in, keep it under 200 characters - my $reason = $cgi->param('reason') || ''; - $reason = substr($reason, 0, 200); - # Calculate the session expiry time (T + 6 hours) my $time_string = time2str('%a, %d-%b-%Y %T %Z', time + MAX_SUDO_TOKEN_AGE, 'GMT'); @@ -164,9 +160,12 @@ elsif ($action eq 'begin-sudo') { # For the present, change the values of Bugzilla::user & Bugzilla::sudoer Bugzilla->sudo_request($target_user, $user); - + # NOTE: If you want to log the start of an sudo session, do it here. + # If we have a reason passed in, keep it under 200 characters + $reason = substr($reason, 0, 200); + # Go ahead and send out the message now my $message; my $mail_template = Bugzilla->template_inner($target_user->setting('lang')); diff --git a/mozilla/webtools/bugzilla/report.cgi b/mozilla/webtools/bugzilla/report.cgi index 4cfa6a6a421..a4d26f4d757 100755 --- a/mozilla/webtools/bugzilla/report.cgi +++ b/mozilla/webtools/bugzilla/report.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/reports.cgi b/mozilla/webtools/bugzilla/reports.cgi index 1f1791e4228..cdc9d4a87d8 100755 --- a/mozilla/webtools/bugzilla/reports.cgi +++ b/mozilla/webtools/bugzilla/reports.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/request.cgi b/mozilla/webtools/bugzilla/request.cgi index 771a32074f5..566781a0c01 100755 --- a/mozilla/webtools/bugzilla/request.cgi +++ b/mozilla/webtools/bugzilla/request.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/rest.cgi b/mozilla/webtools/bugzilla/rest.cgi index 928eb9ce451..f12fb64c44f 100755 --- a/mozilla/webtools/bugzilla/rest.cgi +++ b/mozilla/webtools/bugzilla/rest.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/runtests.pl b/mozilla/webtools/bugzilla/runtests.pl index 6a645000799..52de88e102f 100755 --- a/mozilla/webtools/bugzilla/runtests.pl +++ b/mozilla/webtools/bugzilla/runtests.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -9,6 +9,8 @@ use 5.10.1; use diagnostics; use strict; +use warnings; + use lib qw(lib); use Test::Harness qw(&runtests $verbose); diff --git a/mozilla/webtools/bugzilla/sanitycheck.cgi b/mozilla/webtools/bugzilla/sanitycheck.cgi index 2f87fb828e7..889d7f3e6e5 100755 --- a/mozilla/webtools/bugzilla/sanitycheck.cgi +++ b/mozilla/webtools/bugzilla/sanitycheck.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/sanitycheck.pl b/mozilla/webtools/bugzilla/sanitycheck.pl index 819c661528d..7fd12b17663 100755 --- a/mozilla/webtools/bugzilla/sanitycheck.pl +++ b/mozilla/webtools/bugzilla/sanitycheck.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/search_plugin.cgi b/mozilla/webtools/bugzilla/search_plugin.cgi index e9b281ec2da..7de8bed5f7e 100755 --- a/mozilla/webtools/bugzilla/search_plugin.cgi +++ b/mozilla/webtools/bugzilla/search_plugin.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/show_activity.cgi b/mozilla/webtools/bugzilla/show_activity.cgi index 1383dd018f6..7df10fcb847 100755 --- a/mozilla/webtools/bugzilla/show_activity.cgi +++ b/mozilla/webtools/bugzilla/show_activity.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/show_bug.cgi b/mozilla/webtools/bugzilla/show_bug.cgi index 95815f86b74..f69cae74085 100755 --- a/mozilla/webtools/bugzilla/show_bug.cgi +++ b/mozilla/webtools/bugzilla/show_bug.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/showdependencygraph.cgi b/mozilla/webtools/bugzilla/showdependencygraph.cgi index 6445b617535..02c8fd94f7a 100755 --- a/mozilla/webtools/bugzilla/showdependencygraph.cgi +++ b/mozilla/webtools/bugzilla/showdependencygraph.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use File::Temp; diff --git a/mozilla/webtools/bugzilla/showdependencytree.cgi b/mozilla/webtools/bugzilla/showdependencytree.cgi index fb8a59cc37f..9e193df0215 100755 --- a/mozilla/webtools/bugzilla/showdependencytree.cgi +++ b/mozilla/webtools/bugzilla/showdependencytree.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Bugzilla; diff --git a/mozilla/webtools/bugzilla/skins/standard/bug.css b/mozilla/webtools/bugzilla/skins/standard/bug.css index e23475a3596..851b1bdbab0 100644 --- a/mozilla/webtools/bugzilla/skins/standard/bug.css +++ b/mozilla/webtools/bugzilla/skins/standard/bug.css @@ -114,7 +114,7 @@ table#attachment_flags th, table#attachment_flags td { /* show_bug.cgi (start) */ -.bz_alias_short_desc_container { +.bz_short_desc_container { margin: 8px 0; padding: 0.3em; background-color: rgb(208, 208, 208); @@ -231,7 +231,7 @@ table#flags { .text_input, .bz_userfield, #keywords_container, #tag_container { width: 100%; } -.bz_bug .bz_alias_short_desc_container { +.bz_bug .bz_short_desc_container { width: inherit; } diff --git a/mozilla/webtools/bugzilla/skins/standard/global.css b/mozilla/webtools/bugzilla/skins/standard/global.css index 74005319a0b..60e06af7383 100644 --- a/mozilla/webtools/bugzilla/skins/standard/global.css +++ b/mozilla/webtools/bugzilla/skins/standard/global.css @@ -243,6 +243,15 @@ textarea { font-family: monospace; } + + blockquote { + border-left: 0.2em solid #CCC; + color: #65379C; + padding: 0; + margin-left: 0.5em; + margin-bottom: -1em; + white-space: pre; + } /* generic (end) */ /* Links that control whether or not something is visible. */ @@ -310,7 +319,7 @@ div#docslinks { } /* tbody.file pre is for the Diff view of attachments. */ -.bz_comment_text, .uneditable_textarea, tbody.file pre { +pre.bz_comment_text, .uneditable_textarea, tbody.file pre { font-family: monospace; white-space: pre-wrap; } @@ -723,12 +732,16 @@ input.required, select.required, span.required_explanation { width: auto; } +.comment_preview_pre { + white-space: pre; +} + #comment_preview_loading { font-style: italic; } #comment { - margin: 0px 0px 1em 0px; + margin: 0; } /*******************/ diff --git a/mozilla/webtools/bugzilla/summarize_time.cgi b/mozilla/webtools/bugzilla/summarize_time.cgi index 0d32d16e459..3bdf8ee52f1 100755 --- a/mozilla/webtools/bugzilla/summarize_time.cgi +++ b/mozilla/webtools/bugzilla/summarize_time.cgi @@ -1,4 +1,4 @@ -#!/usr/bin/perl -wT +#!/usr/bin/perl -T # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,6 +8,8 @@ use 5.10.1; use strict; +use warnings; + use lib qw(. lib); use Date::Parse; # strptime diff --git a/mozilla/webtools/bugzilla/t/001compile.t b/mozilla/webtools/bugzilla/t/001compile.t index af779309381..7097ad36119 100644 --- a/mozilla/webtools/bugzilla/t/001compile.t +++ b/mozilla/webtools/bugzilla/t/001compile.t @@ -10,8 +10,10 @@ #Bugzilla Test 1# ###Compilation### -use strict; use 5.10.1; +use strict; +use warnings; + use lib qw(. lib t); use Config; use Support::Files; @@ -52,7 +54,7 @@ sub compile_file { $libs = join " ", map { "-I\"$_\"" } split /$Config{path_sep}/, $ENV{PERL5LIB}; } my $perl = qq{"$^X"}; - my $output = `$perl $libs -wc$T $file 2>&1`; + my $output = `$perl $libs -c$T $file 2>&1`; chomp($output); my $return_val = $?; $output =~ s/^\Q$file\E syntax OK$//ms; diff --git a/mozilla/webtools/bugzilla/t/002goodperl.t b/mozilla/webtools/bugzilla/t/002goodperl.t index 02a57bea1fb..d1858361f7b 100644 --- a/mozilla/webtools/bugzilla/t/002goodperl.t +++ b/mozilla/webtools/bugzilla/t/002goodperl.t @@ -10,15 +10,19 @@ #Bugzilla Test 2# ####GoodPerl##### +use 5.10.1; use strict; +use warnings; use lib 't'; use Support::Files; -use Test::More tests => (scalar(@Support::Files::testitems) * 4); +use Test::More tests => (scalar(@Support::Files::testitems) + + scalar(@Support::Files::test_files)) * 6; -my @testitems = @Support::Files::testitems; # get the files to test. +my @testitems = (@Support::Files::test_files, @Support::Files::testitems); +my @require_taint = qw(email_in.pl importxml.pl mod_perl.pl whine.pl); foreach my $file (@testitems) { $file =~ s/\s.*$//; # nuke everything after the first space (#comment) @@ -38,23 +42,33 @@ foreach my $file (@testitems) { my $flags; if (!defined $ext || $ext eq "pl") { # standalone programs aren't taint checked yet - $flags = "w"; + if (grep { $file eq $_ } @require_taint) { + $flags = 'T'; + } + else { + $flags = ''; + } } elsif ($ext eq "pm") { ok(0, "$file is a module, but has a shebang"); next; } elsif ($ext eq "cgi") { # cgi files must be taint checked - $flags = "wT"; + $flags = 'T'; } else { ok(0, "$file has shebang but unknown extension"); next; } - if ($file_line1 =~ m#^\#\!/usr/bin/perl\s#) { - if ($file_line1 =~ m#\s-$flags#) { - ok(1,"$file uses standard perl location and -$flags"); - } else { - ok(0,"$file is MISSING -$flags --WARNING"); + if ($file_line1 =~ m#^\#\!/usr/bin/perl(?:\s-(\w+))?$#) { + my $file_flags = $1 || ''; + if ($flags eq $file_flags) { + ok(1, "$file uses standard perl location" . ($flags ? " and -$flags flag" : "")); + } + elsif ($flags) { + ok(0, "$file is MISSING -$flags flag --WARNING"); + } + else { + ok(0, "$file has unexpected -$file_flags flag --WARNING"); } } else { ok(0,"$file uses non-standard perl location"); @@ -63,7 +77,10 @@ foreach my $file (@testitems) { } foreach my $file (@testitems) { + my $found_use_perl = 0; my $found_use_strict = 0; + my $found_use_warnings = 0; + $file =~ s/\s.*$//; # nuke everything after the first space (#comment) next if (!$file); # skip null entries if (! open (FILE, $file)) { @@ -71,38 +88,28 @@ foreach my $file (@testitems) { next; } while (my $file_line = ) { - if ($file_line =~ m/^\s*use strict/) { - $found_use_strict = 1; - last; - } + $found_use_perl = 1 if $file_line =~ m/^\s*use 5.10.1/; + $found_use_strict = 1 if $file_line =~ m/^\s*use strict/; + $found_use_warnings = 1 if $file_line =~ m/^\s*use warnings/; + last if ($found_use_perl && $found_use_strict && $found_use_warnings); } close (FILE); + if ($found_use_perl) { + ok(1,"$file requires Perl 5.10.1"); + } else { + ok(0,"$file DOES NOT require Perl 5.10.1 --WARNING"); + } + if ($found_use_strict) { ok(1,"$file uses strict"); } else { ok(0,"$file DOES NOT use strict --WARNING"); } -} -foreach my $file (@testitems) { - my $found_use_feature = 0; - $file =~ s/\s.*$//; # nuke everything after the first space (#comment) - next if (!$file); # skip null entries - if (! open (FILE, $file)) { - ok(0,"could not open $file --WARNING"); - next; - } - while (my $file_line = ) { - if ($file_line =~ m/^\s*use 5.10.1/) { - $found_use_feature = 1; - last; - } - } - close (FILE); - if ($found_use_feature) { - ok(1,"$file requires Perl 5.10.1"); + if ($found_use_warnings) { + ok(1,"$file uses warnings"); } else { - ok(0,"$file DOES NOT require Perl 5.10.1 --WARNING"); + ok(0,"$file DOES NOT use warnings --WARNING"); } } @@ -132,4 +139,35 @@ foreach my $file (@testitems) { close(FILE); } + +# Forbird the { foo => $cgi->param() } syntax, for security reasons. +foreach my $file (@testitems) { + $file =~ s/\s.*$//; # nuke everything after the first space (#comment) + next unless $file; # skip null entries + if (!open(FILE, $file)) { + ok(0, "could not open $file --WARNING"); + next; + } + my $lineno = 0; + my @unsafe_args; + + while (my $file_line = ) { + $lineno++; + $file_line =~ s/^\s*(.+)\s*$/$1/; # Remove leading and trailing whitespaces. + if ($file_line =~ /^[^#]+=> \$cgi\->param/) { + push(@unsafe_args, "$file_line on line $lineno"); + } + } + + if (@unsafe_args) { + ok(0, "$file incorrectly passes a CGI argument to a hash --ERROR\n" . + join("\n", @unsafe_args)); + } + else { + ok(1, "$file has no vulnerable hash syntax"); + } + + close(FILE); +} + exit 0; diff --git a/mozilla/webtools/bugzilla/t/003safesys.t b/mozilla/webtools/bugzilla/t/003safesys.t index 0d6a215b1f2..2a257ffb9a2 100644 --- a/mozilla/webtools/bugzilla/t/003safesys.t +++ b/mozilla/webtools/bugzilla/t/003safesys.t @@ -10,7 +10,9 @@ #Bugzilla Test 3# ###Safesystem#### +use 5.10.1; use strict; +use warnings; use lib 't'; @@ -22,7 +24,7 @@ use Test::More tests => scalar(@Support::Files::testitems); # This will handle verbosity for us automatically. my $fh; { - local $^W = 0; # Don't complain about non-existent filehandles + no warnings qw(unopened); # Don't complain about non-existent filehandles if (-e \*Test::More::TESTOUT) { $fh = \*Test::More::TESTOUT; } elsif (-e \*Test::Builder::TESTOUT) { diff --git a/mozilla/webtools/bugzilla/t/004template.t b/mozilla/webtools/bugzilla/t/004template.t index 604559dc0ba..b0ca5a629bb 100644 --- a/mozilla/webtools/bugzilla/t/004template.t +++ b/mozilla/webtools/bugzilla/t/004template.t @@ -9,7 +9,9 @@ #Bugzilla Test 4# ####Templates#### +use 5.10.1; use strict; +use warnings; use lib 't'; @@ -26,7 +28,7 @@ use Test::More tests => ( scalar(@referenced_files) + 2 * $num_actual_files ); # This will handle verbosity for us automatically. my $fh; { - local $^W = 0; # Don't complain about non-existent filehandles + no warnings qw(unopened); # Don't complain about non-existent filehandles if (-e \*Test::More::TESTOUT) { $fh = \*Test::More::TESTOUT; } elsif (-e \*Test::Builder::TESTOUT) { @@ -86,6 +88,7 @@ foreach my $include_path (@include_paths) { wrap_comment => sub { return $_ }, none => sub { return $_ } , ics => [ sub { return sub { return $_; } }, 1] , + markdown => sub { return $_ } , }, } ); diff --git a/mozilla/webtools/bugzilla/t/005whitespace.t b/mozilla/webtools/bugzilla/t/005whitespace.t index 8cb2f7e8f01..b6de8cee391 100644 --- a/mozilla/webtools/bugzilla/t/005whitespace.t +++ b/mozilla/webtools/bugzilla/t/005whitespace.t @@ -9,7 +9,9 @@ #Bugzilla Test 5# #####no_tabs##### +use 5.10.1; use strict; +use warnings; use lib 't'; diff --git a/mozilla/webtools/bugzilla/t/006spellcheck.t b/mozilla/webtools/bugzilla/t/006spellcheck.t index 7f17c5169a2..24e00242d92 100644 --- a/mozilla/webtools/bugzilla/t/006spellcheck.t +++ b/mozilla/webtools/bugzilla/t/006spellcheck.t @@ -10,29 +10,13 @@ #Bugzilla Test 6# ####Spelling##### +use 5.10.1; +use strict; +use warnings; + use lib 't'; use Support::Files; -BEGIN { - #add the words to check here: - @evilwords = qw( - anyways - appearence - arbitary - cancelled - critera - databasa - dependan - existance - existant - paramater - refered - repsentation - suported - varsion - ); -} - # -1 because 006spellcheck.t must not be checked. use Test::More tests => scalar(@Support::Files::testitems) + scalar(@Support::Files::test_files) - 1; @@ -41,7 +25,7 @@ use Test::More tests => scalar(@Support::Files::testitems) # This will handle verbosity for us automatically. my $fh; { - local $^W = 0; # Don't complain about non-existent filehandles + no warnings qw(unopened); # Don't complain about non-existent filehandles if (-e \*Test::More::TESTOUT) { $fh = \*Test::More::TESTOUT; } elsif (-e \*Test::Builder::TESTOUT) { @@ -53,7 +37,24 @@ my $fh; my @testitems = (@Support::Files::testitems, @Support::Files::test_files); -# at last, here we actually run the test... +#add the words to check here: +my @evilwords = qw( + anyways + appearence + arbitary + cancelled + critera + databasa + dependan + existance + existant + paramater + refered + repsentation + suported + varsion +); + my $evilwordsregexp = join('|', @evilwords); foreach my $file (@testitems) { diff --git a/mozilla/webtools/bugzilla/t/007util.t b/mozilla/webtools/bugzilla/t/007util.t index 495102ffa9d..66c2df032fb 100644 --- a/mozilla/webtools/bugzilla/t/007util.t +++ b/mozilla/webtools/bugzilla/t/007util.t @@ -9,14 +9,18 @@ #Bugzilla Test 7# #####Util.pm##### +use 5.10.1; +use strict; +use warnings; + use lib 't'; use Support::Files; use Test::More tests => 17; use DateTime; BEGIN { - use_ok(Bugzilla); - use_ok(Bugzilla::Util); + use_ok('Bugzilla'); + use_ok('Bugzilla::Util'); } # We need to override user preferences so we can get an expected value when diff --git a/mozilla/webtools/bugzilla/t/008filter.t b/mozilla/webtools/bugzilla/t/008filter.t index 9551ae2b246..204bbdc43dc 100644 --- a/mozilla/webtools/bugzilla/t/008filter.t +++ b/mozilla/webtools/bugzilla/t/008filter.t @@ -15,10 +15,11 @@ # Sample exploit code: '>"> +use 5.10.1; use strict; -use lib qw(. lib t); +use warnings; -use vars qw(%safe); +use lib qw(. lib t); use Bugzilla::Constants; use Support::Templates; @@ -30,6 +31,7 @@ use Cwd; my $oldrecsep = $/; my $topdir = cwd; $/ = undef; +our %safe; foreach my $path (@Support::Templates::include_paths) { $path =~ s|\\|/|g if ON_WINDOWS; # convert \ to / in path if on windows @@ -84,9 +86,9 @@ foreach my $path (@Support::Templates::include_paths) { ok(1, "($lang/$flavor) $file is filter-safe"); next; } - + # Read the entire file into a string - open (FILE, "<$file") || die "Can't open $file: $!\n"; + open (FILE, "<$file") || die "Can't open $file: $!\n"; my $slurp = ; close (FILE); @@ -210,7 +212,7 @@ sub directive_ok { return 1 if $directive =~ /FILTER\ (html|csv|js|base64|css_class_quote|ics| quoteUrls|time|uri|xml|lower|html_light| obsolete|inactive|closed|unitconvert| - txt|html_linebreak|none)\b/x; + txt|html_linebreak|markdown|none)\b/x; return 0; } diff --git a/mozilla/webtools/bugzilla/t/009bugwords.t b/mozilla/webtools/bugzilla/t/009bugwords.t index 988f747f287..e36651edb2a 100644 --- a/mozilla/webtools/bugzilla/t/009bugwords.t +++ b/mozilla/webtools/bugzilla/t/009bugwords.t @@ -15,7 +15,9 @@ # "[% terms.bug %]". This test makes sure the relevant words aren't used # bare. +use 5.10.1; use strict; +use warnings; use lib 't'; diff --git a/mozilla/webtools/bugzilla/t/010dependencies.t b/mozilla/webtools/bugzilla/t/010dependencies.t index 89a26ba5efa..afd29a652b7 100644 --- a/mozilla/webtools/bugzilla/t/010dependencies.t +++ b/mozilla/webtools/bugzilla/t/010dependencies.t @@ -10,7 +10,10 @@ #Bugzilla Test 10# ## dependencies ## +use 5.10.1; use strict; +use warnings; + use lib qw(. lib t); use Support::Files; diff --git a/mozilla/webtools/bugzilla/t/011pod.t b/mozilla/webtools/bugzilla/t/011pod.t index c3ec39898de..8620b94d595 100644 --- a/mozilla/webtools/bugzilla/t/011pod.t +++ b/mozilla/webtools/bugzilla/t/011pod.t @@ -10,7 +10,9 @@ #Bugzilla Test 11# ##POD validation## +use 5.10.1; use strict; +use warnings; use lib 't'; @@ -32,6 +34,7 @@ use constant SUB_WHITELIST => ( 'Bugzilla::FlagType' => qr/^sqlify_criteria$/, 'Bugzilla::JobQueue' => qr/(?:^work_once|work_until_done|subprocess_worker)$/, 'Bugzilla::Search' => qr/^SPECIAL_PARSING$/, + 'Bugzilla::Template' => qr/^field_name$/, ); # These modules do not need to be documented, generally because they @@ -45,13 +48,14 @@ use constant MODULE_WHITELIST => qw( Bugzilla::Config:: Bugzilla::Extension:: Bugzilla::Job:: + Bugzilla::Migrate:: ); # Capture the TESTOUT from Test::More or Test::Builder for printing errors. # This will handle verbosity for us automatically. my $fh; { - local $^W = 0; # Don't complain about non-existent filehandles + no warnings qw(unopened); # Don't complain about non-existent filehandles if (-e \*Test::More::TESTOUT) { $fh = \*Test::More::TESTOUT; } elsif (-e \*Test::Builder::TESTOUT) { diff --git a/mozilla/webtools/bugzilla/t/012throwables.t b/mozilla/webtools/bugzilla/t/012throwables.t index 7600cbd02fc..0ef043fa5f6 100644 --- a/mozilla/webtools/bugzilla/t/012throwables.t +++ b/mozilla/webtools/bugzilla/t/012throwables.t @@ -11,7 +11,10 @@ #Bugzilla Test 12# ######Errors###### +use 5.10.1; use strict; +use warnings; + use lib qw(. lib t); use Bugzilla::Constants; diff --git a/mozilla/webtools/bugzilla/t/013dbschema.t b/mozilla/webtools/bugzilla/t/013dbschema.t index c1f9c7f0cf1..217176ff202 100644 --- a/mozilla/webtools/bugzilla/t/013dbschema.t +++ b/mozilla/webtools/bugzilla/t/013dbschema.t @@ -12,7 +12,10 @@ # Check the Bugzilla database schema to ensure no field names conflict # with SQL reserved words. +use 5.10.1; use strict; +use warnings; + use lib qw(. t lib); use Bugzilla; use Bugzilla::DB::Schema; diff --git a/mozilla/webtools/bugzilla/t/Support/Files.pm b/mozilla/webtools/bugzilla/t/Support/Files.pm index 330a473b1ff..85fa9f5839d 100644 --- a/mozilla/webtools/bugzilla/t/Support/Files.pm +++ b/mozilla/webtools/bugzilla/t/Support/Files.pm @@ -8,15 +8,19 @@ package Support::Files; +use 5.10.1; +use strict; +use warnings; + use File::Find; -@additional_files = (); +our @additional_files = (); -@files = glob('*'); +our @files = glob('*'); find(sub { push(@files, $File::Find::name) if $_ =~ /\.pm$/;}, 'Bugzilla'); push(@files, 'extensions/create.pl'); -@extensions = +our @extensions = grep { $_ ne 'extensions/create.pl' && ! -e "$_/disabled" } glob('extensions/*'); @@ -24,7 +28,7 @@ foreach my $extension (@extensions) { find(sub { push(@files, $File::Find::name) if $_ =~ /\.pm$/;}, $extension); } -@test_files = glob('t/*.t'); +our @test_files = glob('t/*.t'); sub isTestingFile { my ($file) = @_; @@ -40,9 +44,11 @@ sub isTestingFile { return undef; } -foreach $currentfile (@files) { +our (@testitems, @module_files); + +foreach my $currentfile (@files) { if (isTestingFile($currentfile)) { - push(@testitems,$currentfile); + push(@testitems, $currentfile); } push(@module_files, $currentfile) if $currentfile =~ /\.pm$/; } diff --git a/mozilla/webtools/bugzilla/t/Support/Systemexec.pm b/mozilla/webtools/bugzilla/t/Support/Systemexec.pm index 620cce25e66..65be229e3c5 100644 --- a/mozilla/webtools/bugzilla/t/Support/Systemexec.pm +++ b/mozilla/webtools/bugzilla/t/Support/Systemexec.pm @@ -6,6 +6,11 @@ # defined by the Mozilla Public License, v. 2.0. package Support::Systemexec; + +use 5.10.1; +use strict; +use warnings; + require Exporter; @ISA = qw(Exporter); @EXPORT = qw(system exec); diff --git a/mozilla/webtools/bugzilla/t/Support/Templates.pm b/mozilla/webtools/bugzilla/t/Support/Templates.pm index 2185d687f9f..d17c7334b74 100644 --- a/mozilla/webtools/bugzilla/t/Support/Templates.pm +++ b/mozilla/webtools/bugzilla/t/Support/Templates.pm @@ -7,15 +7,15 @@ package Support::Templates; +use 5.10.1; use strict; +use warnings; use lib 't'; use parent qw(Exporter); -@Support::Templates::EXPORT = - qw(@languages @include_paths @english_default_include_paths - %include_path @referenced_files %actual_files $num_actual_files); -use vars qw(@languages @include_paths @english_default_include_paths - %include_path @referenced_files %actual_files $num_actual_files); +@Support::Templates::EXPORT = + qw(@languages @include_paths @english_default_include_paths + @referenced_files %actual_files $num_actual_files); use Bugzilla; use Bugzilla::Constants; @@ -25,18 +25,9 @@ use Support::Files; use File::Find; use File::Spec; -# The available template languages -@languages = (); - -# The colon separated includepath per language -%include_path = (); - -# All include paths -@include_paths = (); - # English default include paths -push @english_default_include_paths, - File::Spec->catdir(bz_locations()->{'templatedir'}, 'en', 'default'); +our @english_default_include_paths = + (File::Spec->catdir(bz_locations()->{'templatedir'}, 'en', 'default')); # And the extensions too foreach my $extension (@Support::Files::extensions) { @@ -47,19 +38,19 @@ foreach my $extension (@Support::Files::extensions) { } # Files which are referenced in the cgi files -@referenced_files = (); +our @referenced_files = (); # All files sorted by include_path -%actual_files = (); +our %actual_files = (); # total number of actual_files -$num_actual_files = 0; +our $num_actual_files = 0; # Set the template available languages and include paths -@languages = @{ Bugzilla->languages }; -@include_paths = @{ template_include_path({ language => Bugzilla->languages }) }; +our @languages = @{ Bugzilla->languages }; +our @include_paths = @{ template_include_path({ language => Bugzilla->languages }) }; -my @files; +our @files; # Local subroutine used with File::Find sub find_templates { diff --git a/mozilla/webtools/bugzilla/template/en/default/account/auth/login-small.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/account/auth/login-small.html.tmpl index 5868b867119..790c135bfae 100644 --- a/mozilla/webtools/bugzilla/template/en/default/account/auth/login-small.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/account/auth/login-small.html.tmpl @@ -9,6 +9,9 @@ [%# Use the current script name. If an empty name is returned, # then we are accessing the home page. %] +[% USE Bugzilla %] +[% cgi = Bugzilla.cgi %] + [% login_target = cgi.url("-relative" => 1, "-query" => 1) %] [% IF !login_target OR login_target.match("^token.cgi") %] [% login_target = "index.cgi" %] diff --git a/mozilla/webtools/bugzilla/template/en/default/account/prefs/apikey.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/account/prefs/apikey.html.tmpl new file mode 100644 index 00000000000..bed3f380980 --- /dev/null +++ b/mozilla/webtools/bugzilla/template/en/default/account/prefs/apikey.html.tmpl @@ -0,0 +1,84 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[%# INTERFACE: + # api_keys: array. Array of api keys this user has. + # any_revoked: boolean. True is any keys have been revoked. + #%] + +

+ API keys are used to authenticate WebService API calls. You can create more than + one API key if required. Each API key has an optional description which can help + you record what each key is used for. Documentation on how to log in is + available from + here. +

+ +

Existing API keys

+ +

You can update the description, and revoke or unrevoke existing API keys +here.

+ + + + + + + + + + [% FOREACH api_key IN api_keys %] + + + + [% IF api_key.last_used %] + + [% ELSE %] + + [% END %] + + + [% END %] + [% UNLESS api_keys.size %] + + [% END %] +
API keyDescription (optional)Last usedRevoked
[% api_key.api_key FILTER html %] + + [% api_key.last_used FILTER time %]never used + +
You don't have any API keys.
+ +[% IF any_revoked %] + Hide Revoked Keys + [%# Show the link if the browser supports JS %] + +[% END %] + +

New API key

+ +

You can generate a new API key by ticking the check box below and optionally +providing a description for the API key. The API key will be randomly +generated for you.

+ +

+ + Generate a new API key with optional description + +

+ diff --git a/mozilla/webtools/bugzilla/template/en/default/account/prefs/prefs.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/account/prefs/prefs.html.tmpl index faa18d58194..8f11d0a6ff8 100644 --- a/mozilla/webtools/bugzilla/template/en/default/account/prefs/prefs.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/account/prefs/prefs.html.tmpl @@ -36,6 +36,9 @@ { name => "account", label => "Account Information", link => "userprefs.cgi?tab=account", saveable => "1", doc_section => "using.html#account-information" }, + { name => "apikey", label => "API Keys", + link => "userprefs.cgi?tab=apikey", saveable => "1", + doc_section => "using.html#apikey" }, { name => "permissions", label => "Permissions", link => "userprefs.cgi?tab=permissions", saveable => "0", doc_section => "using.html#permissions" } ] %] @@ -53,7 +56,7 @@ title = current_tab.label subheader = filtered_login style_urls = ['skins/standard/admin.css'] - javascript_urls = ['js/util.js', 'js/field.js'] + javascript_urls = ['js/util.js', 'js/field.js', 'js/TUI.js'] doc_section = current_tab.doc_section yui = ['autocomplete'] %] diff --git a/mozilla/webtools/bugzilla/template/en/default/admin/groups/list.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/admin/groups/list.html.tmpl index 7a15703dfa6..29e39f65fc6 100644 --- a/mozilla/webtools/bugzilla/template/en/default/admin/groups/list.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/admin/groups/list.html.tmpl @@ -75,7 +75,8 @@ } %] -[% FOREACH group IN ["chartgroup", "insidergroup", "timetrackinggroup", "querysharegroup"] %] +[% FOREACH group IN ["chartgroup", "comment_taggers_group", "debug_group", + "insidergroup", "querysharegroup", "timetrackinggroup"] %] [% special_group = Param(group) %] [% IF special_group %] diff --git a/mozilla/webtools/bugzilla/template/en/default/admin/params/attachment.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/admin/params/attachment.html.tmpl index 5efcc11067c..c850802ab95 100644 --- a/mozilla/webtools/bugzilla/template/en/default/admin/params/attachment.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/admin/params/attachment.html.tmpl @@ -58,5 +58,31 @@ maxlocalattachment => "The maximum size (in megabytes) of attachments to be stored " _ "locally on the web server. If set to a value lower than the " _ "maxattachmentsize parameter, " _ - "attachments will never be kept on the local filesystem." } + "attachments will never be kept on the local filesystem. " _ + "If you want to store all attachments on disk rather than in the " _ + "database, then set " _ + "maxattachmentsize parameter to 0. ", + + + xsendfile_header => + "By default, attachments are served by the CGI script. " _ + "If you enable filesystem file storage for large files using the " _ + "maxlocalattachment parameter " _ + "then you can have those files served directly by the webserver, which " _ + "avoids copying them entirely into memory, and this may result in a " _ + "performance improvement. To do this, configure your webserver appropriately " _ + "and then set the correct header, as follows:" _ + "
" _ + "Please note that attachments stored in the database cannot be offloaded " _ + "to apache/nginx/lighttpd and are always handled by the CGI script." + + } + %] diff --git a/mozilla/webtools/bugzilla/template/en/default/admin/params/auth.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/admin/params/auth.html.tmpl index bf8539b873e..902d2fc826b 100644 --- a/mozilla/webtools/bugzilla/template/en/default/admin/params/auth.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/admin/params/auth.html.tmpl @@ -133,5 +133,11 @@ "lower case letter and a number." _ "
  • letters_numbers_specialchars - Passwords must contain at least one " _ "letter, a number and a special character.
  • " + + password_check_on_login => + "If set, $terms.Bugzilla will check that the password meets the current " _ + "complexity rules and minimum length requirements when the user logs " _ + "into the $terms.Bugzilla web interface. If it doesn't, the user would " _ + "not be able to log in, and recieve a message to reset their password." } %] diff --git a/mozilla/webtools/bugzilla/template/en/default/admin/params/mta.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/admin/params/mta.html.tmpl index 4aee7090ddb..bd93a3ee919 100644 --- a/mozilla/webtools/bugzilla/template/en/default/admin/params/mta.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/admin/params/mta.html.tmpl @@ -14,7 +14,12 @@ mail_delivery_method => "Defines how email is sent, or if it is sent at all.
    • - 'Sendmail', 'SMTP' and 'Qmail' are all MTAs. + 'SMTP' means use the SMTP protocol to talk to a remote + mail server. +
    • +
    • + 'Sendmail' means use the sendmail-compatible MTA + installed on the Bugzilla machine. You need to install a third-party sendmail replacement if you want to use sendmail on Windows.
    • @@ -23,7 +28,7 @@ in 'data/mailer.testfile' instead of being sent.
    • - 'none' will completely disable email. Bugzilla continues + 'None' will completely disable email. Bugzilla continues to act as though it is sending mail, but nothing is sent or stored.
    • @@ -42,7 +47,8 @@ _ " won't get sent). This affects all mail sent by Bugzilla," _ " not just $terms.bug updates.", - smtpserver => "The SMTP server address (if using SMTP for mail delivery).", + smtpserver => "The SMTP server address with optional port number (if using SMTP" _ + " for mail delivery). eg: example.com or example.com:1234", smtp_username => "The username to pass to the SMTP server for SMTP authentication. " _ "Leave this field empty if your SMTP server doesn't require authentication.", diff --git a/mozilla/webtools/bugzilla/template/en/default/admin/params/patchviewer.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/admin/params/patchviewer.html.tmpl deleted file mode 100644 index d8aabd4bae5..00000000000 --- a/mozilla/webtools/bugzilla/template/en/default/admin/params/patchviewer.html.tmpl +++ /dev/null @@ -1,51 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] -[% - title = "Patch Viewer" - desc = "Set up third-party applications to run with PatchViewer" -%] - -[% param_descs = { - cvsroot => "The CVS root that most " _ - "users of your system will be using for 'cvs diff'. Used in " _ - "Patch Viewer ('Diff' option on patches) to figure out where " _ - "patches are rooted even if users did the 'cvs diff' from " _ - "different places in the directory structure. (NOTE: if your " _ - "CVS repository is remote and requires a password, you must " _ - "either ensure the $terms.Bugzilla user has done a 'cvs login' or " _ - "specify the password " _ - "as " _ - "part of the CVS root.) Leave this blank if you have no " _ - "CVS repository.", - - cvsroot_get => "The CVS root Bugzilla will be using to get patches from. " _ - "Some installations may want to mirror their CVS repository on " _ - "the Bugzilla server or even have it on that same server, and " _ - "thus the repository can be the local file system (and much " _ - "faster). Make this the same as cvsroot if you don't " _ - "understand what this is (if cvsroot is blank, make this blank too).", - - bonsai_url => "The URL to a Bonsai " _ - "server containing information about your CVS repository. " _ - "Patch Viewer will use this information to create links to " _ - "bonsai's blame for each section of a patch (it will append " _ - "'/cvsblame.cgi?...' to this url). Leave this blank if you " _ - "don't understand what this is.", - - lxr_url => "The URL to an LXR server " _ - "that indexes your CVS repository. Patch Viewer will use this " _ - "information to create links to LXR for each file in a patch. " _ - "Leave this blank if you don't understand what this is.", - - lxr_root => "Some LXR installations do not index the CVS repository from the root -- " _ - "Mozilla's, for " _ - "example, starts indexing under mozilla/. This " _ - "means URLs are relative to that extra path under the root. " _ - "Enter this if you have a similar situation. Leave it blank " _ - "if you don't know what this is." } -%] diff --git a/mozilla/webtools/bugzilla/template/en/default/admin/products/edit.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/admin/products/edit.html.tmpl index 21689d9a7ff..8e1f5d87bb4 100644 --- a/mozilla/webtools/bugzilla/template/en/default/admin/products/edit.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/admin/products/edit.html.tmpl @@ -42,11 +42,11 @@ [% IF product.components.size -%] - [% FOREACH component = product.components %] + [% FOREACH comp = product.components %] [% component.name FILTER html %]: - [% component.description FILTER html_light %] + [%- comp.name FILTER uri %]">[% comp.name FILTER html %]: + [% comp.description FILTER html_light %]
      [% END %] [% ELSE %] diff --git a/mozilla/webtools/bugzilla/template/en/default/admin/users/responsibilities.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/admin/users/responsibilities.html.tmpl index c2f6584b9be..23eb9587b54 100644 --- a/mozilla/webtools/bugzilla/template/en/default/admin/users/responsibilities.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/admin/users/responsibilities.html.tmpl @@ -23,26 +23,26 @@ Default QA Contact Default CC - [% FOREACH component = item.components %] + [% FOREACH comp = item.components %] - [% IF user.in_group("editcomponents", component.product_id) %] + [% IF user.in_group("editcomponents", comp.product_id) %] + [% comp.name FILTER uri %]"> [% END %] - [% component.name FILTER html %] - [% IF user.in_group("editcomponents", component.product_id) %] + [% comp.name FILTER html %] + [% IF user.in_group("editcomponents", comp.product_id) %] [% END %] [% FOREACH responsibility = ['default_assignee', 'default_qa_contact'] %] - [% component.$responsibility.id == otheruser.id ? "X" : " " %] + [% comp.$responsibility.id == otheruser.id ? "X" : " " %] [% END %] - [% component.initial_cc.contains(otheruser) ? "X" : " " %] + [% comp.initial_cc.contains(otheruser) ? "X" : " " %] [% END %] diff --git a/mozilla/webtools/bugzilla/template/en/default/attachment/diff-file.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/attachment/diff-file.html.tmpl index 38c51725b32..af99761a6c0 100644 --- a/mozilla/webtools/bugzilla/template/en/default/attachment/diff-file.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/attachment/diff-file.html.tmpl @@ -19,11 +19,7 @@ onclick="return twisty_click(this)">[% collapsed ? '(+)' : '(-)' %] - [% IF lxr_prefix && !file.is_add %] - [% file.filename FILTER html %] - [% ELSE %] - [% file.filename FILTER html %] - [% END %] + [% file.filename FILTER html %] [% IF file.plus_lines %] [% IF file.minus_lines %] (-[% file.minus_lines %] / +[% file.plus_lines %] lines) @@ -49,23 +45,13 @@ incremental_restore() [% IF file.is_add %] Added [% ELSIF file.is_remove %] - [% IF bonsai_prefix %] - Removed - [% ELSE %] - Removed - [% END %] + Removed [% ELSE %] - [% IF bonsai_prefix %] - - [% END %] [% IF section.old_lines > 1 %] Lines [% section.old_start %]-[% section.old_start + section.old_lines - 1 %] [% ELSE %] Line [% section.old_start %] [% END %] - [% IF bonsai_prefix %] - - [% END %] [%+ section.func_info FILTER html IF section.func_info %] [% END %] diff --git a/mozilla/webtools/bugzilla/template/en/default/attachment/diff-header.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/attachment/diff-header.html.tmpl index 94d2b9541be..2a32de974b5 100644 --- a/mozilla/webtools/bugzilla/template/en/default/attachment/diff-header.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/attachment/diff-header.html.tmpl @@ -38,7 +38,7 @@ Interdiff of #[% oldid %] and #[% newid %] for [% terms.bug %] #[% bugid %] [% bugsummary FILTER html %] [% END %] [% PROCESS global/header.html.tmpl doc_section = "using.html#patch-viewer" - javascript_urls = "js/attachment.js" + javascript_urls = [ "js/attachment.js" ] style_urls = ['skins/standard/bug.css'] %] [% ELSE %] @@ -60,8 +60,7 @@ Interdiff of #[% oldid %] and #[% newid %] for [% terms.bug %] #[% bugid %] [% IF headers %] View | Details - | Raw Unified | Return to [% "$terms.bug $bugid" FILTER bug_link(bugid) FILTER none %] [% END %] @@ -102,33 +101,6 @@ Interdiff of #[% oldid %] and #[% newid %] for [% terms.bug %] #[% bugid %] onmouseout="window.status = lastStatus; return true" onclick="return expand_all()">Expand All -[% IF do_context %] - [%# only happens for normal viewing, not interdiff %] - | Context: - [% IF context == "patch" %] - (Patch / - [% ELSE %] - (Patch / - [% END %] - [% IF context == "file" %] - File / - [% ELSE %] - File / - [% END %] - - [% IF context == "patch" || context == "file" %] - [% context = 3 %] - [% END %] - [%# textbox for context %] -
      - - - - - -
      ) -[% END %] - [% IF warning %]

      Warning: diff --git a/mozilla/webtools/bugzilla/template/en/default/bug/comment.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/bug/comment.html.tmpl index 96cbb63ed1f..76054f92ab2 100644 --- a/mozilla/webtools/bugzilla/template/en/default/bug/comment.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/bug/comment.html.tmpl @@ -32,6 +32,16 @@
      Generating Preview...
      -
      
      +    
      +
      +[% END %] + +[% IF user.use_markdown %] +
      + + + (help)
      [% END %] diff --git a/mozilla/webtools/bugzilla/template/en/default/bug/comments.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/bug/comments.html.tmpl index d040e651d1c..3895691d75d 100644 --- a/mozilla/webtools/bugzilla/template/en/default/bug/comments.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/bug/comments.html.tmpl @@ -14,13 +14,16 @@ @@ -126,7 +162,13 @@ [% END %] [reply] [% END %] @@ -225,12 +267,12 @@ [%# Don't indent the
       block, since then the spaces are displayed in the
         # generated HTML
         #%]
      -
      -  [%- comment_text FILTER quoteUrls(bug, comment) -%]
      -
      + [%- comment_text FILTER markdown(bug, comment) -%] + [% Hook.process('a_comment-end', 'bug/comments.html.tmpl') %] [% END %] diff --git a/mozilla/webtools/bugzilla/template/en/default/bug/edit.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/bug/edit.html.tmpl index f7cb57fd83f..a7674faf856 100644 --- a/mozilla/webtools/bugzilla/template/en/default/bug/edit.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/bug/edit.html.tmpl @@ -29,6 +29,13 @@ YAHOO.bugzilla.commentTagging.init([% user.can_tag_comments ? 'true' : 'false' %]); YAHOO.bugzilla.commentTagging.min_len = [% constants.MIN_COMMENT_TAG_LENGTH FILTER js %]; YAHOO.bugzilla.commentTagging.max_len = [% constants.MAX_COMMENT_TAG_LENGTH FILTER js %]; + YAHOO.bugzilla.commentTagging.label = 'Comment Tags:'; + YAHOO.bugzilla.commentTagging.min_len_error = + 'Comment tags must be at least + [%~ " " _ constants.MIN_COMMENT_TAG_LENGTH FILTER js %] characters.'; + YAHOO.bugzilla.commentTagging.max_len_error = + 'Comment tags cannot be longer than + [%~ " " _ constants.MAX_COMMENT_TAG_LENGTH FILTER js %] characters.'; [% END %] [% END %] @@ -66,9 +73,13 @@ [%# *** ID, product, component, status, resolution, Hardware, and OS *** %] [% PROCESS section_status %] - + [% PROCESS section_spacer %] - + + [% PROCESS section_aliases %] + + [% PROCESS section_spacer %] + [% PROCESS section_details1 %] [% PROCESS section_spacer %] @@ -173,61 +184,37 @@ [% BLOCK section_title %] [%# That's the main table, which contains all editable fields. %] -
      +
      [% PROCESS commit_button id="_top"%] [%-# %][% terms.Bug %] [% bug.bug_id FILTER html %] - [%-# %] - [% IF bug.alias != "" %] - ([% bug.alias FILTER html %]) + [%-# %] + [% IF bug.alias.size > 0 %] + ([% bug.alias.join(', ') FILTER html %]) [% END %] - [% bug.short_desc FILTER quoteUrls(bug) %] - [% IF bug.check_can_change_field('short_desc', 0, 1) || - bug.check_can_change_field('alias', 0, 1) %] - (edit) + [% IF bug.check_can_change_field('short_desc', 0, 1) %] + (edit) [% END %] - - -
      -
      - - [% IF bug.check_can_change_field('alias', 0, 1) %] - [% INCLUDE "bug/field-label.html.tmpl" - field = bug_fields.alias - editable = 1 - %] - - - [%# *** Summary *** %] - - [% INCLUDE "bug/field-label.html.tmpl" - field = bug_fields.short_desc - editable = 1 - accesskey = "s" - %] - - -
      - [% ELSIF bug.alias %] - ( - [% ELSE %] - - [% END %] - [% PROCESS input inputname => "alias" - size => "20" - maxlength => "20" - no_td => 1 - %][% ")" IF NOT bug.check_can_change_field('alias', 0, 1) - && bug.alias %] -
      - [% PROCESS input inputname => "short_desc" size => "80" colspan => 2 - maxlength => 255 spellcheck => "true" no_td => 1 %] -
      + +
      + [% INCLUDE "bug/field-label.html.tmpl" + field = bug_fields.short_desc + editable = 1 + accesskey = "s" + tag_name = 'span' + %] + [% PROCESS input inputname => "short_desc" size => "80" + maxlength => 255 spellcheck => "true" no_td => 1 %]
      [% END %] @@ -572,7 +559,7 @@ [% RETURN UNLESS bug.duplicates.size %] - : + : @@ -867,6 +854,56 @@ [% END %] [% END %] +[% BLOCK section_aliases %] + + [% INCLUDE "bug/field-label.html.tmpl" + field = bug_fields.alias, editable = 1 + %] + + [% IF bug.alias.size %] + [% bug.alias.join(', ') FILTER html %] + [% ELSE %] + None + [% END %] + [% IF bug.check_can_change_field('alias', 0, 1) %] + + (edit) + +
      +
      +
      +
      + +
      + +
      + [% IF bug.alias.size %] + +
      + + + + + [% END %] +
      + + [% END %] + + +[% END %] + [%############################################################################%] [%# Block for FLAGS #%] [%############################################################################%] @@ -1157,7 +1194,6 @@ + diff --git a/mozilla/webtools/bugzilla/template/en/default/bug/show-header.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/bug/show-header.html.tmpl index 6dfc19dfb8b..6e1244fa0cf 100644 --- a/mozilla/webtools/bugzilla/template/en/default/bug/show-header.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/bug/show-header.html.tmpl @@ -13,13 +13,13 @@ # be overridden by the calling templates. #%] -[% filtered_alias = bug.alias FILTER html %] +[% filtered_alias = bug.alias.join(', ') FILTER html %] [% filtered_desc = bug.short_desc FILTER html %] [% filtered_timestamp = bug.delta_ts FILTER time %] [% subheader = filtered_desc %] [% title = "$bug.bug_id – " %] -[% IF bug.alias != '' %] +[% IF bug.alias.size %] [% title = title _ "($filtered_alias) " %] [% END %] [% title = title _ filtered_desc %] @@ -33,8 +33,8 @@ [% header = "$terms.Bug $bug.bug_id" %] [% header_addl_info = "Last modified: $filtered_timestamp" %] [% unfiltered_title = "$bug.bug_id – " %] - [% IF bug.alias != '' %] - [% unfiltered_title = unfiltered_title _ "($bug.alias) " %] + [% IF bug.alias.size %] + [% unfiltered_title = unfiltered_title _ "(" _ bug.alias.join(', ') _ ") " %] [% END %] [% unfiltered_title = unfiltered_title _ bug.short_desc %] [% javascript = BLOCK %] diff --git a/mozilla/webtools/bugzilla/template/en/default/bug/show-multiple.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/bug/show-multiple.html.tmpl index e098602011f..960746d404e 100644 --- a/mozilla/webtools/bugzilla/template/en/default/bug/show-multiple.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/bug/show-multiple.html.tmpl @@ -48,9 +48,10 @@

      [% terms.Bug %] [% bug.bug_id FILTER html %] - [% IF bug.alias AND NOT bug.error %] - ( - [% bug.alias FILTER html %]) + [% IF bug.alias AND NOT bug.error %] ( + [%- FOREACH alias IN bug.alias %] + [% alias FILTER html %][% UNLESS loop.last %], [% END %] + [%- END %]) [% END %]

      diff --git a/mozilla/webtools/bugzilla/template/en/default/config.rdf.tmpl b/mozilla/webtools/bugzilla/template/en/default/config.rdf.tmpl index b14d0d05671..0d183cf5674 100644 --- a/mozilla/webtools/bugzilla/template/en/default/config.rdf.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/config.rdf.tmpl @@ -139,8 +139,8 @@ [% END %] - [% FOREACH component = product.components %] -
    • [% END %] @@ -176,16 +176,16 @@ [% FOREACH product = products %] - [% FOREACH component = product.components %] + [% FOREACH comp = product.components %]
    • - - [% component.name FILTER html %] - [% component.is_active FILTER html %] + [% comp.name FILTER html %] + [% comp.is_active FILTER html %] [% IF show_flags %] - [% flag_types = component.flag_types.bug.merge(component.flag_types.attachment) %] + [% flag_types = comp.flag_types.bug.merge(comp.flag_types.attachment) %] [% FOREACH flag_type = flag_types %] [% NEXT UNLESS flag_type.is_active %] [% all_visible_flag_types.${flag_type.id} = flag_type %] diff --git a/mozilla/webtools/bugzilla/template/en/default/email/bugmail.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/email/bugmail.html.tmpl index 9473a4459e8..b0f4efb45cf 100644 --- a/mozilla/webtools/bugzilla/template/en/default/email/bugmail.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/email/bugmail.html.tmpl @@ -25,7 +25,7 @@ on [% "$terms.bug $bug.id" FILTER bug_link(bug, { full_url => 1, user => to_user }) FILTER none %] from [% INCLUDE global/user.html.tmpl user = to_user, who = comment.author %] [% END %] -
      [% comment.body_full({ wrap => 1 }) FILTER quoteUrls(bug, comment, to_user) %]
      +
      [% comment.body_full({ wrap => 1 }) FILTER markdown(bug, comment, to_user) %]
      [% END %]

      diff --git a/mozilla/webtools/bugzilla/template/en/default/email/flagmail.txt.tmpl b/mozilla/webtools/bugzilla/template/en/default/email/flagmail.txt.tmpl index d0e1395e2a8..cf64d966135 100644 --- a/mozilla/webtools/bugzilla/template/en/default/email/flagmail.txt.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/email/flagmail.txt.tmpl @@ -68,11 +68,14 @@ Attachment [% attidsummary %] [%- FILTER bullet = wrap(80) %] -[% USE Bugzilla %] -[%-# .defined is necessary to avoid a taint issue, see bug 509794. %] -[% IF Bugzilla.cgi.param("comment").defined && Bugzilla.cgi.param("comment").length > 0 %] -------- Additional Comments from [% user.identity %] -[%+ Bugzilla.cgi.param("comment") FILTER strip_control_chars %] +[% FOREACH comment = new_comments %] + +[%- IF comment.count %] +--- Comment #[% comment.count %] from [% comment.author.identity %] --- +[% ELSE %] +--- Description --- +[% END %] +[%+ comment.body_full({ is_bugmail => 1, wrap => 1 }) FILTER strip_control_chars %] [% END %] [%- END %] diff --git a/mozilla/webtools/bugzilla/template/en/default/email/new-api-key.txt.tmpl b/mozilla/webtools/bugzilla/template/en/default/email/new-api-key.txt.tmpl new file mode 100644 index 00000000000..cfccefdcca3 --- /dev/null +++ b/mozilla/webtools/bugzilla/template/en/default/email/new-api-key.txt.tmpl @@ -0,0 +1,33 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[%# INTERFACE: + # user: The Bugzilla::User object of the user being created + # new_key: The API key created + #%] + +From: [% Param('mailfrom') %] +To: [% user.email %] +Subject: [% terms.Bugzilla %]: New API key created +X-Bugzilla-Type: admin + +[This e-mail has been automatically generated] + +A new [% terms.Bugzilla %] API key[% IF new_key.description %], with the +description '[% new_key.description %]'[% END %] has been created. You can view +or update the key at the following URL: + +[%+ urlbase %]userprefs.cgi?tab=apikey + +IMPORTANT: If you did not request a new key, your [% terms.Bugzilla %] account +may have been compromised. In this case, please disable the key at the above +URL, and change your password immediately. + +For security reasons, we have not included your new key in this e-mail. + +If you have any issues regarding your account, please contact [% Param('maintainer') %]. diff --git a/mozilla/webtools/bugzilla/template/en/default/extensions/config.pm.tmpl b/mozilla/webtools/bugzilla/template/en/default/extensions/config.pm.tmpl index 79fbb995cc0..68ed260c1ff 100644 --- a/mozilla/webtools/bugzilla/template/en/default/extensions/config.pm.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/extensions/config.pm.tmpl @@ -16,6 +16,7 @@ package Bugzilla::Extension::[% name %]; use 5.10.1; use strict; +use warnings; use constant NAME => '[% name %]'; diff --git a/mozilla/webtools/bugzilla/template/en/default/extensions/extension.pm.tmpl b/mozilla/webtools/bugzilla/template/en/default/extensions/extension.pm.tmpl index 637dfdd28d8..823440421e5 100644 --- a/mozilla/webtools/bugzilla/template/en/default/extensions/extension.pm.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/extensions/extension.pm.tmpl @@ -16,6 +16,8 @@ package Bugzilla::Extension::[% name %]; use 5.10.1; use strict; +use warnings; + use parent qw(Bugzilla::Extension); # This code for this is in [% path %]/lib/Util.pm diff --git a/mozilla/webtools/bugzilla/template/en/default/extensions/util.pm.tmpl b/mozilla/webtools/bugzilla/template/en/default/extensions/util.pm.tmpl index a5fbde04d97..3baab57fd07 100644 --- a/mozilla/webtools/bugzilla/template/en/default/extensions/util.pm.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/extensions/util.pm.tmpl @@ -16,6 +16,8 @@ package Bugzilla::Extension::[% name %]::Util; use 5.10.1; use strict; +use warnings; + use parent qw(Exporter); our @EXPORT = qw( diff --git a/mozilla/webtools/bugzilla/template/en/default/filterexceptions.pl b/mozilla/webtools/bugzilla/template/en/default/filterexceptions.pl index 3ad9f685fcf..f5f1bd7836a 100644 --- a/mozilla/webtools/bugzilla/template/en/default/filterexceptions.pl +++ b/mozilla/webtools/bugzilla/template/en/default/filterexceptions.pl @@ -20,7 +20,7 @@ # [% foo.push() %] # TT loop variables - [% loop.count %] # Already-filtered stuff - [% wibble FILTER html %] -# where the filter is one of html|csv|js|quoteUrls|time|uri|xml|none +# where the filter is one of html|csv|js|quoteUrls|time|uri|xml|markdown|none %::safe = ( @@ -167,7 +167,6 @@ ], 'global/messages.html.tmpl' => [ - 'message_tag', 'series.frequency * 2', ], @@ -190,10 +189,6 @@ 'script', ], -'global/site-navigation.html.tmpl' => [ - 'bug.bug_id', -], - 'bug/comments.html.tmpl' => [ 'comment.id', 'comment.count', @@ -327,10 +322,8 @@ ], 'attachment/diff-file.html.tmpl' => [ - 'lxr_prefix', 'file.minus_lines', 'file.plus_lines', - 'bonsai_prefix', 'section.old_start', 'section_num', 'current_line_old', diff --git a/mozilla/webtools/bugzilla/template/en/default/flag/list.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/flag/list.html.tmpl index 47406d6c035..7547e5687c5 100644 --- a/mozilla/webtools/bugzilla/template/en/default/flag/list.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/flag/list.html.tmpl @@ -119,6 +119,9 @@ class="flag_select flag_type-[% type.id %]" [% IF !can_edit_flag %] disabled="disabled"[% END %]> [%# Only display statuses the user is allowed to set. %] + [% IF edit_multiple_bugs %] + + [% END %] [% IF !flag || (can_edit_flag && user.can_request_flag(type)) || flag.setter_id == user.id %] [% END %] @@ -168,6 +171,16 @@ [% END %] [% END %] + + [% IF type.is_multiplicable && edit_multiple_bugs %] + + + [% END %] + [% END %] diff --git a/mozilla/webtools/bugzilla/template/en/default/global/choose-classification.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/global/choose-classification.html.tmpl index 815e625a611..8433380ea39 100644 --- a/mozilla/webtools/bugzilla/template/en/default/global/choose-classification.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/global/choose-classification.html.tmpl @@ -19,7 +19,9 @@ [% DEFAULT title = "Choose the classification" %] [% PROCESS global/header.html.tmpl %] -[% previous_params = cgi.canonicalise_query('classification') %] +[% USE Bugzilla %] +[% previous_params = Bugzilla.cgi.canonicalise_query('classification') %] +

      First, you must pick a classification on which to enter [% terms.abug %]:

      diff --git a/mozilla/webtools/bugzilla/template/en/default/global/choose-product.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/global/choose-product.html.tmpl index 5dc619087d7..7349d1ced1f 100644 --- a/mozilla/webtools/bugzilla/template/en/default/global/choose-product.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/global/choose-product.html.tmpl @@ -28,7 +28,9 @@ [% DEFAULT title = "Choose a Product" %] [% PROCESS global/header.html.tmpl %] -[% previous_params = cgi.canonicalise_query('classification', 'product') %] +[% USE Bugzilla %] +[% previous_params = Bugzilla.cgi.canonicalise_query('classification', 'product') %] +

      [% h2 FILTER html %]

      diff --git a/mozilla/webtools/bugzilla/template/en/default/global/header.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/global/header.html.tmpl index e6bd8f45d2a..852d2c85e5c 100644 --- a/mozilla/webtools/bugzilla/template/en/default/global/header.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/global/header.html.tmpl @@ -85,15 +85,19 @@ [% END %] - [% PROCESS "global/site-navigation.html.tmpl" %] - - [% PROCESS 'global/setting-descs.none.tmpl' %] - [% SET yui = yui_resolve_deps(yui, yui_deps) %] [% SET css_sets = css_files(style_urls, yui, yui_css) %] - + [% IF constants.CONCATENATE_ASSETS %] + [% PROCESS format_css_link asset_url = css_sets.unified_standard_skin %] + [% ELSE %] + [% FOREACH asset_url = css_sets.standard %] + [% PROCESS format_css_link %] + [% END %] + [% FOREACH asset_url = css_sets.skin %] + [% PROCESS format_css_link %] + [% END %] + [% END %] [% IF style %]