Просмотр исходного кода

[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 лет назад
Родитель
Сommit
cfd3a5c
98 измененных файлов с 364 добавлено и 363 удалено
  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 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="container-fluid">
@@ -34,4 +34,4 @@ ${commonheader(_('About Hue'), "about", user, "100px")}
 		<p>Hue ${version}</p>
 	</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(
   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,
   default="localhost")
 

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

@@ -160,9 +160,9 @@ ${field.label_tag() | n}
                 % endif
             % else:
                 %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:
-                    <${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

+ 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="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')}
 
 <div class="container-fluid">
@@ -141,4 +141,4 @@ ${layout.menubar(section='tables')}
     });
 </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="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')}
 
 
@@ -170,4 +170,4 @@ ${layout.menubar(section='tables')}
     });
 </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="util" file="util.mako" />
 
-${commonheader(_('Configuration Variables'), app_name, user, '100px')}
+${ commonheader(_('Configuration Variables'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='configuration')}
 
 <div class="container-fluid">
@@ -88,4 +88,4 @@ ${layout.menubar(section='configuration')}
 	});
 </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="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')}
 
 <div class="container-fluid">
@@ -733,4 +733,4 @@ $(document).ready(function () {
 });
 </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="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')}
 
 <div class="container-fluid">
@@ -125,4 +125,4 @@ ${layout.menubar(section='tables')}
         });
     });
 </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" />
 
-${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')}
 
 <div class="container-fluid">
@@ -57,4 +57,4 @@ ${layout.menubar(section='tables')}
 
 </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:
     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')}
 
 <%def name="column_table(cols)">
@@ -277,4 +277,4 @@ ${layout.menubar(section='tables')}
    });
  </script>
 
- ${commonfooter(messages)}
+ ${ commonfooter(messages) | n,unicode }

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

@@ -33,10 +33,11 @@
         </div>
     % 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">
     % if len(form.query["query"].errors):
-        ${unicode(form.query["query"].errors) | n}
+        ${ unicode(form.query["query"].errors) }
      % endif
     </div>
 
@@ -54,7 +55,7 @@
 </%def>
 
 
-${commonheader(_('Query'), app_name, user, '100px')}
+${ commonheader(_('Query'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='query')}
 
 <div class="container-fluid">
@@ -65,7 +66,7 @@ ${layout.menubar(section='query')}
                     <ul class="nav nav-list">
                         <li class="nav-header">${_('database')}</li>
                         <li>
-                          ${ form.query['database'] }
+                          ${ form.query['database'] | n,unicode }
                         </li>
                         <li class="nav-header">${_('settings')}</li>
                         <li>
@@ -250,7 +251,7 @@ ${layout.menubar(section='query')}
                     % if error_message or log:
                         <div class="tab-pane" id="errorPane">
                         % if log:
-                            <pre>${log | h}</pre>
+                            <pre>${ log }</pre>
                         % endif
                         </div>
                     % endif
@@ -507,4 +508,4 @@ ${layout.menubar(section='query')}
 </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="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')}
 
 <div class="container-fluid">
@@ -47,4 +47,4 @@ ${layout.menubar(section='saved queries')}
 
 </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="layout" file="layout.mako" />
 
-${commonheader(_('Beeswax'), app_name, user, '100px')}
+${ commonheader(_('Beeswax'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 
 <div class="container-fluid">
@@ -94,4 +94,4 @@ ${layout.menubar(section='tables')}
     });
 </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="layout" file="layout.mako" />
 
-${commonheader(_('Queries'), app_name, user, '100px')}
+${ commonheader(_('Queries'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='saved queries')}
 <div class="container-fluid">
     <h1>${_('Queries')}</h1>
@@ -134,4 +134,4 @@ ${layout.menubar(section='saved queries')}
     });
 </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="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')}
 
 <%def name="show_saved_query(design, history)">
@@ -176,4 +176,4 @@ ${layout.menubar(section='history')}
         $("a[data-row-selector='true']").jHueRowSelector();
     });
 </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="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()}
 
@@ -53,4 +53,4 @@ ${layout.menubar()}
   </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" />
 <%!  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')}
 
 <style>
@@ -136,7 +136,7 @@ ${layout.menubar(section='my queries')}
                           % if len(query.query) > 100:
                             <code>${collapse_whitespace(query.query[:100])}...</code>
                           % else:
-                            <code>${collapse_whitespace(query.query)}</code>
+                            <code>${ collapse_whitespace(query.query) }</code>
                           % endif
                         </p>
                       </td>
@@ -253,4 +253,4 @@ ${layout.menubar(section='my queries')}
     });
 </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 django.utils.translation import ugettext as _
 %>
+
 <%namespace name="comps" file="beeswax_components.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()}
 
@@ -52,4 +53,4 @@ ${layout.menubar()}
     </form>
 </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 django.utils.translation import ugettext as _
 %>
+
 <%namespace name="layout" file="layout.mako" />
 <%namespace name="comps" file="beeswax_components.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')}
+
 <div class="container-fluid">
 % if error_msg:
-<h4>${error_msg}</h4>
+  <h4>${error_msg}</h4>
 % endif
   <h1>${_('Save Query Results')}</h1>
 
@@ -122,4 +125,5 @@ ${layout.menubar(section='history')}
     }
   });
 </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" />
 
-${commonheader(_('Table List'), app_name, user, '100px')}
+${ commonheader(_('Table List'), app_name, user, '100px') | n,unicode }
 ${layout.menubar(section='tables')}
 
 
@@ -33,7 +33,7 @@ ${layout.menubar(section='tables')}
                     <li class="nav-header">${_('database')}</li>
                     <li>
                        <form action="${ url(app_name + ':show_tables') }" id="db_form" method="POST">
-                         ${ db_form }
+                         ${ db_form | n,unicode }
                        </form>
                     </li>
                     <li class="nav-header">${_('Actions')}</li>
@@ -138,4 +138,4 @@ ${layout.menubar(section='tables')}
     });
 </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="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')}
 
 <style>
@@ -115,7 +115,7 @@ ${layout.menubar(section='query')}
             % if error:
               <div class="alert alert-error">
                 <h3>${_('Error!')}</h3>
-                <pre>${error_message | h}</pre>
+                <pre>${ error_message }</pre>
               </div>
             % else:
             % if expected_first_row != start_row:
@@ -155,11 +155,11 @@ ${layout.menubar(section='query')}
         </div>
 
         <div class="tab-pane" id="query">
-          <pre>${query.query | h}</pre>
+          <pre>${ query.query }</pre>
         </div>
 
         <div class="tab-pane" id="log">
-          <pre>${log | h}</pre>
+          <pre>${ log }</pre>
         </div>
 
         % if not error:
@@ -327,4 +327,4 @@ ${layout.menubar(section='query')}
     });
 </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="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')}
 
 ## Required for unit tests
@@ -57,10 +57,10 @@ ${layout.menubar(section='query')}
 
 		   	<div class="tab-content">
 				<div class="active tab-pane" id="log">
-					<pre>${log | h}</pre>
+					<pre>${ log }</pre>
 				</div>
 				<div class="tab-pane" id="query">
-					<pre>${query.query | h}</pre>
+					<pre>${ query.query }</pre>
 				</div>
 			</div>
 		</div>
@@ -128,4 +128,4 @@ ${layout.menubar(section='query')}
 </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)
 
 
+  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():
   """Test the gzip reader in create table"""
   # Make gzipped data

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

@@ -28,7 +28,7 @@
 %>
 <%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
 		      <div>
 		      % if 'contents' in view:
-		             <div><pre>${view['contents']|h}</pre></div>
+		             <div><pre>${view['contents']}</pre></div>
 		      % else:
 		        <table>
 		          % for offset, words, masked in view['xxd']:
@@ -214,4 +214,4 @@ ${commonheader(_('%(filename)s - File Viewer') % dict(filename=truncate(filename
 			});
 		});
 	</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" />
 
-${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">
 	% if breadcrumbs:
@@ -115,6 +115,6 @@ ${commonheader(_('%(filename)s - File Viewer') % dict(filename=truncate(filename
 	});
 </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'] %>
                         %if label == '/':
                                 <li><a href="/filebrowser/view${breadcrumb_item['url']}"><span
-                                        class="divider">${label | h}</span></a></li>
+                                        class="divider">${label}</span></a></li>
                         %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
                         % endfor
                 </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.
 
@@ -46,4 +46,4 @@ ${commonheader(_('File Operation'), 'filebrowser', user)}
 </form>
 </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="fb_components" file="fb_components.mako" />
 
-${commonheader(_('File Browser'), 'filebrowser', user)}
+${ commonheader(_('File Browser'), 'filebrowser', user) | n,unicode }
 
 <div class="container-fluid">
     <h1>${_('File Browser')}</h1>
@@ -76,4 +76,4 @@ ${commonheader(_('File Browser'), 'filebrowser', user)}
     </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),
         'pagesize': pagesize,
         'home_directory': request.fs.isdir(home_dir_path) and home_dir_path or None,
-        'filter_str': filter_str,
         'sortby': sortby,
         'descending': descending_param,
         # 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
 %>
-${commonheader("Hue Help", "help", user, "100px")}
+${ commonheader("Hue Help", "help", user, "100px") | n,unicode }
 	<div class="subnav subnav-fixed">
 		<div class="container-fluid">
 		<ul class="nav nav-pills">
@@ -64,4 +64,4 @@ ${commonheader("Hue Help", "help", user, "100px")}
     });
   </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" />
 
-${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">
     <h1>${_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short)}</h1>
     <div class="row-fluid">
