Merge branch 'master' of github.com:domify/registry

This commit is contained in:
Priit Tark 2015-05-20 16:31:42 +03:00
commit 2863cd6749
36 changed files with 534 additions and 92 deletions

View file

@ -20,8 +20,8 @@ Documentation
### Updating documentation ### Updating documentation
AUTODOC=true rspec spec/requests AUTODOC=true rspec spec/requests
EPP_DOC=true rspec spec/epp --tag epp --require support/epp_doc.rb --format EppDoc > doc/epp-examples.md EPP_DOC=true rspec spec/epp --tag epp --require support/epp_doc.rb --format EppDoc > doc/epp-examples.md
Installation Installation
------------ ------------
@ -32,41 +32,41 @@ Registry based on Rails 4 installation (rbenv install is under Debian build doc)
Manual demo install and database setup: Manual demo install and database setup:
cd /home/registry cd /home/registry
git clone git@github.com:internetee/registry.git demo-registry git clone git@github.com:internetee/registry.git demo-registry
cd demo-registry cd demo-registry
rbenv local 2.2.2 rbenv local 2.2.2
bundle bundle
cp config/application-example.yml config/application.yml # and edit it cp config/application-example.yml config/application.yml # and edit it
cp config/database-example.yml config/database.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 db:all:setup # for production, please follow deployment howto
bundle exec rake assets:precompile bundle exec rake assets:precompile
### Apache with patched mod_epp (Debian 7/Ubuntu 14.04 LTS) ### 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 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 wget sourceforge.net/projects/aepps/files/mod_epp/1.10/mod_epp-1.10.tar.gz
tar -xzvf mod_epp-1.10.tar.gz tar -xzvf mod_epp-1.10.tar.gz
cd mod_epp-1.10 cd mod_epp-1.10
Patch mod_epp for Rack. Beacause Rack multipart parser expects specifically Patch mod_epp for Rack. Beacause Rack multipart parser expects specifically
formatted content boundaries, the mod_epp needs to be modified before building: 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://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 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-rack-friendly.patch
patch < mod_epp_1.10-frame-size.patch patch < mod_epp_1.10-frame-size.patch
sudo apxs2 -a -c -i mod_epp.c sudo apxs2 -a -c -i mod_epp.c
Enable ssl: Enable ssl:
sudo a2enmod proxy_http sudo a2enmod proxy_http
sudo mkdir /etc/apache2/ssl 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 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 a2enmod ssl
sudo nano /etc/apache2/sites-enabled/epp_ssl.conf 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: For Apache, registry admin goes to port 443 in production, /etc/apache2/sites-enabled/registry.conf short example:

View file

@ -8,6 +8,10 @@ module Repp
end end
before do 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? next if Rails.env.test? || Rails.env.development?
message = 'Certificate mismatch! Cert common name should be:' message = 'Certificate mismatch! Cert common name should be:'
request_name = env['HTTP_SSL_CLIENT_S_DN_CN'] request_name = env['HTTP_SSL_CLIENT_S_DN_CN']
@ -18,6 +22,7 @@ module Repp
else else
error! "#{message} #{@current_user.username}", 401 if @current_user.username != request_name error! "#{message} #{@current_user.username}", 401 if @current_user.username != request_name
end end
end end
helpers do helpers do

View file

@ -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

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 if @api_user.try(:active) && cert_valid && ip_white?
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'
@ -33,6 +33,17 @@ class Epp::SessionsController < EppController
render_epp_response('login_fail') render_epp_response('login_fail')
end end
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/PerceivedComplexity
# rubocop: enable Metrics/CyclomaticComplexity # rubocop: enable Metrics/CyclomaticComplexity

View file

@ -236,6 +236,8 @@ class EppController < ApplicationController
end end
# rubocop: enable Style/PredicateName # rubocop: enable Style/PredicateName
# rubocop: disable Metrics/PerceivedComplexity
# rubocop: disable Metrics/CyclomaticComplexity
def write_to_epp_log def write_to_epp_log
# return nil if EPP_LOG_ENABLED # return nil if EPP_LOG_ENABLED
request_command = params[:command] || params[:action] # error receives :command, other methods receive :action request_command = params[:command] || params[:action] # error receives :command, other methods receive :action
@ -257,4 +259,6 @@ class EppController < ApplicationController
ip: request.ip ip: request.ip
}) })
end end
# rubocop: enable Metrics/PerceivedComplexity
# rubocop: enable Metrics/CyclomaticComplexity
end end

View file

