Skip to content

Commit 3b10c5d

Browse files
authored
Send rate-limit bypass key to courses.mooc.fi (#599)
1 parent 1ecfc4b commit 3b10c5d

5 files changed

Lines changed: 38 additions & 2 deletions

File tree

‎app/models/user.rb‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ def processing_submissions_count_for_exercise(exercise_name, course_id)
601601

602602
private
603603
def courses_mooc_fi_connection
604-
Faraday.new(request: { open_timeout: 2, timeout: 10 }) do |f|
604+
Faraday.new(headers: CoursesMoocFiRateLimitBypass.headers, request: { open_timeout: 2, timeout: 10 }) do |f|
605605
f.request :json
606606
f.response :json
607607
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# frozen_string_literal: true
2+
3+
# Headers for tmc-server's requests to courses.mooc.fi: sp331 skips its per-IP rate limits when this
4+
# header matches its RATELIMIT_PROTECTION_SAFE_API_KEY, the same shared value as RACK_ATTACK_SAFE_API_KEY.
5+
module CoursesMoocFiRateLimitBypass
6+
HEADER = 'RATELIMIT-PROTECTION-SAFE-API-KEY'
7+
8+
def self.headers
9+
key = ENV['RACK_ATTACK_SAFE_API_KEY']
10+
key.present? ? { HEADER => key } : {}
11+
end
12+
end

‎app/services/courses_mooc_fi_token_introspector.rb‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def request_introspection(token)
6464
raise Unavailable, 'courses_mooc_fi_base_url, COURSES_MOOC_FI_INTROSPECTION_CLIENT_ID or COURSES_MOOC_FI_INTROSPECTION_SECRET is not set'
6565
end
6666

67-
connection = Faraday.new(request: { open_timeout: 2, timeout: 5 }) do |f|
67+
connection = Faraday.new(headers: CoursesMoocFiRateLimitBypass.headers, request: { open_timeout: 2, timeout: 5 }) do |f|
6868
f.request :url_encoded
6969
f.response :json
7070
end

‎spec/models/user_spec.rb‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,18 @@ def stub_courses_mooc_fi_authentication(status:, body:)
342342
allow(Faraday).to receive(:new).and_return(connection)
343343
end
344344

345+
{ 'bypass-key' => { 'RATELIMIT-PROTECTION-SAFE-API-KEY' => 'bypass-key' }, '' => {}, nil => {} }.each do |configured, headers|
346+
it "sends rate-limit bypass headers #{headers} when RACK_ATTACK_SAFE_API_KEY is #{configured.inspect}" do
347+
allow(ENV).to receive(:[]).and_call_original
348+
allow(ENV).to receive(:[]).with('RACK_ATTACK_SAFE_API_KEY').and_return(configured)
349+
stub_courses_mooc_fi_authentication(status: 200, body: true)
350+
351+
User.authenticate_with_status('manageduser', 'secret123')
352+
353+
expect(Faraday).to have_received(:new).with(hash_including(headers: headers))
354+
end
355+
end
356+
345357
it 'rejects a wrong local password' do
346358
User.create!(login: 'localuser', password: 'secret123', email: 'localuser@example.com')
347359
expect(User.authenticate_with_status('localuser', 'wrongpassword').last).to eq(:rejected)

‎spec/services/courses_mooc_fi_token_introspector_spec.rb‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ def introspect
4444
expect(sent.request_headers['Accept']).to eq('application/json')
4545
end
4646

47+
{ 'bypass-key' => 'bypass-key', '' => nil, nil => nil }.each do |configured, sent|
48+
it "sends rate-limit bypass key #{sent.inspect} when RACK_ATTACK_SAFE_API_KEY is #{configured.inspect}" do
49+
allow(ENV).to receive(:[]).and_call_original
50+
allow(ENV).to receive(:[]).with('RACK_ATTACK_SAFE_API_KEY').and_return(configured)
51+
stub_provider(status: 200, body: active_body)
52+
53+
introspect
54+
55+
expect(provider_requests.last.request_headers['RATELIMIT-PROTECTION-SAFE-API-KEY']).to eq(sent)
56+
end
57+
end
58+
4759
it 'derives the endpoint and issuer from courses_mooc_fi_base_url' do
4860
allow(SiteSetting).to receive(:value).with('courses_mooc_fi_base_url').and_return('http://project-331.local/')
4961
provider.post('http://project-331.local/api/v0/main-frontend/oauth/introspect') do

0 commit comments

Comments
 (0)