Browse Source

[core] Fix some XSS vulnerabilities

Make Mako HTML escape all variable as default
EscapeJs javascript loaded in ko models and displayed as text (e.g. jobsub description,
Oozie action json parameters list)
Un-escape all the legitmate form fields
Adding some sanity checks
Romain Rigaux 13 years ago
parent
commit
cfd3a5c040
98 changed files with 364 additions and 363 deletions
  1. 2 2
      apps/about/src/about/templates/index.mako
  2. 3 1
      apps/beeswax/src/beeswax/conf.py
  3. 2 2
      apps/beeswax/src/beeswax/templates/beeswax_components.mako
  4. 2 2
      apps/beeswax/src/beeswax/templates/choose_delimiter.mako
  5. 2 2
      apps/beeswax/src/beeswax/templates/choose_file.mako
  6. 2 2
      apps/beeswax/src/beeswax/templates/configuration.mako
  7. 2 2
      apps/beeswax/src/beeswax/templates/create_table_manually.mako
  8. 2 2
      apps/beeswax/src/beeswax/templates/define_columns.mako
  9. 2 2
      apps/beeswax/src/beeswax/templates/describe_partitions.mako
  10. 2 2
      apps/beeswax/src/beeswax/templates/describe_table.mako
  11. 7 6
      apps/beeswax/src/beeswax/templates/execute.mako
  12. 2 2
      apps/beeswax/src/beeswax/templates/explain.mako
  13. 2 2
      apps/beeswax/src/beeswax/templates/index.mako
  14. 2 2
      apps/beeswax/src/beeswax/templates/list_designs.mako
  15. 2 2
      apps/beeswax/src/beeswax/templates/list_history.mako
  16. 2 2
      apps/beeswax/src/beeswax/templates/load_table.mako
  17. 3 3
      apps/beeswax/src/beeswax/templates/my_queries.mako
  18. 3 2
      apps/beeswax/src/beeswax/templates/parameterization.mako
  19. 7 3
      apps/beeswax/src/beeswax/templates/save_results.mako
  20. 3 3
      apps/beeswax/src/beeswax/templates/show_tables.mako
  21. 5 5
      apps/beeswax/src/beeswax/templates/watch_results.mako
  22. 4 4
      apps/beeswax/src/beeswax/templates/watch_wait.mako
  23. 14 0
      apps/beeswax/src/beeswax/tests.py
  24. 3 3
      apps/filebrowser/src/filebrowser/templates/display.mako
  25. 2 2
      apps/filebrowser/src/filebrowser/templates/edit.mako
  26. 2 2
      apps/filebrowser/src/filebrowser/templates/fb_components.mako
  27. 2 2
      apps/filebrowser/src/filebrowser/templates/fileop.mako
  28. 2 2
      apps/filebrowser/src/filebrowser/templates/listdir.mako
  29. 0 1
      apps/filebrowser/src/filebrowser/views.py
  30. 2 2
      apps/help/src/help/templates/display.mako
  31. 2 2
      apps/jobbrowser/src/jobbrowser/templates/attempt.mako
  32. 3 3
      apps/jobbrowser/src/jobbrowser/templates/attempt_logs.mako
  33. 2 2
      apps/jobbrowser/src/jobbrowser/templates/job.mako
  34. 2 2
      apps/jobbrowser/src/jobbrowser/templates/job_attempt_logs.mako
  35. 3 3
      apps/jobbrowser/src/jobbrowser/templates/jobs.mako
  36. 2 2
      apps/jobbrowser/src/jobbrowser/templates/task.mako
  37. 2 2
      apps/jobbrowser/src/jobbrowser/templates/tasks.mako
  38. 2 2
      apps/jobbrowser/src/jobbrowser/templates/tasktracker.mako
  39. 2 2
      apps/jobbrowser/src/jobbrowser/templates/tasktrackers.mako
  40. 21 16
      apps/jobsub/src/jobsub/templates/edit_design.mako
  41. 5 4
      apps/jobsub/src/jobsub/templates/list_designs.mako
  42. 2 2
      apps/jobsub/src/jobsub/templates/list_history.mako
  43. 4 4
      apps/jobsub/src/jobsub/templates/workflow.mako
  44. 22 9
      apps/jobsub/src/jobsub/tests.py
  45. 5 4
      apps/jobsub/src/jobsub/views.py
  46. 17 3
      apps/oozie/src/oozie/models.py
  47. 4 4
      apps/oozie/src/oozie/templates/dashboard/list_oozie_coordinator.mako
  48. 2 2
      apps/oozie/src/oozie/templates/dashboard/list_oozie_coordinators.mako
  49. 7 7
      apps/oozie/src/oozie/templates/dashboard/list_oozie_workflow.mako
  50. 2 2
      apps/oozie/src/oozie/templates/dashboard/list_oozie_workflow_action.mako
  51. 2 2
      apps/oozie/src/oozie/templates/dashboard/list_oozie_workflows.mako
  52. 3 3
      apps/oozie/src/oozie/templates/dashboard/rerun_job_popup.mako
  53. 1 1
      apps/oozie/src/oozie/templates/editor/action_utils.mako
  54. 1 1
      apps/oozie/src/oozie/templates/editor/control_utils.mako
  55. 8 8
      apps/oozie/src/oozie/templates/editor/coordinator_properties.mako
  56. 2 2
      apps/oozie/src/oozie/templates/editor/create_coordinator.mako
  57. 1 1
      apps/oozie/src/oozie/templates/editor/create_coordinator_data.mako
  58. 2 2
      apps/oozie/src/oozie/templates/editor/create_workflow.mako
  59. 3 3
      apps/oozie/src/oozie/templates/editor/dataset_utils.mako
  60. 15 15
      apps/oozie/src/oozie/templates/editor/edit_coordinator.mako
  61. 6 5
      apps/oozie/src/oozie/templates/editor/edit_workflow.mako
  62. 1 1
      apps/oozie/src/oozie/templates/editor/gen/workflow-generic.xml.mako
  63. 4 4
      apps/oozie/src/oozie/templates/editor/gen/workflow.xml.mako
  64. 2 2
      apps/oozie/src/oozie/templates/editor/import_workflow.mako
  65. 0 78
      apps/oozie/src/oozie/templates/editor/import_workflow_action.mako
  66. 2 2
      apps/oozie/src/oozie/templates/editor/list_coordinators.mako
  67. 2 2
      apps/oozie/src/oozie/templates/editor/list_history.mako
  68. 2 2
      apps/oozie/src/oozie/templates/editor/list_history_record.mako
  69. 2 2
      apps/oozie/src/oozie/templates/editor/list_workflows.mako
  70. 2 2
      apps/oozie/src/oozie/templates/editor/submit_job_popup.mako
  71. 8 8
      apps/oozie/src/oozie/templates/utils.inc.mako
  72. 23 0
      apps/oozie/src/oozie/tests.py
  73. 3 6
      apps/oozie/src/oozie/views/editor.py
  74. 2 2
      apps/shell/src/shell/templates/failed_to_create.mako
  75. 2 2
      apps/shell/src/shell/templates/index.mako
  76. 2 2
      apps/shell/src/shell/templates/no_such_user.mako
  77. 2 2
      apps/shell/src/shell/templates/not_running_spawning.mako
  78. 2 2
      apps/useradmin/src/useradmin/templates/add_ldap_users.mako
  79. 2 2
      apps/useradmin/src/useradmin/templates/confirm.mako
  80. 2 2
      apps/useradmin/src/useradmin/templates/edit_group.mako
  81. 2 2
      apps/useradmin/src/useradmin/templates/edit_permissions.mako
  82. 2 2
      apps/useradmin/src/useradmin/templates/edit_user.mako
  83. 2 2
      apps/useradmin/src/useradmin/templates/list_groups.mako
  84. 2 2
      apps/useradmin/src/useradmin/templates/list_permissions.mako
  85. 2 2
      apps/useradmin/src/useradmin/templates/list_users.mako
  86. 3 3
      desktop/conf.dist/hue.ini
  87. 3 3
      desktop/conf/pseudo-distributed.ini.tmpl
  88. 3 2
      desktop/core/src/desktop/lib/django_mako.py
  89. 1 1
      desktop/core/src/desktop/management/commands/runpylint.py
  90. 2 2
      desktop/core/src/desktop/templates/404.mako
  91. 5 5
      desktop/core/src/desktop/templates/500.mako
  92. 2 2
      desktop/core/src/desktop/templates/check_config.mako
  93. 1 1
      desktop/core/src/desktop/templates/common_header.mako
  94. 2 2
      desktop/core/src/desktop/templates/dump_config.mako
  95. 5 5
      desktop/core/src/desktop/templates/error.mako
  96. 5 5
      desktop/core/src/desktop/templates/login.mako
  97. 5 3
      desktop/core/src/desktop/templates/logs.mako
  98. 7 7
      desktop/core/src/desktop/templates/popup_error.mako

+ 2 - 2
apps/about/src/about/templates/index.mako

@@ -17,7 +17,7 @@
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
-${commonheader(_('About Hue'), "about", user, "100px")}
+${ commonheader(_('About Hue'), "about", user, "100px") | n,unicode }
 
 
 	<div class="subnav subnav-fixed">
 	<div class="subnav subnav-fixed">
 		<div class="container-fluid">
 		<div class="container-fluid">
@@ -34,4 +34,4 @@ ${commonheader(_('About Hue'), "about", user, "100px")}
 		<p>Hue ${version}</p>
 		<p>Hue ${version}</p>
 	</div>
 	</div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 3 - 1
apps/beeswax/src/beeswax/conf.py

@@ -29,7 +29,9 @@ SERVER_INTERFACE = Config(
 
 
 BEESWAX_SERVER_HOST = Config(
 BEESWAX_SERVER_HOST = Config(
   key="beeswax_server_host",
   key="beeswax_server_host",
-  help=_("Host where Beeswax server Thrift daemon is running. FQDN required when using security even if on same host."),
+  help=_("Host where Beeswax server Thrift daemon is running. If Kerberos security is enabled, "
+         "the fully-qualified domain name (FQDN) is required, even if the Thrift daemon is running "
+         "on the same host as Hue."),
   private=True,
   private=True,
   default="localhost")
   default="localhost")
 
 

+ 2 - 2
apps/beeswax/src/beeswax/templates/beeswax_components.mako

@@ -160,9 +160,9 @@ ${field.label_tag() | n}
                 % endif
                 % endif
             % else:
             % else:
                 %if file_chooser:
                 %if file_chooser:
-                    <${tag} name="${field.html_name | n}" value="${extract_field_data(field) or ''}" ${make_attr_str(attrs) | n} class="${cls}" ${plc} /><a class="btn fileChooserBtn" href="#" data-filechooser-destination="${field.html_name | n}">..</a>
+                    <${tag} name="${field.html_name | n}" value="${extract_field_data(field) or ''}" ${make_attr_str(attrs) | n} class="${cls}" ${plc | n,unicode} /><a class="btn fileChooserBtn" href="#" data-filechooser-destination="${field.html_name | n}">..</a>
                 %else:
                 %else:
-                    <${tag} name="${field.html_name | n}" value="${extract_field_data(field) or ''}" ${make_attr_str(attrs) | n} class="${cls}" ${plc} />
+                    <${tag} name="${field.html_name | n}" value="${extract_field_data(field) or ''}" ${make_attr_str(attrs) | n} class="${cls}" ${plc | n,unicode} />
                 %endif
                 %endif
             % endif
             % endif
         % endif
         % endif

+ 2 - 2
apps/beeswax/src/beeswax/templates/choose_delimiter.mako

@@ -22,7 +22,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="util" file="util.mako" />
 <%namespace name="util" file="util.mako" />
 
 
-${commonheader(_('Create table from file'), app_name, user, '100px')}
+${ commonheader(_('Create table from file'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 ${layout.menubar(section='tables')}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -141,4 +141,4 @@ ${layout.menubar(section='tables')}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/choose_file.mako

@@ -21,7 +21,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 
 
-${commonheader(_('Create table from file'), app_name, user, '100px')}
+${ commonheader(_('Create table from file'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 ${layout.menubar(section='tables')}
 
 
 
 
@@ -170,4 +170,4 @@ ${layout.menubar(section='tables')}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/configuration.mako

@@ -21,7 +21,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="util" file="util.mako" />
 <%namespace name="util" file="util.mako" />
 
 
-${commonheader(_('Configuration Variables'), app_name, user, '100px')}
+${ commonheader(_('Configuration Variables'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='configuration')}
 ${layout.menubar(section='configuration')}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -88,4 +88,4 @@ ${layout.menubar(section='configuration')}
 	});
 	});
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/create_table_manually.mako

@@ -21,7 +21,7 @@
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_("Create table manually"), app_name, user, '100px')}
+${ commonheader(_("Create table manually"), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 ${layout.menubar(section='tables')}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -733,4 +733,4 @@ $(document).ready(function () {
 });
 });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/define_columns.mako

@@ -22,7 +22,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="util" file="util.mako" />
 <%namespace name="util" file="util.mako" />
 
 
-${commonheader(_('Create table from file'), app_name, user, '100px')}
+${ commonheader(_('Create table from file'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 ${layout.menubar(section='tables')}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -125,4 +125,4 @@ ${layout.menubar(section='tables')}
         });
         });
     });
     });
 </script>
 </script>
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/describe_partitions.mako

