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

Conflicts:
	app/views/layouts/application.haml
	config/locales/en.yml
This commit is contained in:
Martin Lensment 2014-11-26 15:06:44 +02:00
commit 3bb80b20d2
26 changed files with 328 additions and 409 deletions

View file

@ -26,7 +26,11 @@ group :red_green_refactor, halt_on_fail: true do
# Martin does not want rubocop
unless Socket.gethostname == 'martin'
guard :rubocop, cli: '--display-cop-names -c .rubocop-guard.yml -f fuubar', notification: false do
guard :rubocop,
all_on_start: false,
cli: '--display-cop-names -c .rubocop-guard.yml -f fuubar',
notification: false do
watch(%r{.+\.rb$})
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
watch(%r{(?:.+/)?\.rubocop-guard\.yml$}) { |m| File.dirname(m[0]) }

View file

@ -19,6 +19,12 @@ Usual Rails 4 app installation, rvm and bundler are your friends.
rake db:setup
mv config/secrets-example.yml config/secrets.yml # generate your own keys
If you desire other database locale, you have to create database manually first and
skip rake db:setup. Example:
create database registry owner registry encoding 'UTF-8' LC_COLLATE 'et_EE.utf8' LC_CTYPE 'et_EE.utf8' template template0;
rake db:schema:load
rake db:seeds
### Apache with patched mod_epp (Debian 7/Ubuntu 14.04 LTS)
@ -114,13 +120,35 @@ Wait for the greeting message on the STD, then send EPP/TCP frame:
```xml
<epp><command>
<login>
<clID>test</clID>
<pw>test</pw>
<clID>registrar1</clID>
<pw>test1</pw>
</login>
<clTRID>sample1trid</clTRID>
</command></epp>
```
All demo data locates at:
db/seeds.rb
There are two type of users: admin users and EPP users.
### EPP web client
Please follow EPP web client readme:
https://github.com/internetee/EPP-web-client
### WHOIS server
Please follow WHOIS server readme:
https://github.com/internetee/whois
Testing
---
* Before running tests for the first time: `RAILS_ENV=test rake db:seed`

View file

@ -3,7 +3,10 @@ class SessionsController < Devise::SessionsController
# TODO: Create ID Card login here:
# this is just testing config
# if Rails.env.development? || Rails.env.test?
@user = User.find_by(username: 'gitlab') if params[:gitlab]
@user = User.first if params[:user1]
@user = User.second if params[:user2]
return redirect_to :back, alert: 'No user' if @user.blank?
session[:current_user_registrar_id] = Registrar.first.id if @user.admin?

View file

@ -10,7 +10,7 @@ module Epp::ContactsHelper
# FIXME: Update returns 2303 update multiple times
code = params_hash['epp']['command']['update']['update'][:id]
@contact = Contact.where(code: code).first
if owner? && stamp(@contact) && @contact.update_attributes(contact_and_address_attributes(:update))
if update_rights? && stamp(@contact) && @contact.update_attributes(contact_and_address_attributes(:update))
render 'epp/contacts/update'
else
contact_exists?(code)
@ -21,7 +21,7 @@ module Epp::ContactsHelper
# rubocop:disable Metrics/CyclomaticComplexity
def delete_contact
@contact = find_contact
handle_errors(@contact) and return unless owner?
handle_errors(@contact) and return unless rights? # owner?
handle_errors(@contact) and return unless @contact
handle_errors(@contact) and return unless @contact.destroy_and_clean
@ -36,9 +36,8 @@ module Epp::ContactsHelper
end
def info_contact
# handle_errors and return unless rights?
@contact = find_contact
handle_errors(@contact) and return unless @contact
handle_errors(@contact) and return unless rights?
render 'epp/contacts/info'
end
@ -54,19 +53,22 @@ module Epp::ContactsHelper
## CREATE
def validate_contact_create_request
@ph = params_hash['epp']['command']['create']['create']
xml_attrs_present?(@ph, [%w(postalInfo)])
return false unless validate_params
# xml_attrs_present?(@ph, [%w(postalInfo)])
xml_attrs_present?(@ph, [%w(postalInfo name), %w(postalInfo addr city), %w(postalInfo addr cc),
%w(ident), %w(voice), %w(email)])
return epp_errors.empty? unless @ph['postalInfo'].is_a?(Hash) || @ph['postalInfo'].is_a?(Array)
epp_errors.empty? # unless @ph['postalInfo'].is_a?(Hash) || @ph['postalInfo'].is_a?(Array)
# (epp_errors << Address.validate_postal_info_types(parsed_frame)).flatten!
xml_attrs_array_present?(@ph['postalInfo'], [%w(name), %w(addr city), %w(addr cc)])
# xml_attrs_array_present?(@ph['postalInfo'], [%w(name), %w(addr city), %w(addr cc)])
end
## UPDATE
def validate_contact_update_request
@ph = params_hash['epp']['command']['update']['update']
update_attrs_present?
xml_attrs_present?(@ph, [['id']])
xml_attrs_present?(@ph, [['id'], %w(authInfo pw)])
end
def contact_exists?(code)
@ -88,16 +90,20 @@ module Epp::ContactsHelper
xml_attrs_present?(@ph, [['id']])
end
## CHECK
## check
def validate_contact_check_request
@ph = params_hash['epp']['command']['check']['check']
xml_attrs_present?(@ph, [['id']])
end
## INFO
def validate_contact_info_request
## info
def validate_contact_info_request # and process
@ph = params_hash['epp']['command']['info']['info']
xml_attrs_present?(@ph, [['id']])
return false unless xml_attrs_present?(@ph, [['id']])
@contact = find_contact
return false unless @contact
return true if current_epp_user.registrar == @contact.registrar || xml_attrs_present?(@ph, [%w(authInfo pw)])
false
end
## SHARED
@ -123,15 +129,24 @@ module Epp::ContactsHelper
def rights?
pw = @ph.try(:[], :authInfo).try(:[], :pw)
return true if !find_contact.nil? && find_contact.auth_info_matches(pw)
return true if current_epp_user.try(:registrar) == @contact.try(:registrar)
return true if pw && @contact.auth_info_matches(pw) # @contact.try(:auth_info_matches, pw)
epp_errors << { code: '2201', msg: t('errors.messages.epp_authorization_error'), value: { obj: 'pw', val: pw } }
false
end
def update_rights?
pw = @ph.try(:[], :authInfo).try(:[], :pw)
return true if pw && @contact.auth_info_matches(pw)
epp_errors << { code: '2201', msg: t('errors.messages.epp_authorization_error'), value: { obj: 'pw', val: pw } }
false
end
def contact_and_address_attributes(type = :create)
case type
when :update
# TODO: support for rem/add
contact_hash = merge_attribute_hash(@ph[:chg], type)
else
contact_hash = merge_attribute_hash(@ph, type)
@ -159,4 +174,10 @@ module Epp::ContactsHelper
Contact::IDENT_TYPES.any? { |type| return type if result.include?(type) }
nil
end
def validate_params
return true if @ph
epp_errors << { code: '2001', msg: t(:'errors.messages.epp_command_syntax_error') }
false
end
end

View file

@ -1,7 +1,6 @@
class Contact < ActiveRecord::Base
# TODO: Foreign contact will get email with activation link/username/temp password
# TODO: Phone number validation, in first phase very minimam in order to support current registries
# TODO: Validate presence of name
include EppErrors
@ -18,7 +17,7 @@ class Contact < ActiveRecord::Base
accepts_nested_attributes_for :address, :disclosure
validates :phone, :email, :ident, :address, :registrar, presence: true
validates :name, :phone, :email, :ident, :address, :registrar, presence: true
validate :ident_must_be_valid

View file

@ -99,7 +99,12 @@ class Domain < ActiveRecord::Base
def make_snapshot
{
name: name,
status: status
status: status,
period: period,
period_unit: period_unit,
registrar_id: registrar.try(:id),
valid_to: valid_to,
valid_from: valid_from
}
end

View file

@ -1,56 +0,0 @@
%tr.clickable{"data-target" => "#accordion-#{index}", "data-toggle" => "collapse"}
%td=version.whodunnit #contact.name if contact
%td=version.event #contact.ident if contact
%td=version.created_at #contact.email if contact
%tr
%td{colspan: "3"}
.collapse{ id: "accordion-#{index}" }
.row
.col-md-6
%dl.dl-horizontal
%dt= t('shared.name')
%dd= domain.name
%dt= t('shared.status')
%dd= domain.status
%dt= t('shared.valid_from')
%dd= domain.valid_from
%dt= t('shared.valid_to')
%dd= domain.valid_to
%dt= t('shared.period')
%dd= domain.period
%dt= t('shared.period_unit')
%dd= domain.period_unit
%dt= t('shared.status')
%dd= domain.status
.col-md-6
%dl.dl-horizontal
- if domain.nameservers
- domain.nameservers.each do |ns|
%dt= t('shared.hostname')
%dd= ns.hostname
%dt= t('shared.ipv4')
%dd= ns.ipv4
- if domain.domain_statuses
- domain.domain_statuses.each do |ds|
%dt= t('shared.value')
%dd= ds.value
%dt= t('shared.description')
%dd= ds.description
.row
.col-md-12
- if domain.owner_contact
%h2= t('shared.contacts')
= render 'admin/contact_versions/history', contact: domain.owner_contact
.row
.col-md-12
- if domain.domain_contacts
.row
- if domain.tech_contacts
- domain.tech_contacts.each do |contact|
= render 'admin/contact_versions/history', contact: contact
- if domain.admin_contacts
- domain.admin_contacts.each do |contact|
= render 'admin/contact_versions/history', contact: contact

View file

@ -1,3 +1,18 @@
%td{ class: changes.include?(:domain) ? 'edit-highlight' : 'no-highlight' }
- if children[:domain]
%p{:style => "font-size:x-small;"}
= children[:domain][:period]
= children[:domain][:period_unit] if children[:domain][:period]
- if children[:domain][:valid_to] && children[:domain][:valid_from]
= ","
= l(children[:domain][:valid_from], format: :date) + '-' + l(children[:domain][:valid_to], format: :date)
- if children[:domain].try(:[], :registrar_id)
= ","
= Registrar.find(children[:domain][:registrar_id]).try(:name)
- if children[:domain][:status]
= ',' + children[:domain][:status]
%td{ class: changes.include?(:owner_contact) ? 'edit-highlight' : 'no-highlight' }
- if children[:owner_contact]
%p{:style => "font-size:x-small;"}

View file

@ -1,7 +1,7 @@
.row
.col-sm-6
%h2.text-center-xs
= "#{t('shared.domain_history')} for " + @name.to_s
= "#{t(:domain_history)} for " + @name.to_s
.col-sm-6
%h2.text-right.text-center-xs
@ -12,6 +12,7 @@
%table.table-hover.table-bordered.table-condensed
%thead
%tr
%th{class: 'col-xs-2'}= t(:'shared.domain_info')
%th{class: 'col-xs-2'}= t(:'shared.owner_contact')
%th{class: 'col-xs-2'}= t(:'shared.admin_contacts')
%th{class: 'col-xs-2'}= t(:'shared.tech_contacts')

View file

@ -29,7 +29,6 @@
= sort_link(@q, 'owner_contact_name', t('shared.owner'))
%th{class: 'col-xs-2'}
= sort_link(@q, 'valid_to', t('shared.valid_to'))
%th{class: 'col-xs-1'}= t('shared.history')
%tbody
- @domains.each do |x|
%tr
@ -37,7 +36,6 @@
%td= link_to(x.registrar, root_path) if x.registrar
%td= link_to(x.owner_contact, [:admin, x.owner_contact])
%td= l(x.valid_to, format: :short)
%td= button_to(t(:'shared.history'), admin_domain_version_path(x.id), method: :get)
.row
.col-md-12
= paginate @domains

View file

@ -5,6 +5,8 @@
.col-sm-6
%h2.text-right.text-center-xs
= link_to(t('shared.edit_statuses'), edit_admin_domain_path(@domain), class: 'btn btn-primary')
= link_to(t(:'shared.history'), admin_domain_version_path(@domain.id), method: :get, class: 'btn btn-primary')
/= link_to(t('generate_zonefile'), zonefile_admin_domain_path(@domain), class: 'btn btn-primary')
%hr