@ -8,6 +8,8 @@ class Registrant::DomainUpdateConfirmsController < RegistrantController
@domain = nil unless @domain.registrant_update_confirmable?(params[:token]) @domain = nil unless @domain.registrant_update_confirmable?(params[:token])
end end
# rubocop: disable Metrics/PerceivedComplexity
# rubocop: disable Metrics/CyclomaticComplexity
def update def update
@domain = Domain.find(params[:id]) @domain = Domain.find(params[:id])
unless @domain.registrant_update_confirmable?(params[:token]) unless @domain.registrant_update_confirmable?(params[:token])
@ -37,4 +39,6 @@ class Registrant::DomainUpdateConfirmsController < RegistrantController
end end
end end
end end
# rubocop: enable Metrics/PerceivedComplexity
# rubocop: enable Metrics/CyclomaticComplexity
end end

View file

@ -24,7 +24,7 @@ class Registrar::DomainsController < Registrar::DeppController # EPP controller
if response_ok? if response_ok?
render 'info' render 'info'
else else
flash[:alert] = t(:domain_not_found) flash[:alert] = @data.css('msg').text
redirect_to registrar_domains_url and return redirect_to registrar_domains_url and return
end end
end end
@ -118,9 +118,9 @@ class Registrar::DomainsController < Registrar::DeppController # EPP controller
end end
def init_contacts_autocomplete_map 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] } 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] } # current_user.registrar.priv_contacts.pluck(:name, :code).map { |c| ["#{c.second} #{c.first}", c.second] }
end end
end end

View file

@ -5,6 +5,8 @@ class Registrar::SessionsController < Devise::SessionsController
false false
end end
before_action :check_ip
def login def login
@depp_user = Depp::User.new @depp_user = Depp::User.new
end end
@ -139,4 +141,11 @@ class Registrar::SessionsController < Devise::SessionsController
return User.new unless idc return User.new unless idc
ApiUser.find_by(identity_code: idc) || User.new ApiUser.find_by(identity_code: idc) || User.new
end end
private
def check_ip
return if WhiteIp.registrar_ip_white?(request.ip)
render text: t('ip_is_not_whitelisted') and return
end
end end

View file

@ -1,5 +1,6 @@
class RegistrarController < ApplicationController class RegistrarController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!, :check_ip
# before_action :check_ip
layout 'registrar/application' layout 'registrar/application'
include Registrar::ApplicationHelper include Registrar::ApplicationHelper
@ -9,6 +10,14 @@ class RegistrarController < ApplicationController
false false
end 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 helper_method :head_title_sufix
def head_title_sufix def head_title_sufix
t(:registrar_head_title_sufix) t(:registrar_head_title_sufix)

View file

@ -98,6 +98,7 @@ class Ability
can :manage, BankStatement can :manage, BankStatement
can :manage, BankTransaction can :manage, BankTransaction
can :manage, Invoice can :manage, Invoice
can :manage, WhiteIp
can :read, ApiLog::EppLog can :read, ApiLog::EppLog
can :read, ApiLog::ReppLog can :read, ApiLog::ReppLog
# can :index, :delayed_job # can :index, :delayed_job

View file

@ -14,9 +14,8 @@ class Certificate < ActiveRecord::Base
validate :validate_csr_and_crt validate :validate_csr_and_crt
def validate_csr_and_crt def validate_csr_and_crt
if csr.blank? && crt.blank? return if csr.present? || crt.present?
errors.add(:base, I18n.t(:crt_or_csr_must_be_present)) errors.add(:base, I18n.t(:crt_or_csr_must_be_present))
end
end end
def parsed_crt def parsed_crt

View file

@ -32,6 +32,8 @@ module Depp
def request(xml) def request(xml)
Nokogiri::XML(server.request(xml)).remove_namespaces! Nokogiri::XML(server.request(xml)).remove_namespaces!
rescue EppErrorResponse => e
Nokogiri::XML(e.response_xml.to_s).remove_namespaces!
end end
def repp_request(path, params = {}) def repp_request(path, params = {})
@ -82,7 +84,7 @@ module Depp
res = server.send_request(xml) res = server.send_request(xml)
if Nokogiri::XML(res).css('result').first['code'] != '1000' if Nokogiri::XML(res).css('result').first['code'] != '1000'
errors.add(:base, :authorization_error) errors.add(:base, Nokogiri::XML(res).css('result').text)
end end
server.close_connection server.close_connection

View file

