mirror of
https://github.com/internetee/registry.git
synced 2025-05-17 01:47:18 +02:00
Merge branch 'master' into domains-nested-refactor
Conflicts: config/locales/en.yml
This commit is contained in:
commit
08fb2966d4
93 changed files with 2356 additions and 1678 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -10,10 +10,11 @@ capybara-*.html
|
|||
/spec/tmp
|
||||
**.orig
|
||||
config/initializers/secret_token.rb
|
||||
config/application.yml
|
||||
config/secrets.yml
|
||||
config/database.yml
|
||||
/export
|
||||
/ca
|
||||
todo
|
||||
|
||||
## Environment normalisation:
|
||||
/.bundle
|
||||
|
@ -24,3 +25,6 @@ config/database.yml
|
|||
|
||||
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
||||
.rvmrc
|
||||
|
||||
# Ignore application configuration
|
||||
/config/application.yml
|
||||
|
|
|
@ -77,3 +77,7 @@ Style/AsciiComments:
|
|||
# because NerdCommenter honors commented code intentions
|
||||
Style/CommentIndentation:
|
||||
Enabled: false
|
||||
|
||||
# It did not alayws suggested good format
|
||||
Style/AlignParameters:
|
||||
Enabled: false
|
||||
|
|
27
.travis.yml
Normal file
27
.travis.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
language: ruby
|
||||
rvm:
|
||||
- 2.2
|
||||
- ruby-head
|
||||
env:
|
||||
- DB=postgresql
|
||||
sudo: false
|
||||
before_install:
|
||||
- gem install bundler
|
||||
- "rm ${BUNDLE_GEMFILE}.lock"
|
||||
before_script:
|
||||
- psql -c 'create database registry_test;' -U postgres
|
||||
- psql -c 'create database registry_whois_test;' -U postgres
|
||||
- psql -c 'create database registry_api_log_test;' -U postgres
|
||||
- bundle update
|
||||
- cp config/application-example.yml config/application.yml
|
||||
- cp config/secrets-example.yml config/secrets.yml
|
||||
- cp config/database-travis.yml config/database.yml
|
||||
- RAILS_ENV=test bundle exec rake db:all:schema:load
|
||||
- RAILS_ENV=test bundle exec rake db:seed
|
||||
script:
|
||||
- RAILS_ENV=test bundle exec rake
|
||||
cache: bundler
|
||||
services:
|
||||
- postgresql
|
||||
addons:
|
||||
postgresql: "9.3"
|
92
CHANGELOG.md
92
CHANGELOG.md
|
@ -1,93 +1,11 @@
|
|||
12.02.2015
|
||||
27.02.2015
|
||||
|
||||
Go to registry shared folder and setup CA directory tree:
|
||||
```
|
||||
mkdir ca
|
||||
cd ca
|
||||
mkdir certs crl newcerts private
|
||||
chmod 700 private
|
||||
touch index.txt
|
||||
echo 1000 > serial
|
||||
```
|
||||
* Simplified config/application-example.yml,
|
||||
now system will check if all required settings are present in application.yml
|
||||
|
||||
Generate the root key (prompts for pass phrase):
|
||||
```
|
||||
openssl genrsa -aes256 -out private/ca.key.pem 4096
|
||||
```
|
||||
19.02.2015
|
||||
|
||||
Configure OpenSSL:
|
||||
```
|
||||
sudo su -
|
||||
cd /etc/ssl/
|
||||
cp openssl.cnf openssl.cnf.bak
|
||||
nano openssl.cnf
|
||||
exit
|
||||
```
|
||||
|
||||
Make sure the following options are in place:
|
||||
```
|
||||
[ CA_default ]
|
||||
# Where everything is kept
|
||||
dir = /home/registry/registry/shared/ca
|
||||
|
||||
[ usr_cert ]
|
||||
# These extensions are added when 'ca' signs a request.
|
||||
basicConstraints=CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
nsComment = "OpenSSL Generated Certificate"
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer
|
||||
|
||||
[ v3_ca ]
|
||||
# Extensions for a typical CA
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid:always,issuer
|
||||
basicConstraints = CA:true
|
||||
keyUsage = cRLSign, keyCertSign
|
||||
|
||||
[ policy_match ]
|
||||
countryName = optional
|
||||
stateOrProvinceName = optional
|
||||
organizationName = optional
|
||||
organizationalUnitName = optional
|
||||
commonName = optional
|
||||
emailAddress = optional
|
||||
```
|
||||
|
||||
Issue the root certificate (prompts for additional data):
|
||||
```
|
||||
openssl req -new -x509 -days 3650 -key private/ca.key.pem -sha256 -extensions v3_ca -out certs/ca.cert.pem
|
||||
chmod 444 certs/ca.cert.pem
|
||||
```
|
||||
|
||||
Configure EPP virtual host:
|
||||
```
|
||||
sudo nano /etc/apache2/sites-enabled/epp.conf
|
||||
```
|
||||
|
||||
Replace this line:
|
||||
```
|
||||
SSLVerifyClient optional_no_ca
|
||||
```
|
||||
|
||||
With these lines:
|
||||
```
|
||||
SSLVerifyClient require
|
||||
SSLVerifyDepth 1
|
||||
SSLCACertificateFile /home/registry/registry/shared/ca/certs/ca.cert.pem
|
||||
```
|
||||
|
||||
Reload apache:
|
||||
```
|
||||
sudo /etc/init.d/apache2 reload
|
||||
```
|
||||
|
||||
Configure application.yml to match the CA settings:
|
||||
```
|
||||
ca_cert_path: '/home/registry/registry/shared/ca/certs/ca.cert.pem'
|
||||
ca_key_path: '/home/registry/registry/shared/ca/private/ca.key.pem'
|
||||
ca_key_password: 'registryalpha'
|
||||
```
|
||||
* Cetrificate only enabled, please setup certificates following doc/certificate.md document.
|
||||
|
||||
20.01.2015
|
||||
|
||||
|
|
11
Gemfile
11
Gemfile
|
@ -5,10 +5,16 @@ gem 'rails', '4.2.0'
|
|||
gem 'iso8601', '~> 0.8.2' # for dates and times
|
||||
gem 'hashie_rails', '~> 0.0.1'
|
||||
|
||||
# load env
|
||||
gem 'figaro', '~> 1.1.0'
|
||||
|
||||
# model related
|
||||
gem 'pg', '~> 0.18.0'
|
||||
gem 'ransack', '~> 1.5.1' # for searching
|
||||
gem 'paper_trail', '~> 4.0.0.beta2' # archiving
|
||||
# with polymorphic fix
|
||||
gem 'paper_trail',
|
||||
github: 'airblade/paper_trail',
|
||||
ref: 'a453811226ec4ea59753ba6b827e390ced2fc140' # '~> 4.0.0.beta2' # archiving
|
||||
gem 'rails-settings-cached', '~> 0.4.1' # for settings
|
||||
gem 'delayed_job_active_record', '~> 4.0.3' # delayed job
|
||||
|
||||
|
@ -110,4 +116,7 @@ group :development, :test do
|
|||
|
||||
# dev tools
|
||||
gem 'unicorn'
|
||||
|
||||
# for travis
|
||||
gem 'rake'
|
||||
end
|
||||
|
|
20
Gemfile.lock
20
Gemfile.lock
|
@ -1,3 +1,13 @@
|
|||
GIT
|
||||
remote: git://github.com/airblade/paper_trail.git
|
||||
revision: a453811226ec4ea59753ba6b827e390ced2fc140
|
||||
ref: a453811226ec4ea59753ba6b827e390ced2fc140
|
||||
specs:
|
||||
paper_trail (4.0.0.beta3)
|
||||
activerecord (>= 3.0, < 6.0)
|
||||
activesupport (>= 3.0, < 6.0)
|
||||
request_store (~> 1.1.0)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/haml/html2haml.git
|
||||
revision: 6984f50bdbbd6291535027726a5697f28778ee8d
|
||||
|
@ -142,6 +152,8 @@ GEM
|
|||
i18n (~> 0.5)
|
||||
fastercsv (1.5.5)
|
||||
ffi (1.9.6)
|
||||
figaro (1.1.0)
|
||||
thor (~> 0.14)
|
||||
flay (2.4.0)
|
||||
ruby_parser (~> 3.0)
|
||||
sexp_processor (~> 4.0)
|
||||
|
@ -235,9 +247,6 @@ GEM
|
|||
nprogress-rails (0.1.6.5)
|
||||
open4 (1.3.4)
|
||||
orm_adapter (0.5.0)
|
||||
paper_trail (4.0.0.beta2)
|
||||
activerecord (>= 3.0, < 6.0)
|
||||
activesupport (>= 3.0, < 6.0)
|
||||
parser (2.2.0.2)
|
||||
ast (>= 1.1, < 3.0)
|
||||
pg (0.18.1)
|
||||
|
@ -309,6 +318,7 @@ GEM
|
|||
ruby_parser (~> 3.3)
|
||||
sexp_processor
|
||||
ref (1.0.5)
|
||||
request_store (1.1.0)
|
||||
responders (2.0.2)
|
||||
railties (>= 4.2.0.alpha, < 5)
|
||||
rspec (3.0.0)
|
||||
|
@ -451,6 +461,7 @@ DEPENDENCIES
|
|||
epp-xml (~> 0.10.4)
|
||||
fabrication (~> 2.12.2)
|
||||
faker (~> 1.3.0)
|
||||
figaro (~> 1.1.0)
|
||||
grape (~> 0.10.1)
|
||||
guard (~> 2.6.1)
|
||||
guard-rails (~> 0.7.0)
|
||||
|
@ -469,7 +480,7 @@ DEPENDENCIES
|
|||
newrelic_rpm (~> 3.9.9.275)
|
||||
nokogiri (~> 1.6.2.1)
|
||||
nprogress-rails (~> 0.1.6.5)
|
||||
paper_trail (~> 4.0.0.beta2)
|
||||
paper_trail!
|
||||
pg (~> 0.18.0)
|
||||
phantomjs (~> 1.9.7.1)
|
||||
phantomjs-binaries (~> 1.9.2.4)
|
||||
|
@ -478,6 +489,7 @@ DEPENDENCIES
|
|||
railroady (~> 1.3.0)
|
||||
rails (= 4.2.0)
|
||||
rails-settings-cached (~> 0.4.1)
|
||||
rake
|
||||
ransack (~> 1.5.1)
|
||||
rspec-rails (~> 3.0.2)
|
||||
rubocop (~> 0.26.1)
|
||||
|
|
12
Guardfile
12
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$})
|
||||
|
@ -18,6 +18,8 @@ group :red_green_refactor, halt_on_fail: true do
|
|||
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
||||
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
||||
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
||||
watch(%r{^app/controllers/epp/(.+)_(controller)\.rb$}) { |m| ["spec/epp/#{m[1].sub(/s$/,'')}_spec.rb"] }
|
||||
watch(%r{^app/models/epp/(.+)\.rb$}) { |m| "spec/epp/#{m[1]}_spec.rb" }
|
||||
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
||||
watch('config/routes.rb') { "spec/routing" }
|
||||
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
||||
|
|
145
README.md
145
README.md
|
@ -23,7 +23,7 @@ Installation
|
|||
|
||||
### 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:
|
||||
|
||||
|
@ -32,44 +32,11 @@ Manual demo install and database setup:
|
|||
cd demo-registry
|
||||
rbenv local 2.2.0
|
||||
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/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
|
||||
|
||||
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)
|
||||
|
||||
sudo apt-get install apache2
|
||||
|
@ -152,7 +119,12 @@ Be sure to update paths to match your system configuration.
|
|||
|
||||
SSLVerifyClient require
|
||||
SSLVerifyDepth 1
|
||||
SSLCACertificateFile /home/registry/registry/shared/ca/certs/ca.cert.pem
|
||||
SSLCACertificateFile /home/registry/registry/shared/ca/certs/ca.crt.pem
|
||||
SSLCARevocationFile /home/registry/registry/shared/ca/crl/crl.pem
|
||||
# Uncomment this when upgrading to apache 2.4:
|
||||
# SSLCARevocationCheck chain
|
||||
|
||||
RequestHeader set SSL_CLIENT_S_DN_CN "%{SSL_CLIENT_S_DN_CN}s"
|
||||
|
||||
EPPEngine On
|
||||
EPPCommandRoot /proxy/command
|
||||
|
@ -182,6 +154,21 @@ All registry demo data can be found at:
|
|||
Initially you can use two type of users: admin users and EPP users.
|
||||
|
||||
|
||||
### Certificates setup
|
||||
|
||||
* [Certificates setup](/doc/certificates.md)
|
||||
|
||||
|
||||
### Deployment
|
||||
|
||||
* [Application build and update](/doc/application_build_doc.md)
|
||||
|
||||
|
||||
### Autotesting
|
||||
|
||||
* [Testing](/doc/testing.md)
|
||||
|
||||
|
||||
### EPP web client
|
||||
|
||||
Please follow EPP web client readme:
|
||||
|
@ -196,85 +183,7 @@ Please follow WHOIS server readme:
|
|||
https://github.com/internetee/whois
|
||||
|
||||
|
||||
Deployment
|
||||
----------
|
||||
## Code Status
|
||||
|
||||
* [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
|
||||
Alpha release status, only model tests:
|
||||
[](https://travis-ci.org/domify/registry)
|
||||
|
|
|
@ -12,10 +12,7 @@ class Admin::ApiUsersController < AdminController
|
|||
end
|
||||
|
||||
def create
|
||||
app = api_user_params
|
||||
app[:csr] = params[:api_user][:csr].open.read if params[:api_user][:csr]
|
||||
|
||||
@api_user = ApiUser.new(app)
|
||||
@api_user = ApiUser.new(api_user_params)
|
||||
|
||||
if @api_user.save
|
||||
flash[:notice] = I18n.t('record_created')
|
||||
|
@ -31,10 +28,7 @@ class Admin::ApiUsersController < AdminController
|
|||
def edit; end
|
||||
|
||||
def update
|
||||
app = api_user_params
|
||||
app[:csr] = params[:api_user][:csr].open.read if params[:api_user][:csr]
|
||||
|
||||
if @api_user.update(app)
|
||||
if @api_user.update(api_user_params)
|
||||
flash[:notice] = I18n.t('record_updated')
|
||||
redirect_to [:admin, @api_user]
|
||||
else
|
||||
|
@ -53,14 +47,6 @@ class Admin::ApiUsersController < AdminController
|
|||
end
|
||||
end
|
||||
|
||||
def download_csr
|
||||
send_data @api_user.csr, filename: "#{@api_user.username}.csr.pem"
|
||||
end
|
||||
|
||||
def download_crt
|
||||
send_data @api_user.crt, filename: "#{@api_user.username}.crt.pem"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_api_user
|
||||
|
@ -68,6 +54,6 @@ class Admin::ApiUsersController < AdminController
|
|||
end
|
||||
|
||||
def api_user_params
|
||||
params.require(:api_user).permit(:username, :password, :csr, :active, :registrar_id, :registrar_typeahead)
|
||||
params.require(:api_user).permit(:username, :password, :active, :registrar_id, :registrar_typeahead)
|
||||
end
|
||||
end
|
||||
|
|
68
app/controllers/admin/certificates_controller.rb
Normal file
68
app/controllers/admin/certificates_controller.rb
Normal file
|
@ -0,0 +1,68 @@
|
|||
class Admin::CertificatesController < AdminController
|
||||
load_and_authorize_resource
|
||||
before_action :set_certificate, :set_api_user, only: [:sign, :show, :download_csr, :download_crt, :revoke]
|
||||
|
||||
def show
|
||||
@csr = OpenSSL::X509::Request.new(@certificate.csr) if @certificate.csr
|
||||
@crt = OpenSSL::X509::Certificate.new(@certificate.crt) if @certificate.crt
|
||||
end
|
||||
|
||||
def new
|
||||
set_api_user
|
||||
@certificate = Certificate.new
|
||||
end
|
||||
|
||||
def create
|
||||
@api_user = ApiUser.find(params[:api_user_id])
|
||||
csr = certificate_params[:csr].open.read if certificate_params[:csr]
|
||||
|
||||
@certificate = @api_user.certificates.build(csr: csr)
|
||||
if @api_user.save
|
||||
flash[:notice] = I18n.t('record_created')
|
||||
redirect_to [:admin, @api_user, @certificate]
|
||||
else
|
||||
flash.now[:alert] = I18n.t('failed_to_create_record')
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def sign
|
||||
if @certificate.sign!
|
||||
flash[:notice] = I18n.t('record_updated')
|
||||
else
|
||||
flash[:alert] = I18n.t('failed_to_update_record')
|
||||
end
|
||||
redirect_to [:admin, @api_user, @certificate]
|
||||
end
|
||||
|
||||
def revoke
|
||||
if @certificate.revoke!
|
||||
flash[:notice] = I18n.t('record_updated')
|
||||
else
|
||||
flash[:alert] = I18n.t('failed_to_update_record')
|
||||
end
|
||||
redirect_to [:admin, @api_user, @certificate]
|
||||
end
|
||||
|
||||
def download_csr
|
||||
send_data @certificate.csr, filename: "#{@api_user.username}.csr.pem"
|
||||
end
|
||||
|
||||
def download_crt
|
||||
send_data @certificate.crt, filename: "#{@api_user.username}.crt.pem"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_certificate
|
||||
@certificate = Certificate.find(params[:id])
|
||||
end
|
||||
|
||||
def set_api_user
|
||||
@api_user = ApiUser.find(params[:api_user_id])
|
||||
end
|
||||
|
||||
def certificate_params
|
||||
params.require(:certificate).permit(:csr)
|
||||
end
|
||||
end
|
|
@ -1,4 +1,3 @@
|
|||
class AdminController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
check_authorization
|
||||
end
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
check_authorization unless: :devise_controller?
|
||||
|
||||
# Prevent CSRF attacks by raising an exception.
|
||||
# For APIs, you may want to use :null_session instead.
|
||||
protect_from_forgery with: :exception
|
||||
|
@ -9,8 +11,14 @@ class ApplicationController < ActionController::Base
|
|||
params[resource] &&= send(method) if respond_to?(method, true)
|
||||
end
|
||||
|
||||
rescue_from CanCan::AccessDenied do |exception|
|
||||
redirect_to admin_dashboard_path, alert: exception.message
|
||||
end
|
||||
|
||||
def after_sign_in_path_for(_resource)
|
||||
return session[:user_return_to].to_s if session[:user_return_to] && session[:user_return_to] != login_path
|
||||
if session[:user_return_to] && session[:user_return_to] != login_path
|
||||
return session[:user_return_to].to_s
|
||||
end
|
||||
admin_dashboard_path
|
||||
end
|
||||
|
||||
|
@ -34,9 +42,3 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
rescue_from CanCan::AccessDenied do |exception|
|
||||
redirect_to admin_dashboard_path, alert: exception.message
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,188 +1,125 @@
|
|||
class Epp::ContactsController < EppController
|
||||
helper WhodunnitHelper ## Refactor this?
|
||||
|
||||
def create
|
||||
@contact = Contact.new(contact_and_address_attributes)
|
||||
@contact.registrar = current_user.registrar
|
||||
render_epp_response '/epp/contacts/create' and return if @contact.save
|
||||
handle_errors(@contact)
|
||||
end
|
||||
|
||||
def update
|
||||
# FIXME: Update returns 2303 update multiple times
|
||||
code = params_hash['epp']['command']['update']['update'][:id]
|
||||
|
||||
@contact = Contact.where(code: code).first
|
||||
# if update_rights? && @contact.update_attributes(contact_and_address_attributes(:update))
|
||||
if owner? && @contact.update_attributes(contact_and_address_attributes(:update))
|
||||
render_epp_response 'epp/contacts/update'
|
||||
else
|
||||
contact_exists?(code)
|
||||
handle_errors(@contact) and return
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
def delete
|
||||
@contact = find_contact
|
||||
handle_errors(@contact) and return unless rights? # owner?
|
||||
handle_errors(@contact) and return unless @contact
|
||||
handle_errors(@contact) and return unless @contact.destroy_and_clean
|
||||
|
||||
render_epp_response '/epp/contacts/delete'
|
||||
end
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
|
||||
def check
|
||||
ph = params_hash['epp']['command']['check']['check']
|
||||
@contacts = Contact.check_availability(ph[:id])
|
||||
render_epp_response '/epp/contacts/check'
|
||||
end
|
||||
before_action :find_contact, only: [:info, :update, :delete]
|
||||
before_action :find_password, only: [:info, :update, :delete]
|
||||
|
||||
def info
|
||||
handle_errors(@contact) and return unless @contact && rights?
|
||||
# handle_errors(@contact) and return unless rights?
|
||||
@disclosure = ContactDisclosure.default_values.merge(@contact.disclosure.try(:as_hash) || {})
|
||||
@disclosure_policy = @contact.disclosure.try(:attributes_with_flag)
|
||||
@owner = owner?(false)
|
||||
# need to reload contact eagerly
|
||||
@contact = find_contact if @owner # for clarity, could just be true
|
||||
authorize! :info, @contact, @password
|
||||
render_epp_response 'epp/contacts/info'
|
||||
end
|
||||
|
||||
def check
|
||||
authorize! :check, Epp::Contact
|
||||
|
||||
ids = params[:parsed_frame].css('id').map(&:text)
|
||||
@results = Contact.check_availability(ids)
|
||||
render_epp_response '/epp/contacts/check'
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Epp::Contact
|
||||
@contact = Epp::Contact.new(params[:parsed_frame], current_user.registrar)
|
||||
|
||||
if @contact.save
|
||||
render_epp_response '/epp/contacts/create'
|
||||
else
|
||||
handle_errors(@contact)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, @contact, @password
|
||||
|
||||
if @contact.update_attributes(params[:parsed_frame])
|
||||
render_epp_response 'epp/contacts/update'
|
||||
else
|
||||
handle_errors(@contact)
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
authorize! :delete, @contact, @password
|
||||
|
||||
if @contact.destroy_and_clean
|
||||
render_epp_response '/epp/contacts/delete'
|
||||
else
|
||||
handle_errors(@contact)
|
||||
end
|
||||
end
|
||||
|
||||
def renew
|
||||
authorize! :renew, Epp::Contact
|
||||
epp_errors << { code: '2101', msg: t(:'errors.messages.unimplemented_command') }
|
||||
handle_errors
|
||||
end
|
||||
|
||||
## HELPER METHODS
|
||||
|
||||
private
|
||||
|
||||
## CREATE
|
||||
def validate_create
|
||||
@ph = params_hash['epp']['command']['create']['create']
|
||||
return false unless validate_params
|
||||
xml_attrs_present?(@ph, [%w(postalInfo name), %w(postalInfo addr city), %w(postalInfo addr cc),
|
||||
%w(ident), %w(voice), %w(email)])
|
||||
|
||||
epp_errors.empty?
|
||||
def find_password
|
||||
@password = params[:parsed_frame].css('authInfo pw').text
|
||||
end
|
||||
|
||||
## UPDATE
|
||||
def validate_updatezz
|
||||
@ph = params_hash['epp']['command']['update']['update']
|
||||
update_attrs_present?
|
||||
# xml_attrs_present?(@ph, [['id'], %w(authInfo pw)])
|
||||
xml_attrs_present?(@ph, [['id']])
|
||||
end
|
||||
|
||||
def contact_exists?(code)
|
||||
return true if @contact.is_a?(Contact)
|
||||
epp_errors << { code: '2303', msg: t('errors.messages.epp_obj_does_not_exist'),
|
||||
value: { obj: 'id', val: code } }
|
||||
end
|
||||
|
||||
def update_attrs_present?
|
||||
return true if params[:parsed_frame].css('add').present?
|
||||
return true if params[:parsed_frame].css('rem').present?
|
||||
return true if params[:parsed_frame].css('chg').present?
|
||||
epp_errors << { code: '2003', msg: I18n.t('errors.messages.required_parameter_missing', key: 'add, rem or chg') }
|
||||
end
|
||||
|
||||
## DELETE
|
||||
def validate_delete
|
||||
@ph = params_hash['epp']['command']['delete']['delete']
|
||||
xml_attrs_present?(@ph, [['id']])
|
||||
end
|
||||
|
||||
## check
|
||||
def validate_check
|
||||
@ph = params_hash['epp']['command']['check']['check']
|
||||
xml_attrs_present?(@ph, [['id']])
|
||||
end
|
||||
|
||||
## info
|
||||
def validate_info # and process
|
||||
@ph = params_hash['epp']['command']['info']['info']
|
||||
return false unless xml_attrs_present?(@ph, [['id']])
|
||||
@contact = find_contact
|
||||
return false unless @contact
|
||||
return true if current_user.registrar == @contact.registrar || xml_attrs_present?(@ph, [%w(authInfo pw)])
|
||||
false
|
||||
end
|
||||
|
||||
## SHARED
|
||||
|
||||
def find_contact
|
||||
contact = Contact.find_by(code: @ph[:id])
|
||||
unless contact
|
||||
epp_errors << { code: '2303',
|
||||
msg: t('errors.messages.epp_obj_does_not_exist'),
|
||||
value: { obj: 'id', val: @ph[:id] } }
|
||||
code = params[:parsed_frame].css('id').text.strip.downcase
|
||||
@contact = Epp::Contact.find_by(code: code)
|
||||
|
||||
if @contact.blank?
|
||||
epp_errors << {
|
||||
code: '2303',
|
||||
msg: t('errors.messages.epp_obj_does_not_exist'),
|
||||
value: { obj: 'id', val: code }
|
||||
}
|
||||
fail CanCan::AccessDenied
|
||||
end
|
||||
contact
|
||||
@contact
|
||||
end
|
||||
|
||||
def owner?(with_errors = true)
|
||||
return false unless find_contact
|
||||
return true if @contact.registrar == current_user.registrar
|
||||
return false unless with_errors
|
||||
epp_errors << { code: '2201', msg: t('errors.messages.epp_authorization_error') }
|
||||
false
|
||||
#
|
||||
# Validations
|
||||
#
|
||||
def validate_info
|
||||
@prefix = 'info > info >'
|
||||
requires 'id'
|
||||
end
|
||||
|
||||
def rights?
|
||||
pw = @ph.try(:[], :authInfo).try(:[], :pw)
|
||||
|
||||
return true if current_user.try(:registrar) == @contact.try(:registrar)
|
||||
return true if pw && @contact.auth_info_matches(pw) # @contact.try(:auth_info_matches, pw)
|
||||
|
||||
epp_errors << { code: '2200', msg: t('errors.messages.epp_authentication_error') }
|
||||
false
|
||||
def validate_check
|
||||
@prefix = 'check > check >'
|
||||
requires 'id'
|
||||
end
|
||||
|
||||
def update_rights?
|
||||
pw = @ph.try(:[], :authInfo).try(:[], :pw)
|
||||
return true if pw && @contact.auth_info_matches(pw)
|
||||
epp_errors << { code: '2200', msg: t('errors.messages.epp_authentication_error') }
|
||||
false
|
||||
end
|
||||
|
||||
def contact_and_address_attributes(type = :create)
|
||||
case type
|
||||
when :update
|
||||
# TODO: support for rem/add
|
||||
contact_hash = merge_attribute_hash(@ph[:chg], type).delete_if { |_k, v| v.empty? }
|
||||
else
|
||||
contact_hash = merge_attribute_hash(@ph, type)
|
||||
end
|
||||
contact_hash[:ident_type] = ident_type unless ident_type.nil?
|
||||
contact_hash
|
||||
end
|
||||
|
||||
def merge_attribute_hash(prms, type)
|
||||
contact_hash = Contact.extract_attributes(prms, type)
|
||||
contact_hash = contact_hash.merge(
|
||||
Address.extract_attributes((prms.try(:[], :postalInfo) || []))
|
||||
def validate_create
|
||||
@prefix = 'create > create >'
|
||||
requires(
|
||||
'postalInfo > name', 'postalInfo > addr > city',
|
||||
'postalInfo > addr > cc', 'ident', 'voice', 'email'
|
||||
)
|
||||
contact_hash[:disclosure_attributes] =
|
||||
ContactDisclosure.extract_attributes(params[:parsed_frame])
|
||||
|
||||
contact_hash
|
||||
ident = params[:parsed_frame].css('ident')
|
||||
if ident.present? && ident.text != 'birthday' && ident.attr('cc').blank?
|
||||
epp_errors << {
|
||||
code: '2003',
|
||||
msg: I18n.t('errors.messages.required_attribute_missing', key: 'ident country code missing')
|
||||
}
|
||||
end
|
||||
@prefix = nil
|
||||
requires 'extension > extdata > legalDocument'
|
||||
end
|
||||
|
||||
def ident_type
|
||||
result = params[:parsed_frame].css('ident').first.try(:attributes).try(:[], 'type').try(:value)
|
||||
return nil unless result
|
||||
|
||||
Contact::IDENT_TYPES.any? { |type| return type if result.include?(type) }
|
||||
nil
|
||||
def validate_update
|
||||
@prefix = 'update > update >'
|
||||
if element_count('chg') == 0 && element_count('rem') == 0 && element_count('add') == 0
|
||||
epp_errors << {
|
||||
code: '2003',
|
||||
msg: I18n.t('errors.messages.required_parameter_missing', key: 'add, rem or chg')
|
||||
}
|
||||
end
|
||||
requires 'id', 'authInfo > pw'
|
||||
@prefix = nil
|
||||
requires 'extension > extdata > legalDocument'
|
||||
end
|
||||
|
||||
def validate_params
|
||||
return true if @ph
|
||||
epp_errors << { code: '2001', msg: t(:'errors.messages.epp_command_syntax_error') }
|
||||
false
|
||||
def validate_delete
|
||||
@prefix = 'delete > delete >'
|
||||
requires 'id', 'authInfo > pw'
|
||||
@prefix = nil
|
||||
requires 'extension > extdata > legalDocument'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Epp::DomainsController < EppController
|
||||
skip_authorization_check # TODO: remove it
|
||||
|
||||
def create
|
||||
@domain = Epp::EppDomain.new(domain_create_params)
|
||||
# @domain.parse_and_attach_domain_dependencies(params[:parsed_frame])
|
||||
|
@ -334,7 +336,7 @@ class Epp::DomainsController < EppController
|
|||
|
||||
return domain if domain.auth_info == params[:parsed_frame].css('authInfo pw').text
|
||||
|
||||
if (domain.registrar != current_user.registrar && secure[:secure] == true) &&
|
||||
if (domain.registrar != current_user.registrar) && secure[:secure] == true
|
||||
epp_errors << {
|
||||
code: '2302',
|
||||
msg: I18n.t('errors.messages.domain_exists_but_belongs_to_other_registrar'),
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Epp::ErrorsController < EppController
|
||||
skip_authorization_check # TODO: remove it
|
||||
|
||||
def error
|
||||
epp_errors << { code: params[:code], msg: params[:msg] }
|
||||
render_epp_response '/epp/error'
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Epp::KeyrelaysController < EppController
|
||||
skip_authorization_check # TODO: remove it
|
||||
|
||||
# rubocop: disable Metrics/PerceivedComplexity
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
def keyrelay
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class Epp::PollsController < EppController
|
||||
skip_authorization_check # TODO: remove it
|
||||
|
||||
def poll
|
||||
req_poll if params[:parsed_frame].css('poll').first['op'] == 'req'
|
||||
ack_poll if params[:parsed_frame].css('poll').first['op'] == 'ack'
|
||||
|
@ -38,6 +40,6 @@ class Epp::PollsController < EppController
|
|||
private
|
||||
|
||||
def validate_poll
|
||||
requires_attribute 'poll', 'op', values: %(ack req)
|
||||
requires_attribute 'poll', 'op', values: %(ack req), allow_blank: true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,12 +1,24 @@
|
|||
class Epp::SessionsController < EppController
|
||||
skip_authorization_check only: [:hello, :login, :logout]
|
||||
|
||||
def hello
|
||||
render_epp_response('greeting')
|
||||
end
|
||||
|
||||
# rubocop: disable Metrics/PerceivedComplexity
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
def login
|
||||
@api_user = ApiUser.find_by(login_params)
|
||||
cert_valid = true
|
||||
if request.ip == ENV['webclient_ip']
|
||||
@api_user = ApiUser.find_by(login_params)
|
||||
else
|
||||
if request.env['HTTP_SSL_CLIENT_S_DN_CN'] != login_params[:username]
|
||||
cert_valid = false
|
||||
end
|
||||
@api_user = ApiUser.find_by(login_params)
|
||||
end
|
||||
|
||||
if @api_user.try(:active)
|
||||
if @api_user.try(:active) && cert_valid
|
||||
epp_session[:api_user_id] = @api_user.id
|
||||
render_epp_response('login_success')
|
||||
else
|
||||
|
@ -14,6 +26,8 @@ class Epp::SessionsController < EppController
|
|||
render_epp_response('login_fail')
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/PerceivedComplexity
|
||||
# rubocop: enable Metrics/CyclomaticComplexity
|
||||
|
||||
def logout
|
||||
@api_user = current_user # cache current_user for logging
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
class EppController < ApplicationController
|
||||
layout false
|
||||
protect_from_forgery with: :null_session
|
||||
skip_before_action :verify_authenticity_token
|
||||
|
||||
before_action :generate_svtrid
|
||||
before_action :validate_request
|
||||
layout false
|
||||
helper_method :current_user
|
||||
|
||||
rescue_from CanCan::AccessDenied do |_exception|
|
||||
@errors ||= []
|
||||
if @errors.blank?
|
||||
@errors = [{
|
||||
msg: t('errors.messages.epp_authorization_error'),
|
||||
code: '2201'
|
||||
}]
|
||||
end
|
||||
render_epp_response '/epp/error'
|
||||
end
|
||||
|
||||
def generate_svtrid
|
||||
# rubocop: disable Style/VariableName
|
||||
@svTRID = "ccReg-#{format('%010d', rand(10**10))}"
|
||||
|
@ -84,15 +97,23 @@ class EppController < ApplicationController
|
|||
# TODO: Add possibility to pass validations / options in the method
|
||||
|
||||
def requires(*selectors)
|
||||
options = selectors.extract_options!
|
||||
allow_blank = options[:allow_blank] ||= false # allow_blank is false by default
|
||||
|
||||
el, missing = nil, nil
|
||||
selectors.each do |selector|
|
||||
full_selector = [@prefix, selector].compact.join(' ')
|
||||
attr = selector.split('>').last.strip.underscore
|
||||
el = params[:parsed_frame].css(full_selector).first
|
||||
|
||||
missing = el.nil?
|
||||
if allow_blank
|
||||
missing = el.nil?
|
||||
else
|
||||
missing = el.present? ? el.text.blank? : true
|
||||
end
|
||||
epp_errors << {
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -105,7 +126,7 @@ class EppController < ApplicationController
|
|||
# requires_attribute 'transfer', 'op', values: %(approve, query, reject)
|
||||
|
||||
def requires_attribute(element_selector, attribute_selector, options)
|
||||
element = requires(element_selector)
|
||||
element = requires(element_selector, allow_blank: options[:allow_blank])
|
||||
return unless element
|
||||
|
||||
attribute = element[attribute_selector]
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class SessionsController < Devise::SessionsController
|
||||
skip_authorization_check
|
||||
|
||||
def create
|
||||
# TODO: Create ID Card login here:
|
||||
# this is just testing config
|
||||
|
|
|
@ -8,4 +8,13 @@ module ApplicationHelper
|
|||
return '' if unstable_env.nil?
|
||||
"background-image: url(#{image_path(unstable_env.to_s + '.png')});"
|
||||
end
|
||||
|
||||
def ident_indicator(contact)
|
||||
case contact.ident_type
|
||||
when 'birthday'
|
||||
"[#{contact.ident_type}]"
|
||||
else
|
||||
"[#{contact.ident_country_code} #{contact.ident_type}]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
module WhodunnitHelper
|
||||
def link_to_whodunnit(whodunnit)
|
||||
return nil unless whodunnit
|
||||
if whodunnit.include?('-ApiUser')
|
||||
user = ApiUser.find(whodunnit)
|
||||
return link_to(user.username, admin_epp_user_path(user))
|
||||
end
|
||||
user = AdminUser.find(whodunnit)
|
||||
return link_to(user.username, admin_user_path(user))
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
return nil
|
||||
end
|
||||
|
||||
def whodunnit_with_protocol(whodunnit)
|
||||
return nil unless whodunnit
|
||||
if whodunnit.include?('-ApiUser')
|
||||
user = ApiUser.find(whodunnit)
|
||||
return "#{user.username} (EPP)"
|
||||
end
|
||||
user = AdminUser.find(whodunnit)
|
||||
return user.username
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
return nil
|
||||
end
|
||||
end
|
|
@ -2,16 +2,31 @@ class Ability
|
|||
include CanCan::Ability
|
||||
|
||||
def initialize(user)
|
||||
alias_action :create, :read, :update, :destroy, to: :crud
|
||||
alias_action :show, :create, :update, :destroy, to: :crud
|
||||
|
||||
@user = user || AdminUser.new
|
||||
@user.roles.each { |role| send(role) } if @user.roles
|
||||
|
||||
return if @user.roles || @user.roles.any?
|
||||
case @user.class.to_s
|
||||
when 'AdminUser'
|
||||
@user.roles.each { |role| send(role) } if @user.roles
|
||||
when 'ApiUser'
|
||||
epp
|
||||
end
|
||||
|
||||
can :show, :dashboard
|
||||
end
|
||||
|
||||
def epp
|
||||
# Epp::Contact
|
||||
can(:info, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw }
|
||||
can(:check, Epp::Contact)
|
||||
can(:create, Epp::Contact)
|
||||
can(:update, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id && c.auth_info == pw }
|
||||
can(:delete, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id && c.auth_info == pw }
|
||||
can(:renew, Epp::Contact)
|
||||
can(:view_password, Epp::Contact) { |c| c.registrar_id == @user.registrar_id }
|
||||
end
|
||||
|
||||
def user
|
||||
can :show, :dashboard
|
||||
end
|
||||
|
@ -30,6 +45,7 @@ class Ability
|
|||
can :manage, DomainVersion
|
||||
can :manage, User
|
||||
can :manage, ApiUser
|
||||
can :manage, Certificate
|
||||
can :manage, Keyrelay
|
||||
can :manage, LegalDocument
|
||||
can :read, ApiLog::EppLog
|
||||
|
|
|
@ -5,14 +5,24 @@ class ApiUser < User
|
|||
# TODO: should have max request limit per day
|
||||
belongs_to :registrar
|
||||
has_many :contacts
|
||||
has_many :certificates
|
||||
|
||||
validates :username, :password, :registrar, presence: true
|
||||
validates :username, uniqueness: true
|
||||
|
||||
before_save :create_crt, if: -> (au) { au.csr_changed? }
|
||||
|
||||
attr_accessor :registrar_typeahead
|
||||
|
||||
def ability
|
||||
@ability ||= Ability.new(self)
|
||||
end
|
||||
delegate :can?, :cannot?, to: :ability
|
||||
|
||||
after_initialize :set_defaults
|
||||
def set_defaults
|
||||
return unless new_record?
|
||||
self.active = true unless active_changed?
|
||||
end
|
||||
|
||||
def registrar_typeahead
|
||||
@registrar_typeahead || registrar || nil
|
||||
end
|
||||
|
@ -24,28 +34,5 @@ class ApiUser < User
|
|||
def queued_messages
|
||||
registrar.messages.queued
|
||||
end
|
||||
|
||||
def create_crt
|
||||
csr_file = Tempfile.new('client_csr')
|
||||
csr_file.write(csr)
|
||||
csr_file.rewind
|
||||
|
||||
crt_file = Tempfile.new('client_crt')
|
||||
_out, err, _st = Open3.capture3("openssl ca -keyfile #{APP_CONFIG['ca_key_path']} \
|
||||
-cert #{APP_CONFIG['ca_cert_path']} \
|
||||
-extensions usr_cert -notext -md sha256 \
|
||||
-in #{csr_file.path} -out #{crt_file.path} -key '#{APP_CONFIG['ca_key_password']}' -batch")
|
||||
|
||||
if err.match(/Data Base Updated/)
|
||||
crt_file.rewind
|
||||
self.crt = crt_file.read
|
||||
return true
|
||||
else
|
||||
errors.add(:base, I18n.t('failed_to_create_certificate'))
|
||||
logger.error('FAILED TO CREATE CLIENT CERTIFICATE')
|
||||
logger.error(err)
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/ClassLength
|
||||
|
|
|
@ -32,10 +32,10 @@ class ApiUserDeprecated < ActiveRecord::Base
|
|||
csr_file.rewind
|
||||
|
||||
crt_file = Tempfile.new('client_crt')
|
||||
_out, err, _st = Open3.capture3("openssl ca -keyfile #{APP_CONFIG['ca_key_path']} \
|
||||
-cert #{APP_CONFIG['ca_cert_path']} \
|
||||
_out, err, _st = Open3.capture3("openssl ca -keyfile #{ENV['ca_key_path']} \
|
||||
-cert #{ENV['ca_cert_path']} \
|
||||
-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/)
|
||||
crt_file.rewind
|
||||
|
|
88
app/models/certificate.rb
Normal file
88
app/models/certificate.rb
Normal file
|
@ -0,0 +1,88 @@
|
|||
class Certificate < ActiveRecord::Base
|
||||
include Versions
|
||||
|
||||
belongs_to :api_user
|
||||
|
||||
SIGNED = 'signed'
|
||||
UNSIGNED = 'unsigned'
|
||||
EXPIRED = 'expired'
|
||||
REVOKED = 'revoked'
|
||||
VALID = 'valid'
|
||||
|
||||
validates :csr, presence: true
|
||||
|
||||
def parsed_crt
|
||||
@p_crt ||= OpenSSL::X509::Certificate.new(crt) if crt
|
||||
end
|
||||
|
||||
def parsed_csr
|
||||
@p_csr ||= OpenSSL::X509::Request.new(csr) if csr
|
||||
end
|
||||
|
||||
def revoked?
|
||||
status == REVOKED
|
||||
end
|
||||
|
||||
def status
|
||||
return UNSIGNED if crt.blank?
|
||||
return @cached_status if @cached_status
|
||||
|
||||
@cached_status = SIGNED
|
||||
|
||||
if parsed_crt.not_before > Time.now.utc && parsed_crt.not_after < Time.now.utc
|
||||
@cached_status = EXPIRED
|
||||
end
|
||||
|
||||
crl = OpenSSL::X509::CRL.new(File.open(ENV['crl_path']).read)
|
||||
return @cached_status unless crl.revoked.map(&:serial).include?(parsed_crt.serial)
|
||||
|
||||
@cached_status = REVOKED
|
||||
end
|
||||
|
||||
def sign!
|
||||
csr_file = Tempfile.new('client_csr')
|
||||
csr_file.write(csr)
|
||||
csr_file.rewind
|
||||
|
||||
crt_file = Tempfile.new('client_crt')
|
||||
_out, err, _st = Open3.capture3("openssl ca -config #{ENV['openssl_config_path']} -keyfile #{ENV['ca_key_path']} \
|
||||
-cert #{ENV['ca_cert_path']} \
|
||||
-extensions usr_cert -notext -md sha256 \
|
||||
-in #{csr_file.path} -out #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
|
||||
|
||||
if err.match(/Data Base Updated/)
|
||||
crt_file.rewind
|
||||
self.crt = crt_file.read
|
||||
save!
|
||||
else
|
||||
errors.add(:base, I18n.t('failed_to_create_certificate'))
|
||||
logger.error('FAILED TO CREATE CLIENT CERTIFICATE')
|
||||
logger.error(err)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def revoke!
|
||||
crt_file = Tempfile.new('client_crt')
|
||||
crt_file.write(crt)
|
||||
crt_file.rewind
|
||||
|
||||
_out, err, _st = Open3.capture3("openssl ca -config #{ENV['openssl_config_path']} -keyfile #{ENV['ca_key_path']} \
|
||||
-cert #{ENV['ca_cert_path']} \
|
||||
-revoke #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch")
|
||||
|
||||
if err.match(/Data Base Updated/) || err.match(/ERROR:Already revoked/)
|
||||
save!
|
||||
@cached_status = REVOKED
|
||||
else
|
||||
errors.add(:base, I18n.t('failed_to_revoke_certificate'))
|
||||
logger.error('FAILED TO REVOKE CLIENT CERTIFICATE')
|
||||
logger.error(err)
|
||||
return false
|
||||
end
|
||||
|
||||
_out, _err, _st = Open3.capture3("openssl ca -config #{ENV['openssl_config_path']} -keyfile #{ENV['ca_key_path']} \
|
||||
-cert #{ENV['ca_cert_path']} \
|
||||
-gencrl -out #{ENV['crl_path']} -key '#{ENV['ca_key_password']}' -batch")
|
||||
end
|
||||
end
|
|
@ -3,42 +3,43 @@ module EppErrors
|
|||
|
||||
def construct_epp_errors
|
||||
epp_errors = []
|
||||
errors.messages.each do |key, values|
|
||||
key = key.to_s.split('.')[0].to_sym
|
||||
next if key == :epp_errors
|
||||
errors.messages.each do |attr, errors|
|
||||
attr = attr.to_s.split('.')[0].to_sym
|
||||
next if attr == :epp_errors
|
||||
|
||||
if self.class.reflect_on_association(key)
|
||||
epp_errors << collect_child_errors(key)
|
||||
if self.class.reflect_on_association(attr)
|
||||
epp_errors << collect_child_errors(attr)
|
||||
end
|
||||
|
||||
epp_errors << collect_parent_errors(values)
|
||||
epp_errors << collect_parent_errors(attr, errors)
|
||||
end
|
||||
|
||||
errors[:epp_errors] = epp_errors
|
||||
errors[:epp_errors].flatten!
|
||||
end
|
||||
|
||||
def collect_parent_errors(values)
|
||||
epp_errors = []
|
||||
values = [values] if values.is_a?(String)
|
||||
def collect_parent_errors(attr, errors)
|
||||
errors = [errors] if errors.is_a?(String)
|
||||
|
||||
values.each do |err|
|
||||
epp_errors = []
|
||||
errors.each do |err|
|
||||
code, value = find_epp_code_and_value(err)
|
||||
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
|
||||
epp_errors
|
||||
end
|
||||
|
||||
def collect_child_errors(key)
|
||||
macro = self.class.reflect_on_association(key).macro
|
||||
def collect_child_errors(attr)
|
||||
macro = self.class.reflect_on_association(attr).macro
|
||||
multi = [:has_and_belongs_to_many, :has_many]
|
||||
# single = [:belongs_to, :has_one]
|
||||
|
||||
epp_errors = []
|
||||
send(key).each do |x|
|
||||
x.errors.messages.each do |_key, values|
|
||||
epp_errors << x.collect_parent_errors(values)
|
||||
send(attr).each do |x|
|
||||
x.errors.messages.each do |attribute, errors|
|
||||
epp_errors << x.collect_parent_errors(attribute, errors)
|
||||
end
|
||||
end if multi.include?(macro)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ module VersionSession
|
|||
before_save :add_session
|
||||
|
||||
def add_session
|
||||
self.session = PaperSession.session
|
||||
self.session = ::PaperSession.session
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,9 +28,9 @@ module Versions
|
|||
return nil if creator_str.blank?
|
||||
|
||||
if creator_str =~ /^\d-api-/
|
||||
ApiUser.find(creator_str)
|
||||
ApiUser.find_by(id: creator_str)
|
||||
else
|
||||
AdminUser.find(creator_str)
|
||||
AdminUser.find_by(id: creator_str)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -38,9 +38,9 @@ module Versions
|
|||
return nil if updator_str.blank?
|
||||
|
||||
if updator_str =~ /^\d-api-/
|
||||
ApiUser.find(updator_str)
|
||||
ApiUser.find_by(id: updator_str)
|
||||
else
|
||||
AdminUser.find(updator_str)
|
||||
AdminUser.find_by(id: updator_str)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
class Contact < ActiveRecord::Base
|
||||
include Versions # version/contact_version.rb
|
||||
include EppErrors
|
||||
|
||||
has_one :address, dependent: :destroy
|
||||
has_one :disclosure, class_name: 'ContactDisclosure', dependent: :destroy
|
||||
|
@ -8,45 +7,46 @@ class Contact < ActiveRecord::Base
|
|||
has_many :domain_contacts
|
||||
has_many :domains, through: :domain_contacts
|
||||
has_many :statuses, class_name: 'ContactStatus'
|
||||
has_many :legal_documents, as: :documentable
|
||||
|
||||
belongs_to :registrar
|
||||
|
||||
accepts_nested_attributes_for :address, :disclosure
|
||||
accepts_nested_attributes_for :address, :disclosure, :legal_documents
|
||||
|
||||
validates :name, :phone, :email, :ident, :address, :registrar, :ident_type, presence: true
|
||||
|
||||
# Phone nr validation is very minimam in order to support legacy requirements
|
||||
validates :phone, format: /\+[0-9]{1,3}\.[0-9]{1,14}?/
|
||||
validates :email, format: /@/
|
||||
validates :ident, format: /\d{4}-\d{2}-\d{2}/, if: proc { |c| c.ident_type == 'birthday' }
|
||||
validates :ident,
|
||||
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 },
|
||||
format: { with: /\A[\w\-\:]*\Z/i },
|
||||
length: { maximum: 100 }
|
||||
|
||||
validate :ident_must_be_valid
|
||||
validate :ident_valid_format?
|
||||
|
||||
validates :code, uniqueness: { message: :epp_id_taken }
|
||||
delegate :street, to: :address
|
||||
delegate :city, to: :address
|
||||
delegate :zip, to: :address
|
||||
delegate :state, to: :address
|
||||
delegate :country_code, to: :address
|
||||
delegate :country, to: :address
|
||||
|
||||
delegate :city, to: :address # , prefix: true
|
||||
delegate :street, to: :address # , prefix: true
|
||||
delegate :zip, to: :address # , prefix: true
|
||||
|
||||
# callbacks
|
||||
# TODO: remove old
|
||||
# after_commit :domains_snapshot
|
||||
# after_update :domains_snapshot
|
||||
# after_destroy :domains_snapshot
|
||||
before_validation :set_ident_country_code
|
||||
before_create :generate_code
|
||||
before_create :generate_auth_info
|
||||
after_create :ensure_disclosure
|
||||
|
||||
# scopes
|
||||
scope :current_registrars, ->(id) { where(registrar_id: id) }
|
||||
|
||||
IDENT_TYPE_ICO = 'ico'
|
||||
IDENT_TYPE_BIC = 'bic'
|
||||
IDENT_TYPES = [
|
||||
IDENT_TYPE_ICO, # Company registry code (or similar)
|
||||
'bic', # Business registry code
|
||||
IDENT_TYPE_BIC, # Company registry code (or similar)
|
||||
'priv', # National idendtification number
|
||||
'op', # Estonian ID, depricated
|
||||
'passport', # Passport number, depricated
|
||||
'birthday' # Birthday date
|
||||
]
|
||||
|
||||
|
@ -54,124 +54,10 @@ class Contact < ActiveRecord::Base
|
|||
CONTACT_TYPE_ADMIN = 'admin'
|
||||
CONTACT_TYPES = [CONTACT_TYPE_TECH, CONTACT_TYPE_ADMIN]
|
||||
|
||||
def ident_must_be_valid
|
||||
# TODO: Ident can also be passport number or company registry code.
|
||||
# so have to make changes to validations (and doc/schema) accordingly
|
||||
return true unless ident.present? && ident_type.present? && ident_type == 'op'
|
||||
code = Isikukood.new(ident)
|
||||
errors.add(:ident, 'bad format') unless code.valid?
|
||||
end
|
||||
|
||||
def ensure_disclosure
|
||||
create_disclosure! unless disclosure
|
||||
end
|
||||
|
||||
# TODO: remove old
|
||||
# def domains_snapshot
|
||||
# (domains + domains_owned).uniq.each do |domain|
|
||||
# next unless domain.is_a?(Domain)
|
||||
# # next if domain.versions.last == domain.create_snapshot
|
||||
# domain.create_version # Method from paper_trail
|
||||
# end
|
||||
# end
|
||||
|
||||
def juridical?
|
||||
ident_type == IDENT_TYPE_ICO
|
||||
end
|
||||
|
||||
def citizen?
|
||||
ident_type != IDENT_TYPE_ICO
|
||||
end
|
||||
|
||||
def cr_id
|
||||
# created_by ? created_by.username : nil
|
||||
end
|
||||
|
||||
def up_id
|
||||
# updated_by ? updated_by.username : nil
|
||||
end
|
||||
|
||||
def auth_info_matches(pw)
|
||||
auth_info == pw
|
||||
end
|
||||
|
||||
# generate random id for contact
|
||||
def generate_code
|
||||
self.code = SecureRandom.hex(4)
|
||||
end
|
||||
|
||||
def generate_auth_info
|
||||
self.auth_info = SecureRandom.hex(16)
|
||||
end
|
||||
|
||||
# Find a way to use self.domains with contact
|
||||
def domains_owned
|
||||
Domain.where(owner_contact_id: id)
|
||||
end
|
||||
|
||||
def relations_with_domain?
|
||||
return true if domain_contacts.present? || domains_owned.present?
|
||||
false
|
||||
end
|
||||
|
||||
# should use only in transaction
|
||||
def destroy_and_clean
|
||||
if relations_with_domain?
|
||||
errors.add(:domains, :exist)
|
||||
return false
|
||||
end
|
||||
destroy
|
||||
end
|
||||
|
||||
def epp_code_map # rubocop:disable Metrics/MethodLength
|
||||
{
|
||||
'2302' => [ # Object exists
|
||||
[:code, :epp_id_taken]
|
||||
],
|
||||
'2305' => [ # Association exists
|
||||
[:domains, :exist]
|
||||
],
|
||||
'2005' => [ # Value syntax error
|
||||
[:phone, :invalid],
|
||||
[:email, :invalid],
|
||||
[:ident, :invalid]
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
# TODO: remove old
|
||||
# for archiving
|
||||
# def snapshot
|
||||
# {
|
||||
# name: name,
|
||||
# phone: phone,
|
||||
# code: code,
|
||||
# ident: ident,
|
||||
# email: email
|
||||
# }
|
||||
# end
|
||||
|
||||
class << self
|
||||
# non-EPP
|
||||
|
||||
# EPP
|
||||
def extract_attributes(ph, _type = :create)
|
||||
ph[:postalInfo] = ph[:postalInfo].first if ph[:postalInfo].is_a?(Array)
|
||||
contact_hash = {
|
||||
phone: ph[:voice],
|
||||
ident: ph[:ident],
|
||||
ident_type: ph[:ident_type],
|
||||
email: ph[:email],
|
||||
fax: ph[:fax],
|
||||
name: ph[:postalInfo].try(:[], :name),
|
||||
org_name: ph[:postalInfo].try(:[], :org)
|
||||
}
|
||||
# contact_hash[:auth_info] = ph[:authInfo][:pw] if type == :create
|
||||
contact_hash.delete_if { |_k, v| v.nil? }
|
||||
def search_by_query(query)
|
||||
res = search(code_cont: query).result
|
||||
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v.name} (#{v.code})" } }
|
||||
end
|
||||
|
||||
def check_availability(codes)
|
||||
|
@ -188,10 +74,84 @@ class Contact < ActiveRecord::Base
|
|||
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
def search_by_query(query)
|
||||
res = search(code_cont: query).result
|
||||
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v.name} (#{v.code})" } }
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def ident_valid_format?
|
||||
case ident_type
|
||||
when 'priv'
|
||||
case ident_country_code
|
||||
when 'EE'
|
||||
code = Isikukood.new(ident)
|
||||
errors.add(:ident, :invalid_EE_identity_format) unless code.valid?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_disclosure
|
||||
create_disclosure! unless disclosure
|
||||
end
|
||||
|
||||
def bic?
|
||||
ident_type == IDENT_TYPE_BIC
|
||||
end
|
||||
|
||||
def priv?
|
||||
ident_type != IDENT_TYPE_BIC
|
||||
end
|
||||
|
||||
def generate_code
|
||||
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)
|
||||
end
|
||||
|
||||
def relations_with_domain?
|
||||
return true if domain_contacts.present? || domains_owned.present?
|
||||
false
|
||||
end
|
||||
|
||||
# TODO: refactor, it should not allow to destroy with normal destroy,
|
||||
# no need separate method
|
||||
# should use only in transaction
|
||||
def destroy_and_clean
|
||||
if relations_with_domain?
|
||||
errors.add(:domains, :exist)
|
||||
return false
|
||||
end
|
||||
destroy
|
||||
end
|
||||
|
||||
def set_ident_country_code
|
||||
return true unless ident_country_code_changed? && ident_country_code.present?
|
||||
code = Country.new(ident_country_code)
|
||||
if code
|
||||
self.ident_country_code = code.alpha2
|
||||
else
|
||||
errors.add(:ident_country_code, 'is not following ISO_3166-1 alpha 2 format')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -85,9 +85,9 @@ class Dnskey < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def generate_ds_key_tag
|
||||
public_key.gsub!(' ', '')
|
||||
pk = public_key.gsub(' ', '')
|
||||
wire_format = [flags, protocol, alg].pack('S!>CC')
|
||||
wire_format += Base64.decode64(public_key)
|
||||
wire_format += Base64.decode64(pk)
|
||||
|
||||
c = 0
|
||||
wire_format.each_byte.with_index do |b, i|
|
||||
|
|
|
@ -20,8 +20,6 @@ class Domain < ActiveRecord::Base
|
|||
-> { where(domain_contacts: { contact_type: DomainContact::ADMIN }) },
|
||||
through: :domain_contacts, source: :contact
|
||||
|
||||
# TODO: remove old
|
||||
# has_many :nameservers, dependent: :delete_all, after_add: :track_nameserver_add
|
||||
has_many :nameservers, dependent: :delete_all
|
||||
|
||||
accepts_nested_attributes_for :nameservers, allow_destroy: true,
|
||||
|
@ -43,11 +41,11 @@ class Domain < ActiveRecord::Base
|
|||
has_many :legal_documents, as: :documentable
|
||||
accepts_nested_attributes_for :legal_documents, reject_if: proc { |attrs| attrs[:body].blank? }
|
||||
|
||||
delegate :code, to: :owner_contact, prefix: true
|
||||
delegate :code, to: :owner_contact, prefix: true
|
||||
delegate :email, to: :owner_contact, prefix: true
|
||||
delegate :ident, to: :owner_contact, prefix: true
|
||||
delegate :phone, to: :owner_contact, prefix: true
|
||||
delegate :name, to: :registrar, prefix: true
|
||||
delegate :name, to: :registrar, prefix: true
|
||||
|
||||
before_create :generate_auth_info
|
||||
before_create :set_validity_dates
|
||||
|
@ -118,11 +116,6 @@ class Domain < ActiveRecord::Base
|
|||
|
||||
attr_accessor :owner_contact_typeahead, :update_me
|
||||
|
||||
# TODO: remove old
|
||||
# archiving
|
||||
# if proc works only on changes on domain sadly
|
||||
# has_paper_trail class_name: 'DomainVersion', meta: { snapshot: :create_snapshot }, if: proc(&:new_version)
|
||||
|
||||
def tech_domain_contacts
|
||||
domain_contacts.select { |x| x.contact_type == DomainContact::TECH }
|
||||
end
|
||||
|
@ -131,52 +124,6 @@ class Domain < ActiveRecord::Base
|
|||
domain_contacts.select { |x| x.contact_type == DomainContact::ADMIN }
|
||||
end
|
||||
|
||||
# TODO: remove old
|
||||
# def new_version
|
||||
# return false if versions.try(:last).try(:snapshot) == create_snapshot
|
||||
# true
|
||||
# end
|
||||
|
||||
# TODO: remove old
|
||||
# def create_version
|
||||
# return true unless PaperTrail.enabled?
|
||||
# return true unless valid?
|
||||
# touch_with_version if new_version
|
||||
# end
|
||||
|
||||
# TODO: remove old
|
||||
# def track_nameserver_add(_nameserver)
|
||||
# return true if versions.count == 0
|
||||
# return true unless valid? && new_version
|
||||
|
||||
# touch_with_version
|
||||
# end
|
||||
|
||||
# TODO: remove old
|
||||
# def create_snapshot
|
||||
# oc = owner_contact.snapshot if owner_contact.is_a?(Contact)
|
||||
# {
|
||||
# owner_contact: oc,
|
||||
# tech_contacts: tech_contacts.map(&:snapshot),
|
||||
# admin_contacts: admin_contacts.map(&:snapshot),
|
||||
# nameservers: nameservers.map(&:snapshot),
|
||||
# domain: make_snapshot
|
||||
# }.to_yaml
|
||||
# end
|
||||
|
||||
# TODO: remove old
|
||||
# def make_snapshot
|
||||
# {
|
||||
# name: name,
|
||||
# status: status,
|
||||
# period: period,
|
||||
# period_unit: period_unit,
|
||||
# registrar_id: registrar.try(:id),
|
||||
# valid_to: valid_to,
|
||||
# valid_from: valid_from
|
||||
# }
|
||||
# end
|
||||
|
||||
def name=(value)
|
||||
value.strip!
|
||||
value.downcase!
|
||||
|
@ -265,7 +212,7 @@ class Domain < ActiveRecord::Base
|
|||
attach_contact(DomainContact::TECH, owner_contact)
|
||||
end
|
||||
|
||||
return unless admin_domain_contacts.count.zero? && owner_contact.citizen?
|
||||
return unless admin_domain_contacts.count.zero? && owner_contact.priv?
|
||||
attach_contact(DomainContact::ADMIN, owner_contact)
|
||||
end
|
||||
|
||||
|
@ -305,36 +252,36 @@ class Domain < ActiveRecord::Base
|
|||
# rubocop:disable Metrics/MethodLength
|
||||
def update_whois_body
|
||||
self.whois_body = <<-EOS
|
||||
This Whois Server contains information on
|
||||
Estonian Top Level Domain ee TLD
|
||||
This Whois Server contains information on
|
||||
Estonian Top Level Domain ee TLD
|
||||
|
||||
domain: #{name}
|
||||
registrar: #{registrar}
|
||||
status:
|
||||
registered:
|
||||
changed: #{updated_at.to_s(:db)}
|
||||
expire:
|
||||
outzone:
|
||||
delete:
|
||||
domain: #{name}
|
||||
registrar: #{registrar}
|
||||
status:
|
||||
registered:
|
||||
changed: #{updated_at.to_s(:db)}
|
||||
expire:
|
||||
outzone:
|
||||
delete:
|
||||
|
||||
contact
|
||||
name:
|
||||
e-mail:
|
||||
registrar:
|
||||
created:
|
||||
contact
|
||||
name:
|
||||
e-mail:
|
||||
registrar:
|
||||
created:
|
||||
|
||||
contact:
|
||||
contact:
|
||||
|
||||
nsset:
|
||||
nserver:
|
||||
nsset:
|
||||
nserver:
|
||||
|
||||
registrar:
|
||||
org:
|
||||
url:
|
||||
phone:
|
||||
address:
|
||||
created:
|
||||
changed:
|
||||
registrar:
|
||||
org:
|
||||
url:
|
||||
phone:
|
||||
address:
|
||||
created:
|
||||
changed:
|
||||
EOS
|
||||
end
|
||||
# rubocop:enabled Metrics/MethodLength
|
||||
|
|
102
app/models/epp/contact.rb
Normal file
102
app/models/epp/contact.rb
Normal file
|
@ -0,0 +1,102 @@
|
|||
# rubocop: disable Metrics/ClassLength
|
||||
class Epp::Contact < Contact
|
||||
include EppErrors
|
||||
|
||||
# disable STI, there is type column present
|
||||
self.inheritance_column = :sti_disabled
|
||||
|
||||
class << self
|
||||
# rubocop: disable Metrics/PerceivedComplexity
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
# rubocop: disable Metrics/MethodLength
|
||||
def attrs_from(frame)
|
||||
f = frame
|
||||
at = {}.with_indifferent_access
|
||||
at[:name] = f.css('postalInfo name').text if f.css('postalInfo name').present?
|
||||
at[:org_name] = f.css('postalInfo org').text if f.css('postalInfo org').present?
|
||||
at[:email] = f.css('email').text if f.css('email').present?
|
||||
at[:fax] = f.css('fax').text if f.css('fax').present?
|
||||
at[:phone] = f.css('voice').text if f.css('voice').present?
|
||||
at[:auth_info] = f.css('authInfo pw').text if f.css('authInfo pw').present?
|
||||
|
||||
if f.css('ident').present? && f.css('ident').attr('type').present?
|
||||
at[:ident] = f.css('ident').text
|
||||
at[:ident_type] = f.css('ident').attr('type').try(:text)
|
||||
at[:ident_country_code] = f.css('ident').attr('cc').try(:text)
|
||||
end
|
||||
|
||||
at[:address_attributes] = {}.with_indifferent_access
|
||||
sat = at[:address_attributes]
|
||||
sat[:city] = f.css('postalInfo addr city').text if f.css('postalInfo addr city').present?
|
||||
sat[:zip] = f.css('postalInfo addr pc').text if f.css('postalInfo addr pc').present?
|
||||
sat[:street] = f.css('postalInfo addr street').text if f.css('postalInfo addr street').present?
|
||||
sat[:state] = f.css('postalInfo addr sp').text if f.css('postalInfo addr sp').present?
|
||||
sat[:country_code] = f.css('postalInfo addr cc').text if f.css('postalInfo addr cc').present?
|
||||
at.delete(:address_attributes) if at[:address_attributes].blank?
|
||||
|
||||
legal_frame = f.css('legalDocument').first
|
||||
if legal_frame.present?
|
||||
at[:legal_documents_attributes] = legal_document_attrs(legal_frame)
|
||||
end
|
||||
|
||||
at
|
||||
end
|
||||
# rubocop: enable Metrics/MethodLength
|
||||
# rubocop: enable Metrics/PerceivedComplexity
|
||||
# rubocop: enable Metrics/CyclomaticComplexity
|
||||
|
||||
def new(frame, registrar)
|
||||
return super if frame.blank?
|
||||
|
||||
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)
|
||||
[{
|
||||
body: legal_frame.text,
|
||||
document_type: legal_frame['type']
|
||||
}]
|
||||
end
|
||||
end
|
||||
|
||||
def epp_code_map # rubocop:disable Metrics/MethodLength
|
||||
{
|
||||
'2302' => [ # Object exists
|
||||
[:code, :epp_id_taken]
|
||||
],
|
||||
'2305' => [ # Association exists
|
||||
[:domains, :exist]
|
||||
],
|
||||
'2005' => [ # Value syntax error
|
||||
[:phone, :invalid],
|
||||
[:email, :invalid],
|
||||
[:ident, :invalid],
|
||||
[:ident, :invalid_EE_identity_format],
|
||||
[:ident, :invalid_birthday_format]
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def update_attributes(frame)
|
||||
return super if frame.blank?
|
||||
at = {}.with_indifferent_access
|
||||
at.deep_merge!(self.class.attrs_from(frame.css('chg')))
|
||||
legal_frame = frame.css('legalDocument').first
|
||||
at[:legal_documents_attributes] = self.class.legal_document_attrs(legal_frame)
|
||||
|
||||
super(at)
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/ClassLength
|
|
@ -146,7 +146,7 @@ class Epp::EppDomain < Domain
|
|||
next
|
||||
end
|
||||
|
||||
if k == :admin && contact.juridical?
|
||||
if k == :admin && contact.bic?
|
||||
add_epp_error('2306', 'contact', x[:contact], [:domain_contacts, :admin_contact_can_be_only_citizen])
|
||||
next
|
||||
end
|
||||
|
|
|
@ -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(
|
||||
|
@ -23,7 +31,7 @@ class Registrar < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def address
|
||||
[street, city, state, zip].reject(&:empty?).compact.join(', ')
|
||||
[street, city, state, zip].reject(&:blank?).compact.join(', ')
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -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
|
||||
|
|
4
app/models/version/certificate_version.rb
Normal file
4
app/models/version/certificate_version.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
class CertificateVersion < PaperTrail::Version
|
||||
self.table_name = :log_certificates
|
||||
self.sequence_name = :log_certificates_id_seq
|
||||
end
|
|
@ -18,7 +18,7 @@ class ZonefileSetting < ActiveRecord::Base
|
|||
"select generate_zonefile('#{origin}')"
|
||||
)[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"
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
%hr
|
||||
|
||||
.row
|
||||
.col-md-6
|
||||
.col-md-12
|
||||
.form-group
|
||||
= f.label :username
|
||||
= f.text_field(:username, class: 'form-control')
|
||||
|
@ -26,11 +26,6 @@
|
|||
%label{for: 'api_user_active'}
|
||||
= f.check_box(:active)
|
||||
= t('active')
|
||||
|
||||
.col-md-6.text-left
|
||||
.form-group
|
||||
= f.label :csr, t('certificate_signing_req')
|
||||
= f.file_field :csr
|
||||
%hr
|
||||
.row
|
||||
.col-md-12.text-right
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
- if @api_user.errors.any?
|
||||
%hr
|
||||
.row
|
||||
.col-md-6
|
||||
.col-md-12
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
%h3.panel-title= t('general')
|
||||
|
@ -29,21 +29,24 @@
|
|||
|
||||
%dt= t('active')
|
||||
%dd= @api_user.active
|
||||
|
||||
.col-md-6
|
||||
.row
|
||||
.col-md-12
|
||||
.panel.panel-default
|
||||
.panel-heading
|
||||
%h3.panel-title= t('certificates')
|
||||
.panel-body
|
||||
%dl.dl-horizontal
|
||||
%dt= t('csr')
|
||||
- if @api_user.csr
|
||||
%dd= link_to(t('download'), download_csr_admin_api_user_path)
|
||||
- else
|
||||
%dd -
|
||||
.panel-heading.clearfix
|
||||
.pull-left
|
||||
= t('certificates')
|
||||
.pull-right
|
||||
= link_to(t('upload_csr'), new_admin_api_user_certificate_path(@api_user), class: 'btn btn-primary btn-xs')
|
||||
|
||||
%dt= t('crt')
|
||||
- if @api_user.csr
|
||||
%dd= link_to(t('download'), download_crt_admin_api_user_path)
|
||||
- else
|
||||
%dd -
|
||||
.table-responsive
|
||||
%table.table.table-hover.table-bordered.table-condensed
|
||||
%thead
|
||||
%tr
|
||||
%th{class: 'col-xs-10'}= t('subject')
|
||||
%th{class: 'col-xs-2'}= t('status')
|
||||
%tbody
|
||||
- @api_user.certificates.each do |x|
|
||||
- if x.csr
|
||||
%tr
|
||||
%td= link_to(x.parsed_csr.try(:subject), admin_api_user_certificate_path(@api_user, x))
|
||||
%td= x.status
|
||||
|
|
20
app/views/admin/certificates/new.haml
Normal file
20
app/views/admin/certificates/new.haml
Normal file
|
@ -0,0 +1,20 @@
|
|||
%h2= t('upload_csr')
|
||||
%hr
|
||||
= form_for([:admin, @api_user, @certificate], multipart: true) do |f|
|
||||
- if @certificate.errors.any?
|
||||
- @certificate.errors.each do |attr, err|
|
||||
= err
|
||||
%br
|
||||
- if @certificate.errors.any?
|
||||
%hr
|
||||
|
||||
.row
|
||||
.col-md-12.text-left
|
||||
.form-group
|
||||
= f.label :csr, t('certificate_signing_req')
|
||||
= f.file_field :csr
|
||||
%hr
|
||||
.row
|
||||
.col-md-12.text-right
|
||||
= button_tag(t('save'), class: 'btn btn-primary')
|
||||
|
75
app/views/admin/certificates/show.haml
Normal file
75
app/views/admin/certificates/show.haml
Normal file
|
@ -0,0 +1,75 @@
|
|||
.row
|
||||
.col-sm-6
|
||||
%h2.text-center-xs
|
||||
= t('certificates')
|
||||
.col-sm-6
|
||||
%h2.text-right.text-center-xs
|
||||
= link_to(t('back_to_api_user'), [:admin, @api_user], class: 'btn btn-default')
|
||||
|
||||
%hr
|
||||
- if @certificate.errors.any?
|
||||
- @certificate.errors.each do |attr, err|
|
||||
= err
|
||||
%br
|
||||
- if @certificate.errors.any?
|
||||
%hr
|
||||
.row
|
||||
.col-md-12
|
||||
.panel.panel-default
|
||||
.panel-heading.clearfix
|
||||
.pull-left
|
||||
= t('csr')
|
||||
.pull-right
|
||||
= link_to(t('download'), download_csr_admin_api_user_certificate_path(@api_user, @certificate), class: 'btn btn-default btn-xs')
|
||||
- unless @crt
|
||||
= link_to(t('sign_this_request'), sign_admin_api_user_certificate_path(@api_user, @certificate), method: :post, class: 'btn btn-primary btn-xs')
|
||||
|
||||
.panel-body
|
||||
%dl.dl-horizontal
|
||||
%dt= t('version')
|
||||
%dd= @csr.version
|
||||
|
||||
%dt= t('subject')
|
||||
%dd= @csr.subject
|
||||
|
||||
%dt= t('signature_algorithm')
|
||||
%dd= @csr.signature_algorithm
|
||||
|
||||
- if @crt
|
||||
.row
|
||||
.col-md-12
|
||||
.panel.panel-default
|
||||
.panel-heading.clearfix
|
||||
.pull-left
|
||||
= t('crt') unless @certificate.revoked?
|
||||
= t('crt_revoked') if @certificate.revoked?
|
||||
.pull-right
|
||||
= link_to(t('download'), download_crt_admin_api_user_certificate_path(@api_user, @certificate), class: 'btn btn-default btn-xs')
|
||||
- unless @certificate.revoked?
|
||||
= link_to(t('revoke_this_certificate'), revoke_admin_api_user_certificate_path(@api_user, @certificate), method: :post, class: 'btn btn-primary btn-xs')
|
||||
- if @crt
|
||||
.panel-body
|
||||
%dl.dl-horizontal
|
||||
%dt= t('version')
|
||||
%dd= @crt.version
|
||||
|
||||
%dt= t('serial_number')
|
||||
%dd= @crt.serial
|
||||
|
||||
%dt= t('signature_algorithm')
|
||||
%dd= @crt.signature_algorithm
|
||||
|
||||
%dt= t('issuer')
|
||||
%dd= @crt.issuer
|
||||
|
||||
%dt= t('valid_from')
|
||||
%dd= @crt.not_before
|
||||
|
||||
%dt= t('valid_to')
|
||||
%dd= @crt.not_after
|
||||
|
||||
%dt= t('subject')
|
||||
%dd= @crt.subject
|
||||
|
||||
%dt= t('extensions')
|
||||
%dd= @crt.extensions.map(&:to_s).join('<br>').html_safe
|
|
@ -22,20 +22,20 @@
|
|||
%thead
|
||||
%tr
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'name', t('name'))
|
||||
= sort_link(@q, 'name', t(:name))
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'code', t('code'))
|
||||
= sort_link(@q, 'ident', t(:identity))
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'ident', t('identity_code'))
|
||||
= sort_link(@q, 'email', t(:email))
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'email', t('email'))
|
||||
= sort_link(@q, 'code', t(:code))
|
||||
%tbody
|
||||
- @contacts.each do |x|
|
||||
- @contacts.each do |contact|
|
||||
%tr
|
||||
%td= link_to(x, admin_contact_path(x))
|
||||
%td= x.code
|
||||
%td= x.ident
|
||||
%td= x.email
|
||||
%td= link_to(contact, admin_contact_path(contact))
|
||||
%td= "#{contact.ident} #{ident_indicator(contact)}"
|
||||
%td= contact.email
|
||||
%td= contact.code
|
||||
.row
|
||||
.col-md-12
|
||||
= paginate @contacts
|
||||
|
|
|
@ -1,28 +1,24 @@
|
|||
.panel.panel-default
|
||||
.panel-heading
|
||||
%h3.panel-title= t('address')
|
||||
%h3.panel-title= t(:address)
|
||||
.panel-body
|
||||
- unless @contact.address.nil?
|
||||
%dl.dl-horizontal
|
||||
%dt= t('country')
|
||||
%dd= @contact.address.country
|
||||
- if @contact.bic?
|
||||
%dt= t(:org_name)
|
||||
%dd= @contact.org_name
|
||||
|
||||
%dt= t('city')
|
||||
%dd= @contact.address.city
|
||||
%dt= t(:street)
|
||||
%dd= @contact.street
|
||||
|
||||
%dt= t('street')
|
||||
%dd= @contact.address.street
|
||||
%dt= t(:city)
|
||||
%dd= @contact.city
|
||||
|
||||
- if @contact.address.street2
|
||||
%dt= t('street')
|
||||
%dd= @contact.address.street2
|
||||
%dt= t(:zip)
|
||||
%dd= @contact.zip
|
||||
|
||||
- if @contact.address.street3
|
||||
%dt= t('street')
|
||||
%dd= @contact.address.street3
|
||||
|
||||
|
||||
|
||||
%dt= t('zip')
|
||||
%dd= @contact.address.zip
|
||||
%dt= t(:state)
|
||||
%dd= @contact.state
|
||||
|
||||
%dt= t(:country)
|
||||
%dd= @contact.country
|
||||
|
|
|
@ -3,30 +3,25 @@
|
|||
%h3.panel-title= t('general')
|
||||
.panel-body
|
||||
%dl.dl-horizontal
|
||||
%dt= t('name')
|
||||
%dd= @contact.name
|
||||
%dt= t(:ident)
|
||||
%dd= "#{@contact.ident} #{ident_indicator(@contact)}"
|
||||
|
||||
%dt= t('org_name')
|
||||
%dd= @contact.org_name
|
||||
%br
|
||||
|
||||
%dt= t('code')
|
||||
%dd= @contact.code
|
||||
|
||||
%dt= t('ident')
|
||||
%dd= @contact.ident
|
||||
|
||||
%dt= t('ident_type')
|
||||
%dd= @contact.ident_type
|
||||
|
||||
%dt= t('email')
|
||||
%dt= t(:email)
|
||||
%dd= @contact.email
|
||||
|
||||
%dt= t('phone')
|
||||
%dt= t(:phone)
|
||||
%dd= @contact.phone
|
||||
|
||||
- if @contact.fax
|
||||
%dt= t('fax')
|
||||
%dt= t(:fax)
|
||||
%dd= @contact.fax
|
||||
|
||||
%br
|
||||
|
||||
%dt= t(:code)
|
||||
%dd= @contact.code
|
||||
|
||||
%dt= t('password')
|
||||
%dd= @contact.auth_info
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
.row
|
||||
.col-sm-12
|
||||
%h2.text-center-xs
|
||||
= "#{t('contact_details')}"
|
||||
= @contact.name
|
||||
%hr
|
||||
.row
|
||||
.col-md-6= render 'admin/contacts/partials/general'
|
||||
.col-md-6= render 'admin/contacts/partials/address'
|
||||
.row
|
||||
.col-md-12= render 'admin/contacts/partials/domains'
|
||||
.row
|
||||
.col-md-12
|
||||
= render 'admin/domains/partials/legal_documents', legal_documents: @contact.legal_documents
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
%th{class: 'col-xs-8'}= t('created_at')
|
||||
%th{class: 'col-xs-4'}= t('type')
|
||||
%tbody
|
||||
- @domain.legal_documents.each do |x|
|
||||
- legal_documents.each do |x|
|
||||
%tr
|
||||
%td= link_to(x.created_at, [:admin, x])
|
||||
%td= x.document_type
|
||||
|
|
|
@ -24,4 +24,5 @@
|
|||
.row
|
||||
.col-md-12= render 'admin/domains/partials/keyrelays'
|
||||
.row
|
||||
.col-md-12= render 'admin/domains/partials/legal_documents'
|
||||
.col-md-12
|
||||
= render 'admin/domains/partials/legal_documents', legal_documents: @domain.legal_documents
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
address = @contact.address
|
||||
xml.tag!('contact:postalInfo', type: 'int') do
|
||||
xml.tag!('contact:name', @contact.name) if @disclosure.try(:[], :name) || @owner
|
||||
xml.tag!('contact:org', @contact.org_name) if @disclosure.try(:[], :org_name) || @owner
|
||||
if @disclosure.try(:addr) || @owner
|
||||
xml.tag!('contact:name', @contact.name) #if @disclosure.try(:[], :name) || @owner
|
||||
xml.tag!('contact:org', @contact.org_name) #if @disclosure.try(:[], :org_name) || @owner
|
||||
# if @disclosure.try(:addr) || @owner
|
||||
xml.tag!('contact:addr') do
|
||||
xml.tag!('contact:street', address.street) if address
|
||||
xml.tag!('contact:cc', address.country_code) unless address.country_code.nil?
|
||||
xml.tag!('contact:city', address.city) if address
|
||||
xml.tag!('contact:street', @contact.street)
|
||||
xml.tag!('contact:city', @contact.city)
|
||||
xml.tag!('contact:pc', @contact.zip)
|
||||
xml.tag!('contact:sp', @contact.state)
|
||||
xml.tag!('contact:cc', @contact.country_code)
|
||||
end
|
||||
end
|
||||
# end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,11 +6,10 @@ xml.epp_head do
|
|||
|
||||
xml.resData do
|
||||
xml.tag!('contact:chkData', 'xmlns:contact' => 'urn:ietf:params:xml:ns:contact-1.0') do
|
||||
#xml.tag!('contact:id', @contact.code)
|
||||
@contacts.each do |contact|
|
||||
@results.each do |result|
|
||||
xml.tag!('contact:cd') do
|
||||
xml.tag! "contact:id", contact[:code], avail: contact[:avail]
|
||||
xml.tag!('contact:reason', contact[:reason]) unless contact[:avail] == 1
|
||||
xml.tag! "contact:id", result[:code], avail: result[:avail]
|
||||
xml.tag!('contact:reason', result[:reason]) unless result[:avail] == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,9 +8,9 @@ xml.epp_head do
|
|||
xml.tag!('contact:chkData', 'xmlns:contact' => 'urn:ietf:params:xml:ns:contact-1.0') do
|
||||
xml.tag!('contact:id', @contact.code)
|
||||
xml << render('/epp/contacts/postal_info')
|
||||
xml.tag!('contact:voice', @contact.phone) if @disclosure.try(:phone) || @owner
|
||||
xml.tag!('contact:fax', @contact.fax) if @disclosure.try(:fax) || @owner
|
||||
xml.tag!('contact:email', @contact.email) if @disclosure.try(:email) || @owner
|
||||
xml.tag!('contact:voice', @contact.phone) #if @disclosure.try(:phone) || @owner
|
||||
xml.tag!('contact:fax', @contact.fax) #if @disclosure.try(:fax) || @owner
|
||||
xml.tag!('contact:email', @contact.email) #if @disclosure.try(:email) || @owner
|
||||
xml.tag!('contact:clID', @contact.registrar.try(:name))
|
||||
xml.tag!('contact:crID', @contact.creator.try(:registrar))
|
||||
xml.tag!('contact:crDate', @contact.created_at)
|
||||
|
@ -18,18 +18,17 @@ xml.epp_head do
|
|||
xml.tag!('contact:upID', @contact.updator.try(:registrar))
|
||||
xml.tag!('contact:upDate', @contact.updated_at)
|
||||
end
|
||||
xml.tag!('contact:ident', @contact.ident, type: @contact.ident_type)
|
||||
xml.tag!('contact:trDate', '123') if false
|
||||
if @owner
|
||||
xml.tag!('contact:ident', @contact.ident, type: @contact.ident_type, cc: @contact.ident_country_code)
|
||||
# xml.tag!('contact:trDate', '123') if false
|
||||
if can? :view_password, @contact
|
||||
xml.tag!('contact:authInfo') do
|
||||
xml.tag!('contact:pw', @contact.auth_info) # Doc says we have to return this but is it necessary?
|
||||
xml.tag!('contact:pw', @contact.auth_info)
|
||||
end
|
||||
end
|
||||
# statuses
|
||||
@contact.statuses.each do |cs|
|
||||
xml.tag!('contact:status', s: cs.value)
|
||||
@contact.statuses.each do |status|
|
||||
xml.tag!('contact:status', s: status.value)
|
||||
end
|
||||
xml << render('/epp/contacts/disclosure_policy')
|
||||
# xml << render('/epp/contacts/disclosure_policy')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
%span.icon-bar
|
||||
%span.icon-bar
|
||||
= link_to admin_dashboard_path, class: 'navbar-brand' do
|
||||
= APP_CONFIG['app_name']
|
||||
= ENV['app_name']
|
||||
- if unstable_env.present?
|
||||
.text-center
|
||||
%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 ..
|
||||
|
||||
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
|
||||
|
||||
RAILS_ENV=test bundle exec rake db:drop
|
||||
RAILS_ENV=test bundle exec rake db:all:create
|
||||
RAILS_ENV=test bundle exec rake db:all:schema:load
|
||||
RAILS_ENV=test bundle exec rake db:seed
|
||||
RAILS_ENV=test bundle exec rake db:all:drop
|
||||
RAILS_ENV=test bundle exec rake db:all:setup
|
||||
RAILS_ENV=test bundle exec rake assets:precompile
|
||||
|
||||
echo "GIT_LAST_COMMITS"
|
||||
|
@ -36,6 +36,10 @@ RCODE=$?
|
|||
echo "END_OF_RUBOCOP_RESULTS"
|
||||
|
||||
echo "TEST_RESULTS"
|
||||
# basic test
|
||||
# ROBOT=true bundle exec rake
|
||||
|
||||
# all tests with EPP
|
||||
ROBOT=true bundle exec rake test
|
||||
TCODE=$?
|
||||
echo "END_OF_TEST_RESULTS"
|
||||
|
@ -45,7 +49,7 @@ bundle exec bundle-audit update
|
|||
bundle exec bundle-audit
|
||||
BCODE=$?
|
||||
BCODE=0 # tmp
|
||||
bundle exec brakeman
|
||||
bundle exec brakeman -q
|
||||
echo "END_OF_SECURITY_RESULTS"
|
||||
|
||||
# update code review
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
defaults: &defaults
|
||||
app_name: .EE Registry
|
||||
zonefile_export_dir: 'export/zonefiles'
|
||||
# Be sure to restart your server when you modify settings.
|
||||
|
||||
# You can use `rake secret` to generate a secure secret key.
|
||||
# Your secret key is used for verifying the integrity of signed cookies.
|
||||
# If you change this key, all old signed cookies will become invalid!
|
||||
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
|
||||
ca_cert_path: ca-cert-path-here
|
||||
ca_key_path: ca-key-path-here
|
||||
ca_key_password: ca-key-pass-phrase-here
|
||||
app_name: .EE Registry
|
||||
zonefile_export_dir: 'export/zonefiles'
|
||||
|
||||
development:
|
||||
<<: *defaults
|
||||
# You can use `rake secret` to generate a secure secret key.
|
||||
# Your secret key is used for verifying the integrity of signed cookies.
|
||||
# If you change this key, all old signed cookies will become invalid!
|
||||
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
|
||||
|
||||
# Used by admin server, you can leave those empty for when running EPP server:
|
||||
openssl_config_path: '/etc/ssl/openssl.cnf'
|
||||
crl_path: '/home/registry/registry/shared/ca/crl/crl.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_password: 'your-root-key-password'
|
||||
|
||||
# Used only by EPP server, you can leave it empty when running admin server:
|
||||
webclient_ip: '127.0.0.1'
|
||||
|
||||
# autotest config overwrites
|
||||
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
|
19
config/database-travis.yml
Normal file
19
config/database-travis.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
default: &default
|
||||
host: localhost
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
pool: 5
|
||||
username: postgres
|
||||
password:
|
||||
|
||||
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
|
||||
# random tokens. Changing this key will render invalid all existing
|
||||
# confirmation, reset password and unlock tokens in the database.
|
||||
config.secret_key = APP_CONFIG['devise_secret']
|
||||
config.secret_key = ENV['devise_secret']
|
||||
|
||||
# ==> Mailer Configuration
|
||||
# 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.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_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']
|
|
@ -1,24 +1,3 @@
|
|||
# Files in the config/locales directory are used for internationalization
|
||||
# and are automatically loaded by Rails. If you want to use locales other
|
||||
# than English, add the necessary files in this directory.
|
||||
#
|
||||
# To use the locales, use `I18n.t`:
|
||||
#
|
||||
# I18n.t 'hello'
|
||||
#
|
||||
# In views, this is aliased to just `t`:
|
||||
#
|
||||
# <%= t('hello') %>
|
||||
#
|
||||
# To use a different locale, set it with `I18n.locale`:
|
||||
#
|
||||
# I18n.locale = :es
|
||||
#
|
||||
# This would use the information in config/locales/es.yml.
|
||||
#
|
||||
# To learn more, please read the Rails Internationalization guide
|
||||
# available at http://guides.rubyonrails.org/i18n.html.
|
||||
|
||||
en:
|
||||
views:
|
||||
pagination:
|
||||
|
@ -52,7 +31,6 @@ en:
|
|||
activerecord:
|
||||
errors:
|
||||
models:
|
||||
|
||||
contact:
|
||||
attributes:
|
||||
code:
|
||||
|
@ -67,6 +45,8 @@ en:
|
|||
invalid: "Email is invalid"
|
||||
ident:
|
||||
blank: "Required parameter missing - ident"
|
||||
invalid_EE_identity_format: "Ident not in valid Estonian identity format."
|
||||
invalid_birthday_format: "Ident not in valid birthady format, should be YYYY-MM-DD"
|
||||
domains:
|
||||
exist: 'Object association prohibits operation'
|
||||
|
||||
|
@ -258,7 +238,7 @@ en:
|
|||
invalid_type: 'PostalInfo type is invalid'
|
||||
unimplemented_command: 'Unimplemented command'
|
||||
domain_exists_but_belongs_to_other_registrar: 'Domain exists but belongs to other registrar'
|
||||
|
||||
required_attribute_missing: Required attributes missing
|
||||
|
||||
code: 'Code'
|
||||
value: 'Value'
|
||||
|
@ -321,7 +301,7 @@ en:
|
|||
domain_status_prohibits_deleting: 'Domain status prohibits deleting'
|
||||
domain_deleted: 'Domain deleted!'
|
||||
failed_to_delete_domain: 'Failed to delete domain!'
|
||||
email: 'Email'
|
||||
email: 'E-mail'
|
||||
fax: 'Fax'
|
||||
contact_details: 'Contact details'
|
||||
ident: 'Ident'
|
||||
|
@ -330,8 +310,8 @@ en:
|
|||
country: 'Country'
|
||||
city: 'City'
|
||||
street: 'Street'
|
||||
zip: 'Zip'
|
||||
org_name: 'Organisation name'
|
||||
zip: 'Postcode'
|
||||
org_name: 'Org name'
|
||||
failed_to_add_domain: 'Failed to add domain!'
|
||||
domain_added: 'Domain added!'
|
||||
new_contact: 'New contact'
|
||||
|
@ -502,3 +482,11 @@ en:
|
|||
download: 'Download'
|
||||
failed_to_create_certificate: 'Failed to create certificate!'
|
||||
registrant_not_found: 'Registrant not found'
|
||||
failed_to_revoke_certificate: 'Failed to revoke certificate!'
|
||||
contact_code: Contact code
|
||||
upload_csr: 'Upload CSR'
|
||||
signature_algorithm: 'Signature algorithm'
|
||||
version: 'Version'
|
||||
sign_this_request: 'Sign this request'
|
||||
revoke_this_certificate: 'Revoke this certificate'
|
||||
crt_revoked: 'CRT (revoked)'
|
||||
|
|
|
@ -3,6 +3,7 @@ require 'epp_constraint'
|
|||
Rails.application.routes.draw do
|
||||
namespace(:epp, defaults: { format: :xml }) do
|
||||
match 'session/:action', controller: 'sessions', via: :all
|
||||
match 'session/pki/:action', controller: 'sessions', via: :all
|
||||
|
||||
post 'command/:action', controller: 'domains', constraints: EppConstraint.new(:domain)
|
||||
post 'command/:action', controller: 'contacts', constraints: EppConstraint.new(:contact)
|
||||
|
@ -47,9 +48,13 @@ Rails.application.routes.draw do
|
|||
|
||||
resources :admin_users
|
||||
resources :api_users do
|
||||
member do
|
||||
get 'download_csr'
|
||||
get 'download_crt'
|
||||
resources :certificates do
|
||||
member do
|
||||
post 'sign'
|
||||
post 'revoke'
|
||||
get 'download_csr'
|
||||
get 'download_crt'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
5
db/migrate/20150212125339_add_state_to_address.rb
Normal file
5
db/migrate/20150212125339_add_state_to_address.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddStateToAddress < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :addresses, :state, :string
|
||||
end
|
||||
end
|
5
db/migrate/20150217133755_add_country_code_ident.rb
Normal file
5
db/migrate/20150217133755_add_country_code_ident.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddCountryCodeIdent < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :contacts, :ident_country_code, :string
|
||||
end
|
||||
end
|
5
db/migrate/20150217133937_add_index_for_contact_code.rb
Normal file
5
db/migrate/20150217133937_add_index_for_contact_code.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddIndexForContactCode < ActiveRecord::Migration
|
||||
def change
|
||||
add_index :contacts, :code
|
||||
end
|
||||
end
|
29
db/migrate/20150223104842_create_certificates.rb
Normal file
29
db/migrate/20150223104842_create_certificates.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
class CreateCertificates < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :certificates do |t|
|
||||
t.integer :api_user_id
|
||||
t.text :csr
|
||||
t.text :crt
|
||||
t.string :creator_str
|
||||
t.string :updator_str
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :log_certificates do |t|
|
||||
t.string "item_type", null: false
|
||||
t.integer "item_id", null: false
|
||||
t.string "event", null: false
|
||||
t.string "whodunnit"
|
||||
t.json "object"
|
||||
t.json "object_changes"
|
||||
t.datetime "created_at"
|
||||
t.string "session"
|
||||
t.json "children"
|
||||
end
|
||||
|
||||
ApiUser.all.each do |x|
|
||||
x.certificates << Certificate.new(crt: x.crt, csr: x.csr)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -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(validate: false)
|
||||
end
|
||||
end
|
||||
end
|
37
db/schema.rb
37
db/schema.rb
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150213104014) do
|
||||
ActiveRecord::Schema.define(version: 20150303151224) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -29,6 +29,7 @@ ActiveRecord::Schema.define(version: 20150213104014) do
|
|||
t.string "creator_str"
|
||||
t.string "updator_str"
|
||||
t.string "country_code"
|
||||
t.string "state"
|
||||
end
|
||||
|
||||
create_table "api_users", force: :cascade do |t|
|
||||
|
@ -52,6 +53,16 @@ ActiveRecord::Schema.define(version: 20150213104014) do
|
|||
|
||||
add_index "cached_nameservers", ["hostname", "ipv4", "ipv6"], name: "index_cached_nameservers_on_hostname_and_ipv4_and_ipv6", unique: true, using: :btree
|
||||
|
||||
create_table "certificates", force: :cascade do |t|
|
||||
t.integer "api_user_id"
|
||||
t.text "csr"
|
||||
t.text "crt"
|
||||
t.string "creator_str"
|
||||
t.string "updator_str"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "contact_disclosures", force: :cascade do |t|
|
||||
t.integer "contact_id"
|
||||
t.boolean "phone"
|
||||
|
@ -95,8 +106,11 @@ ActiveRecord::Schema.define(version: 20150213104014) do
|
|||
t.integer "registrar_id"
|
||||
t.string "creator_str"
|
||||
t.string "updator_str"
|
||||
t.string "ident_country_code"
|
||||
end
|
||||
|
||||
add_index "contacts", ["code"], name: "index_contacts_on_code", using: :btree
|
||||
|
||||
create_table "countries", force: :cascade do |t|
|
||||
t.string "iso"
|
||||
t.string "name"
|
||||
|
@ -271,6 +285,18 @@ ActiveRecord::Schema.define(version: 20150213104014) do
|
|||
add_index "log_api_users", ["item_type", "item_id"], name: "index_log_api_users_on_item_type_and_item_id", using: :btree
|
||||
add_index "log_api_users", ["whodunnit"], name: "index_log_api_users_on_whodunnit", using: :btree
|
||||
|
||||
create_table "log_certificates", force: :cascade do |t|
|
||||
t.string "item_type", null: false
|
||||
t.integer "item_id", null: false
|
||||
t.string "event", null: false
|
||||
t.string "whodunnit"
|
||||
t.json "object"
|
||||
t.json "object_changes"
|
||||
t.datetime "created_at"
|
||||
t.string "session"
|
||||
t.json "children"
|
||||
end
|
||||
|
||||
create_table "log_contact_disclosures", force: :cascade do |t|
|
||||
t.string "item_type", null: false
|
||||
t.integer "item_id", null: false
|
||||
|
@ -585,8 +611,11 @@ ActiveRecord::Schema.define(version: 20150213104014) 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"
|
||||
|
@ -614,19 +643,19 @@ ActiveRecord::Schema.define(version: 20150213104014) do
|
|||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "email"
|
||||
t.integer "sign_in_count", default: 0, null: false
|
||||
t.integer "sign_in_count", default: 0, null: false
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.inet "current_sign_in_ip"
|
||||
t.inet "last_sign_in_ip"
|
||||
t.string "identity_code"
|
||||
t.integer "country_id"
|
||||
t.string "roles", array: true
|
||||
t.string "roles", array: true
|
||||
t.string "creator_str"
|
||||
t.string "updator_str"
|
||||
t.string "country_code"
|
||||
t.integer "registrar_id"
|
||||
t.boolean "active", default: false
|
||||
t.boolean "active"
|
||||
t.text "csr"
|
||||
t.text "crt"
|
||||
t.string "type"
|
||||
|
|
32
db/seeds.rb
32
db/seeds.rb
|
@ -4,7 +4,10 @@
|
|||
registrar1 = Registrar.where(
|
||||
name: 'Registrar First AS',
|
||||
reg_no: '10300220',
|
||||
address: 'Pärnu mnt 2, Tallinna linn, Harju maakond, 11415',
|
||||
street: 'Pärnu mnt 2',
|
||||
city: 'Tallinn',
|
||||
state: 'Harju maakond',
|
||||
zip: '11415',
|
||||
email: 'registrar1@example.com',
|
||||
country_code: 'EE'
|
||||
).first_or_create!
|
||||
|
@ -19,7 +22,10 @@ ApiUser.where(
|
|||
registrar2 = Registrar.where(
|
||||
name: 'Registrar Second AS',
|
||||
reg_no: '10529229',
|
||||
address: 'Vabaduse pst 32, 11316 Tallinn',
|
||||
street: 'Vabaduse pst 32',
|
||||
city: 'Tallinn',
|
||||
state: 'Harju maakond',
|
||||
zip: '11315',
|
||||
email: 'registrar2@example.com',
|
||||
country_code: 'EE'
|
||||
).first_or_create!
|
||||
|
@ -55,4 +61,26 @@ AdminUser.where(
|
|||
country_code: 'EE'
|
||||
).first_or_create!
|
||||
|
||||
ZonefileSetting.where({
|
||||
origin: 'ee',
|
||||
ttl: 43200,
|
||||
refresh: 3600,
|
||||
retry: 900,
|
||||
expire: 1209600,
|
||||
minimum_ttl: 3600,
|
||||
email: 'hostmaster.eestiinternet.ee',
|
||||
master_nameserver: 'ns.tld.ee'
|
||||
}).first_or_create!
|
||||
|
||||
ZonefileSetting.where({
|
||||
origin: 'pri.ee',
|
||||
ttl: 43200,
|
||||
refresh: 3600,
|
||||
retry: 900,
|
||||
expire: 1209600,
|
||||
minimum_ttl: 3600,
|
||||
email: 'hostmaster.eestiinternet.ee',
|
||||
master_nameserver: 'ns.tld.ee'
|
||||
}).first_or_create!
|
||||
|
||||
AdminUser.update_all(roles: ['admin'])
|
||||
|
|
|
@ -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)
|
||||
instead of Capistrano.
|
||||
### Debian setup
|
||||
|
||||
* [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.
|
||||
|
||||
|
@ -68,3 +109,13 @@ General rake and mina tips:
|
|||
rake -T # list all rake commands
|
||||
rake -T db # list all database related 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.
|
||||
|
||||
|
|
196
doc/certificates.md
Normal file
196
doc/certificates.md
Normal file
|
@ -0,0 +1,196 @@
|
|||
Certificates setup
|
||||
------------------
|
||||
|
||||
Guide to setup all registry/epp/repp, webclient and api user certificates.
|
||||
|
||||
There are three type of certificates:
|
||||
|
||||
* root cert (one time action using command line)
|
||||
* webclient server cert (one time action using command line)
|
||||
* api user cert (multiple actions through admin interface)
|
||||
|
||||
API users CSR are uploaded through registry admin interface for each API user.
|
||||
|
||||
Private key and certificate must be packaged to pkcs12 and added to user browser.
|
||||
|
||||
|
||||
### 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:
|
||||
|
||||
sudo cp /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.bak
|
||||
sudo vi /etc/ssl/openssl.cnf
|
||||
|
||||
Make sure the following options are in place:
|
||||
|
||||
[ CA_default ]
|
||||
# Where everything is kept
|
||||
dir = /home/registry/registry/shared/ca # around line nr 42
|
||||
|
||||
crl_extensions = crl_ext # around line nr 71
|
||||
|
||||
# For the CA policy
|
||||
[ policy_match ]
|
||||
countryName = optional # around line nr 85
|
||||
stateOrProvinceName = optional # around line nr 86
|
||||
organizationName = optional # around line nr 87
|
||||
organizationalUnitName = optional # around line nr 88
|
||||
commonName = supplied # around line nr 89
|
||||
emailAddress = optional # around line nr 90
|
||||
|
||||
[ usr_cert ]
|
||||
# These extensions are added when 'ca' signs a request.
|
||||
basicConstraints=CA:FALSE # around line nr 170
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment # around line nr 188
|
||||
nsComment = "OpenSSL Generated Certificate" # around line nr 191
|
||||
subjectKeyIdentifier=hash # around line nr 194
|
||||
authorityKeyIdentifier=keyid,issuer # around line nr 195
|
||||
|
||||
[ v3_ca ]
|
||||
# Extensions for a typical CA
|
||||
subjectKeyIdentifier=hash # around line nr 232
|
||||
authorityKeyIdentifier=keyid:always,issuer # around line nr 234
|
||||
basicConstraints = CA:true # around line nr 240
|
||||
keyUsage = cRLSign, keyCertSign # around line nr 245
|
||||
|
||||
Generate the root key and remember your password, you need it later in application.yml:
|
||||
|
||||
openssl genrsa -aes256 -out private/ca.key.pem 4096
|
||||
|
||||
Create root registry certificate (prompts for additional data and review days flag):
|
||||
|
||||
openssl req -new -x509 -days 3653 -key private/ca.key.pem -sha256 -extensions v3_ca -out certs/ca.crt.pem
|
||||
chmod 444 certs/ca.crt.pem
|
||||
|
||||
Create a webclient key and CSR for accepting webclient request:
|
||||
|
||||
openssl genrsa -out private/webclient.key.pem 4096
|
||||
chmod 400 private/webclient.key.pem
|
||||
openssl req -sha256 -new -days 3653 -key private/webclient.key.pem -out csrs/webclient.csr.pem
|
||||
|
||||
Sign CSR and create certificate:
|
||||
|
||||
openssl ca -keyfile private/ca.key.pem -cert certs/ca.crt.pem -extensions usr_cert -notext -md sha256 -in csrs/webclient.csr.pem -days 3653 -out certs/webclient.crt.pem
|
||||
chmod 444 certs/webclient.crt.pem
|
||||
|
||||
Create certificate revocation list (prompts for pass phrase):
|
||||
|
||||
openssl ca -keyfile private/ca.key.pem -cert certs/ca.crt.pem -gencrl -out crl/crl.pem
|
||||
|
||||
Configure registry registry/shared/config/application.yml to match the CA settings:
|
||||
|
||||
openssl_config_path: '/etc/ssl/openssl.cnf'
|
||||
crl_path: '/home/registry/registry/shared/ca/crl/crl.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_password: 'your-root-key-password'
|
||||
|
||||
|
||||
### Registry EPP setup
|
||||
|
||||
Configure registry epp registry-epp/shared/config/application.yml:
|
||||
|
||||
webclient_ip: '54.154.91.240'
|
||||
|
||||
Configure EPP port 700 virtual host:
|
||||
|
||||
sudo vi /etc/apache2/sites-enabled/epp.conf
|
||||
|
||||
Replace this line:
|
||||
|
||||
SSLVerifyClient optional_no_ca
|
||||
|
||||
With these lines:
|
||||
|
||||
SSLVerifyClient require
|
||||
SSLVerifyDepth 1
|
||||
SSLCACertificateFile /home/registry/registry/shared/ca/certs/ca.crt.pem
|
||||
SSLCARevocationFile /home/registry/registry/shared/ca/crl/crl.pem
|
||||
# Uncomment this when upgrading to apache 2.4:
|
||||
# SSLCARevocationCheck chain
|
||||
RequestHeader set SSL_CLIENT_S_DN_CN "%{SSL_CLIENT_S_DN_CN}s"
|
||||
|
||||
Reload apache:
|
||||
|
||||
sudo a2enmod headers
|
||||
sudo /etc/init.d/apache2 restart
|
||||
|
||||
|
||||
### Webclient setup
|
||||
|
||||
Copy all registry/shared/ca directory to your webclient server if webclient is in different server,
|
||||
otherwise just point everything to your registry/shared/ca directory.
|
||||
|
||||
Configure webclient/shared/config/application.yml to match the CA settings:
|
||||
|
||||
cert_path: '/home/webclient/webclient/shared/ca/certs/webclient.crt.pem'
|
||||
key_path: '/home/webclient/webclient/shared/ca/private/webclient.key.pem'
|
||||
|
||||
Configure webclient virtual host:
|
||||
|
||||
sudo vi /etc/apache2/sites-enabled/webclient.conf
|
||||
|
||||
Add these lines:
|
||||
|
||||
SSLVerifyClient none
|
||||
SSLVerifyDepth 1
|
||||
SSLCACertificateFile /home/webclient/webclient/shared/ca/certs/ca.crt.pem
|
||||
SSLCARevocationFile /home/webclient/webclient/shared/ca/crl/crl.pem
|
||||
# Uncomment this when upgrading to apache 2.4:
|
||||
# SSLCARevocationCheck chain
|
||||
|
||||
RequestHeader set SSL_CLIENT_S_DN_CN ""
|
||||
|
||||
<Location /sessions/pki>
|
||||
SSLVerifyClient require
|
||||
RequestHeader set SSL_CLIENT_S_DN_CN "%{SSL_CLIENT_S_DN_CN}s"
|
||||
</Location>
|
||||
|
||||
Reload apache:
|
||||
|
||||
sudo a2enmod headers
|
||||
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
|
||||
---------------
|
||||
|
||||
In development environment it's convenient to set unique_subject option to false,
|
||||
thus you can generate quickly as many certs as you wish.
|
||||
|
||||
In CA directory:
|
||||
|
||||
echo "unique_subject = no" > index.txt.attr
|
|
@ -1,6 +1,6 @@
|
|||
## Contact related functions
|
||||
|
||||
Please study official Cantact Mapping protocol:
|
||||
Please study official Contact Mapping protocol:
|
||||
http://tools.ietf.org/html/rfc5733
|
||||
|
||||
More info at http://en.wikipedia.org/wiki/Extensible_Provisioning_Protocol
|
||||
|
@ -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
|
||||
|
@ -30,12 +31,10 @@ Contact Mapping protocol short version:
|
|||
"priv" # National idendtification number
|
||||
"birthday" # Birthday date in format in DD-MM-YYYY
|
||||
<extension> 1
|
||||
<eis:extdata> 1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
|
||||
<eis:legalDocument> 1 Base64 encoded document
|
||||
<eis:extdata> 1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
|
||||
<eis:legalDocument> 1 Base64 encoded document
|
||||
Attribute: type="pdf/bdoc/ddoc/zip/rar/gz/tar/7z"
|
||||
|
||||
|
||||
|
||||
[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-create-command-successfully-creates-a-contact)
|
||||
|
||||
### Contact update
|
||||
|
@ -44,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
|
||||
|
@ -65,9 +64,9 @@ Contact Mapping protocol short version:
|
|||
<contact:authInfo> 0-1 Required if registrar is not the owner of the contact.
|
||||
<contact:pw> 1 Contact password. Attribute: roid="String"
|
||||
<extension> 0-1
|
||||
<eis:extdata> 0-1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
|
||||
<eis:legalDocument> 0-1 Base64 encoded document.
|
||||
Attribute: type="pdf/bdoc/ddoc/zip/rar/gz/tar/7z"
|
||||
<eis:extdata> 0-1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
|
||||
<eis:legalDocument> 0-1 Base64 encoded document.
|
||||
Attribute: type="pdf/bdoc/ddoc/zip/rar/gz/tar/7z"
|
||||
|
||||
|
||||
[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-update-command-is-succesful)
|
||||
|
@ -82,10 +81,10 @@ Contact Mapping protocol short version:
|
|||
<contact:authInfo> 0-1 Required if registrar is not the owner of the contact.
|
||||
<contact:pw> 1 Contact password. Attribute: roid="String"
|
||||
<extension> 1
|
||||
<eis:extdata> 1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
|
||||
<eis:legalDocument> 1 Base64 encoded document.
|
||||
<eis:extdata> 1 Attribute: xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
|
||||
<eis:legalDocument> 1 Base64 encoded document.
|
||||
Attribute: type="pdf/bdoc/ddoc/zip/rar/gz/tar/7z"
|
||||
<clTRID> 0-1 Client transaction id
|
||||
<clTRID> 0-1 Client transaction id
|
||||
|
||||
[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-delete-command-deletes-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
|
||||
|
|
@ -1,16 +1,14 @@
|
|||
namespace :db do
|
||||
def databases
|
||||
@db ||= ["api_log_#{Rails.env}", "whois_#{Rails.env}", "#{Rails.env}"]
|
||||
def other_databases
|
||||
@db ||= ["api_log_#{Rails.env}", "whois_#{Rails.env}"]
|
||||
end
|
||||
|
||||
def schema_file(db)
|
||||
case db
|
||||
when databases.first
|
||||
when "api_log_#{Rails.env}"
|
||||
'api_log_schema.rb'
|
||||
when databases.second
|
||||
when "whois_#{Rails.env}"
|
||||
'whois_schema.rb'
|
||||
when databases.third
|
||||
'schema.rb'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -19,16 +17,51 @@ namespace :db do
|
|||
task setup: [:environment] do
|
||||
Rake::Task['db:all:create'].invoke
|
||||
Rake::Task['db:all:schema:load'].invoke
|
||||
Rake::Task['db:seed'].invoke
|
||||
|
||||
ActiveRecord::Base.clear_all_connections!
|
||||
ActiveRecord::Base.establish_connection(Rails.env.to_sym)
|
||||
# puts "\n---------------------------- Import seed ----------------------------------------\n"
|
||||
# Rake::Task['db:seed'].invoke
|
||||
puts "\n All done!\n\n"
|
||||
end
|
||||
|
||||
desc 'Create all databases: registry, api_log and whois'
|
||||
task create: [:environment] do
|
||||
databases.each do |name|
|
||||
puts "\n---------------------------- Create main database ----------------------------------------\n"
|
||||
Rake::Task['db:create'].invoke
|
||||
|
||||
other_databases.each do |name|
|
||||
begin
|
||||
conf = ActiveRecord::Base.configurations
|
||||
puts "\n---------------------------- Create #{name} ----------------------------------------\n"
|
||||
ActiveRecord::Base.clear_all_connections!
|
||||
ActiveRecord::Base.connection.create_database(conf[name]['database'], conf[name])
|
||||
conf = ActiveRecord::Base.configurations
|
||||
ActiveRecord::Base.connection.create_database(conf[name]['database'].to_sym, conf[name])
|
||||
rescue => e
|
||||
puts "\n#{e}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Drop all databaseses: registry, api_log and whois'
|
||||
task drop: [:environment] do
|
||||
# just in case we allow only drop test, comment it out please for temp
|
||||
return unless Rails.env.test?
|
||||
|
||||
Rake::Task['db:drop'].invoke
|
||||
conf = ActiveRecord::Base.configurations
|
||||
puts "#{conf[Rails.env]['database']} dropped"
|
||||
|
||||
other_databases.each do |name|
|
||||
begin
|
||||
ActiveRecord::Base.clear_all_connections!
|
||||
ActiveRecord::Base.establish_connection(name.to_sym)
|
||||
|
||||
conf = ActiveRecord::Base.configurations
|
||||
if ActiveRecord::Tasks::DatabaseTasks.drop(conf[name])
|
||||
puts "#{conf[name]['database']} dropped"
|
||||
else
|
||||
puts "Didn't find database #{name}, no drop"
|
||||
end
|
||||
rescue => e
|
||||
puts "\n#{e}"
|
||||
end
|
||||
|
@ -38,10 +71,14 @@ namespace :db do
|
|||
namespace :schema do
|
||||
desc 'Schema load for all databases: registry, api_log and whois'
|
||||
task load: [:environment] do
|
||||
databases.each do |name|
|
||||
puts "\n---------------------------- Main schema load ----------------------------------------\n"
|
||||
Rake::Task['db:schema:load'].invoke
|
||||
|
||||
other_databases.each do |name|
|
||||
begin
|
||||
puts "\n---------------------------- #{name} ----------------------------------------\n"
|
||||
ActiveRecord::Base.establish_connection(name)
|
||||
puts "\n---------------------------- #{name} schema loaded ----------------------------------------\n"
|
||||
ActiveRecord::Base.clear_all_connections!
|
||||
ActiveRecord::Base.establish_connection(name.to_sym)
|
||||
if ActiveRecord::Base.connection.table_exists?('schema_migrations')
|
||||
puts 'Found tables, skip schema load!'
|
||||
else
|
||||
|
@ -55,7 +92,10 @@ namespace :db do
|
|||
|
||||
desc 'Schema load for all databases: registry, api_log and whois'
|
||||
task dump: [:environment] do
|
||||
databases.each do |name|
|
||||
puts "\n---------------------------- Main schema load ----------------------------------------\n"
|
||||
Rake::Task['db:schema:dump'].invoke
|
||||
|
||||
other_databases.each do |name|
|
||||
begin
|
||||
puts "\n---------------------------- #{name} ----------------------------------------\n"
|
||||
filename = "#{Rails.root}/db/#{schema_file(name)}"
|
||||
|
|
|
@ -30,7 +30,7 @@ begin
|
|||
end
|
||||
|
||||
Rake::Task[:default].prerequisites.clear
|
||||
task default: :test
|
||||
task default: 'test:other'
|
||||
|
||||
def test_against_server
|
||||
_stdin, _stdout, _stderr, wait_thr = Open3.popen3('unicorn -E test -p 8989')
|
||||
|
|
|
@ -1,451 +1,441 @@
|
|||
# require 'rails_helper'
|
||||
|
||||
# describe 'EPP Contact', epp: true do
|
||||
# before :all do
|
||||
# create_settings
|
||||
# create_disclosure_settings
|
||||
# @registrar1 = Fabricate(:registrar1)
|
||||
# @registrar2 = Fabricate(:registrar2)
|
||||
# @epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
|
||||
|
||||
# Fabricate(:api_user, username: 'registrar1', registrar: @registrar1)
|
||||
# Fabricate(:api_user, username: 'registrar2', registrar: @registrar2)
|
||||
|
||||
# login_as :registrar1
|
||||
|
||||
# Contact.skip_callback(:create, :before, :generate_code)
|
||||
# Contact.skip_callback(:create, :before, :generate_auth_info)
|
||||
# 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
|
||||
# it 'fails if request xml is missing' do
|
||||
# xml = @epp_xml.create
|
||||
# response = epp_plain_request(xml, :xml)
|
||||
# response[:results][0][:msg].should == 'Command syntax error'
|
||||
# response[:results][0][:result_code].should == '2001'
|
||||
|
||||
# response[:results].count.should == 1
|
||||
# end
|
||||
|
||||
# it 'fails if request xml is missing' do
|
||||
# xml = @epp_xml.create(
|
||||
# postalInfo: { addr: { value: nil } }
|
||||
# )
|
||||
# response = epp_plain_request(xml, :xml)
|
||||
# response[:results][0][:msg].should == 'Required parameter missing: name'
|
||||
# response[:results][1][:msg].should == 'Required parameter missing: city'
|
||||
# response[:results][2][:msg].should == 'Required parameter missing: cc'
|
||||
# response[:results][3][:msg].should == 'Required parameter missing: ident'
|
||||
# response[:results][4][:msg].should == 'Required parameter missing: voice'
|
||||
# response[:results][5][:msg].should == 'Required parameter missing: email'
|
||||
|
||||
# response[:results][0][:result_code].should == '2003'
|
||||
# response[:results][1][:result_code].should == '2003'
|
||||
# response[:results][2][:result_code].should == '2003'
|
||||
# response[:results][3][:result_code].should == '2003'
|
||||
# response[:results][4][:result_code].should == '2003'
|
||||
# response[:results][5][:result_code].should == '2003'
|
||||
|
||||
# response[:results].count.should == 6
|
||||
# end
|
||||
|
||||
# it 'successfully saves ident type' do
|
||||
# xml = { ident: { value: '1990-22-12', attrs: { type: 'birthday' } } }
|
||||
# epp_plain_request(create_contact_xml(xml), :xml)
|
||||
|
||||
# Contact.last.ident_type.should == 'birthday'
|
||||
# end
|
||||
|
||||
# it 'successfully creates a contact' do
|
||||
# response = epp_plain_request(create_contact_xml, :xml)
|
||||
|
||||
# response[:msg].should == 'Command completed successfully'
|
||||
# response[:result_code].should == '1000'
|
||||
|
||||
# @contact = Contact.last
|
||||
|
||||
# @contact.registrar.should == @registrar1
|
||||
# # registrar1.api_users.should include(@contact.created_by)
|
||||
# # @contact.updated_by_id.should == nil
|
||||
# @contact.ident.should == '37605030299'
|
||||
# @contact.address.street.should == '123 Example'
|
||||
|
||||
# log = ApiLog::EppLog.last
|
||||
# log.request_command.should == 'create'
|
||||
# log.request_object.should == 'contact'
|
||||
# log.request_successful.should == true
|
||||
# log.api_user_name.should == '1-api-registrar1'
|
||||
# log.api_user_registrar.should == 'registrar1'
|
||||
# end
|
||||
|
||||
# it 'successfully adds registrar' do
|
||||
# response = epp_plain_request(create_contact_xml, :xml)
|
||||
|
||||
# response[:msg].should == 'Command completed successfully'
|
||||
# response[:result_code].should == '1000'
|
||||
|
||||
# Contact.last.registrar.should == @registrar1
|
||||
# end
|
||||
|
||||
# it 'returns result data upon success' do
|
||||
# response = epp_plain_request(create_contact_xml, :xml)
|
||||
|
||||
# response[:msg].should == 'Command completed successfully'
|
||||
# response[:result_code].should == '1000'
|
||||
|
||||
# id = response[:parsed].css('resData creData id').first
|
||||
# cr_date = response[:parsed].css('resData creData crDate').first
|
||||
|
||||
# id.text.length.should == 8
|
||||
# # 5 seconds for what-ever weird lag reasons might happen
|
||||
# cr_date.text.to_time.should be_within(5).of(Time.now)
|
||||
# end
|
||||
|
||||
# it 'creates disclosure data' do
|
||||
# xml = {
|
||||
# disclose: { value: {
|
||||
# voice: { value: '' },
|
||||
# addr: { value: '' },
|
||||
# name: { value: '' },
|
||||
# org_name: { value: '' },
|
||||
# email: { value: '' },
|
||||
# fax: { value: '' }
|
||||
# }, attrs: { flag: '1' }
|
||||
# }
|
||||
# }
|
||||
|
||||
# response = epp_plain_request(create_contact_xml(xml), :xml)
|
||||
# response[:result_code].should == '1000'
|
||||
|
||||
# @contact = Contact.last
|
||||
# @contact.disclosure.name.should == true
|
||||
# @contact.disclosure.org_name.should == true
|
||||
# @contact.disclosure.phone.should == true
|
||||
# @contact.disclosure.fax.should == true
|
||||
# @contact.disclosure.email.should == true
|
||||
# @contact.disclosure.address.should == true
|
||||
# end
|
||||
|
||||
# it 'creates disclosure data merging with defaults' do
|
||||
# xml = {
|
||||
# disclose: { value: {
|
||||
# voice: { value: '' },
|
||||
# addr: { value: '' }
|
||||
# }, attrs: { flag: '1' }
|
||||
# }
|
||||
# }
|
||||
|
||||
# response = epp_plain_request(create_contact_xml(xml), :xml)
|
||||
# response[:result_code].should == '1000'
|
||||
|
||||
# @contact = Contact.last
|
||||
# @contact.disclosure.name.should == nil
|
||||
# @contact.disclosure.org_name.should == nil
|
||||
# @contact.disclosure.phone.should == true
|
||||
# @contact.disclosure.fax.should == nil
|
||||
# @contact.disclosure.email.should == nil
|
||||
# @contact.disclosure.address.should == true
|
||||
# end
|
||||
# end
|
||||
|
||||
# context 'update command' do
|
||||
# before :all do
|
||||
# @contact =
|
||||
# Fabricate(
|
||||
# :contact,
|
||||
# # created_by_id: 1,
|
||||
# registrar: @registrar1,
|
||||
# email: 'not_updated@test.test',
|
||||
# code: 'sh8013',
|
||||
# auth_info: 'password'
|
||||
# )
|
||||
# end
|
||||
|
||||
# it 'fails if request is invalid' do
|
||||
# xml = @epp_xml.update
|
||||
# response = epp_plain_request(xml, :xml) # epp_request('contacts/update_missing_attr.xml')
|
||||
|
||||
# response[:results][0][:result_code].should == '2003'
|
||||
# response[:results][0][:msg].should == 'Required parameter missing: add, rem or chg'
|
||||
# response[:results][1][:result_code].should == '2003'
|
||||
# response[:results][1][:msg].should == 'Required parameter missing: id'
|
||||
# response[:results].count.should == 2
|
||||
# end
|
||||
|
||||
# it 'fails with wrong authentication info' do
|
||||
# login_as :registrar2 do
|
||||
# response = epp_plain_request(update_contact_xml({ id: { value: 'sh8013' } }), :xml)
|
||||
# expect(response[:msg]).to eq('Authorization error')
|
||||
# expect(response[:result_code]).to eq('2201')
|
||||
# end
|
||||
# end
|
||||
|
||||
# it 'is succesful' do
|
||||
# response = epp_plain_request(update_contact_xml({ id: { value: 'sh8013' } }), :xml)
|
||||
|
||||
# response[:msg].should == 'Command completed successfully'
|
||||
# @contact.reload
|
||||
# @contact.name.should == 'John Doe Edited'
|
||||
# @contact.email.should == 'edited@example.example'
|
||||
# end
|
||||
|
||||
# it 'returns phone and email error' do
|
||||
# xml = {
|
||||
# id: { value: 'sh8013' },
|
||||
# chg: {
|
||||
# voice: { value: '123213' },
|
||||
# email: { value: 'aaa' }
|
||||
# }
|
||||
# }
|
||||
|
||||
# response = epp_plain_request(update_contact_xml(xml), :xml)
|
||||
|
||||
# response[:results][0][:msg].should == 'Phone nr is invalid'
|
||||
# response[:results][0][:result_code].should == '2005'
|
||||
|
||||
# response[:results][1][:msg].should == 'Email is invalid'
|
||||
# response[:results][1][:result_code].should == '2005'
|
||||
# end
|
||||
|
||||
# it 'updates disclosure items' do
|
||||
# Fabricate(
|
||||
# :contact,
|
||||
# code: 'sh8013disclosure',
|
||||
# auth_info: '2fooBAR',
|
||||
# registrar: @registrar1,
|
||||
# # created_by_id: ApiUser.first.id,
|
||||
# disclosure: Fabricate(:contact_disclosure, phone: true, email: true))
|
||||
|
||||
# xml = {
|
||||
# id: { value: 'sh8013disclosure' },
|
||||
# authInfo: { pw: { value: '2fooBAR' } }
|
||||
# }
|
||||
# @response = epp_plain_request(update_contact_xml(xml), :xml)
|
||||
|
||||
# @response[:results][0][:msg].should == 'Command completed successfully'
|
||||
# @response[:results][0][:result_code].should == '1000'
|
||||
|
||||
# Contact.last.disclosure.phone.should == false
|
||||
# Contact.last.disclosure.email.should == false
|
||||
# end
|
||||
# end
|
||||
|
||||
# context 'delete command' do
|
||||
# it 'fails if request is invalid' do
|
||||
# xml = @epp_xml.delete({ uid: { value: '23123' } })
|
||||
# response = epp_plain_request(xml, :xml)
|
||||
|
||||
# response[:results][0][:msg].should == 'Required parameter missing: id'
|
||||
# response[:results][0][:result_code].should == '2003'
|
||||
# response[:results].count.should == 1
|
||||
# end
|
||||
|
||||
# it 'deletes contact' do
|
||||
# @contact_deleted =
|
||||
# # Fabricate(:contact, code: 'dwa1234', created_by_id: ApiUser.first.id, registrar: registrar1)
|
||||
# Fabricate(:contact, code: 'dwa1234', registrar: @registrar1)
|
||||
|
||||
# response = epp_plain_request(delete_contact_xml({ id: { value: 'dwa1234' } }), :xml)
|
||||
# response[:msg].should == 'Command completed successfully'
|
||||
# response[:result_code].should == '1000'
|
||||
# response[:clTRID].should == 'ABC-12345'
|
||||
|
||||
# Contact.find_by_id(@contact_deleted.id).should == nil
|
||||
# end
|
||||
|
||||
# it 'returns error if obj doesnt exist' do
|
||||
# response = epp_plain_request(delete_contact_xml, :xml)
|
||||
# response[:msg].should == 'Object does not exist'
|
||||
# response[:result_code].should == '2303'
|
||||
# end
|
||||
|
||||
# it 'fails if contact has associated domain' do
|
||||
# Fabricate(
|
||||
# :domain,
|
||||
# registrar: @registrar1,
|
||||
# owner_contact: Fabricate(
|
||||
# :contact,
|
||||
# code: 'dwa1234',
|
||||
# # created_by_id: registrar1.id,
|
||||
# registrar: @registrar1)
|
||||
# )
|
||||
# Domain.last.owner_contact.address.present?.should == true
|
||||
# response = epp_plain_request(delete_contact_xml({ id: { value: 'dwa1234' } }), :xml)
|
||||
|
||||
# response[:msg].should == 'Object association prohibits operation'
|
||||
# response[:result_code].should == '2305'
|
||||
|
||||
# Domain.last.owner_contact.present?.should == true
|
||||
# end
|
||||
# end
|
||||
|
||||
# context 'check command' do
|
||||
# it 'fails if request is invalid' do
|
||||
# xml = @epp_xml.check({ uid: { value: '123asde' } })
|
||||
# response = epp_plain_request(xml, :xml)
|
||||
|
||||
# response[:results][0][:msg].should == 'Required parameter missing: id'
|
||||
# response[:results][0][:result_code].should == '2003'
|
||||
# response[:results].count.should == 1
|
||||
# end
|
||||
|
||||
# it 'returns info about contact availability' do
|
||||
# Fabricate(:contact, code: 'check-1234')
|
||||
|
||||
# response = epp_plain_request(check_multiple_contacts_xml, :xml)
|
||||
|
||||
# response[:msg].should == 'Command completed successfully'
|
||||
# response[:result_code].should == '1000'
|
||||
# ids = response[:parsed].css('resData chkData id')
|
||||
|
||||
# ids[0].attributes['avail'].text.should == '0'
|
||||
# ids[1].attributes['avail'].text.should == '1'
|
||||
|
||||
# ids[0].text.should == 'check-1234'
|
||||
# ids[1].text.should == 'check-4321'
|
||||
# end
|
||||
# end
|
||||
|
||||
# # context 'info command' do
|
||||
# # before :all do
|
||||
# # @registrar1_contact = Fabricate(:contact, code: 'info-4444', registrar: @registrar1,
|
||||
# # name: 'Johnny Awesome', address: Fabricate(:address))
|
||||
# # end
|
||||
|
||||
# # fit 'return info about contact' do
|
||||
# # login_as :registrar2 do
|
||||
# # xml = @epp_xml.info(id: { value: @registrar1_contact.code })
|
||||
# # response = epp_plain_request(xml, :xml)
|
||||
# # response[:msg].should == 'Command completed successfully'
|
||||
# # response[:result_code].should == '1000'
|
||||
|
||||
# # contact = response[:parsed].css('resData chkData')
|
||||
# # contact.css('name').first.text.should == 'Johnny Awesome'
|
||||
# # end
|
||||
# # end
|
||||
|
||||
# # it 'fails if request invalid' do
|
||||
# # response = epp_plain_request(@epp_xml.info({ wrongid: { value: '123123' } }), :xml)
|
||||
# # response[:results][0][:msg].should == 'Required parameter missing: id'
|
||||
# # response[:results][0][:result_code].should == '2003'
|
||||
# # response[:results].count.should == 1
|
||||
# # end
|
||||
|
||||
# # it 'returns error when object does not exist' do
|
||||
# # response = epp_plain_request(info_contact_xml({ id: { value: 'no-contact' } }), :xml)
|
||||
# # response[:msg].should == 'Object does not exist'
|
||||
# # response[:result_code].should == '2303'
|
||||
# # response[:results][0][:value].should == 'no-contact'
|
||||
# # end
|
||||
|
||||
# # # it 'returns auth error for non-owner with wrong password' do
|
||||
# # # @contact = Fabricate(:contact,
|
||||
# # # registrar: registrar2, code: 'info-4444', name: 'Johnny Awesome', auth_info: 'asde',
|
||||
# # # address: Fabricate(:address), disclosure: Fabricate(:contact_disclosure, name: false))
|
||||
|
||||
# # # xml = @epp_xml.info({ id: { value: @contact.code }, authInfo: { pw: { value: 'asdesde' } } })
|
||||
# # # response = epp_plain_request(xml, :xml, :registrar1)
|
||||
|
||||
# # # expect(response[:result_code]).to eq('2200')
|
||||
# # # expect(response[:msg]).to eq('Authentication error')
|
||||
# # # end
|
||||
|
||||
# # context 'about disclose' do
|
||||
# # it 'discloses items with wrong password when queried by owner' do
|
||||
# # @contact = Fabricate(:contact,
|
||||
# # registrar: registrar1, code: 'info-4444',
|
||||
# # name: 'Johnny Awesome', auth_info: 'asde',
|
||||
# # address: Fabricate(:address), disclosure: Fabricate(:contact_disclosure, name: false))
|
||||
|
||||
# # xml = @epp_xml.info({ id: { value: @contact.code } })
|
||||
# # login_as :registrar1 do
|
||||
# # response = epp_plain_request(xml, :xml)
|
||||
# # contact = response[:parsed].css('resData chkData')
|
||||
|
||||
# # expect(response[:result_code]).to eq('1000')
|
||||
# # expect(response[:msg]).to eq('Command completed successfully')
|
||||
# # expect(contact.css('name').first.text).to eq('Johnny Awesome')
|
||||
# # end
|
||||
# # end
|
||||
|
||||
# # it 'doesn\'t disclose items to non-owner with right password' do
|
||||
# # @contact = Fabricate(:contact, registrar: registrar2, code: 'info-4444',
|
||||
# # name: 'Johnny Awesome', auth_info: 'password',
|
||||
# # address: Fabricate(:address), disclosure: Fabricate(:contact_disclosure, name: false))
|
||||
|
||||
# # xml = @epp_xml.info({ id: { value: @contact.code }, authInfo: { pw: { value: 'password' } } })
|
||||
# # response = epp_plain_request(xml, :xml, :registrar1)
|
||||
# # contact = response[:parsed].css('resData chkData')
|
||||
|
||||
# # expect(response[:result_code]).to eq('1000')
|
||||
# # expect(response[:msg]).to eq('Command completed successfully')
|
||||
# # expect(contact.css('chkData postalInfo name').first).to eq(nil)
|
||||
# # end
|
||||
|
||||
# # it 'discloses items to owner' do
|
||||
# # @contact = Fabricate(:contact, registrar: registrar1, code: 'info-4444', name: 'Johnny Awesome',
|
||||
# # auth_info: 'password',
|
||||
# # address: Fabricate(:address), disclosure: Fabricate(:contact_disclosure, name: false))
|
||||
|
||||
# # xml = @epp_xml.info({ id: { value: @contact.code } })
|
||||
# # response = epp_plain_request(xml, :xml, :registrar1)
|
||||
# # contact = response[:parsed].css('resData chkData')
|
||||
|
||||
# # expect(response[:result_code]).to eq('1000')
|
||||
# # expect(response[:msg]).to eq('Command completed successfully')
|
||||
# # expect(contact.css('name').first.text).to eq('Johnny Awesome')
|
||||
# # end
|
||||
|
||||
# # it 'doesn\'t disclose private elements' do
|
||||
# # Fabricate(:contact, code: 'info-4444', auth_info: '2fooBAR', registrar: registrar2,
|
||||
# # disclosure: Fabricate(:contact_disclosure, name: true, email: false, phone: false))
|
||||
|
||||
# # xml = @epp_xml.info({ id: { value: 'info-4444' }, authInfo: { pw: { value: '2fooBAR' } } })
|
||||
|
||||
# # response = epp_plain_request(xml, :xml, :registrar1)
|
||||
# # contact = response[:parsed].css('resData chkData')
|
||||
|
||||
# # expect(response[:result_code]).to eq('1000')
|
||||
|
||||
# # expect(contact.css('chkData phone')).to eq(contact.css('chkData disclose phone'))
|
||||
# # expect(contact.css('chkData phone').count).to eq(1)
|
||||
# # expect(contact.css('chkData email')).to eq(contact.css('chkData disclose email'))
|
||||
# # expect(contact.css('chkData email').count).to eq(1)
|
||||
# # expect(contact.css('postalInfo name').present?).to be(true)
|
||||
# # end
|
||||
# # end
|
||||
|
||||
# # it 'does not display unassociated object without password' do
|
||||
# # xml = @epp_xml.info(id: { value: @registrar1_contact.code })
|
||||
# # response = epp_plain_request(xml, :xml, :registrar2)
|
||||
# # expect(response[:result_code]).to eq('2003')
|
||||
# # expect(response[:msg]).to eq('Required parameter missing: pw')
|
||||
# # end
|
||||
|
||||
# # it 'does not display unassociated object with wrong password' do
|
||||
# # login_as :registrar2
|
||||
# # xml = @epp_xml.info(id: { value: @registrar1_contact.code },
|
||||
# # authInfo: { pw: { value: 'wrong-pw' } })
|
||||
# # response = epp_plain_request(xml, :xml)
|
||||
|
||||
# # response[:msg].should == 'Authentication error'
|
||||
# # response[:result_code].should == '2200'
|
||||
# # end
|
||||
# # end
|
||||
|
||||
# context 'renew command' do
|
||||
# it 'returns 2101-unimplemented command' do
|
||||
# response = epp_plain_request('contacts/renew.xml')
|
||||
|
||||
# response[:msg].should == 'Unimplemented command'
|
||||
# response[:result_code].should == '2101'
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'EPP Contact', epp: true do
|
||||
before :all do
|
||||
create_settings
|
||||
create_disclosure_settings
|
||||
@registrar1 = Fabricate(:registrar1)
|
||||
@registrar2 = Fabricate(:registrar2)
|
||||
@epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
|
||||
|
||||
Fabricate(:api_user, username: 'registrar1', registrar: @registrar1)
|
||||
Fabricate(:api_user, username: 'registrar2', registrar: @registrar2)
|
||||
|
||||
login_as :registrar1
|
||||
|
||||
@contact = Fabricate(:contact, registrar: @registrar1)
|
||||
|
||||
@legal_document = {
|
||||
legalDocument: {
|
||||
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
|
||||
attrs: { type: 'pdf' }
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'with valid user' do
|
||||
context 'create command' do
|
||||
def create_request(overwrites = {})
|
||||
defaults = {
|
||||
postalInfo: {
|
||||
name: { value: 'John Doe' },
|
||||
addr: {
|
||||
street: { value: '123 Example' },
|
||||
city: { value: 'Tallinn' },
|
||||
cc: { value: 'EE' }
|
||||
}
|
||||
},
|
||||
voice: { value: '+372.1234567' },
|
||||
email: { value: 'test@example.example' },
|
||||
ident: { value: '37605030299', attrs: { type: 'priv', cc: 'EE' } }
|
||||
}
|
||||
create_xml = @epp_xml.create(defaults.deep_merge(overwrites), @legal_document)
|
||||
epp_plain_request(create_xml, :xml)
|
||||
end
|
||||
|
||||
it 'fails if request xml is missing' do
|
||||
response = epp_plain_request(@epp_xml.create, :xml)
|
||||
response[:results][0][:msg].should ==
|
||||
'Required parameter missing: create > create > postalInfo > name [name]'
|
||||
response[:results][1][:msg].should ==
|
||||
'Required parameter missing: create > create > postalInfo > addr > city [city]'
|
||||
response[:results][2][:msg].should ==
|
||||
'Required parameter missing: create > create > postalInfo > addr > cc [cc]'
|
||||
response[:results][3][:msg].should ==
|
||||
'Required parameter missing: create > create > ident [ident]'
|
||||
response[:results][4][:msg].should ==
|
||||
'Required parameter missing: create > create > voice [voice]'
|
||||
response[:results][5][:msg].should ==
|
||||
'Required parameter missing: create > create > email [email]'
|
||||
response[:results][6][:msg].should ==
|
||||
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||
|
||||
response[:results][0][:result_code].should == '2003'
|
||||
response[:results][1][:result_code].should == '2003'
|
||||
response[:results][2][:result_code].should == '2003'
|
||||
response[:results][3][:result_code].should == '2003'
|
||||
response[:results][4][:result_code].should == '2003'
|
||||
response[:results][5][:result_code].should == '2003'
|
||||
response[:results][6][:result_code].should == '2003'
|
||||
|
||||
response[:results].count.should == 7
|
||||
end
|
||||
|
||||
it 'successfully creates a contact' do
|
||||
response = create_request
|
||||
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
|
||||
@contact = Contact.last
|
||||
|
||||
@contact.registrar.should == @registrar1
|
||||
@registrar1.api_users.should include(@contact.creator)
|
||||
@contact.ident.should == '37605030299'
|
||||
@contact.address.street.should == '123 Example'
|
||||
@contact.legal_documents.count.should == 1
|
||||
|
||||
log = ApiLog::EppLog.last
|
||||
log.request_command.should == 'create'
|
||||
log.request_object.should == 'contact'
|
||||
log.request_successful.should == true
|
||||
log.api_user_name.should == '1-api-registrar1'
|
||||
log.api_user_registrar.should == 'registrar1'
|
||||
end
|
||||
|
||||
it 'successfully saves ident type' do
|
||||
response = create_request(
|
||||
{ ident: { value: '1990-22-12', attrs: { type: 'birthday' } } }
|
||||
)
|
||||
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
|
||||
Contact.last.ident_type.should == 'birthday'
|
||||
end
|
||||
|
||||
it 'successfully adds registrar' do
|
||||
response = create_request
|
||||
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
|
||||
Contact.last.registrar.should == @registrar1
|
||||
end
|
||||
|
||||
it 'returns result data upon success' do
|
||||
response = create_request
|
||||
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
|
||||
id = response[:parsed].css('resData creData id').first
|
||||
cr_date = response[:parsed].css('resData creData crDate').first
|
||||
|
||||
id.text.length.should == 8
|
||||
# 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
|
||||
before :all do
|
||||
@contact =
|
||||
Fabricate(
|
||||
:contact,
|
||||
registrar: @registrar1,
|
||||
email: 'not_updated@test.test',
|
||||
code: 'sh8013'
|
||||
)
|
||||
end
|
||||
|
||||
def update_request(overwrites = {})
|
||||
defaults = {
|
||||
id: { value: 'asd123123er' },
|
||||
authInfo: { pw: { value: 'password' } },
|
||||
chg: {
|
||||
postalInfo: {
|
||||
name: { value: 'John Doe Edited' }
|
||||
},
|
||||
voice: { value: '+372.7654321' },
|
||||
email: { value: 'edited@example.example' },
|
||||
disclose: {
|
||||
value: {
|
||||
voice: { value: '' },
|
||||
email: { value: '' }
|
||||
}, attrs: { flag: '0' }
|
||||
}
|
||||
}
|
||||
}
|
||||
update_xml = @epp_xml.update(defaults.deep_merge(overwrites), @legal_document)
|
||||
epp_plain_request(update_xml, :xml)
|
||||
end
|
||||
|
||||
it 'fails if request is invalid' do
|
||||
response = epp_plain_request(@epp_xml.update, :xml)
|
||||
|
||||
response[:results][0][:msg].should ==
|
||||
'Required parameter missing: add, rem or chg'
|
||||
response[:results][0][:result_code].should == '2003'
|
||||
response[:results][1][:msg].should ==
|
||||
'Required parameter missing: update > update > id [id]'
|
||||
response[:results][1][:result_code].should == '2003'
|
||||
response[:results][2][:msg].should ==
|
||||
'Required parameter missing: update > update > authInfo > pw [pw]'
|
||||
response[:results][2][:result_code].should == '2003'
|
||||
response[:results][3][:msg].should ==
|
||||
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||
response[:results][3][:result_code].should == '2003'
|
||||
response[:results].count.should == 4
|
||||
end
|
||||
|
||||
it 'returns error if obj doesnt exist' do
|
||||
response = update_request({ id: { value: 'not-exists' } })
|
||||
response[:msg].should == 'Object does not exist'
|
||||
response[:result_code].should == '2303'
|
||||
response[:results].count.should == 1
|
||||
end
|
||||
|
||||
it 'is succesful' do
|
||||
response = update_request({ id: { value: 'sh8013' } })
|
||||
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
@contact.reload
|
||||
@contact.name.should == 'John Doe Edited'
|
||||
@contact.email.should == 'edited@example.example'
|
||||
end
|
||||
|
||||
it 'fails with wrong authentication info' do
|
||||
login_as :registrar2 do
|
||||
response = update_request({ id: { value: 'sh8013' } })
|
||||
response[:msg].should == 'Authorization error'
|
||||
response[:result_code].should == '2201'
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns phone and email error' do
|
||||
response = update_request({
|
||||
id: { value: 'sh8013' },
|
||||
chg: {
|
||||
voice: { value: '123213' },
|
||||
email: { value: 'wrong' }
|
||||
}
|
||||
})
|
||||
|
||||
response[:results][0][:msg].should == 'Phone nr is invalid [phone]'
|
||||
response[:results][0][:result_code].should == '2005'
|
||||
response[:results][1][:msg].should == 'Email is invalid [email]'
|
||||
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
|
||||
before do
|
||||
@contact = Fabricate(:contact, registrar: @registrar1)
|
||||
end
|
||||
|
||||
def delete_request(overwrites = {})
|
||||
defaults = {
|
||||
id: { value: @contact.code },
|
||||
authInfo: { pw: { value: @contact.auth_info } }
|
||||
}
|
||||
delete_xml = @epp_xml.delete(defaults.deep_merge(overwrites), @legal_document)
|
||||
epp_plain_request(delete_xml, :xml)
|
||||
end
|
||||
|
||||
it 'fails if request is invalid' do
|
||||
response = epp_plain_request(@epp_xml.delete, :xml)
|
||||
|
||||
response[:results][0][:msg].should ==
|
||||
'Required parameter missing: delete > delete > id [id]'
|
||||
response[:results][0][:result_code].should == '2003'
|
||||
response[:results][1][:msg].should ==
|
||||
'Required parameter missing: delete > delete > authInfo > pw [pw]'
|
||||
response[:results][1][:result_code].should == '2003'
|
||||
response[:results][2][:msg].should ==
|
||||
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||
response[:results][2][:result_code].should == '2003'
|
||||
response[:results].count.should == 3
|
||||
end
|
||||
|
||||
it 'returns error if obj doesnt exist' do
|
||||
response = delete_request({ id: { value: 'not-exists' } })
|
||||
response[:msg].should == 'Object does not exist'
|
||||
response[:result_code].should == '2303'
|
||||
response[:results].count.should == 1
|
||||
end
|
||||
|
||||
it 'deletes contact' do
|
||||
response = delete_request
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
response[:clTRID].should == 'ABC-12345'
|
||||
|
||||
Contact.find_by_id(@contact.id).should == nil
|
||||
end
|
||||
|
||||
it 'fails if contact has associated domain' do
|
||||
@domain = Fabricate(:domain, registrar: @registrar1, owner_contact: @contact)
|
||||
@domain.owner_contact.address.present?.should == true
|
||||
|
||||
response = delete_request
|
||||
response[:msg].should == 'Object association prohibits operation [domains]'
|
||||
response[:result_code].should == '2305'
|
||||
response[:results].count.should == 1
|
||||
|
||||
@domain.owner_contact.present?.should == true
|
||||
end
|
||||
|
||||
it 'fails with wrong authentication info' do
|
||||
login_as :registrar2 do
|
||||
response = delete_request
|
||||
response[:msg].should == 'Authorization error'
|
||||
response[:result_code].should == '2201'
|
||||
response[:results].count.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'check command' do
|
||||
def check_request(overwrites = {})
|
||||
defaults = {
|
||||
id: { value: @contact.code },
|
||||
authInfo: { pw: { value: @contact.auth_info } }
|
||||
}
|
||||
xml = @epp_xml.check(defaults.deep_merge(overwrites))
|
||||
epp_plain_request(xml, :xml)
|
||||
end
|
||||
|
||||
it 'fails if request is invalid' do
|
||||
response = epp_plain_request(@epp_xml.check, :xml)
|
||||
|
||||
response[:results][0][:msg].should == 'Required parameter missing: check > check > id [id]'
|
||||
response[:results][0][:result_code].should == '2003'
|
||||
response[:results].count.should == 1
|
||||
end
|
||||
|
||||
it 'returns info about contact availability' do
|
||||
Fabricate(:contact, code: 'check-1234')
|
||||
|
||||
response = epp_plain_request(check_multiple_contacts_xml, :xml)
|
||||
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
ids = response[:parsed].css('resData chkData id')
|
||||
|
||||
ids[0].attributes['avail'].text.should == '0'
|
||||
ids[1].attributes['avail'].text.should == '1'
|
||||
|
||||
ids[0].text.should == 'check-1234'
|
||||
ids[1].text.should == 'check-4321'
|
||||
end
|
||||
end
|
||||
|
||||
context 'info command' do
|
||||
def info_request(overwrites = {})
|
||||
defaults = {
|
||||
id: { value: @contact.code },
|
||||
authInfo: { pw: { value: @contact.auth_info } }
|
||||
}
|
||||
xml = @epp_xml.info(defaults.deep_merge(overwrites))
|
||||
epp_plain_request(xml, :xml)
|
||||
end
|
||||
|
||||
it 'fails if request invalid' do
|
||||
response = epp_plain_request(@epp_xml.info, :xml)
|
||||
response[:results][0][:msg].should ==
|
||||
'Required parameter missing: info > info > id [id]'
|
||||
response[:results][0][:result_code].should == '2003'
|
||||
response[:results].count.should == 1
|
||||
end
|
||||
|
||||
it 'returns error when object does not exist' do
|
||||
response = info_request({ id: { value: 'no-contact' } })
|
||||
response[:msg].should == 'Object does not exist'
|
||||
response[:result_code].should == '2303'
|
||||
response[:results][0][:value].should == 'no-contact'
|
||||
response[:results].count.should == 1
|
||||
end
|
||||
|
||||
it 'return info about contact' do
|
||||
@registrar1_contact = Fabricate(
|
||||
:contact, code: 'info-4444', registrar: @registrar1,
|
||||
name: 'Johnny Awesome', address: Fabricate(:address))
|
||||
|
||||
response = info_request({ id: { value: @registrar1_contact.code } })
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
|
||||
contact = response[:parsed].css('resData chkData')
|
||||
contact.css('name').first.text.should == 'Johnny Awesome'
|
||||
end
|
||||
|
||||
it 'returns no authorization error for wrong password when owner' do
|
||||
response = info_request({ authInfo: { pw: { value: 'wrong-pw' } } })
|
||||
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
response[:results].count.should == 1
|
||||
end
|
||||
|
||||
it 'returns no authorization error for wrong user but correct pw' do
|
||||
login_as :registrar2 do
|
||||
response = info_request
|
||||
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
response[:results].count.should == 1
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns authorization error for wrong user and wrong pw' do
|
||||
login_as :registrar2 do
|
||||
response = info_request({ authInfo: { pw: { value: 'wrong-pw' } } })
|
||||
response[:msg].should == 'Authorization error'
|
||||
response[:result_code].should == '2201'
|
||||
response[:results].count.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'renew command' do
|
||||
it 'returns 2101-unimplemented command' do
|
||||
response = epp_plain_request('contacts/renew.xml')
|
||||
|
||||
response[:msg].should == 'Unimplemented command'
|
||||
response[:result_code].should == '2101'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_multiple_contacts_xml
|
||||
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<contact:check
|
||||
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
|
||||
<contact:id>check-1234</contact:id>
|
||||
<contact:id>check-4321</contact:id>
|
||||
</contact:check>
|
||||
</check>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,12 +11,10 @@ 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')
|
||||
Fabricate(:contact, code: 'juridical_1234', ident_type: 'ico')
|
||||
Fabricate(:contact, code: 'juridical_1234', ident_type: 'bic')
|
||||
Fabricate(:reserved_domain)
|
||||
|
||||
@uniq_no = proc { @i ||= 0; @i += 1 }
|
||||
|
@ -61,16 +59,20 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
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][: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][: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][:msg].should == 'Required parameter missing: extension > extdata > legalDocument'
|
||||
response[:results][3][:msg].should ==
|
||||
'Required parameter missing: extension > extdata > legalDocument [legal_document]'
|
||||
end
|
||||
|
||||
context 'with citizen as an owner' do
|
||||
|
@ -169,7 +171,7 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:result_code].should == '2306'
|
||||
response[:msg].should == 'IPv4 is missing'
|
||||
response[:msg].should == 'IPv4 is missing [ipv4]'
|
||||
end
|
||||
|
||||
# it 'does not create duplicate domain' do
|
||||
|
@ -191,7 +193,7 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
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'
|
||||
end
|
||||
|
||||
|
@ -200,14 +202,23 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
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
|
||||
|
||||
it 'does not create domain without nameservers' do
|
||||
xml = domain_create_xml(ns: [])
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:result_code].should == '2003'
|
||||
response[:msg].should == 'Required parameter missing: create > create > ns > hostAttr'
|
||||
|
||||
response[:results][0][:msg].should ==
|
||||
'Required parameter missing: create > create > ns [ns]'
|
||||
response[:results][0][:result_code].should == '2003'
|
||||
|
||||
response[:results][1][:msg].should ==
|
||||
'Required parameter missing: create > create > ns > hostAttr [host_attr]'
|
||||
response[:results][1][:result_code].should == '2003'
|
||||
|
||||
response[:results].count.should == 2
|
||||
end
|
||||
|
||||
it 'does not create domain with too many nameservers' do
|
||||
|
@ -226,7 +237,7 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
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
|
||||
|
||||
it 'returns error when invalid nameservers are present' do
|
||||
|
@ -246,8 +257,8 @@ describe 'EPP Domain', epp: true do
|
|||
})
|
||||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:msg].should == 'Hostname is invalid [hostname]'
|
||||
response[:result_code].should == '2005'
|
||||
response[:msg].should == 'Hostname is invalid'
|
||||
end
|
||||
|
||||
it 'checks hostAttr presence' do
|
||||
|
@ -263,8 +274,8 @@ describe 'EPP Domain', epp: true do
|
|||
})
|
||||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:msg].should == 'Required parameter missing: create > create > ns > hostAttr [host_attr]'
|
||||
response[:result_code].should == '2003'
|
||||
response[:msg].should == 'Required parameter missing: create > create > ns > hostAttr'
|
||||
end
|
||||
|
||||
it 'creates domain with nameservers with ips' do
|
||||
|
@ -280,10 +291,10 @@ describe 'EPP Domain', epp: true do
|
|||
nameserver_count = Nameserver.count
|
||||
response = epp_plain_request(domain_create_with_invalid_ns_ip_xml, :xml)
|
||||
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][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'
|
||||
# ensure nothing gets saved to db:
|
||||
Domain.count.should == domain_count
|
||||
|
@ -294,8 +305,8 @@ describe 'EPP Domain', epp: true do
|
|||
xml = domain_create_xml(period_value: 365, period_unit: 'd')
|
||||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:result_code].should == '1000'
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
Domain.first.valid_to.should == Date.today + 1.year
|
||||
end
|
||||
|
||||
|
@ -306,7 +317,7 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
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'
|
||||
end
|
||||
|
||||
|
@ -391,24 +402,25 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
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][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][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][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][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][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'
|
||||
end
|
||||
|
||||
|
@ -435,7 +447,7 @@ describe 'EPP Domain', epp: true do
|
|||
response = epp_plain_request(xml, :xml)
|
||||
|
||||
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'
|
||||
end
|
||||
|
||||
|
@ -464,7 +476,7 @@ describe 'EPP Domain', epp: true do
|
|||
response = epp_plain_request(xml, :xml)
|
||||
|
||||
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
|
||||
end
|
||||
|
@ -661,8 +673,8 @@ describe 'EPP Domain', epp: true do
|
|||
})
|
||||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:msg].should == 'Admin contacts count must be between 1-10 [admin_contacts]'
|
||||
response[:result_code].should == '2004'
|
||||
response[:msg].should == 'Admin contacts count must be between 1-10'
|
||||
response[:clTRID].should == 'ABC-12345'
|
||||
|
||||
Domain.count.should == domain_count
|
||||
|
@ -678,8 +690,8 @@ describe 'EPP Domain', epp: true do
|
|||
})
|
||||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:result_code].should == '2306'
|
||||
response[:msg].should == 'Admin contact can be only citizen'
|
||||
response[:result_code].should == '2306'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -853,7 +865,8 @@ describe 'EPP Domain', epp: true do
|
|||
login_as :registrar2 do
|
||||
response = epp_plain_request(xml, :xml)
|
||||
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
|
||||
|
||||
|
@ -970,7 +983,7 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
response[:result_code].should == '2201'
|
||||
response[:msg].should == 'Authorization error'
|
||||
response[:msg].should == 'Authorization error [auth_info]'
|
||||
end
|
||||
|
||||
it 'ignores transfer when owner registrar requests transfer' do
|
||||
|
@ -1017,7 +1030,7 @@ describe 'EPP Domain', epp: true do
|
|||
epp_plain_request(xml, :xml) # transfer domain
|
||||
response = epp_plain_request(xml, :xml) # attempt second transfer
|
||||
response[:result_code].should == '2201'
|
||||
response[:msg].should == 'Authorization error'
|
||||
response[:msg].should == 'Authorization error [auth_info]'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1120,27 +1133,27 @@ describe 'EPP Domain', epp: true do
|
|||
response = epp_plain_request(xml, :xml)
|
||||
|
||||
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][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][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][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][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][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][6][:msg].should == 'Public key already exists'
|
||||
response[:results][6][:msg].should == 'Public key already exists [public_key]'
|
||||
response[:results][6][:value].should == '841936717ae427ace63c28d04918569a841936717ae427ace63c28d0'
|
||||
|
||||
d.domain_statuses.count.should == 2
|
||||
|
@ -1292,11 +1305,11 @@ describe 'EPP Domain', epp: true do
|
|||
response = epp_plain_request(xml, :xml)
|
||||
|
||||
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][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
|
||||
end
|
||||
|
||||
|
@ -1309,7 +1322,8 @@ describe 'EPP Domain', epp: true do
|
|||
}
|
||||
|
||||
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'
|
||||
end
|
||||
|
||||
|
@ -1366,7 +1380,7 @@ describe 'EPP Domain', epp: true do
|
|||
|
||||
response = epp_plain_request(xml, :xml)
|
||||
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'
|
||||
end
|
||||
|
||||
|
@ -1518,7 +1532,8 @@ describe 'EPP Domain', epp: true do
|
|||
it 'does not delete domain without legal document' do
|
||||
response = epp_plain_request(@epp_xml.domain.delete(name: { value: 'example.ee' }), :xml)
|
||||
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
|
||||
|
||||
### CHECK ###
|
||||
|
|
|
@ -64,7 +64,7 @@ describe 'EPP Keyrelay', epp: true do
|
|||
})
|
||||
|
||||
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
|
||||
end
|
||||
|
|
|
@ -35,6 +35,7 @@ describe 'EPP Session', epp: true do
|
|||
|
||||
inactive = @epp_xml.session.login(clID: { value: 'inactive-user' }, pw: { value: 'ghyt9e4fu' })
|
||||
response = epp_plain_request(inactive, :xml)
|
||||
response[:msg].should == 'Authentication error; server closing connection'
|
||||
response[:result_code].should == '2501'
|
||||
end
|
||||
|
||||
|
|
33
spec/fabricators/certificate_fabricator.rb
Normal file
33
spec/fabricators/certificate_fabricator.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# default fabricator should be reusable
|
||||
Fabricator(:certificate) do
|
||||
api_user
|
||||
csr "-----BEGIN CERTIFICATE REQUEST-----\n" \
|
||||
"MIIE+DCCAuACAQAwgZ0xCzAJBgNVBAYTAkVFMREwDwYDVQQIDAhIYXJqdW1hYTEQ\n" \
|
||||
"MA4GA1UEBwwHVGFsbGlubjEbMBkGA1UECgwSRWVzdGkgSW50ZXJuZXRpIFNBMRIw\n" \
|
||||
"EAYDVQQLDAlSRUdJU1RSQVIxEjAQBgNVBAMMCXdlYmNsaWVudDEkMCIGCSqGSIb3\n" \
|
||||
"DQEJARYVd2ViY2xpZW50QGludGVybmV0LmVlMIICIjANBgkqhkiG9w0BAQEFAAOC\n" \
|
||||
"Ag8AMIICCgKCAgEAuXronFj8CxPWGkyUhXf+/WirkFGb8a/My2+7GvQWYE10Nq4C\n" \
|
||||
"u9wDgjU3AuLw8qzwEeE3Z5uxHXWfwnshXOF6aJNCQWUsrs0odCxw69iIwCNGKhyF\n" \
|
||||
"jljtx8uSH8RRSRc8BFIUkvUpmp8m7kZTlB4FDey+XaGy4p/rImiAiwfFMIJMjdE9\n" \
|
||||
"9gk0EGDbomgP6KC3Ss/iQfuOFCQWSqjFuvp3mygr193YplaPgeLM1ERIW1LVFGDK\n" \
|
||||
"jy6keZ3E/Vb4O4qUPDRgTMr2KWM3Auzh2hXCymHNWn3yRn5Q4KSjJbG/P7Kz5nfZ\n" \
|
||||
"kY3eVRBIBll+1Q0VV7g+1B48zzjZX2qiY3iL77MV1oL17KeOO3PAxsEtptdqNgUa\n" \
|
||||
"Fpp73dwPST1ZKvq8FSgDKcdTCziSeViGhXjJRpEMr8FoeKNO7nvd1maKN9HAOy75\n" \
|
||||
"eSxatj6LoQ+JFN7Ci3IbwKFI7BnIHbEr9eP7O7Qbhljz2GE9+GWUqr3zwUEgpFSI\n" \
|
||||
"crAnRHQI2ALakEMsryF416zg5yr/bJp8/IzgZLaKpBVLOL88sI6r+JRdM6QXvKYx\n" \
|
||||
"XhamV6bH6CrR8ZYN4okaZH6sAcy8eyBnEmc05h/KsDzTNadwadeZe73F+PltoEXH\n" \
|
||||
"XgtpTpQ8XarN1uLq99WD6gWilAx3LF/xetCO86+w/MkYBmfOrXge+WLUUW8CAwEA\n" \
|
||||
"AaAVMBMGCSqGSIb3DQEJBzEGDAR0ZXN0MA0GCSqGSIb3DQEBCwUAA4ICAQAkTlU3\n" \
|
||||
"RcI6UMRA7As2FJSph3QurPebQFoZhnhMD+hb6+hXip8MY77YxLwo/ihB9wghaZKL\n" \
|
||||
"uV0BxjdZgjDt9GhA8dtPgaCp5LvB6kQYvcEzRvitN2CpJhtz39rlF3gxuy+RtpNf\n" \
|
||||
"5KbC691FivoXur1qx9I7mc4snB3DTzLiJPIZ6nQzPYcSVpPCbns30N/i/sOdHO0o\n" \
|
||||
"9hP5wlhCdYrOxad993m+InpMDyDWhB1+TA9ZO7gYpg8S4kBX3Cz9OXe80Pe56ZdK\n" \
|
||||
"pcgjTXnUDjNSRRGamJib2lyZ/axMbb/etwyy3X+jBDuOQropkmgrPEFJHpgNlFah\n" \
|
||||
"BuW7KEASqbw5YxpTSc0nDk5uxBw3voL8fk9M1sX64tbzGAEBRZnrWGeb1mOLM/YI\n" \
|
||||
"K6ocAYSBhNmWUzpHTwL7qSeP9ztQUGzoGHyRjBdan+1U2G75Kpj+TjEm/X8wmtnq\n" \
|
||||
"3/qVhUYNEavcZbgR1gSE45+mS8NsD7Oq0Xdc0UKsVDbUcCGIkGG9+ERAbRznfi3W\n" \
|
||||
"qhChtUxySX8T3SmX5mviwlJ5OwQVjdUF1/2voPK0oFK7zV+wZqcuORzDKdqB8XV7\n" \
|
||||
"MDcQjza4EOB78OmcHDgQ7nMXuY7/UL4F+bRZosxPy43X2JId5d+/GpgV8sP9dzK8\n" \
|
||||
"UGJDNEZ2YsBbPuKZS+2eNZ8g3sjjFBeadvrQ1w==\n" \
|
||||
"-----END CERTIFICATE REQUEST-----"
|
||||
end
|
|
@ -1,12 +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'
|
||||
code { "sh#{Faker::Number.number(8)}" }
|
||||
ident_type 'op'
|
||||
auth_info 'ccds4324pok'
|
||||
ident_type 'priv'
|
||||
ident_country_code 'EE'
|
||||
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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Fabricator(:domain) do
|
||||
name { "#{Faker::Internet.domain_word}.ee" }
|
||||
name { "fabricate_name#{rand(1_000_000)}.ee" }
|
||||
valid_to Date.new(2014, 8, 7)
|
||||
period 1
|
||||
period_unit 'y'
|
||||
|
|
|
@ -20,6 +20,11 @@ describe ApiUser do
|
|||
it 'should not have any versions' do
|
||||
@api_user.versions.should == []
|
||||
end
|
||||
|
||||
it 'should be active by default' do
|
||||
@api_user.active.should == true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'with valid attributes' do
|
||||
|
|
61
spec/models/certificate_spec.rb
Normal file
61
spec/models/certificate_spec.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Certificate do
|
||||
it { should belong_to(:api_user) }
|
||||
|
||||
context 'with invalid attribute' do
|
||||
before :all do
|
||||
@certificate = Certificate.new
|
||||
end
|
||||
|
||||
it 'should not be valid' do
|
||||
@certificate.valid?
|
||||
@certificate.errors.full_messages.should match_array([
|
||||
"Csr is missing"
|
||||
])
|
||||
end
|
||||
|
||||
it 'should not have any versions' do
|
||||
@certificate.versions.should == []
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid attributes' do
|
||||
before :all do
|
||||
@certificate = Fabricate(:certificate)
|
||||
end
|
||||
|
||||
it 'should be valid' do
|
||||
@certificate.valid?
|
||||
@certificate.errors.full_messages.should match_array([])
|
||||
end
|
||||
|
||||
it 'should be valid twice' do
|
||||
@certificate = Fabricate(:certificate)
|
||||
@certificate.valid?
|
||||
@certificate.errors.full_messages.should match_array([])
|
||||
end
|
||||
|
||||
it 'should sign csr', epp: true do
|
||||
@certificate.status.should == 'unsigned'
|
||||
@certificate.sign!
|
||||
@certificate.status.should == 'signed'
|
||||
@certificate.crt.should_not be_blank
|
||||
end
|
||||
|
||||
it 'should revoke crt', epp: true do
|
||||
@certificate.revoke!
|
||||
@certificate.status.should == 'revoked'
|
||||
end
|
||||
|
||||
it 'should have one version' do
|
||||
with_versioning do
|
||||
@certificate.versions.should == []
|
||||
@certificate.csr = 'new_request'
|
||||
@certificate.save
|
||||
@certificate.errors.full_messages.should match_array([])
|
||||
@certificate.versions.size.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,91 +0,0 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe ContactDisclosure do
|
||||
it { should belong_to(:contact) }
|
||||
|
||||
context 'about class' do
|
||||
it 'should have versioning enabled?' do
|
||||
ContactDisclosure.paper_trail_enabled_for_model?.should == true
|
||||
end
|
||||
|
||||
it 'should have custom log prexied table name for versions table' do
|
||||
ContactDisclosureVersion.table_name.should == 'log_contact_disclosures'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid attribute' do
|
||||
before :all do
|
||||
@contact_disclosure = ContactDisclosure.new
|
||||
end
|
||||
|
||||
it 'should not be valid' do
|
||||
@contact_disclosure.valid?
|
||||
@contact_disclosure.errors.full_messages.should match_array([
|
||||
])
|
||||
end
|
||||
|
||||
it 'should not have any versions' do
|
||||
@contact_disclosure.versions.should == []
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid attributes' do
|
||||
before :all do
|
||||
@contact_disclosure = Fabricate(:contact_disclosure)
|
||||
end
|
||||
|
||||
it 'should be valid' do
|
||||
@contact_disclosure.valid?
|
||||
@contact_disclosure.errors.full_messages.should match_array([])
|
||||
end
|
||||
|
||||
it 'should be valid twice' do
|
||||
@contact_disclosure = Fabricate(:contact_disclosure)
|
||||
@contact_disclosure.valid?
|
||||
@contact_disclosure.errors.full_messages.should match_array([])
|
||||
end
|
||||
|
||||
it 'should have one version' do
|
||||
with_versioning do
|
||||
@contact_disclosure.versions.should == []
|
||||
@contact_disclosure.name = false
|
||||
@contact_disclosure.save
|
||||
@contact_disclosure.errors.full_messages.should match_array([])
|
||||
@contact_disclosure.versions.size.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '.extract_attributes' do
|
||||
it 'should return empty hash for empty arguments' do
|
||||
result = ContactDisclosure.extract_attributes(Nokogiri::XML::Document.new)
|
||||
expect(result).to eq({})
|
||||
end
|
||||
|
||||
it 'should return empty hash if no disclosure' do
|
||||
parsed_frame = Nokogiri::XML(create_contact_xml).remove_namespaces!
|
||||
result = ContactDisclosure.extract_attributes(parsed_frame)
|
||||
expect(result).to eq({})
|
||||
end
|
||||
|
||||
# TODO: remodel create contact xml to support disclosure
|
||||
it 'should return disclosure has if disclosure' do
|
||||
epp_xml = EppXml::Contact.new
|
||||
xml = epp_xml.create(
|
||||
{
|
||||
disclose: { value: {
|
||||
voice: { value: '' },
|
||||
addr: { value: '' },
|
||||
name: { value: '' },
|
||||
org_name: { value: '' },
|
||||
email: { value: '' },
|
||||
fax: { value: '' }
|
||||
}, attrs: { flag: '0' }
|
||||
} })
|
||||
parsed_frame = Nokogiri::XML(xml).remove_namespaces!
|
||||
result = ContactDisclosure.extract_attributes(parsed_frame)
|
||||
expect(result).to eq({ phone: '0', email: '0', fax: '0', address: '0', name: '0', org_name: '0' })
|
||||
end
|
||||
end
|
|
@ -39,11 +39,11 @@ describe Contact do
|
|||
end
|
||||
|
||||
it 'should not have creator' do
|
||||
@contact.cr_id.should == nil
|
||||
@contact.creator.should == nil
|
||||
end
|
||||
|
||||
it 'should not have updater' do
|
||||
@contact.up_id.should == nil
|
||||
@contact.updator.should == nil
|
||||
end
|
||||
|
||||
it 'phone should return false' do
|
||||
|
@ -52,9 +52,51 @@ describe Contact do
|
|||
@contact.errors[:phone].should == ["Phone nr is invalid"]
|
||||
end
|
||||
|
||||
it 'should require country code when bic' do
|
||||
@contact.ident_type = 'bic'
|
||||
@contact.valid?
|
||||
@contact.errors[:ident_country_code].should == ['is missing']
|
||||
end
|
||||
|
||||
it 'should require country code when priv' do
|
||||
@contact.ident_type = 'priv'
|
||||
@contact.valid?
|
||||
@contact.errors[:ident_country_code].should == ['is missing']
|
||||
end
|
||||
|
||||
it 'should validate correct country code' do
|
||||
@contact.ident_type = 'bic'
|
||||
@contact.ident_country_code = 'EE'
|
||||
@contact.valid?
|
||||
|
||||
@contact.errors[:ident_country_code].should == []
|
||||
end
|
||||
|
||||
it 'should require valid country code' do
|
||||
@contact.ident_type = 'bic'
|
||||
@contact.ident_country_code = 'INVALID'
|
||||
@contact.valid?
|
||||
|
||||
@contact.errors[:ident_country_code].should == ['is not following ISO_3166-1 alpha 2 format']
|
||||
end
|
||||
|
||||
it 'should convert to alpha2 country code' do
|
||||
@contact.ident_type = 'bic'
|
||||
@contact.ident_country_code = 'ee'
|
||||
@contact.valid?
|
||||
|
||||
@contact.ident_country_code.should == 'EE'
|
||||
end
|
||||
|
||||
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
|
||||
|
@ -87,18 +129,23 @@ describe Contact do
|
|||
@contact.relations_with_domain?.should == false
|
||||
end
|
||||
|
||||
# it 'ico should be valid' do
|
||||
# @contact.ident_type = 'ico'
|
||||
# @contact.ident = '1234'
|
||||
# @contact.errors.full_messages.should match_array([])
|
||||
# end
|
||||
it 'bic should be valid' do
|
||||
@contact.ident_type = 'bic'
|
||||
@contact.ident = '1234'
|
||||
@contact.valid?
|
||||
@contact.errors.full_messages.should match_array([])
|
||||
end
|
||||
|
||||
# it 'ident should return false' do
|
||||
# puts @contact.ident_type
|
||||
# @contact.ident = '123abc'
|
||||
# @contact.valid?
|
||||
# @contact.errors.full_messages.should_not == []
|
||||
# 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
|
||||
|
@ -119,7 +166,8 @@ describe Contact do
|
|||
invalid.each do |date|
|
||||
@contact.ident = date
|
||||
@contact.valid?
|
||||
@contact.errors.full_messages.should == ["Ident is invalid"]
|
||||
@contact.errors.full_messages.should ==
|
||||
["Ident Ident not in valid birthady format, should be YYYY-MM-DD"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -151,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
|
||||
|
@ -174,62 +258,13 @@ 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
|
||||
|
||||
context 'with creator' do
|
||||
before :all do
|
||||
# @contact.created_by = @api_user
|
||||
end
|
||||
|
||||
# TODO: change cr_id to something else
|
||||
it 'should return username of creator' do
|
||||
# @contact.cr_id.should == 'gitlab'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with updater' do
|
||||
before :all do
|
||||
# @contact.updated_by = @api_user
|
||||
end
|
||||
|
||||
# TODO: change up_id to something else
|
||||
it 'should return username of updater' do
|
||||
# @contact.up_id.should == 'gitlab'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: investigate it a bit more
|
||||
# describe Contact, '#relations_with_domain?' do
|
||||
# context 'with relation' do
|
||||
# before :all do
|
||||
# create_settings
|
||||
# Fabricate(:domain)
|
||||
# @contact = Fabricate(:contact)
|
||||
# end
|
||||
|
||||
# it 'should have relation with domain' do
|
||||
# @contact.relations_with_domain?.should == true
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
describe Contact, '.extract_params' do
|
||||
it 'returns params hash'do
|
||||
ph = { id: '123123', email: 'jdoe@example.com', authInfo: { pw: 'asde' },
|
||||
postalInfo: { name: 'fred', addr: { cc: 'EE' } } }
|
||||
Contact.extract_attributes(ph).should == {
|
||||
name: 'fred',
|
||||
email: 'jdoe@example.com'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe Contact, '.check_availability' do
|
||||
before do
|
||||
Fabricate(:contact, code: 'asd12')
|
||||
|
|
|
@ -61,22 +61,28 @@ describe Dnskey do
|
|||
d = Fabricate(:domain, name: 'emta.ee', dnskeys: [@dnskey])
|
||||
|
||||
dk = d.dnskeys.last
|
||||
dk.public_key = 'AwEAAfB9jK8rj/FAdE3t9bYXiTLpelwlgUyxbHEtvMvhdxs+yHv0h9fE '\
|
||||
'710u94LPAeVmXumT6SZPsoo+ALKdmTexkcU9DGQvb2+sPfModBKM/num '\
|
||||
'rScUw1FBe3HwRa9SqQpgpnCjIt0kEVKHAQdLOP86YznSA9uHAg9TTJuT '\
|
||||
'LkUtgtmwNAVFr6/mG+smE1v5NbxPccsFwVTA/T1IyaI4Z48VGCP2WNro '\
|
||||
'R7P6vet1gWhssirnnVYnur8DwWuMJ89o/HjzXeiEGUB8k5SOX+//67FN '\
|
||||
'm8Zs+1ObuAfY8xAHe0L5bxluEbh1T1ARp41QX77EMKVbkcSj7nuBeY8H '\
|
||||
'KiN8HsTvmZyDbRAQQaAJi68qOXsUIoQcpn89PoNoc60F7WlueA6ExSGX '\
|
||||
'KMWIH6nfLXFgidoZ6HxteyUUnZbHEdULjpAoCRuUDjjUnUgFS7eRANfw '\
|
||||
'RCcu9aLziMDp4UU61zVjtmQ7xn3G2W2+2ycqn/vEl/yFyBmHZ+7stpoC '\
|
||||
'd6NTZUn4/ellYSm9lx/vaXdPSinARpYMWtU79Hu/VRifaCQjYkBGAMwK '\
|
||||
'DshX4yJPjza/bqo0XV4WHj1szDFHe0tLN7g1Ojwtf5FR0zyHU3FN9uUa '\
|
||||
'y8a+dowd/fqOQA1jXR04g2PIfFYe0VudCEpmxSV9YDoqjghHeIKUX7Jn '\
|
||||
'KiHL5gk404S5a/Bv'
|
||||
|
||||
pk = 'AwEAAfB9jK8rj/FAdE3t9bYXiTLpelwlgUyxbHEtvMvhdxs+yHv0h9fE '\
|
||||
'710u94LPAeVmXumT6SZPsoo+ALKdmTexkcU9DGQvb2+sPfModBKM/num '\
|
||||
'rScUw1FBe3HwRa9SqQpgpnCjIt0kEVKHAQdLOP86YznSA9uHAg9TTJuT '\
|
||||
'LkUtgtmwNAVFr6/mG+smE1v5NbxPccsFwVTA/T1IyaI4Z48VGCP2WNro '\
|
||||
'R7P6vet1gWhssirnnVYnur8DwWuMJ89o/HjzXeiEGUB8k5SOX+//67FN '\
|
||||
'm8Zs+1ObuAfY8xAHe0L5bxluEbh1T1ARp41QX77EMKVbkcSj7nuBeY8H '\
|
||||
'KiN8HsTvmZyDbRAQQaAJi68qOXsUIoQcpn89PoNoc60F7WlueA6ExSGX '\
|
||||
'KMWIH6nfLXFgidoZ6HxteyUUnZbHEdULjpAoCRuUDjjUnUgFS7eRANfw '\
|
||||
'RCcu9aLziMDp4UU61zVjtmQ7xn3G2W2+2ycqn/vEl/yFyBmHZ+7stpoC '\
|
||||
'd6NTZUn4/ellYSm9lx/vaXdPSinARpYMWtU79Hu/VRifaCQjYkBGAMwK '\
|
||||
'DshX4yJPjza/bqo0XV4WHj1szDFHe0tLN7g1Ojwtf5FR0zyHU3FN9uUa '\
|
||||
'y8a+dowd/fqOQA1jXR04g2PIfFYe0VudCEpmxSV9YDoqjghHeIKUX7Jn '\
|
||||
'KiHL5gk404S5a/Bv'
|
||||
|
||||
dk.public_key = pk
|
||||
|
||||
dk.save
|
||||
dk.ds_digest.should == 'D7045D3C2EF7332409A132D935C8E2834A2AAB769B35BC370FA68C9445398288'
|
||||
dk.ds_key_tag.should == '31051'
|
||||
|
||||
dk.public_key.should == pk
|
||||
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
|
||||
|
|
|
@ -112,7 +112,7 @@ module Epp
|
|||
end
|
||||
|
||||
def next_domain_name
|
||||
"example#{@uniq_no.call}.ee"
|
||||
"example#{rand(100000000)}.ee"
|
||||
end
|
||||
|
||||
### REQUEST TEMPLATES ###
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
module EppContactXmlHelper
|
||||
def create_contact_xml(xml_params = {})
|
||||
defaults = {
|
||||
postalInfo: {
|
||||
name: { value: 'John Doe' },
|
||||
addr: {
|
||||
street: { value: '123 Example' },
|
||||
city: { value: 'Tallinn' },
|
||||
cc: { value: 'EE' }
|
||||
}
|
||||
},
|
||||
voice: { value: '+372.1234567' },
|
||||
email: { value: 'test@example.example' },
|
||||
ident: { value: '37605030299', attrs: { type: 'op' } }
|
||||
}
|
||||
|
||||
xml_params = defaults.deep_merge(xml_params)
|
||||
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
|
||||
epp_xml.create(xml_params)
|
||||
end
|
||||
|
||||
def update_contact_xml(xml_params = {})
|
||||
defaults = {
|
||||
id: { value: 'asd123123er' },
|
||||
authInfo: { pw: { value: 'password' } },
|
||||
chg: {
|
||||
postalInfo: {
|
||||
name: { value: 'John Doe Edited' }
|
||||
},
|
||||
voice: { value: '+372.7654321' },
|
||||
email: { value: 'edited@example.example' },
|
||||
disclose: {
|
||||
value: {
|
||||
voice: { value: '' },
|
||||
email: { value: '' }
|
||||
}, attrs: { flag: '0' }
|
||||
}
|
||||
}
|
||||
}
|
||||
xml_params = defaults.deep_merge(xml_params)
|
||||
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
|
||||
epp_xml.update(xml_params)
|
||||
end
|
||||
|
||||
def delete_contact_xml(xml_params = {})
|
||||
defaults = { id: { value: 'sh8012' } }
|
||||
xml_params = defaults.deep_merge(xml_params)
|
||||
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
|
||||
epp_xml.delete(xml_params)
|
||||
end
|
||||
|
||||
def info_contact_xml(xml_params = {})
|
||||
defaults = { id: { value: 'sh8012' }, authInfo: { pw: { value: 'password' } } }
|
||||
xml_params = defaults.deep_merge(xml_params)
|
||||
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
|
||||
epp_xml.info(xml_params)
|
||||
end
|
||||
|
||||
def check_contact_xml(xml_params = {})
|
||||
defaults = {
|
||||
id: { value: 'ad123c3' }
|
||||
}
|
||||
xml_params = defaults.deep_merge(xml_params)
|
||||
epp_xml = EppXml::Contact.new(cl_trid: 'ABC-12345')
|
||||
epp_xml.check(xml_params)
|
||||
end
|
||||
|
||||
def check_multiple_contacts_xml
|
||||
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<contact:check
|
||||
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
|
||||
<contact:id>check-1234</contact:id>
|
||||
<contact:id>check-4321</contact:id>
|
||||
</contact:check>
|
||||
</check>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>'
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.include EppContactXmlHelper
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue