From: Anton Khorev Date: Wed, 27 Mar 2024 10:25:28 +0000 (+0300) Subject: Move trace pictures/icons into their own controllers X-Git-Tag: live~943^2 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/180a61bcc30a165899e0bbadb77d1114170a0fda Move trace pictures/icons into their own controllers --- diff --git a/app/abilities/ability.rb b/app/abilities/ability.rb index b43cc6b29..3aba63c33 100644 --- a/app/abilities/ability.rb +++ b/app/abilities/ability.rb @@ -23,7 +23,7 @@ class Ability can [:new, :create, :edit, :update], :password can [:index, :show], Redaction can [:new, :create, :destroy], :session - can [:index, :show, :data, :georss, :picture, :icon], Trace + can [:index, :show, :data, :georss], Trace can [:terms, :new, :create, :save, :suspended, :show, :auth_success, :auth_failure], User can [:index, :show, :blocks_on, :blocks_by], UserBlock end diff --git a/app/controllers/traces/icons_controller.rb b/app/controllers/traces/icons_controller.rb new file mode 100644 index 000000000..a58179654 --- /dev/null +++ b/app/controllers/traces/icons_controller.rb @@ -0,0 +1,29 @@ +module Traces + class IconsController < ApplicationController + before_action :authorize_web + before_action :check_database_readable + + authorize_resource :trace + + def show + trace = Trace.find(params[:trace_id]) + + if trace.visible? && trace.inserted? + if trace.public? || (current_user && current_user == trace.user) + if trace.icon.attached? + redirect_to rails_blob_path(trace.icon, :disposition => "inline") + else + expires_in 7.days, :private => !trace.public?, :public => trace.public? + send_file(trace.icon_picture_name, :filename => "#{trace.id}_icon.gif", :type => "image/gif", :disposition => "inline") + end + else + head :forbidden + end + else + head :not_found + end + rescue ActiveRecord::RecordNotFound + head :not_found + end + end +end diff --git a/app/controllers/traces/pictures_controller.rb b/app/controllers/traces/pictures_controller.rb new file mode 100644 index 000000000..aeac7df86 --- /dev/null +++ b/app/controllers/traces/pictures_controller.rb @@ -0,0 +1,29 @@ +module Traces + class PicturesController < ApplicationController + before_action :authorize_web + before_action :check_database_readable + + authorize_resource :trace + + def show + trace = Trace.find(params[:trace_id]) + + if trace.visible? && trace.inserted? + if trace.public? || (current_user && current_user == trace.user) + if trace.icon.attached? + redirect_to rails_blob_path(trace.image, :disposition => "inline") + else + expires_in 7.days, :private => !trace.public?, :public => trace.public? + send_file(trace.large_picture_name, :filename => "#{trace.id}.gif", :type => "image/gif", :disposition => "inline") + end + else + head :forbidden + end + else + head :not_found + end + rescue ActiveRecord::RecordNotFound + head :not_found + end + end +end diff --git a/app/controllers/traces_controller.rb b/app/controllers/traces_controller.rb index 42aea8299..f717d6943 100644 --- a/app/controllers/traces_controller.rb +++ b/app/controllers/traces_controller.rb @@ -208,48 +208,6 @@ class TracesController < ApplicationController @traces = @traces.includes(:user) end - def picture - trace = Trace.find(params[:id]) - - if trace.visible? && trace.inserted? - if trace.public? || (current_user && current_user == trace.user) - if trace.icon.attached? - redirect_to rails_blob_path(trace.image, :disposition => "inline") - else - expires_in 7.days, :private => !trace.public?, :public => trace.public? - send_file(trace.large_picture_name, :filename => "#{trace.id}.gif", :type => "image/gif", :disposition => "inline") - end - else - head :forbidden - end - else - head :not_found - end - rescue ActiveRecord::RecordNotFound - head :not_found - end - - def icon - trace = Trace.find(params[:id]) - - if trace.visible? && trace.inserted? - if trace.public? || (current_user && current_user == trace.user) - if trace.icon.attached? - redirect_to rails_blob_path(trace.icon, :disposition => "inline") - else - expires_in 7.days, :private => !trace.public?, :public => trace.public? - send_file(trace.icon_picture_name, :filename => "#{trace.id}_icon.gif", :type => "image/gif", :disposition => "inline") - end - else - head :forbidden - end - else - head :not_found - end - rescue ActiveRecord::RecordNotFound - head :not_found - end - private def do_create(file, tags, description, visibility) diff --git a/config/routes.rb b/config/routes.rb index 224639464..1633e2b26 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -209,8 +209,10 @@ OpenStreetMap::Application.routes.draw do get "/user/:display_name/traces/tag/:tag/rss" => "traces#georss", :defaults => { :format => :rss } get "/user/:display_name/traces/rss" => "traces#georss", :defaults => { :format => :rss } get "/user/:display_name/traces/:id" => "traces#show", :as => "show_trace" - get "/user/:display_name/traces/:id/picture" => "traces#picture", :as => "trace_picture" - get "/user/:display_name/traces/:id/icon" => "traces#icon", :as => "trace_icon" + scope "/user/:display_name/traces/:trace_id", :module => :traces do + get "picture" => "pictures#show", :as => "trace_picture" + get "icon" => "icons#show", :as => "trace_icon" + end get "/traces/tag/:tag/page/:page", :page => /[1-9][0-9]*/, :to => redirect(:path => "/traces/tag/%{tag}") get "/traces/tag/:tag" => "traces#index" get "/traces/page/:page", :page => /[1-9][0-9]*/, :to => redirect(:path => "/traces") diff --git a/test/controllers/traces/icons_controller_test.rb b/test/controllers/traces/icons_controller_test.rb new file mode 100644 index 000000000..9d1c6ed9c --- /dev/null +++ b/test/controllers/traces/icons_controller_test.rb @@ -0,0 +1,76 @@ +require "test_helper" + +module Api + class IconsControllerTest < ActionDispatch::IntegrationTest + ## + # test all routes which lead to this controller + def test_routes + assert_routing( + { :path => "/user/username/traces/1/icon", :method => :get }, + { :controller => "traces/icons", :action => "show", :display_name => "username", :trace_id => "1" } + ) + end + + # Test downloading the icon for a trace + def test_show + public_trace_file = create(:trace, :visibility => "public", :fixture => "a") + + # First with no auth, which should work since the trace is public + get trace_icon_path(public_trace_file.user, public_trace_file) + check_trace_icon public_trace_file + + # Now with some other user, which should work since the trace is public + session_for(create(:user)) + get trace_icon_path(public_trace_file.user, public_trace_file) + check_trace_icon public_trace_file + + # And finally we should be able to do it with the owner of the trace + session_for(public_trace_file.user) + get trace_icon_path(public_trace_file.user, public_trace_file) + check_trace_icon public_trace_file + end + + # Check the icon for an anonymous trace can't be downloaded by another user + def test_show_anon + anon_trace_file = create(:trace, :visibility => "private", :fixture => "b") + + # First with no auth + get trace_icon_path(anon_trace_file.user, anon_trace_file) + assert_response :forbidden + + # Now with some other user, which shouldn't work since the trace is anon + session_for(create(:user)) + get trace_icon_path(anon_trace_file.user, anon_trace_file) + assert_response :forbidden + + # And finally we should be able to do it with the owner of the trace + session_for(anon_trace_file.user) + get trace_icon_path(anon_trace_file.user, anon_trace_file) + check_trace_icon anon_trace_file + end + + # Test downloading the icon for a trace that doesn't exist + def test_show_not_found + deleted_trace_file = create(:trace, :deleted) + + # First with a trace that has never existed + get trace_icon_path(create(:user), 0) + assert_response :not_found + + # Now with a trace that has been deleted + session_for(deleted_trace_file.user) + get trace_icon_path(deleted_trace_file.user, deleted_trace_file) + assert_response :not_found + end + + private + + def check_trace_icon(trace) + follow_redirect! + follow_redirect! + assert_response :success + assert_equal "image/gif", response.media_type + assert_equal trace.icon_picture, response.body + end + end +end diff --git a/test/controllers/traces/pictures_controller_test.rb b/test/controllers/traces/pictures_controller_test.rb new file mode 100644 index 000000000..3bc531cbe --- /dev/null +++ b/test/controllers/traces/pictures_controller_test.rb @@ -0,0 +1,76 @@ +require "test_helper" + +module Api + class PicturesControllerTest < ActionDispatch::IntegrationTest + ## + # test all routes which lead to this controller + def test_routes + assert_routing( + { :path => "/user/username/traces/1/picture", :method => :get }, + { :controller => "traces/pictures", :action => "show", :display_name => "username", :trace_id => "1" } + ) + end + + # Test downloading the picture for a trace + def test_show + public_trace_file = create(:trace, :visibility => "public", :fixture => "a") + + # First with no auth, which should work since the trace is public + get trace_picture_path(public_trace_file.user, public_trace_file) + check_trace_picture public_trace_file + + # Now with some other user, which should work since the trace is public + session_for(create(:user)) + get trace_picture_path(public_trace_file.user, public_trace_file) + check_trace_picture public_trace_file + + # And finally we should be able to do it with the owner of the trace + session_for(public_trace_file.user) + get trace_picture_path(public_trace_file.user, public_trace_file) + check_trace_picture public_trace_file + end + + # Check the picture for an anonymous trace can't be downloaded by another user + def test_show_anon + anon_trace_file = create(:trace, :visibility => "private", :fixture => "b") + + # First with no auth + get trace_picture_path(anon_trace_file.user, anon_trace_file) + assert_response :forbidden + + # Now with some other user, which shouldn't work since the trace is anon + session_for(create(:user)) + get trace_picture_path(anon_trace_file.user, anon_trace_file) + assert_response :forbidden + + # And finally we should be able to do it with the owner of the trace + session_for(anon_trace_file.user) + get trace_picture_path(anon_trace_file.user, anon_trace_file) + check_trace_picture anon_trace_file + end + + # Test downloading the picture for a trace that doesn't exist + def test_show_not_found + deleted_trace_file = create(:trace, :deleted) + + # First with a trace that has never existed + get trace_picture_path(create(:user), 0) + assert_response :not_found + + # Now with a trace that has been deleted + session_for(deleted_trace_file.user) + get trace_picture_path(deleted_trace_file.user, deleted_trace_file) + assert_response :not_found + end + + private + + def check_trace_picture(trace) + follow_redirect! + follow_redirect! + assert_response :success + assert_equal "image/gif", response.media_type + assert_equal trace.large_picture, response.body + end + end +end diff --git a/test/controllers/traces_controller_test.rb b/test/controllers/traces_controller_test.rb index d187f2264..73966641e 100644 --- a/test/controllers/traces_controller_test.rb +++ b/test/controllers/traces_controller_test.rb @@ -51,14 +51,6 @@ class TracesControllerTest < ActionDispatch::IntegrationTest { :path => "/user/username/traces/1", :method => :get }, { :controller => "traces", :action => "show", :display_name => "username", :id => "1" } ) - assert_routing( - { :path => "/user/username/traces/1/picture", :method => :get }, - { :controller => "traces", :action => "picture", :display_name => "username", :id => "1" } - ) - assert_routing( - { :path => "/user/username/traces/1/icon", :method => :get }, - { :controller => "traces", :action => "icon", :display_name => "username", :id => "1" } - ) assert_routing( { :path => "/traces/new", :method => :get }, @@ -516,110 +508,6 @@ class TracesControllerTest < ActionDispatch::IntegrationTest assert_response :not_found end - # Test downloading the picture for a trace - def test_picture - public_trace_file = create(:trace, :visibility => "public", :fixture => "a") - - # First with no auth, which should work since the trace is public - get trace_picture_path(public_trace_file.user, public_trace_file) - check_trace_picture public_trace_file - - # Now with some other user, which should work since the trace is public - session_for(create(:user)) - get trace_picture_path(public_trace_file.user, public_trace_file) - check_trace_picture public_trace_file - - # And finally we should be able to do it with the owner of the trace - session_for(public_trace_file.user) - get trace_picture_path(public_trace_file.user, public_trace_file) - check_trace_picture public_trace_file - end - - # Check the picture for an anonymous trace can't be downloaded by another user - def test_picture_anon - anon_trace_file = create(:trace, :visibility => "private", :fixture => "b") - - # First with no auth - get trace_picture_path(anon_trace_file.user, anon_trace_file) - assert_response :forbidden - - # Now with some other user, which shouldn't work since the trace is anon - session_for(create(:user)) - get trace_picture_path(anon_trace_file.user, anon_trace_file) - assert_response :forbidden - - # And finally we should be able to do it with the owner of the trace - session_for(anon_trace_file.user) - get trace_picture_path(anon_trace_file.user, anon_trace_file) - check_trace_picture anon_trace_file - end - - # Test downloading the picture for a trace that doesn't exist - def test_picture_not_found - deleted_trace_file = create(:trace, :deleted) - - # First with a trace that has never existed - get trace_picture_path(create(:user), 0) - assert_response :not_found - - # Now with a trace that has been deleted - session_for(deleted_trace_file.user) - get trace_picture_path(deleted_trace_file.user, deleted_trace_file) - assert_response :not_found - end - - # Test downloading the icon for a trace - def test_icon - public_trace_file = create(:trace, :visibility => "public", :fixture => "a") - - # First with no auth, which should work since the trace is public - get trace_icon_path(public_trace_file.user, public_trace_file) - check_trace_icon public_trace_file - - # Now with some other user, which should work since the trace is public - session_for(create(:user)) - get trace_icon_path(public_trace_file.user, public_trace_file) - check_trace_icon public_trace_file - - # And finally we should be able to do it with the owner of the trace - session_for(public_trace_file.user) - get trace_icon_path(public_trace_file.user, public_trace_file) - check_trace_icon public_trace_file - end - - # Check the icon for an anonymous trace can't be downloaded by another user - def test_icon_anon - anon_trace_file = create(:trace, :visibility => "private", :fixture => "b") - - # First with no auth - get trace_icon_path(anon_trace_file.user, anon_trace_file) - assert_response :forbidden - - # Now with some other user, which shouldn't work since the trace is anon - session_for(create(:user)) - get trace_icon_path(anon_trace_file.user, anon_trace_file) - assert_response :forbidden - - # And finally we should be able to do it with the owner of the trace - session_for(anon_trace_file.user) - get trace_icon_path(anon_trace_file.user, anon_trace_file) - check_trace_icon anon_trace_file - end - - # Test downloading the icon for a trace that doesn't exist - def test_icon_not_found - deleted_trace_file = create(:trace, :deleted) - - # First with a trace that has never existed - get trace_icon_path(create(:user), 0) - assert_response :not_found - - # Now with a trace that has been deleted - session_for(deleted_trace_file.user) - get trace_icon_path(deleted_trace_file.user, deleted_trace_file) - assert_response :not_found - end - # Test fetching the new trace page def test_new_get # First with no auth @@ -876,20 +764,4 @@ class TracesControllerTest < ActionDispatch::IntegrationTest assert_equal content_type, response.media_type assert_equal "attachment; filename=\"#{trace.id}.#{extension}\"; filename*=UTF-8''#{trace.id}.#{extension}", @response.header["Content-Disposition"] end - - def check_trace_picture(trace) - follow_redirect! - follow_redirect! - assert_response :success - assert_equal "image/gif", response.media_type - assert_equal trace.large_picture, response.body - end - - def check_trace_icon(trace) - follow_redirect! - follow_redirect! - assert_response :success - assert_equal "image/gif", response.media_type - assert_equal trace.icon_picture, response.body - end end