@@ -21,7 +21,7 @@
 
 
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Beeswax Table Partitions: %(tableName)s') % dict(tableName=table.name), app_name, user, '100px')}
+${ commonheader(_('Beeswax Table Partitions: %(tableName)s') % dict(tableName=table.name), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 ${layout.menubar(section='tables')}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -57,4 +57,4 @@ ${layout.menubar(section='tables')}
 
 
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/describe_table.mako

@@ -27,7 +27,7 @@ from django.utils.translation import ugettext as _
   else:
   else:
     view_or_table_noun = _("Table")
     view_or_table_noun = _("Table")
 %>
 %>
-${commonheader(_("%s Metadata: %s") % (view_or_table_noun, table.name), app_name, user, '100px')}
+${ commonheader(_("%s Metadata: %s") % (view_or_table_noun, table.name), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 ${layout.menubar(section='tables')}
 
 
 <%def name="column_table(cols)">
 <%def name="column_table(cols)">
@@ -277,4 +277,4 @@ ${layout.menubar(section='tables')}
    });
    });
  </script>
  </script>
 
 
- ${commonfooter(messages)}
+ ${ commonfooter(messages) | n,unicode }

+ 7 - 6
apps/beeswax/src/beeswax/templates/execute.mako

@@ -33,10 +33,11 @@
         </div>
         </div>
     % endif
     % endif
 
 
-    <textarea class="span9" rows="18" placeholder="${_('Example: SELECT * FROM tablename')}" name="${form.query["query"].html_name | n}" id="queryField">${extract_field_data(form.query["query"]) or ''}</textarea>
+    <textarea class="span9" rows="18" placeholder="${_('Example: SELECT * FROM tablename')}" name="${form.query["query"].html_name}" id="queryField">${extract_field_data(form.query["query"]) or ''}</textarea>
+
     <div id="validationResults">
     <div id="validationResults">
     % if len(form.query["query"].errors):
     % if len(form.query["query"].errors):
-        ${unicode(form.query["query"].errors) | n}
+        ${ unicode(form.query["query"].errors) }
      % endif
      % endif
     </div>
     </div>
 
 
@@ -54,7 +55,7 @@
 </%def>
 </%def>
 
 
 
 
-${commonheader(_('Query'), app_name, user, '100px')}
+${ commonheader(_('Query'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='query')}
 ${layout.menubar(section='query')}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -65,7 +66,7 @@ ${layout.menubar(section='query')}
                     <ul class="nav nav-list">
                     <ul class="nav nav-list">
                         <li class="nav-header">${_('database')}</li>
                         <li class="nav-header">${_('database')}</li>
                         <li>
                         <li>
-                          ${ form.query['database'] }
+                          ${ form.query['database'] | n,unicode }
                         </li>
                         </li>
                         <li class="nav-header">${_('settings')}</li>
                         <li class="nav-header">${_('settings')}</li>
                         <li>
                         <li>
@@ -250,7 +251,7 @@ ${layout.menubar(section='query')}
                     % if error_message or log:
                     % if error_message or log:
                         <div class="tab-pane" id="errorPane">
                         <div class="tab-pane" id="errorPane">
                         % if log:
                         % if log:
-                            <pre>${log | h}</pre>
+                            <pre>${ log }</pre>
                         % endif
                         % endif
                         </div>
                         </div>
                     % endif
                     % endif
@@ -507,4 +508,4 @@ ${layout.menubar(section='query')}
 </script>
 </script>
 
 
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/explain.mako

@@ -22,7 +22,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="util" file="util.mako" />
 <%namespace name="util" file="util.mako" />
 
 
-${commonheader(_('Query Explanation'), app_name, user, '100px')}
+${ commonheader(_('Query Explanation'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='saved queries')}
 ${layout.menubar(section='saved queries')}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -47,4 +47,4 @@ ${layout.menubar(section='saved queries')}
 
 
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/index.mako

@@ -21,7 +21,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Beeswax'), app_name, user, '100px')}
+${ commonheader(_('Beeswax'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 ${layout.menubar(section='tables')}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -94,4 +94,4 @@ ${layout.menubar(section='tables')}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/list_designs.mako

@@ -23,7 +23,7 @@
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Queries'), app_name, user, '100px')}
+${ commonheader(_('Queries'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='saved queries')}
 ${layout.menubar(section='saved queries')}
 <div class="container-fluid">
 <div class="container-fluid">
     <h1>${_('Queries')}</h1>
     <h1>${_('Queries')}</h1>
@@ -134,4 +134,4 @@ ${layout.menubar(section='saved queries')}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/list_history.mako

@@ -23,7 +23,7 @@ from beeswax.views import collapse_whitespace
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 
 
-${commonheader(_('Query History'), app_name, user, '100px')}
+${ commonheader(_('Query History'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='history')}
 ${layout.menubar(section='history')}
 
 
 <%def name="show_saved_query(design, history)">
 <%def name="show_saved_query(design, history)">
@@ -176,4 +176,4 @@ ${layout.menubar(section='history')}
         $("a[data-row-selector='true']").jHueRowSelector();
         $("a[data-row-selector='true']").jHueRowSelector();
     });
     });
 </script>
 </script>
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/beeswax/src/beeswax/templates/load_table.mako

@@ -21,7 +21,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="util" file="util.mako" />
 <%namespace name="util" file="util.mako" />
 
 
-${commonheader(_('Load Data into %(table)s') % {'table': table}, app_name, user, '100px')}
+${ commonheader(_('Load Data into %(table)s') % {'table': table}, app_name, user, '100px') | n,unicode }
 
 
 ${layout.menubar()}
 ${layout.menubar()}
 
 
@@ -53,4 +53,4 @@ ${layout.menubar()}
   </div>
   </div>
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 3 - 3
apps/beeswax/src/beeswax/templates/my_queries.mako

@@ -23,7 +23,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%!  from beeswax.views import collapse_whitespace %>
 <%!  from beeswax.views import collapse_whitespace %>
 
 
-${commonheader(_('My Queries'), app_name, user, '100px')}
+${ commonheader(_('My Queries'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='my queries')}
 ${layout.menubar(section='my queries')}
 
 
 <style>
 <style>
@@ -136,7 +136,7 @@ ${layout.menubar(section='my queries')}
                           % if len(query.query) > 100:
                           % if len(query.query) > 100:
                             <code>${collapse_whitespace(query.query[:100])}...</code>
                             <code>${collapse_whitespace(query.query[:100])}...</code>
                           % else:
                           % else:
-                            <code>${collapse_whitespace(query.query)}</code>
+                            <code>${ collapse_whitespace(query.query) }</code>
                           % endif
                           % endif
                         </p>
                         </p>
                       </td>
                       </td>
@@ -253,4 +253,4 @@ ${layout.menubar(section='my queries')}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 3 - 2
apps/beeswax/src/beeswax/templates/parameterization.mako

@@ -17,10 +17,11 @@
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
+
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Parameterize Query'), app_name, user, '100px')}
+${ commonheader(_('Parameterize Query'), app_name, user, '100px') | n,unicode }
 
 
 ${layout.menubar()}
 ${layout.menubar()}
 
 
@@ -52,4 +53,4 @@ ${layout.menubar()}
     </form>
     </form>
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 7 - 3
apps/beeswax/src/beeswax/templates/save_results.mako

@@ -17,14 +17,17 @@
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
+
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="util" file="util.mako" />
 <%namespace name="util" file="util.mako" />
-${commonheader(_('Create table from file'), app_name, user, '100px')}
+
+${ commonheader(_('Create table from file'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='history')}
 ${layout.menubar(section='history')}
+
 <div class="container-fluid">
 <div class="container-fluid">
 % if error_msg:
 % if error_msg:
-<h4>${error_msg}</h4>
+  <h4>${error_msg}</h4>
 % endif
 % endif
   <h1>${_('Save Query Results')}</h1>
   <h1>${_('Save Query Results')}</h1>
 
 
@@ -122,4 +125,5 @@ ${layout.menubar(section='history')}
     }
     }
   });
   });
 </script>
 </script>
-${commonfooter(messages)}
+
+${ commonfooter(messages) | n,unicode }

+ 3 - 3
apps/beeswax/src/beeswax/templates/show_tables.mako

@@ -20,7 +20,7 @@ from django.utils.translation import ugettext as _
 
 
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Table List'), app_name, user, '100px')}
+${ commonheader(_('Table List'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 ${layout.menubar(section='tables')}
 
 
 
 
@@ -33,7 +33,7 @@ ${layout.menubar(section='tables')}
                     <li class="nav-header">${_('database')}</li>
                     <li class="nav-header">${_('database')}</li>
                     <li>
                     <li>
                        <form action="${ url(app_name + ':show_tables') }" id="db_form" method="POST">
                        <form action="${ url(app_name + ':show_tables') }" id="db_form" method="POST">
-                         ${ db_form }
+                         ${ db_form | n,unicode }
                        </form>
                        </form>
                     </li>
                     </li>
                     <li class="nav-header">${_('Actions')}</li>
                     <li class="nav-header">${_('Actions')}</li>
@@ -138,4 +138,4 @@ ${layout.menubar(section='tables')}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 5 - 5
apps/beeswax/src/beeswax/templates/watch_results.mako

@@ -22,7 +22,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="util" file="util.mako" />
 <%namespace name="util" file="util.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 <%namespace name="comps" file="beeswax_components.mako" />
 
 
-${commonheader(_('Query Results'), app_name, user, '100px')}
+${ commonheader(_('Query Results'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='query')}
 ${layout.menubar(section='query')}
 
 
 <style>
 <style>
@@ -115,7 +115,7 @@ ${layout.menubar(section='query')}
             % if error:
             % if error:
               <div class="alert alert-error">
               <div class="alert alert-error">
                 <h3>${_('Error!')}</h3>
                 <h3>${_('Error!')}</h3>
-                <pre>${error_message | h}</pre>
+                <pre>${ error_message }</pre>
               </div>
               </div>
             % else:
             % else:
             % if expected_first_row != start_row:
             % if expected_first_row != start_row:
@@ -155,11 +155,11 @@ ${layout.menubar(section='query')}
         </div>
         </div>
 
 
         <div class="tab-pane" id="query">
         <div class="tab-pane" id="query">
-          <pre>${query.query | h}</pre>
+          <pre>${ query.query }</pre>
         </div>
         </div>
 
 
         <div class="tab-pane" id="log">
         <div class="tab-pane" id="log">
-          <pre>${log | h}</pre>
+          <pre>${ log }</pre>
         </div>
         </div>
 
 
         % if not error:
         % if not error:
@@ -327,4 +327,4 @@ ${layout.menubar(section='query')}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 4 - 4
apps/beeswax/src/beeswax/templates/watch_wait.mako

@@ -21,7 +21,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="util" file="util.mako" />
 <%namespace name="util" file="util.mako" />
 
 
-${commonheader(_('Waiting for query...'), app_name, user, '100px')}
+${ commonheader(_('Waiting for query...'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='query')}
 ${layout.menubar(section='query')}
 
 
 ## Required for unit tests
 ## Required for unit tests
@@ -57,10 +57,10 @@ ${layout.menubar(section='query')}
 
 
 		   	<div class="tab-content">
 		   	<div class="tab-content">
 				<div class="active tab-pane" id="log">
 				<div class="active tab-pane" id="log">
-					<pre>${log | h}</pre>
+					<pre>${ log }</pre>
 				</div>
 				</div>
 				<div class="tab-pane" id="query">
 				<div class="tab-pane" id="query">
-					<pre>${query.query | h}</pre>
+					<pre>${ query.query }</pre>
 				</div>
 				</div>
 			</div>
 			</div>
 		</div>
 		</div>
@@ -128,4 +128,4 @@ ${layout.menubar(section='query')}
 </script>
 </script>
 
 
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 14 - 0
apps/beeswax/src/beeswax/tests.py

@@ -1106,6 +1106,20 @@ for x in sys.stdin:
     assert_true('Error' in response.content, response.content)
     assert_true('Error' in response.content, response.content)
 
 
 
 
+  def test_xss_html_escaping(self):
+    client = make_logged_in_client()
+
+    data = {
+        u'settings-next_form_id': [u'1'], u'settings-0-key': [u'"><script>alert(1);</script>'], u'button-submit': [u'Execute'],
+        u'functions-next_form_id': [u'0'], u'settings-0-value': [u'"><script>alert(1);</script>'], u'query-is_parameterized': [u'on'],
+        u'query-query': [u'query'], u'query-database': [u'default'], u'settings-0-_exists': [u'True'], u'file_resources-next_form_id': [u'0']
+     }
+
+    resp = client.post('/beeswax/execute/', data)
+    assert_false('"><script>alert(1);</script>' in resp.content, resp.content)
+    assert_true('&quot;&gt;&lt;script&gt;alert(1);&lt;/script&gt;' in resp.content, resp.content)
+
+
 def test_import_gzip_reader():
 def test_import_gzip_reader():
   """Test the gzip reader in create table"""
   """Test the gzip reader in create table"""
   # Make gzipped data
   # Make gzipped data

+ 3 - 3
apps/filebrowser/src/filebrowser/templates/display.mako

@@ -28,7 +28,7 @@
 %>
 %>
 <%namespace name="fb_components" file="fb_components.mako" />
 <%namespace name="fb_components" file="fb_components.mako" />
 
 
-${commonheader(_('%(filename)s - File Viewer') % dict(filename=truncate(filename)), 'filebrowser', user)}
+${ commonheader(_('%(filename)s - File Viewer') % dict(filename=truncate(filename)), 'filebrowser', user) | n,unicode }
 
 
 
 
 
 
@@ -144,7 +144,7 @@ ${commonheader(_('%(filename)s - File Viewer') % dict(filename=truncate(filename
 		    % endif
 		    % endif
 		      <div>
 		      <div>
 		      % if 'contents' in view:
 		      % if 'contents' in view:
-		             <div><pre>${view['contents']|h}</pre></div>
+		             <div><pre>${view['contents']}</pre></div>
 		      % else:
 		      % else:
 		        <table>
 		        <table>
 		          % for offset, words, masked in view['xxd']:
 		          % for offset, words, masked in view['xxd']:
@@ -214,4 +214,4 @@ ${commonheader(_('%(filename)s - File Viewer') % dict(filename=truncate(filename
 			});
 			});
 		});
 		});
 	</script>
 	</script>
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/filebrowser/src/filebrowser/templates/edit.mako

@@ -26,7 +26,7 @@
 %>
 %>
 <%namespace name="fb_components" file="fb_components.mako" />
 <%namespace name="fb_components" file="fb_components.mako" />
 
 
-${commonheader(_('%(filename)s - File Viewer') % dict(filename=truncate(filename)), 'filebrowser', user)}
+${ commonheader(_('%(filename)s - File Viewer') % dict(filename=truncate(filename)), 'filebrowser', user) | n,unicode }
 
 
 <div class="container-fluid">
 <div class="container-fluid">
 	% if breadcrumbs:
 	% if breadcrumbs:
@@ -115,6 +115,6 @@ ${commonheader(_('%(filename)s - File Viewer') % dict(filename=truncate(filename
 	});
 	});
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }
 
 
 
 

+ 2 - 2
apps/filebrowser/src/filebrowser/templates/fb_components.mako

@@ -39,9 +39,9 @@ from django.utils.translation import ugettext as _
                         <% label = breadcrumb_item['label'] %>
                         <% label = breadcrumb_item['label'] %>
                         %if label == '/':
                         %if label == '/':
                                 <li><a href="/filebrowser/view${breadcrumb_item['url']}"><span
                                 <li><a href="/filebrowser/view${breadcrumb_item['url']}"><span
-                                        class="divider">${label | h}</span></a></li>
+                                        class="divider">${label}</span></a></li>
                         %else:
                         %else:
-                                <li><a href="/filebrowser/view${breadcrumb_item['url']}">${label | h}</a><span class="divider">/</span></li>
+                                <li><a href="/filebrowser/view${breadcrumb_item['url']}">${label}</a><span class="divider">/</span></li>
                         %endif
                         %endif
                         % endfor
                         % endfor
                 </ul>
                 </ul>

+ 2 - 2
apps/filebrowser/src/filebrowser/templates/fileop.mako

@@ -23,7 +23,7 @@ from django.utils.translation import ugettext as _
 
 
 
 
 
 
-${commonheader(_('File Operation'), 'filebrowser', user)}
+${ commonheader(_('File Operation'), 'filebrowser', user) | n,unicode }
 
 
 ## Not sure if enctype breaks anything if used for things other than file upload.
 ## Not sure if enctype breaks anything if used for things other than file upload.
 
 
@@ -46,4 +46,4 @@ ${commonheader(_('File Operation'), 'filebrowser', user)}
 </form>
 </form>
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/filebrowser/src/filebrowser/templates/listdir.mako

@@ -23,7 +23,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="dir" file="listdir_components.mako" />
 <%namespace name="dir" file="listdir_components.mako" />
 <%namespace name="fb_components" file="fb_components.mako" />
 <%namespace name="fb_components" file="fb_components.mako" />
 
 
-${commonheader(_('File Browser'), 'filebrowser', user)}
+${ commonheader(_('File Browser'), 'filebrowser', user) | n,unicode }
 
 
 <div class="container-fluid">
 <div class="container-fluid">
     <h1>${_('File Browser')}</h1>
     <h1>${_('File Browser')}</h1>
@@ -76,4 +76,4 @@ ${commonheader(_('File Browser'), 'filebrowser', user)}
     </div>
     </div>
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 0 - 1
apps/filebrowser/src/filebrowser/views.py

@@ -452,7 +452,6 @@ def listdir_paged(request, path):
         'page': _massage_page(page),
         'page': _massage_page(page),
         'pagesize': pagesize,
         'pagesize': pagesize,
         'home_directory': request.fs.isdir(home_dir_path) and home_dir_path or None,
         'home_directory': request.fs.isdir(home_dir_path) and home_dir_path or None,
-        'filter_str': filter_str,
         'sortby': sortby,
         'sortby': sortby,
         'descending': descending_param,
         'descending': descending_param,
         # The following should probably be deprecated
         # The following should probably be deprecated

+ 2 - 2
apps/help/src/help/templates/display.mako

@@ -16,7 +16,7 @@
 <%!
 <%!
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 %>
 %>
-${commonheader("Hue Help", "help", user, "100px")}
+${ commonheader("Hue Help", "help", user, "100px") | n,unicode }
 	<div class="subnav subnav-fixed">
 	<div class="subnav subnav-fixed">
 		<div class="container-fluid">
 		<div class="container-fluid">
 		<ul class="nav nav-pills">
 		<ul class="nav nav-pills">
@@ -64,4 +64,4 @@ ${commonheader("Hue Help", "help", user, "100px")}
     });
     });
   </script>
   </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/attempt.mako

