]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1286290 - CSP compliant bug modal
authorDylan William Hardison <dylan@hardison.net>
Wed, 25 Jan 2017 20:04:07 +0000 (15:04 -0500)
committerDylan William Hardison <dylan@hardison.net>
Wed, 25 Jan 2017 20:04:21 +0000 (15:04 -0500)
29 files changed:
Bugzilla.pm
Bugzilla/CGI.pm
Bugzilla/CGI/ContentSecurityPolicy.pm
Bugzilla/Template.pm
attachment.cgi
extensions/BMO/template/en/default/hook/bug_modal/edit-top_actions.html.tmpl
extensions/BMO/web/js/edituser_menu.js
extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
extensions/BugModal/template/en/default/bug_modal/user.html.tmpl
extensions/BugModal/web/bug_modal.js
extensions/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl
extensions/Needinfo/template/en/default/bug/needinfo.html.tmpl
extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl
extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl
extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl
extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl
index.cgi
js/global.js
post_bug.cgi
process_bug.cgi
show_bug.cgi
template/en/default/account/auth/login-small.html.tmpl
template/en/default/bug/process/bugmail.html.tmpl
template/en/default/global/common-links.html.tmpl
template/en/default/global/header.html.tmpl
template/en/default/global/per-bug-queries.html.tmpl
template/en/default/global/userselect.html.tmpl
template/en/default/index.html.tmpl
template/en/default/pages/quicksearch.html.tmpl

