diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb index eb460a8d1..d5844500e 100644 --- a/app/controllers/epp/sessions_controller.rb +++ b/app/controllers/epp/sessions_controller.rb @@ -74,7 +74,7 @@ class Epp::SessionsController < EppController success = false end - if success && !connection_limit_ok? + if success && EppSession.limit_reached?(@api_user.registrar) epp_errors << { msg: 'Authentication error; server closing connection (connection limit reached)', code: '2501' @@ -143,12 +143,4 @@ class Epp::SessionsController < EppController def resource @api_user end - - def connection_limit_ok? - epp_session_count = EppSession.where(user_id: @api_user.registrar.api_users.ids) - .where('updated_at >= ?', Time.zone.now - 1.second).count - - return false if epp_session_count >= 4 - true - end end diff --git a/app/models/epp_session.rb b/app/models/epp_session.rb index 0a1a146a2..dfd603fc4 100644 --- a/app/models/epp_session.rb +++ b/app/models/epp_session.rb @@ -2,4 +2,13 @@ class EppSession < ActiveRecord::Base belongs_to :user, required: true validates :session_id, uniqueness: true, presence: true + + def self.limit_per_registrar + 4 + end + + def self.limit_reached?(registrar) + count = where(user_id: registrar.api_users.ids).where('updated_at >= ?', Time.zone.now - 1.second).count + count >= limit_per_registrar + end end diff --git a/test/integration/epp/session/limit_test.rb b/test/integration/epp/session/limit_test.rb new file mode 100644 index 000000000..b186031b6 --- /dev/null +++ b/test/integration/epp/session/limit_test.rb @@ -0,0 +1,63 @@ +require 'test_helper' + +class EppSessionLimitTest < ActionDispatch::IntegrationTest + def setup + travel_to Time.zone.parse('2010-07-05') + EppSession.delete_all + end + + def test_not_reached + (EppSession.limit_per_registrar - 1).times do + EppSession.create!(session_id: SecureRandom.hex, + user: users(:api_bestnames), + updated_at: Time.zone.parse('2010-07-05')) + end + + assert_difference 'EppSession.count' do + post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' } + end + + assert Nokogiri::XML(response.body).at_css('result[code="1000"]') + assert_equal 1, Nokogiri::XML(response.body).css('result').size + end + + def test_reached + EppSession.limit_per_registrar.times do + EppSession.create!(session_id: SecureRandom.hex, + user: users(:api_bestnames), + updated_at: Time.zone.parse('2010-07-05')) + end + + assert_no_difference 'EppSession.count' do + post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' } + end + + assert Nokogiri::XML(response.body).at_css('result[code="2501"]') + end + + private + + def request_xml + <<-XML + + + + + test_bestnames + testtest + + 1.0 + en + + + https://epp.tld.ee/schema/domain-eis-1.0.xsd + https://epp.tld.ee/schema/contact-ee-1.1.xsd + urn:ietf:params:xml:ns:host-1.0 + urn:ietf:params:xml:ns:keyrelay-1.0 + + + + + XML + end +end diff --git a/test/models/epp_session_test.rb b/test/models/epp_session_test.rb index 1a0e9e114..fd795b23c 100644 --- a/test/models/epp_session_test.rb +++ b/test/models/epp_session_test.rb @@ -43,4 +43,21 @@ class EppSessionTest < ActiveSupport::TestCase @epp_session.save(validate: false) end end + + def test_limit_per_registrar + assert_equal 4, EppSession.limit_per_registrar + end + + def test_limit_is_per_registrar + travel_to Time.zone.parse('2010-07-05') + EppSession.delete_all + + EppSession.limit_per_registrar.times do + EppSession.create!(session_id: SecureRandom.hex, + user: users(:api_goodnames), + updated_at: Time.zone.parse('2010-07-05')) + end + + refute EppSession.limit_reached?(registrars(:bestnames)) + end end