@@ -19,7 +19,7 @@
 %>
 %>
 <%namespace name="comps" file="jobbrowser_components.mako" />
 <%namespace name="comps" file="jobbrowser_components.mako" />
 
 
-${commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short), "jobbrowser", user)}
+${ commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short), "jobbrowser", user) | n,unicode }
 <div class="container-fluid">
 <div class="container-fluid">
     <h1>${_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short)}</h1>
     <h1>${_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short)}</h1>
     <div class="row-fluid">
     <div class="row-fluid">
@@ -167,4 +167,4 @@ ${commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=a
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 3 - 3
apps/jobbrowser/src/jobbrowser/templates/attempt_logs.mako

@@ -19,7 +19,7 @@
 %>
 %>
 <%namespace name="comps" file="jobbrowser_components.mako" />
 <%namespace name="comps" file="jobbrowser_components.mako" />
 
 
-${commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short), "jobbrowser", user)}
+${ commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short), "jobbrowser", user) | n,unicode }
 <div class="container-fluid">
 <div class="container-fluid">
     <h1>${_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short)}</h1>
     <h1>${_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short)}</h1>
     <div class="row-fluid">
     <div class="row-fluid">
@@ -68,7 +68,7 @@ ${commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=a
                     <%def name="format_log(raw)">
                     <%def name="format_log(raw)">
                         ## have to remove any indentation here or it breaks inside the pre tags
                         ## have to remove any indentation here or it breaks inside the pre tags
                           % for line in raw.split('\n'):
                           % for line in raw.split('\n'):
-                              ${ line | h,trim }
+                              ${ line | unicode,trim }
                         % endfor
                         % endfor
                     </%def>
                     </%def>
                     <h2>${_('task diagnostic log')}</h2>
                     <h2>${_('task diagnostic log')}</h2>
@@ -137,4 +137,4 @@ ${commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=a
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/job.mako

@@ -90,7 +90,7 @@
     % endfor
     % endfor
 </%def>
 </%def>
 
 
-${commonheader(_('Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short), "jobbrowser", user)}
+${ commonheader(_('Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short), "jobbrowser", user) | n,unicode }
 
 
 <div class="container-fluid">
 <div class="container-fluid">
     <h1>${_('Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short)}</h1>
     <h1>${_('Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short)}</h1>
@@ -394,4 +394,4 @@ ${commonheader(_('Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short),
 </script>
 </script>
 
 
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/job_attempt_logs.mako

@@ -20,7 +20,7 @@
 
 
 <%namespace name="comps" file="jobbrowser_components.mako" />
 <%namespace name="comps" file="jobbrowser_components.mako" />
 
 
-${ commonheader(_('Job Browser - Job Attempt: %(attempt_index)s') % {'attempt_index': attempt_index}, "jobbrowser", user) }
+${ commonheader(_('Job Browser - Job Attempt: %(attempt_index)s') % {'attempt_index': attempt_index}, "jobbrowser", user) | n,unicode }
 
 
 <div class="container-fluid">
 <div class="container-fluid">
     <h1>
     <h1>
@@ -110,4 +110,4 @@ ${ commonheader(_('Job Browser - Job Attempt: %(attempt_index)s') % {'attempt_in
     });
     });
 </script>
 </script>
 
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

+ 3 - 3
apps/jobbrowser/src/jobbrowser/templates/jobs.mako

@@ -29,7 +29,7 @@
 </%def>
 </%def>
 
 
 % if jobs or filtered:
 % if jobs or filtered:
-${commonheader(_('Job Browser'), "jobbrowser", user)}
+${ commonheader(_('Job Browser'), "jobbrowser", user) | n,unicode }
 <div class="container-fluid">
 <div class="container-fluid">
 <h1>${_('Job Browser')}</h1>
 <h1>${_('Job Browser')}</h1>
 <form class="well form-inline" action="/jobbrowser/jobs" method="GET">
 <form class="well form-inline" action="/jobbrowser/jobs" method="GET">
@@ -153,7 +153,7 @@ ${commonheader(_('Job Browser'), "jobbrowser", user)}
     % endif
     % endif
 
 
     % else:
     % else:
-        ${commonheader(_('Job Browser'), "jobbrowser", user)}
+        ${ commonheader(_('Job Browser'), "jobbrowser", user) | n,unicode }
         <div class="container-fluid">
         <div class="container-fluid">
         <h1>${_('Welcome to the Job Browser')}</h1>
         <h1>${_('Welcome to the Job Browser')}</h1>
         <div>
         <div>
@@ -237,4 +237,4 @@ ${commonheader(_('Job Browser'), "jobbrowser", user)}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/task.mako

@@ -19,7 +19,7 @@
 %>
 %>
 <%namespace name="comps" file="jobbrowser_components.mako" />
 <%namespace name="comps" file="jobbrowser_components.mako" />
 
 
-${commonheader(_('Job Task: %(taskId)s - Job Browser') % dict(taskId=task.taskId_short), "jobbrowser", user)}
+${ commonheader(_('Job Task: %(taskId)s - Job Browser') % dict(taskId=task.taskId_short), "jobbrowser", user) | n,unicode }
 
 
 <div class="container-fluid">
 <div class="container-fluid">
     <h1>${_('Job Task: %(taskId)s - Job Browser') % dict(taskId=task.taskId_short)}</h1>
     <h1>${_('Job Task: %(taskId)s - Job Browser') % dict(taskId=task.taskId_short)}</h1>
@@ -200,4 +200,4 @@ ${commonheader(_('Job Task: %(taskId)s - Job Browser') % dict(taskId=task.taskId
 </script>
 </script>
 
 
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/tasks.mako

@@ -21,7 +21,7 @@
 
 
 <%namespace name="comps" file="jobbrowser_components.mako" />
 <%namespace name="comps" file="jobbrowser_components.mako" />
 
 
-${ commonheader(_('Task View: Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short), "jobbrowser", user) }
+${ commonheader(_('Task View: Job: %(jobId)s - Job Browser') % dict(jobId=job.jobId_short), "jobbrowser", user) | n,unicode }
 
 
 <%def name="selected(val, state)">
 <%def name="selected(val, state)">
     %   if val is not None and state is not None and val in state:
     %   if val is not None and state is not None and val in state:
@@ -127,4 +127,4 @@ ${ commonheader(_('Task View: Job: %(jobId)s - Job Browser') % dict(jobId=job.jo
     });
     });
 </script>
 </script>
 
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/tasktracker.mako

@@ -19,7 +19,7 @@
 %>
 %>
 <%namespace name="comps" file="jobbrowser_components.mako" />
 <%namespace name="comps" file="jobbrowser_components.mako" />
 
 
-${commonheader(_('Tracker: %(trackerId)s - Job Browser') % dict(trackerId=tracker.trackerId), "jobbrowser", user)}
+${ commonheader(_('Tracker: %(trackerId)s - Job Browser') % dict(trackerId=tracker.trackerId), "jobbrowser", user) | n,unicode }
 <div class="container-fluid">
 <div class="container-fluid">
 	<h1>${_('Tracker at %(trackerHost)s on port %(trackerPort)s') % dict(trackerHost=tracker.host, trackerPort=tracker.httpPort)}</h1>
 	<h1>${_('Tracker at %(trackerHost)s on port %(trackerPort)s') % dict(trackerHost=tracker.host, trackerPort=tracker.httpPort)}</h1>
 	<div>
 	<div>
@@ -58,4 +58,4 @@ ${commonheader(_('Tracker: %(trackerId)s - Job Browser') % dict(trackerId=tracke
 	</div>
 	</div>
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/tasktrackers.mako

@@ -19,7 +19,7 @@
 %>
 %>
 
 
 <%namespace name="comps" file="jobbrowser_components.mako" />
 <%namespace name="comps" file="jobbrowser_components.mako" />
-${commonheader(_('Task Trackers - Job Browser'), "jobbrowser", user)}
+${ commonheader(_('Task Trackers - Job Browser'), "jobbrowser", user) | n,unicode }
 
 
 <div class="container-fluid">
 <div class="container-fluid">
 
 
@@ -74,4 +74,4 @@ $(document).ready(function(){
 });
 });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 21 - 16
apps/jobsub/src/jobsub/templates/edit_design.mako

@@ -23,7 +23,7 @@ from django.utils.translation import ugettext as _
 
 
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Job Designer'), "jobsub", user, "100px")}
+${ commonheader(_('Job Designer'), "jobsub", user, "100px") | n,unicode }
 ${layout.menubar(section='designs')}
 ${layout.menubar(section='designs')}
 
 
 
 
@@ -33,17 +33,21 @@ ${layout.menubar(section='designs')}
 <script src="/static/ext/js/jquery/plugins/jquery-ui-autocomplete-1.8.18.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/jquery/plugins/jquery-ui-autocomplete-1.8.18.min.js" type="text/javascript" charset="utf-8"></script>
 
 
 
 
-<%def name="render_field(field)">
-  %if not field.is_hidden:
-    <% group_class = len(field.errors) and "error" or "" %>
-    <div class="control-group ${group_class}">
-      <label class="control-label">${field.label | n}</label>
+
+
+<%def name="render_field(field, show_label=True, extra_attrs={})">
+  % if not field.is_hidden:
+    <% group_class = field.errors and "error" or "" %>
+    <div class="control-group ${group_class}"
+      rel="popover" data-original-title="${ field.label }" data-content="${ field.help_text }">
+      % if show_label:
+        <label class="control-label">${ field.label }</label>
+      % endif
       <div class="controls">
       <div class="controls">
-        <input type="text" name="${field.html_name | n}"
-            class="span5 ${field.field.widget.attrs.get('class', '')}"
-            value="${extract_field_data(field) or ''}" />
-        % if len(field.errors):
-          <span class="help-inline">${unicode(field.errors) | n}</span>
+        <% field.field.widget.attrs.update(extra_attrs) %>
+        ${ field | n,unicode }
+        % if field.errors:
+          <span class="help-inline">${ unicode(field.errors) | n,unicode }</span>
         % endif
         % endif
       </div>
       </div>
     </div>
     </div>
@@ -198,7 +202,7 @@ ${layout.menubar(section='designs')}
 
 
 <script type="text/javascript" charset="utf-8">
 <script type="text/javascript" charset="utf-8">
     $(document).ready(function(){
     $(document).ready(function(){
-        var propertiesHint = ${properties_hint};
+        var propertiesHint = ${ properties_hint | n,unicode };
 
 
         // The files and archives are dictionaries in the model, because we
         // The files and archives are dictionaries in the model, because we
         // can add and remove it the same way we add/remove properties.
         // can add and remove it the same way we add/remove properties.
@@ -287,9 +291,10 @@ ${layout.menubar(section='designs')}
             };
             };
         };
         };
 
 
-        var viewModel = new ViewModel(${properties},
-                arrayToDictArray(${files}),
-                arrayToDictArray(${archives}));
+        var viewModel = new ViewModel(
+                ${ properties | n,unicode },
+                arrayToDictArray(${ files | n,unicode }),
+                arrayToDictArray(${ archives | n,unicode }));
 
 
         ko.bindingHandlers.fileChooser = {
         ko.bindingHandlers.fileChooser = {
             init: function(element, valueAccessor, allBindings, model) {
             init: function(element, valueAccessor, allBindings, model) {
@@ -327,4 +332,4 @@ ${layout.menubar(section='designs')}
 </script>
 </script>
 
 
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 5 - 4
apps/jobsub/src/jobsub/templates/list_designs.mako

@@ -20,10 +20,11 @@ import urllib
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
+
 <%namespace name="commonlayout" file="layout.mako" />
 <%namespace name="commonlayout" file="layout.mako" />
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="actionbar" file="actionbar.mako" />
 
 
-${commonheader(_('Job Designer'), "jobsub", user, "100px")}
+${ commonheader(_('Job Designer'), "jobsub", user, "100px") | n,unicode }
 ${commonlayout.menubar(section='designs')}
 ${commonlayout.menubar(section='designs')}
 
 
 <script src="/static/ext/js/datatables-paging-0.1.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/datatables-paging-0.1.js" type="text/javascript" charset="utf-8"></script>
@@ -144,7 +145,6 @@ ${layout()}
     var submitMessage = "${_('Submit %(name)s to the cluster') % dict(name='##PLACEHOLDER##')}";
     var submitMessage = "${_('Submit %(name)s to the cluster') % dict(name='##PLACEHOLDER##')}";
 
 
     $(document).ready(function() {
     $(document).ready(function() {
-
         var designTable, viewModel;
         var designTable, viewModel;
 
 
         $("#filterInput").keyup(function() {
         $("#filterInput").keyup(function() {
@@ -157,7 +157,7 @@ ${layout()}
             $("#installSamples").modal("show");
             $("#installSamples").modal("show");
         });
         });
 
 
-        viewModel = new JobSubModel(${designs});
+        viewModel = new JobSubModel(${ designs | n });
         ko.applyBindings(viewModel);
         ko.applyBindings(viewModel);
         designTable = $('#designTable').dataTable( {
         designTable = $('#designTable').dataTable( {
             "sPaginationType": "bootstrap",
             "sPaginationType": "bootstrap",
@@ -196,4 +196,5 @@ ${layout()}
         $("a[data-row-selector='true']").jHueRowSelector();
         $("a[data-row-selector='true']").jHueRowSelector();
     });
     });
 </script>
 </script>
-${commonfooter(messages)}
+
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/jobsub/src/jobsub/templates/list_history.mako

@@ -24,7 +24,7 @@ from django.utils.translation import ugettext as _
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="actionbar" file="actionbar.mako" />
 
 
-${commonheader(_('Job Designer'), "jobsub", user, "100px")}
+${ commonheader(_('Job Designer'), "jobsub", user, "100px") | n,unicode }
 ${layout.menubar(section='history')}
 ${layout.menubar(section='history')}
 
 
 <script src="/static/ext/js/datatables-paging-0.1.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/datatables-paging-0.1.js" type="text/javascript" charset="utf-8"></script>
@@ -98,4 +98,4 @@ ${layout.menubar(section='history')}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 4 - 4
apps/jobsub/src/jobsub/templates/workflow.mako

@@ -22,7 +22,7 @@
 %>
 %>
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_("Job Designer"), "jobsub", user, "100px")}
+${ commonheader(_("Job Designer"), "jobsub", user, "100px") | n,unicode }
 ${layout.menubar(section='history')}
 ${layout.menubar(section='history')}
 
 
 <%def name="format_time(st_time)">
 <%def name="format_time(st_time)">
@@ -198,12 +198,12 @@ ${layout.menubar(section='history')}
 
 
         ## Tab: Definition
         ## Tab: Definition
         <div class="tab-pane" id="definition">
         <div class="tab-pane" id="definition">
-          <textarea id="definitionEditor">${definition|h}</textarea>
+          <textarea id="definitionEditor">${ definition }</textarea>
         </div>
         </div>
 
 
         ## Tab: Log
         ## Tab: Log
         <div class="tab-pane" id="log">
         <div class="tab-pane" id="log">
-            <pre>${log|h}</pre>
+            <pre>${log}</pre>
         </div>
         </div>
     </ul>
     </ul>
   </div>
   </div>
@@ -238,4 +238,4 @@ ${configModal("appConfigModal", "Application Configuration", workflow.conf_dict)
   });
   });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 22 - 9
apps/jobsub/src/jobsub/tests.py

@@ -19,6 +19,11 @@ import copy
 import logging
 import logging
 import time
 import time
 
 
+try:
+  import json
+except ImportError:
+  import simplejson as json
+
 from nose.tools import assert_true, assert_false, assert_equal, assert_raises
 from nose.tools import assert_true, assert_false, assert_equal, assert_raises
 from django.contrib.auth.models import User
 from django.contrib.auth.models import User
 
 
@@ -30,6 +35,7 @@ from jobsub import conf
 from jobsub.management.commands import jobsub_setup
 from jobsub.management.commands import jobsub_setup
 from jobsub.models import OozieDesign, OozieMapreduceAction, OozieStreamingAction, CheckForSetup
 from jobsub.models import OozieDesign, OozieMapreduceAction, OozieStreamingAction, CheckForSetup
 from jobsub.parameterization import recursive_walk, find_variables, substitute_variables
 from jobsub.parameterization import recursive_walk, find_variables, substitute_variables
+from django.template.defaultfilters import escapejs
 
 
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)
@@ -141,29 +147,32 @@ def test_job_design_cycle():
   # Now check list
   # Now check list
   response = c.get('/jobsub/')
   response = c.get('/jobsub/')
   for design in OozieDesign.objects.all():
   for design in OozieDesign.objects.all():
-    assert_true(design.name in response.content, response.content)
+    assert_true(escape(design.name) in response.content, response.content)
 
 
   # With some filters
   # With some filters
+  name1 = escape('name-1')
+  name2 = escape('name-2')
+
   response = c.get('/jobsub/', dict(name='name-1'))
   response = c.get('/jobsub/', dict(name='name-1'))
-  assert_true('name-1' in response.content, response.content)
-  assert_false('name-2' in response.content, response.content)
+  assert_true(name1 in response.content, response.content)
+  assert_false(name2 in response.content, response.content)
 
 
   response = c.get('/jobsub/', dict(owner='doesnotexist'))
   response = c.get('/jobsub/', dict(owner='doesnotexist'))
   assert_false('doesnotexist' in response.content)
   assert_false('doesnotexist' in response.content)
 
 
   response = c.get('/jobsub/', dict(owner='test', name='name-1'))
   response = c.get('/jobsub/', dict(owner='test', name='name-1'))
-  assert_true('name-1' in response.content, response.content)
-  assert_false('name-2' in response.content, response.content)
+  assert_true(name1 in response.content, response.content)
+  assert_false(name2 in response.content, response.content)
 
 
   response = c.get('/jobsub/', dict(name="name"))
   response = c.get('/jobsub/', dict(name="name"))
-  assert_true('name-1' in response.content, response.content)
-  assert_true('name-2' in response.content, response.content)
+  assert_true(name1 in response.content, response.content)
+  assert_true(name2 in response.content, response.content)
   assert_false('doesnotexist' in response.content, response.content)
   assert_false('doesnotexist' in response.content, response.content)
 
 
   # Combined filters
   # Combined filters
   response = c.get('/jobsub/', dict(owner="test", name="name-2"))
   response = c.get('/jobsub/', dict(owner="test", name="name-2"))
-  assert_false('name-1' in response.content, response.content)
-  assert_true('name-2' in response.content, response.content)
+  assert_false(name1 in response.content, response.content)
+  assert_true(name2 in response.content, response.content)
   assert_false('doesnotexist' in response.content, response.content)
   assert_false('doesnotexist' in response.content, response.content)
 
 
   # Try delete
   # Try delete
@@ -181,6 +190,10 @@ def test_job_design_cycle():
   assert_true('Permission denied.' in response.content, response.content)
   assert_true('Permission denied.' in response.content, response.content)
 
 
 
 
+def escape(text):
+  return json.dumps(escapejs(text))
+
+
 class TestJobsubWithHadoop(OozieServerProvider):
 class TestJobsubWithHadoop(OozieServerProvider):
 
 
   def setUp(self):
   def setUp(self):

+ 5 - 4
apps/jobsub/src/jobsub/views.py

@@ -14,6 +14,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
+from django.template.defaultfilters import escapejs
 """
 """
 Views for JobSubmission.
 Views for JobSubmission.
 
 
@@ -159,9 +160,9 @@ def list_designs(request):
   for design in data:
   for design in data:
       ko_design = {
       ko_design = {
           'id': design.id,
           'id': design.id,
-          'owner': design.owner.username,
-          'name': design.name,
-          'description': design.description,
+          'owner': escapejs(design.owner.username),
+          'name': escapejs(design.name),
+          'description': escapejs(design.description),
           'type': design.root_action.action_type,
           'type': design.root_action.action_type,
           'last_modified': py_time.mktime(design.last_modified.timetuple()),
           'last_modified': py_time.mktime(design.last_modified.timetuple()),
           'url_params': urlresolvers.reverse(jobsub.views.get_design_params, kwargs={'design_id': design.id}),
           'url_params': urlresolvers.reverse(jobsub.views.get_design_params, kwargs={'design_id': design.id}),
@@ -175,7 +176,7 @@ def list_designs(request):
       designs.append(ko_design)
       designs.append(ko_design)
 
 
   return render("list_designs.mako", request, {
   return render("list_designs.mako", request, {
-    'currentuser':request.user,
+    'currentuser': request.user,
     'owner': owner,
     'owner': owner,
     'name': name,
     'name': name,
     'designs': json.dumps(designs),
     'designs': json.dumps(designs),

+ 17 - 3
apps/oozie/src/oozie/models.py

@@ -17,6 +17,7 @@
 
 
 import logging
 import logging
 import time
 import time
+from django.template.defaultfilters import escapejs
 
 
 try:
 try:
   import json
   import json
@@ -147,6 +148,16 @@ class Job(models.Model):
   def get_parameters(self):
   def get_parameters(self):
     return json.loads(self.parameters)
     return json.loads(self.parameters)
 
 
+  @property
+  def parameters_escapejs(self):
+    return self._escapejs_parameters_list(self.parameters)
+
+  def _escapejs_parameters_list(self, parameters):
+    escaped = []
+    for item in json.loads(parameters):
+      escaped.append({"name": escapejs(item["name"]), "value": escapejs(item["value"])})
+    return json.dumps(escaped)
+
   @property
   @property
   def status(self):
   def status(self):
     if self.is_shared:
     if self.is_shared:
@@ -296,6 +307,10 @@ class Workflow(Job):
 
 
     return copy
     return copy
 
 
+  @property
+  def job_properties_escapejs(self):
+    return self._escapejs_parameters_list(self.job_properties)
+
   def has_cycle(self):
   def has_cycle(self):
     """
     """
     Topological sort for detecting cycles in the directed graph.
     Topological sort for detecting cycles in the directed graph.
@@ -316,7 +331,6 @@ class Workflow(Job):
 
 
     return len(graph_edges - removed_edges) > 0 # Graph does not have unseen edges
     return len(graph_edges - removed_edges) > 0 # Graph does not have unseen edges
 
 
-
   def find_parameters(self):
   def find_parameters(self):
     params = set()
     params = set()
 
 
@@ -939,8 +953,8 @@ class Email(Action):
   PARAM_FIELDS = ('to', 'cc', 'subject', 'body')
   PARAM_FIELDS = ('to', 'cc', 'subject', 'body')
   node_type = 'email'
   node_type = 'email'
 
 
-  to = models.TextField(default='', verbose_name=_t('to addresses'), help_text=_t('Comma-separated values.'))
-  cc = models.TextField(default='', verbose_name=_t('cc addresses (optional)'), blank=True, help_text=_t('Comma-separated values.'))
+  to = models.TextField(default='', verbose_name=_t('TO addresses'), help_text=_t('Comma-separated values.'))
+  cc = models.TextField(default='', verbose_name=_t('CC addresses (optional)'), blank=True, help_text=_t('Comma-separated values.'))
   subject = models.TextField(default='', verbose_name=_t('Subject'), help_text=_t('Plain-text.'))
   subject = models.TextField(default='', verbose_name=_t('Subject'), help_text=_t('Plain-text.'))
   body = models.TextField(default='', verbose_name=_t('Body'), help_text=_t('Plain-text.'))
   body = models.TextField(default='', verbose_name=_t('Body'), help_text=_t('Plain-text.'))
 
 

+ 4 - 4
apps/oozie/src/oozie/templates/dashboard/list_oozie_coordinator.mako

@@ -22,7 +22,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='dashboard') }
 ${ layout.menubar(section='dashboard') }
 
 
 
 
@@ -211,11 +211,11 @@ ${ layout.menubar(section='dashboard') }
     </div>
     </div>
 
 
     <div class="tab-pane" id="log">
     <div class="tab-pane" id="log">
-        <pre>${ oozie_coordinator.log | h }</pre>
+        <pre>${ oozie_coordinator.log }</pre>
     </div>
     </div>
 
 
     <div class="tab-pane" id="definition">
     <div class="tab-pane" id="definition">
-        <pre>${ oozie_coordinator.definition | h }</pre>
+        <pre>${ oozie_coordinator.definition }</pre>
     </div>
     </div>
     </div>
     </div>
   </div>
   </div>
@@ -263,4 +263,4 @@ ${ layout.menubar(section='dashboard') }
   });
   });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/oozie/src/oozie/templates/dashboard/list_oozie_coordinators.mako

@@ -22,7 +22,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${commonheader(_("Oozie App"), "oozie", user, "100px")}
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${layout.menubar(section='dashboard')}
 ${layout.menubar(section='dashboard')}
 
 
 
 
@@ -312,4 +312,4 @@ ${layout.menubar(section='dashboard')}
   });
   });
 </script>
 </script>
 
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

+ 7 - 7
apps/oozie/src/oozie/templates/dashboard/list_oozie_workflow.mako

@@ -23,7 +23,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='dashboard') }
 ${ layout.menubar(section='dashboard') }
 
 
 
 
@@ -100,10 +100,10 @@ ${ layout.menubar(section='dashboard') }
         <div class="row-fluid">
         <div class="row-fluid">
           <div class="span3"></div>
           <div class="span3"></div>
           <div class="span3">
           <div class="span3">
-            ${ var | h }
+            ${ var }
           </div>
           </div>
           <div class="span3">
           <div class="span3">
-            ${ utils.guess_hdfs_link(var, str(value)) | h }
+            ${ utils.guess_hdfs_link(var, str(value)) }
           </div>
           </div>
         </div>
         </div>
       % endif
       % endif
@@ -168,7 +168,7 @@ ${ layout.menubar(section='dashboard') }
            forms = WorkflowFormSet(instance=hue_workflow.get_full_node()).forms
            forms = WorkflowFormSet(instance=hue_workflow.get_full_node()).forms
          %>
          %>
 
 
-           ${ hue_workflow.get_full_node().gen_status_graph(forms, oozie_workflow.get_working_actions()) }
+           ${ hue_workflow.get_full_node().gen_status_graph(forms, oozie_workflow.get_working_actions()) | n,unicode }
          % endif
          % endif
        </div>
        </div>
      % endif
      % endif
@@ -272,11 +272,11 @@ ${ layout.menubar(section='dashboard') }
       </div>
       </div>
 
 
       <div class="tab-pane" id="log">
       <div class="tab-pane" id="log">
-          <pre>${ oozie_workflow.log | h }</pre>
+          <pre>${ oozie_workflow.log }</pre>
       </div>
       </div>
 
 
       <div class="tab-pane" id="definition">
       <div class="tab-pane" id="definition">
-          <textarea id="definitionEditor">${ oozie_workflow.definition | h }</textarea>
+          <textarea id="definitionEditor">${ oozie_workflow.definition }</textarea>
       </div>
       </div>
   </div>
   </div>
 
 
@@ -368,4 +368,4 @@ ${ layout.menubar(section='dashboard') }
   });
   });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/oozie/src/oozie/templates/dashboard/list_oozie_workflow_action.mako

@@ -22,7 +22,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='running') }
 ${ layout.menubar(section='running') }
 
 
 
 
@@ -130,4 +130,4 @@ ${ layout.menubar(section='running') }
   <a class="btn" onclick="history.back()">${ _('Back') }</a>
   <a class="btn" onclick="history.back()">${ _('Back') }</a>
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/oozie/src/oozie/templates/dashboard/list_oozie_workflows.mako

@@ -23,7 +23,7 @@
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='dashboard') }
 ${ layout.menubar(section='dashboard') }
 
 
 
 
@@ -307,4 +307,4 @@ ${ layout.menubar(section='dashboard') }
   });
   });
 </script>
 </script>
 
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

+ 3 - 3
apps/oozie/src/oozie/templates/dashboard/rerun_job_popup.mako

@@ -48,7 +48,7 @@
       </div>
       </div>
 
 
       <div id="param-container">
       <div id="param-container">
-        ${ params_form.management_form }
+        ${ params_form.management_form | n,unicode }
 
 
         % if params_form.forms:
         % if params_form.forms:
           % if len(params_form.forms) > 1:
           % if len(params_form.forms) > 1:
@@ -56,7 +56,7 @@
           % endif
           % endif
           % for form in params_form.forms:
           % for form in params_form.forms:
             % for hidden in form.hidden_fields():
             % for hidden in form.hidden_fields():
-              ${ hidden }
+              ${ hidden | n,unicode }
             % endfor
             % endfor
             <div class="fieldWrapper">
             <div class="fieldWrapper">
               <div class="row-fluid
               <div class="row-fluid
@@ -94,4 +94,4 @@
             height:100
             height:100
         });
         });
     });
     });