index f563ba9e37f65dfedd2bb4f10b6bb697e58c5c9d..55e4169330697d91d94a0728724f6ee1fa5b289c 100644 (file)
@@ -210,10 +210,13 @@ sub init_page {
 sub template {
     # BMO - use metrics subclass if required
     if (Bugzilla->metrics_enabled) {
-        return $_[0]->request_cache->{template} ||= Bugzilla::Metrics::Template->create();
+        $_[0]->request_cache->{template} ||= Bugzilla::Metrics::Template->create();
     } else {
-        return $_[0]->request_cache->{template} ||= Bugzilla::Template->create();
+        $_[0]->request_cache->{template} ||= Bugzilla::Template->create();
     }
+    $_[0]->request_cache->{template}->{_is_main} = 1;
+
+    return $_[0]->request_cache->{template};
 }
 
 sub template_inner {
index 78987ab711a6a43396312356041f84e2813ce05d..91dec7e7279bb569819575bc435eba5afe6d0e9b 100644 (file)
@@ -33,13 +33,41 @@ BEGIN {
 
 use constant DEFAULT_CSP => (
     default_src => [ 'self' ],
-    script_src  => [ 'self', 'https://login.persona.org', 'unsafe-inline', 'unsafe-eval' ],
-    child_src   => [ 'self', 'https://login.persona.org' ],
+    script_src  => [ 'self', 'unsafe-inline', 'unsafe-eval' ],
+    child_src   => [ 'self', ],
     img_src     => [ 'self', 'https://secure.gravatar.com' ],
     style_src   => [ 'self', 'unsafe-inline' ],
-    disable     => 1,
+    object_src  => [ 'none' ],
+    form_action => [
+        'self',
+        # used in template/en/default/search/search-google.html.tmpl
+        'https://www.google.com/search'
+    ],
+    frame_ancestors => [ 'none' ],
+    disable         => 1,
 );
 
+# Because show_bug code lives in many different .cgi files,
+# we needed a centralized place to define the policy.
+# normally the policy would just live in one .cgi file.
+# Additionally, correct_urlbase() cannot be called at compile time, so this can't be a constant.
+sub SHOW_BUG_MODAL_CSP {
+    return (
+        script_src  => ['self', 'nonce', 'unsafe-inline', 'unsafe-eval' ],
+        object_src  => [correct_urlbase() . "extensions/BugModal/web/ZeroClipboard/ZeroClipboard.swf"],
+        connect_src => [
+            'self',
+            # This is from extensions/OrangeFactor/web/js/orange_factor.js
+            'https://brasstacks.mozilla.com/orangefactor/api/count',
+        ],
+        child_src   => [
+            'self',
+            # This is for the socorro lens addon and is to be removed by Bug 1332016
+            'https://ashughes1.github.io/bugzilla-socorro-lens/chart.htm'
+        ],
+    );
+}
+
 sub _init_bz_cgi_globals {
     my $invocant = shift;
     # We need to disable output buffering - see bug 179174
@@ -143,9 +171,9 @@ sub content_security_policy {
     my ($self, %add_params) = @_;
     if (Bugzilla->has_feature('csp')) {
         require Bugzilla::CGI::ContentSecurityPolicy;
-        return $self->{Bugzilla_csp} if $self->{Bugzilla_csp};
-        my %params = DEFAULT_CSP;
-        if (%add_params) {
+        if (%add_params || !$self->{Bugzilla_csp}) {
+            my %params = DEFAULT_CSP;
+            delete $params{disable} if %add_params && !$add_params{disable};
             foreach my $key (keys %add_params) {
                 if (defined $add_params{$key}) {
                     $params{$key} = $add_params{$key};
@@ -154,8 +182,10 @@ sub content_security_policy {
                     delete $params{$key};
                 }
             }
+            $self->{Bugzilla_csp} = Bugzilla::CGI::ContentSecurityPolicy->new(%params);
         }
-        return $self->{Bugzilla_csp} = Bugzilla::CGI::ContentSecurityPolicy->new(%params);
+
+        return $self->{Bugzilla_csp};
     }
     return undef;
 }
@@ -455,7 +485,7 @@ sub header {
     $headers{'-x_content_type_options'} = 'nosniff';
 
     my $csp = $self->content_security_policy;
-    $csp->add_cgi_headers(\%headers) if defined $csp;
+    $csp->add_cgi_headers(\%headers) if defined $csp && !$csp->disable;
 
     Bugzilla::Hook::process('cgi_headers',
         { cgi => $self, headers => \%headers }
index 74bce6374b83c687a763f614ca922b6062507bca..022d49b44f60296db238110e6472680df036a22d 100644 (file)
@@ -37,6 +37,7 @@ my @ALL_SRC = qw(
     default_src child_src  connect_src
     font_src    img_src    media_src
     object_src  script_src style_src
+    frame_ancestors form_action
 );
 
 has \@ALL_SRC     => ( is => 'ro', isa => $SOURCE_LIST, predicate => 1 );
index eb1496fca8f56c85f982555a0b425a74fa4fbf48..2887f0138897b4d4e308311081f74e5b163482ac 100644 (file)
@@ -1000,6 +1000,11 @@ sub create {
             # Currenly active language
             'current_language' => sub { return Bugzilla->current_language; },
 
+            'script_nonce' => sub {
+                my $cgi = Bugzilla->cgi;
+                return $cgi->csp_nonce ? sprintf('nonce="%s"', $cgi->csp_nonce) : '';
+            },
+
             # If an sudo session is in progress, this is the user who
             # started the session.
             'sudoer' => sub { return Bugzilla->sudoer; },
index d5a69f198057f27bdd284b270e693b066e3ed4a0..d228c9c7f25a070e3458f4eb7eaca5551faa28d3 100755 (executable)
@@ -628,6 +628,14 @@ sub insert {
   my $recipients =  { 'changer' => $user, 'owner' => $owner };
   $vars->{'sent_bugmail'} = Bugzilla::BugMail::Send($bugid, $recipients);
 
+  # BMO: add show_bug_format hook for experimental UI work
+  my $show_bug_format = {};
+  Bugzilla::Hook::process('show_bug_format', $show_bug_format);
+
+  if ($show_bug_format->{format} eq 'modal') {
+      $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+  }
+
   print $cgi->header();
   # Generate and return the UI (HTML page) from the appropriate template.
   $template->process("attachment/created.html.tmpl", $vars)
@@ -784,6 +792,14 @@ sub update {
     $vars->{'sent_bugmail'} = 
         Bugzilla::BugMail::Send($bug->id, { 'changer' => $user });
 
+    # BMO: add show_bug_format hook for experimental UI work
+    my $show_bug_format = {};
+    Bugzilla::Hook::process('show_bug_format', $show_bug_format);
+
+    if ($show_bug_format->{format} eq 'modal') {
+        $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+    }
+
     print $cgi->header();
 
     # Generate and return the UI (HTML page) from the appropriate template.
@@ -796,8 +812,6 @@ sub delete_attachment {
     my $user = Bugzilla->login(LOGIN_REQUIRED);
     my $dbh = Bugzilla->dbh;
 
-    print $cgi->header();
-
     $user->in_group('admin')
       || ThrowUserError('auth_failure', {group  => 'admin',
                                          action => 'delete',
@@ -853,6 +867,15 @@ sub delete_attachment {
         $vars->{'sent_bugmail'} =
             Bugzilla::BugMail::Send($bug->id, { 'changer' => $user });
 
+        # BMO: add show_bug_format hook for experimental UI work
+        my $show_bug_format = {};
+        Bugzilla::Hook::process('show_bug_format', $show_bug_format);
+
+        if ($show_bug_format->{format} eq 'modal') {
+            $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+        }
+
+        print $cgi->header();
         $template->process("attachment/updated.html.tmpl", $vars)
           || ThrowTemplateError($template->error());
     }
@@ -863,6 +886,7 @@ sub delete_attachment {
         $vars->{'a'} = $attachment;
         $vars->{'token'} = $token;
 
+        print $cgi->header();
         $template->process("attachment/confirm-delete.html.tmpl", $vars)
           || ThrowTemplateError($template->error());
     }
index 03c7d2e49746dbb366398cba27272dde66011632..a21e8a44193e4a7c411d8edfe18105f6ab170151 100644 (file)
@@ -16,7 +16,7 @@
     END;
   END;
 %]
-<button type="button" class="minor"
-  onclick="document.location='page.cgi?id=attachment_bounty_form.html&amp;bug_id=[% bug.id FILTER none %]'">
+<button type="button" class="minor button-link"
+  data-href="page.cgi?id=attachment_bounty_form.html&amp;bug_id=[% bug.id FILTER none %]">
   [% has_bounty_attachment ? "Edit" : "Add" %] Bounty Tracking Attachment
 </button>
index 707e35b6e0d5ee6928f1181edf491c2e7b5c6db6..7008a2b844d2d6b85f622e0e78dca04e637c4a0c 100644 (file)
@@ -45,3 +45,9 @@ function show_usermenu(id, email, show_edit) {
     });
 }
 
+$(function() {
+  $('.show_usermenu').on("click", function (event) {
+    var $this = $(this);
+    return show_usermenu($this.data('user-id'), $this.data('user-email'), $this.data('show-edit'));
+  });
+});
index fe0a7d4fe2506586f7aefd7d7ff665a10de47037..acdd55ee2c6fe9a8c049be83fbab6dc6d4bb99c9 100644 (file)
 
 [%# === initialise module visibility === %]
 
-<script>
+<script [% script_nonce FILTER none %]>
   init_module_visibility();
 </script>
 
index 4c28936cc0903bf0bb075d210447fa36ece59eb2..5c630ba07cbf8de93d0889dcf7cf61c30345a215 100644 (file)
@@ -41,11 +41,12 @@ END;
           width="[% gravatar_size FILTER none %]" height="[% gravatar_size FILTER none %]">
       [% END %]
       [% UNLESS gravatar_only %]
-        <a class="email [%= "disabled" UNLESS u.is_enabled %]"
+        <a class="email [%= "disabled" UNLESS u.is_enabled %] [%= "show_usermenu" IF user.id %]"
           [% IF user.id %]
             href="mailto:[% u.email FILTER html %]"
-            onclick="return show_usermenu([% u.id FILTER none %], '[% u.email FILTER js %]',
-              [% user.in_group('editusers') || user.bless_groups.size > 0 ? "true" : "false" %])"
+            data-user-id="[% u.id FILTER html %]"
+            data-user-email="[% u.email FILTER html %]"
+            data-show-edit="[% user.in_group('editusers') || user.bless_groups.size > 9 ? 'true' : 'false' %]"
             title="[% u.identity FILTER html %]"
           [% ELSE %]
             href="user_profile?user_id=[% u.id FILTER none %]"
index d7782192998c535238394452e83def75a853c1cc..01be1fd2c8a668671a46a1c1ade250efad1fe174 100644 (file)
@@ -1483,6 +1483,13 @@ function lb_close(event) {
     $('#lb_overlay, #lb_overlay2, #lb_close_btn, #lb_img, #lb_text').remove();
 }
 
+$(function() {
+    $("button.button-link").on("click", function (event) {
+        event.preventDefault();
+        window.location = $(this).data("href");
+    });
+});
+
 // extensions
 
 (function($) {
index adcd9e067031dd82a262746fd2c83fcffce23856..801d3d5fa8189cee8402ca4bc55a1e080dd545d8 100644 (file)
@@ -8,7 +8,7 @@
 [% USE Bugzilla %]
 
 [% IF Param('user_info_class').split(',').contains('GitHubAuth') %]
-  <script type="text/javascript">
+  <script [% script_nonce FILTER none %] type="text/javascript">
    YAHOO.util.Event.addListener('login_link[% qs_suffix FILTER js %]','click', function () {
      var login_link = YAHOO.util.Dom.get('github_mini_login[% qs_suffix FILTER js %]');
      YAHOO.util.Dom.removeClass(login_link, 'bz_default_hidden');
index 4d2a39f385816a24d4b8b86082b9c53c0f08f92b..915379316085ee1d0485e94c484f745f98869ec6 100644 (file)
@@ -39,7 +39,7 @@
   RETURN UNLESS needinfo_flagtype;
 %]
 
-<script>
+<script [% script_nonce FILTER none%]>
 [% IF needinfo_flags.size > 0 %]
 $(function() {
   [%# Displays NEEDINFO tag in bug header %]
@@ -139,12 +139,11 @@ $(function() {
     $('#needinfo').change();
   }
 
-  function needinfo_from_changed() {
-    $('#needinfo').prop('checked', $('#needinfo_from').val() !== '');
-  }
-
   $(function() {
     needinfo_init();
+    $(".needinfo_from_changed").on("change", function (event) {
+        $("#needinfo").prop("checked", $("#needinfo_from").val() !== '');
+    });
   });
 [% END %]
 </script>
@@ -227,7 +226,7 @@ $(function() {
               value       => ""
               size        => 30
               multiple    => 5
-              onchange    => "needinfo_from_changed()"
+              classes     => ["needinfo_from_changed"]
               field_title => "Enter one or more comma separated users to request more information from"
           %]
         </span>
index c964f9fed7e8068e92c2d73544cde20a583f5c9c..1743db9a669ad6f4c6da1f8d381da1c2f41f2b28 100644 (file)
@@ -1,7 +1,7 @@
 [% IF Param('user_info_class').split(',').contains('Persona')
       && Param('persona_includejs_url') %]
 <p>
-  <img src="extensions/Persona/web/images/persona_sign_in.png" width="185" height="25" onclick="persona_sign_in()">
+  <img src="extensions/Persona/web/images/persona_sign_in.png" width="185" height="25" class="persona_sign_in">
 </p>
 <p>
   <strong>Note:</strong> Persona authentication will be removed on October 25th, 2016 (<a href="page.cgi?id=persona_deprecated.html">more info</a>).
index 5d8503d734a6365966e8fcd25b9a80a45ec201ab..17a86a71ddec5a3937f268abc428145dd202caa7 100644 (file)
@@ -1,6 +1,6 @@
 [% IF Param('user_info_class').split(',').contains('Persona')
       && Param('persona_includejs_url') %]
-<script type="text/javascript">
+<script [% script_nonce FILTER none %] type="text/javascript">
   YAHOO.util.Event.addListener('login_link[% qs_suffix FILTER js %]','click', function () {
       var login_link = YAHOO.util.Dom.get('persona_mini_login[% qs_suffix FILTER js %]');
       YAHOO.util.Dom.removeClass(login_link, 'bz_default_hidden');
@@ -12,6 +12,6 @@
 </script>
 <span id="persona_mini_login[% qs_suffix FILTER html %]" class="bz_default_hidden">
   <img src="extensions/Persona/web/images/sign_in.png" height="22" width="75" align="absmiddle"
-       title="Sign in with Persona" onclick="persona_sign_in()"> or
+       title="Sign in with Persona" class='persona_sign_in'> or
 </span>
 [% END %]
index 355ce3629b43e1891993781510e883ffb14e8b1e..b6fb1eedc6051c2574552989f653e9e2ce6ec6d8 100644 (file)
@@ -9,5 +9,5 @@
 [% RETURN UNLESS Param('user_info_class').split(',').contains('Persona') %]
 
 Or, use your Persona account:
-<img src="extensions/Persona/web/images/sign_in.png" onclick="persona_sign_in()"
+<img src="extensions/Persona/web/images/sign_in.png" class="persona_sign_in"
      width="95" height="25" align="absmiddle">
index 5b2fa043b9ae503164a1ecefd340dc1a3f283372..12282df163b7d56a054be28feb48ebfc9501895b 100644 (file)
@@ -17,8 +17,8 @@
 [% USE Bugzilla %]
 [% cgi = Bugzilla.cgi %]
 
-<script defer src="[% Param('persona_includejs_url') %]" type="text/javascript"></script>
-<script type="text/javascript">
+<script [% script_nonce FILTER none %] defer src="[% Param('persona_includejs_url') %]" type="text/javascript"></script>
+<script [% script_nonce FILTER none %] type="text/javascript">
 
 function createHidden(name, value, form) {
   var field = document.createElement('input');
@@ -84,4 +84,7 @@ function persona_sign_in() {
   persona_ignore_login = false;
   navigator.id.request({ siteName: '[% terms.BugzillaTitle FILTER js %]' });
 }
+$(function() {
+    $('.persona_sign_in').on("click", persona_sign_in);
+});
 </script>
index 1dd62d9fb8273bfcd4b3e041a045fbf96640b83e..56513aff7d8b2a836f0987ed34405f6343e07192 100755 (executable)
--- a/index.cgi
+++ b/index.cgi
@@ -33,6 +33,8 @@ if ($cgi->param('logout')) {
     $cgi->delete('logout');
 }
 
+$cgi->content_security_policy(script_src  => ['self', 'nonce']);
+
 ###############################################################################
 # Main Body Execution
 ###############################################################################
index 8ff5092893aa56c96c74b9aeceb86f4c83a3eb41..a997821f49131e20c0e027f622c46514be8d544a 100644 (file)
 *                 
 */
 
+$(function () {
+  $('.show_mini_login_form').on("click", function (event) {
+    return show_mini_login_form($(this).data('qs-suffix'));
+  });
+  $('.hide_mini_login_form').on("click", function (event) {
+    return hide_mini_login_form($(this).data('qs-suffix'));
+  });
+  $('.show_forgot_form').on("click", function (event) {
+    return show_forgot_form($(this).data('qs-suffix'));
+  });
+  $('.hide_forgot_form').on("click", function (event) {
+    return hide_forgot_form($(this).data('qs-suffix'));
+  });
+  $('.check_mini_login_fields').on("click", function (event) {
+    return check_mini_login_fields($(this).data('qs-suffix'));
+  });
+  $('form .quicksearch_check_empty').on("submit", function (event) {
+      if (this.quicksearch.value == '') {
+        alert('Please enter one or more search terms first.');
+        return false;
+      }
+      return true;
+  });
+});
+
 function show_mini_login_form( suffix ) {
     $('#login_link' + suffix).addClass('bz_default_hidden');
     $('#mini_login' + suffix).removeClass('bz_default_hidden');
@@ -37,6 +62,7 @@ function show_forgot_form( suffix ) {
     return false;
 }
 
+
 function hide_forgot_form( suffix ) {
     $('#forgot_link' + suffix).removeClass('bz_default_hidden');
     $('#forgot_form' + suffix).addClass('bz_default_hidden');
index 0975e32ae8b7f711cdcdb3f9e8e02fb7fae8d0b0..bbba125c16edc72b3fec7f17c7ddb6817645cbab 100755 (executable)
@@ -264,6 +264,9 @@ $format = $template->get_format("bug/create/created",
 # don't leak the enter_bug format param to show_bug
 $cgi->delete('format');
 
+if ($user->setting('ui_experiments') eq 'on') {
+    Bugzilla->cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+}
 print $cgi->header();
 $template->process($format->{'template'}, $vars)
     || ThrowTemplateError($template->error());
index 0858a3ff872a97d7d0f31873ce79568a49c74f07..ac8e32c5355f7ca1a2f8fe0a092eadefa54670be 100755 (executable)
@@ -419,9 +419,12 @@ my $format_params = {
     ctype  => scalar $cgi->param('ctype'),
 };
 Bugzilla::Hook::process('show_bug_format', $format_params);
+if ($format_params->{format} eq 'modal') {
+    $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+}
 my $format = $template->get_format("bug/show",
-                                    $format_params->{format},
-                                    $format_params->{ctype});
+                                   $format_params->{format},
+                                   $format_params->{ctype});
 
 if (Bugzilla->usage_mode != USAGE_MODE_EMAIL) {
     print $cgi->header();
@@ -466,5 +469,4 @@ if (Bugzilla->usage_mode != USAGE_MODE_EMAIL) {
     $template->process("global/footer.html.tmpl", $vars)
         || ThrowTemplateError($template->error());
 }
-
 1;
index 5170176884fee827991533826223d790ef275fb8..d4e6ea7718817654cf8536e9d4e4a3752fd1a939 100755 (executable)
@@ -19,6 +19,7 @@ use Bugzilla::User;
 use Bugzilla::Keyword;
 use Bugzilla::Bug;
 use Bugzilla::Hook;
+use Bugzilla::CGI;
 
 my $cgi = Bugzilla->cgi;
 my $template = Bugzilla->template;
@@ -36,6 +37,10 @@ my $format = $template->get_format("bug/show",
                                    $format_params->{format},
                                    $format_params->{ctype});
 
+if ($format_params->{format} eq 'modal') {
+    $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+}
+
 # Editable, 'single' HTML bugs are treated slightly specially in a few places
 my $single = (!$format->{format} || $format->{format} ne 'multiple')
              && $format->{extension} eq 'html';
index 111aca0dd4cc56524cc51f27c9e39b2bcde0d5f3..b182ddef33e81a844d54a986af1aa732bbf3fb2f 100644 (file)
   [% END %]
   [% script_url = login_target _ connector _ "GoAheadAndLogIn=1" %]
   <a id="login_link[% qs_suffix %]" href="[% script_url FILTER html %]"
-     onclick="return show_mini_login_form('[% qs_suffix %]')">Log In</a>
+     class='show_mini_login_form' data-qs-suffix="[% qs_suffix FILTER html %]">Log In</a>
 
   [% Hook.process('additional_methods') %]
   
   <form action="[% login_target FILTER html %]" method="POST" 
         class="mini_login bz_default_hidden"
         id="mini_login[% qs_suffix FILTER html %]"
-        onsubmit="return check_mini_login_fields( '[% qs_suffix FILTER html %]' );"
+        class="check_mini_login_fields"
+        data-qs-suffix="[% qs_suffix FILTER html %]"
   >
     
     <input id="Bugzilla_login[% qs_suffix FILTER html %]" 
     <input type="submit" name="GoAheadAndLogIn" value="Log in"
             id="log_in[% qs_suffix %]">
     <a href="#" id="hide_mini_login[% qs_suffix FILTER html %]" 
-       onclick="return hide_mini_login_form('[% qs_suffix %]')">[x]</a>
+       class="hide_mini_login_form" data-qs-suffix="[% qs_suffix FILTER html %]">[x]</a>
   </form>
 </li>
 <li id="forgot_container[% qs_suffix %]">
   <span class="separator">| </span>
   <a id="forgot_link[% qs_suffix %]" href="[% script_url FILTER html %]#forgot"
-     onclick="return show_forgot_form('[% qs_suffix %]')">Forgot Password</a>
+     class='show_forgot_form'
+     data-qs-suffix="[% qs_suffix FILTER html %]">Forgot Password</a>
   <form action="token.cgi" method="post" id="forgot_form[% qs_suffix %]"
         class="mini_forgot bz_default_hidden">
     <label for="login[% qs_suffix FILTER html %]">Login:</label>
@@ -92,6 +94,6 @@
            type="submit">
     <input type="hidden" name="a" value="reqpw">
     <input type="hidden" id="token[% qs_suffix FILTER html %]" name="token" value="[% issue_hash_token(['reqpw']) FILTER html %]">
-    <a href="#" onclick="return hide_forgot_form('[% qs_suffix %]')">[x]</a>
+    <a href="#" class="hide_forgot_form" data-qs-suffix="[% qs_suffix FILTER html %]">[x]</a>
   </form>
 </li>
index 0c4f2f27d96ebd69ef3d7095c686cf565307a6e9..0e392c760ad6a13497bb3612d5ec6768f9d5700d 100644 (file)
 %]
 [% recipient_count = sent_bugmail.sent.size %]
 
-<script>
-function toggleBugmailRecipients(bug_id, show) {
-  if (show) {
-    YAHOO.util.Dom.removeClass('bugmail_summary_' + bug_id, 'bz_default_hidden');
-    YAHOO.util.Dom.addClass('bugmail_summary_' + bug_id + '_short', 'bz_default_hidden');
-  } else {
-    YAHOO.util.Dom.addClass('bugmail_summary_' + bug_id, 'bz_default_hidden');
-    YAHOO.util.Dom.removeClass('bugmail_summary_' + bug_id + '_short', 'bz_default_hidden');
+<script [% script_nonce FILTER none %]>
+  function toggleBugmailRecipients(bug_id, show) {
+    if (show) {
+      $("#bugmail_summary_" + bug_id).show();
+      $("#bugmail_summary_" + bug_id + "_short").hide();
+    } else {
+      $("#bugmail_summary_" + bug_id).hide();
+      $("#bugmail_summary_" + bug_id + "_short").show();
+    }
+    $.cookie('show_bugmail_recipients', (show ? 1 : 0), {
+        expires: new Date("January 12, 2025")
+    });
   }
-  YAHOO.util.Cookie.set('show_bugmail_recipients', (show ? 1 : 0), {
-    expires: new Date("January 12, 2025")
-  });
-  return false;
-}
+  $(function() {
+    $(".toggleBugmailRecipients").on("click", function (event) {
+      event.preventDefault();
+      toggleBugmailRecipients($(this).data('mailing-bugid'), $(this).data('mailing-show'));
+     });
+   });
 </script>
 
 <dl id="bugmail_summary_[% mailing_bugid FILTER none %]"
@@ -63,7 +68,8 @@ function toggleBugmailRecipients(bug_id, show) {
     [% ELSE %]
       no one
     [% END %]
-    (<a href="#" onclick="return toggleBugmailRecipients([% mailing_bugid FILTER none %], false)">hide</a>)
+    (<a href="#" class="toggleBugmailRecipients" data-mailing-bugid="[% mailing_bugid FILTER html %]"
+        data-mailing-show="false">hide</a>)
   [% ELSE %]
     (list of e-mails not available)
   [% END %]
@@ -74,7 +80,8 @@ function toggleBugmailRecipients(bug_id, show) {
      class="[% show_recipients ? "bz_default_hidden" : "" %]">
   [% IF recipient_count > 0 %]
     Email sent to [% recipient_count FILTER html %] recipient[% 's' UNLESS recipient_count == 1 %].
-    (<a href="#" onclick="return toggleBugmailRecipients([% mailing_bugid FILTER none %], true)">show</a>)
+    (<a href="#" class="toggleBugmailRecipients" data-mailing-bugid="[% mailing_bugid FILTER html %]"
+                                                 data-mailing-show="true">show</a>)
   [% ELSE %]
     No emails were sent.
   [% END %]
index 50cfa020c5b11af704a64c5df495f6d16b20cb6e..76b0855d8642378015ad53957856a43bd035f55e 100644 (file)
@@ -31,9 +31,7 @@
   <li class="form quicksearch_form">
     <span class="separator">| </span>
     <form action="buglist.cgi" method="get"
-        onsubmit="if (this.quicksearch.value == '')
-                  { alert('Please enter one or more search terms first.');
-                    return false; } return true;">
+      class='quicksearch_check_empty'>
     <input class="txt" type="text" id="quicksearch[% qs_suffix FILTER html %]" name="quicksearch" 
            title="Quick Search" value="[% quicksearch FILTER html %]">
     <input class="btn" type="submit" value="Search" 
index 1ef96a5532686873a82201e2100d381d7d7b11a7..2e08a461d4f386909068334cac2eada476acdcde 100644 (file)
       [% PROCESS format_js_link %]
     [% END %]
 
-    <script type="text/javascript">
+    <script [% script_nonce FILTER none %] type="text/javascript">
     <!--
         [% IF NOT no_yui %]
           YAHOO.namespace('bugzilla');
+          [% IF 0 %]
           YAHOO.util.Event.addListener = function (el, sType, fn, obj, overrideContext) {
               if ( ("onpagehide" in window || YAHOO.env.ua.gecko) && sType === "unload") { sType = "pagehide"; };
               var capture = ((sType == "focusin" || sType == "focusout") && !YAHOO.env.ua.ie) ? true : false;
               return this._addListener(el, this._getType(sType), fn, obj, overrideContext, capture);
           };
+          [% END %]
           if ( "onpagehide" in window || YAHOO.env.ua.gecko) {
               YAHOO.util.Event._simpleRemove(window, "unload",
                                              YAHOO.util.Event._unload);
 [%# Migration note: contents of the old Param 'bodyhtml' go in the body tag,
   # but set the onload attribute in the DEFAULT directive above.
   #%]
-
-  <body onload="[% onload %]"
+  [% IF onload %]
+  <script [% script_nonce FILTER none %]>
+  $(function() { [% onload %] });
+  </script>
+  [% END %]
+  <body
         class="[% urlbase.replace('^https?://','').replace('/$','').replace('[-~@:/.]+','-') FILTER css_class_quote %]
                skin-[% user.settings.skin.value FILTER css_class_quote %]
                [% FOREACH class = bodyclasses %]
 [% END %]
 
 [% BLOCK format_js_link %]
-  <script type="text/javascript" src="[% asset_url FILTER mtime FILTER html %]"></script>
+  <script [% script_nonce FILTER none %] type="text/javascript" src="[% asset_url FILTER mtime FILTER html %]"></script>
 [% END %]
index 90418981f506f95f64451b17f1580f3f842fa9d4..71723c178e0ab3a327f0c2cd405444a46b2d9836 100644 (file)
@@ -15,7 +15,7 @@
 
 [% IF user.id && user.settings.per_bug_queries.value == "on" %]
   <li id="links-special">
-    <script type="text/javascript">
+    <script [% script_nonce FILTER none %] type="text/javascript">
       <!--
       function update_text() {
         // 'lob' means list_of_bugs.
           old_lists.disabled = false;
         }
       }
+      $(function() {
+        $("#lob_action").on("change", update_text);
+        $("#lob_newqueryname").on("keyup", manage_old_lists);
+      });
       //-->
     </script>
 
@@ -58,7 +62,7 @@
         <input type="hidden" name="remtype" value="asnamed">
         <input type="hidden" name="list_of_bugs" value="1">
         <input type="hidden" name="token" value="[% issue_hash_token(['savedsearch']) FILTER html %]">
-        <select id="lob_action" name="action" onchange="update_text();">
+        <select id="lob_action" name="action" >
           <option value="add">Add</option>
           [% IF user.tags.size %]
             <option value="remove">Remove</option>
@@ -81,8 +85,7 @@
         <span id="lob_new_query_text">
           [% " or create and add the tag" IF user.tags.size %]
           <input class="txt" type="text" id="lob_newqueryname"
-                 size="20" maxlength="64" name="newqueryname"
-                 onkeyup="manage_old_lists();">
+                 size="20" maxlength="64" name="newqueryname">
         </span>
         <span id="lob_direction">to</span>
         [%+ terms.bugs %]
index f7dc03d8992fb7919bec737e1bdb14650d8a0f41..5577448fb3829522636684242287f82846ea5860 100644 (file)
@@ -11,7 +11,6 @@
   # id: optional; field id
   # value: optional; default field value/selection
   # classes: optional; an array of classes to be added
-  # onchange: optional; onchange attribute value
   # disabled: optional; if true, the field is disabled
   # accesskey: optional, input only; accesskey attribute value
   # size: optional, input only; size attribute value
   # mandatory: optional; if true, the field cannot be empty.
   #%]
 
+[% THROW "onchange is not allowed" IF onchange %]
+
 [% IF Param("usemenuforusers") %]
 <select name="[% name FILTER html %]"
   [% IF id %] id="[% id FILTER html %]" [% END %]
   [% IF classes %] class="[% classes.join(' ') FILTER html %]" [% END %]
-  [% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
   [% IF disabled %] disabled="[% disabled FILTER html %]" [% END %]
   [% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
   [% IF multiple %] multiple="multiple" size="[% multiple FILTER html %]" [% END %]
@@ -86,7 +86,6 @@
     name="[% name FILTER html %]"
     value="[% value FILTER html %]"
     [% IF classes %] class="[% classes.join(' ') FILTER html %]" [% END %]
-    [% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
     [% IF disabled %] disabled="[% disabled FILTER html %]" [% END %]
     [% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
     [% IF field_title %] title="[% field_title FILTER html %]" [% END %]
index f99287d49f88387d829c05773ef8e753867e411b..a3fa0a9063bc0aebc30154ec0bac2647995a9711 100644 (file)
@@ -32,7 +32,7 @@
    style_urls = [ 'skins/standard/index.css' ]
 %]
 
-<script type="text/javascript">
+<script [% script_nonce FILTER none %] type="text/javascript">
 function checkQuicksearch( form ) {
   if (form.quicksearch.value == '') {
     alert('Please enter one or more search terms first.');
@@ -40,6 +40,11 @@ function checkQuicksearch( form ) {
   }
   return true;
 }
+$(function () {
+    $("#quicksearchForm").on("submit", function (event) {
+        return checkQuicksearch(this);
+    });
+});
 </script>
 
 <div id="page-index">
@@ -63,8 +68,7 @@ function checkQuicksearch( form ) {
              href="?GoAheadAndLogIn=1"><span>Log In</span></a>
            [% END %]
 
-        <form id="quicksearchForm" name="quicksearchForm" action="buglist.cgi"
-              onsubmit="return checkQuicksearch(this);">
+        <form id="quicksearchForm" name="quicksearchForm" action="buglist.cgi">
           <div>
             <input id="quicksearch_main" type="text" name="quicksearch"
               placeholder="Enter [% terms.abug %] number or some search terms"
index 18bf4dfb1ea9d7b71cbbaf856d4527cc29381879..a3359752fc2eece6fcdf940cba714fb29c302813 100644 (file)
@@ -31,9 +31,7 @@
 <p>Type in one or more words (or pieces of words) to search for:</p>
 
 <form name="f" action="buglist.cgi" method="get"
-      onsubmit="if (this.quicksearch.value == '')
-                { alert('Please enter one or more search terms first.');
-                  return false; } return true;">
+      class='quicksearch_check_empty'>
   <input type="text" size="40" name="quicksearch">
   <input type="submit" value="Search" id="find">
 </form>