View file

@ -4,11 +4,11 @@ xml.tag!('contact:postalInfo', type: 'int') do
xml.tag!('contact:org', @contact.org_name)# if @contact.disclosure.try(:int_org_name)
#if @contact.disclosure.try(:int_addr)
xml.tag!('contact:addr') do
xml.tag!('contact:street', address.street) if address.street
xml.tag!('contact:street', address.street) if address
#xml.tag!('contact:street', address.street2) if address.street2
#xml.tag!('contact:street', address.street3) if address.street3
xml.tag!('contact:cc', address.try(:country).try(:iso)) unless address.try(:country).nil?
xml.tag!('contact:city', address.city)
xml.tag!('contact:city', address.city) if address
end
#end
end

View file

@ -23,38 +23,28 @@
= link_to APP_CONFIG['app_name'], root_path, class: 'navbar-brand'
.navbar-collapse.collapse
%ul.nav.navbar-nav
%li
= link_to t('shared.domains'), admin_domains_path
%li
= link_to t('shared.contacts'), admin_contacts_path
%li
= link_to t('shared.registrars'), admin_registrars_path
%li= link_to t('shared.domains'), admin_domains_path
%li= link_to t('shared.contacts'), admin_contacts_path
%li= link_to t('shared.registrars'), admin_registrars_path
%li.dropdown
%a.dropdown-toggle{"data-toggle" => "dropdown", href: "#"}
= t('shared.settings')
%span.caret
%ul.dropdown-menu{role: "menu"}
%li.dropdown-header= t('shared.system')
%li
= link_to t('shared.settings'), admin_settings_path
%li
= link_to t('zonefile'), admin_zonefile_settings_path
%li= link_to t('shared.settings'), admin_settings_path
%li= link_to t('zonefile'), admin_zonefile_settings_path
%li= link_to t(:domains_history), admin_domain_versions_path
%li= link_to t(:background_jobs), admin_delayed_jobs_path
%li.divider
%li.dropdown-header= t('shared.users')
%li
= link_to t('shared.epp_users'), admin_epp_users_path
%li
= link_to t('shared.users'), admin_users_path
%li
= link_to t('shared.domains_history'), admin_domain_versions_path
%li
= link_to t('shared.jobs'), admin_delayed_jobs_path
%li= link_to t(:admin_users), admin_users_path
%li= link_to t(:epp_users), admin_epp_users_path
%ul.nav.navbar-nav.navbar-right
%li= link_to t('shared.log_out', user: current_user), '/logout'
/ /.nav-collapse
.container
- display = (flash.empty?) ? 'none' : 'block'

View file