-</script>
+</script>

+ 1 - 1
apps/oozie/src/oozie/templates/editor/action_utils.mako

@@ -30,7 +30,7 @@
     <form class="form-horizontal" id="import-node-form" method="POST">
     <form class="form-horizontal" id="import-node-form" method="POST">
       <div class="modal-header">
       <div class="modal-header">
         <a href="#" class="close">&times;</a>
         <a href="#" class="close">&times;</a>
-        <h3 class="message">${_('Import Node')}</h3>
+        <h3 class="message">${_('Import Action')}</h3>
       </div>
       </div>
 
 
       <div class="modal-content">
       <div class="modal-content">

+ 1 - 1
apps/oozie/src/oozie/templates/editor/control_utils.mako

@@ -82,7 +82,7 @@
                 <br/>
                 <br/>
                 ${"${"} hadoop:counters('secondjob')[RECORDS][REDUCE_OUT] lt 1000000 }
                 ${"${"} hadoop:counters('secondjob')[RECORDS][REDUCE_OUT] lt 1000000 }
                 <br/>
                 <br/>
-                <a href="http://oozie.apache.org/docs/3.3.0/WorkflowFunctionalSpec.html#a4.2_Expression_Language_Functions">More on predicates</a>
+                <a href="http://oozie.apache.org/docs/3.3.0/WorkflowFunctionalSpec.html#a4.2_Expression_Language_Functions">${ _('More on predicates') }</a>
               </div>
               </div>
             </div>
             </div>
           </div>
           </div>

