mirror of
https://github.com/internetee/registry.git
synced 2025-05-28 12:31:21 +02:00
Added custom contact id support
This commit is contained in:
parent
aa5cc83344
commit
767f7bb6df
13 changed files with 195 additions and 42 deletions
10
Guardfile
10
Guardfile
|
@ -3,11 +3,11 @@ group :red_green_refactor, halt_on_fail: true do
|
|||
# be sure you have apache2 configured to
|
||||
# accept EPP request on port 701, what proxy to 8989.
|
||||
# port and environment is just for correct notification, all is overwritten by CLI
|
||||
guard :rails, port: 8989, environment: 'test' do
|
||||
# guard :rails, port: 8989, environment: 'test', CLI: 'RAILS_ENV=test unicorn -p 8989' do
|
||||
watch('Gemfile.lock')
|
||||
watch(%r{^(config|lib)/.*})
|
||||
end
|
||||
# guard :rails, port: 8989, environment: 'test' do
|
||||
# # guard :rails, port: 8989, environment: 'test', CLI: 'RAILS_ENV=test unicorn -p 8989' do
|
||||
# watch('Gemfile.lock')
|
||||
# watch(%r{^(config|lib)/.*})
|
||||
# end
|
||||
|
||||
guard :rspec, cmd: 'spring rspec', notification: false do
|
||||
watch(%r{^spec/.+_spec\.rb$})
|
||||
|
|
|
@ -17,9 +17,7 @@ class Epp::ContactsController < EppController
|
|||
|
||||
def create
|
||||
authorize! :create, Epp::Contact
|
||||
|
||||
@contact = Epp::Contact.new(params[:parsed_frame])
|
||||
@contact.registrar = current_user.registrar
|
||||
@contact = Epp::Contact.new(params[:parsed_frame], current_user.registrar)
|
||||
|
||||
if @contact.save
|
||||
render_epp_response '/epp/contacts/create'
|
||||
|
|
|
@ -22,7 +22,11 @@ class Contact < ActiveRecord::Base
|
|||
format: { with: /\d{4}-\d{2}-\d{2}/, message: :invalid_birthday_format },
|
||||
if: proc { |c| c.ident_type == 'birthday' }
|
||||
validates :ident_country_code, presence: true, if: proc { |c| %w(bic priv).include? c.ident_type }
|
||||
validates :code, uniqueness: { message: :epp_id_taken }
|
||||
validates :code,
|
||||
uniqueness: { message: :epp_id_taken },
|
||||
format: { with: /\A[\w\-\:]*\Z/i },
|
||||
length: { maximum: 100 }
|
||||
|
||||
validate :ident_valid_format?
|
||||
|
||||
delegate :street, to: :address
|
||||
|
@ -99,15 +103,27 @@ class Contact < ActiveRecord::Base
|
|||
ident_type != IDENT_TYPE_BIC
|
||||
end
|
||||
|
||||
# generate random id for contact
|
||||
def generate_code
|
||||
self.code = SecureRandom.hex(4)
|
||||
self.code = SecureRandom.hex(4) if code.blank?
|
||||
end
|
||||
|
||||
def generate_auth_info
|
||||
return if @generate_auth_info_disabled
|
||||
self.auth_info = SecureRandom.hex(16)
|
||||
end
|
||||
|
||||
def disable_generate_auth_info! # needed for testing
|
||||
@generate_auth_info_disabled = true
|
||||
end
|
||||
|
||||
def auth_info=(pw)
|
||||
self[:auth_info] = pw if new_record?
|
||||
end
|
||||
|
||||
def code=(code)
|
||||
self[:code] = code if new_record?
|
||||
end
|
||||
|
||||
# Find a way to use self.domains with contact
|
||||
def domains_owned
|
||||
Domain.where(owner_contact_id: id)
|
||||
|
|
|
@ -45,9 +45,22 @@ class Epp::Contact < Contact
|
|||
# rubocop: enable Metrics/PerceivedComplexity
|
||||
# rubocop: enable Metrics/CyclomaticComplexity
|
||||
|
||||
def new(frame)
|
||||
def new(frame, registrar)
|
||||
return super if frame.blank?
|
||||
super(attrs_from(frame))
|
||||
|
||||
custom_code =
|
||||
if frame.css('id').present?
|
||||
"#{registrar.code}:#{frame.css('id').text.parameterize}"
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
super(
|
||||
attrs_from(frame).merge(
|
||||
code: custom_code,
|
||||
registrar: registrar
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def legal_document_attrs(legal_frame)
|
||||
|
|
|
@ -9,10 +9,18 @@ class Registrar < ActiveRecord::Base
|
|||
|
||||
validates :name, :reg_no, :country_code, :email, presence: true
|
||||
validates :name, :reg_no, uniqueness: true
|
||||
validate :set_code, if: :new_record?
|
||||
after_save :touch_domains_version
|
||||
|
||||
validates :email, :billing_email, format: /@/, allow_blank: true
|
||||
|
||||
class << self
|
||||
def search_by_query(query)
|
||||
res = search(name_or_reg_no_cont: query).result
|
||||
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v[:name]} (#{v[:reg_no]})" } }
|
||||
end
|
||||
end
|
||||
|
||||
def domain_transfers
|
||||
at = DomainTransfer.arel_table
|
||||
DomainTransfer.where(
|
||||
|
@ -34,10 +42,23 @@ class Registrar < ActiveRecord::Base
|
|||
Country.new(country_code)
|
||||
end
|
||||
|
||||
class << self
|
||||
def search_by_query(query)
|
||||
res = search(name_or_reg_no_cont: query).result
|
||||
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v[:name]} (#{v[:reg_no]})" } }
|
||||
def code=(code)
|
||||
self[:code] = code if new_record?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_code
|
||||
return false if name.blank?
|
||||
new_code = name.parameterize
|
||||
|
||||
# ensure code is always uniq automatically for a new record
|
||||
seq = 1
|
||||
while self.class.find_by_code(new_code)
|
||||
new_code += seq.to_s
|
||||
seq += 1
|
||||
end
|
||||
|
||||
self.code = new_code
|
||||
end
|
||||
end
|
||||
|
|
6
db/migrate/20150303130729_add_code_to_registrar.rb
Normal file
6
db/migrate/20150303130729_add_code_to_registrar.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class AddCodeToRegistrar < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :registrars, :code, :string
|
||||
add_index :registrars, :code
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150227113121) do
|
||||
ActiveRecord::Schema.define(version: 20150303130729) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -611,8 +611,11 @@ ActiveRecord::Schema.define(version: 20150227113121) do
|
|||
t.string "city"
|
||||
t.string "street"
|
||||
t.string "zip"
|
||||
t.string "code"
|
||||
end
|
||||
|
||||
add_index "registrars", ["code"], name: "index_registrars_on_code", using: :btree
|
||||
|
||||
create_table "reserved_domains", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.datetime "created_at"
|
||||
|
|
|
@ -13,6 +13,7 @@ Contact Mapping protocol short version:
|
|||
----------------------- ------- -----------------
|
||||
<create> 1
|
||||
<contact:create> 1 Attribute: xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"
|
||||
<contact:id> 0-1 Contact id, optional, generated automatically if missing
|
||||
<contact:postalInfo> 1 Postal information container
|
||||
<contact:name> 1 Full name of the contact
|
||||
<contact:org> 0-1 Name of organization
|
||||
|
@ -42,7 +43,7 @@ Contact Mapping protocol short version:
|
|||
----------------------- ------- -----------------
|
||||
<update> 1
|
||||
<contact:update> 1 Attribute: xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"
|
||||
<contact:id> 1 contact id, required
|
||||
<contact:id> 1 Contact id, required
|
||||
<contact:chg> 1 Change container
|
||||
<contact:postalInfo> 1 Postal information container
|
||||
<contact:name> 0-1 Full name of the contact
|
||||
|
|
|
@ -13,10 +13,8 @@ describe 'EPP Contact', epp: true do
|
|||
|
||||
login_as :registrar1
|
||||
|
||||
Contact.skip_callback(:create, :before, :generate_code)
|
||||
Contact.skip_callback(:create, :before, :generate_auth_info)
|
||||
|
||||
@contact = Fabricate(:contact, registrar: @registrar1)
|
||||
|
||||
@legal_document = {
|
||||
legalDocument: {
|
||||
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
|
||||
|
@ -25,11 +23,6 @@ describe 'EPP Contact', epp: true do
|
|||
}
|
||||
end
|
||||
|
||||
after :all do
|
||||
Contact.set_callback(:create, :before, :generate_code)
|
||||
Contact.set_callback(:create, :before, :generate_auth_info)
|
||||
end
|
||||
|
||||
context 'with valid user' do
|
||||
context 'create command' do
|
||||
def create_request(overwrites = {})
|
||||
|
@ -133,6 +126,17 @@ describe 'EPP Contact', epp: true do
|
|||
# 5 seconds for what-ever weird lag reasons might happen
|
||||
cr_date.text.to_time.should be_within(5).of(Time.now)
|
||||
end
|
||||
|
||||
it 'successfully saves custom code' do
|
||||
response = create_request(
|
||||
{ id: { value: '12345' } }
|
||||
)
|
||||
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
|
||||
Contact.last.code.should == 'registrar1:12345'
|
||||
end
|
||||
end
|
||||
|
||||
context 'update command' do
|
||||
|
@ -140,11 +144,9 @@ describe 'EPP Contact', epp: true do
|
|||
@contact =
|
||||
Fabricate(
|
||||
:contact,
|
||||
# created_by_id: 1,
|
||||
registrar: @registrar1,
|
||||
email: 'not_updated@test.test',
|
||||
code: 'sh8013',
|
||||
auth_info: 'password'
|
||||
code: 'sh8013'
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -226,6 +228,20 @@ describe 'EPP Contact', epp: true do
|
|||
response[:results][1][:msg].should == 'Email is invalid'
|
||||
response[:results][1][:result_code].should == '2005'
|
||||
end
|
||||
|
||||
it 'should not update code with custom string' do
|
||||
response = update_request(
|
||||
id: { value: 'sh8013' },
|
||||
chg: {
|
||||
id: { value: 'notpossibletoupdate' }
|
||||
}
|
||||
)
|
||||
|
||||
response[:msg].should == 'Object does not exist'
|
||||
response[:result_code].should == '2303'
|
||||
|
||||
@contact.reload.code.should == 'sh8013'
|
||||
end
|
||||
end
|
||||
|
||||
context 'delete command' do
|
||||
|
|
|
@ -11,8 +11,6 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
login_as :registrar1
|
||||
|
||||
Contact.skip_callback(:create, :before, :generate_code)
|
||||
|
||||
Fabricate(:contact, code: 'citizen_1234')
|
||||
Fabricate(:contact, code: 'sh8013')
|
||||
Fabricate(:contact, code: 'sh801333')
|
||||
|
@ -254,8 +252,8 @@ describe 'EPP Domain', epp: true do
|
|||
})
|
||||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:result_code].should == '2005'
|
||||
response[:msg].should == 'Hostname is invalid'
|
||||
response[:result_code].should == '2005'
|
||||
end
|
||||
|
||||
it 'checks hostAttr presence' do
|
||||
|
@ -271,8 +269,8 @@ describe 'EPP Domain', epp: true do
|
|||
})
|
||||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:result_code].should == '2003'
|
||||
response[:msg].should == 'Required parameter missing: create > create > ns > hostAttr'
|
||||
response[:result_code].should == '2003'
|
||||
end
|
||||
|
||||
it 'creates domain with nameservers with ips' do
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
Fabricator(:contact) do
|
||||
code { "sh#{Faker::Number.number(8)}" }
|
||||
auth_info 'password'
|
||||
name { sequence(:name) { |i| "#{Faker::Name.name}#{i}" } }
|
||||
phone '+372.12345678'
|
||||
email Faker::Internet.email
|
||||
ident '37605030299'
|
||||
ident_type 'priv'
|
||||
ident_country_code 'EE'
|
||||
auth_info 'ccds4324pok'
|
||||
address
|
||||
registrar { Fabricate(:registrar, name: Faker::Company.name, reg_no: Faker::Company.duns_number) }
|
||||
disclosure { Fabricate(:contact_disclosure) }
|
||||
# rubocop: disable Style/SymbolProc
|
||||
after_validation { |c| c.disable_generate_auth_info! }
|
||||
# rubocop: enamble Style/SymbolProc
|
||||
end
|
||||
|
|
|
@ -91,6 +91,12 @@ describe Contact do
|
|||
it 'should not have any versions' do
|
||||
@contact.versions.should == []
|
||||
end
|
||||
|
||||
it 'should not accept long code' do
|
||||
@contact.code = 'verylongcode' * 100
|
||||
@contact.valid?
|
||||
@contact.errors[:code].should == ['is too long (maximum is 100 characters)']
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid attributes' do
|
||||
|
@ -130,6 +136,17 @@ describe Contact do
|
|||
@contact.errors.full_messages.should match_array([])
|
||||
end
|
||||
|
||||
it 'should not accept new custom code' do
|
||||
old_code = @contact.code
|
||||
@contact.code = 'CID:REG1:12345'
|
||||
@contact.save.should == true
|
||||
@contact.code.should == old_code
|
||||
end
|
||||
|
||||
it 'should have static password' do
|
||||
@contact.auth_info.should == 'password'
|
||||
end
|
||||
|
||||
context 'as birthday' do
|
||||
before :all do
|
||||
@contact.ident_type = 'birthday'
|
||||
|
@ -182,20 +199,56 @@ describe Contact do
|
|||
end
|
||||
|
||||
context 'after create' do
|
||||
it 'should generate a new code and password' do
|
||||
it 'should not generate a new code when code is present' do
|
||||
@contact = Fabricate.build(:contact, code: '123asd', auth_info: 'qwe321')
|
||||
@contact.code.should == '123asd'
|
||||
@contact.save.should == true
|
||||
@contact.code.should == '123asd'
|
||||
end
|
||||
|
||||
it 'should generate a new password' do
|
||||
@contact = Fabricate.build(:contact, code: '123asd', auth_info: 'qwe321')
|
||||
@contact.code.should == '123asd'
|
||||
@contact.auth_info.should == 'qwe321'
|
||||
@contact.save!
|
||||
@contact.code.should_not == '123asd'
|
||||
@contact.save.should == true
|
||||
@contact.auth_info.should_not == 'qwe321'
|
||||
end
|
||||
|
||||
it 'should not allow same code' do
|
||||
@double_contact = Fabricate.build(:contact, code: @contact.code)
|
||||
@double_contact.valid?
|
||||
@double_contact.errors.full_messages.should == ["Code Contact id already exists"]
|
||||
end
|
||||
|
||||
it 'should allow supported code format' do
|
||||
@contact = Fabricate.build(:contact, code: 'CID:REG1:12345')
|
||||
@contact.valid?
|
||||
@contact.errors.full_messages.should == []
|
||||
end
|
||||
|
||||
it 'should not allow unsupported characters in code' do
|
||||
@contact = Fabricate.build(:contact, code: 'unsupported!ÄÖÜ~?')
|
||||
@contact.valid?
|
||||
@contact.errors.full_messages.should == ['Code is invalid']
|
||||
end
|
||||
|
||||
it 'should generate code if empty code is given' do
|
||||
@contact = Fabricate(:contact, code: '')
|
||||
@contact.code.should_not == ''
|
||||
end
|
||||
|
||||
it 'should not allow empty spaces as code' do
|
||||
@contact = Fabricate.build(:contact, code: ' ')
|
||||
@contact.valid?
|
||||
@contact.errors.full_messages.should == ['Code is invalid']
|
||||
end
|
||||
end
|
||||
|
||||
context 'after update' do
|
||||
before :all do
|
||||
@contact.code = '123asd'
|
||||
@contact.auth_info = 'qwe321'
|
||||
@contact = Fabricate.build(:contact, code: '123asd', auth_info: 'qwe321')
|
||||
@contact.save
|
||||
@contact.code.should == '123asd'
|
||||
@auth_info = @contact.auth_info
|
||||
end
|
||||
|
||||
it 'should not generate new code' do
|
||||
|
@ -205,7 +258,7 @@ describe Contact do
|
|||
|
||||
it 'should not generate new auth_info' do
|
||||
@contact.update_attributes(name: 'fvrsgbqevciherot23')
|
||||
@contact.auth_info.should == 'qwe321'
|
||||
@contact.auth_info.should == @auth_info
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,6 +28,10 @@ describe Registrar do
|
|||
@registrar.errors[:email].should == ['is invalid']
|
||||
@registrar.errors[:billing_email].should == ['is invalid']
|
||||
end
|
||||
|
||||
it 'should not have valid code' do
|
||||
@registrar.code.should == nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid attributes' do
|
||||
|
@ -59,5 +63,26 @@ describe Registrar do
|
|||
it 'should return full address' do
|
||||
@registrar.address.should == 'Street 999, Town, County, Postal'
|
||||
end
|
||||
|
||||
it 'should have code' do
|
||||
@registrar.code.should =~ /registrar/
|
||||
end
|
||||
|
||||
it 'should not be able to change code' do
|
||||
@registrar.code = 'not-updated'
|
||||
@registrar.code.should =~ /registrar/
|
||||
end
|
||||
|
||||
it 'should automatically add next code if original is taken' do
|
||||
@registrar = Fabricate(:registrar, name: 'uniq')
|
||||
@registrar.name = 'New name'
|
||||
@registrar.code.should == 'uniq'
|
||||
@registrar.save
|
||||
|
||||
@new_registrar = Fabricate.build(:registrar, name: 'uniq')
|
||||
@new_registrar.valid?
|
||||
@new_registrar.errors.full_messages.should == []
|
||||
@new_registrar.code.should == 'uniq1'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue