Files
grecia/app/views/budgets/index.html.erb
Javi Martín 7bf4e4d611 Sanitize descriptions in the views
Sanitizing descriptions before saving a record has a few drawbacks:

1. It makes the application rely on data being safe in the database. If
somehow dangerous data enters the database, the application will be
vulnerable to XSS attacks
2. It makes the code complicated
3. It isn't backwards compatible; if we decide to disallow a certain
HTML tag in the future, we'd need to sanitize existing data.

On the other hand, sanitizing the data in the view means we don't need
to triple-check dangerous HTML has already been stripped when we see the
method `auto_link_already_sanitized_html`, since now every time we use
it we sanitize the text in the same line we call this method.

We could also sanitize the data twice, both when saving to the database
and when displaying values in the view. However, doing so wouldn't make
the application safer, since we sanitize text introduced through
textarea fields but we don't sanitize text introduced through input
fields.

Finally, we could also overwrite the `description` method so it
sanitizes the text. But we're already introducing Globalize which
overwrites that method, and overwriting it again is a bit too confusing
in my humble opinion. It can also lead to hard-to-debug behaviour.
2019-10-21 21:32:02 +02:00

156 lines
5.7 KiB
Plaintext

<% if has_banners? %>
<%= render "shared/banner" %>
<% end %>
<% provide :title do %><%= t("budgets.index.title") %><% end %>
<% content_for :canonical do %>
<%= render "shared/canonical", href: budgets_url %>
<% end %>
<% if current_budget.present? %>
<div id="budget_heading" class="expanded budget no-margin-top">
<div class="row" data-equalizer data-equalizer-on="medium">
<div class="small-12 medium-9 column padding" data-equalizer-watch>
<h1><%= current_budget.name %></h1>
<div class="description">
<%= auto_link_already_sanitized_html wysiwyg(current_budget.description) %>
</div>
<p>
<%= link_to t("budgets.index.section_header.help"), "#section_help" %>
</p>
</div>
<div class="small-12 medium-3 column info padding" data-equalizer-watch>
<p>
<strong><%= t("budgets.show.phase") %></strong>
</p>
<h2><%= t("budgets.phase.#{current_budget.phase}") %></h2>
<%= link_to t("budgets.index.section_header.all_phases"), "#all_phases" %>
<% if current_budget.accepting? %>
<% if current_user %>
<% if current_user.level_two_or_three_verified? %>
<%= link_to t("budgets.investments.index.sidebar.create"),
new_budget_investment_path(current_budget),
class: "button margin-top expanded" %>
<% else %>
<div class="callout warning margin-top">
<%= sanitize(t("budgets.investments.index.sidebar.verified_only",
verify: link_to_verify_account)) %>
</div>
<% end %>
<% else %>
<div class="callout primary margin-top">
<%= sanitize(t("budgets.investments.index.sidebar.not_logged_in",
sign_in: link_to_signin, sign_up: link_to_signup)) %>
</div>
<% end %>
<% end %>
<% if can?(:read_results, current_budget) %>
<%= link_to t("budgets.show.see_results"),
budget_results_path(current_budget, heading_id: current_budget.headings.first),
class: "button margin-top expanded" %>
<% end %>
</div>
</div>
</div>
<div id="budget_info" class="budget-info">
<div class="row margin-top">
<div class="small-12 column">
<div id="groups_and_headings" class="groups-and-headings">
<% current_budget.groups.each do |group| %>
<h2 id="<%= group.name.parameterize %>"><%= group.name %></h2>
<ul class="no-bullet" data-equalizer data-equalizer-on="medium">
<% group.headings.sort_by_name.each do |heading| %>
<li class="heading small-12 medium-4 large-2" data-equalizer-watch>
<% unless current_budget.informing? || current_budget.finished? %>
<%= link_to budget_investments_path(current_budget.id,
heading_id: heading.id) do %>
<%= heading_name_and_price_html(heading, current_budget) %>
<% end %>
<% else %>
<div class="heading-name">
<%= heading_name_and_price_html(heading, current_budget) %>
</div>
<% end %>
</li>
<% end %>
</ul>
<% end %>
</div>
<% unless current_budget.informing? %>
<div class="map inline">
<h3><%= t("budgets.index.map") %></h3>
<%= render_map(nil, "budgets", false, nil, @budgets_coordinates) %>
</div>
<ul class="no-bullet margin-top">
<% show_links = show_links_to_budget_investments(current_budget) %>
<% if show_links %>
<li>
<%= link_to budget_path(current_budget) do %>
<small><%= t("budgets.index.investment_proyects") %></small>
<% end %>
</li>
<% end %>
<li>
<%= link_to budget_path(current_budget, filter: "unfeasible") do %>
<small><%= t("budgets.index.unfeasible_investment_proyects") %></small>
<% end %>
</li>
<% if show_links %>
<li>
<%= link_to budget_path(current_budget, filter: "unselected") do %>
<small><%= t("budgets.index.not_selected_investment_proyects") %></small>
<% end %>
</li>
<% end %>
</ul>
<% end %>
<div id="all_phases">
<h2><%= t("budgets.index.all_phases") %></h2>
<%= render "phases", budget: current_budget %>
</div>
</div>
</div>
<% if @finished_budgets.present? %>
<%= render "finished", budgets: @finished_budgets %>
<% end %>
</div>
<% else %>
<div class="expanded budget no-margin-top margin-bottom">
<div class="row">
<div class="small-12 medium-9 column padding">
<h1><%= t("budgets.index.title") %></h1>
</div>
</div>
</div>
<div class="row">
<div class="small-12 column">
<div class="callout primary">
<%= t("budgets.index.empty_budgets") %>
</div>
</div>
</div>
<% end %>
<div class="row">
<div class="small-12 column">
<div id="section_help" class="margin" data-magellan-target="section_help">
<p class="lead">
<strong><%= t("budgets.index.section_footer.title") %></strong>
</p>
<p><%= t("budgets.index.section_footer.description") %></p>
</div>
</div>
</div>