+ 8 - 8
apps/oozie/src/oozie/templates/editor/coordinator_properties.mako

@@ -62,34 +62,34 @@
 
 
 </%def>
 </%def>
 
 
-<%def name="init_viewmodel(element, initial_value)">
+<%def name="init_viewmodel(coordinator)">
   <script type="text/javascript">
   <script type="text/javascript">
     $(document).ready(function(){
     $(document).ready(function(){
-      var ViewModel = function(${ element }) {
+      var ViewModel = function() {
         var self = this;
         var self = this;
-        self.${ element } = ko.observableArray(${ element });
+        self.parameters = ko.observableArray(${ coordinator.parameters_escapejs | n });
 
 
         self.add_parameters = function() {
         self.add_parameters = function() {
-          self.${ element }.push({name: "", value: ""});
+          self.parameters.push({name: "", value: ""});
         };
         };
 
 
         self.remove_parameters = function(val) {
         self.remove_parameters = function(val) {
-          self.${ element }.remove(val);
+          self.parameters.remove(val);
         };
         };
 
 
         self.submit = function(form) {
         self.submit = function(form) {
           var form = $("#jobForm");
           var form = $("#jobForm");
 
 
           $("<input>").attr("type", "hidden")
           $("<input>").attr("type", "hidden")
-                  .attr("name", "${ element }")
-                  .attr("value", ko.utils.stringifyJson(self.${ element }))
+                  .attr("name", "parameters")
+                  .attr("value", ko.utils.stringifyJson(self.parameters))
                   .appendTo(form);
                   .appendTo(form);
 
 
           form.submit();
           form.submit();
         };
         };
       };
       };
 
 
-      window.viewModel = new ViewModel(${ initial_value });
+      window.viewModel = new ViewModel();
     });
     });
   </script>
   </script>
 </%def>
 </%def>

+ 2 - 2
apps/oozie/src/oozie/templates/editor/create_coordinator.mako

@@ -22,7 +22,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='coordinators') }
 ${ layout.menubar(section='coordinators') }
 
 
 <style type="text/css">
 <style type="text/css">
@@ -229,4 +229,4 @@ ${ layout.menubar(section='coordinators') }
 
 
 ${ utils.decorate_datetime_fields() }
 ${ utils.decorate_datetime_fields() }
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 1 - 1
apps/oozie/src/oozie/templates/editor/create_coordinator_data.mako

@@ -54,7 +54,7 @@ from django.utils.safestring import mark_safe
 
 
   <button type="button" class="btn" data-bind="click: add_${ element }">${ _('Add') }</button>
   <button type="button" class="btn" data-bind="click: add_${ element }">${ _('Add') }</button>
 
 
-  ${ formset.management_form }
+  ${ formset.management_form | n,unicode }
 
 
   </div>
   </div>
 
 

+ 2 - 2
apps/oozie/src/oozie/templates/editor/create_workflow.mako

@@ -22,7 +22,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='workflows') }
 ${ layout.menubar(section='workflows') }
 
 
 
 
@@ -89,4 +89,4 @@ ${ utils.path_chooser_libs(True, True) }
   });
   });
 </script>
 </script>
 
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

+ 3 - 3
apps/oozie/src/oozie/templates/editor/dataset_utils.mako

@@ -58,9 +58,9 @@
 </div>
 </div>
 
 
 <div class="hide">
 <div class="hide">
-    ${ dataset_form['instance_choice'] }
-    ${ dataset_form['advanced_start_instance'] }
-    ${ dataset_form['advanced_end_instance'] }
+    ${ dataset_form['instance_choice'] | n,unicode }
+    ${ dataset_form['advanced_start_instance'] | n,unicode }
+    ${ dataset_form['advanced_end_instance'] | n,unicode  }
 </div>
 </div>
 
 
 <script type="text/javascript">
 <script type="text/javascript">

+ 15 - 15
apps/oozie/src/oozie/templates/editor/edit_coordinator.mako

@@ -24,7 +24,7 @@
 <%namespace name="properties" file="coordinator_properties.mako" />
 <%namespace name="properties" file="coordinator_properties.mako" />
 <%namespace name="coordinator_data" file="create_coordinator_data.mako" />
 <%namespace name="coordinator_data" file="create_coordinator_data.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='coordinators') }
 ${ layout.menubar(section='coordinators') }
 
 
 <style type="text/css">
 <style type="text/css">
@@ -86,10 +86,10 @@ ${ layout.menubar(section='coordinators') }
           <li><a href="#step4" class="step">${ _('Step 4: Outputs') }</a></li>
           <li><a href="#step4" class="step">${ _('Step 4: Outputs') }</a></li>
           <li><a href="#step5" class="step">${ _('Step 5: Advanced settings') }</a></li>
           <li><a href="#step5" class="step">${ _('Step 5: Advanced settings') }</a></li>
         </ul>
         </ul>
-        ${ dataset_formset.management_form }
-        ${ data_input_formset.management_form }
-        ${ data_output_formset.management_form }
-        ${ properties.init_viewmodel('parameters', parameters) }
+        ${ dataset_formset.management_form | n,unicode }
+        ${ data_input_formset.management_form | n,unicode }
+        ${ data_output_formset.management_form | n,unicode }
+        ${ properties.init_viewmodel(coordinator) }
         <div class="steps">
         <div class="steps">
 
 
           <div id="step1" class="stepDetails">
           <div id="step1" class="stepDetails">
@@ -98,7 +98,7 @@ ${ layout.menubar(section='coordinators') }
               ${ utils.render_field_no_popover(coordinator_form['name'], extra_attrs = {'validate':'true'}) }
               ${ utils.render_field_no_popover(coordinator_form['name'], extra_attrs = {'validate':'true'}) }
               ${ utils.render_field_no_popover(coordinator_form['description']) }
               ${ utils.render_field_no_popover(coordinator_form['description']) }
               ${ utils.render_field_no_popover(coordinator_form['workflow'], extra_attrs = {'validate':'true'}) }
               ${ utils.render_field_no_popover(coordinator_form['workflow'], extra_attrs = {'validate':'true'}) }
-              ${ coordinator_form['parameters'] }
+              ${ coordinator_form['parameters'] | n,unicode }
               <div class="hide">
               <div class="hide">
                 ${ utils.render_field(coordinator_form['timeout']) }
                 ${ utils.render_field(coordinator_form['timeout']) }
                 ${ coordinator_form['schema_version'] }
                 ${ coordinator_form['schema_version'] }