@@ -167,4 +167,4 @@ ${commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=a
     });
 </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" />
 
-${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">
     <h1>${_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=attempt.attemptId_short)}</h1>
     <div class="row-fluid">
@@ -68,7 +68,7 @@ ${commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=a
                     <%def name="format_log(raw)">
                         ## have to remove any indentation here or it breaks inside the pre tags
                           % for line in raw.split('\n'):
-                              ${ line | h,trim }
+                              ${ line | unicode,trim }
                         % endfor
                     </%def>
                     <h2>${_('task diagnostic log')}</h2>
@@ -137,4 +137,4 @@ ${commonheader(_('Task Attempt: %(attemptId)s - Job Browser') % dict(attemptId=a
     });
 </script>
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

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

@@ -90,7 +90,7 @@
     % endfor
 </%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">
     <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>
 
 
-${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" />
 
-${ 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">
     <h1>
@@ -110,4 +110,4 @@ ${ commonheader(_('Job Browser - Job Attempt: %(attempt_index)s') % {'attempt_in
     });
 </script>
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

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

@@ -29,7 +29,7 @@
 </%def>
 
 % if jobs or filtered:
-${commonheader(_('Job Browser'), "jobbrowser", user)}
+${ commonheader(_('Job Browser'), "jobbrowser", user) | n,unicode }
 <div class="container-fluid">
 <h1>${_('Job Browser')}</h1>
 <form class="well form-inline" action="/jobbrowser/jobs" method="GET">
@@ -153,7 +153,7 @@ ${commonheader(_('Job Browser'), "jobbrowser", user)}
     % endif
 
     % else:
-        ${commonheader(_('Job Browser'), "jobbrowser", user)}
+        ${ commonheader(_('Job Browser'), "jobbrowser", user) | n,unicode }
         <div class="container-fluid">
         <h1>${_('Welcome to the Job Browser')}</h1>
         <div>
@@ -237,4 +237,4 @@ ${commonheader(_('Job Browser'), "jobbrowser", user)}
     });
 </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" />
 
-${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">
     <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>
 
 
-${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" />
 
-${ 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)">
     %   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>
 
-${ 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" />
 
-${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">
 	<h1>${_('Tracker at %(trackerHost)s on port %(trackerPort)s') % dict(trackerHost=tracker.host, trackerPort=tracker.httpPort)}</h1>
 	<div>
@@ -58,4 +58,4 @@ ${commonheader(_('Tracker: %(trackerId)s - Job Browser') % dict(trackerId=tracke
 	</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" />
-${commonheader(_('Task Trackers - Job Browser'), "jobbrowser", user)}
+${ commonheader(_('Task Trackers - Job Browser'), "jobbrowser", user) | n,unicode }
 
 <div class="container-fluid">
 
@@ -74,4 +74,4 @@ $(document).ready(function(){
 });
 </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" />
 
-${commonheader(_('Job Designer'), "jobsub", user, "100px")}
+${ commonheader(_('Job Designer'), "jobsub", user, "100px") | n,unicode }
 ${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>
 
 
-<%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">
-        <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
       </div>
     </div>
@@ -198,7 +202,7 @@ ${layout.menubar(section='designs')}
 
 <script type="text/javascript" charset="utf-8">
     $(document).ready(function(){
-        var propertiesHint = ${properties_hint};
+        var propertiesHint = ${ properties_hint | n,unicode };
 
         // The files and archives are dictionaries in the model, because we
         // 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 = {
             init: function(element, valueAccessor, allBindings, model) {
@@ -327,4 +332,4 @@ ${layout.menubar(section='designs')}
 </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 django.utils.translation import ugettext as _
 %>
+
 <%namespace name="commonlayout" file="layout.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')}
 
 <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##')}";
 
     $(document).ready(function() {
-
         var designTable, viewModel;
 
         $("#filterInput").keyup(function() {
@@ -157,7 +157,7 @@ ${layout()}
             $("#installSamples").modal("show");
         });
 
-        viewModel = new JobSubModel(${designs});
+        viewModel = new JobSubModel(${ designs | n });
         ko.applyBindings(viewModel);
         designTable = $('#designTable').dataTable( {
             "sPaginationType": "bootstrap",
@@ -196,4 +196,5 @@ ${layout()}
         $("a[data-row-selector='true']").jHueRowSelector();
     });
 </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="actionbar" file="actionbar.mako" />
 
-${commonheader(_('Job Designer'), "jobsub", user, "100px")}
+${ commonheader(_('Job Designer'), "jobsub", user, "100px") | n,unicode }
 ${layout.menubar(section='history')}
 
 <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>
 
-${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" />
 
-${commonheader(_("Job Designer"), "jobsub", user, "100px")}
+${ commonheader(_("Job Designer"), "jobsub", user, "100px") | n,unicode }
 ${layout.menubar(section='history')}
 
 <%def name="format_time(st_time)">
@@ -198,12 +198,12 @@ ${layout.menubar(section='history')}
 
         ## Tab: Definition
         <div class="tab-pane" id="definition">
-          <textarea id="definitionEditor">${definition|h}</textarea>
+          <textarea id="definitionEditor">${ definition }</textarea>
         </div>
 
         ## Tab: Log
         <div class="tab-pane" id="log">
-            <pre>${log|h}</pre>
+            <pre>${log}</pre>
         </div>
     </ul>
   </div>
@@ -238,4 +238,4 @@ ${configModal("appConfigModal", "Application Configuration", workflow.conf_dict)
   });
 </script>
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

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

@@ -19,6 +19,11 @@ import copy
 import logging
 import time
 
+try:
+  import json
+except ImportError:
+  import simplejson as json
+
 from nose.tools import assert_true, assert_false, assert_equal, assert_raises
 from django.contrib.auth.models import User
 
@@ -30,6 +35,7 @@ from jobsub import conf
 from jobsub.management.commands import jobsub_setup
 from jobsub.models import OozieDesign, OozieMapreduceAction, OozieStreamingAction, CheckForSetup
 from jobsub.parameterization import recursive_walk, find_variables, substitute_variables
+from django.template.defaultfilters import escapejs
 
 
 LOG = logging.getLogger(__name__)
@@ -141,29 +147,32 @@ def test_job_design_cycle():
   # Now check list
   response = c.get('/jobsub/')
   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
+  name1 = escape('name-1')
+  name2 = escape('name-2')
+
   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'))
   assert_false('doesnotexist' in response.content)
 
   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"))
-  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)
 
   # Combined filters
   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)
 
   # Try delete
@@ -181,6 +190,10 @@ def test_job_design_cycle():
   assert_true('Permission denied.' in response.content, response.content)
 
 
+def escape(text):
+  return json.dumps(escapejs(text))
+
+
 class TestJobsubWithHadoop(OozieServerProvider):
 
   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.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+from django.template.defaultfilters import escapejs
 """
 Views for JobSubmission.
 
@@ -159,9 +160,9 @@ def list_designs(request):
   for design in data:
       ko_design = {
           '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,
           'last_modified': py_time.mktime(design.last_modified.timetuple()),
           '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)
 
   return render("list_designs.mako", request, {
-    'currentuser':request.user,
+    'currentuser': request.user,
     'owner': owner,
     'name': name,
     'designs': json.dumps(designs),

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

@@ -17,6 +17,7 @@
 
 import logging
 import time
+from django.template.defaultfilters import escapejs
 
 try:
   import json
@@ -147,6 +148,16 @@ class Job(models.Model):
   def get_parameters(self):
     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
   def status(self):
     if self.is_shared:
@@ -296,6 +307,10 @@ class Workflow(Job):
 
     return copy
 
+  @property
+  def job_properties_escapejs(self):
+    return self._escapejs_parameters_list(self.job_properties)
+
   def has_cycle(self):
     """
     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
 
-
   def find_parameters(self):
     params = set()
 
@@ -939,8 +953,8 @@ class Email(Action):
   PARAM_FIELDS = ('to', 'cc', 'subject', 'body')
   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.'))
   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="utils" file="../utils.inc.mako" />
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='dashboard') }
 
 
@@ -211,11 +211,11 @@ ${ layout.menubar(section='dashboard') }
     </div>
 
     <div class="tab-pane" id="log">
-        <pre>${ oozie_coordinator.log | h }</pre>
+        <pre>${ oozie_coordinator.log }</pre>
     </div>
 
     <div class="tab-pane" id="definition">
-        <pre>${ oozie_coordinator.definition | h }</pre>
+        <pre>${ oozie_coordinator.definition }</pre>
     </div>
     </div>
   </div>
@@ -263,4 +263,4 @@ ${ layout.menubar(section='dashboard') }
   });
 </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="utils" file="../utils.inc.mako" />
 
-${commonheader(_("Oozie App"), "oozie", user, "100px")}
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${layout.menubar(section='dashboard')}
 
 
@@ -312,4 +312,4 @@ ${layout.menubar(section='dashboard')}
   });
 </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="utils" file="../utils.inc.mako" />
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='dashboard') }
 
 
@@ -100,10 +100,10 @@ ${ layout.menubar(section='dashboard') }
         <div class="row-fluid">
           <div class="span3"></div>
           <div class="span3">
-            ${ var | h }
+            ${ var }
           </div>
           <div class="span3">
-            ${ utils.guess_hdfs_link(var, str(value)) | h }
+            ${ utils.guess_hdfs_link(var, str(value)) }
           </div>
         </div>
       % endif
@@ -168,7 +168,7 @@ ${ layout.menubar(section='dashboard') }
            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
        </div>
      % endif
@@ -272,11 +272,11 @@ ${ layout.menubar(section='dashboard') }
       </div>
 
       <div class="tab-pane" id="log">
-          <pre>${ oozie_workflow.log | h }</pre>
+          <pre>${ oozie_workflow.log }</pre>
       </div>
 
       <div class="tab-pane" id="definition">
-          <textarea id="definitionEditor">${ oozie_workflow.definition | h }</textarea>
+          <textarea id="definitionEditor">${ oozie_workflow.definition }</textarea>
       </div>
   </div>
 
@@ -368,4 +368,4 @@ ${ layout.menubar(section='dashboard') }
   });
 </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="utils" file="../utils.inc.mako" />
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='running') }
 
 
@@ -130,4 +130,4 @@ ${ layout.menubar(section='running') }
   <a class="btn" onclick="history.back()">${ _('Back') }</a>
 </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" />
 
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='dashboard') }
 
 
@@ -307,4 +307,4 @@ ${ layout.menubar(section='dashboard') }
   });
 </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 id="param-container">