@ -297,7 +297,6 @@ class Domain < ActiveRecord::Base
registrant.try(:name) registrant.try(:name)
end end
# rubocop:disable Lint/Loop # rubocop:disable Lint/Loop
def generate_auth_info def generate_auth_info
begin begin

View file

@ -10,6 +10,7 @@ class Registrar < ActiveRecord::Base
has_many :nameservers, through: :domains has_many :nameservers, through: :domains
has_many :whois_records has_many :whois_records
has_many :priv_contacts, -> { privs }, class_name: 'Contact' 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, :country_code, :email, :code, presence: true
validates :name, :reg_no, :reference_no, :code, uniqueness: true validates :name, :reg_no, :reference_no, :code, uniqueness: true
@ -48,7 +49,7 @@ class Registrar < ActiveRecord::Base
after_save :update_whois_records after_save :update_whois_records
def 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 whois_records.map(&:save) # slow currently
end end
@ -145,4 +146,20 @@ class Registrar < ActiveRecord::Base
def code=(code) def code=(code)
self[:code] = code.gsub(/[ :]/, '').upcase if new_record? && code.present? self[:code] = code.gsub(/[ :]/, '').upcase if new_record? && code.present?
end 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 end

View file

@ -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

40
app/models/white_ip.rb Normal file
View file

@ -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

View file

@ -63,7 +63,7 @@
.pull-left .pull-left
= t(:api_users) = t(:api_users)
.pull-right .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-responsive
%table.table.table-hover.table-bordered.table-condensed %table.table.table-hover.table-bordered.table-condensed
@ -76,3 +76,26 @@
%tr %tr
%td= link_to(x, [:admin, x]) %td= link_to(x, [:admin, x])
%td= x.active %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

View file

@ -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')

View file

@ -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'

View file

@ -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'

View file

@ -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

View file

@ -1,7 +1,7 @@
xml.epp_head do xml.epp_head do
xml.response do xml.response do
xml.result('code' => '2501') do xml.result('code' => '2501') do
xml.msg('Authentication error; server closing connection') xml.msg(@msg || 'Authentication error; server closing connection')
end end
end end

View file

@ -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

View file

@ -225,6 +225,9 @@ en:
state: 'State / Province' state: 'State / Province'
deposit: deposit:
amount: 'Amount' amount: 'Amount'
white_ip:
ipv4: 'IPv4'
ipv6: 'IPv6'
errors: errors:
messages: messages:
@ -560,8 +563,6 @@ en:
code: 'Code' code: 'Code'
nameservers: 'Nameservers' nameservers: 'Nameservers'
hostname: 'Hostname' hostname: 'Hostname'
ipv4: 'IPv4'
ipv6: 'IPv6'
dnskeys: 'DNS Keys' dnskeys: 'DNS Keys'
flag: 'Flag' flag: 'Flag'
protocol: 'Protocol' protocol: 'Protocol'
@ -772,6 +773,11 @@ en:
not_valid_domain_verification_body: This could mean your verification has been expired or done already.<br><br>Please contact us if you think something is wrong. not_valid_domain_verification_body: This could mean your verification has been expired or done already.<br><br>Please contact us if you think something is wrong.
upload_crt: 'Upload CRT' upload_crt: 'Upload CRT'
crt_or_csr_must_be_present: 'CRT or CSR must be present' 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' confirm_domain_delete: 'Confirm domain delete'
reject_domain_delete: 'Reject domain delete' reject_domain_delete: 'Reject domain delete'
confirm_domain_registrant_update: 'Confirm domain ownership change' 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.' domain_registrant_change_body: 'There is a request to change domain ownership. Before doing it we need your confirmation.'
new_pending_registrant: 'New owner' new_pending_registrant: 'New owner'
current_registrant: 'Current 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_title: 'Domain owner change has been confirmed'
domain_registrant_change_confirmed_body: 'You have successfully confirmed domain owner change.' domain_registrant_change_confirmed_body: 'You have successfully confirmed domain owner change.'
registrant_domain_verification_confirmed: 'Domain owner change has successfully confirmed.' 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.' 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: 'Domain owner change has been rejected successfully.'
registrant_domain_verification_rejected_failed: 'Something went wrong' registrant_domain_verification_rejected_failed: 'Something went wrong'
ip_is_not_whitelisted: 'IP is not whitelisted'

View file

@ -181,8 +181,10 @@ Rails.application.routes.draw do
end end
resources :settings resources :settings
resources :registrars do resources :registrars do
resources :api_users resources :api_users
resources :white_ips
collection do collection do
get :search get :search
end end