@@ -156,12 +156,12 @@ ${ layout.menubar(section='coordinators') }
                 <tbody>
                 <tbody>
                 % for form in data_input_formset.forms:
                 % for form in data_input_formset.forms:
                 <tr>
                 <tr>
-                ${ form['id'] }
+                  ${ form['id'] }
                   <td>${ form['name'] }</td>
                   <td>${ form['name'] }</td>
                   <td>${ form['dataset'] }</td>
                   <td>${ form['dataset'] }</td>
                   <td>${ form['dataset'].form.instance.dataset.uri }</td>
                   <td>${ form['dataset'].form.instance.dataset.uri }</td>
                 % if coordinator.is_editable(user):
                 % if coordinator.is_editable(user):
-                  <td><a class="btn btn-small delete-row" href="javascript:void(0);">${ _('Delete') }${ form['DELETE'] }</a></td>
+                  <td><a class="btn btn-small delete-row" href="javascript:void(0);">${ _('Delete') }${ form['DELETE'] | n,unicode }</a></td>
                 % endif
                 % endif
                 </tr>
                 </tr>
                 % endfor
                 % endfor
@@ -214,7 +214,7 @@ ${ layout.menubar(section='coordinators') }
                     <td>${ form['dataset'] }</td>
                     <td>${ form['dataset'] }</td>
                     <td>${ form['dataset'].form.instance.dataset.uri }</td>
                     <td>${ form['dataset'].form.instance.dataset.uri }</td>
                     % if coordinator.is_editable(user):
                     % if coordinator.is_editable(user):
-                      <td><a class="btn btn-small delete-row" href="javascript:void(0);">${ _('Delete') }${ form['DELETE'] }</a></td>
+                      <td><a class="btn btn-small delete-row" href="javascript:void(0);">${ _('Delete') }${ form['DELETE'] | n,unicode }</a></td>
                     % endif
                     % endif
                   </tr>
                   </tr>
                 % endfor
                 % endfor
@@ -250,7 +250,7 @@ ${ layout.menubar(section='coordinators') }
               </div>
               </div>
             </div>
             </div>
             ${ utils.render_field_no_popover(coordinator_form['execution']) }
             ${ utils.render_field_no_popover(coordinator_form['execution']) }
-            ${ coordinator_form['schema_version'] }
+            ${ coordinator_form['schema_version'] | n,unicode }
           </div>
           </div>
 
 
         </div>
         </div>
@@ -311,7 +311,7 @@ ${ layout.menubar(section='coordinators') }
               <tbody>
               <tbody>
               % for form in dataset_formset.forms:
               % for form in dataset_formset.forms:
                 % for hidden in form.hidden_fields():
                 % for hidden in form.hidden_fields():
-                  ${ hidden }
+                  ${ hidden | n,unicode }
                 % endfor
                 % endfor
                 <tr>
                 <tr>
                   <td>
                   <td>
@@ -328,15 +328,15 @@ ${ layout.menubar(section='coordinators') }
                   <td>${ form.instance.done_flag }</td>
                   <td>${ form.instance.done_flag }</td>
                   % if coordinator.is_editable(user):
                   % if coordinator.is_editable(user):
                     <td data-row-selector-exclude="true">
                     <td data-row-selector-exclude="true">
-                      <a class="btn btn-small delete-row" href="javascript:void(0);">${ _('Delete') }${ form['DELETE'] }</a>
+                      <a class="btn btn-small delete-row" href="javascript:void(0);">${ _('Delete') }${ form['DELETE'] | n,unicode }</a>
                     </td>
                     </td>
                   % endif
                   % endif
                 </tr>
                 </tr>
 
 
                 <div class="hide">
                 <div class="hide">
                   % for field in form.visible_fields():
                   % for field in form.visible_fields():
-                  ${ field.errors }
-                  ${ field.label }: ${ field }
+                  ${ field.errors | n,unicode }
+                  ${ field.label }: ${ field | n,unicode }
                   % endfor
                   % endfor
                 </div>
                 </div>
               % endfor
               % endfor
@@ -697,4 +697,4 @@ ${ layout.menubar(section='coordinators') }
 
 
 ${ utils.decorate_datetime_fields() }
 ${ utils.decorate_datetime_fields() }
 
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

+ 6 - 5
apps/oozie/src/oozie/templates/editor/edit_workflow.mako

@@ -17,6 +17,7 @@
 <%!
 <%!
   from desktop.views import commonheader, commonfooter
   from desktop.views import commonheader, commonfooter
   from django.utils.translation import ugettext as _
   from django.utils.translation import ugettext as _
+  from django.template.defaultfilters import escapejs
 %>
 %>
 
 
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
@@ -25,7 +26,7 @@
 <%namespace name="controls" file="control_utils.mako" />
 <%namespace name="controls" file="control_utils.mako" />
 <%namespace name="workflows" file="workflow_utils.mako" />
 <%namespace name="workflows" file="workflow_utils.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='workflows') }
 ${ layout.menubar(section='workflows') }
 
 
 
 
@@ -160,7 +161,7 @@ ${ layout.menubar(section='workflows') }
               <div class="tab-pane" id="import">
               <div class="tab-pane" id="import">
                 <p>
                 <p>
                 <a title="${ _('Click to add to the end of the workflow') }" class="btn import-jobsub-node-link">
                 <a title="${ _('Click to add to the end of the workflow') }" class="btn import-jobsub-node-link">
-                  <i class="icon-plus"></i> ${ _('Import Job Designer Workflow') }
+                  <i class="icon-plus"></i> ${ _('Job Designer Workflow') }
                 </a>
                 </a>
                 <p/>
                 <p/>
               </div>
               </div>
@@ -489,8 +490,8 @@ var workflow_model = new WorkflowModel({
   job_xml: "${ workflow.job_xml }",
   job_xml: "${ workflow.job_xml }",
   deployment_dir: "${ workflow.deployment_dir }",
   deployment_dir: "${ workflow.deployment_dir }",
   is_shared: "${ workflow.is_shared }" == "True",
   is_shared: "${ workflow.is_shared }" == "True",
-  parameters: ${ workflow.parameters },
-  job_properties: ${ workflow.job_properties }
+  parameters: ${ workflow.parameters_escapejs | n,unicode },
+  job_properties: ${ workflow.job_properties_escapejs | n,unicode }
 });
 });
 var registry = new Registry();
 var registry = new Registry();
 var workflow = new Workflow({
 var workflow = new Workflow({
@@ -754,4 +755,4 @@ ${ utils.path_chooser_libs(True) }
   });
   });
 </script>
 </script>
 
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

+ 1 - 1
apps/oozie/src/oozie/templates/editor/gen/workflow-generic.xml.mako

@@ -15,7 +15,7 @@
 ## limitations under the License.
 ## limitations under the License.
 
 
     <action name="${ node }">
     <action name="${ node }">
-        ${ node.xml }
+        ${ node.xml | n,unicode }
         <ok to="${ node.get_oozie_child('ok') }"/>
         <ok to="${ node.get_oozie_child('ok') }"/>
         <error to="${ node.get_oozie_child('error') }"/>
         <error to="${ node.get_oozie_child('error') }"/>
     </action>
     </action>

+ 4 - 4
apps/oozie/src/oozie/templates/editor/gen/workflow.xml.mako

@@ -17,18 +17,18 @@
 <%namespace name="common" file="workflow-common.xml.mako" />
 <%namespace name="common" file="workflow-common.xml.mako" />
 
 
 
 
-<workflow-app name="${ workflow.name }" xmlns="${ workflow.schema_version }">
+<workflow-app name="${ workflow.name | x }" xmlns="${ workflow.schema_version }">
   % if workflow.job_xml or workflow.get_properties():
   % if workflow.job_xml or workflow.get_properties():
   <global>
   <global>
     % if workflow.job_xml:
     % if workflow.job_xml:
-      <job-xml>${ workflow.job_xml }</job-xml>
+      <job-xml>${ workflow.job_xml | x }</job-xml>
     % endif
     % endif
     % if workflow.get_properties():
     % if workflow.get_properties():
-      ${ common.configuration(workflow.get_properties()) }
+      ${ common.configuration(workflow.get_properties()) | x }
     % endif
     % endif
   </global>
   </global>
   % endif
   % endif
   % for node in workflow.node_list:
   % for node in workflow.node_list:
-      ${ node.to_xml() }
+      ${ node.to_xml() | n }
   % endfor
   % endfor
 </workflow-app>
 </workflow-app>

+ 2 - 2
apps/oozie/src/oozie/templates/editor/import_workflow.mako

@@ -22,7 +22,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='workflows') }
 ${ layout.menubar(section='workflows') }
 
 
 
 
@@ -82,4 +82,4 @@ ${ layout.menubar(section='workflows') }
 
 
 ${ utils.path_chooser_libs(True) }
 ${ utils.path_chooser_libs(True) }
 
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

+ 0 - 78
apps/oozie/src/oozie/templates/editor/import_workflow_action.mako

@@ -1,78 +0,0 @@
-## Licensed to Cloudera, Inc. under one
-## or more contributor license agreements.  See the NOTICE file
-## distributed with this work for additional information
-## regarding copyright ownership.  Cloudera, Inc. licenses this file
-## to you under the Apache License, Version 2.0 (the
-## "License"); you may not use this file except in compliance
-## with the License.  You may obtain a copy of the License at
-##
-##     http://www.apache.org/licenses/LICENSE-2.0
-##
-## Unless required by applicable law or agreed to in writing, software
-## distributed under the License is distributed on an "AS IS" BASIS,
-## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-## See the License for the specific language governing permissions and
-## limitations under the License.
-
-<%!
-  from django.utils.translation import ugettext as _
-%>
-
-<form id="actionForm" action="${ form_url }" method="POST">
-  <div class="modal-header">
-    <a href="#" class="close" data-dismiss="modal">&times;</a>
-    <h3>${_("Select Job Design to Import")}</h3>
-  </div>
-  <div class="modal-content">
-    <div class="container-fluid">
-      <table id="jobdesignerActionsTable" class="table datatables">
-        <thead>
-          <tr>
-            <th></th>
-            <th>${ _('Name') }</th>
-            <th>${ _('Description') }</th>
-          </tr>
-        </thead>
-        <tbody>
-          %for action in available_actions:
-            <tr class="action-row">
-              <td class=".btn-large action-column" data-row-selector-exclude="true" style="background-color: white;">
-                <input type="radio" name="action_id" value="${ action.id }" />
-              </td>
-              <td>
-                ${ action.name }
-              </td>
-              <td>${ action.description }</td>
-            </tr>
-          %endfor
-          % if not available_actions:
-            <tr class="action-row">
-              <td>${ _('N/A') }</td><td></td><td></td>
-            </tr>
-          % endif
-        </tbody>
-      </table>
-    </div>
-  </div>
-  <div class="modal-footer">
-    <a href="#" class="btn" data-dismiss="modal">${_('Cancel')}</a>
-    <input type="submit" class="btn btn-primary" value="${_('Import')}"/>
-  </div>
-</form>
-
-
-<script src="/static/ext/js/datatables-paging-0.1.js" type="text/javascript" charset="utf-8"></script>
-
-<script type="text/javascript" charset="utf-8">
-  $(document).ready(function() {
-    $(".action-row").click(function(e){
-      var select_btn = $(this).find('input');
-      select_btn.prop("checked", true);
-
-      $(".action-row").css("background-color", "");
-      $(this).css("background-color", "#ECF4F8");
-    });
-
-    $("a[data-row-selector='true']").jHueRowSelector();
-  });
-</script>

+ 2 - 2
apps/oozie/src/oozie/templates/editor/list_coordinators.mako

@@ -23,7 +23,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='coordinators') }
 ${ layout.menubar(section='coordinators') }
 
 
 
 
@@ -250,4 +250,4 @@ ${ layout.menubar(section='coordinators') }
   });
   });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/oozie/src/oozie/templates/editor/list_history.mako

@@ -24,7 +24,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='history') }
 ${ layout.menubar(section='history') }
 
 
 
 
@@ -103,4 +103,4 @@ ${ layout.menubar(section='history') }
   $("a[data-row-selector='true']").jHueRowSelector();
   $("a[data-row-selector='true']").jHueRowSelector();
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/oozie/src/oozie/templates/editor/list_history_record.mako

@@ -22,7 +22,7 @@
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='history') }
 ${ layout.menubar(section='history') }
 
 
 
 
@@ -81,4 +81,4 @@ ${ layout.menubar(section='history') }
    <a href="${ url('oozie:list_history') }" class="btn">${ _('Back') }</a>
    <a href="${ url('oozie:list_history') }" class="btn">${ _('Back') }</a>
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/oozie/src/oozie/templates/editor/list_workflows.mako

@@ -23,7 +23,7 @@
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="layout" file="../navigation-bar.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 <%namespace name="utils" file="../utils.inc.mako" />
 
 
-${ commonheader( _("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='workflows') }
 ${ layout.menubar(section='workflows') }
 
 
 
 
@@ -261,4 +261,4 @@ ${ layout.menubar(section='workflows') }
   });
   });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${commonfooter(messages) |n,unicode}

+ 2 - 2
apps/oozie/src/oozie/templates/editor/submit_job_popup.mako

@@ -30,11 +30,11 @@
     <fieldset>
     <fieldset>
       <div id="param-container">
       <div id="param-container">
 
 
-       ${ params_form.management_form }
+       ${ params_form.management_form | n,unicode }
 
 
        % for form in params_form.forms:
        % for form in params_form.forms:
           % for hidden in form.hidden_fields():
           % for hidden in form.hidden_fields():
-            ${ hidden }
+            ${ hidden | n,unicode }
           % endfor
           % endfor
           <div class="fieldWrapper">
           <div class="fieldWrapper">
             <div class="row-fluid
             <div class="row-fluid

