From 8e37355e13d3a118fafc48ee4ea7cd0b59178d08 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 May 2015 16:47:29 +0300 Subject: [PATCH 01/11] Create white ips --- app/controllers/admin/white_ips_controller.rb | 56 +++++++++++++++++++ app/models/ability.rb | 1 + app/models/registrar.rb | 3 +- app/models/white_ip.rb | 16 ++++++ app/views/admin/registrars/show.haml | 25 ++++++++- app/views/admin/white_ips/_form.haml | 30 ++++++++++ app/views/admin/white_ips/edit.haml | 5 ++ app/views/admin/white_ips/new.haml | 5 ++ app/views/admin/white_ips/show.haml | 24 ++++++++ config/locales/en.yml | 5 ++ config/routes.rb | 2 + db/migrate/20150519115050_create_white_ip.rb | 11 ++++ db/schema.rb | 11 +++- spec/models/registrar_spec.rb | 1 + spec/models/white_ip_spec.rb | 54 ++++++++++++++++++ 15 files changed, 246 insertions(+), 3 deletions(-) create mode 100644 app/controllers/admin/white_ips_controller.rb create mode 100644 app/models/white_ip.rb create mode 100644 app/views/admin/white_ips/_form.haml create mode 100644 app/views/admin/white_ips/edit.haml create mode 100644 app/views/admin/white_ips/new.haml create mode 100644 app/views/admin/white_ips/show.haml create mode 100644 db/migrate/20150519115050_create_white_ip.rb create mode 100644 spec/models/white_ip_spec.rb diff --git a/app/controllers/admin/white_ips_controller.rb b/app/controllers/admin/white_ips_controller.rb new file mode 100644 index 000000000..7c0ecb184 --- /dev/null +++ b/app/controllers/admin/white_ips_controller.rb @@ -0,0 +1,56 @@ +class Admin::WhiteIpsController < AdminController + load_and_authorize_resource + + before_action :set_registrar, only: [:new, :show, :edit, :destroy, :update] + + def new + @white_ip = WhiteIp.new(registrar: @registrar) + end + + def show; end + + def edit; end + + def destroy + if @white_ip.destroy + flash[:notice] = I18n.t('record_deleted') + redirect_to admin_registrar_path(@registrar) + else + flash.now[:alert] = I18n.t('failed_to_delete_record') + render 'show' + end + end + + def create + @white_ip = WhiteIp.new(white_ip_params) + @registrar = @white_ip.registrar + + if @white_ip.save + flash[:notice] = I18n.t('record_created') + redirect_to [:admin, @registrar, @white_ip] + else + flash.now[:alert] = I18n.t('failed_to_create_record') + render 'new' + end + end + + def update + if @white_ip.update(white_ip_params) + flash[:notice] = I18n.t('record_updated') + redirect_to [:admin, @registrar, @white_ip] + else + flash.now[:alert] = I18n.t('failed_to_update_record') + render 'edit' + end + end + + private + + def set_registrar + @registrar = Registrar.find_by(id: params[:registrar_id]) + end + + def white_ip_params + params.require(:white_ip).permit(:ipv4, :ipv6, :interface, :registrar_id) + end +end diff --git a/app/models/ability.rb b/app/models/ability.rb index 84be67c3a..7e1eba17c 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -97,6 +97,7 @@ class Ability can :manage, BankStatement can :manage, BankTransaction can :manage, Invoice + can :manage, WhiteIp can :read, ApiLog::EppLog can :read, ApiLog::ReppLog # can :index, :delayed_job diff --git a/app/models/registrar.rb b/app/models/registrar.rb index cb78c2ec4..977e44eb7 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -10,6 +10,7 @@ class Registrar < ActiveRecord::Base has_many :nameservers, through: :domains has_many :whois_records has_many :priv_contacts, -> { privs }, class_name: 'Contact' + has_many :white_ips, dependent: :destroy validates :name, :reg_no, :country_code, :email, :code, presence: true validates :name, :reg_no, :reference_no, :code, uniqueness: true @@ -48,7 +49,7 @@ class Registrar < ActiveRecord::Base after_save :update_whois_records def update_whois_records - return true unless changed? && (changes.keys & WHOIS_TRIGGERS).present? + return true unless changed? && (changes.keys & WHOIS_TRIGGERS).present? whois_records.map(&:save) # slow currently end diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb new file mode 100644 index 000000000..04ca14ffb --- /dev/null +++ b/app/models/white_ip.rb @@ -0,0 +1,16 @@ +class WhiteIp < ActiveRecord::Base + belongs_to :registrar + + # rubocop: disable Metrics/LineLength + validates :ipv4, format: { with: /\A(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\z/, allow_blank: true } + validates :ipv6, format: { with: /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/, allow_blank: true } + # rubocop: enable Metrics/LineLength + + validate :validate_ipv4_and_ipv6 + def validate_ipv4_and_ipv6 + return if ipv4.present? || ipv6.present? + errors.add(:base, I18n.t(:ipv4_or_ipv6_must_be_present)) + end + + INTERFACES = ['epp', 'repp', 'registrar'] +end diff --git a/app/views/admin/registrars/show.haml b/app/views/admin/registrars/show.haml index c59401898..b0102344b 100644 --- a/app/views/admin/registrars/show.haml +++ b/app/views/admin/registrars/show.haml @@ -63,7 +63,7 @@ .pull-left = t(:api_users) .pull-right - = link_to(t(:create_new_api_user), new_admin_registrar_api_user_path(@registrar), class: 'btn btn-primary btn-xs') + = link_to(t(:create_new_api_user), new_admin_registrar_api_user_path(@registrar), class: 'btn btn-default btn-xs') .table-responsive %table.table.table-hover.table-bordered.table-condensed @@ -76,3 +76,26 @@ %tr %td= link_to(x, [:admin, x]) %td= x.active + +.row + .col-md-12 + #epp-users.panel.panel-default + .panel-heading.clearfix + .pull-left + = t(:white_ips) + .pull-right + = link_to(t(:create_new_white_ip), new_admin_registrar_white_ip_path(@registrar), class: 'btn btn-default btn-xs') + + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-4'}= t(:ipv4) + %th{class: 'col-xs-6'}= t(:ipv6) + %th{class: 'col-xs-2'}= t(:interface) + %tbody + - @registrar.white_ips.order(:interface).each do |x| + %tr + %td= link_to(x.ipv4, [:admin, @registrar, x]) + %td= link_to(x.ipv6, [:admin, @registrar, x]) + %td= x.interface.upcase diff --git a/app/views/admin/white_ips/_form.haml b/app/views/admin/white_ips/_form.haml new file mode 100644 index 000000000..e496348ba --- /dev/null +++ b/app/views/admin/white_ips/_form.haml @@ -0,0 +1,30 @@ += form_for([:admin, @registrar, @white_ip], html: {class: 'form-horizontal'}) do |f| + = render 'shared/full_errors', object: @white_ip + + .row + .col-md-8 + .form-group + .col-md-4.control-label + = f.label :registrar + .col-md-7 + = f.text_field(:registrar, class: 'form-control', disabled: :disabled) + = f.hidden_field(:registrar_id, class: 'js-registrar-id') + .form-group + .col-md-4.control-label + = f.label :ipv4 + .col-md-7 + = f.text_field(:ipv4, class: 'form-control') + .form-group + .col-md-4.control-label + = f.label :ipv6 + .col-md-7 + = f.text_field(:ipv6, class: 'form-control') + .form-group + .col-md-4.control-label + = f.label :interface + .col-md-7 + = f.select :interface, [[t(:choose), '']] + WhiteIp::INTERFACES.map {|x| [x.upcase, x]}, {}, class: 'form-control selectize', placeholder: t(:choose) + %hr + .row + .col-md-8.text-right + = button_tag(t(:save), class: 'btn btn-primary') diff --git a/app/views/admin/white_ips/edit.haml b/app/views/admin/white_ips/edit.haml new file mode 100644 index 000000000..ace12a289 --- /dev/null +++ b/app/views/admin/white_ips/edit.haml @@ -0,0 +1,5 @@ +- content_for :actions do + = link_to(t(:back_to_registrar), admin_registrar_path(@registrar), class: 'btn btn-default') + += render 'shared/title', name: t(:edit_white_ip) += render 'form' diff --git a/app/views/admin/white_ips/new.haml b/app/views/admin/white_ips/new.haml new file mode 100644 index 000000000..99150a871 --- /dev/null +++ b/app/views/admin/white_ips/new.haml @@ -0,0 +1,5 @@ +- content_for :actions do + = link_to(t(:back_to_registrar), admin_registrar_path(@registrar), class: 'btn btn-default') + += render 'shared/title', name: t(:create_new_white_ip) += render 'form' diff --git a/app/views/admin/white_ips/show.haml b/app/views/admin/white_ips/show.haml new file mode 100644 index 000000000..da1da9616 --- /dev/null +++ b/app/views/admin/white_ips/show.haml @@ -0,0 +1,24 @@ +- content_for :actions do + = link_to(t(:edit), edit_admin_registrar_white_ip_path(@registrar, @white_ip), class: 'btn btn-primary') + = link_to(t(:delete), admin_registrar_white_ip_path(@registrar, @white_ip), + method: :delete, data: { confirm: t(:are_you_sure) }, class: 'btn btn-danger') += render 'shared/title', name: t('white_ip') + +.row + .col-md-12 + .panel.panel-default + .panel-heading + %h3.panel-title= t(:general) + .panel-body + %dl.dl-horizontal + %dt= t(:registrar) + %dd= link_to(@registrar, [:admin, @registrar]) + + %dt= t(:ipv4) + %dd= @white_ip.ipv4 + + %dt= t(:ipv6) + %dd= @white_ip.ipv6 + + %dt= t(:interface) + %dd= @white_ip.interface.upcase diff --git a/config/locales/en.yml b/config/locales/en.yml index c745de9ea..53939d6fc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -773,3 +773,8 @@ en: not_valid_domain_verification_body: This could mean your verification has been expired or done already.

