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:
diff --git a/app/api/repp/api.rb b/app/api/repp/api.rb
index e467534f0..8a2ac761f 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! 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?
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/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/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 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/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/controllers/registrar/sessions_controller.rb b/app/controllers/registrar/sessions_controller.rb
index 4490b0609..20f02e492 100644
--- a/app/controllers/registrar/sessions_controller.rb
+++ b/app/controllers/registrar/sessions_controller.rb
@@ -5,6 +5,8 @@ class Registrar::SessionsController < Devise::SessionsController
false
end
+ before_action :check_ip
+
def login
@depp_user = Depp::User.new
end
@@ -139,4 +141,11 @@ class Registrar::SessionsController < Devise::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/ability.rb b/app/models/ability.rb
index 3fa44e6b0..742463c37 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -98,6 +98,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/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/depp/user.rb b/app/models/depp/user.rb
index 16eacb25b..fcce49c10 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 = {})
@@ -82,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/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
diff --git a/app/models/registrar.rb b/app/models/registrar.rb
index cb78c2ec4..7292b4bcb 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
@@ -145,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/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
new file mode 100644
index 000000000..b3f6e9922
--- /dev/null
+++ b/app/models/white_ip.rb
@@ -0,0 +1,40 @@
+class WhiteIp < ActiveRecord::Base
+ include Versions
+ 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
+
+ EPP = 'epp'
+ REPP = 'repp'
+ REGISTRAR = 'registrar'
+ GLOBAL = 'global'
+
+ 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) }
+
+ 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
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..5432db9fa
--- /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', ipv4: true)
+ .form-group
+ .col-md-4.control-label
+ = f.label :ipv6
+ .col-md-7
+ = f.text_field(:ipv6, class: 'form-control', ipv6: true)
+ .form-group
+ .col-md-4.control-label
+ = f.label :interface
+ .col-md-7
+ = f.select :interface, WhiteIp::INTERFACES.map {|x| [x.upcase, x]}, {}, class: 'form-control selectize'
+ %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/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/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
diff --git a/config/locales/en.yml b/config/locales/en.yml
index b1c334c8c..c3bd4256e 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'
@@ -772,6 +773,11 @@ 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'
confirm_domain_delete: 'Confirm domain delete'
reject_domain_delete: 'Reject domain delete'
confirm_domain_registrant_update: 'Confirm domain ownership change'
@@ -780,7 +786,7 @@ en:
domain_registrant_change_body: 'There is a request to change domain ownership. Before doing it we need your confirmation.'
new_pending_registrant: 'New owner'
current_registrant: 'Current owner'
- registrant_domain_verification_failed: 'Domain verification not available'
+ registrant_domain_verification_failed: 'Domain verification not available'
domain_registrant_change_confirmed_title: 'Domain owner change has been confirmed'
domain_registrant_change_confirmed_body: 'You have successfully confirmed domain owner change.'
registrant_domain_verification_confirmed: 'Domain owner change has successfully confirmed.'
@@ -789,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/config/routes.rb b/config/routes.rb
index 70c991a7c..c8d4e0b0e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -181,8 +181,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/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 c2666ade6..a34b0c750 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -797,6 +797,18 @@ ActiveRecord::Schema.define(version: 20150519144118) 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
@@ -954,6 +966,17 @@ ActiveRecord::Schema.define(version: 20150519144118) 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"
+ t.string "creator_str"
+ t.string "updator_str"
+ end
+
create_table "whois_records", force: :cascade do |t|
t.integer "domain_id"
t.string "name"
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 59fed19c5..09ee644e9 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)] }
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
new file mode 100644
index 000000000..8c4783093
--- /dev/null
+++ b/spec/fabricators/white_ip_fabricator.rb
@@ -0,0 +1,16 @@
+Fabricator(:white_ip) do
+ ipv4 '127.0.0.1'
+ 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/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
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..7c169c539
--- /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.2'
+ @white_ip.save
+ @white_ip.errors.full_messages.should match_array([])
+ @white_ip.versions.size.should == 1
+ end
+ end
+ end
+end
diff --git a/spec/requests/v1/account_spec.rb b/spec/requests/v1/account_spec.rb
index 3928ad64a..8754234f1 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_epp), Fabricate(:white_ip_registrar)])
+ @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