Skip to content
Merged
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
2 changes: 1 addition & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ def processing_submissions_count_for_exercise(exercise_name, course_id)

private
def courses_mooc_fi_connection
Faraday.new(request: { open_timeout: 2, timeout: 10 }) do |f|
Faraday.new(headers: CoursesMoocFiRateLimitBypass.headers, request: { open_timeout: 2, timeout: 10 }) do |f|
f.request :json
f.response :json
end
Expand Down
12 changes: 12 additions & 0 deletions app/services/courses_mooc_fi_rate_limit_bypass.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

# Headers for tmc-server's requests to courses.mooc.fi: sp331 skips its per-IP rate limits when this
# header matches its RATELIMIT_PROTECTION_SAFE_API_KEY, the same shared value as RACK_ATTACK_SAFE_API_KEY.
module CoursesMoocFiRateLimitBypass
HEADER = 'RATELIMIT-PROTECTION-SAFE-API-KEY'

def self.headers
key = ENV['RACK_ATTACK_SAFE_API_KEY']
key.present? ? { HEADER => key } : {}
end
end
2 changes: 1 addition & 1 deletion app/services/courses_mooc_fi_token_introspector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def request_introspection(token)
raise Unavailable, 'courses_mooc_fi_base_url, COURSES_MOOC_FI_INTROSPECTION_CLIENT_ID or COURSES_MOOC_FI_INTROSPECTION_SECRET is not set'
end

connection = Faraday.new(request: { open_timeout: 2, timeout: 5 }) do |f|
connection = Faraday.new(headers: CoursesMoocFiRateLimitBypass.headers, request: { open_timeout: 2, timeout: 5 }) do |f|
f.request :url_encoded
f.response :json
end
Expand Down
12 changes: 12 additions & 0 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,18 @@ def stub_courses_mooc_fi_authentication(status:, body:)
allow(Faraday).to receive(:new).and_return(connection)
end

{ 'bypass-key' => { 'RATELIMIT-PROTECTION-SAFE-API-KEY' => 'bypass-key' }, '' => {}, nil => {} }.each do |configured, headers|
it "sends rate-limit bypass headers #{headers} when RACK_ATTACK_SAFE_API_KEY is #{configured.inspect}" do
allow(ENV).to receive(:[]).and_call_original
allow(ENV).to receive(:[]).with('RACK_ATTACK_SAFE_API_KEY').and_return(configured)
stub_courses_mooc_fi_authentication(status: 200, body: true)

User.authenticate_with_status('manageduser', 'secret123')

expect(Faraday).to have_received(:new).with(hash_including(headers: headers))
end
end

it 'rejects a wrong local password' do
User.create!(login: 'localuser', password: 'secret123', email: 'localuser@example.com')
expect(User.authenticate_with_status('localuser', 'wrongpassword').last).to eq(:rejected)
Expand Down
12 changes: 12 additions & 0 deletions spec/services/courses_mooc_fi_token_introspector_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ def introspect
expect(sent.request_headers['Accept']).to eq('application/json')
end

{ 'bypass-key' => 'bypass-key', '' => nil, nil => nil }.each do |configured, sent|
it "sends rate-limit bypass key #{sent.inspect} when RACK_ATTACK_SAFE_API_KEY is #{configured.inspect}" do
allow(ENV).to receive(:[]).and_call_original
allow(ENV).to receive(:[]).with('RACK_ATTACK_SAFE_API_KEY').and_return(configured)
stub_provider(status: 200, body: active_body)

introspect

expect(provider_requests.last.request_headers['RATELIMIT-PROTECTION-SAFE-API-KEY']).to eq(sent)
end
end

it 'derives the endpoint and issuer from courses_mooc_fi_base_url' do
allow(SiteSetting).to receive(:value).with('courses_mooc_fi_base_url').and_return('http://project-331.local/')
provider.post('http://project-331.local/api/v0/main-frontend/oauth/introspect') do
Expand Down
Loading