Please contact us if you think something is wrong. upload_crt: 'Upload CRT' crt_or_csr_must_be_present: 'CRT or CSR must be present' + white_ips: 'White IP-s' + create_new_white_ip: 'Create new white IP' + ipv4_or_ipv6_must_be_present: 'IPv4 or IPv6 must be present' + white_ip: 'White IP' + edit_white_ip: 'Edit white IP' diff --git a/config/routes.rb b/config/routes.rb index 689c7f399..97923232d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -179,8 +179,10 @@ Rails.application.routes.draw do end resources :settings + resources :registrars do resources :api_users + resources :white_ips collection do get :search end diff --git a/db/migrate/20150519115050_create_white_ip.rb b/db/migrate/20150519115050_create_white_ip.rb new file mode 100644 index 000000000..13a710f41 --- /dev/null +++ b/db/migrate/20150519115050_create_white_ip.rb @@ -0,0 +1,11 @@ +class CreateWhiteIp < ActiveRecord::Migration + def change + create_table :white_ips do |t| + t.integer :registrar_id + t.string :ipv4 + t.string :ipv6 + t.string :interface + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 841976d41..16cf3d6fd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150518084324) do +ActiveRecord::Schema.define(version: 20150519115050) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -928,6 +928,15 @@ ActiveRecord::Schema.define(version: 20150518084324) do t.text "depricated_table_but_somehow_paper_trail_tests_fails_without_it" end + create_table "white_ips", force: :cascade do |t| + t.integer "registrar_id" + t.string "ipv4" + t.string "ipv6" + t.string "interface" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "whois_records", force: :cascade do |t| t.integer "domain_id" t.string "name" diff --git a/spec/models/registrar_spec.rb b/spec/models/registrar_spec.rb index 067c999af..e8d719e92 100644 --- a/spec/models/registrar_spec.rb +++ b/spec/models/registrar_spec.rb @@ -4,6 +4,7 @@ describe Registrar do it { should have_many(:domains) } it { should have_many(:api_users) } it { should have_many(:messages) } + it { should have_many(:white_ips) } context 'with invalid attribute' do before :all do diff --git a/spec/models/white_ip_spec.rb b/spec/models/white_ip_spec.rb new file mode 100644 index 000000000..ce16780f8 --- /dev/null +++ b/spec/models/white_ip_spec.rb @@ -0,0 +1,54 @@ +require 'rails_helper' + +describe WhiteIp do + it { should belong_to(:registrar) } + + context 'with invalid attribute' do + before :all do + @white_ip = WhiteIp.new + end + + it 'is not valid' do + @white_ip.valid? + @white_ip.errors.full_messages.should match_array([ + 'IPv4 or IPv6 must be present' + ]) + end + + it 'returns an error with invalid ips' do + @white_ip.ipv4 = 'bla' + @white_ip.ipv6 = 'bla' + + @white_ip.valid? + @white_ip.errors[:ipv4].should == ['is invalid'] + @white_ip.errors[:ipv6].should == ['is invalid'] + end + end + + # context 'with valid attributes' do + # before :all do + # @white_ip = Fabricate(:white_ip) + # end + + # it 'should be valid' do + # @white_ip.valid? + # @white_ip.errors.full_messages.should match_array([]) + # end + + # it 'should be valid twice' do + # @white_ip = Fabricate(:white_ip) + # @white_ip.valid? + # @white_ip.errors.full_messages.should match_array([]) + # end + + # it 'should have one version' do + # with_versioning do + # @white_ip.versions.should == [] + # @white_ip.ipv4 = '192.168.1.1' + # @white_ip.save + # @white_ip.errors.full_messages.should match_array([]) + # @white_ip.versions.size.should == 1 + # end + # end + # end +end From 76ea1389e63458714a13a58c76f7492426ffa4fd Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 May 2015 17:25:47 +0300 Subject: [PATCH 02/11] Add logging to white ip --- app/models/version/white_ip_version.rb | 5 ++ app/models/white_ip.rb | 7 ++- app/views/admin/white_ips/_form.haml | 4 +- .../20150519140853_create_white_ip_log.rb | 18 ++++++++ db/schema.rb | 16 ++++++- spec/fabricators/white_ip_fabricator.rb | 4 ++ spec/models/white_ip_spec.rb | 46 +++++++++---------- 7 files changed, 73 insertions(+), 27 deletions(-) create mode 100644 app/models/version/white_ip_version.rb create mode 100644 db/migrate/20150519140853_create_white_ip_log.rb create mode 100644 spec/fabricators/white_ip_fabricator.rb diff --git a/app/models/version/white_ip_version.rb b/app/models/version/white_ip_version.rb new file mode 100644 index 000000000..0f2ee8a53 --- /dev/null +++ b/app/models/version/white_ip_version.rb @@ -0,0 +1,5 @@ +class WhiteIpVersion < PaperTrail::Version + include VersionSession + self.table_name = :log_white_ips + self.sequence_name = :log_white_ips_id_seq +end diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index 04ca14ffb..f71a9aaf3 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -1,4 +1,5 @@ class WhiteIp < ActiveRecord::Base + include Versions belongs_to :registrar # rubocop: disable Metrics/LineLength @@ -12,5 +13,9 @@ class WhiteIp < ActiveRecord::Base errors.add(:base, I18n.t(:ipv4_or_ipv6_must_be_present)) end - INTERFACES = ['epp', 'repp', 'registrar'] + INTERFACE_EPP = 'epp' + INTERFACE_REPP = 'repp' + INTERFACE_REGISTRAR = 'registrar' + + INTERFACES = [INTERFACE_EPP, INTERFACE_REPP, INTERFACE_REGISTRAR] end diff --git a/app/views/admin/white_ips/_form.haml b/app/views/admin/white_ips/_form.haml index e496348ba..f9bb48376 100644 --- a/app/views/admin/white_ips/_form.haml +++ b/app/views/admin/white_ips/_form.haml @@ -13,12 +13,12 @@ .col-md-4.control-label = f.label :ipv4 .col-md-7 - = f.text_field(:ipv4, class: 'form-control') + = f.text_field(:ipv4, class: 'form-control', ipv4: true) .form-group .col-md-4.control-label = f.label :ipv6 .col-md-7 - = f.text_field(:ipv6, class: 'form-control') + = f.text_field(:ipv6, class: 'form-control', ipv6: true) .form-group .col-md-4.control-label = f.label :interface diff --git a/db/migrate/20150519140853_create_white_ip_log.rb b/db/migrate/20150519140853_create_white_ip_log.rb new file mode 100644 index 000000000..b5f1e6e0b --- /dev/null +++ b/db/migrate/20150519140853_create_white_ip_log.rb @@ -0,0 +1,18 @@ +class CreateWhiteIpLog < ActiveRecord::Migration + def change + create_table :log_white_ips do |t| + t.string "item_type", null: false + t.integer "item_id", null: false + t.string "event", null: false + t.string "whodunnit" + t.json "object" + t.json "object_changes" + t.datetime "created_at" + t.string "session" + t.json "children" + end + + add_column :white_ips, :creator_str, :string + add_column :white_ips, :updator_str, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 16cf3d6fd..2b23859cc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150519115050) do +ActiveRecord::Schema.define(version: 20150519140853) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -797,6 +797,18 @@ ActiveRecord::Schema.define(version: 20150519115050) do add_index "log_users", ["item_type", "item_id"], name: "index_log_users_on_item_type_and_item_id", using: :btree add_index "log_users", ["whodunnit"], name: "index_log_users_on_whodunnit", using: :btree + create_table "log_white_ips", force: :cascade do |t| + t.string "item_type", null: false + t.integer "item_id", null: false + t.string "event", null: false + t.string "whodunnit" + t.json "object" + t.json "object_changes" + t.datetime "created_at" + t.string "session" + t.json "children" + end + create_table "log_zonefile_settings", force: :cascade do |t| t.string "item_type", null: false t.integer "item_id", null: false @@ -935,6 +947,8 @@ ActiveRecord::Schema.define(version: 20150519115050) do t.string "interface" t.datetime "created_at" t.datetime "updated_at" + t.string "creator_str" + t.string "updator_str" end create_table "whois_records", force: :cascade do |t| diff --git a/spec/fabricators/white_ip_fabricator.rb b/spec/fabricators/white_ip_fabricator.rb new file mode 100644 index 000000000..2508fe4cf --- /dev/null +++ b/spec/fabricators/white_ip_fabricator.rb @@ -0,0 +1,4 @@ +Fabricator(:white_ip) do + ipv4 '192.168.1.1' + interface WhiteIp::INTERFACE_EPP +end diff --git a/spec/models/white_ip_spec.rb b/spec/models/white_ip_spec.rb index ce16780f8..7c169c539 100644 --- a/spec/models/white_ip_spec.rb +++ b/spec/models/white_ip_spec.rb @@ -25,30 +25,30 @@ describe WhiteIp do end end - # context 'with valid attributes' do - # before :all do - # @white_ip = Fabricate(:white_ip) - # end + context 'with valid attributes' do + before :all do + @white_ip = Fabricate(:white_ip) + end - # it 'should be valid' do - # @white_ip.valid? - # @white_ip.errors.full_messages.should match_array([]) - # end + it 'should be valid' do + @white_ip.valid? + @white_ip.errors.full_messages.should match_array([]) + end - # it 'should be valid twice' do - # @white_ip = Fabricate(:white_ip) - # @white_ip.valid? - # @white_ip.errors.full_messages.should match_array([]) - # end + it 'should be valid twice' do + @white_ip = Fabricate(:white_ip) + @white_ip.valid? + @white_ip.errors.full_messages.should match_array([]) + end - # it 'should have one version' do - # with_versioning do - # @white_ip.versions.should == [] - # @white_ip.ipv4 = '192.168.1.1' - # @white_ip.save - # @white_ip.errors.full_messages.should match_array([]) - # @white_ip.versions.size.should == 1 - # end - # end - # end + it 'should have one version' do + with_versioning do + @white_ip.versions.should == [] + @white_ip.ipv4 = '192.168.1.2' + @white_ip.save + @white_ip.errors.full_messages.should match_array([]) + @white_ip.versions.size.should == 1 + end + end + end end From ae746be9701da1ad0272f5dce07231ae9b03a4b4 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 May 2015 17:29:42 +0300 Subject: [PATCH 03/11] Fix rubocop --- app/controllers/epp_controller.rb | 4 ++++ .../registrant/domain_update_confirms_controller.rb | 4 ++++ app/models/certificate.rb | 5 ++--- app/models/domain.rb | 1 - 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/controllers/epp_controller.rb b/app/controllers/epp_controller.rb index 1cf54559e..c27ce1e6b 100644 --- a/app/controllers/epp_controller.rb +++ b/app/controllers/epp_controller.rb @@ -236,6 +236,8 @@ class EppController < ApplicationController end # rubocop: enable Style/PredicateName + # rubocop: disable Metrics/PerceivedComplexity + # rubocop: disable Metrics/CyclomaticComplexity def write_to_epp_log # return nil if EPP_LOG_ENABLED request_command = params[:command] || params[:action] # error receives :command, other methods receive :action @@ -257,4 +259,6 @@ class EppController < ApplicationController ip: request.ip }) end + # rubocop: enable Metrics/PerceivedComplexity + # rubocop: enable Metrics/CyclomaticComplexity end diff --git a/app/controllers/registrant/domain_update_confirms_controller.rb b/app/controllers/registrant/domain_update_confirms_controller.rb index 7cdcd3f4b..9830b5331 100644 --- a/app/controllers/registrant/domain_update_confirms_controller.rb +++ b/app/controllers/registrant/domain_update_confirms_controller.rb @@ -8,6 +8,8 @@ class Registrant::DomainUpdateConfirmsController < RegistrantController @domain = nil unless @domain.registrant_update_confirmable?(params[:token]) end + # rubocop: disable Metrics/PerceivedComplexity + # rubocop: disable Metrics/CyclomaticComplexity def update @domain = Domain.find(params[:id]) unless @domain.registrant_update_confirmable?(params[:token]) @@ -37,4 +39,6 @@ class Registrant::DomainUpdateConfirmsController < RegistrantController end end end + # rubocop: enable Metrics/PerceivedComplexity + # rubocop: enable Metrics/CyclomaticComplexity end diff --git a/app/models/certificate.rb b/app/models/certificate.rb index c5b18ebe7..a6fdd9b6b 100644 --- a/app/models/certificate.rb +++ b/app/models/certificate.rb @@ -14,9 +14,8 @@ class Certificate < ActiveRecord::Base validate :validate_csr_and_crt def validate_csr_and_crt - if csr.blank? && crt.blank? - errors.add(:base, I18n.t(:crt_or_csr_must_be_present)) - end + return if csr.present? || crt.present? + errors.add(:base, I18n.t(:crt_or_csr_must_be_present)) end def parsed_crt diff --git a/app/models/domain.rb b/app/models/domain.rb index 621f7f6e0..3355469f1 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -297,7 +297,6 @@ class Domain < ActiveRecord::Base registrant.try(:name) end - # rubocop:disable Lint/Loop def generate_auth_info begin From 292590cbbfa9427b4105eade3ce6dc990dad7183 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 May 2015 18:03:06 +0300 Subject: [PATCH 04/11] Feature tests for ip whitelist --- config/locales/en.yml | 5 ++- db/schema.rb | 2 +- spec/features/admin/api_user_spec.rb | 4 +- spec/features/admin/white_ip_spec.rb | 63 ++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 spec/features/admin/white_ip_spec.rb diff --git a/config/locales/en.yml b/config/locales/en.yml index 797d97177..adc329141 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -225,6 +225,9 @@ en: state: 'State / Province' deposit: amount: 'Amount' + white_ip: + ipv4: 'IPv4' + ipv6: 'IPv6' errors: messages: @@ -560,8 +563,6 @@ en: code: 'Code' nameservers: 'Nameservers' hostname: 'Hostname' - ipv4: 'IPv4' - ipv6: 'IPv6' dnskeys: 'DNS Keys' flag: 'Flag' protocol: 'Protocol' diff --git a/db/schema.rb b/db/schema.rb index b6637648f..c3f85aabe 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150519102521) do +ActiveRecord::Schema.define(version: 20150519140853) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/spec/features/admin/api_user_spec.rb b/spec/features/admin/api_user_spec.rb index 36ba2a767..f37adc2b6 100644 --- a/spec/features/admin/api_user_spec.rb +++ b/spec/features/admin/api_user_spec.rb @@ -15,14 +15,14 @@ feature 'Api users', type: :feature do it 'should redirect to login path' do visit admin_api_user_url(@api_user) - + current_path.should == '/admin/login' end end context 'as logged in user' do - it 'should show index of contacts' do + it 'should show index of api users' do sign_in @user visit admin_api_users_url diff --git a/spec/features/admin/white_ip_spec.rb b/spec/features/admin/white_ip_spec.rb new file mode 100644 index 000000000..fb84b3d30 --- /dev/null +++ b/spec/features/admin/white_ip_spec.rb @@ -0,0 +1,63 @@ +require 'rails_helper' + +feature 'Api users', type: :feature do + before :all do + @user = Fabricate(:admin_user, username: 'user1', identity_code: '37810013087') + @registrar = Fabricate(:registrar) + end + + context 'as unknown user' do + it 'should redirect to login path' do + visit new_admin_registrar_white_ip_url(@registrar) + + current_path.should == '/admin/login' + end + end + + context 'as logged in user' do + before { sign_in @user } + + it 'should add new white ip to registrar' do + visit admin_registrar_url(@registrar) + + page.should_not have_text('192.168.1.1') + + click_link 'Create new white IP' + + fill_in 'IPv4', with: '192.168.1.1' + fill_in 'IPv6', with: 'FE80:0000:0000:0000:0202:B3FF:FE1E:8329' + select 'REPP', from: 'Interface' + click_button 'Save' + + page.should have_text('Record created') + page.should have_text('White IP') + page.should have_link(@registrar.to_s) + page.should have_text('192.168.1.1') + page.should have_text('FE80:0000:0000:0000:0202:B3FF:FE1E:8329') + page.should have_text('REPP') + + click_link @registrar.to_s + + current_path.should == "/admin/registrars/#{@registrar.id}" + page.should have_text('192.168.1.1') + page.should have_text('FE80:0000:0000:0000:0202:B3FF:FE1E:8329') + page.should have_text('REPP') + end + + it 'should not add invalid ip to registrar' do + visit new_admin_registrar_white_ip_url(@registrar) + + click_button 'Save' + page.should have_text('IPv4 or IPv6 must be present') + page.should have_text('Failed to create record') + + fill_in 'IPv4', with: 'bla' + fill_in 'IPv6', with: 'bla' + + click_button 'Save' + + page.should have_text('IPv4 is invalid') + page.should have_text('IPv6 is invalid') + end + end +end From 8321f894d5754ba80025070feb623c198af921d9 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 May 2015 18:06:38 +0300 Subject: [PATCH 05/11] Fix doc --- README.md | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index c3fe45972..4b3c5c8d6 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ Documentation ### Updating documentation -AUTODOC=true rspec spec/requests -EPP_DOC=true rspec spec/epp --tag epp --require support/epp_doc.rb --format EppDoc > doc/epp-examples.md + AUTODOC=true rspec spec/requests + EPP_DOC=true rspec spec/epp --tag epp --require support/epp_doc.rb --format EppDoc > doc/epp-examples.md Installation ------------ @@ -32,41 +32,41 @@ Registry based on Rails 4 installation (rbenv install is under Debian build doc) Manual demo install and database setup: -cd /home/registry -git clone git@github.com:internetee/registry.git demo-registry -cd demo-registry -rbenv local 2.2.2 -bundle -cp config/application-example.yml config/application.yml # and edit it -cp config/database-example.yml config/database.yml # and edit it -bundle exec rake db:all:setup # for production, please follow deployment howto -bundle exec rake assets:precompile + cd /home/registry + git clone git@github.com:internetee/registry.git demo-registry + cd demo-registry + rbenv local 2.2.2 + bundle + cp config/application-example.yml config/application.yml # and edit it + cp config/database-example.yml config/database.yml # and edit it + bundle exec rake db:all:setup # for production, please follow deployment howto + bundle exec rake assets:precompile ### Apache with patched mod_epp (Debian 7/Ubuntu 14.04 LTS) -sudo apt-get install apache2 + sudo apt-get install apache2 -sudo apt-get install apache2-threaded-dev # needed to compile mod_epp -wget sourceforge.net/projects/aepps/files/mod_epp/1.10/mod_epp-1.10.tar.gz -tar -xzvf mod_epp-1.10.tar.gz -cd mod_epp-1.10 + sudo apt-get install apache2-threaded-dev # needed to compile mod_epp + wget sourceforge.net/projects/aepps/files/mod_epp/1.10/mod_epp-1.10.tar.gz + tar -xzvf mod_epp-1.10.tar.gz + cd mod_epp-1.10 Patch mod_epp for Rack. Beacause Rack multipart parser expects specifically formatted content boundaries, the mod_epp needs to be modified before building: -wget https://github.com/internetee/registry/raw/master/doc/patches/mod_epp_1.10-rack-friendly.patch -wget https://raw.githubusercontent.com/domify/registry/master/doc/patches/mod_epp_1.10-frame-size.patch -patch < mod_epp_1.10-rack-friendly.patch -patch < mod_epp_1.10-frame-size.patch -sudo apxs2 -a -c -i mod_epp.c + wget https://github.com/internetee/registry/raw/master/doc/patches/mod_epp_1.10-rack-friendly.patch + wget https://raw.githubusercontent.com/domify/registry/master/doc/patches/mod_epp_1.10-frame-size.patch + patch < mod_epp_1.10-rack-friendly.patch + patch < mod_epp_1.10-frame-size.patch + sudo apxs2 -a -c -i mod_epp.c Enable ssl: -sudo a2enmod proxy_http -sudo mkdir /etc/apache2/ssl -sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt -sudo a2enmod ssl -sudo nano /etc/apache2/sites-enabled/epp_ssl.conf + sudo a2enmod proxy_http + sudo mkdir /etc/apache2/ssl + sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt + sudo a2enmod ssl + sudo nano /etc/apache2/sites-enabled/epp_ssl.conf For Apache, registry admin goes to port 443 in production, /etc/apache2/sites-enabled/registry.conf short example: From abf47b1e0819c9cf47d6bda45b048fa9f8a8e975 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 May 2015 19:12:43 +0300 Subject: [PATCH 06/11] Add IP protection for REPP --- app/api/repp/api.rb | 5 +++++ app/models/registrar.rb | 16 ++++++++++++++++ app/models/white_ip.rb | 14 ++++++++++---- app/views/admin/white_ips/_form.haml | 2 +- spec/fabricators/registrar_fabricator.rb | 1 + spec/fabricators/white_ip_fabricator.rb | 7 ++++++- 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/app/api/repp/api.rb b/app/api/repp/api.rb index e467534f0..c2a2c7715 100644 --- a/app/api/repp/api.rb +++ b/app/api/repp/api.rb @@ -8,6 +8,10 @@ module Repp end before do + unless Rails.env.development? + error! 'IP is not whitelisted', 401 unless @current_user.registrar.repp_ip_white?(request.ip) + end + next if Rails.env.test? || Rails.env.development? message = 'Certificate mismatch! Cert common name should be:' request_name = env['HTTP_SSL_CLIENT_S_DN_CN'] @@ -18,6 +22,7 @@ module Repp else error! "#{message} #{@current_user.username}", 401 if @current_user.username != request_name end + end helpers do diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 977e44eb7..7292b4bcb 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -146,4 +146,20 @@ class Registrar < ActiveRecord::Base def code=(code) self[:code] = code.gsub(/[ :]/, '').upcase if new_record? && code.present? end + + def repp_ip_white?(ip) + white_ips.repp.pluck(:ipv4, :ipv6).flatten.include?(ip) || global_ip_white?(ip) + end + + def epp_ip_white?(ip) + white_ips.epp.pluck(:ipv4, :ipv6).flatten.include?(ip) || global_ip_white?(ip) + end + + def registrar_ip_white?(ip) + white_ips.registrar.pluck(:ipv4, :ipv6).flatten.include?(ip) || global_ip_white?(ip) + end + + def global_ip_white?(ip) + white_ips.global.pluck(:ipv4, :ipv6).flatten.include?(ip) + end end diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index f71a9aaf3..499fba031 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -13,9 +13,15 @@ class WhiteIp < ActiveRecord::Base errors.add(:base, I18n.t(:ipv4_or_ipv6_must_be_present)) end - INTERFACE_EPP = 'epp' - INTERFACE_REPP = 'repp' - INTERFACE_REGISTRAR = 'registrar' + EPP = 'epp' + REPP = 'repp' + REGISTRAR = 'registrar' + GLOBAL = 'global' - INTERFACES = [INTERFACE_EPP, INTERFACE_REPP, INTERFACE_REGISTRAR] + INTERFACES = [GLOBAL, EPP, REPP, REGISTRAR] + + scope :epp, -> { where(interface: EPP) } + scope :repp, -> { where(interface: REPP) } + scope :registrar, -> { where(interface: REGISTRAR) } + scope :global, -> { where(interface: GLOBAL) } end diff --git a/app/views/admin/white_ips/_form.haml b/app/views/admin/white_ips/_form.haml index f9bb48376..5432db9fa 100644 --- a/app/views/admin/white_ips/_form.haml +++ b/app/views/admin/white_ips/_form.haml @@ -23,7 +23,7 @@ .col-md-4.control-label = f.label :interface .col-md-7 - = f.select :interface, [[t(:choose), '']] + WhiteIp::INTERFACES.map {|x| [x.upcase, x]}, {}, class: 'form-control selectize', placeholder: t(:choose) + = f.select :interface, WhiteIp::INTERFACES.map {|x| [x.upcase, x]}, {}, class: 'form-control selectize' %hr .row .col-md-8.text-right diff --git a/spec/fabricators/registrar_fabricator.rb b/spec/fabricators/registrar_fabricator.rb index 59fed19c5..6816f0253 100644 --- a/spec/fabricators/registrar_fabricator.rb +++ b/spec/fabricators/registrar_fabricator.rb @@ -10,6 +10,7 @@ Fabricator(:registrar) do code { sequence(:code) { |i| "REGISTRAR#{i}" } } reference_no { sequence(:reference_no) { |i| "RF#{i}" } } accounts(count: 1) + white_ips { [Fabricate(:white_ip_repp, ipv4: '127.0.0.1')] } end Fabricator(:registrar_with_no_account_activities, from: :registrar) do diff --git a/spec/fabricators/white_ip_fabricator.rb b/spec/fabricators/white_ip_fabricator.rb index 2508fe4cf..e449573fb 100644 --- a/spec/fabricators/white_ip_fabricator.rb +++ b/spec/fabricators/white_ip_fabricator.rb @@ -1,4 +1,9 @@ Fabricator(:white_ip) do ipv4 '192.168.1.1' - interface WhiteIp::INTERFACE_EPP + interface WhiteIp::EPP +end + +Fabricator(:white_ip_repp, from: :white_ip) do + ipv4 '127.0.0.1' + interface WhiteIp::REPP end From 9b4e9ca12cb55f5c2e5646aa0727c7f0d8406b41 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Tue, 19 May 2015 19:24:53 +0300 Subject: [PATCH 07/11] Add test for REPP IP whitelisting --- spec/fabricators/white_ip_fabricator.rb | 3 +- spec/requests/v1/account_spec.rb | 53 +++++++++++++++---------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/spec/fabricators/white_ip_fabricator.rb b/spec/fabricators/white_ip_fabricator.rb index e449573fb..b9a4b73ab 100644 --- a/spec/fabricators/white_ip_fabricator.rb +++ b/spec/fabricators/white_ip_fabricator.rb @@ -1,9 +1,8 @@ Fabricator(:white_ip) do - ipv4 '192.168.1.1' + ipv4 '127.0.0.1' interface WhiteIp::EPP end Fabricator(:white_ip_repp, from: :white_ip) do - ipv4 '127.0.0.1' interface WhiteIp::REPP end diff --git a/spec/requests/v1/account_spec.rb b/spec/requests/v1/account_spec.rb index 3928ad64a..324e8d191 100644 --- a/spec/requests/v1/account_spec.rb +++ b/spec/requests/v1/account_spec.rb @@ -1,30 +1,43 @@ require 'rails_helper' describe Repp::AccountV1 do - before :all do - @registrar1 = Fabricate(:registrar1, accounts: - [Fabricate(:account, { balance: '324.45', account_activities: [] })] - ) - @api_user = Fabricate(:gitlab_api_user, registrar: @registrar1) + it 'should fail without whitelisted IP' do + @registrar1 = Fabricate(:registrar, white_ips: [Fabricate(:white_ip)]) + @api_user = Fabricate(:api_user, registrar: @registrar1) + + get_with_auth '/repp/v1/accounts/balance', {}, @api_user + response.status.should == 401 + body = JSON.parse(response.body) + + body['error'].should == 'IP is not whitelisted' end - describe 'GET /repp/v1/accounts/balance' do - it 'returns account balance of the current registrar', autodoc: true, route_info_doc: true do - get_with_auth '/repp/v1/accounts/balance', {}, @api_user - response.status.should == 200 + context 'with valid registrar' do + before :all do + @registrar1 = Fabricate(:registrar1, accounts: + [Fabricate(:account, { balance: '324.45', account_activities: [] })] + ) + @api_user = Fabricate(:gitlab_api_user, registrar: @registrar1) + end - body = JSON.parse(response.body) - body['balance'].should == '324.45' - body['currency'].should == 'EUR' + describe 'GET /repp/v1/accounts/balance' do + it 'returns account balance of the current registrar', autodoc: true, route_info_doc: true do + get_with_auth '/repp/v1/accounts/balance', {}, @api_user + response.status.should == 200 - log = ApiLog::ReppLog.last - log[:request_path].should == '/repp/v1/accounts/balance' - log[:request_method].should == 'GET' - log[:request_params].should == '{}' - log[:response_code].should == '200' - log[:api_user_name].should == 'gitlab' - log[:api_user_registrar].should == 'registrar1' - log[:ip].should == '127.0.0.1' + body = JSON.parse(response.body) + body['balance'].should == '324.45' + body['currency'].should == 'EUR' + + log = ApiLog::ReppLog.last + log[:request_path].should == '/repp/v1/accounts/balance' + log[:request_method].should == 'GET' + log[:request_params].should == '{}' + log[:response_code].should == '200' + log[:api_user_name].should == 'gitlab' + log[:api_user_registrar].should == 'registrar1' + log[:ip].should == '127.0.0.1' + end end end end From dc1ad9e6c5bce8bb2e2257553b495cfcada7b1af Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Wed, 20 May 2015 12:47:34 +0300 Subject: [PATCH 08/11] Add whitelist to EPP --- app/api/repp/api.rb | 2 +- app/controllers/epp_controller.rb | 20 +++++++++++++++++++ .../registrar/domains_controller.rb | 6 +++--- app/models/depp/user.rb | 2 ++ config/locales/en.yml | 1 + spec/fabricators/registrar_fabricator.rb | 2 +- 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/app/api/repp/api.rb b/app/api/repp/api.rb index c2a2c7715..8a2ac761f 100644 --- a/app/api/repp/api.rb +++ b/app/api/repp/api.rb @@ -9,7 +9,7 @@ module Repp before do unless Rails.env.development? - error! 'IP is not whitelisted', 401 unless @current_user.registrar.repp_ip_white?(request.ip) + error! I18n.t('ip_is_not_whitelisted'), 401 unless @current_user.registrar.repp_ip_white?(request.ip) end next if Rails.env.test? || Rails.env.development? diff --git a/app/controllers/epp_controller.rb b/app/controllers/epp_controller.rb index c27ce1e6b..770ee0c56 100644 --- a/app/controllers/epp_controller.rb +++ b/app/controllers/epp_controller.rb @@ -80,7 +80,11 @@ class EppController < ApplicationController end # VALIDATION + # rubocop: disable Metrics/PerceivedComplexity + # rubocop: disable Metrics/CyclomaticComplexity def validate_request + handle_errors and return unless ip_white? + validation_method = "validate_#{params[:action]}" return unless respond_to?(validation_method, true) send(validation_method) @@ -93,6 +97,22 @@ class EppController < ApplicationController handle_errors and return if epp_errors.any? end + # rubocop: enable Metrics/PerceivedComplexity + # rubocop: enable Metrics/CyclomaticComplexity + + def ip_white? + if current_user + unless current_user.registrar.epp_ip_white?(request.ip) + epp_errors << { + msg: t('ip_is_not_whitelisted'), + code: '2201' + } + return false + end + end + + true + end # let's follow grape's validations: https://github.com/intridea/grape/#parameter-validation-and-coercion diff --git a/app/controllers/registrar/domains_controller.rb b/app/controllers/registrar/domains_controller.rb index d7e7fa34a..5da13d089 100644 --- a/app/controllers/registrar/domains_controller.rb +++ b/app/controllers/registrar/domains_controller.rb @@ -24,7 +24,7 @@ class Registrar::DomainsController < Registrar::DeppController # EPP controller if response_ok? render 'info' else - flash[:alert] = t(:domain_not_found) + flash[:alert] = @data.css('msg').text redirect_to registrar_domains_url and return end end @@ -118,9 +118,9 @@ class Registrar::DomainsController < Registrar::DeppController # EPP controller end def init_contacts_autocomplete_map - @contacts_autocomplete_map ||= + @contacts_autocomplete_map ||= current_user.registrar.contacts.pluck(:name, :code).map { |c| ["#{c.second} #{c.first}", c.second] } - # @priv_contacts_autocomplete_map ||= + # @priv_contacts_autocomplete_map ||= # current_user.registrar.priv_contacts.pluck(:name, :code).map { |c| ["#{c.second} #{c.first}", c.second] } end end diff --git a/app/models/depp/user.rb b/app/models/depp/user.rb index 16eacb25b..36cd08115 100644 --- a/app/models/depp/user.rb +++ b/app/models/depp/user.rb @@ -32,6 +32,8 @@ module Depp def request(xml) Nokogiri::XML(server.request(xml)).remove_namespaces! + rescue EppErrorResponse => e + Nokogiri::XML(e.response_xml.to_s).remove_namespaces! end def repp_request(path, params = {}) diff --git a/config/locales/en.yml b/config/locales/en.yml index adc329141..c3bd4256e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -795,3 +795,4 @@ en: domain_registrant_change_rejected_body: 'You have rejected domain owner change.' registrant_domain_verification_rejected: 'Domain owner change has been rejected successfully.' registrant_domain_verification_rejected_failed: 'Something went wrong' + ip_is_not_whitelisted: 'IP is not whitelisted' diff --git a/spec/fabricators/registrar_fabricator.rb b/spec/fabricators/registrar_fabricator.rb index 6816f0253..d5e1ca5f7 100644 --- a/spec/fabricators/registrar_fabricator.rb +++ b/spec/fabricators/registrar_fabricator.rb @@ -10,7 +10,7 @@ Fabricator(:registrar) do code { sequence(:code) { |i| "REGISTRAR#{i}" } } reference_no { sequence(:reference_no) { |i| "RF#{i}" } } accounts(count: 1) - white_ips { [Fabricate(:white_ip_repp, ipv4: '127.0.0.1')] } + white_ips { [Fabricate(:white_ip_repp, ipv4: '127.0.0.1'), Fabricate(:white_ip, ipv4: '127.0.0.1')] } end Fabricator(:registrar_with_no_account_activities, from: :registrar) do From 19e133ec6ad05b7564165d097ec12ff9820d0af8 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Wed, 20 May 2015 13:49:34 +0300 Subject: [PATCH 09/11] Refactor + tests --- app/controllers/epp/sessions_controller.rb | 13 +++++++++++- app/controllers/epp_controller.rb | 20 ------------------- app/views/epp/sessions/login_fail.xml.builder | 2 +- spec/epp/session_spec.rb | 13 ++++++++++++ spec/fabricators/registrar_fabricator.rb | 2 +- spec/fabricators/white_ip_fabricator.rb | 10 +++++++++- spec/requests/v1/account_spec.rb | 2 +- 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb index 47d10dbc2..96197835c 100644 --- a/app/controllers/epp/sessions_controller.rb +++ b/app/controllers/epp/sessions_controller.rb @@ -18,7 +18,7 @@ class Epp::SessionsController < EppController @api_user = ApiUser.find_by(login_params) end - if @api_user.try(:active) && cert_valid + if @api_user.try(:active) && cert_valid && ip_white? if parsed_frame.css('newPW').first unless @api_user.update(password: parsed_frame.css('newPW').first.text) response.headers['X-EPP-Returncode'] = '2200' @@ -33,6 +33,17 @@ class Epp::SessionsController < EppController render_epp_response('login_fail') end end + + def ip_white? + if @api_user + unless @api_user.registrar.epp_ip_white?(request.ip) + @msg = t('ip_is_not_whitelisted') + return false + end + end + true + end + # rubocop: enable Metrics/PerceivedComplexity # rubocop: enable Metrics/CyclomaticComplexity diff --git a/app/controllers/epp_controller.rb b/app/controllers/epp_controller.rb index 770ee0c56..c27ce1e6b 100644 --- a/app/controllers/epp_controller.rb +++ b/app/controllers/epp_controller.rb @@ -80,11 +80,7 @@ class EppController < ApplicationController end # VALIDATION - # rubocop: disable Metrics/PerceivedComplexity - # rubocop: disable Metrics/CyclomaticComplexity def validate_request - handle_errors and return unless ip_white? - validation_method = "validate_#{params[:action]}" return unless respond_to?(validation_method, true) send(validation_method) @@ -97,22 +93,6 @@ class EppController < ApplicationController handle_errors and return if epp_errors.any? end - # rubocop: enable Metrics/PerceivedComplexity - # rubocop: enable Metrics/CyclomaticComplexity - - def ip_white? - if current_user - unless current_user.registrar.epp_ip_white?(request.ip) - epp_errors << { - msg: t('ip_is_not_whitelisted'), - code: '2201' - } - return false - end - end - - true - end # let's follow grape's validations: https://github.com/intridea/grape/#parameter-validation-and-coercion diff --git a/app/views/epp/sessions/login_fail.xml.builder b/app/views/epp/sessions/login_fail.xml.builder index 1deb05a1e..a76057270 100644 --- a/app/views/epp/sessions/login_fail.xml.builder +++ b/app/views/epp/sessions/login_fail.xml.builder @@ -1,7 +1,7 @@ xml.epp_head do xml.response do xml.result('code' => '2501') do - xml.msg('Authentication error; server closing connection') + xml.msg(@msg || 'Authentication error; server closing connection') end end diff --git a/spec/epp/session_spec.rb b/spec/epp/session_spec.rb index 8fd1b2c67..ad1658710 100644 --- a/spec/epp/session_spec.rb +++ b/spec/epp/session_spec.rb @@ -39,6 +39,19 @@ describe 'EPP Session', epp: true do response[:result_code].should == '2501' end + it 'does not log in with ip that is not whitelisted' do + @registrar = Fabricate(:registrar, + { name: 'registrar123', reg_no: '1234', white_ips: [Fabricate(:white_ip_repp), Fabricate(:white_ip_registrar)] } + ) + Fabricate(:api_user, username: 'invalid-ip-user', registrar: @registrar) + + inactive = @epp_xml.session.login(clID: { value: 'invalid-ip-user' }, pw: { value: 'ghyt9e4fu' }) + response = epp_plain_request(inactive, :xml) + + response[:msg].should == 'IP is not whitelisted' + response[:result_code].should == '2501' + end + it 'prohibits further actions unless logged in' do response = epp_plain_request(@epp_xml.domain.create, :xml) response[:msg].should == 'You need to login first.' diff --git a/spec/fabricators/registrar_fabricator.rb b/spec/fabricators/registrar_fabricator.rb index d5e1ca5f7..09ee644e9 100644 --- a/spec/fabricators/registrar_fabricator.rb +++ b/spec/fabricators/registrar_fabricator.rb @@ -10,7 +10,7 @@ Fabricator(:registrar) do code { sequence(:code) { |i| "REGISTRAR#{i}" } } reference_no { sequence(:reference_no) { |i| "RF#{i}" } } accounts(count: 1) - white_ips { [Fabricate(:white_ip_repp, ipv4: '127.0.0.1'), Fabricate(:white_ip, ipv4: '127.0.0.1')] } + white_ips { [Fabricate(:white_ip)] } end Fabricator(:registrar_with_no_account_activities, from: :registrar) do diff --git a/spec/fabricators/white_ip_fabricator.rb b/spec/fabricators/white_ip_fabricator.rb index b9a4b73ab..8c4783093 100644 --- a/spec/fabricators/white_ip_fabricator.rb +++ b/spec/fabricators/white_ip_fabricator.rb @@ -1,8 +1,16 @@ Fabricator(:white_ip) do ipv4 '127.0.0.1' - interface WhiteIp::EPP + interface WhiteIp::GLOBAL end Fabricator(:white_ip_repp, from: :white_ip) do interface WhiteIp::REPP end + +Fabricator(:white_ip_epp, from: :white_ip) do + interface WhiteIp::EPP +end + +Fabricator(:white_ip_registrar, from: :white_ip) do + interface WhiteIp::REGISTRAR +end diff --git a/spec/requests/v1/account_spec.rb b/spec/requests/v1/account_spec.rb index 324e8d191..8754234f1 100644 --- a/spec/requests/v1/account_spec.rb +++ b/spec/requests/v1/account_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' describe Repp::AccountV1 do it 'should fail without whitelisted IP' do - @registrar1 = Fabricate(:registrar, white_ips: [Fabricate(:white_ip)]) + @registrar1 = Fabricate(:registrar, white_ips: [Fabricate(:white_ip_epp), Fabricate(:white_ip_registrar)]) @api_user = Fabricate(:api_user, registrar: @registrar1) get_with_auth '/repp/v1/accounts/balance', {}, @api_user From 940355a417e2c21bea92ec1c434aea630f6d90ac Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Wed, 20 May 2015 15:43:25 +0300 Subject: [PATCH 10/11] Check IP in registrar --- app/controllers/registrar/sessions_controller.rb | 9 +++++++++ app/controllers/registrar_controller.rb | 11 ++++++++++- app/models/depp/user.rb | 2 +- app/models/white_ip.rb | 13 +++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/controllers/registrar/sessions_controller.rb b/app/controllers/registrar/sessions_controller.rb index bbd06cbd4..59803233b 100644 --- a/app/controllers/registrar/sessions_controller.rb +++ b/app/controllers/registrar/sessions_controller.rb @@ -5,6 +5,8 @@ class Registrar::SessionsController < ::SessionsController false end + before_action :check_ip + def login @depp_user = Depp::User.new end @@ -139,4 +141,11 @@ class Registrar::SessionsController < ::SessionsController return User.new unless idc ApiUser.find_by(identity_code: idc) || User.new end + + private + + def check_ip + return if WhiteIp.registrar_ip_white?(request.ip) + render text: t('ip_is_not_whitelisted') and return + end end diff --git a/app/controllers/registrar_controller.rb b/app/controllers/registrar_controller.rb index e236814ad..8da12c3c1 100644 --- a/app/controllers/registrar_controller.rb +++ b/app/controllers/registrar_controller.rb @@ -1,5 +1,6 @@ class RegistrarController < ApplicationController - before_action :authenticate_user! + before_action :authenticate_user!, :check_ip + # before_action :check_ip layout 'registrar/application' include Registrar::ApplicationHelper @@ -9,6 +10,14 @@ class RegistrarController < ApplicationController false end + def check_ip + return unless current_user + return if current_user.registrar.registrar_ip_white?(request.ip) + flash[:alert] = t('ip_is_not_whitelisted') + sign_out(current_user) + redirect_to registrar_login_path and return + end + helper_method :head_title_sufix def head_title_sufix t(:registrar_head_title_sufix) diff --git a/app/models/depp/user.rb b/app/models/depp/user.rb index 36cd08115..fcce49c10 100644 --- a/app/models/depp/user.rb +++ b/app/models/depp/user.rb @@ -84,7 +84,7 @@ module Depp res = server.send_request(xml) if Nokogiri::XML(res).css('result').first['code'] != '1000' - errors.add(:base, :authorization_error) + errors.add(:base, Nokogiri::XML(res).css('result').text) end server.close_connection diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index 499fba031..b3f6e9922 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -24,4 +24,17 @@ class WhiteIp < ActiveRecord::Base scope :repp, -> { where(interface: REPP) } scope :registrar, -> { where(interface: REGISTRAR) } scope :global, -> { where(interface: GLOBAL) } + + class << self + def registrar_ip_white?(ip) + at = WhiteIp.arel_table + WhiteIp.where( + at[:interface].eq(REGISTRAR).or( + at[:interface].eq(GLOBAL) + ).and( + at[:ipv4].eq(ip) + ) + ) + end + end end From 9fd54025f57f0225387cdaca0889e8b18e0ab419 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Wed, 20 May 2015 15:44:47 +0300 Subject: [PATCH 11/11] Remove old crl script --- bin/update-crl | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100755 bin/update-crl diff --git a/bin/update-crl b/bin/update-crl deleted file mode 100755 index 202409988..000000000 --- a/bin/update-crl +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -CRL_PATH='/home/registry/registry/shared/ca/crl' - -mkdir -p $CRL_PATH/crl-temp -cd $CRL_PATH/crl-temp - -wget https://sk.ee/crls/esteid/esteid2007.crl -wget https://sk.ee/crls/juur/crl.crl -wget https://sk.ee/crls/eeccrca/eeccrca.crl -wget https://sk.ee/repository/crls/esteid2011.crl - -openssl crl -in esteid2007.crl -out esteid2007.crl -inform DER -openssl crl -in crl.crl -out crl.crl -inform DER -openssl crl -in eeccrca.crl -out eeccrca.crl -inform DER -openssl crl -in esteid2011.crl -out esteid2011.crl -inform DER - -ln -s crl.crl `openssl crl -hash -noout -in crl.crl`.r0 -ln -s esteid2007.crl `openssl crl -hash -noout -in esteid2007.crl`.r0 -ln -s eeccrca.crl `openssl crl -hash -noout -in eeccrca.crl`.r0 -ln -s esteid2011.crl `openssl crl -hash -noout -in esteid2011.crl`.r0 - -rm -rf ../*.crl ../*.r0 - -mv * .. -cd .. -rm -rf crl-temp -/etc/init.d/apache2 reload