+ 8 - 8
apps/oozie/src/oozie/templates/utils.inc.mako

@@ -170,11 +170,11 @@
     <div class="control-group ${group_class}"
     <div class="control-group ${group_class}"
       rel="popover" data-original-title="${ field.label }" data-content="${ field.help_text }">
       rel="popover" data-original-title="${ field.label }" data-content="${ field.help_text }">
       % if show_label:
       % if show_label:
-        <label class="control-label">${ field.label | h }</label>
+        <label class="control-label">${ field.label }</label>
       % endif
       % endif
       <div class="controls">
       <div class="controls">
         <% field.field.widget.attrs.update(extra_attrs) %>
         <% field.field.widget.attrs.update(extra_attrs) %>
-        ${ field }
+        ${ field | n,unicode }
         % if field.errors:
         % if field.errors:
           <span class="help-inline">${ unicode(field.errors) }</span>
           <span class="help-inline">${ unicode(field.errors) }</span>
         % endif
         % endif
@@ -188,11 +188,11 @@
     <% group_class = field.errors and "error" or "" %>
     <% group_class = field.errors and "error" or "" %>
     <div class="control-group ${group_class}">
     <div class="control-group ${group_class}">
     % if show_label:
     % if show_label:
-        <label class="control-label">${ field.label | h }</label>
+        <label class="control-label">${ field.label }</label>
     % endif
     % endif
     <div class="controls">
     <div class="controls">
     <% field.field.widget.attrs.update(extra_attrs) %>
     <% field.field.widget.attrs.update(extra_attrs) %>
-    ${ field }
+    ${ field | n,unicode }
     % if field.errors:
     % if field.errors:
         <span class="help-inline">${ unicode(field.errors) }</span>
         <span class="help-inline">${ unicode(field.errors) }</span>
     % endif
     % endif
@@ -207,13 +207,13 @@
 
 
 <%def name="render_field_with_error_js(field, error_name, show_label=True, extra_attrs={})">
 <%def name="render_field_with_error_js(field, error_name, show_label=True, extra_attrs={})">
   % if not field.is_hidden:
   % if not field.is_hidden:
-    <div class="control-group" rel="popover" data-original-title="${ field.label }" data-content="${ field.help_text | h }" data-bind="attr: {'class': ( errors.${ error_name }().length > 0 ) ? 'control-group error' : 'control-group'}">
+    <div class="control-group" rel="popover" data-original-title="${ field.label }" data-content="${ field.help_text }" data-bind="attr: {'class': ( errors.${ error_name }().length > 0 ) ? 'control-group error' : 'control-group'}">
       % if show_label:
       % if show_label:
-        <label class="control-label">${ field.label | h }</label>
+        <label class="control-label">${ field.label }</label>
       % endif
       % endif
       <div class="controls">
       <div class="controls">
         <% field.field.widget.attrs.update(extra_attrs) %>
         <% field.field.widget.attrs.update(extra_attrs) %>
-        ${ field }
+        ${ field | n,unicode }
         <ul class="help-inline" data-bind="foreach: errors.${ error_name }()">
         <ul class="help-inline" data-bind="foreach: errors.${ error_name }()">
           <li class="error" data-bind="html: $data"></li>
           <li class="error" data-bind="html: $data"></li>
         </ul>
         </ul>
@@ -225,7 +225,7 @@
 
 
 <%def name="render_constant(label, value)">
 <%def name="render_constant(label, value)">
   <div class="control-group">
   <div class="control-group">
-    <label class="control-label">${ label | h }</label>
+    <label class="control-label">${ label }</label>
     <div class="controls">
     <div class="controls">
       <div style="padding-top:4px">
       <div style="padding-top:4px">
       ${ value }
       ${ value }

+ 23 - 0
apps/oozie/src/oozie/tests.py

@@ -1298,6 +1298,29 @@ class TestEditor(OozieMockBase):
     workflow.delete()
     workflow.delete()
 
 
 
 
+  def test_xss_escape_js(self):
+    escaped = '[{"name": "oozie.use.system.libpath", "value": "true"}, {"name": "123\\\\u0022\\\\u003E\\\\u003Cscript\\\\u003Ealert(1)\\\\u003C/script\\\\u003E", "value": "hacked"}]'
+    hacked = '[{"name":"oozie.use.system.libpath","value":"true"}, {"name": "123\\"><script>alert(1)</script>", "value": "hacked"}]'
+
+    self.wf.job_properties = hacked
+    self.wf.parameters = hacked
+
+    assert_equal(escaped, self.wf._escapejs_parameters_list(hacked))
+    assert_equal(escaped, self.wf.job_properties_escapejs)
+    assert_equal(escaped, self.wf.parameters_escapejs)
+
+
+  def test_xss_html_escaping(self):
+    data = WORKFLOW_DICT.copy()
+    data['description'] = [u'"><script>alert(1);</script>']
+
+    self.wf = create_workflow(self.c, workflow_dict=data)
+
+    resp = self.c.get('/oozie/list_workflows/')
+    assert_false('"><script>alert(1);</script>' in resp.content, resp.content)
+    assert_true('&quot;&gt;&lt;script&gt;alert(1);&lt;/script&gt;' in resp.content, resp.content)
+
+
 class TestPermissions(OozieBase):
 class TestPermissions(OozieBase):
 
 
   def setUp(self):
   def setUp(self):

+ 3 - 6
apps/oozie/src/oozie/views/editor.py

@@ -34,20 +34,18 @@ from desktop.lib.django_util import render, extract_field_data
 from desktop.lib.exceptions_renderable import PopupException
 from desktop.lib.exceptions_renderable import PopupException
 from desktop.lib.rest.http_client import RestException
 from desktop.lib.rest.http_client import RestException
 from hadoop.fs.exceptions import WebHdfsException
 from hadoop.fs.exceptions import WebHdfsException
-from jobsub.models import OozieDesign
 from liboozie.submittion import Submission
 from liboozie.submittion import Submission
 
 
 from oozie.conf import SHARE_JOBS
 from oozie.conf import SHARE_JOBS
 from oozie.decorators import check_job_access_permission, check_job_edition_permission,\
 from oozie.decorators import check_job_access_permission, check_job_edition_permission,\
                              check_dataset_access_permission, check_dataset_edition_permission
                              check_dataset_access_permission, check_dataset_edition_permission
 from oozie.import_workflow import import_workflow as _import_workflow
 from oozie.import_workflow import import_workflow as _import_workflow
-from oozie.import_jobsub import convert_jobsub_design
 from oozie.management.commands import oozie_setup
 from oozie.management.commands import oozie_setup
-from oozie.models import Job, Workflow, History, Coordinator, Mapreduce, Java, Streaming,\
+from oozie.models import Job, Workflow, History, Coordinator,\
                          Dataset, DataInput, DataOutput, ACTION_TYPES
                          Dataset, DataInput, DataOutput, ACTION_TYPES
 from oozie.forms import WorkflowForm, CoordinatorForm, DatasetForm,\
 from oozie.forms import WorkflowForm, CoordinatorForm, DatasetForm,\
   DataInputForm, DataInputSetForm, DataOutputForm, DataOutputSetForm, LinkForm,\
   DataInputForm, DataInputSetForm, DataOutputForm, DataOutputSetForm, LinkForm,\
-  DefaultLinkForm, design_form_by_type, ImportJobsubDesignForm, ParameterForm,\
+  DefaultLinkForm, design_form_by_type, ParameterForm,\
   ImportWorkflowForm
   ImportWorkflowForm
 
 
 
 
@@ -334,8 +332,7 @@ def edit_coordinator(request, coordinator):
     'dataset_form': dataset_form,
     'dataset_form': dataset_form,
     'new_data_input_formset': new_data_input_formset,
     'new_data_input_formset': new_data_input_formset,
     'new_data_output_formset': new_data_output_formset,
     'new_data_output_formset': new_data_output_formset,
-    'history': history,
-    'parameters': extract_field_data(coordinator_form['parameters'])
+    'history': history
   })
   })
 
 
 
 

+ 2 - 2
apps/shell/src/shell/templates/failed_to_create.mako

@@ -18,7 +18,7 @@ from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
 
 
-${commonheader(_('Hue Shell'), "shell", user)}
+${ commonheader(_('Hue Shell'), "shell", user) | n,unicode }
 <div class="container-fluid">
 <div class="container-fluid">
 <div>
 <div>
     <h3>${_('Failed to create a shell of the given type. The possible reasons for this are:')}</h3>
     <h3>${_('Failed to create a shell of the given type. The possible reasons for this are:')}</h3>
@@ -31,4 +31,4 @@ ${commonheader(_('Hue Shell'), "shell", user)}
     </ol>
     </ol>
 </div>
 </div>
 </div>
 </div>
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/shell/src/shell/templates/index.mako

@@ -19,7 +19,7 @@ from django.utils.translation import ugettext as _
 %>
 %>
 
 
 
 
-${commonheader(_('Hue Shell'), "shell", user, "100px")}
+${ commonheader(_('Hue Shell'), "shell", user, "100px") | n,unicode }
 
 
 <div class="subnav subnav-fixed">
 <div class="subnav subnav-fixed">
     <div class="container-fluid">
     <div class="container-fluid">
@@ -297,4 +297,4 @@ ${commonheader(_('Hue Shell'), "shell", user, "100px")}
 </script>
 </script>
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/shell/src/shell/templates/no_such_user.mako

@@ -18,7 +18,7 @@ from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
 
 
-${commonheader(_('Hue Shell'), "shell", user)}
+${ commonheader(_('Hue Shell'), "shell", user) | n,unicode }
 <div class="container-fluid">
 <div class="container-fluid">
 <div>
 <div>
     <h3>${_('The Shell application requires a Unix user account for every user of Hue on the remote web server.')}</h3>
     <h3>${_('The Shell application requires a Unix user account for every user of Hue on the remote web server.')}</h3>
@@ -27,4 +27,4 @@ ${commonheader(_('Hue Shell'), "shell", user)}
 
 
 </div>
 </div>
 </div>
 </div>
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/shell/src/shell/templates/not_running_spawning.mako

@@ -18,10 +18,10 @@ from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
 
 
-${commonheader(_('Hue Shell'), "shell", user)}
+${ commonheader(_('Hue Shell'), "shell", user) | n,unicode }
 <div class="container-fluid">
 <div class="container-fluid">
 <div>
 <div>
 	<h3>${_('The webserver currently running Hue does not support the Shell application. Please contact your administrator.')}</h3>
 	<h3>${_('The webserver currently running Hue does not support the Shell application. Please contact your administrator.')}</h3>
 </div>
 </div>
 </div>
 </div>
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/useradmin/src/useradmin/templates/add_ldap_users.mako

@@ -22,7 +22,7 @@ from django.utils.translation import ugettext as _
 
 
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Hue Users'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Users'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='users', _=_)}
 ${layout.menubar(section='users', _=_)}
 
 
 
 
@@ -64,4 +64,4 @@ ${layout.menubar(section='users', _=_)}
   });
   });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/useradmin/src/useradmin/templates/confirm.mako

@@ -17,7 +17,7 @@
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
-${commonheader(title, "useradmin", user)}
+${ commonheader(title, "useradmin", user) | n,unicode }
 <div class="container-fluid">
 <div class="container-fluid">
 	<h1>${_('Confirm')}</h1>
 	<h1>${_('Confirm')}</h1>
 	<form action="${path}" method="POST">
 	<form action="${path}" method="POST">
@@ -25,4 +25,4 @@ ${commonheader(title, "useradmin", user)}
 		<input type="submit" value="${_('Yes')}">
 		<input type="submit" value="${_('Yes')}">
 	</form>
 	</form>
 </div>
 </div>
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/useradmin/src/useradmin/templates/edit_group.mako

@@ -23,7 +23,7 @@ from django.utils.translation import ugettext as _
 
 
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Hue Groups'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Groups'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='groups', _=_)}
 ${layout.menubar(section='groups', _=_)}
 
 
 <%def name="render_field(field)">
 <%def name="render_field(field)">
@@ -96,4 +96,4 @@ ${layout.menubar(section='groups', _=_)}
 	});
 	});
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/useradmin/src/useradmin/templates/edit_permissions.mako

@@ -20,7 +20,7 @@ from django.utils.translation import ugettext as _
 %>
 %>
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Hue Permissions'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Permissions'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='permissions', _=_)}
 ${layout.menubar(section='permissions', _=_)}
 
 
 
 
@@ -66,4 +66,4 @@ ${layout.menubar(section='permissions', _=_)}
         });
         });
 	});
 	});
 </script>
 </script>
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/useradmin/src/useradmin/templates/edit_user.mako

@@ -22,7 +22,7 @@ from django.utils.translation import ugettext as _
 
 
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
 
 
-${commonheader(_('Hue Users'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Users'), "useradmin", user, "100px") | n,unicode }
 
 
 % if user.is_superuser:
 % if user.is_superuser:
   ${layout.menubar(section='users', _=_)}
   ${layout.menubar(section='users', _=_)}
@@ -101,4 +101,4 @@ ${commonheader(_('Hue Users'), "useradmin", user, "100px")}
     });
     });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/useradmin/src/useradmin/templates/list_groups.mako

