Skip to content

Commit 8ed2e84

Browse files
authored
Use headers instead of cookies for authorization (#771)
## Status - Closes [1256](RaspberryPiFoundation/digital-editor-issues#1256) - Related to [1239](RaspberryPiFoundation/digital-editor-issues#1239) and [1255](RaspberryPiFoundation/digital-editor-issues#1255) ## What's changed? - Force endpoints to use authentication headers instead of Cookies - Removed cookie helpers since not used anymore ## Steps to perform after deploying to production _If the production environment requires any extra work after this PR has been deployed detail it here. This could be running a Rake task, a migration, or upgrading a Gem. That kind of thing._
1 parent 86cd297 commit 8ed2e84

8 files changed

Lines changed: 17 additions & 114 deletions

File tree

app/controllers/api/projects_controller.rb

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@
44

55
module Api
66
class ProjectsController < ApiController
7-
include ActionController::Cookies
8-
97
before_action :authorize_user, only: %i[create update index destroy]
108
before_action :load_project, only: %i[show update destroy show_context]
119
before_action :load_projects, only: %i[index]
1210
load_and_authorize_resource
1311
before_action :verify_lesson_belongs_to_school, only: :create
1412
after_action :pagination_link_header, only: %i[index]
15-
before_action :set_auth_cookie_for_scratch, only: %i[show]
1613

1714
def index
1815
@paginated_projects = @projects.page(params[:page])
@@ -62,18 +59,6 @@ def show_context
6259

6360
private
6461

65-
def set_auth_cookie_for_scratch
66-
return unless @project.scratch_project?
67-
return unless Flipper.enabled?(:cat_mode, school)
68-
69-
cookies[:scratch_auth] = {
70-
value: request.headers['Authorization'],
71-
secure: Rails.env.production?,
72-
same_site: :strict,
73-
http_only: true
74-
}
75-
end
76-
7762
def verify_lesson_belongs_to_school
7863
return if base_params[:lesson_id].blank?
7964
return if school&.lessons&.pluck(:id)&.include?(base_params[:lesson_id])

app/controllers/api/scratch/scratch_controller.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
module Api
44
module Scratch
55
class ScratchController < ApiController
6-
include IdentifiableByCookie
7-
86
before_action :authorize_user
97
before_action :check_scratch_feature
108

app/controllers/concerns/identifiable_by_cookie.rb

Lines changed: 0 additions & 16 deletions
This file was deleted.

spec/features/scratch/creating_a_scratch_asset_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
RSpec.describe 'Creating a Scratch asset', type: :request do
66
let(:school) { create(:school) }
77
let(:teacher) { create(:teacher, school:) }
8-
let(:cookie_headers) { { 'Cookie' => "scratch_auth=#{UserProfileMock::TOKEN}" } }
8+
let(:auth_headers) { { 'Authorization' => UserProfileMock::TOKEN } }
99

1010
before do
1111
Flipper.disable :cat_mode
1212
Flipper.disable_actor :cat_mode, school
1313
end
1414

15-
it 'responds 401 Unauthorized when no cookie is provided' do
15+
it 'responds 401 Unauthorized when no Authorization header is provided' do
1616
post '/api/scratch/assets/example.svg'
1717

1818
expect(response).to have_http_status(:unauthorized)
@@ -21,16 +21,16 @@
2121
it 'responds 404 Not Found when cat_mode is not enabled' do
2222
authenticated_in_hydra_as(teacher)
2323

24-
post '/api/scratch/assets/example.svg', headers: cookie_headers
24+
post '/api/scratch/assets/example.svg', headers: auth_headers
2525

2626
expect(response).to have_http_status(:not_found)
2727
end
2828

29-
it 'creates an asset when cat_mode is enabled and a cookie is provided' do
29+
it 'creates an asset when cat_mode is enabled and the required headers are provided' do
3030
authenticated_in_hydra_as(teacher)
3131
Flipper.enable_actor :cat_mode, school
3232

33-
post '/api/scratch/assets/example.svg', headers: cookie_headers
33+
post '/api/scratch/assets/example.svg', headers: auth_headers
3434

3535
expect(response).to have_http_status(:created)
3636

spec/features/scratch/creating_a_scratch_project_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
let(:teacher) { create(:teacher, school:) }
88
let(:headers) do
99
{
10-
'Cookie' => "scratch_auth=#{UserProfileMock::TOKEN}",
10+
'Authorization' => UserProfileMock::TOKEN,
1111
'Origin' => 'editor.com'
1212
}
1313
end
@@ -49,7 +49,7 @@ def make_request(query: request_query, request_headers: headers, request_params:
4949
)
5050
end
5151

52-
it 'responds 401 Unauthorized when no cookie is provided' do
52+
it 'responds 401 Unauthorized when no Authorization header is provided' do
5353
make_request(request_headers: {})
5454

5555
expect(response).to have_http_status(:unauthorized)

spec/features/scratch/creating_and_showing_a_scratch_asset_spec.rb

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,16 @@
99
let(:filename) { "#{basename}.#{format}" }
1010
let(:school) { create(:school) }
1111
let(:teacher) { create(:teacher, school:) }
12-
let(:cookie_headers) { { 'Cookie' => "scratch_auth=#{UserProfileMock::TOKEN}" } }
12+
let(:auth_headers) { { 'Authorization' => UserProfileMock::TOKEN } }
1313

1414
describe 'GET #show' do
1515
context 'when the asset is PNG' do
1616
before do
1717
create(:scratch_asset, :with_file, filename:, asset_path: file_fixture(filename))
1818
end
1919

20-
let(:make_request) { get '/api/scratch/assets/internalapi/asset/test_image_1.png/get/' }
21-
2220
it 'serves the file with png content type' do
23-
make_request
21+
get '/api/scratch/assets/internalapi/asset/test_image_1.png/get/'
2422

2523
follow_redirect! while response.redirect?
2624

@@ -33,10 +31,8 @@
3331
create(:scratch_asset, :with_file, filename: svg_filename, asset_path: file_fixture(svg_filename))
3432
end
3533

36-
let(:make_request) { get '/api/scratch/assets/internalapi/asset/test_svg_image.svg/get/' }
37-
3834
it 'serves the file with image/svg+xml content type' do
39-
make_request
35+
get '/api/scratch/assets/internalapi/asset/test_svg_image.svg/get/'
4036

4137
follow_redirect! while response.redirect?
4238

@@ -48,7 +44,7 @@
4844
describe 'POST #create' do
4945
let(:upload) { File.binread(file_fixture(filename)) }
5046
let(:make_request) do
51-
post '/api/scratch/assets/test_image_1.png', headers: { 'Content-Type' => 'application/octet-stream' }.merge(cookie_headers), params: upload
47+
post '/api/scratch/assets/test_image_1.png', headers: { 'Content-Type' => 'application/octet-stream' }.merge(auth_headers), params: upload
5248
end
5349

5450
context 'when user is logged in and cat_mode is enabled' do
@@ -59,54 +55,42 @@
5955
end
6056

6157
it 'creates a new asset' do
62-
# Arrange
6358
Flipper.enable_actor :cat_mode, school
6459

65-
# Act & Assert
6660
expect { make_request }.to change(ScratchAsset, :count).by(1)
6761
end
6862

6963
it 'sets the filename on the asset' do
70-
# Arrange
7164
Flipper.enable_actor :cat_mode, school
7265

73-
# Act & Assert
7466
make_request
7567
expect(ScratchAsset.last.filename).to eq(filename)
7668
end
7769

7870
it 'attaches the uploaded file to the asset' do
79-
# Arrange
8071
Flipper.enable_actor :cat_mode, school
8172

82-
# Act & Assert
8373
make_request
8474
expect(ScratchAsset.last.file).to be_attached
8575
end
8676

8777
it 'stores the content of the file in the attachment' do
88-
# Arrange
8978
Flipper.enable_actor :cat_mode, school
9079

91-
# Act & Assert
9280
make_request
9381
expect(ScratchAsset.last.file.download).to eq(upload)
9482
end
9583

9684
it 'responds with 201 Created' do
97-
# Arrange
9885
Flipper.enable_actor :cat_mode, school
9986

100-
# Act & Assert
10187
make_request
10288
expect(response).to have_http_status(:created)
10389
end
10490

10591
it 'includes the status and filename (without extension) in the response' do
106-
# Arrange
10792
Flipper.enable_actor :cat_mode, school
10893

109-
# Act & Assert
11094
make_request
11195
expect(response.parsed_body).to include(
11296
'status' => 'ok',
@@ -124,28 +108,22 @@
124108
end
125109

126110
it 'does not update the content of the file in the attachment' do
127-
# Arrange
128111
Flipper.enable_actor :cat_mode, school
129112

130-
# Act & Assert
131113
make_request
132114
expect(ScratchAsset.last.file.download).to eq(original_upload)
133115
end
134116

135117
it 'responds with 201 Created' do
136-
# Arrange
137118
Flipper.enable_actor :cat_mode, school
138119

139-
# Act & Assert
140120
make_request
141121
expect(response).to have_http_status(:created)
142122
end
143123

144124
it 'includes the status and filename (without extension) in the response' do
145-
# Arrange
146125
Flipper.enable_actor :cat_mode, school
147126

148-
# Act & Assert
149127
make_request
150128
expect(response.parsed_body).to include(
151129
'status' => 'ok',
@@ -163,10 +141,8 @@
163141
end
164142

165143
it 'responds 404 Not Found when cat_mode is not enabled' do
166-
# Act
167-
post '/api/scratch/assets/example.svg', headers: cookie_headers
144+
post '/api/scratch/assets/example.svg', headers: auth_headers
168145

169-
# Assert
170146
expect(response).to have_http_status(:not_found)
171147
end
172148
end

spec/features/scratch/updating_a_scratch_project_spec.rb

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
RSpec.describe 'Updating a Scratch project', type: :request do
66
let(:school) { create(:school) }
77
let(:teacher) { create(:teacher, school:) }
8-
let(:cookie_headers) { { 'Cookie' => "scratch_auth=#{UserProfileMock::TOKEN}" } }
8+
let(:auth_headers) { { 'Authorization' => UserProfileMock::TOKEN } }
99

1010
before do
1111
Flipper.disable :cat_mode
1212
Flipper.disable_actor :cat_mode, school
1313
end
1414

15-
it 'responds 401 Unauthorized when no cookie is provided' do
15+
it 'responds 401 Unauthorized when no Authorization header is provided' do
1616
put '/api/scratch/projects/any-identifier', params: { project: { targets: [] } }
1717

1818
expect(response).to have_http_status(:unauthorized)
@@ -21,13 +21,12 @@
2121
it 'responds 404 Not Found when cat_mode is not enabled' do
2222
authenticated_in_hydra_as(teacher)
2323

24-
put '/api/scratch/projects/any-identifier', params: { content: { targets: [] } }, headers: cookie_headers
24+
put '/api/scratch/projects/any-identifier', params: { content: { targets: [] } }, headers: auth_headers
2525

2626
expect(response).to have_http_status(:not_found)
2727
end
2828

29-
it 'updates a project when cat_mode is enabled and a cookie is provided' do
30-
# Arrange
29+
it 'updates a project when cat_mode is enabled and an Authorization header is provided' do
3130
authenticated_in_hydra_as(teacher)
3231
Flipper.enable_actor :cat_mode, school
3332
project = create(
@@ -37,10 +36,8 @@
3736
)
3837
create(:scratch_component, project: project)
3938

40-
# Act
41-
put "/api/scratch/projects/#{project.identifier}", params: { targets: ['some update'] }, headers: cookie_headers
39+
put "/api/scratch/projects/#{project.identifier}", params: { targets: ['some update'] }, headers: auth_headers
4240

43-
# Assert
4441
expect(response).to have_http_status(:ok)
4542

4643
data = JSON.parse(response.body, symbolize_names: true)

spec/requests/projects/show_spec.rb

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -54,43 +54,6 @@
5454
end
5555
end
5656

57-
context 'when setting scratch auth cookie' do
58-
let(:project_type) { Project::Types::PYTHON }
59-
let!(:project) { create(:project, school:, user_id: teacher.id, locale: nil, project_type:) }
60-
61-
before do
62-
Flipper.disable :cat_mode
63-
Flipper.disable_actor :cat_mode, school
64-
end
65-
66-
it 'does not set auth cookie when project is not scratch' do
67-
get("/api/projects/#{project.identifier}", headers:)
68-
69-
expect(response).to have_http_status(:ok)
70-
expect(response.cookies['scratch_auth']).to be_nil
71-
end
72-
73-
context 'when project is code editor scratch' do
74-
let(:project_type) { Project::Types::CODE_EDITOR_SCRATCH }
75-
76-
it 'does not set auth cookie when cat_mode is not enabled' do
77-
get("/api/projects/#{project.identifier}", headers:)
78-
79-
expect(response).to have_http_status(:ok)
80-
expect(response.cookies['scratch_auth']).to be_nil
81-
end
82-
83-
it 'sets auth cookie to auth header' do
84-
Flipper.enable_actor :cat_mode, school
85-
86-
get("/api/projects/#{project.identifier}", headers:)
87-
88-
expect(response).to have_http_status(:ok)
89-
expect(cookies['scratch_auth']).to eq(UserProfileMock::TOKEN)
90-
end
91-
end
92-
end
93-
9457
context 'when loading a student\'s project' do
9558
let(:school_class) { create(:school_class, school:, teacher_ids: [teacher.id]) }
9659
let(:lesson) { create(:lesson, school:, school_class:, user_id: teacher.id, visibility: 'students') }

0 commit comments

Comments
 (0)