-        ${ params_form.management_form }
+        ${ params_form.management_form | n,unicode }
 
         % if params_form.forms:
           % if len(params_form.forms) > 1:
@@ -56,7 +56,7 @@
           % endif
           % for form in params_form.forms:
             % for hidden in form.hidden_fields():
-              ${ hidden }
+              ${ hidden | n,unicode }
             % endfor
             <div class="fieldWrapper">
               <div class="row-fluid
@@ -94,4 +94,4 @@
             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">
       <div class="modal-header">
         <a href="#" class="close">&times;</a>
-        <h3 class="message">${_('Import Node')}</h3>
+        <h3 class="message">${_('Import Action')}</h3>
       </div>
 
       <div class="modal-content">

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

@@ -82,7 +82,7 @@
                 <br/>
                 ${"${"} hadoop:counters('secondjob')[RECORDS][REDUCE_OUT] lt 1000000 }
                 <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>

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

@@ -62,34 +62,34 @@
 
 </%def>
 
-<%def name="init_viewmodel(element, initial_value)">
+<%def name="init_viewmodel(coordinator)">
   <script type="text/javascript">
     $(document).ready(function(){
-      var ViewModel = function(${ element }) {
+      var ViewModel = function() {
         var self = this;
-        self.${ element } = ko.observableArray(${ element });
+        self.parameters = ko.observableArray(${ coordinator.parameters_escapejs | n });
 
         self.add_parameters = function() {
-          self.${ element }.push({name: "", value: ""});
+          self.parameters.push({name: "", value: ""});
         };
 
         self.remove_parameters = function(val) {
-          self.${ element }.remove(val);
+          self.parameters.remove(val);
         };
 
         self.submit = function(form) {
           var form = $("#jobForm");
 
           $("<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);
 
           form.submit();
         };
       };
 
-      window.viewModel = new ViewModel(${ initial_value });
+      window.viewModel = new ViewModel();
     });
   </script>
 </%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="utils" file="../utils.inc.mako" />
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='coordinators') }
 
 <style type="text/css">
