Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions app/controllers/spi/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ class BaseController < ApplicationController
skip_after_action :set_csp_header
skip_after_action :set_link_header

prepend_before_action :ensure_canonical_path!

layout false

private
def ensure_canonical_path!
path = request.original_fullpath.split("?", 2).first
return if path == "/spi" || path.start_with?("/spi/")

head :not_found
end
end
end
13 changes: 8 additions & 5 deletions config/routes/spi.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# ### #
# SPI #
# ### #
namespace :spi do
resources :tooling_jobs, only: :update
get "solution_image_data/:track_slug/:exercise_slug/:user_handle" => "solution_image_data#show"
get "profile_image_data/:user_handle" => "profile_image_data#show"
patch "unsubscribe_user" => "unsubscribe_users#unsubscribe_by_email", as: "unsubscribe_user"
# These routes only answer on the internal SPI host.
constraints(->(request) { request.host == URI(Exercism.config.spi_url).host }) do
namespace :spi do
resources :tooling_jobs, only: :update
get "solution_image_data/:track_slug/:exercise_slug/:user_handle" => "solution_image_data#show"
get "profile_image_data/:user_handle" => "profile_image_data#show"
patch "unsubscribe_user" => "unsubscribe_users#unsubscribe_by_email", as: "unsubscribe_user"
end
end
41 changes: 41 additions & 0 deletions test/controllers/spi/base_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require "test_helper"

class SPI::BaseControllerTest < ActionDispatch::IntegrationTest
setup do
host! URI(Exercism.config.spi_url).host
end

test "serves requests on the canonical spi path" do
user = create :user

client = mock
Exercism.expects(:ses_client).returns(client)
client.expects(:put_suppressed_destination)
User::UnsubscribeFromAllEmails.expects(:call).with(user)

patch "/spi/unsubscribe_user", params: { email: user.email, reason: :bounce }

assert_response :no_content
end

test "returns 404 for non-canonical paths" do
user = create :user
User::UnsubscribeFromAllEmails.expects(:call).never

patch "/spi/unsubscribe_user",
params: { email: user.email, reason: :bounce },
env: { "PATH_INFO" => "//spi/unsubscribe_user" }

assert_response :not_found
end

test "is not routed on the website host" do
user = create :user
User::UnsubscribeFromAllEmails.expects(:call).never
host! URI(Rails.application.routes.default_url_options[:host]).host

assert_raises ActionController::RoutingError do
patch "/spi/unsubscribe_user", params: { email: user.email, reason: :bounce }
end
end
end
4 changes: 4 additions & 0 deletions test/controllers/spi/profile_image_data_controller_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
require "test_helper"

class SPI::ProfileImageDataControllerTest < ActionDispatch::IntegrationTest
setup do
host! URI(Exercism.config.spi_url).host
end

test "returns the data needed to draw the image" do
user = create :user, handle: 'ihid', name: 'Jeremy Walker', flair: :founder
create(:user_profile, user:)
Expand Down
4 changes: 4 additions & 0 deletions test/controllers/spi/solution_image_data_controller_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
require "test_helper"

class SPI::SolutionImageDataControllerTest < ActionDispatch::IntegrationTest
setup do
host! URI(Exercism.config.spi_url).host
end

test "returns the data needed to draw the image" do
track = create :track, slug: 'ruby', title: 'Ruby'
exercise = create :practice_exercise, track:, slug: 'bob', title: 'Bob'
Expand Down
6 changes: 5 additions & 1 deletion test/controllers/spi/tooling_jobs_controller_test.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
require "test_helper"

class SPI::ToolingJobsControllerTest < ActionDispatch::IntegrationTest
setup do
host! URI(Exercism.config.spi_url).host
end

test "update proxies to command" do
id = SecureRandom.uuid
ToolingJob::Process.expects(:call).with(id)

patch spi_tooling_job_url(id)
patch spi_tooling_job_path(id)
end
end
4 changes: 4 additions & 0 deletions test/controllers/spi/unsubscribe_user_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
require "test_helper"

class SPI::UnsubscribeUserTest < ActionDispatch::IntegrationTest
setup do
host! URI(Exercism.config.spi_url).host
end

test "unsubscribes correctly" do
user = create :user

Expand Down
Loading