Do not allow more than 4 simultaneous EPP connections

This commit is contained in:
Martin Lensment 2015-05-20 20:41:53 +03:00
parent b39c3ab262
commit 6a63c258f6
5 changed files with 25 additions and 4 deletions

View file

@ -18,7 +18,7 @@ class Epp::SessionsController < EppController
@api_user = ApiUser.find_by(login_params) @api_user = ApiUser.find_by(login_params)
end end
if @api_user.try(:active) && cert_valid && ip_white? if @api_user.try(:active) && cert_valid && ip_white? && connection_limit_ok?
if parsed_frame.css('newPW').first if parsed_frame.css('newPW').first
unless @api_user.update(password: parsed_frame.css('newPW').first.text) unless @api_user.update(password: parsed_frame.css('newPW').first.text)
response.headers['X-EPP-Returncode'] = '2200' response.headers['X-EPP-Returncode'] = '2200'
@ -27,6 +27,7 @@ class Epp::SessionsController < EppController
end end
epp_session[:api_user_id] = @api_user.id epp_session[:api_user_id] = @api_user.id
epp_session.update_column(:registrar_id, @api_user.registrar_id)
render_epp_response('login_success') render_epp_response('login_success')
else else
response.headers['X-EPP-Returncode'] = '2200' response.headers['X-EPP-Returncode'] = '2200'
@ -45,12 +46,24 @@ class Epp::SessionsController < EppController
true true
end end
def connection_limit_ok?
c = EppSession.where(
'registrar_id = ? AND updated_at >= ?', @api_user.registrar_id, Time.zone.now - 5.minutes
).count
if c >= 4
@msg = t('connection_limit_reached')
return false
end
true
end
# rubocop: enable Metrics/PerceivedComplexity # rubocop: enable Metrics/PerceivedComplexity
# rubocop: enable Metrics/CyclomaticComplexity # rubocop: enable Metrics/CyclomaticComplexity
def logout def logout
@api_user = current_user # cache current_user for logging @api_user = current_user # cache current_user for logging
epp_session[:api_user_id] = nil epp_session.destroy
response.headers['X-EPP-Returncode'] = '1500' response.headers['X-EPP-Returncode'] = '1500'
render_epp_response('logout') render_epp_response('logout')
end end

View file

@ -1,8 +1,9 @@
class EppSession < ActiveRecord::Base class EppSession < ActiveRecord::Base
before_save :marshal_data! before_save :marshal_data!
belongs_to :registrar
# rubocop: disable Rails/ReadWriteAttribute # rubocop: disable Rails/ReadWriteAttribute
# Turned back to read_attribute, thus in Rails 4 # Turned back to read_attribute, thus in Rails 4
# there is differences between self[:data] and read_attribute. # there is differences between self[:data] and read_attribute.
def data def data
@data ||= self.class.unmarshal(read_attribute(:data)) || {} @data ||= self.class.unmarshal(read_attribute(:data)) || {}

View file

@ -797,3 +797,4 @@ en:
registrant_domain_verification_rejected_failed: 'Something went wrong' registrant_domain_verification_rejected_failed: 'Something went wrong'
ip_is_not_whitelisted: 'IP is not whitelisted' ip_is_not_whitelisted: 'IP is not whitelisted'
access_denied: 'Access denied' access_denied: 'Access denied'
connection_limit_reached: 'Connection limit reached'

View file

@ -0,0 +1,5 @@
class AddRegistrarIdToEppSession < ActiveRecord::Migration
def change
add_column :epp_sessions, :registrar_id, :integer
end
end

View file

@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150519144118) do ActiveRecord::Schema.define(version: 20150520164507) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -317,6 +317,7 @@ ActiveRecord::Schema.define(version: 20150519144118) do
t.text "data" t.text "data"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.integer "registrar_id"
end end
add_index "epp_sessions", ["session_id"], name: "index_epp_sessions_on_session_id", unique: true, using: :btree add_index "epp_sessions", ["session_id"], name: "index_epp_sessions_on_session_id", unique: true, using: :btree