@@ -229,4 +229,4 @@ ${ layout.menubar(section='coordinators') }
 
 ${ 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>
 
-  ${ formset.management_form }
+  ${ formset.management_form | n,unicode }
 
   </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="utils" file="../utils.inc.mako" />
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='workflows') }
 
 
@@ -89,4 +89,4 @@ ${ utils.path_chooser_libs(True, True) }
   });
 </script>
 
-${ commonfooter(messages) }
+${ commonfooter(messages) | n,unicode }

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

@@ -58,9 +58,9 @@
 </div>
 
 <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>
 
 <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="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') }
 
 <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="#step5" class="step">${ _('Step 5: Advanced settings') }</a></li>
         </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 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['description']) }
               ${ utils.render_field_no_popover(coordinator_form['workflow'], extra_attrs = {'validate':'true'}) }
-              ${ coordinator_form['parameters'] }
+              ${ coordinator_form['parameters'] | n,unicode }
               <div class="hide">
                 ${ utils.render_field(coordinator_form['timeout']) }
                 ${ coordinator_form['schema_version'] }
@@ -156,12 +156,12 @@ ${ layout.menubar(section='coordinators') }
                 <tbody>
                 % for form in data_input_formset.forms:
                 <tr>
-                ${ form['id'] }
+                  ${ form['id'] }
                   <td>${ form['name'] }</td>
                   <td>${ form['dataset'] }</td>
                   <td>${ form['dataset'].form.instance.dataset.uri }</td>
                 % 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
                 </tr>
                 % endfor
@@ -214,7 +214,7 @@ ${ layout.menubar(section='coordinators') }
                     <td>${ form['dataset'] }</td>
                     <td>${ form['dataset'].form.instance.dataset.uri }</td>
                     % 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
                   </tr>
                 % endfor
@@ -250,7 +250,7 @@ ${ layout.menubar(section='coordinators') }
               </div>
             </div>
             ${ utils.render_field_no_popover(coordinator_form['execution']) }
-            ${ coordinator_form['schema_version'] }
+            ${ coordinator_form['schema_version'] | n,unicode }
           </div>
 
         </div>
@@ -311,7 +311,7 @@ ${ layout.menubar(section='coordinators') }
               <tbody>
               % for form in dataset_formset.forms:
                 % for hidden in form.hidden_fields():
-                  ${ hidden }
+                  ${ hidden | n,unicode }
                 % endfor
                 <tr>
                   <td>
@@ -328,15 +328,15 @@ ${ layout.menubar(section='coordinators') }
                   <td>${ form.instance.done_flag }</td>
                   % if coordinator.is_editable(user):
                     <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>
                   % endif
                 </tr>
 
                 <div class="hide">
                   % for field in form.visible_fields():
-                  ${ field.errors }
-                  ${ field.label }: ${ field }
+                  ${ field.errors | n,unicode }
+                  ${ field.label }: ${ field | n,unicode }
                   % endfor
                 </div>
               % endfor
@@ -697,4 +697,4 @@ ${ layout.menubar(section='coordinators') }
 
 ${ 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 django.utils.translation import ugettext as _
+  from django.template.defaultfilters import escapejs
 %>
 
 <%namespace name="layout" file="../navigation-bar.mako" />
@@ -25,7 +26,7 @@
 <%namespace name="controls" file="control_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') }
 
 
@@ -160,7 +161,7 @@ ${ layout.menubar(section='workflows') }
               <div class="tab-pane" id="import">
                 <p>
                 <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>
                 <p/>
               </div>
@@ -489,8 +490,8 @@ var workflow_model = new WorkflowModel({
   job_xml: "${ workflow.job_xml }",
   deployment_dir: "${ workflow.deployment_dir }",
   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 workflow = new Workflow({
@@ -754,4 +755,4 @@ ${ utils.path_chooser_libs(True) }
   });
 </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.
 
     <action name="${ node }">
-        ${ node.xml }
+        ${ node.xml | n,unicode }
         <ok to="${ node.get_oozie_child('ok') }"/>
         <error to="${ node.get_oozie_child('error') }"/>
     </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" />
 
 
-<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():
   <global>
     % if workflow.job_xml:
-      <job-xml>${ workflow.job_xml }</job-xml>
+      <job-xml>${ workflow.job_xml | x }</job-xml>
     % endif
     % if workflow.get_properties():
-      ${ common.configuration(workflow.get_properties()) }
+      ${ common.configuration(workflow.get_properties()) | x }
     % endif
   </global>
   % endif
   % for node in workflow.node_list:
-      ${ node.to_xml() }
+      ${ node.to_xml() | n }
   % endfor
 </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="utils" file="../utils.inc.mako" />
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='workflows') }
 
 
@@ -82,4 +82,4 @@ ${ layout.menubar(section='workflows') }
 
 ${ 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="utils" file="../utils.inc.mako" />
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='coordinators') }
 
 
@@ -250,4 +250,4 @@ ${ layout.menubar(section='coordinators') }
   });
 </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="utils" file="../utils.inc.mako" />
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='history') }
 
 
@@ -103,4 +103,4 @@ ${ layout.menubar(section='history') }
   $("a[data-row-selector='true']").jHueRowSelector();
 </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="layout" file="../navigation-bar.mako" />
 
-${ commonheader(_("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='history') }
 
 
@@ -81,4 +81,4 @@ ${ layout.menubar(section='history') }
    <a href="${ url('oozie:list_history') }" class="btn">${ _('Back') }</a>
 </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="utils" file="../utils.inc.mako" />
 
-${ commonheader( _("Oozie App"), "oozie", user, "100px") }
+${ commonheader(_("Oozie App"), "oozie", user, "100px") | n,unicode }
 ${ layout.menubar(section='workflows') }
 
 
@@ -261,4 +261,4 @@ ${ layout.menubar(section='workflows') }
   });
 </script>
 
-${commonfooter(messages)}
+${commonfooter(messages) |n,unicode}

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

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

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

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

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

@@ -1298,6 +1298,29 @@ class TestEditor(OozieMockBase):
     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):
 
   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.rest.http_client import RestException
 from hadoop.fs.exceptions import WebHdfsException
-from jobsub.models import OozieDesign
 from liboozie.submittion import Submission
 
 from oozie.conf import SHARE_JOBS
 from oozie.decorators import check_job_access_permission, check_job_edition_permission,\
                              check_dataset_access_permission, check_dataset_edition_permission
 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.models import Job, Workflow, History, Coordinator, Mapreduce, Java, Streaming,\
+from oozie.models import Job, Workflow, History, Coordinator,\
                          Dataset, DataInput, DataOutput, ACTION_TYPES
 from oozie.forms import WorkflowForm, CoordinatorForm, DatasetForm,\
   DataInputForm, DataInputSetForm, DataOutputForm, DataOutputSetForm, LinkForm,\
-  DefaultLinkForm, design_form_by_type, ImportJobsubDesignForm, ParameterForm,\
+  DefaultLinkForm, design_form_by_type, ParameterForm,\
   ImportWorkflowForm
 
 
@@ -334,8 +332,7 @@ def edit_coordinator(request, coordinator):
     'dataset_form': dataset_form,
     'new_data_input_formset': new_data_input_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 _
 %>
 
-${commonheader(_('Hue Shell'), "shell", user)}
+${ commonheader(_('Hue Shell'), "shell", user) | n,unicode }
 <div class="container-fluid">
 <div>
     <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>
 </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="container-fluid">
@@ -297,4 +297,4 @@ ${commonheader(_('Hue Shell'), "shell", user, "100px")}
 </script>
 </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 _
 %>
 
-${commonheader(_('Hue Shell'), "shell", user)}
+${ commonheader(_('Hue Shell'), "shell", user) | n,unicode }
 <div class="container-fluid">
 <div>
     <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>