@ -57,7 +57,7 @@
%span.caret
%ul.dropdown-menu{role: "menu"}
%li
= link_to t('shared.domains_history'), client_domain_versions_path
= link_to t(:domains_history'), client_domain_versions_path
%li
= link_to t('shared.contacts_history'), client_contact_versions_path

View file

@ -5,7 +5,7 @@
%meta{:content => "IE=edge", "http-equiv" => "X-UA-Compatible"}/
%meta{:content => "width=device-width, initial-scale=1", :name => "viewport"}/
%meta{:content => "Full stack top-level domain (TLD) management.", :name => "description"}/
%meta{:content => "Gitlab LTD", :name => "author"}/
%meta{:content => "Gitlab Ltd", :name => "author"}/
= csrf_meta_tags
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
= stylesheet_link_tag 'login', media: 'all', 'data-turbolinks-track' => true
@ -22,5 +22,8 @@
%hr
/ TODO: Refactor this when ID card login is done
- if can? :create, :admin_session
= button_to 'ID card (gitlab)', 'sessions',
class: 'btn btn-lg btn-primary btn-block', name: 'gitlab'
= button_to 'ID card (user1)', 'sessions',
class: 'btn btn-lg btn-primary btn-block', name: 'user1'
= button_to 'ID card (user2)', 'sessions',
class: 'btn btn-lg btn-primary btn-block', name: 'user2'

View file

@ -43,6 +43,7 @@ en:
longer: "%a, %e. %b %Y, %H:%M"
long: "%A, %e. %B %Y, %H:%M"
short: "%d.%m.%y, %H:%M"
date: "%d.%m.%y"
date:
formats:
@ -236,6 +237,7 @@ en:
epp_domain_not_found: 'Domain not found'
epp_exp_dates_do_not_match: 'Given and current expire dates do not match'
epp_registrant_not_found: 'Registrant not found'
epp_command_syntax_error: 'Command syntax error'
required_parameter_missing: 'Required parameter missing: %{key}'
attr_missing: 'Required parameter missing: %{key}'
repeating_postal_info: 'Only one of each postal info types may be provided'
@ -263,7 +265,6 @@ en:
registrar: 'Registrar'
owner: 'Owner'
domain_details: 'Domain details'
domain_history: 'Domain history'
registered_at: 'Registered at'
password: 'Password'
valid_from: 'Valid from'
@ -430,3 +431,8 @@ en:
key_data_allowed: 'Allow key data'
ds_algorithm: 'DS algorithm'
zonefile_settings: 'Zonefile settings'
background_jobs: Background jobs
domain_history: Domain history
domains_history: Domains history
admin_users: Admin users
epp_users: EPP users

View file

@ -9,7 +9,7 @@
Country.where(name: 'Estonia', iso: 'EE').first_or_create!
Country.where(name: 'Latvia', iso: 'LV').first_or_create!
zone = Registrar.where(
registrar1 = Registrar.where(
name: 'Registrar First AS',
reg_no: '10300220',
address: 'Pärnu mnt 2, Tallinna linn, Harju maakond, 11415',
@ -20,10 +20,10 @@ EppUser.where(
username: 'registrar1',
password: 'test1',
active: true,
registrar: zone
registrar: registrar1
).first_or_create
elkdata = Registrar.where(
registrar2 = Registrar.where(
name: 'Registrar Second AS',
reg_no: '10529229',
address: 'Vabaduse pst 32, 11316 Tallinn',
@ -34,7 +34,7 @@ EppUser.where(
username: 'registrar2',
password: 'test2',
active: true,
registrar: elkdata
registrar: registrar2
).first_or_create
User.where(
@ -52,7 +52,7 @@ User.where(
email: 'user2@example.ee',
admin: false,
identity_code: '37810010085',
registrar_id: zone.id,
registrar_id: registrar1.id,
country: Country.where(name: 'Estonia').first
).first_or_create
@ -62,7 +62,7 @@ User.where(
email: 'user3@example.ee',
admin: false,
identity_code: '37810010727',
registrar_id: elkdata.id,
registrar_id: registrar2.id,
country: Country.where(name: 'Estonia').first
).first_or_create

View file

@ -1,89 +0,0 @@
require 'net/ssh'
require 'net/scp'
desc 'Commands for whois'
desc 'generate whois file(s)'
task 'whois:generate' => :environment do
Dir.mkdir('./tmp/whois') unless File.exist?('./tmp/whois') # a folder for ze stuff
letter = ENV['letter']
@path = 'tmp/whois/'
letter.nil? ? generate_whois : whois_data(letter)
end
# TODO: refactor
desc 'Generate and copy one file'
task 'whois:handle_domain' => :environment do
letter = ENV['letter']
@path = 'tmp/whois/'
whois_data(letter)
copy_files(["tmp/whois/#{letter}_domain.yaml"])
end
desc 'copy whois files'
task 'whois:scp' => :environment do
letter = ENV['letter']
files = letter.nil? ? Dir['tmp/whois/*_domain.yaml'] : ["tmp/whois/#{letter}_domain.yaml"]
unless files.present?
Rails.logger.warn("tmp/whois/ is empty, no files copied at #{Time.now}")
return
end
copy_files(files)
end
# Generates whois data for all domains
def generate_whois
alphabet = (('a'..'z').to_a << %w(ö õ ü ä)).flatten!
alphabet.each do |letter|
whois_data(letter)
end
end
# Generates whois data for a domains starting with 'letter'
def whois_data(letter)
data = {}
domains = Domain.where(['name LIKE ?', "#{letter}%"])
domains.each do |domain|
data[domain.name] = {
valid_to: domain.valid_to,
status: domain.status,
contacts: [
{ name: domain.owner_contact.name, email: domain.owner_contact.email },
{ registrar: domain.registrar.name, address: domain.registrar.address }
]
}
end
File.open(@path + "#{letter}_domain.yaml", 'w') { |f| f.write(data.to_yaml) }
end
# copies files from paths passed in ( files = [ path_to_file, path_to_another_file ] )
def copy_files(files)
connection_info
generate_sum
Net::SSH.start(@host, @username, port: @port) do |session|
session.scp.upload!('tmp/whois/checklist.chk', @remote_path)
files.each do |file|
session.scp.upload!(file, @remote_path) do |_ch, name, sent, total|
puts "#{name}: #{sent}/#{total}"
end
end
end
end
def generate_sum
result = `( cd tmp/whois/; md5sum *.yaml > checklist.chk )`
Rails.logger.info(result)
end
# Describes the connection info for scp, ssh keys have to in order (passwordless login) for this to work
# TODO: move to settings
def connection_info
@host = '95.215.45.231'
@username = 'whois'
@port = 22
@remote_path = 'app/shared/data/'
end

View file

@ -2,13 +2,13 @@ require 'rails_helper'
describe 'EPP Contact', epp: true do
before do
# we don't really care about the code validations here, it's done in models
# dynamic Contact.code just makes it harder to test EPP
Contact.skip_callback(:create, :before, :generate_code)
Contact.skip_callback(:create, :before, :generate_auth_info)
end
after do
Contact.set_callback(:create, :before, :generate_code)
Contact.set_callback(:create, :before, :generate_auth_info)
end
let(:server_zone) { Epp::Server.new({ server: 'localhost', tag: 'zone', password: 'ghyt9e4fu', port: 701 }) }
@ -26,38 +26,55 @@ describe 'EPP Contact', epp: true do
context 'create command' do
it 'fails if request is invalid' do
response = epp_request(contact_create_xml({ addr: { cc: false, city: false } }), :xml)
it 'fails if request xml is missing' do
xml = EppXml::Contact.create
response = epp_request(xml, :xml)
expect(response[:results][0][:result_code]).to eq('2001')
expect(response[:results][0][:msg]).to eq('Command syntax error')
expect(response[:results].count).to eq 1
end
it 'fails if request xml is missing' do
xml = EppXml::Contact.create(
postalInfo: { addr: { value: nil } }
)
response = epp_request(xml, :xml)
expect(response[:results][0][:result_code]).to eq('2003')
expect(response[:results][1][:result_code]).to eq('2003')
expect(response[:results][2][:result_code]).to eq('2003')
expect(response[:results][3][:result_code]).to eq('2003')
expect(response[:results][4][:result_code]).to eq('2003')
expect(response[:results][5][:result_code]).to eq('2003')
expect(response[:results][0][:msg]).to eq('Required parameter missing: city')
expect(response[:results][1][:msg]).to eq('Required parameter missing: cc')
expect(response[:results].count).to eq 2
expect(response[:results][0][:msg]).to eq('Required parameter missing: name')
expect(response[:results][1][:msg]).to eq('Required parameter missing: city')
expect(response[:results][2][:msg]).to eq('Required parameter missing: cc')
expect(response[:results][3][:msg]).to eq('Required parameter missing: ident')
expect(response[:results][4][:msg]).to eq('Required parameter missing: voice')
expect(response[:results][5][:msg]).to eq('Required parameter missing: email')
expect(response[:results].count).to eq 6
end
it 'successfully creates a contact' do
response = epp_request(contact_create_xml, :xml)
response = epp_request(create_contact_xml, :xml)
expect(response[:result_code]).to eq('1000')
expect(response[:msg]).to eq('Command completed successfully')
# expect(response[:clTRID]).to eq('ABC-12345')
expect(Contact.first.created_by_id).to eq 2
expect(Contact.first.registrar).to eq(zone)
expect(zone.epp_users).to include(Contact.first.created_by)
expect(Contact.first.updated_by_id).to eq nil
expect(Contact.count).to eq(1)
expect(Contact.first.org_name).to eq('Example Inc.')
expect(Contact.first.ident).to eq '37605030299'
expect(Contact.first.ident_type).to eq 'op'
expect(Contact.first.address.street).to eq('123 Example Dr.')
# expect(Contact.first.address.street2).to eq('Suite 100')
# expect(Contact.first.address.street3).to eq nil
expect(Contact.first.address.street).to eq('123 Example')
end
it 'successfully adds registrar' do
response = epp_request(contact_create_xml, :xml)
response = epp_request(create_contact_xml, :xml)
expect(response[:result_code]).to eq('1000')
expect(response[:msg]).to eq('Command completed successfully')
@ -67,17 +84,8 @@ describe 'EPP Contact', epp: true do
expect(Contact.first.registrar).to eq(zone)
end
it 'successfully creates contact with 2 addresses' do
response = epp_request('contacts/create_with_two_addresses.xml')
expect(response[:result_code]).to eq('1000')
expect(Contact.count).to eq(1)
expect(Address.count).to eq(1)
end
it 'returns result data upon success' do
response = epp_request(contact_create_xml, :xml)
response = epp_request(create_contact_xml, :xml)
expect(response[:result_code]).to eq('1000')
expect(response[:msg]).to eq('Command completed successfully')
@ -93,19 +101,22 @@ describe 'EPP Contact', epp: true do
context 'update command' do
it 'fails if request is invalid' do
response = epp_request('contacts/update_missing_attr.xml')
xml = EppXml::Contact.update
response = epp_request(xml, :xml) # epp_request('contacts/update_missing_attr.xml')
expect(response[:results][0][:result_code]).to eq('2003')
expect(response[:results][0][:msg]).to eq('Required parameter missing: add, rem or chg')
expect(response[:results][1][:result_code]).to eq('2003')
expect(response[:results][1][:msg]).to eq('Required parameter missing: id')
expect(response[:results].count).to eq 2
expect(response[:results][2][:result_code]).to eq('2003')
expect(response[:results][2][:msg]).to eq('Required parameter missing: pw')
expect(response[:results].count).to eq 3
end
it 'fails with wrong authentication info' do
Fabricate(:contact, code: 'sh8013', auth_info: 'secure_password')
Fabricate(:contact, code: 'sh8013', auth_info: 'password_wrong')
response = epp_request('contacts/update.xml')
response = epp_request(update_contact_xml({ id: { value: 'sh8013' } }), :xml, :elkdata)
expect(response[:msg]).to eq('Authorization error')
expect(response[:result_code]).to eq('2201')
@ -118,15 +129,13 @@ describe 'EPP Contact', epp: true do
registrar: zone,
email: 'not_updated@test.test',
code: 'sh8013',
auth_info: '2fooBAR'
auth_info: 'password'
)
response = epp_request('contacts/update.xml')
response = epp_request(update_contact_xml({ id: { value: 'sh8013' } }), :xml)
expect(response[:msg]).to eq('Command completed successfully')
expect(Contact.first.name).to eq('John Doe')
expect(Contact.first.email).to eq('jdoe@example.com')
expect(Contact.first.ident).to eq('J836954')
expect(Contact.first.ident_type).to eq('passport')
expect(Contact.first.name).to eq('John Doe Edited')
expect(Contact.first.email).to eq('edited@example.example')
end
it 'returns phone and email error' do
@ -136,10 +145,18 @@ describe 'EPP Contact', epp: true do
created_by_id: 1,
email: 'not_updated@test.test',
code: 'sh8013',
auth_info: '2fooBAR'
auth_info: 'password'
)
response = epp_request('contacts/update_with_errors.xml')
xml = {
id: { value: 'sh8013' },
chg: {
voice: { value: '123213' },
email: { value: 'aaa' }
}
}
response = epp_request(update_contact_xml(xml), :xml)
expect(response[:results][0][:result_code]).to eq('2005')
expect(response[:results][0][:msg]).to eq('Phone nr is invalid')
@ -162,7 +179,8 @@ describe 'EPP Contact', epp: true do
context 'delete command' do
it 'fails if request is invalid' do
response = epp_request('contacts/delete_missing_attr.xml')
xml = EppXml::Contact.delete({ uid: { value: '23123' } })
response = epp_request(xml, :xml)
expect(response[:results][0][:result_code]).to eq('2003')
expect(response[:results][0][:msg]).to eq('Required parameter missing: id')
@ -171,7 +189,7 @@ describe 'EPP Contact', epp: true do
it 'deletes contact' do
Fabricate(:contact, code: 'dwa1234', created_by_id: EppUser.first.id, registrar: zone)
response = epp_request('contacts/delete.xml')
response = epp_request(delete_contact_xml({ id: { value: 'dwa1234' } }), :xml)
expect(response[:result_code]).to eq('1000')
expect(response[:msg]).to eq('Command completed successfully')
expect(response[:clTRID]).to eq('ABC-12345')
@ -180,7 +198,7 @@ describe 'EPP Contact', epp: true do
end
it 'returns error if obj doesnt exist' do
response = epp_request('contacts/delete.xml')
response = epp_request(delete_contact_xml, :xml)
expect(response[:result_code]).to eq('2303')
expect(response[:msg]).to eq('Object does not exist')
end
@ -196,7 +214,7 @@ describe 'EPP Contact', epp: true do
registrar: zone)
)
expect(Domain.first.owner_contact.address.present?).to be true
response = epp_request('contacts/delete.xml')
response = epp_request(delete_contact_xml({ id: { value: 'dwa1234' } }), :xml)
expect(response[:result_code]).to eq('2305')
expect(response[:msg]).to eq('Object association prohibits operation')
@ -208,7 +226,8 @@ describe 'EPP Contact', epp: true do
context 'check command' do
it 'fails if request is invalid' do
response = epp_request(contact_check_xml(ids: [false]), :xml)
xml = EppXml::Contact.check({ uid: { value: '123asde' } })
response = epp_request(xml, :xml)
expect(response[:results][0][:result_code]).to eq('2003')
expect(response[:results][0][:msg]).to eq('Required parameter missing: id')
@ -218,7 +237,7 @@ describe 'EPP Contact', epp: true do
it 'returns info about contact availability' do
Fabricate(:contact, code: 'check-1234')
response = epp_request(contact_check_xml(ids: [{ id: 'check-1234' }, { id: 'check-4321' }]), :xml)
response = epp_request(check_multiple_contacts_xml, :xml)
expect(response[:result_code]).to eq('1000')
expect(response[:msg]).to eq('Command completed successfully')
@ -234,7 +253,7 @@ describe 'EPP Contact', epp: true do
context 'info command' do
it 'fails if request invalid' do
response = epp_request('contacts/delete_missing_attr.xml')
response = epp_request(EppXml::Contact.info({ uid: { value: '123123' } }), :xml)
expect(response[:results][0][:result_code]).to eq('2003')
expect(response[:results][0][:msg]).to eq('Required parameter missing: id')
@ -242,17 +261,18 @@ describe 'EPP Contact', epp: true do
end
it 'returns error when object does not exist' do
response = epp_request('contacts/info.xml')
response = epp_request(info_contact_xml({ id: { value: 'info-4444' } }), :xml)
expect(response[:result_code]).to eq('2303')
expect(response[:msg]).to eq('Object does not exist')
expect(response[:results][0][:value]).to eq('info-4444')
end
it 'returns info about contact' do
Fabricate(:contact, created_by_id: '1', code: 'info-4444', auth_info: '2fooBAR', name: 'Johnny Awesome',
@contact = Fabricate(:contact, registrar: zone, code: 'info-4444', name: 'Johnny Awesome',
address: Fabricate(:address))
response = epp_request('contacts/info.xml')
xml = EppXml::Contact.info(id: { value: @contact.code })
response = epp_request(xml, :xml, :zone)
contact = response[:parsed].css('resData chkData')
expect(response[:result_code]).to eq('1000')
@ -265,7 +285,7 @@ describe 'EPP Contact', epp: true do
pending 'Disclosure needs to have some of the details worked out'
Fabricate(:contact, code: 'info-4444', auth_info: '2fooBAR',
disclosure: Fabricate(:contact_disclosure, email: false, phone: false))
response = epp_request('contacts/info.xml')
response = epp_request(info_contact_xml(id: { value: 'info-4444' }), :xml)
contact = response[:parsed].css('resData chkData')
expect(response[:result_code]).to eq('1000')
@ -275,14 +295,36 @@ describe 'EPP Contact', epp: true do
expect(contact.css('name').present?).to be(true)
end
it 'doesn\'t display unassociated object', pending: true do
pending 'Have to rework contact info request to have optional password requirement'
Fabricate(:contact, code: 'info-4444')
it 'doesn\'t display unassociated object without password' do
@contact = Fabricate(:contact, code: 'info-4444', registrar: zone)
response = epp_request('contacts/info.xml')
xml = EppXml::Contact.info(id: { value: @contact.code })
response = epp_request(xml, :xml, :elkdata)
expect(response[:result_code]).to eq('2003')
expect(response[:msg]).to eq('Required parameter missing: pw')
end
it 'doesn\'t display unassociated object with wrong password' do
@contact = Fabricate(:contact, code: 'info-4444', registrar: zone)
xml = EppXml::Contact.info(id: { value: @contact.code }, authInfo: { pw: { value: 'qwe321' } })
response = epp_request(xml, :xml, :elkdata)
expect(response[:result_code]).to eq('2201')
expect(response[:msg]).to eq('Authorization error')
end
it 'doest display unassociated object with correct password' do
@contact = Fabricate(:contact, code: 'info-4444', registrar: zone, name: 'Johnny Awesome')
xml = EppXml::Contact.info(id: { value: @contact.code }, authInfo: { pw: { value: @contact.auth_info } })
response = epp_request(xml, :xml, :elkdata)
contact = response[:parsed].css('resData chkData')
expect(response[:result_code]).to eq('1000')
expect(response[:msg]).to eq('Command completed successfully')
expect(contact.css('name').first.text).to eq('Johnny Awesome')
end
end
context 'renew command' do

View file

@ -14,9 +14,9 @@ feature 'Sessions', type: :feature do
scenario 'Admin logs in' do
visit root_path
expect(page).to have_button('ID card (gitlab)')
expect(page).to have_button('ID card (user1)')
click_on 'ID card (gitlab)'
click_on 'ID card (user1)'
expect(page).to have_text('Welcome!')
uri = URI.parse(current_url)

View file

@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Setting management', type: :feature do
let(:zone) { Fabricate(:registrar) }
let(:zone_user) { Fabricate(:user, registrar: zone, username: 'gitlab', admin: true, identity_code: '37810013087') }
let(:zone_user) { Fabricate(:user, registrar: zone, username: 'user1', admin: true, identity_code: '37810013087') }
background { create_settings }

View file

@ -11,7 +11,7 @@ describe '.extract_attributes' do
end
it 'should return empty hash if no disclosure' do
parsed_frame = Nokogiri::XML(contact_create_xml).remove_namespaces!
parsed_frame = Nokogiri::XML(create_contact_xml).remove_namespaces!
result = ContactDisclosure.extract_attributes(parsed_frame)
expect(result).to eq({})
end

View file

@ -21,6 +21,7 @@ describe Contact do
expect(@contact.valid?).to eq false
expect(@contact.errors.messages).to match_array({
name: ['Required parameter missing - name'],
phone: ['Required parameter missing - phone', 'Phone nr is invalid'],
email: ['Required parameter missing - email', 'Email is invalid'],
ident: ['Required parameter missing - ident'],

View file

@ -54,7 +54,7 @@ describe DomainVersion do
expect(DomainVersion.count).to eq(2)
expect(DomainVersion.last.load_snapshot).to include({
admin_contacts: [],
domain: { name: 'version.ee', status: nil },
# domain: { name: 'version.ee', status: nil },
nameservers: [],
tech_contacts: []
})
@ -104,9 +104,15 @@ describe DomainVersion do
expect(DomainVersion.last.load_snapshot[:admin_contacts].first).to include(
name: 'admin_contact 1', phone: '+372.12345678', ident: '37605030299', email: 'admin1@v.ee'
)
expect(DomainVersion.last.load_snapshot[:domain]).to eq(
{ name: 'version.ee', status: nil }
)
expect(DomainVersion.last.load_snapshot[:domain][:name]).to eq('version.ee')
expect(DomainVersion.last.load_snapshot[:domain][:status]).to eq(nil)
expect(DomainVersion.last.load_snapshot[:domain][:period]).to eq(1)
expect(DomainVersion.last.load_snapshot[:domain][:period_unit]).to eq('y')
expect(DomainVersion.last.load_snapshot[:domain][:valid_from]).to eq(Time.now.utc.beginning_of_day)
expect(DomainVersion.last.load_snapshot[:domain][:valid_to]).to eq(Time.now.utc.beginning_of_day + 1.year)
expect(DomainVersion.last.load_snapshot[:domain][:period]).to eq(1)
expect(DomainVersion.last.load_snapshot[:nameservers].size).to eq(1)
expect(DomainVersion.last.load_snapshot[:nameservers].first).to include(
hostname: 'ns.test.ee', ipv4: nil, ipv6: nil
@ -127,9 +133,11 @@ describe DomainVersion do
expect(DomainVersion.last.load_snapshot[:admin_contacts].first).to include(
name: 'admin_contact 1', phone: '+372.12345678', ident: '37605030299', email: 'admin1@v.ee'
)
expect(DomainVersion.last.load_snapshot[:domain]).to eq(
{ name: 'version.ee', status: nil }
)
expect(DomainVersion.last.load_snapshot[:domain][:name]).to eq('version.ee')
expect(DomainVersion.last.load_snapshot[:domain][:status]).to eq(nil)
expect(DomainVersion.last.load_snapshot[:domain][:period]).to eq(1)
expect(DomainVersion.last.load_snapshot[:domain][:period_unit]).to eq('y')
expect(DomainVersion.last.load_snapshot[:nameservers].size).to eq(1)
expect(DomainVersion.last.load_snapshot[:nameservers].first).to include(
hostname: 'ns.test.ee', ipv4: nil, ipv6: nil
@ -163,9 +171,11 @@ describe DomainVersion do
expect(DomainVersion.last.load_snapshot[:admin_contacts].first).to include(
name: 'edited admin_contact', phone: '+372.12345678', ident: '37605030299', email: 'admin1@v.ee'
)
expect(DomainVersion.last.load_snapshot[:domain]).to eq(
{ name: 'version.ee', status: nil }
)
expect(DomainVersion.last.load_snapshot[:domain][:name]).to eq('version.ee')
expect(DomainVersion.last.load_snapshot[:domain][:status]).to eq(nil)
expect(DomainVersion.last.load_snapshot[:domain][:period]).to eq(1)
expect(DomainVersion.last.load_snapshot[:domain][:period_unit]).to eq('y')
expect(DomainVersion.last.load_snapshot[:nameservers].size).to eq(1)
expect(DomainVersion.last.load_snapshot[:nameservers].first).to include(
hostname: 'ns.test.ee', ipv4: nil, ipv6: nil

View file

@ -1,140 +0,0 @@
module EppContactXmlBuilder
def contact_check_xml(xml_params = {})
xml_params[:ids] = xml_params[:ids] || [{ id: 'check-1234' }, { id: 'check-4321' }]
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, standalone: 'no')
xml.epp('xmlns' => 'urn:ietf:params:xml:ns:epp-1.0') do
xml.command do
xml.check do
xml.tag!('contact:check', 'xmlns:contact' => 'urn:ietf:params:xml:ns:contact-1.0') do
unless xml_params[:ids] == [false]
xml_params[:ids].each do |x|
xml.tag!('contact:id', x[:id])
end
end
end
end
xml.clTRID 'ABC-12345'
end
end
end
def contact_create_xml(xml_params = {})
# xml_params[:ids] = xml_params[:ids] || [ { id: 'check-1234' }, { id: 'check-4321' } ]
xml = Builder::XmlMarkup.new
xml_params[:addr] = xml_params[:addr] || { street: '123 Example Dr.', street2: 'Suite 100', street3: nil,
city: 'Megaton', sp: 'F3 ', pc: '201-33', cc: 'EE' }
xml_params[:authInfo] = xml_params[:authInfo] || { pw: 'Aas34fq' }
xml.instruct!(:xml, standalone: 'no')
xml.epp('xmlns' => 'urn:ietf:params:xml:ns:epp-1.0') do
xml.command do
xml.create do
xml.tag!('contact:create', 'xmlns:contact' => 'urn:ietf:params:xml:ns:contact-1.0') do
xml.tag!('contact:id', xml_params[:id], 'sh8013') unless xml_params[:id] == false
unless xml_params[:postalInfo] == [false]
xml.tag!('contact:postalInfo', type: 'int') do
xml.tag!('contact:name', ( xml_params[:name] || 'Sillius Soddus')) unless xml_params[:name] == false
xml.tag!('contact:org', ( xml_params[:org_name] || 'Example Inc.')) unless xml_params[:org_name] == false
unless xml_params[:addr] == [false]
xml.tag!('contact:addr') do
xml.tag!('contact:street', xml_params[:addr][:street]) unless xml_params[:addr][:street] == false
#xml.tag!('contact:street', xml_params[:addr][:street2]) unless xml_params[:addr][:street2] == false
#xml.tag!('contact:street', xml_params[:addr][:street3]) unless xml_params[:addr][:street3] == false
xml.tag!('contact:city', xml_params[:addr][:city]) unless xml_params[:addr][:city] == false
xml.tag!('contact:sp', xml_params[:addr][:sp]) unless xml_params[:addr][:sp] == false
xml.tag!('contact:pc', xml_params[:addr][:pc]) unless xml_params[:addr][:pc] == false
xml.tag!('contact:cc', xml_params[:addr][:cc]) unless xml_params[:addr][:cc] == false
end
end
end
end
xml.tag!('contact:voice', (xml_params[:voice] || '+372.1234567')) unless xml_params[:voice] == false
xml.tag!('contact:fax', (xml_params[:fax] || '123123')) unless xml_params[:fax] == false
xml.tag!('contact:email', (xml_params[:email] || 'example@test.example')) unless xml_params[:email] == false
xml.tag!('contact:ident', (xml_params[:ident] || '37605030299'), type: 'op') unless xml_params[:ident] == false
unless xml_params[:authInfo] == [false]
xml.tag!('contact:authInfo') do
xml.tag!('contact:pw', xml_params[:authInfo][:pw]) unless xml_params[:authInfo][:pw] == false
end
end
# Disclosure logic
end
end
xml.clTRID 'ABC-12345'
end
end
end
# CONTACT UPDATE NEEDS WORK USE ON YOUR OWN RISK
def contact_update_xml(xml_params = {})
xml = Builder::XmlMarkup.new
# postalInfo = xml_params.try(:chg).try(:postalInfo)
# addr = postalInfo.try(:addr)
postalInfo = xml_params[:chg][:postalInfo] rescue nil
addr = postalInfo[:addr] rescue nil
unless addr
addr = { street: 'Downtown', city: 'Stockholm', cc: 'SE' }
end
unless postalInfo
postalInfo = { name: 'Jane Doe', org: 'Fake Inc.', voice: '+321.12345', fax: '12312312', addr: addr }
end
xml_params[:chg] = xml_params[:chg] || { postalInfo: postalInfo }
xml_params[:chg][:postalInfo] = postalInfo
xml_params[:chg][:postalInfo][:addr] = addr
xml_params[:chg][:authInfo] = xml_params[:chg][:authInfo] || { pw: 'ccds4324pok' }
xml.instruct!(:xml, standalone: 'no')
xml.epp('xmlns' => 'urn:ietf:params:xml:ns:epp-1.0') do
xml.command do
xml.update do
xml.tag!('contact:update', 'xmlns:contact' => 'urn:ietf:params:xml:ns:contact-1.0') do
xml.tag!('contact:id', (xml_params[:id] || 'sh8013')) unless xml_params[:id] == false
unless xml_params[:chg] == [false]
xml.tag!('contact:chg') do
xml.tag!('contact:voice', xml_params[:chg][:phone] || '+123.321123') unless xml_params[:chg][:phone] == false
xml.tag!('contact:email', xml_params[:chg][:email] || 'jane@doe.com') unless xml_params[:chg][:email] == false
unless xml_params[:chg][:postalInfo] == false
xml.tag!('contact:postalInfo') do
xml.tag!('contact:name', xml_params[:chg][:postalInfo][:name]) unless xml_params[:chg][:postalInfo][:name] == false
xml.tag!('contact:org', xml_params[:chg][:postalInfo][:org]) unless xml_params[:chg][:postalInfo][:org] == false
unless xml_params[:chg][:postalInfo][:addr] == false
xml.tag!('contact:addr') do
xml.tag!('contact:street', xml_params[:chg][:postalInfo][:addr][:street]) unless xml_params[:chg][:postalInfo][:addr][:street] == false
#xml.tag!('contact:street', xml_params[:chg][:postalInfo][:addr][:street2]) unless xml_params[:chg][:postalInfo][:addr][:street2] == false
#xml.tag!('contact:street', xml_params[:chg][:postalInfo][:addr][:street3]) unless xml_params[:chg][:postalInfo][:addr][:street3] == false
xml.tag!('contact:city', xml_params[:chg][:postalInfo][:addr][:city]) unless xml_params[:chg][:postalInfo][:addr][:city] == false
xml.tag!('contact:sp', xml_params[:chg][:postalInfo][:addr][:sp]) unless xml_params[:chg][:postalInfo][:addr][:sp] == false
xml.tag!('contact:pc', xml_params[:chg][:postalInfo][:addr][:pc]) unless xml_params[:chg][:postalInfo][:addr][:pc] == false
xml.tag!('contact:cc', xml_params[:chg][:postalInfo][:addr][:cc]) unless xml_params[:chg][:postalInfo][:addr][:cc] == false
end
end
end
end
unless xml_params[:chg][:authInfo] == [false]
xml.tag!('contact:authInfo') do
xml.tag!('contact:pw', xml_params[:chg][:authInfo][:pw]) unless xml_params[:chg][:authInfo][:pw] == false
end
end
end
end
end
end
xml.clTRID 'ABC-12345'
end
end
end
end
RSpec.configure do |c|
c.include EppContactXmlBuilder
end

View file

@ -0,0 +1,76 @@
module EppContactXmlHelper
def create_contact_xml(xml_params = {})
defaults = {
postalInfo: {
name: { value: 'John Doe' },
addr: {
street: { value: '123 Example' },
city: { value: 'Tallinn' },
cc: { value: 'EE' }
}
},
voice: { value: '+372.1234567' },
email: { value: 'test@example.example' },
ident: { value: '37605030299' }
}
xml_params = defaults.deep_merge(xml_params)
EppXml::Contact.create(xml_params)
end
def update_contact_xml(xml_params = {})
defaults = {
id: { value: 'asd123123er' },
authInfo: { pw: { value: 'password' } },
chg: {
postalInfo: {
name: { value: 'John Doe Edited' }
},
voice: { value: '+372.7654321' },
email: { value: 'edited@example.example' }
}
}
xml_params = defaults.deep_merge(xml_params)
EppXml::Contact.update(xml_params)
end
def delete_contact_xml(xml_params = {})
defaults = { id: { value: 'sh8012' } }
xml_params = defaults.deep_merge(xml_params)
EppXml::Contact.delete(xml_params)
end
def info_contact_xml(xml_params = {})
defaults = { id: { value: 'sh8012' }, authInfo: { pw: { value: 'password' } } }
xml_params = defaults.deep_merge(xml_params)
EppXml::Contact.info(xml_params)
end
def check_contact_xml(xml_params = {})
defaults = {
id: { value: 'ad123c3' }
}
xml_params = defaults.deep_merge(xml_params)
EppXml::Contact.check(xml_params)
end
def check_multiple_contacts_xml
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<check>
<contact:check
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
<contact:id>check-1234</contact:id>
<contact:id>check-4321</contact:id>
</contact:check>
</check>
<clTRID>ABC-12345</clTRID>
</command>
</epp>'
end
end
RSpec.configure do |c|
c.include EppContactXmlHelper
end