@@ -22,7 +22,7 @@ from useradmin.models import group_permissions
 
 
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
-${commonheader(_('Hue Groups'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Groups'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='groups', _=_)}
 ${layout.menubar(section='groups', _=_)}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -165,4 +165,4 @@ ${layout.menubar(section='groups', _=_)}
 
 
 ${layout.commons()}
 ${layout.commons()}
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/useradmin/src/useradmin/templates/list_permissions.mako

@@ -23,7 +23,7 @@ from django.contrib.auth.models import Group
 
 
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
-${commonheader(_('Hue Permissions'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Permissions'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='permissions', _=_)}
 ${layout.menubar(section='permissions', _=_)}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -92,4 +92,4 @@ ${layout.menubar(section='permissions', _=_)}
 
 
 ${layout.commons()}
 ${layout.commons()}
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
apps/useradmin/src/useradmin/templates/list_users.mako

@@ -22,7 +22,7 @@ from django.utils.translation import ugettext as _
 
 
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="layout" file="layout.mako" />
-${commonheader(_('Hue Users'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Users'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='users', _=_)}
 ${layout.menubar(section='users', _=_)}
 
 
 <div class="container-fluid">
 <div class="container-fluid">
@@ -176,4 +176,4 @@ ${layout.menubar(section='users', _=_)}
 
 
 ${layout.commons()}
 ${layout.commons()}
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 3 - 3
desktop/conf.dist/hue.ini

@@ -341,9 +341,9 @@
 
 
 [beeswax]
 [beeswax]
 
 
-  # Host where Beeswax Thrift server is running.
-  # Required when using security or when Beeswax is not on localhost.
-  # The FQDN should be the same as the FQDN specified in the hue_principal configuration.
+  # Host where Beeswax server Thrift daemon is running.
+  # If Kerberos security is enabled, the fully-qualified domain name (FQDN) is
+  # required, even if the Thrift daemon is running on the same host as Hue.
   ## beeswax_server_host=<FQDN of Beeswax Server>
   ## beeswax_server_host=<FQDN of Beeswax Server>
 
 
   # Port where Beeswax Thrift server runs on.
   # Port where Beeswax Thrift server runs on.

+ 3 - 3
desktop/conf/pseudo-distributed.ini.tmpl

@@ -344,9 +344,9 @@
 
 
 [beeswax]
 [beeswax]
 
 
-  # Host where Beeswax Thrift server is running.
-  # Required when using security or when Beeswax is not on localhost.
-  # The FQDN should be the same as the FQDN specified in the hue_principal configuration.
+  # Host where Beeswax server Thrift daemon is running.
+  # If Kerberos security is enabled, the fully-qualified domain name (FQDN) is
+  # required, even if the Thrift daemon is running on the same host as Hue.
   ## beeswax_server_host=<FQDN of Beeswax Server>
   ## beeswax_server_host=<FQDN of Beeswax Server>
 
 
   # Port where Beeswax Thrift server runs on.
   # Port where Beeswax Thrift server runs on.

+ 3 - 2
desktop/core/src/desktop/lib/django_mako.py

@@ -28,7 +28,8 @@ ENCODING_ERRORS = 'replace'
 
 
 # Things to automatically import into all template namespaces
 # Things to automatically import into all template namespaces
 IMPORTS=[
 IMPORTS=[
-  "from desktop.lib.django_mako import url"
+  "from desktop.lib.django_mako import url",
+  "from django.utils.html import escape"
 ]
 ]
 
 
 class DesktopLookup(TemplateCollection):
 class DesktopLookup(TemplateCollection):
@@ -63,7 +64,7 @@ class DesktopLookup(TemplateCollection):
                             output_encoding=i18n.get_site_encoding(),
                             output_encoding=i18n.get_site_encoding(),
                             input_encoding=i18n.get_site_encoding(),
                             input_encoding=i18n.get_site_encoding(),
                             encoding_errors=ENCODING_ERRORS,
                             encoding_errors=ENCODING_ERRORS,
-                            default_filters=['unicode'], 
+                            default_filters=['unicode', 'escape'], 
                             imports=IMPORTS)
                             imports=IMPORTS)
     # TODO(philip): Make a django_aware default filter, that understands
     # TODO(philip): Make a django_aware default filter, that understands
     # django safe strings.  See http://www.makotemplates.org/docs/filtering.html.
     # django safe strings.  See http://www.makotemplates.org/docs/filtering.html.

+ 1 - 1
desktop/core/src/desktop/management/commands/runpylint.py

@@ -26,7 +26,7 @@ from django.utils.translation import ugettext as _
 
 
 class Command(BaseCommand):
 class Command(BaseCommand):
   help = _("""
   help = _("""
-  Runs pylint on desktop code.
+  Runs pylint on desktop and app code.
 
 
   With no arguments, or with "all", this will run pylint on all
   With no arguments, or with "all", this will run pylint on all
   installed apps.  Otherwise, specify modules to run, as well
   installed apps.  Otherwise, specify modules to run, as well

+ 2 - 2
desktop/core/src/desktop/templates/404.mako

@@ -17,7 +17,7 @@
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
-${commonheader(_('Not Found'), "", user)}
+${ commonheader(_('Not Found'), "", user) | n,unicode }
 
 
   <div class="container-fluid">
   <div class="container-fluid">
     <h1>${_('Page not found')}</h1>
     <h1>${_('Page not found')}</h1>
@@ -26,4 +26,4 @@ ${commonheader(_('Not Found'), "", user)}
     <code>${uri}</code>
     <code>${uri}</code>
   </div>
   </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 5 - 5
desktop/core/src/desktop/templates/500.mako

@@ -18,7 +18,7 @@ from desktop.lib.i18n import smart_unicode
 from desktop.views import commonheader, commonfooter
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
-${commonheader(_('Error'), "", user)}
+${ commonheader(_('Error'), "", user) | n,unicode }
 
 
   <div class="container-fluid">
   <div class="container-fluid">
     <h1>${_('Server Error (500)')}</h1>
     <h1>${_('Server Error (500)')}</h1>
@@ -42,9 +42,9 @@ ${commonheader(_('Error'), "", user)}
           <tbody>
           <tbody>
             % for (file_name, line_number, function_name, text) in traceback:
             % for (file_name, line_number, function_name, text) in traceback:
               <tr>
               <tr>
-                <td>${smart_unicode(file_name) or "" | h}</td>
-                <td>${smart_unicode(line_number) or "" | h}</td>
-                <td>${smart_unicode(function_name) or "" | h}</td>
+                <td>${smart_unicode(file_name) or ""}</td>
+                <td>${smart_unicode(line_number) or ""}</td>
+                <td>${smart_unicode(function_name) or ""}</td>
               </tr>
               </tr>
             % endfor
             % endfor
           </tbody>
           </tbody>
@@ -62,4 +62,4 @@ ${commonheader(_('Error'), "", user)}
     }
     }
   </script>
   </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 2 - 2
desktop/core/src/desktop/templates/check_config.mako

@@ -20,7 +20,7 @@ from django.utils.translation import ugettext as _
 %>
 %>
 
 
 <%namespace name="layout" file="about_layout.mako" />
 <%namespace name="layout" file="about_layout.mako" />
-${commonheader(_('About'), "about", user, "100px")}
+${ commonheader(_('About'), "about", user, "100px") | n,unicode }
 
 
 ${layout.menubar(section='check_config')}
 ${layout.menubar(section='check_config')}
 
 
@@ -57,4 +57,4 @@ ${layout.menubar(section='check_config')}
     % endif
     % endif
 </div>
 </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 1 - 1
desktop/core/src/desktop/templates/common_header.mako

@@ -24,7 +24,7 @@ from django.utils.translation import ugettext as _
 <html lang="en">
 <html lang="en">
 <head>
 <head>
   <meta charset="utf-8">
   <meta charset="utf-8">
-  <title>${smart_unicode(title) | h}</title>
+  <title>${smart_unicode(title)}</title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <meta name="description" content="">
   <meta name="description" content="">
   <meta name="author" content="">
   <meta name="author" content="">

+ 2 - 2
desktop/core/src/desktop/templates/dump_config.mako

@@ -23,7 +23,7 @@ from django.utils.translation import ugettext as _
 
 
 <%namespace name="layout" file="about_layout.mako" />
 <%namespace name="layout" file="about_layout.mako" />
 
 
-${commonheader(_('About'), "about", user, "100px")}
+${ commonheader(_('About'), "about", user, "100px") | n,unicode }
 ${layout.menubar(section='dump_config')}
 ${layout.menubar(section='dump_config')}
 
 
     <div class="container-fluid">
     <div class="container-fluid">
@@ -118,4 +118,4 @@ ${layout.menubar(section='dump_config')}
 
 
     </div>
     </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 5 - 5
desktop/core/src/desktop/templates/error.mako

@@ -19,19 +19,19 @@ from desktop.lib.i18n import smart_unicode
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
 
 
-${commonheader(_('Error'), app_name, user)}
+${ commonheader(_('Error'), app_name, user) | n,unicode }
 
 
   <div class="container-fluid">
   <div class="container-fluid">
-    <h1>${_('Error!')}</h1>
-    <pre>${smart_unicode(error) | h }</pre>
+    <h1>${ _('Error!') }</h1>
+    <pre>${ smart_unicode(error) }</pre>
 
 
     %if traceback:
     %if traceback:
       <textarea style="width: 100%;" rows=80 readonly="readonly">
       <textarea style="width: 100%;" rows=80 readonly="readonly">
-      ${smart_unicode(traceback) | h}
+      ${ smart_unicode(traceback) }
       </textarea>
       </textarea>
     %endif
     %endif
 
 
     <a class="btn" onclick="history.back()">${ _('Back') }</a>
     <a class="btn" onclick="history.back()">${ _('Back') }</a>
   </div>
   </div>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 5 - 5
desktop/core/src/desktop/templates/login.mako

@@ -64,22 +64,22 @@ from django.utils.translation import ugettext as _
             <div class="span4 offset4">
             <div class="span4 offset4">
                 <form method="POST" action="${action}" class="well">
                 <form method="POST" action="${action}" class="well">
                     <label>${_('Username')}
                     <label>${_('Username')}
-                        ${ form['username'] }
+                        ${ form['username'] | n,unicode }
                         ${ form['username'].errors }
                         ${ form['username'].errors }
                     </label>
                     </label>
                     <label>${_('Password')}
                     <label>${_('Password')}
-                        ${ form['password'] }
+                        ${ form['password'] | n,unicode }
                         ${ form['password'].errors }
                         ${ form['password'].errors }
                     </label>
                     </label>
 
 
-                    %if first_login_ever==True:
+                    %if first_login_ever:
                         <input type="submit" class="btn btn-primary" value="${_('Sign up')}" />
                         <input type="submit" class="btn btn-primary" value="${_('Sign up')}" />
                     %else:
                     %else:
                         <input type="submit" class="btn btn-primary" value="${_('Sign in')}" />
                         <input type="submit" class="btn btn-primary" value="${_('Sign in')}" />
                     %endif
                     %endif
                     <input type="hidden" name="next" value="${next}" />
                     <input type="hidden" name="next" value="${next}" />
 
 
-                    %if login_errors==True:
+                    %if login_errors:
                         <br/>
                         <br/>
                         <br/>
                         <br/>
                         <div class="alert alert-error">
                         <div class="alert alert-error">
@@ -90,7 +90,7 @@ from django.utils.translation import ugettext as _
             </div>
             </div>
         </div>
         </div>
 
 
-        %if first_login_ever==True:
+        %if first_login_ever:
         <div class="row">
         <div class="row">
             <div class="span6 offset3">
             <div class="span6 offset3">
                 <div class="alert alert-block">
                 <div class="alert alert-block">

+ 5 - 3
desktop/core/src/desktop/templates/logs.mako

@@ -20,9 +20,11 @@ from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 import re
 import re
 %>
 %>
+
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="actionbar" file="actionbar.mako" />
 <%namespace name="layout" file="about_layout.mako" />
 <%namespace name="layout" file="about_layout.mako" />
-${commonheader(_('About'), "about", user, "100px")}
+
+${ commonheader(_('About'), "about", user, "100px") | n,unicode }
 ${layout.menubar(section='log_view')}
 ${layout.menubar(section='log_view')}
 
 
 <style>
 <style>
@@ -71,7 +73,7 @@ ${layout.menubar(section='log_view')}
 
 
   <div id="logs">
   <div id="logs">
       % for l in log:
       % for l in log:
-        <pre>${smart_unicode(l, errors='ignore') | h}</pre>
+        <pre>${smart_unicode(l, errors='ignore')}</pre>
       % endfor
       % endfor
   </div>
   </div>
 
 
@@ -141,4 +143,4 @@ ${layout.menubar(section='log_view')}
   });
   });
 </script>
 </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

+ 7 - 7
desktop/core/src/desktop/templates/popup_error.mako

@@ -19,14 +19,14 @@ from desktop.lib.i18n import smart_unicode
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 %>
 %>
 
 
-${commonheader(title, "", user)}
+${ commonheader(title, "", user) | n,unicode }
 
 
   <div class="container-fluid">
   <div class="container-fluid">
     <div class="alert">
     <div class="alert">
-      <p><strong>${smart_unicode(message) | h}</strong></p>
+      <p><strong>${smart_unicode(message)}</strong></p>
 
 
       % if detail:
       % if detail:
-      <p>${smart_unicode(detail) or "" | h}</p>
+      <p>${smart_unicode(detail) or "" }</p>
       % endif
       % endif
 
 
     </div>
     </div>
@@ -50,9 +50,9 @@ ${commonheader(title, "", user)}
             <tbody>
             <tbody>
               % for (file_name, line_number, function_name, text) in traceback:
               % for (file_name, line_number, function_name, text) in traceback:
                 <tr>
                 <tr>
-                  <td>${smart_unicode(file_name) or "" | h}</td>
-                  <td>${smart_unicode(line_number) or "" | h}</td>
-                  <td>${smart_unicode(function_name) or "" | h}</td>
+                  <td>${smart_unicode(file_name) or ""}</td>
+                  <td>${smart_unicode(line_number) or ""}</td>
+                  <td>${smart_unicode(function_name) or ""}</td>
                 </tr>
                 </tr>
               % endfor
               % endfor
             </tbody>
             </tbody>
@@ -76,4 +76,4 @@ ${commonheader(title, "", user)}
     }
     }
   </script>
   </script>
 
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }