mirror of
https://github.com/internetee/registry.git
synced 2025-05-17 09:57:23 +02:00
Merge branch 'master' of github.com:domify/registry
This commit is contained in:
commit
860d489e54
42 changed files with 616 additions and 319 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -10,7 +10,6 @@ capybara-*.html
|
||||||
/spec/tmp
|
/spec/tmp
|
||||||
**.orig
|
**.orig
|
||||||
config/initializers/secret_token.rb
|
config/initializers/secret_token.rb
|
||||||
config/application.yml
|
|
||||||
config/secrets.yml
|
config/secrets.yml
|
||||||
config/database.yml
|
config/database.yml
|
||||||
/export
|
/export
|
||||||
|
@ -26,3 +25,6 @@ todo
|
||||||
|
|
||||||
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
||||||
.rvmrc
|
.rvmrc
|
||||||
|
|
||||||
|
# Ignore application configuration
|
||||||
|
/config/application.yml
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
27.02.2015
|
||||||
|
|
||||||
|
* Simplified config/application-example.yml,
|
||||||
|
now system will check if all required settings are present in application.yml
|
||||||
|
|
||||||
19.02.2015
|
19.02.2015
|
||||||
|
|
||||||
* Cetrificate only enabled, please setup certificates following doc/certificate.md document.
|
* Cetrificate only enabled, please setup certificates following doc/certificate.md document.
|
||||||
|
|
3
Gemfile
3
Gemfile
|
@ -5,6 +5,9 @@ gem 'rails', '4.2.0'
|
||||||
gem 'iso8601', '~> 0.8.2' # for dates and times
|
gem 'iso8601', '~> 0.8.2' # for dates and times
|
||||||
gem 'hashie_rails', '~> 0.0.1'
|
gem 'hashie_rails', '~> 0.0.1'
|
||||||
|
|
||||||
|
# load env
|
||||||
|
gem 'figaro', '~> 1.1.0'
|
||||||
|
|
||||||
# model related
|
# model related
|
||||||
gem 'pg', '~> 0.18.0'
|
gem 'pg', '~> 0.18.0'
|
||||||
gem 'ransack', '~> 1.5.1' # for searching
|
gem 'ransack', '~> 1.5.1' # for searching
|
||||||
|
|
|
@ -152,6 +152,8 @@ GEM
|
||||||
i18n (~> 0.5)
|
i18n (~> 0.5)
|
||||||
fastercsv (1.5.5)
|
fastercsv (1.5.5)
|
||||||
ffi (1.9.6)
|
ffi (1.9.6)
|
||||||
|
figaro (1.1.0)
|
||||||
|
thor (~> 0.14)
|
||||||
flay (2.4.0)
|
flay (2.4.0)
|
||||||
ruby_parser (~> 3.0)
|
ruby_parser (~> 3.0)
|
||||||
sexp_processor (~> 4.0)
|
sexp_processor (~> 4.0)
|
||||||
|
@ -459,6 +461,7 @@ DEPENDENCIES
|
||||||
epp-xml (~> 0.10.4)
|
epp-xml (~> 0.10.4)
|
||||||
fabrication (~> 2.12.2)
|
fabrication (~> 2.12.2)
|
||||||
faker (~> 1.3.0)
|
faker (~> 1.3.0)
|
||||||
|
figaro (~> 1.1.0)
|
||||||
grape (~> 0.10.1)
|
grape (~> 0.10.1)
|
||||||
guard (~> 2.6.1)
|
guard (~> 2.6.1)
|
||||||
guard-rails (~> 0.7.0)
|
guard-rails (~> 0.7.0)
|
||||||
|
|
10
Guardfile
10
Guardfile
|
@ -3,11 +3,11 @@ group :red_green_refactor, halt_on_fail: true do
|
||||||
# be sure you have apache2 configured to
|
# be sure you have apache2 configured to
|
||||||
# accept EPP request on port 701, what proxy to 8989.
|
# accept EPP request on port 701, what proxy to 8989.
|
||||||
# port and environment is just for correct notification, all is overwritten by CLI
|
# 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' do
|
||||||
# guard :rails, port: 8989, environment: 'test', CLI: 'RAILS_ENV=test unicorn -p 8989' do
|
# # guard :rails, port: 8989, environment: 'test', CLI: 'RAILS_ENV=test unicorn -p 8989' do
|
||||||
watch('Gemfile.lock')
|
# watch('Gemfile.lock')
|
||||||
watch(%r{^(config|lib)/.*})
|
# watch(%r{^(config|lib)/.*})
|
||||||
end
|
# end
|
||||||
|
|
||||||
guard :rspec, cmd: 'spring rspec', notification: false do
|
guard :rspec, cmd: 'spring rspec', notification: false do
|
||||||
watch(%r{^spec/.+_spec\.rb$})
|
watch(%r{^spec/.+_spec\.rb$})
|
||||||
|
|
133
README.md
133
README.md
|
@ -23,7 +23,7 @@ Installation
|
||||||
|
|
||||||
### Registry app
|
### Registry app
|
||||||
|
|
||||||
Usual Rails 4 app installation (rbenv install is under Debian build doc)
|
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:
|
||||||
|
|
||||||
|
@ -32,44 +32,11 @@ Manual demo install and database setup:
|
||||||
cd demo-registry
|
cd demo-registry
|
||||||
rbenv local 2.2.0
|
rbenv local 2.2.0
|
||||||
bundle
|
bundle
|
||||||
|
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
|
||||||
cp config/initializers/devise_secret_example.rb.txt config/initializers/devise_secret.rb # and edit
|
bundle exec rake db:all:setup # for production, please follow deployment howto
|
||||||
bundle exec rake assets:precompile
|
bundle exec rake assets:precompile
|
||||||
|
|
||||||
Create registry database manually, example:
|
|
||||||
|
|
||||||
create database registry_production owner registry encoding 'UTF-8' LC_COLLATE 'et_EE.utf8' LC_CTYPE 'et_EE.utf8' template template0;
|
|
||||||
rake db:schema:load
|
|
||||||
rake db:seeds
|
|
||||||
|
|
||||||
Or create all databases:
|
|
||||||
|
|
||||||
rake db:all:setup # will create all databases and loads all schemas
|
|
||||||
rake db:all:create # creates all databases
|
|
||||||
rake db:all:schema:load # loads all schemas
|
|
||||||
rake db:all:schema:dump # dumps all schemas
|
|
||||||
|
|
||||||
Production install (database schema should be loaded and seeds should be present)
|
|
||||||
|
|
||||||
# at your local machine
|
|
||||||
git clone git@github.com:internetee/registry.git
|
|
||||||
cd registry
|
|
||||||
rbenv local 2.2.0 # more info about rbenv at debian doc
|
|
||||||
gem install mina
|
|
||||||
mina pr setup # one time, only creates missing directories
|
|
||||||
ssh registry
|
|
||||||
|
|
||||||
# at your server
|
|
||||||
cd registry
|
|
||||||
cp current/config/application-example.yml shared/config/application.yml # and edit it
|
|
||||||
cp current/config/database-example.yml shared/config/database.yml # and edit it
|
|
||||||
|
|
||||||
vi /etc/apache2/sites-enabled/registry.conf # add conf and all needed serts
|
|
||||||
vi /etc/apache2/sites-enabled/epp.conf # add epp conf, restart apache
|
|
||||||
exit
|
|
||||||
# at your local machine
|
|
||||||
mina pr deploy # this is command you use in every application code update
|
|
||||||
|
|
||||||
### 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
|
||||||
|
@ -186,11 +153,22 @@ All registry demo data can be found at:
|
||||||
|
|
||||||
Initially you can use two type of users: admin users and EPP users.
|
Initially you can use two type of users: admin users and EPP users.
|
||||||
|
|
||||||
|
|
||||||
### Certificates setup
|
### Certificates setup
|
||||||
|
|
||||||
* [Certificates setup](/doc/certificates.md)
|
* [Certificates setup](/doc/certificates.md)
|
||||||
|
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
|
||||||
|
* [Application build and update](/doc/application_build_doc.md)
|
||||||
|
|
||||||
|
|
||||||
|
### Autotesting
|
||||||
|
|
||||||
|
* [Testing](/doc/testing.md)
|
||||||
|
|
||||||
|
|
||||||
### EPP web client
|
### EPP web client
|
||||||
|
|
||||||
Please follow EPP web client readme:
|
Please follow EPP web client readme:
|
||||||
|
@ -205,89 +183,6 @@ Please follow WHOIS server readme:
|
||||||
https://github.com/internetee/whois
|
https://github.com/internetee/whois
|
||||||
|
|
||||||
|
|
||||||
Deployment
|
|
||||||
----------
|
|
||||||
|
|
||||||
* [Debian build](/doc/debian_build_doc.md)
|
|
||||||
* [Application build and update](/doc/application_build_doc.md)
|
|
||||||
|
|
||||||
CRON
|
|
||||||
----
|
|
||||||
|
|
||||||
Crontab can be setup after deploy. Jobs can be viewed [here](/config/schedule.rb).
|
|
||||||
|
|
||||||
mina pr cron:setup # to update the crontab.
|
|
||||||
mina pr cron:clear # to clear crontab.
|
|
||||||
|
|
||||||
Autotesting
|
|
||||||
-----------
|
|
||||||
|
|
||||||
* Before running tests for the first time: `RAILS_ENV=test rake db:seed`
|
|
||||||
* Run tests: `rake`
|
|
||||||
* Run EPP tests: `rake test:epp`
|
|
||||||
* Run all but EPP tests: `rake test:other`
|
|
||||||
|
|
||||||
To see internal errors while testing EPP
|
|
||||||
|
|
||||||
unicorn -E test -p 8989
|
|
||||||
rake spec:epp
|
|
||||||
|
|
||||||
### Apache mod_epp autotesting/debugging
|
|
||||||
|
|
||||||
Autotesting Apache mod_epp without Registry app.
|
|
||||||
|
|
||||||
sudo apt-get install apache2-dbg
|
|
||||||
|
|
||||||
Includes htpasswd command to generate authentication files
|
|
||||||
|
|
||||||
sudo apt-get install apache2-utils
|
|
||||||
|
|
||||||
For manual debugging purposes, standalone CGI scripts can be used:
|
|
||||||
This needs a static greeting file, so you will have to make /var/www writable.
|
|
||||||
|
|
||||||
```apache
|
|
||||||
<IfModule mod_epp.c>
|
|
||||||
<Directory "/usr/lib/cgi-bin/epp">
|
|
||||||
Options ExecCGI
|
|
||||||
SetHandler cgi-script
|
|
||||||
</Directory>
|
|
||||||
|
|
||||||
Listen 1700
|
|
||||||
|
|
||||||
<VirtualHost *:1700>
|
|
||||||
EPPEngine On
|
|
||||||
EPPCommandRoot /cgi-bin/epp/command
|
|
||||||
EPPSessionRoot /cgi-bin/epp/session
|
|
||||||
EPPErrorRoot /cgi-bin/epp/error
|
|
||||||
|
|
||||||
Alias /cgi-bin/epp/session/hello /var/www/html/epp/session-hello
|
|
||||||
|
|
||||||
Alias /cgi-bin/epp/session/login /usr/lib/cgi-bin/epp/session-login
|
|
||||||
Alias /cgi-bin/epp/session/logout /usr/lib/cgi-bin/epp/session-logout
|
|
||||||
Alias /cgi-bin/epp/error/schema /usr/lib/cgi-bin/epp/error-schema
|
|
||||||
Alias /cgi-bin/epp/command/create /usr/lib/cgi-bin/epp/create
|
|
||||||
Alias /cgi-bin/epp/command/info /usr/lib/cgi-bin/epp/info
|
|
||||||
|
|
||||||
EPPAuthURI /epp/auth/login
|
|
||||||
<Location /epp/auth>
|
|
||||||
AuthType Basic
|
|
||||||
AuthName "EPP"
|
|
||||||
AuthUserFile /etc/apache2/htpasswd
|
|
||||||
require valid-user
|
|
||||||
</Location>
|
|
||||||
</VirtualHost>
|
|
||||||
</IfModule>
|
|
||||||
```
|
|
||||||
|
|
||||||
sudo a2enmod cgi
|
|
||||||
sudo a2enmod authn_file # will be used for non implicit authentication URIs
|
|
||||||
sudo htpasswd -c /etc/apache2/htpasswd test
|
|
||||||
Type "test" when prompted
|
|
||||||
cd /usr/lib/cgi-bin
|
|
||||||
mkdir epp
|
|
||||||
|
|
||||||
Copy the files from $mod_epp/examples/cgis to /usr/lib/cgi-bin/epp
|
|
||||||
|
|
||||||
## Code Status
|
## Code Status
|
||||||
|
|
||||||
Alpha release status, only model tests:
|
Alpha release status, only model tests:
|
||||||
|
|
|
@ -17,9 +17,7 @@ class Epp::ContactsController < EppController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize! :create, Epp::Contact
|
authorize! :create, Epp::Contact
|
||||||
|
@contact = Epp::Contact.new(params[:parsed_frame], current_user.registrar)
|
||||||
@contact = Epp::Contact.new(params[:parsed_frame])
|
|
||||||
@contact.registrar = current_user.registrar
|
|
||||||
|
|
||||||
if @contact.save
|
if @contact.save
|
||||||
render_epp_response '/epp/contacts/create'
|
render_epp_response '/epp/contacts/create'
|
||||||
|
|
|
@ -9,7 +9,7 @@ class Epp::SessionsController < EppController
|
||||||
# rubocop: disable Metrics/CyclomaticComplexity
|
# rubocop: disable Metrics/CyclomaticComplexity
|
||||||
def login
|
def login
|
||||||
cert_valid = true
|
cert_valid = true
|
||||||
if request.ip == APP_CONFIG['webclient_ip']
|
if request.ip == ENV['webclient_ip']
|
||||||
@api_user = ApiUser.find_by(login_params)
|
@api_user = ApiUser.find_by(login_params)
|
||||||
else
|
else
|
||||||
if request.env['HTTP_SSL_CLIENT_S_DN_CN'] != login_params[:username]
|
if request.env['HTTP_SSL_CLIENT_S_DN_CN'] != login_params[:username]
|
||||||
|
|
|
@ -103,6 +103,7 @@ class EppController < ApplicationController
|
||||||
el, missing = nil, nil
|
el, missing = nil, nil
|
||||||
selectors.each do |selector|
|
selectors.each do |selector|
|
||||||
full_selector = [@prefix, selector].compact.join(' ')
|
full_selector = [@prefix, selector].compact.join(' ')
|
||||||
|
attr = selector.split('>').last.strip.underscore
|
||||||
el = params[:parsed_frame].css(full_selector).first
|
el = params[:parsed_frame].css(full_selector).first
|
||||||
|
|
||||||
if allow_blank
|
if allow_blank
|
||||||
|
@ -112,7 +113,7 @@ class EppController < ApplicationController
|
||||||
end
|
end
|
||||||
epp_errors << {
|
epp_errors << {
|
||||||
code: '2003',
|
code: '2003',
|
||||||
msg: I18n.t('errors.messages.required_parameter_missing', key: full_selector)
|
msg: I18n.t('errors.messages.required_parameter_missing', key: "#{full_selector} [#{attr}]")
|
||||||
} if missing
|
} if missing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class ApiUser < User
|
||||||
after_initialize :set_defaults
|
after_initialize :set_defaults
|
||||||
def set_defaults
|
def set_defaults
|
||||||
return unless new_record?
|
return unless new_record?
|
||||||
self.active = true
|
self.active = true unless active_changed?
|
||||||
end
|
end
|
||||||
|
|
||||||
def registrar_typeahead
|
def registrar_typeahead
|
||||||
|
|
|
@ -32,10 +32,10 @@ class ApiUserDeprecated < ActiveRecord::Base
|
||||||
csr_file.rewind
|
csr_file.rewind
|
||||||
|
|
||||||
crt_file = Tempfile.new('client_crt')
|
crt_file = Tempfile.new('client_crt')
|
||||||
_out, err, _st = Open3.capture3("openssl ca -keyfile #{APP_CONFIG['ca_key_path']} \
|
_out, err, _st = Open3.capture3("openssl ca -keyfile #{ENV['ca_key_path']} \
|
||||||
-cert #{APP_CONFIG['ca_cert_path']} \
|
-cert #{ENV['ca_cert_path']} \
|
||||||
-extensions usr_cert -notext -md sha256 \
|
-extensions usr_cert -notext -md sha256 \
|
||||||
-in #{csr_file.path} -out #{crt_file.path} -key '#{APP_CONFIG['ca_key_password']}' -batch")
|
-in #{csr_file.path} -out #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
|
||||||
|
|
||||||
if err.match(/Data Base Updated/)
|
if err.match(/Data Base Updated/)
|
||||||
crt_file.rewind
|
crt_file.rewind
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Certificate < ActiveRecord::Base
|
||||||
@cached_status = EXPIRED
|
@cached_status = EXPIRED
|
||||||
end
|
end
|
||||||
|
|
||||||
crl = OpenSSL::X509::CRL.new(File.open(APP_CONFIG['crl_path']).read)
|
crl = OpenSSL::X509::CRL.new(File.open(ENV['crl_path']).read)
|
||||||
return @cached_status unless crl.revoked.map(&:serial).include?(parsed_crt.serial)
|
return @cached_status unless crl.revoked.map(&:serial).include?(parsed_crt.serial)
|
||||||
|
|
||||||
@cached_status = REVOKED
|
@cached_status = REVOKED
|
||||||
|
@ -45,10 +45,10 @@ class Certificate < ActiveRecord::Base
|
||||||
csr_file.rewind
|
csr_file.rewind
|
||||||
|
|
||||||
crt_file = Tempfile.new('client_crt')
|
crt_file = Tempfile.new('client_crt')
|
||||||
_out, err, _st = Open3.capture3("openssl ca -keyfile #{APP_CONFIG['ca_key_path']} \
|
_out, err, _st = Open3.capture3("openssl ca -keyfile #{ENV['ca_key_path']} \
|
||||||
-cert #{APP_CONFIG['ca_cert_path']} \
|
-cert #{ENV['ca_cert_path']} \
|
||||||
-extensions usr_cert -notext -md sha256 \
|
-extensions usr_cert -notext -md sha256 \
|
||||||
-in #{csr_file.path} -out #{crt_file.path} -key '#{APP_CONFIG['ca_key_password']}' -batch")
|
-in #{csr_file.path} -out #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
|
||||||
|
|
||||||
if err.match(/Data Base Updated/)
|
if err.match(/Data Base Updated/)
|
||||||
crt_file.rewind
|
crt_file.rewind
|
||||||
|
@ -67,9 +67,9 @@ class Certificate < ActiveRecord::Base
|
||||||
crt_file.write(crt)
|
crt_file.write(crt)
|
||||||
crt_file.rewind
|
crt_file.rewind
|
||||||
|
|
||||||
_out, err, _st = Open3.capture3("openssl ca -keyfile #{APP_CONFIG['ca_key_path']} \
|
_out, err, _st = Open3.capture3("openssl ca -keyfile #{ENV['ca_key_path']} \
|
||||||
-cert #{APP_CONFIG['ca_cert_path']} \
|
-cert #{ENV['ca_cert_path']} \
|
||||||
-revoke #{crt_file.path} -key '#{APP_CONFIG['ca_key_password']}' -batch")
|
-revoke #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
|
||||||
|
|
||||||
if err.match(/Data Base Updated/) || err.match(/ERROR:Already revoked/)
|
if err.match(/Data Base Updated/) || err.match(/ERROR:Already revoked/)
|
||||||
save!
|
save!
|
||||||
|
@ -81,8 +81,8 @@ class Certificate < ActiveRecord::Base
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
_out, _err, _st = Open3.capture3("openssl ca -keyfile #{APP_CONFIG['ca_key_path']} \
|
_out, _err, _st = Open3.capture3("openssl ca -keyfile #{ENV['ca_key_path']} \
|
||||||
-cert #{APP_CONFIG['ca_cert_path']} \
|
-cert #{ENV['ca_cert_path']} \
|
||||||
-gencrl -out #{APP_CONFIG['crl_path']} -key '#{APP_CONFIG['ca_key_password']}' -batch")
|
-gencrl -out #{ENV['crl_path']} -key '#{ENV['ca_key_password']}' -batch")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,42 +3,43 @@ module EppErrors
|
||||||
|
|
||||||
def construct_epp_errors
|
def construct_epp_errors
|
||||||
epp_errors = []
|
epp_errors = []
|
||||||
errors.messages.each do |key, values|
|
errors.messages.each do |attr, errors|
|
||||||
key = key.to_s.split('.')[0].to_sym
|
attr = attr.to_s.split('.')[0].to_sym
|
||||||
next if key == :epp_errors
|
next if attr == :epp_errors
|
||||||
|
|
||||||
if self.class.reflect_on_association(key)
|
if self.class.reflect_on_association(attr)
|
||||||
epp_errors << collect_child_errors(key)
|
epp_errors << collect_child_errors(attr)
|
||||||
end
|
end
|
||||||
|
|
||||||
epp_errors << collect_parent_errors(values)
|
epp_errors << collect_parent_errors(attr, errors)
|
||||||
end
|
end
|
||||||
|
|
||||||
errors[:epp_errors] = epp_errors
|
errors[:epp_errors] = epp_errors
|
||||||
errors[:epp_errors].flatten!
|
errors[:epp_errors].flatten!
|
||||||
end
|
end
|
||||||
|
|
||||||
def collect_parent_errors(values)
|
def collect_parent_errors(attr, errors)
|
||||||
epp_errors = []
|
errors = [errors] if errors.is_a?(String)
|
||||||
values = [values] if values.is_a?(String)
|
|
||||||
|
|
||||||
values.each do |err|
|
epp_errors = []
|
||||||
|
errors.each do |err|
|
||||||
code, value = find_epp_code_and_value(err)
|
code, value = find_epp_code_and_value(err)
|
||||||
next unless code
|
next unless code
|
||||||
epp_errors << { code: code, msg: err, value: value }
|
msg = attr.to_sym == :base ? err : "#{err} [#{attr}]"
|
||||||
|
epp_errors << { code: code, msg: msg, value: value }
|
||||||
end
|
end
|
||||||
epp_errors
|
epp_errors
|
||||||
end
|
end
|
||||||
|
|
||||||
def collect_child_errors(key)
|
def collect_child_errors(attr)
|
||||||
macro = self.class.reflect_on_association(key).macro
|
macro = self.class.reflect_on_association(attr).macro
|
||||||
multi = [:has_and_belongs_to_many, :has_many]
|
multi = [:has_and_belongs_to_many, :has_many]
|
||||||
# single = [:belongs_to, :has_one]
|
# single = [:belongs_to, :has_one]
|
||||||
|
|
||||||
epp_errors = []
|
epp_errors = []
|
||||||
send(key).each do |x|
|
send(attr).each do |x|
|
||||||
x.errors.messages.each do |_key, values|
|
x.errors.messages.each do |attribute, errors|
|
||||||
epp_errors << x.collect_parent_errors(values)
|
epp_errors << x.collect_parent_errors(attribute, errors)
|
||||||
end
|
end
|
||||||
end if multi.include?(macro)
|
end if multi.include?(macro)
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,11 @@ class Contact < ActiveRecord::Base
|
||||||
format: { with: /\d{4}-\d{2}-\d{2}/, message: :invalid_birthday_format },
|
format: { with: /\d{4}-\d{2}-\d{2}/, message: :invalid_birthday_format },
|
||||||
if: proc { |c| c.ident_type == 'birthday' }
|
if: proc { |c| c.ident_type == 'birthday' }
|
||||||
validates :ident_country_code, presence: true, if: proc { |c| %w(bic priv).include? c.ident_type }
|
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?
|
validate :ident_valid_format?
|
||||||
|
|
||||||
delegate :street, to: :address
|
delegate :street, to: :address
|
||||||
|
@ -99,15 +103,27 @@ class Contact < ActiveRecord::Base
|
||||||
ident_type != IDENT_TYPE_BIC
|
ident_type != IDENT_TYPE_BIC
|
||||||
end
|
end
|
||||||
|
|
||||||
# generate random id for contact
|
|
||||||
def generate_code
|
def generate_code
|
||||||
self.code = SecureRandom.hex(4)
|
self.code = SecureRandom.hex(4) if code.blank?
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_auth_info
|
def generate_auth_info
|
||||||
|
return if @generate_auth_info_disabled
|
||||||
self.auth_info = SecureRandom.hex(16)
|
self.auth_info = SecureRandom.hex(16)
|
||||||
end
|
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
|
# Find a way to use self.domains with contact
|
||||||
def domains_owned
|
def domains_owned
|
||||||
Domain.where(owner_contact_id: id)
|
Domain.where(owner_contact_id: id)
|
||||||
|
|
|
@ -45,9 +45,22 @@ class Epp::Contact < Contact
|
||||||
# rubocop: enable Metrics/PerceivedComplexity
|
# rubocop: enable Metrics/PerceivedComplexity
|
||||||
# rubocop: enable Metrics/CyclomaticComplexity
|
# rubocop: enable Metrics/CyclomaticComplexity
|
||||||
|
|
||||||
def new(frame)
|
def new(frame, registrar)
|
||||||
return super if frame.blank?
|
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
|
end
|
||||||
|
|
||||||
def legal_document_attrs(legal_frame)
|
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, :country_code, :email, presence: true
|
||||||
validates :name, :reg_no, uniqueness: true
|
validates :name, :reg_no, uniqueness: true
|
||||||
|
validate :set_code, if: :new_record?
|
||||||
after_save :touch_domains_version
|
after_save :touch_domains_version
|
||||||
|
|
||||||
validates :email, :billing_email, format: /@/, allow_blank: true
|
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
|
def domain_transfers
|
||||||
at = DomainTransfer.arel_table
|
at = DomainTransfer.arel_table
|
||||||
DomainTransfer.where(
|
DomainTransfer.where(
|
||||||
|
@ -34,10 +42,23 @@ class Registrar < ActiveRecord::Base
|
||||||
Country.new(country_code)
|
Country.new(country_code)
|
||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
def code=(code)
|
||||||
def search_by_query(query)
|
self[:code] = code if new_record?
|
||||||
res = search(name_or_reg_no_cont: query).result
|
end
|
||||||
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v[:name]} (#{v[:reg_no]})" } }
|
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,7 +18,7 @@ class ZonefileSetting < ActiveRecord::Base
|
||||||
"select generate_zonefile('#{origin}')"
|
"select generate_zonefile('#{origin}')"
|
||||||
)[0]['generate_zonefile']
|
)[0]['generate_zonefile']
|
||||||
|
|
||||||
File.open("#{APP_CONFIG['zonefile_export_dir']}/#{filename}", 'w') { |f| f.write(zf) }
|
File.open("#{ENV['zonefile_export_dir']}/#{filename}", 'w') { |f| f.write(zf) }
|
||||||
|
|
||||||
STDOUT << "#{Time.now.utc} - Successfully generated zonefile #{filename}\n"
|
STDOUT << "#{Time.now.utc} - Successfully generated zonefile #{filename}\n"
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
%span.icon-bar
|
%span.icon-bar
|
||||||
%span.icon-bar
|
%span.icon-bar
|
||||||
= link_to admin_dashboard_path, class: 'navbar-brand' do
|
= link_to admin_dashboard_path, class: 'navbar-brand' do
|
||||||
= APP_CONFIG['app_name']
|
= ENV['app_name']
|
||||||
- if unstable_env.present?
|
- if unstable_env.present?
|
||||||
.text-center
|
.text-center
|
||||||
%small{style: 'color: #0074B3;'}= unstable_env
|
%small{style: 'color: #0074B3;'}= unstable_env
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# For docker
|
|
||||||
#
|
|
||||||
|
|
||||||
# cd to Rails root directory
|
|
||||||
cd "$(dirname "$0")"; cd ..
|
|
||||||
|
|
||||||
bin/update-repo
|
|
||||||
bin/robot
|
|
16
bin/robot
16
bin/robot
|
@ -16,14 +16,14 @@ export RAILS_ENV=test
|
||||||
cd "$(dirname "$0")"; cd ..
|
cd "$(dirname "$0")"; cd ..
|
||||||
|
|
||||||
cp config/application-example.yml config/application.yml
|
cp config/application-example.yml config/application.yml
|
||||||
# create manually config/database.yml
|
cp config/secrets-example.yml config/secrets.yml
|
||||||
|
cp config/database-robot.yml config/database.yml
|
||||||
|
|
||||||
|
# under jenkins use rbenv-plugin wrapper
|
||||||
bundle install
|
bundle install
|
||||||
|
|
||||||
RAILS_ENV=test bundle exec rake db:drop
|
RAILS_ENV=test bundle exec rake db:all:drop
|
||||||
RAILS_ENV=test bundle exec rake db:all:create
|
RAILS_ENV=test bundle exec rake db:all:setup
|
||||||
RAILS_ENV=test bundle exec rake db:all:schema:load
|
|
||||||
RAILS_ENV=test bundle exec rake db:seed
|
|
||||||
RAILS_ENV=test bundle exec rake assets:precompile
|
RAILS_ENV=test bundle exec rake assets:precompile
|
||||||
|
|
||||||
echo "GIT_LAST_COMMITS"
|
echo "GIT_LAST_COMMITS"
|
||||||
|
@ -36,6 +36,10 @@ RCODE=$?
|
||||||
echo "END_OF_RUBOCOP_RESULTS"
|
echo "END_OF_RUBOCOP_RESULTS"
|
||||||
|
|
||||||
echo "TEST_RESULTS"
|
echo "TEST_RESULTS"
|
||||||
|
# basic test
|
||||||
|
# ROBOT=true bundle exec rake
|
||||||
|
|
||||||
|
# all tests with EPP
|
||||||
ROBOT=true bundle exec rake test
|
ROBOT=true bundle exec rake test
|
||||||
TCODE=$?
|
TCODE=$?
|
||||||
echo "END_OF_TEST_RESULTS"
|
echo "END_OF_TEST_RESULTS"
|
||||||
|
@ -45,7 +49,7 @@ bundle exec bundle-audit update
|
||||||
bundle exec bundle-audit
|
bundle exec bundle-audit
|
||||||
BCODE=$?
|
BCODE=$?
|
||||||
BCODE=0 # tmp
|
BCODE=0 # tmp
|
||||||
bundle exec brakeman
|
bundle exec brakeman -q
|
||||||
echo "END_OF_SECURITY_RESULTS"
|
echo "END_OF_SECURITY_RESULTS"
|
||||||
|
|
||||||
# update code review
|
# update code review
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
defaults: &defaults
|
# Be sure to restart your server when you modify settings.
|
||||||
|
|
||||||
app_name: .EE Registry
|
app_name: .EE Registry
|
||||||
zonefile_export_dir: 'export/zonefiles'
|
zonefile_export_dir: 'export/zonefiles'
|
||||||
|
|
||||||
|
@ -8,26 +9,20 @@ defaults: &defaults
|
||||||
secret_key_base: please-change-it-you-can-generate-it-with-rake-secret
|
secret_key_base: please-change-it-you-can-generate-it-with-rake-secret
|
||||||
devise_secret: please-change-it-you-can-generate-it-with-rake-secret
|
devise_secret: please-change-it-you-can-generate-it-with-rake-secret
|
||||||
|
|
||||||
# Used by registry admin server:
|
# Used by admin server, you can leave those empty for when running EPP server:
|
||||||
crl_path: '/home/registry/registry/shared/ca/crl/crl.pem'
|
crl_path: '/home/registry/registry/shared/ca/crl/crl.pem'
|
||||||
ca_cert_path: '/home/registry/registry/shared/ca/certs/ca.crt.pem'
|
ca_cert_path: '/home/registry/registry/shared/ca/certs/ca.crt.pem'
|
||||||
ca_key_path: '/home/registry/registry/shared/ca/private/ca.key.pem'
|
ca_key_path: '/home/registry/registry/shared/ca/private/ca.key.pem'
|
||||||
ca_key_password: 'your-root-key-password'
|
ca_key_password: 'your-root-key-password'
|
||||||
|
|
||||||
# Used by EPP server
|
# Used only by EPP server, you can leave it empty when running admin server:
|
||||||
webclient_ip: '54.154.91.240'
|
webclient_ip: '127.0.0.1'
|
||||||
|
|
||||||
development:
|
|
||||||
<<: *defaults
|
|
||||||
|
|
||||||
|
# autotest config overwrites
|
||||||
test:
|
test:
|
||||||
<<: *defaults
|
webclient_ip: '127.0.0.1' # it should match to localhost ip address
|
||||||
|
crl_path: '/var/lib/jenkins/workspace/registry/ca/crl/crl.pem'
|
||||||
|
ca_cert_path: '/var/lib/jenkins/workspace/registry/ca/certs/ca.crt.pem'
|
||||||
|
ca_key_path: '/var/lib/jenkins/workspace/registry/ca/private/ca.key.pem'
|
||||||
|
ca_key_password: 'test'
|
||||||
|
|
||||||
alpha:
|
|
||||||
<<: *defaults
|
|
||||||
|
|
||||||
staging:
|
|
||||||
<<: *defaults
|
|
||||||
|
|
||||||
production:
|
|
||||||
<<: *defaults
|
|
||||||
|
|
19
config/database-robot.yml
Normal file
19
config/database-robot.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
default: &default
|
||||||
|
host: localhost
|
||||||
|
adapter: postgresql
|
||||||
|
encoding: unicode
|
||||||
|
pool: 5
|
||||||
|
username: test
|
||||||
|
password: test
|
||||||
|
|
||||||
|
test:
|
||||||
|
<<: *default
|
||||||
|
database: registry_test
|
||||||
|
|
||||||
|
whois_test:
|
||||||
|
<<: *default
|
||||||
|
database: registry_whois_test
|
||||||
|
|
||||||
|
api_log_test:
|
||||||
|
<<: *default
|
||||||
|
database: registry_api_log_test
|
|
@ -1,2 +0,0 @@
|
||||||
APP_CONFIG = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env]
|
|
||||||
Registry::Application.config.secret_token = APP_CONFIG['secret_key_base']
|
|
|
@ -4,7 +4,7 @@ Devise.setup do |config|
|
||||||
# The secret key used by Devise. Devise uses this key to generate
|
# The secret key used by Devise. Devise uses this key to generate
|
||||||
# random tokens. Changing this key will render invalid all existing
|
# random tokens. Changing this key will render invalid all existing
|
||||||
# confirmation, reset password and unlock tokens in the database.
|
# confirmation, reset password and unlock tokens in the database.
|
||||||
config.secret_key = APP_CONFIG['devise_secret']
|
config.secret_key = ENV['devise_secret']
|
||||||
|
|
||||||
# ==> Mailer Configuration
|
# ==> Mailer Configuration
|
||||||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||||
|
|
13
config/initializers/env_required.rb
Normal file
13
config/initializers/env_required.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
required = %w(
|
||||||
|
app_name
|
||||||
|
zonefile_export_dir
|
||||||
|
secret_key_base
|
||||||
|
devise_secret
|
||||||
|
crl_path
|
||||||
|
ca_cert_path
|
||||||
|
ca_key_path
|
||||||
|
ca_key_password
|
||||||
|
webclient_ip
|
||||||
|
)
|
||||||
|
|
||||||
|
Figaro.require_keys(required)
|
|
@ -1,4 +1,5 @@
|
||||||
if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('settings') # otherwise rake not working 100%
|
# otherwise rake not working 100%
|
||||||
|
if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('settings')
|
||||||
Setting.disclosure_name = true if Setting.disclosure_name.nil?
|
Setting.disclosure_name = true if Setting.disclosure_name.nil?
|
||||||
Setting.disclosure_name = true if Setting.disclosure_name.nil?
|
Setting.disclosure_name = true if Setting.disclosure_name.nil?
|
||||||
Setting.disclosure_org_name = true if Setting.disclosure_org_name.nil?
|
Setting.disclosure_org_name = true if Setting.disclosure_org_name.nil?
|
||||||
|
|
1
config/initializers/set_secret.rb
Normal file
1
config/initializers/set_secret.rb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Registry::Application.config.secret_token = ENV['secret_key_base']
|
|
@ -0,0 +1,5 @@
|
||||||
|
class ChangeApiUserDefaultValue < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
change_column_default :users, :active, nil
|
||||||
|
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
db/migrate/20150303151224_data_update_regisntrar_codes.rb
Normal file
11
db/migrate/20150303151224_data_update_regisntrar_codes.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class DataUpdateRegisntrarCodes < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
puts 'Registrar code updates:'
|
||||||
|
Registrar.all.each do |r|
|
||||||
|
next if r.code.present?
|
||||||
|
r[:code] = r.name.parameterize
|
||||||
|
puts "#{r.id}: #{r.changes.inspect}"
|
||||||
|
r.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20150223104842) do
|
ActiveRecord::Schema.define(version: 20150303151224) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -611,8 +611,11 @@ ActiveRecord::Schema.define(version: 20150223104842) do
|
||||||
t.string "city"
|
t.string "city"
|
||||||
t.string "street"
|
t.string "street"
|
||||||
t.string "zip"
|
t.string "zip"
|
||||||
|
t.string "code"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_index "registrars", ["code"], name: "index_registrars_on_code", using: :btree
|
||||||
|
|
||||||
create_table "reserved_domains", force: :cascade do |t|
|
create_table "reserved_domains", force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
|
@ -652,7 +655,7 @@ ActiveRecord::Schema.define(version: 20150223104842) do
|
||||||
t.string "updator_str"
|
t.string "updator_str"
|
||||||
t.string "country_code"
|
t.string "country_code"
|
||||||
t.integer "registrar_id"
|
t.integer "registrar_id"
|
||||||
t.boolean "active", default: false
|
t.boolean "active"
|
||||||
t.text "csr"
|
t.text "csr"
|
||||||
t.text "crt"
|
t.text "crt"
|
||||||
t.string "type"
|
t.string "type"
|
||||||
|
|
|
@ -1,7 +1,48 @@
|
||||||
### Application build and update
|
Application build and update
|
||||||
|
----------------------------
|
||||||
|
|
||||||
For application deployment we are using faster [Mina](https://github.com/mina-deploy/mina)
|
### Debian setup
|
||||||
instead of Capistrano.
|
|
||||||
|
* [Debian build](/doc/debian_build_doc.md)
|
||||||
|
|
||||||
|
|
||||||
|
### Certificates setup
|
||||||
|
|
||||||
|
* [Certificates setup](/doc/certificates.md)
|
||||||
|
|
||||||
|
|
||||||
|
### Production env setup
|
||||||
|
|
||||||
|
For production you probably would like to create databases to your locale, example:
|
||||||
|
|
||||||
|
create database registry_production owner registry encoding 'UTF-8' LC_COLLATE 'et_EE.utf8' LC_CTYPE 'et_EE.utf8' template template0;
|
||||||
|
|
||||||
|
Deploy overview: (database schema should be loaded and seeds should be present)
|
||||||
|
|
||||||
|
# at your local machine
|
||||||
|
git clone git@github.com:internetee/registry.git
|
||||||
|
cd registry
|
||||||
|
rbenv local 2.2.0 # more info about rbenv at debian doc
|
||||||
|
gem install mina
|
||||||
|
mina pr setup # one time, only creates missing directories
|
||||||
|
ssh registry
|
||||||
|
|
||||||
|
# at your server
|
||||||
|
cd registry
|
||||||
|
cp current/config/application-example.yml shared/config/application.yml # and edit it
|
||||||
|
cp current/config/database-example.yml shared/config/database.yml # and edit it
|
||||||
|
|
||||||
|
vi /etc/apache2/sites-enabled/registry.conf # add conf and all needed serts
|
||||||
|
vi /etc/apache2/sites-enabled/epp.conf # add epp conf, restart apache
|
||||||
|
exit
|
||||||
|
# at your local machine
|
||||||
|
mina pr deploy # this is command you use in every application code update
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Deploy script setup
|
||||||
|
|
||||||
|
We recommend [Mina](https://github.com/mina-deploy/mina) instead of Capistrano for deployment.
|
||||||
|
|
||||||
All deploy code locates at config/deploy.rb file.
|
All deploy code locates at config/deploy.rb file.
|
||||||
|
|
||||||
|
@ -68,3 +109,13 @@ General rake and mina tips:
|
||||||
rake -T # list all rake commands
|
rake -T # list all rake commands
|
||||||
rake -T db # list all database related commands
|
rake -T db # list all database related commands
|
||||||
mina -T # list all mina deploy commands
|
mina -T # list all mina deploy commands
|
||||||
|
|
||||||
|
|
||||||
|
CRON
|
||||||
|
----
|
||||||
|
|
||||||
|
Crontab can be setup after deploy. Jobs can be viewed [here](/config/schedule.rb).
|
||||||
|
|
||||||
|
mina pr cron:setup # to update the crontab.
|
||||||
|
mina pr cron:clear # to clear crontab.
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,16 @@ Private key and certificate must be packaged to pkcs12 and added to user browser
|
||||||
|
|
||||||
### Registry setup
|
### Registry setup
|
||||||
|
|
||||||
|
Setup CA directory in shared directory:
|
||||||
|
|
||||||
|
cd /home/registry/registry/shared
|
||||||
|
mkdir ca ca/certs ca/crl ca/newcerts ca/private ca/csrs
|
||||||
|
cd ca
|
||||||
|
chmod 700 private
|
||||||
|
touch index.txt
|
||||||
|
echo 1000 > serial
|
||||||
|
echo 1000 > crlnumber
|
||||||
|
|
||||||
Configure OpenSSL:
|
Configure OpenSSL:
|
||||||
|
|
||||||
sudo cp /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.bak
|
sudo cp /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.bak
|
||||||
|
@ -53,17 +63,6 @@ Make sure the following options are in place:
|
||||||
basicConstraints = CA:true # around line nr 240
|
basicConstraints = CA:true # around line nr 240
|
||||||
keyUsage = cRLSign, keyCertSign # around line nr 245
|
keyUsage = cRLSign, keyCertSign # around line nr 245
|
||||||
|
|
||||||
Setup CA directory in shared directory:
|
|
||||||
|
|
||||||
cd /home/registry/registry/shared
|
|
||||||
mkdir ca
|
|
||||||
cd ca
|
|
||||||
mkdir certs crl newcerts private csrs
|
|
||||||
chmod 700 private
|
|
||||||
touch index.txt
|
|
||||||
echo 1000 > serial
|
|
||||||
echo 1000 > crlnumber
|
|
||||||
|
|
||||||
Generate the root key and remember your password, you need it later in application.yml:
|
Generate the root key and remember your password, you need it later in application.yml:
|
||||||
|
|
||||||
openssl genrsa -aes256 -out private/ca.key.pem 4096
|
openssl genrsa -aes256 -out private/ca.key.pem 4096
|
||||||
|
@ -90,10 +89,10 @@ Create certificate revocation list (prompts for pass phrase):
|
||||||
|
|
||||||
Configure registry registry/shared/config/application.yml to match the CA settings:
|
Configure registry registry/shared/config/application.yml to match the CA settings:
|
||||||
|
|
||||||
|
crl_path: '/home/registry/registry/shared/ca/crl/crl.pem'
|
||||||
ca_cert_path: '/home/registry/registry/shared/ca/certs/ca.crt.pem'
|
ca_cert_path: '/home/registry/registry/shared/ca/certs/ca.crt.pem'
|
||||||
ca_key_path: '/home/registry/registry/shared/ca/private/ca.key.pem'
|
ca_key_path: '/home/registry/registry/shared/ca/private/ca.key.pem'
|
||||||
ca_key_password: 'your-root-key-password'
|
ca_key_password: 'your-root-key-password'
|
||||||
crl_path: '/home/registry/registry/shared/ca/crl/crl.pem'
|
|
||||||
|
|
||||||
|
|
||||||
### Registry EPP setup
|
### Registry EPP setup
|
||||||
|
@ -162,6 +161,29 @@ Reload apache:
|
||||||
sudo /etc/init.d/apache2 restart
|
sudo /etc/init.d/apache2 restart
|
||||||
|
|
||||||
|
|
||||||
|
### ApiUser browser setup
|
||||||
|
|
||||||
|
In short:
|
||||||
|
|
||||||
|
* Upload CSR file to api user at admin page /admin/api_users
|
||||||
|
* Sign it
|
||||||
|
* Generate p12 file and install into user browser
|
||||||
|
|
||||||
|
#### Creating CSR file
|
||||||
|
|
||||||
|
openssl genrsa -out private/api-user.key.pem 4096
|
||||||
|
chmod 400 private/api-user.key.pem
|
||||||
|
openssl req -sha256 -new -days 3653 -key private/api-user.key.pem -out csrs/api-user.csr.pem
|
||||||
|
|
||||||
|
Upload api-user.csr.pem file to api user at admin interface.
|
||||||
|
Sign it
|
||||||
|
Download CRT file and create p12 file.
|
||||||
|
|
||||||
|
openssl pkcs12 -export -inkey private/api-user.key.pem -in certs/api-user.crt.pem -out pkcs/api_user.p12
|
||||||
|
|
||||||
|
Add api_user.p12 to your browser.
|
||||||
|
|
||||||
|
|
||||||
Development env
|
Development env
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
## Contact related functions
|
## Contact related functions
|
||||||
|
|
||||||
Please study official Cantact Mapping protocol:
|
Please study official Contact Mapping protocol:
|
||||||
http://tools.ietf.org/html/rfc5733
|
http://tools.ietf.org/html/rfc5733
|
||||||
|
|
||||||
More info at http://en.wikipedia.org/wiki/Extensible_Provisioning_Protocol
|
More info at http://en.wikipedia.org/wiki/Extensible_Provisioning_Protocol
|
||||||
|
@ -13,6 +13,7 @@ Contact Mapping protocol short version:
|
||||||
----------------------- ------- -----------------
|
----------------------- ------- -----------------
|
||||||
<create> 1
|
<create> 1
|
||||||
<contact:create> 1 Attribute: xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"
|
<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:postalInfo> 1 Postal information container
|
||||||
<contact:name> 1 Full name of the contact
|
<contact:name> 1 Full name of the contact
|
||||||
<contact:org> 0-1 Name of organization
|
<contact:org> 0-1 Name of organization
|
||||||
|
@ -42,7 +43,7 @@ Contact Mapping protocol short version:
|
||||||
----------------------- ------- -----------------
|
----------------------- ------- -----------------
|
||||||
<update> 1
|
<update> 1
|
||||||
<contact:update> 1 Attribute: xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"
|
<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:chg> 1 Change container
|
||||||
<contact:postalInfo> 1 Postal information container
|
<contact:postalInfo> 1 Postal information container
|
||||||
<contact:name> 0-1 Full name of the contact
|
<contact:name> 0-1 Full name of the contact
|
||||||
|
|
114
doc/testing.md
Normal file
114
doc/testing.md
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
Testing
|
||||||
|
-------
|
||||||
|
|
||||||
|
Setup test databases:
|
||||||
|
|
||||||
|
RAILS_ENV=test rake db:all:setup
|
||||||
|
|
||||||
|
Run basic test (no EPP tests):
|
||||||
|
|
||||||
|
rake
|
||||||
|
|
||||||
|
|
||||||
|
Testing EPP
|
||||||
|
===========
|
||||||
|
|
||||||
|
In order to test EPP, you have to configure apache to handle EPP request correctly.
|
||||||
|
|
||||||
|
### Apache site config
|
||||||
|
|
||||||
|
First you should have mod_epp installed, please follow main README for doing it.
|
||||||
|
|
||||||
|
Apache site config for autotest, add file to /etc/apache2/sites-enabled/epp-autotest.conf
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<IfModule mod_epp.c>
|
||||||
|
Listen 701
|
||||||
|
<VirtualHost *:701>
|
||||||
|
SSLEngine on
|
||||||
|
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
|
||||||
|
SSLCertificateFile /etc/apache2/ssl/apache.crt
|
||||||
|
SSLCertificateKeyFile /etc/apache2/ssl/apache.key
|
||||||
|
|
||||||
|
SSLVerifyClient optional_no_ca
|
||||||
|
|
||||||
|
EPPEngine On
|
||||||
|
EPPCommandRoot /proxy/command
|
||||||
|
EPPSessionRoot /proxy/session
|
||||||
|
EPPErrorRoot /proxy/error
|
||||||
|
EPPRawFrame raw_frame
|
||||||
|
|
||||||
|
ProxyPass /proxy/ http://localhost:8989/epp/
|
||||||
|
|
||||||
|
EPPAuthURI implicit
|
||||||
|
EPPReturncodeHeader X-EPP-Returncode
|
||||||
|
</VirtualHost>
|
||||||
|
</IfModule>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* Run all tests with temp server running automatically on port 8989:
|
||||||
|
|
||||||
|
rake test
|
||||||
|
|
||||||
|
|
||||||
|
Manual debugging
|
||||||
|
================
|
||||||
|
|
||||||
|
### Apache mod_epp manual debugging
|
||||||
|
|
||||||
|
Debugging Apache mod_epp without Registry app.
|
||||||
|
|
||||||
|
sudo apt-get install apache2-dbg
|
||||||
|
|
||||||
|
Includes htpasswd command to generate authentication files
|
||||||
|
|
||||||
|
sudo apt-get install apache2-utils
|
||||||
|
|
||||||
|
For manual debugging purposes, standalone CGI scripts can be used:
|
||||||
|
This needs a static greeting file, so you will have to make /var/www writable.
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<IfModule mod_epp.c>
|
||||||
|
<Directory "/usr/lib/cgi-bin/epp">
|
||||||
|
Options ExecCGI
|
||||||
|
SetHandler cgi-script
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
Listen 1700
|
||||||
|
|
||||||
|
<VirtualHost *:1700>
|
||||||
|
EPPEngine On
|
||||||
|
EPPCommandRoot /cgi-bin/epp/command
|
||||||
|
EPPSessionRoot /cgi-bin/epp/session
|
||||||
|
EPPErrorRoot /cgi-bin/epp/error
|
||||||
|
|
||||||
|
Alias /cgi-bin/epp/session/hello /var/www/html/epp/session-hello
|
||||||
|
|
||||||
|
Alias /cgi-bin/epp/session/login /usr/lib/cgi-bin/epp/session-login
|
||||||
|
Alias /cgi-bin/epp/session/logout /usr/lib/cgi-bin/epp/session-logout
|
||||||
|
Alias /cgi-bin/epp/error/schema /usr/lib/cgi-bin/epp/error-schema
|
||||||
|
Alias /cgi-bin/epp/command/create /usr/lib/cgi-bin/epp/create
|
||||||
|
Alias /cgi-bin/epp/command/info /usr/lib/cgi-bin/epp/info
|
||||||
|
|
||||||
|
EPPAuthURI /epp/auth/login
|
||||||
|
<Location /epp/auth>
|
||||||
|
AuthType Basic
|
||||||
|
AuthName "EPP"
|
||||||
|
AuthUserFile /etc/apache2/htpasswd
|
||||||
|
require valid-user
|
||||||
|
</Location>
|
||||||
|
</VirtualHost>
|
||||||
|
</IfModule>
|
||||||
|
```
|
||||||
|
|
||||||
|
sudo a2enmod cgi
|
||||||
|
sudo a2enmod authn_file # will be used for non implicit authentication URIs
|
||||||
|
sudo htpasswd -c /etc/apache2/htpasswd test
|
||||||
|
Type "test" when prompted
|
||||||
|
cd /usr/lib/cgi-bin
|
||||||
|
mkdir epp
|
||||||
|
|
||||||
|
Copy the files from $mod_epp/examples/cgis to /usr/lib/cgi-bin/epp
|
||||||
|
|
|
@ -13,10 +13,8 @@ describe 'EPP Contact', epp: true do
|
||||||
|
|
||||||
login_as :registrar1
|
login_as :registrar1
|
||||||
|
|
||||||
Contact.skip_callback(:create, :before, :generate_code)
|
|
||||||
Contact.skip_callback(:create, :before, :generate_auth_info)
|
|
||||||
|
|
||||||
@contact = Fabricate(:contact, registrar: @registrar1)
|
@contact = Fabricate(:contact, registrar: @registrar1)
|
||||||
|
|
||||||
@legal_document = {
|
@legal_document = {
|
||||||
legalDocument: {
|
legalDocument: {
|
||||||
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
|
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
|
||||||
|
@ -25,11 +23,6 @@ describe 'EPP Contact', epp: true do
|
||||||
}
|
}
|
||||||
end
|
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 'with valid user' do
|
||||||
context 'create command' do
|
context 'create command' do
|
||||||
def create_request(overwrites = {})
|
def create_request(overwrites = {})
|
||||||
|
@ -53,19 +46,19 @@ describe 'EPP Contact', epp: true do
|
||||||
it 'fails if request xml is missing' do
|
it 'fails if request xml is missing' do
|
||||||
response = epp_plain_request(@epp_xml.create, :xml)
|
response = epp_plain_request(@epp_xml.create, :xml)
|
||||||
response[:results][0][:msg].should ==
|
response[:results][0][:msg].should ==
|
||||||
'Required parameter missing: create > create > postalInfo > name'
|
'Required parameter missing: create > create > postalInfo > name [name]'
|
||||||
response[:results][1][:msg].should ==
|
response[:results][1][:msg].should ==
|
||||||
'Required parameter missing: create > create > postalInfo > addr > city'
|
'Required parameter missing: create > create > postalInfo > addr > city [city]'
|
||||||
response[:results][2][:msg].should ==
|
response[:results][2][:msg].should ==
|
||||||
'Required parameter missing: create > create > postalInfo > addr > cc'
|
'Required parameter missing: create > create > postalInfo > addr > cc [cc]'
|
||||||
response[:results][3][:msg].should ==
|
response[:results][3][:msg].should ==
|
||||||
'Required parameter missing: create > create > ident'
|
'Required parameter missing: create > create > ident [ident]'
|
||||||
response[:results][4][:msg].should ==
|
response[:results][4][:msg].should ==
|
||||||
'Required parameter missing: create > create > voice'
|
'Required parameter missing: create > create > voice [voice]'
|
||||||
response[:results][5][:msg].should ==
|
response[:results][5][:msg].should ==
|
||||||
'Required parameter missing: create > create > email'
|
'Required parameter missing: create > create > email [email]'
|
||||||
response[:results][6][:msg].should ==
|
response[:results][6][:msg].should ==
|
||||||
'Required parameter missing: extension > extdata > legalDocument'
|
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||||
|
|
||||||
response[:results][0][:result_code].should == '2003'
|
response[:results][0][:result_code].should == '2003'
|
||||||
response[:results][1][:result_code].should == '2003'
|
response[:results][1][:result_code].should == '2003'
|
||||||
|
@ -133,6 +126,17 @@ describe 'EPP Contact', epp: true do
|
||||||
# 5 seconds for what-ever weird lag reasons might happen
|
# 5 seconds for what-ever weird lag reasons might happen
|
||||||
cr_date.text.to_time.should be_within(5).of(Time.now)
|
cr_date.text.to_time.should be_within(5).of(Time.now)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context 'update command' do
|
context 'update command' do
|
||||||
|
@ -140,11 +144,9 @@ describe 'EPP Contact', epp: true do
|
||||||
@contact =
|
@contact =
|
||||||
Fabricate(
|
Fabricate(
|
||||||
:contact,
|
:contact,
|
||||||
# created_by_id: 1,
|
|
||||||
registrar: @registrar1,
|
registrar: @registrar1,
|
||||||
email: 'not_updated@test.test',
|
email: 'not_updated@test.test',
|
||||||
code: 'sh8013',
|
code: 'sh8013'
|
||||||
auth_info: 'password'
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -177,13 +179,13 @@ describe 'EPP Contact', epp: true do
|
||||||
'Required parameter missing: add, rem or chg'
|
'Required parameter missing: add, rem or chg'
|
||||||
response[:results][0][:result_code].should == '2003'
|
response[:results][0][:result_code].should == '2003'
|
||||||
response[:results][1][:msg].should ==
|
response[:results][1][:msg].should ==
|
||||||
'Required parameter missing: update > update > id'
|
'Required parameter missing: update > update > id [id]'
|
||||||
response[:results][1][:result_code].should == '2003'
|
response[:results][1][:result_code].should == '2003'
|
||||||
response[:results][2][:msg].should ==
|
response[:results][2][:msg].should ==
|
||||||
'Required parameter missing: update > update > authInfo > pw'
|
'Required parameter missing: update > update > authInfo > pw [pw]'
|
||||||
response[:results][2][:result_code].should == '2003'
|
response[:results][2][:result_code].should == '2003'
|
||||||
response[:results][3][:msg].should ==
|
response[:results][3][:msg].should ==
|
||||||
'Required parameter missing: extension > extdata > legalDocument'
|
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||||
response[:results][3][:result_code].should == '2003'
|
response[:results][3][:result_code].should == '2003'
|
||||||
response[:results].count.should == 4
|
response[:results].count.should == 4
|
||||||
end
|
end
|
||||||
|
@ -221,11 +223,25 @@ describe 'EPP Contact', epp: true do
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
response[:results][0][:msg].should == 'Phone nr is invalid'
|
response[:results][0][:msg].should == 'Phone nr is invalid [phone]'
|
||||||
response[:results][0][:result_code].should == '2005'
|
response[:results][0][:result_code].should == '2005'
|
||||||
response[:results][1][:msg].should == 'Email is invalid'
|
response[:results][1][:msg].should == 'Email is invalid [email]'
|
||||||
response[:results][1][:result_code].should == '2005'
|
response[:results][1][:result_code].should == '2005'
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context 'delete command' do
|
context 'delete command' do
|
||||||
|
@ -246,13 +262,13 @@ describe 'EPP Contact', epp: true do
|
||||||
response = epp_plain_request(@epp_xml.delete, :xml)
|
response = epp_plain_request(@epp_xml.delete, :xml)
|
||||||
|
|
||||||
response[:results][0][:msg].should ==
|
response[:results][0][:msg].should ==
|
||||||
'Required parameter missing: delete > delete > id'
|
'Required parameter missing: delete > delete > id [id]'
|
||||||
response[:results][0][:result_code].should == '2003'
|
response[:results][0][:result_code].should == '2003'
|
||||||
response[:results][1][:msg].should ==
|
response[:results][1][:msg].should ==
|
||||||
'Required parameter missing: delete > delete > authInfo > pw'
|
'Required parameter missing: delete > delete > authInfo > pw [pw]'
|
||||||
response[:results][1][:result_code].should == '2003'
|
response[:results][1][:result_code].should == '2003'
|
||||||
response[:results][2][:msg].should ==
|
response[:results][2][:msg].should ==
|
||||||
'Required parameter missing: extension > extdata > legalDocument'
|
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||||
response[:results][2][:result_code].should == '2003'
|
response[:results][2][:result_code].should == '2003'
|
||||||
response[:results].count.should == 3
|
response[:results].count.should == 3
|
||||||
end
|
end
|
||||||
|
@ -278,7 +294,7 @@ describe 'EPP Contact', epp: true do
|
||||||
@domain.owner_contact.address.present?.should == true
|
@domain.owner_contact.address.present?.should == true
|
||||||
|
|
||||||
response = delete_request
|
response = delete_request
|
||||||
response[:msg].should == 'Object association prohibits operation'
|
response[:msg].should == 'Object association prohibits operation [domains]'
|
||||||
response[:result_code].should == '2305'
|
response[:result_code].should == '2305'
|
||||||
response[:results].count.should == 1
|
response[:results].count.should == 1
|
||||||
|
|
||||||
|
@ -308,7 +324,7 @@ describe 'EPP Contact', epp: true do
|
||||||
it 'fails if request is invalid' do
|
it 'fails if request is invalid' do
|
||||||
response = epp_plain_request(@epp_xml.check, :xml)
|
response = epp_plain_request(@epp_xml.check, :xml)
|
||||||
|
|
||||||
response[:results][0][:msg].should == 'Required parameter missing: check > check > id'
|
response[:results][0][:msg].should == 'Required parameter missing: check > check > id [id]'
|
||||||
response[:results][0][:result_code].should == '2003'
|
response[:results][0][:result_code].should == '2003'
|
||||||
response[:results].count.should == 1
|
response[:results].count.should == 1
|
||||||
end
|
end
|
||||||
|
@ -343,7 +359,7 @@ describe 'EPP Contact', epp: true do
|
||||||
it 'fails if request invalid' do
|
it 'fails if request invalid' do
|
||||||
response = epp_plain_request(@epp_xml.info, :xml)
|
response = epp_plain_request(@epp_xml.info, :xml)
|
||||||
response[:results][0][:msg].should ==
|
response[:results][0][:msg].should ==
|
||||||
'Required parameter missing: info > info > id'
|
'Required parameter missing: info > info > id [id]'
|
||||||
response[:results][0][:result_code].should == '2003'
|
response[:results][0][:result_code].should == '2003'
|
||||||
response[:results].count.should == 1
|
response[:results].count.should == 1
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,8 +11,6 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
login_as :registrar1
|
login_as :registrar1
|
||||||
|
|
||||||
Contact.skip_callback(:create, :before, :generate_code)
|
|
||||||
|
|
||||||
Fabricate(:contact, code: 'citizen_1234')
|
Fabricate(:contact, code: 'citizen_1234')
|
||||||
Fabricate(:contact, code: 'sh8013')
|
Fabricate(:contact, code: 'sh8013')
|
||||||
Fabricate(:contact, code: 'sh801333')
|
Fabricate(:contact, code: 'sh801333')
|
||||||
|
@ -61,16 +59,20 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:results][0][:result_code].should == '2003'
|
response[:results][0][:result_code].should == '2003'
|
||||||
response[:results][0][:msg].should == 'Required parameter missing: create > create > ns'
|
response[:results][0][:msg].should ==
|
||||||
|
'Required parameter missing: create > create > ns [ns]'
|
||||||
|
|
||||||
response[:results][1][:result_code].should == '2003'
|
response[:results][1][:result_code].should == '2003'
|
||||||
response[:results][1][:msg].should == 'Required parameter missing: create > create > registrant'
|
response[:results][1][:msg].should ==
|
||||||
|
'Required parameter missing: create > create > registrant [registrant]'
|
||||||
|
|
||||||
response[:results][2][:result_code].should == '2003'
|
response[:results][2][:result_code].should == '2003'
|
||||||
response[:results][2][:msg].should == 'Required parameter missing: create > create > ns > hostAttr'
|
response[:results][2][:msg].should ==
|
||||||
|
'Required parameter missing: create > create > ns > hostAttr [host_attr]'
|
||||||
|
|
||||||
response[:results][3][:result_code].should == '2003'
|
response[:results][3][:result_code].should == '2003'
|
||||||
response[:results][3][:msg].should == 'Required parameter missing: extension > extdata > legalDocument'
|
response[:results][3][:msg].should ==
|
||||||
|
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with citizen as an owner' do
|
context 'with citizen as an owner' do
|
||||||
|
@ -169,7 +171,7 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:result_code].should == '2306'
|
response[:result_code].should == '2306'
|
||||||
response[:msg].should == 'IPv4 is missing'
|
response[:msg].should == 'IPv4 is missing [ipv4]'
|
||||||
end
|
end
|
||||||
|
|
||||||
# it 'does not create duplicate domain' do
|
# it 'does not create duplicate domain' do
|
||||||
|
@ -191,7 +193,7 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:result_code].should == '2302'
|
response[:result_code].should == '2302'
|
||||||
response[:msg].should == 'Domain name is reserved or restricted'
|
response[:msg].should == 'Domain name is reserved or restricted [name_dirty]'
|
||||||
response[:clTRID].should == 'ABC-12345'
|
response[:clTRID].should == 'ABC-12345'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -200,7 +202,8 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:results][0][:result_code].should == '2003'
|
response[:results][0][:result_code].should == '2003'
|
||||||
response[:results][0][:msg].should == 'Required parameter missing: create > create > registrant'
|
response[:results][0][:msg].should ==
|
||||||
|
'Required parameter missing: create > create > registrant [registrant]'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not create domain without nameservers' do
|
it 'does not create domain without nameservers' do
|
||||||
|
@ -208,11 +211,11 @@ describe 'EPP Domain', epp: true do
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
|
|
||||||
response[:results][0][:msg].should ==
|
response[:results][0][:msg].should ==
|
||||||
'Required parameter missing: create > create > ns'
|
'Required parameter missing: create > create > ns [ns]'
|
||||||
response[:results][0][:result_code].should == '2003'
|
response[:results][0][:result_code].should == '2003'
|
||||||
|
|
||||||
response[:results][1][:msg].should ==
|
response[:results][1][:msg].should ==
|
||||||
'Required parameter missing: create > create > ns > hostAttr'
|
'Required parameter missing: create > create > ns > hostAttr [host_attr]'
|
||||||
response[:results][1][:result_code].should == '2003'
|
response[:results][1][:result_code].should == '2003'
|
||||||
|
|
||||||
response[:results].count.should == 2
|
response[:results].count.should == 2
|
||||||
|
@ -234,7 +237,7 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:result_code].should == '2004'
|
response[:result_code].should == '2004'
|
||||||
response[:msg].should == 'Nameservers count must be between 2-11'
|
response[:msg].should == 'Nameservers count must be between 2-11 [nameservers]'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns error when invalid nameservers are present' do
|
it 'returns error when invalid nameservers are present' do
|
||||||
|
@ -254,8 +257,8 @@ describe 'EPP Domain', epp: true do
|
||||||
})
|
})
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
|
response[:msg].should == 'Hostname is invalid [hostname]'
|
||||||
response[:result_code].should == '2005'
|
response[:result_code].should == '2005'
|
||||||
response[:msg].should == 'Hostname is invalid'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'checks hostAttr presence' do
|
it 'checks hostAttr presence' do
|
||||||
|
@ -271,8 +274,8 @@ describe 'EPP Domain', epp: true do
|
||||||
})
|
})
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
|
response[:msg].should == 'Required parameter missing: create > create > ns > hostAttr [host_attr]'
|
||||||
response[:result_code].should == '2003'
|
response[:result_code].should == '2003'
|
||||||
response[:msg].should == 'Required parameter missing: create > create > ns > hostAttr'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates domain with nameservers with ips' do
|
it 'creates domain with nameservers with ips' do
|
||||||
|
@ -288,10 +291,10 @@ describe 'EPP Domain', epp: true do
|
||||||
nameserver_count = Nameserver.count
|
nameserver_count = Nameserver.count
|
||||||
response = epp_plain_request(domain_create_with_invalid_ns_ip_xml, :xml)
|
response = epp_plain_request(domain_create_with_invalid_ns_ip_xml, :xml)
|
||||||
response[:results][0][:result_code].should == '2005'
|
response[:results][0][:result_code].should == '2005'
|
||||||
response[:results][0][:msg].should == 'IPv4 is invalid'
|
response[:results][0][:msg].should == 'IPv4 is invalid [ipv4]'
|
||||||
response[:results][0][:value].should == '192.0.2.2.invalid'
|
response[:results][0][:value].should == '192.0.2.2.invalid'
|
||||||
response[:results][1][:result_code].should == '2005'
|
response[:results][1][:result_code].should == '2005'
|
||||||
response[:results][1][:msg].should == 'IPv6 is invalid'
|
response[:results][1][:msg].should == 'IPv6 is invalid [ipv6]'
|
||||||
response[:results][1][:value].should == 'INVALID_IPV6'
|
response[:results][1][:value].should == 'INVALID_IPV6'
|
||||||
# ensure nothing gets saved to db:
|
# ensure nothing gets saved to db:
|
||||||
Domain.count.should == domain_count
|
Domain.count.should == domain_count
|
||||||
|
@ -314,7 +317,7 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:results][0][:result_code].should == '2004'
|
response[:results][0][:result_code].should == '2004'
|
||||||
response[:results][0][:msg].should == 'Period must add up to 1, 2 or 3 years'
|
response[:results][0][:msg].should == 'Period must add up to 1, 2 or 3 years [period]'
|
||||||
response[:results][0][:value].should == '367'
|
response[:results][0][:value].should == '367'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -399,24 +402,25 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
|
|
||||||
response[:results][0][:msg].should == 'Valid algorithms are: 3, 5, 6, 7, 8, 252, 253, 254, 255'
|
response[:results][0][:msg].should ==
|
||||||
|
'Valid algorithms are: 3, 5, 6, 7, 8, 252, 253, 254, 255 [alg]'
|
||||||
response[:results][0][:value].should == '9'
|
response[:results][0][:value].should == '9'
|
||||||
|
|
||||||
response[:results][1][:msg].should == 'Valid protocols are: 3'
|
response[:results][1][:msg].should == 'Valid protocols are: 3 [protocol]'
|
||||||
response[:results][1][:value].should == '4'
|
response[:results][1][:value].should == '4'
|
||||||
|
|
||||||
response[:results][2][:msg].should == 'Valid flags are: 0, 256, 257'
|
response[:results][2][:msg].should == 'Valid flags are: 0, 256, 257 [flags]'
|
||||||
response[:results][2][:value].should == '250'
|
response[:results][2][:value].should == '250'
|
||||||
|
|
||||||
response[:results][3][:msg].should == 'Valid algorithms are: 3, 5, 6, 7, 8, 252, 253, 254, 255'
|
response[:results][3][:msg].should == 'Valid algorithms are: 3, 5, 6, 7, 8, 252, 253, 254, 255 [alg]'
|
||||||
response[:results][3][:value].should == '10'
|
response[:results][3][:value].should == '10'
|
||||||
|
|
||||||
response[:results][4][:msg].should == 'Valid flags are: 0, 256, 257'
|
response[:results][4][:msg].should == 'Valid flags are: 0, 256, 257 [flags]'
|
||||||
response[:results][4][:value].should == '1'
|
response[:results][4][:value].should == '1'
|
||||||
|
|
||||||
response[:results][5][:msg].should == 'Public key is missing'
|
response[:results][5][:msg].should == 'Public key is missing [public_key]'
|
||||||
|
|
||||||
response[:results][6][:msg].should == 'Valid protocols are: 3'
|
response[:results][6][:msg].should == 'Valid protocols are: 3 [protocol]'
|
||||||
response[:results][6][:value].should == '5'
|
response[:results][6][:value].should == '5'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -443,7 +447,7 @@ describe 'EPP Domain', epp: true do
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
|
|
||||||
response[:result_code].should == '2302'
|
response[:result_code].should == '2302'
|
||||||
response[:msg].should == 'Public key already exists'
|
response[:msg].should == 'Public key already exists [public_key]'
|
||||||
response[:results][0][:value].should == '700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f'
|
response[:results][0][:value].should == '700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -472,7 +476,7 @@ describe 'EPP Domain', epp: true do
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
|
|
||||||
response[:result_code].should == '2004'
|
response[:result_code].should == '2004'
|
||||||
response[:msg].should == 'DNS keys count must be between 0-1'
|
response[:msg].should == 'DNS keys count must be between 0-1 [dnskeys]'
|
||||||
|
|
||||||
create_settings
|
create_settings
|
||||||
end
|
end
|
||||||
|
@ -669,7 +673,7 @@ describe 'EPP Domain', epp: true do
|
||||||
})
|
})
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:msg].should == 'Admin contacts count must be between 1-10'
|
response[:msg].should == 'Admin contacts count must be between 1-10 [admin_contacts]'
|
||||||
response[:result_code].should == '2004'
|
response[:result_code].should == '2004'
|
||||||
response[:clTRID].should == 'ABC-12345'
|
response[:clTRID].should == 'ABC-12345'
|
||||||
|
|
||||||
|
@ -861,7 +865,8 @@ describe 'EPP Domain', epp: true do
|
||||||
login_as :registrar2 do
|
login_as :registrar2 do
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:result_code].should == '2003'
|
response[:result_code].should == '2003'
|
||||||
response[:msg].should == 'Required parameter missing: extension > extdata > legalDocument'
|
response[:msg].should ==
|
||||||
|
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -978,7 +983,7 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:result_code].should == '2201'
|
response[:result_code].should == '2201'
|
||||||
response[:msg].should == 'Authorization error'
|
response[:msg].should == 'Authorization error [auth_info]'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'ignores transfer when owner registrar requests transfer' do
|
it 'ignores transfer when owner registrar requests transfer' do
|
||||||
|
@ -1025,7 +1030,7 @@ describe 'EPP Domain', epp: true do
|
||||||
epp_plain_request(xml, :xml) # transfer domain
|
epp_plain_request(xml, :xml) # transfer domain
|
||||||
response = epp_plain_request(xml, :xml) # attempt second transfer
|
response = epp_plain_request(xml, :xml) # attempt second transfer
|
||||||
response[:result_code].should == '2201'
|
response[:result_code].should == '2201'
|
||||||
response[:msg].should == 'Authorization error'
|
response[:msg].should == 'Authorization error [auth_info]'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1128,27 +1133,27 @@ describe 'EPP Domain', epp: true do
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
|
|
||||||
response[:results][0][:result_code].should == '2302'
|
response[:results][0][:result_code].should == '2302'
|
||||||
response[:results][0][:msg].should == 'Nameserver already exists on this domain'
|
response[:results][0][:msg].should == 'Nameserver already exists on this domain [hostname]'
|
||||||
response[:results][0][:value].should == 'ns1.example.com'
|
response[:results][0][:value].should == 'ns1.example.com'
|
||||||
|
|
||||||
response[:results][1][:result_code].should == '2302'
|
response[:results][1][:result_code].should == '2302'
|
||||||
response[:results][1][:msg].should == 'Nameserver already exists on this domain'
|
response[:results][1][:msg].should == 'Nameserver already exists on this domain [hostname]'
|
||||||
response[:results][1][:value].should == 'ns2.example.com'
|
response[:results][1][:value].should == 'ns2.example.com'
|
||||||
|
|
||||||
response[:results][2][:result_code].should == '2302'
|
response[:results][2][:result_code].should == '2302'
|
||||||
response[:results][2][:msg].should == 'Contact already exists on this domain'
|
response[:results][2][:msg].should == 'Contact already exists on this domain [contact_code_cache]'
|
||||||
response[:results][2][:value].should == 'mak21'
|
response[:results][2][:value].should == 'mak21'
|
||||||
|
|
||||||
response[:results][3][:msg].should == 'Status already exists on this domain'
|
response[:results][3][:msg].should == 'Status already exists on this domain [value]'
|
||||||
response[:results][3][:value].should == 'clientHold'
|
response[:results][3][:value].should == 'clientHold'
|
||||||
|
|
||||||
response[:results][4][:msg].should == 'Status already exists on this domain'
|
response[:results][4][:msg].should == 'Status already exists on this domain [value]'
|
||||||
response[:results][4][:value].should == 'clientUpdateProhibited'
|
response[:results][4][:value].should == 'clientUpdateProhibited'
|
||||||
|
|
||||||
response[:results][5][:msg].should == 'Public key already exists'
|
response[:results][5][:msg].should == 'Public key already exists [public_key]'
|
||||||
response[:results][5][:value].should == '700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f'
|
response[:results][5][:value].should == '700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f'
|
||||||
|
|
||||||
response[:results][6][:msg].should == 'Public key already exists'
|
response[:results][6][:msg].should == 'Public key already exists [public_key]'
|
||||||
response[:results][6][:value].should == '841936717ae427ace63c28d04918569a841936717ae427ace63c28d0'
|
response[:results][6][:value].should == '841936717ae427ace63c28d04918569a841936717ae427ace63c28d0'
|
||||||
|
|
||||||
d.domain_statuses.count.should == 2
|
d.domain_statuses.count.should == 2
|
||||||
|
@ -1300,11 +1305,11 @@ describe 'EPP Domain', epp: true do
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
|
|
||||||
response[:results][0][:result_code].should == '2302'
|
response[:results][0][:result_code].should == '2302'
|
||||||
response[:results][0][:msg].should == 'Nameserver already exists on this domain'
|
response[:results][0][:msg].should == 'Nameserver already exists on this domain [hostname]'
|
||||||
response[:results][0][:value].should == n.hostname
|
response[:results][0][:value].should == n.hostname
|
||||||
|
|
||||||
response[:results][1][:result_code].should == '2302'
|
response[:results][1][:result_code].should == '2302'
|
||||||
response[:results][1][:msg].should == 'Contact already exists on this domain'
|
response[:results][1][:msg].should == 'Contact already exists on this domain [contact_code_cache]'
|
||||||
response[:results][1][:value].should == c.code
|
response[:results][1][:value].should == c.code
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1317,7 +1322,8 @@ describe 'EPP Domain', epp: true do
|
||||||
}
|
}
|
||||||
|
|
||||||
response = epp_plain_request(domain_update_xml(xml_params), :xml)
|
response = epp_plain_request(domain_update_xml(xml_params), :xml)
|
||||||
response[:results][0][:msg].should == 'Required parameter missing: extension > extdata > legalDocument'
|
response[:results][0][:msg].should ==
|
||||||
|
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||||
response[:results][0][:result_code].should == '2003'
|
response[:results][0][:result_code].should == '2003'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1374,7 +1380,7 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:results][0][:result_code].should == '2004'
|
response[:results][0][:result_code].should == '2004'
|
||||||
response[:results][0][:msg].should == 'Period must add up to 1, 2 or 3 years'
|
response[:results][0][:msg].should == 'Period must add up to 1, 2 or 3 years [period]'
|
||||||
response[:results][0][:value].should == '4'
|
response[:results][0][:value].should == '4'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1526,7 +1532,8 @@ describe 'EPP Domain', epp: true do
|
||||||
it 'does not delete domain without legal document' do
|
it 'does not delete domain without legal document' do
|
||||||
response = epp_plain_request(@epp_xml.domain.delete(name: { value: 'example.ee' }), :xml)
|
response = epp_plain_request(@epp_xml.domain.delete(name: { value: 'example.ee' }), :xml)
|
||||||
response[:result_code].should == '2003'
|
response[:result_code].should == '2003'
|
||||||
response[:msg].should == 'Required parameter missing: extension > extdata > legalDocument'
|
response[:msg].should ==
|
||||||
|
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||||
end
|
end
|
||||||
|
|
||||||
### CHECK ###
|
### CHECK ###
|
||||||
|
|
|
@ -64,7 +64,7 @@ describe 'EPP Keyrelay', epp: true do
|
||||||
})
|
})
|
||||||
|
|
||||||
response = epp_plain_request(xml, :xml)
|
response = epp_plain_request(xml, :xml)
|
||||||
response[:msg].should == 'Required parameter missing: keyrelay > keyData > flags'
|
response[:msg].should == 'Required parameter missing: keyrelay > keyData > flags [flags]'
|
||||||
|
|
||||||
@registrar2.messages.queued.count.should == msg_count
|
@registrar2.messages.queued.count.should == msg_count
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,6 +35,7 @@ describe 'EPP Session', epp: true do
|
||||||
|
|
||||||
inactive = @epp_xml.session.login(clID: { value: 'inactive-user' }, pw: { value: 'ghyt9e4fu' })
|
inactive = @epp_xml.session.login(clID: { value: 'inactive-user' }, pw: { value: 'ghyt9e4fu' })
|
||||||
response = epp_plain_request(inactive, :xml)
|
response = epp_plain_request(inactive, :xml)
|
||||||
|
response[:msg].should == 'Authentication error; server closing connection'
|
||||||
response[:result_code].should == '2501'
|
response[:result_code].should == '2501'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
Fabricator(:contact) do
|
Fabricator(:contact) do
|
||||||
code { "sh#{Faker::Number.number(8)}" }
|
code { "sh#{Faker::Number.number(8)}" }
|
||||||
|
auth_info 'password'
|
||||||
name { sequence(:name) { |i| "#{Faker::Name.name}#{i}" } }
|
name { sequence(:name) { |i| "#{Faker::Name.name}#{i}" } }
|
||||||
phone '+372.12345678'
|
phone '+372.12345678'
|
||||||
email Faker::Internet.email
|
email Faker::Internet.email
|
||||||
ident '37605030299'
|
ident '37605030299'
|
||||||
ident_type 'priv'
|
ident_type 'priv'
|
||||||
ident_country_code 'EE'
|
ident_country_code 'EE'
|
||||||
auth_info 'ccds4324pok'
|
|
||||||
address
|
address
|
||||||
registrar { Fabricate(:registrar, name: Faker::Company.name, reg_no: Faker::Company.duns_number) }
|
registrar { Fabricate(:registrar, name: Faker::Company.name, reg_no: Faker::Company.duns_number) }
|
||||||
disclosure { Fabricate(:contact_disclosure) }
|
disclosure { Fabricate(:contact_disclosure) }
|
||||||
|
# rubocop: disable Style/SymbolProc
|
||||||
|
after_validation { |c| c.disable_generate_auth_info! }
|
||||||
|
# rubocop: enamble Style/SymbolProc
|
||||||
end
|
end
|
||||||
|
|
|
@ -91,6 +91,12 @@ describe Contact do
|
||||||
it 'should not have any versions' do
|
it 'should not have any versions' do
|
||||||
@contact.versions.should == []
|
@contact.versions.should == []
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context 'with valid attributes' do
|
context 'with valid attributes' do
|
||||||
|
@ -130,6 +136,17 @@ describe Contact do
|
||||||
@contact.errors.full_messages.should match_array([])
|
@contact.errors.full_messages.should match_array([])
|
||||||
end
|
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
|
context 'as birthday' do
|
||||||
before :all do
|
before :all do
|
||||||
@contact.ident_type = 'birthday'
|
@contact.ident_type = 'birthday'
|
||||||
|
@ -182,20 +199,56 @@ describe Contact do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'after create' do
|
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 = Fabricate.build(:contact, code: '123asd', auth_info: 'qwe321')
|
||||||
@contact.code.should == '123asd'
|
@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.auth_info.should == 'qwe321'
|
@contact.auth_info.should == 'qwe321'
|
||||||
@contact.save!
|
@contact.save.should == true
|
||||||
@contact.code.should_not == '123asd'
|
|
||||||
@contact.auth_info.should_not == 'qwe321'
|
@contact.auth_info.should_not == 'qwe321'
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context 'after update' do
|
context 'after update' do
|
||||||
before :all do
|
before :all do
|
||||||
@contact.code = '123asd'
|
@contact = Fabricate.build(:contact, code: '123asd', auth_info: 'qwe321')
|
||||||
@contact.auth_info = 'qwe321'
|
@contact.save
|
||||||
|
@contact.code.should == '123asd'
|
||||||
|
@auth_info = @contact.auth_info
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not generate new code' do
|
it 'should not generate new code' do
|
||||||
|
@ -205,7 +258,7 @@ describe Contact do
|
||||||
|
|
||||||
it 'should not generate new auth_info' do
|
it 'should not generate new auth_info' do
|
||||||
@contact.update_attributes(name: 'fvrsgbqevciherot23')
|
@contact.update_attributes(name: 'fvrsgbqevciherot23')
|
||||||
@contact.auth_info.should == 'qwe321'
|
@contact.auth_info.should == @auth_info
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,6 +28,10 @@ describe Registrar do
|
||||||
@registrar.errors[:email].should == ['is invalid']
|
@registrar.errors[:email].should == ['is invalid']
|
||||||
@registrar.errors[:billing_email].should == ['is invalid']
|
@registrar.errors[:billing_email].should == ['is invalid']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should not have valid code' do
|
||||||
|
@registrar.code.should == nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with valid attributes' do
|
context 'with valid attributes' do
|
||||||
|
@ -59,5 +63,26 @@ describe Registrar do
|
||||||
it 'should return full address' do
|
it 'should return full address' do
|
||||||
@registrar.address.should == 'Street 999, Town, County, Postal'
|
@registrar.address.should == 'Street 999, Town, County, Postal'
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue