@@ -235,18 +235,7 @@ class AgentsController < ApplicationController |
||
| 235 | 235 |
|
| 236 | 236 |
# Sanitize params[:return] to prevent open redirect attacks, a common security issue. |
| 237 | 237 |
def redirect_back(message, options = {})
|
| 238 |
- case ret = params[:return] || options[:return] |
|
| 239 |
- when "show" |
|
| 240 |
- if @agent && !@agent.destroyed? |
|
| 241 |
- path = agent_path(@agent) |
|
| 242 |
- else |
|
| 243 |
- path = agents_path |
|
| 244 |
- end |
|
| 245 |
- when /\A#{Regexp::escape scenarios_path}\/\d+\z/, agents_path
|
|
| 246 |
- path = ret |
|
| 247 |
- end |
|
| 248 |
- |
|
| 249 |
- if path |
|
| 238 |
+ if path = filtered_agent_return_link(options) |
|
| 250 | 239 |
redirect_to path, notice: message |
| 251 | 240 |
else |
| 252 | 241 |
super agents_path, notice: message |
@@ -30,6 +30,20 @@ class ApplicationController < ActionController::Base |
||
| 30 | 30 |
basecamp_auth_check |
| 31 | 31 |
end |
| 32 | 32 |
|
| 33 |
+ def filtered_agent_return_link(options = {})
|
|
| 34 |
+ case ret = params[:return].presence || options[:return] |
|
| 35 |
+ when "show" |
|
| 36 |
+ if @agent && !@agent.destroyed? |
|
| 37 |
+ agent_path(@agent) |
|
| 38 |
+ else |
|
| 39 |
+ agents_path |
|
| 40 |
+ end |
|
| 41 |
+ when /\A#{(Regexp::escape scenarios_path)}/, /\A#{(Regexp::escape agents_path)}/, /\A#{(Regexp::escape events_path)}/
|
|
| 42 |
+ ret |
|
| 43 |
+ end |
|
| 44 |
+ end |
|
| 45 |
+ helper_method :filtered_agent_return_link |
|
| 46 |
+ |
|
| 33 | 47 |
private |
| 34 | 48 |
|
| 35 | 49 |
def twitter_oauth_check |
@@ -1,7 +1,7 @@ |
||
| 1 | 1 |
<ul class="dropdown-menu" role="menu"> |
| 2 | 2 |
<% if agent.can_be_scheduled? %> |
| 3 | 3 |
<li> |
| 4 |
- <%= link_to icon_tag('glyphicon-refresh', class: 'color-success') + ' Run', run_agent_path(agent, return: returnTo), method: :post, tabindex: "-1" %>
|
|
| 4 |
+ <%= link_to icon_tag('glyphicon-refresh', class: 'color-success') + ' Run', run_agent_path(agent, return: return_to), method: :post, tabindex: "-1" %>
|
|
| 5 | 5 |
</li> |
| 6 | 6 |
<% end %> |
| 7 | 7 |
|
@@ -12,13 +12,13 @@ |
||
| 12 | 12 |
<% end %> |
| 13 | 13 |
|
| 14 | 14 |
<li> |
| 15 |
- <%= link_to icon_tag('glyphicon-eye-open') + ' Show'.html_safe, agent_path(agent) %>
|
|
| 15 |
+ <%= link_to icon_tag('glyphicon-eye-open') + ' Show'.html_safe, agent_path(agent, return: return_to) %>
|
|
| 16 | 16 |
</li> |
| 17 | 17 |
|
| 18 | 18 |
<li class="divider"></li> |
| 19 | 19 |
|
| 20 | 20 |
<li> |
| 21 |
- <%= link_to icon_tag('glyphicon-pencil') + ' Edit agent'.html_safe, edit_agent_path(agent) %>
|
|
| 21 |
+ <%= link_to icon_tag('glyphicon-pencil') + ' Edit agent'.html_safe, edit_agent_path(agent, return: return_to) %>
|
|
| 22 | 22 |
</li> |
| 23 | 23 |
|
| 24 | 24 |
<li> |
@@ -40,7 +40,7 @@ |
||
| 40 | 40 |
|
| 41 | 41 |
<% agent.scenarios.each do |scenario| %> |
| 42 | 42 |
<li> |
| 43 |
- <%= link_to icon_tag('glyphicon-remove-circle', class: 'color-warning') + " Remove from #{scenario_label(scenario)}".html_safe, leave_scenario_agent_path(agent, scenario_id: scenario.to_param, return: returnTo), method: :put, tabindex: "-1" %>
|
|
| 43 |
+ <%= link_to icon_tag('glyphicon-remove-circle', class: 'color-warning') + " Remove from #{scenario_label(scenario)}".html_safe, leave_scenario_agent_path(agent, scenario_id: scenario.to_param, return: return_to), method: :put, tabindex: "-1" %>
|
|
| 44 | 44 |
</li> |
| 45 | 45 |
<% end %> |
| 46 | 46 |
<% end %> |
@@ -49,12 +49,12 @@ |
||
| 49 | 49 |
|
| 50 | 50 |
<% if agent.can_create_events? && agent.events.count > 0 %> |
| 51 | 51 |
<li> |
| 52 |
- <%= link_to icon_tag('glyphicon-trash', class: 'color-danger') + ' Delete all events', remove_events_agent_path(agent, return: returnTo), method: :delete, data: {confirm: 'Are you sure you want to delete ALL emitted events for this Agent?'}, tabindex: "-1" %>
|
|
| 52 |
+ <%= link_to icon_tag('glyphicon-trash', class: 'color-danger') + ' Delete all events', remove_events_agent_path(agent, return: return_to), method: :delete, data: {confirm: 'Are you sure you want to delete ALL emitted events for this Agent?'}, tabindex: "-1" %>
|
|
| 53 | 53 |
</li> |
| 54 | 54 |
<% end %> |
| 55 | 55 |
|
| 56 | 56 |
<li> |
| 57 |
- <%= link_to icon_tag('glyphicon-remove', class: 'color-danger') + ' Delete agent', agent_path(agent, return: returnTo), method: :delete, data: { confirm: 'Are you sure that you want to permanently delete this Agent?' }, tabindex: "-1" %>
|
|
| 57 |
+ <%= link_to icon_tag('glyphicon-remove', class: 'color-danger') + ' Delete agent', agent_path(agent, return: return_to), method: :delete, data: { confirm: 'Are you sure that you want to permanently delete this Agent?' }, tabindex: "-1" %>
|
|
| 58 | 58 |
</li> |
| 59 | 59 |
</ul> |
| 60 | 60 |
|
@@ -69,7 +69,7 @@ |
||
| 69 | 69 |
<p><% if agent.disabled? %>Enable<% else %>Disable<% end %> "<%= agent.name %>"?</p> |
| 70 | 70 |
</div> |
| 71 | 71 |
<div class="modal-footer"> |
| 72 |
- <%= form_for(agent, as: :agent, url: agent_path(agent, return: returnTo), method: 'PUT') do |f| %> |
|
| 72 |
+ <%= form_for(agent, as: :agent, url: agent_path(agent, return: return_to), method: 'PUT') do |f| %> |
|
| 73 | 73 |
<% if agent.disabled && agent.can_receive_events? %> |
| 74 | 74 |
<div class="form-group"> |
| 75 | 75 |
<%= f.check_box :drop_pending_events %> |
@@ -15,6 +15,8 @@ |
||
| 15 | 15 |
method: @agent.new_record? ? "POST" : "PUT", |
| 16 | 16 |
html: { class: 'agent-form' }) do |f| %>
|
| 17 | 17 |
|
| 18 |
+ <%= hidden_field_tag :return, params[:return] %> |
|
| 19 |
+ |
|
| 18 | 20 |
<div class="row"> |
| 19 | 21 |
<div class="col-md-6"> |
| 20 | 22 |
<div class="row"> |
@@ -14,7 +14,7 @@ |
||
| 14 | 14 |
<% @agents.each do |agent| %> |
| 15 | 15 |
<tr> |
| 16 | 16 |
<td class='<%= "agent-unavailable" if agent.unavailable? %>'> |
| 17 |
- <%= link_to agent.name, agent_path(agent) %> |
|
| 17 |
+ <%= link_to agent.name, agent_path(agent, return: (defined?(return_to) && return_to) || request.path) %> |
|
| 18 | 18 |
<br/> |
| 19 | 19 |
<span class='text-muted'><%= agent.short_type.titleize %></span> |
| 20 | 20 |
<% if agent.scenarios.present? %> |
@@ -64,7 +64,7 @@ |
||
| 64 | 64 |
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown"> |
| 65 | 65 |
<span class="glyphicon glyphicon-th-list"></span> Actions <span class="caret"></span> |
| 66 | 66 |
</button> |
| 67 |
- <%= render 'agents/action_menu', :agent => agent, :returnTo => (defined?(returnTo) && returnTo) || "index" %> |
|
| 67 |
+ <%= render 'agents/action_menu', agent: agent, return_to: (defined?(return_to) && return_to) || request.path %> |
|
| 68 | 68 |
</div> |
| 69 | 69 |
</td> |
| 70 | 70 |
</tr> |
@@ -2,7 +2,7 @@ |
||
| 2 | 2 |
<div class='row'> |
| 3 | 3 |
<div class='col-md-2'> |
| 4 | 4 |
<ul class="nav nav-pills nav-stacked" id="show-tabs"> |
| 5 |
- <li><%= link_to icon_tag('glyphicon-chevron-left') + ' Back'.html_safe, agents_path %></li>
|
|
| 5 |
+ <li><%= link_to icon_tag('glyphicon-chevron-left') + ' Back'.html_safe, filtered_agent_return_link || agents_path %></li>
|
|
| 6 | 6 |
|
| 7 | 7 |
<% if agent_show_view(@agent).present? %> |
| 8 | 8 |
<li class='active'><a href="#summary" data-toggle="tab"><span class='glyphicon glyphicon-picture'></span> Summary</a></li> |
@@ -22,7 +22,7 @@ |
||
| 22 | 22 |
|
| 23 | 23 |
<li class="dropdown"> |
| 24 | 24 |
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><span class="glyphicon glyphicon-th-list"></span> Actions <span class="caret"></span></a> |
| 25 |
- <%= render 'agents/action_menu', :agent => @agent, :returnTo => "show" %> |
|
| 25 |
+ <%= render 'agents/action_menu', :agent => @agent, :return_to => "show" %> |
|
| 26 | 26 |
</li> |
| 27 | 27 |
</ul> |
| 28 | 28 |
</div> |
@@ -19,7 +19,7 @@ |
||
| 19 | 19 |
<% @events.each do |event| %> |
| 20 | 20 |
<% next unless event.agent %> |
| 21 | 21 |
<%= content_tag :tr, class: (highlighted?(event.id) ? 'hl' : nil) do %> |
| 22 |
- <td><%= link_to event.agent.name, agent_path(event.agent) %></td> |
|
| 22 |
+ <td><%= link_to event.agent.name, agent_path(event.agent, return: request.fullpath) %></td> |
|
| 23 | 23 |
<td title='<%= event.created_at %>'><%= time_ago_in_words event.created_at %> ago</td> |
| 24 | 24 |
<td class='payload'><%= truncate event.payload.to_json, :length => 90, :omission => "" %></td> |
| 25 | 25 |
<td> |
@@ -40,7 +40,7 @@ |
||
| 40 | 40 |
|
| 41 | 41 |
<% if @agent %> |
| 42 | 42 |
<div class="btn-group"> |
| 43 |
- <%= link_to icon_tag('glyphicon-chevron-left') + ' Back'.html_safe, agents_path, class: "btn btn-default" %>
|
|
| 43 |
+ <%= link_to icon_tag('glyphicon-eye-open') + ' View Agent'.html_safe, agent_path(@agent, return: request.fullpath), class: "btn btn-default" %>
|
|
| 44 | 44 |
<%= link_to icon_tag('glyphicon-random') + ' See all events'.html_safe, events_path, class: "btn btn-default" %>
|
| 45 | 45 |
</div> |
| 46 | 46 |
<% end %> |
@@ -10,13 +10,13 @@ |
||
| 10 | 10 |
<blockquote><%= markdown(@scenario.description) %></blockquote> |
| 11 | 11 |
<% end %> |
| 12 | 12 |
|
| 13 |
- <%= render 'agents/table', :returnTo => scenario_path(@scenario) %> |
|
| 13 |
+ <%= render 'agents/table', :return_to => scenario_path(@scenario) %> |
|
| 14 | 14 |
|
| 15 | 15 |
<br/> |
| 16 | 16 |
|
| 17 | 17 |
<div class="btn-group"> |
| 18 | 18 |
<%= link_to icon_tag('glyphicon-chevron-left') + ' Back', scenarios_path, class: "btn btn-default" %>
|
| 19 |
- <%= link_to icon_tag('glyphicon-plus') + ' New Agent', new_agent_path(scenario_id: @scenario.id), class: "btn btn-default" %>
|
|
| 19 |
+ <%= link_to icon_tag('glyphicon-plus') + ' New Agent', new_agent_path(scenario_id: @scenario.id, return: request.path), class: "btn btn-default" %>
|
|
| 20 | 20 |
<%= link_to icon_tag('glyphicon-random') + ' View Diagram', scenario_diagram_path(@scenario), class: "btn btn-default" %>
|
| 21 | 21 |
<%= link_to icon_tag('glyphicon-edit') + ' Edit', edit_scenario_path(@scenario), class: "btn btn-default" %>
|
| 22 | 22 |
<% if @scenario.source_url.present? %> |