View file

@ -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

View file

@ -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

View file

@ -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", ["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 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| create_table "log_zonefile_settings", force: :cascade do |t|
t.string "item_type", null: false t.string "item_type", null: false
t.integer "item_id", 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" t.text "depricated_table_but_somehow_paper_trail_tests_fails_without_it"
end 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| create_table "whois_records", force: :cascade do |t|
t.integer "domain_id" t.integer "domain_id"
t.string "name" t.string "name"

View file

@ -39,6 +39,19 @@ describe 'EPP Session', epp: true do
response[:result_code].should == '2501' response[:result_code].should == '2501'
end 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 it 'prohibits further actions unless logged in' do
response = epp_plain_request(@epp_xml.domain.create, :xml) response = epp_plain_request(@epp_xml.domain.create, :xml)
response[:msg].should == 'You need to login first.' response[:msg].should == 'You need to login first.'

View file

@ -10,6 +10,7 @@ Fabricator(:registrar) do
code { sequence(:code) { |i| "REGISTRAR#{i}" } } code { sequence(:code) { |i| "REGISTRAR#{i}" } }
reference_no { sequence(:reference_no) { |i| "RF#{i}" } } reference_no { sequence(:reference_no) { |i| "RF#{i}" } }
accounts(count: 1) accounts(count: 1)
white_ips { [Fabricate(:white_ip)] }
end end
Fabricator(:registrar_with_no_account_activities, from: :registrar) do Fabricator(:registrar_with_no_account_activities, from: :registrar) do

View file

@ -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

View file

@ -15,14 +15,14 @@ feature 'Api users', type: :feature do
it 'should redirect to login path' do it 'should redirect to login path' do
visit admin_api_user_url(@api_user) visit admin_api_user_url(@api_user)
current_path.should == '/admin/login' current_path.should == '/admin/login'
end end
end end
context 'as logged in user' do context 'as logged in user' do
it 'should show index of contacts' do it 'should show index of api users' do
sign_in @user sign_in @user
visit admin_api_users_url visit admin_api_users_url

View file

@ -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

View file

@ -4,6 +4,7 @@ describe Registrar do
it { should have_many(:domains) } it { should have_many(:domains) }
it { should have_many(:api_users) } it { should have_many(:api_users) }
it { should have_many(:messages) } it { should have_many(:messages) }
it { should have_many(:white_ips) }
context 'with invalid attribute' do context 'with invalid attribute' do
before :all do before :all do

View file

@ -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

View file

@ -1,30 +1,43 @@
require 'rails_helper' require 'rails_helper'
describe Repp::AccountV1 do describe Repp::AccountV1 do
before :all do it 'should fail without whitelisted IP' do
@registrar1 = Fabricate(:registrar1, accounts: @registrar1 = Fabricate(:registrar, white_ips: [Fabricate(:white_ip_epp), Fabricate(:white_ip_registrar)])
[Fabricate(:account, { balance: '324.45', account_activities: [] })] @api_user = Fabricate(:api_user, registrar: @registrar1)
)
@api_user = Fabricate(:gitlab_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 end
describe 'GET /repp/v1/accounts/balance' do context 'with valid registrar' do
it 'returns account balance of the current registrar', autodoc: true, route_info_doc: true do before :all do
get_with_auth '/repp/v1/accounts/balance', {}, @api_user @registrar1 = Fabricate(:registrar1, accounts:
response.status.should == 200 [Fabricate(:account, { balance: '324.45', account_activities: [] })]
)
@api_user = Fabricate(:gitlab_api_user, registrar: @registrar1)
end
body = JSON.parse(response.body) describe 'GET /repp/v1/accounts/balance' do
body['balance'].should == '324.45' it 'returns account balance of the current registrar', autodoc: true, route_info_doc: true do
body['currency'].should == 'EUR' get_with_auth '/repp/v1/accounts/balance', {}, @api_user
response.status.should == 200
log = ApiLog::ReppLog.last body = JSON.parse(response.body)
log[:request_path].should == '/repp/v1/accounts/balance' body['balance'].should == '324.45'
log[:request_method].should == 'GET' body['currency'].should == 'EUR'
log[:request_params].should == '{}'
log[:response_code].should == '200' log = ApiLog::ReppLog.last
log[:api_user_name].should == 'gitlab' log[:request_path].should == '/repp/v1/accounts/balance'
log[:api_user_registrar].should == 'registrar1' log[:request_method].should == 'GET'
log[:ip].should == '127.0.0.1' 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 end
end end