-${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 _
 %>
 
-${commonheader(_('Hue Shell'), "shell", user)}
+${ commonheader(_('Hue Shell'), "shell", user) | n,unicode }
 <div class="container-fluid">
 <div>
 	<h3>${_('The webserver currently running Hue does not support the Shell application. Please contact your administrator.')}</h3>
 </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" />
 
-${commonheader(_('Hue Users'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Users'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='users', _=_)}
 
 
@@ -64,4 +64,4 @@ ${layout.menubar(section='users', _=_)}
   });
 </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 django.utils.translation import ugettext as _
 %>
-${commonheader(title, "useradmin", user)}
+${ commonheader(title, "useradmin", user) | n,unicode }
 <div class="container-fluid">
 	<h1>${_('Confirm')}</h1>
 	<form action="${path}" method="POST">
@@ -25,4 +25,4 @@ ${commonheader(title, "useradmin", user)}
 		<input type="submit" value="${_('Yes')}">
 	</form>
 </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" />
 
-${commonheader(_('Hue Groups'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Groups'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='groups', _=_)}
 
 <%def name="render_field(field)">
@@ -96,4 +96,4 @@ ${layout.menubar(section='groups', _=_)}
 	});
 </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" />
 
-${commonheader(_('Hue Permissions'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Permissions'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='permissions', _=_)}
 
 
@@ -66,4 +66,4 @@ ${layout.menubar(section='permissions', _=_)}
         });
 	});
 </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" />
 
-${commonheader(_('Hue Users'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Users'), "useradmin", user, "100px") | n,unicode }
 
 % if user.is_superuser:
   ${layout.menubar(section='users', _=_)}
@@ -101,4 +101,4 @@ ${commonheader(_('Hue Users'), "useradmin", user, "100px")}
     });
 </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="layout" file="layout.mako" />
-${commonheader(_('Hue Groups'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Groups'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='groups', _=_)}
 
 <div class="container-fluid">
@@ -165,4 +165,4 @@ ${layout.menubar(section='groups', _=_)}
 
 ${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="layout" file="layout.mako" />
-${commonheader(_('Hue Permissions'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Permissions'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='permissions', _=_)}
 
 <div class="container-fluid">
@@ -92,4 +92,4 @@ ${layout.menubar(section='permissions', _=_)}
 
 ${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="layout" file="layout.mako" />
-${commonheader(_('Hue Users'), "useradmin", user, "100px")}
+${ commonheader(_('Hue Users'), "useradmin", user, "100px") | n,unicode }
 ${layout.menubar(section='users', _=_)}
 
 <div class="container-fluid">
@@ -176,4 +176,4 @@ ${layout.menubar(section='users', _=_)}
 
 ${layout.commons()}
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }

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

@@ -341,9 +341,9 @@
 
 [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>
 
   # Port where Beeswax Thrift server runs on.

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

@@ -344,9 +344,9 @@
 
 [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>
 
   # 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
 IMPORTS=[
-  "from desktop.lib.django_mako import url"
+  "from desktop.lib.django_mako import url",
+  "from django.utils.html import escape"
 ]
 
 class DesktopLookup(TemplateCollection):
@@ -63,7 +64,7 @@ class DesktopLookup(TemplateCollection):
                             output_encoding=i18n.get_site_encoding(),
                             input_encoding=i18n.get_site_encoding(),
                             encoding_errors=ENCODING_ERRORS,
-                            default_filters=['unicode'], 
+                            default_filters=['unicode', 'escape'], 
                             imports=IMPORTS)
     # TODO(philip): Make a django_aware default filter, that understands
     # 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):
   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
   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 django.utils.translation import ugettext as _
 %>
-${commonheader(_('Not Found'), "", user)}
+${ commonheader(_('Not Found'), "", user) | n,unicode }
 
   <div class="container-fluid">
     <h1>${_('Page not found')}</h1>
@@ -26,4 +26,4 @@ ${commonheader(_('Not Found'), "", user)}
     <code>${uri}</code>
   </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 django.utils.translation import ugettext as _
 %>
-${commonheader(_('Error'), "", user)}
+${ commonheader(_('Error'), "", user) | n,unicode }
 
   <div class="container-fluid">
     <h1>${_('Server Error (500)')}</h1>
@@ -42,9 +42,9 @@ ${commonheader(_('Error'), "", user)}
           <tbody>
             % for (file_name, line_number, function_name, text) in traceback:
               <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>
             % endfor
           </tbody>
@@ -62,4 +62,4 @@ ${commonheader(_('Error'), "", user)}
     }
   </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" />
-${commonheader(_('About'), "about", user, "100px")}
+${ commonheader(_('About'), "about", user, "100px") | n,unicode }
 
 ${layout.menubar(section='check_config')}
 
@@ -57,4 +57,4 @@ ${layout.menubar(section='check_config')}
     % endif
 </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">
 <head>
   <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="description" 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" />
 
-${commonheader(_('About'), "about", user, "100px")}
+${ commonheader(_('About'), "about", user, "100px") | n,unicode }
 ${layout.menubar(section='dump_config')}
 
     <div class="container-fluid">
@@ -118,4 +118,4 @@ ${layout.menubar(section='dump_config')}
 
     </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 _
 %>
 
-${commonheader(_('Error'), app_name, user)}
+${ commonheader(_('Error'), app_name, user) | n,unicode }
 
   <div class="container-fluid">
-    <h1>${_('Error!')}</h1>
-    <pre>${smart_unicode(error) | h }</pre>
+    <h1>${ _('Error!') }</h1>
+    <pre>${ smart_unicode(error) }</pre>
 
     %if traceback:
       <textarea style="width: 100%;" rows=80 readonly="readonly">
-      ${smart_unicode(traceback) | h}
+      ${ smart_unicode(traceback) }
       </textarea>
     %endif
 
     <a class="btn" onclick="history.back()">${ _('Back') }</a>
   </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">
                 <form method="POST" action="${action}" class="well">
                     <label>${_('Username')}
-                        ${ form['username'] }
+                        ${ form['username'] | n,unicode }
                         ${ form['username'].errors }
                     </label>
                     <label>${_('Password')}
-                        ${ form['password'] }
+                        ${ form['password'] | n,unicode }
                         ${ form['password'].errors }
                     </label>
 
-                    %if first_login_ever==True:
+                    %if first_login_ever:
                         <input type="submit" class="btn btn-primary" value="${_('Sign up')}" />
                     %else:
                         <input type="submit" class="btn btn-primary" value="${_('Sign in')}" />
                     %endif
                     <input type="hidden" name="next" value="${next}" />
 
-                    %if login_errors==True:
+                    %if login_errors:
                         <br/>
                         <br/>
                         <div class="alert alert-error">
@@ -90,7 +90,7 @@ from django.utils.translation import ugettext as _
             </div>
         </div>
 
-        %if first_login_ever==True:
+        %if first_login_ever:
         <div class="row">
             <div class="span6 offset3">
                 <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 _
 import re
 %>
+
 <%namespace name="actionbar" file="actionbar.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')}
 
 <style>
@@ -71,7 +73,7 @@ ${layout.menubar(section='log_view')}
 
   <div id="logs">
       % for l in log:
-        <pre>${smart_unicode(l, errors='ignore') | h}</pre>
+        <pre>${smart_unicode(l, errors='ignore')}</pre>
       % endfor
   </div>
 
@@ -141,4 +143,4 @@ ${layout.menubar(section='log_view')}
   });
 </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 _
 %>
 
-${commonheader(title, "", user)}
+${ commonheader(title, "", user) | n,unicode }
 
   <div class="container-fluid">
     <div class="alert">
-      <p><strong>${smart_unicode(message) | h}</strong></p>
+      <p><strong>${smart_unicode(message)}</strong></p>
 
       % if detail:
-      <p>${smart_unicode(detail) or "" | h}</p>
+      <p>${smart_unicode(detail) or "" }</p>
       % endif
 
     </div>
@@ -50,9 +50,9 @@ ${commonheader(title, "", user)}
             <tbody>
               % for (file_name, line_number, function_name, text) in traceback:
                 <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>
               % endfor
             </tbody>
@@ -76,4 +76,4 @@ ${commonheader(title, "", user)}
     }
   </script>
 
-${commonfooter(messages)}
+${ commonfooter(messages) | n,unicode }