mirror of
https://github.com/internetee/registry.git
synced 2025-07-25 20:18:22 +02:00
Merge branch 'master' of github.com:internetee/registry
This commit is contained in:
commit
66b6778243
20 changed files with 290 additions and 34 deletions
|
@ -307,3 +307,9 @@ Rollback to previous release:
|
|||
|
||||
mina rollback # staging
|
||||
mina pr rollback # production
|
||||
|
||||
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
|
||||
|
|
|
@ -10,7 +10,8 @@ module Epp::ContactsHelper
|
|||
# FIXME: Update returns 2303 update multiple times
|
||||
code = params_hash['epp']['command']['update']['update'][:id]
|
||||
@contact = Contact.where(code: code).first
|
||||
if update_rights? && stamp(@contact) && @contact.update_attributes(contact_and_address_attributes(:update))
|
||||
# if update_rights? && stamp(@contact) && @contact.update_attributes(contact_and_address_attributes(:update))
|
||||
if owner? && stamp(@contact) && @contact.update_attributes(contact_and_address_attributes(:update))
|
||||
render 'epp/contacts/update'
|
||||
else
|
||||
contact_exists?(code)
|
||||
|
@ -38,8 +39,8 @@ module Epp::ContactsHelper
|
|||
def info_contact
|
||||
handle_errors(@contact) and return unless @contact
|
||||
handle_errors(@contact) and return unless rights?
|
||||
@disclosure = ContactDisclosure.default_values.merge(@contact.disclosure.as_hash)
|
||||
@disclosure_policy = @contact.disclosure.attributes_with_flag
|
||||
@disclosure = ContactDisclosure.default_values.merge(@contact.disclosure.try(:as_hash) || {})
|
||||
@disclosure_policy = @contact.disclosure.try(:attributes_with_flag)
|
||||
@owner = owner?(false)
|
||||
render 'epp/contacts/info'
|
||||
end
|
||||
|
@ -67,7 +68,8 @@ module Epp::ContactsHelper
|
|||
def validate_contact_update_request
|
||||
@ph = params_hash['epp']['command']['update']['update']
|
||||
update_attrs_present?
|
||||
xml_attrs_present?(@ph, [['id'], %w(authInfo pw)])
|
||||
# xml_attrs_present?(@ph, [['id'], %w(authInfo pw)])
|
||||
xml_attrs_present?(@ph, [['id']])
|
||||
end
|
||||
|
||||
def contact_exists?(code)
|
||||
|
|
|
@ -11,13 +11,18 @@ module DomainVersionObserver
|
|||
name = domain_name
|
||||
return unless name
|
||||
body = snapshot
|
||||
delay.update_whois(name, body)
|
||||
delay.update_private_whois(name, body)
|
||||
delay.update_public_whois(name, body)
|
||||
end
|
||||
|
||||
# not sure we need to pass in the params since i don't know if delayed job has access to
|
||||
# all the regular attributes and stuff
|
||||
def update_whois(domain_name, body)
|
||||
wd = WhoisDomain.find_or_initialize_by(name: domain_name)
|
||||
def update_private_whois(domain_name, body)
|
||||
wd = Whois::PublicDomain.find_or_initialize_by(name: domain_name)
|
||||
wd.body = body
|
||||
wd.save!
|
||||
end
|
||||
|
||||
def update_public_whois(domain_name, body)
|
||||
wd = Whois::PrivateDomain.find_or_initialize_by(name: domain_name)
|
||||
wd.body = body
|
||||
wd.save!
|
||||
end
|
||||
|
|
|
@ -9,6 +9,7 @@ class Contact < ActiveRecord::Base
|
|||
|
||||
has_many :domain_contacts
|
||||
has_many :domains, through: :domain_contacts
|
||||
has_many :statuses, class_name: 'ContactStatus'
|
||||
|
||||
# TODO: remove the x_by
|
||||
belongs_to :created_by, class_name: 'EppUser', foreign_key: :created_by_id
|
||||
|
|
78
app/models/contact_status.rb
Normal file
78
app/models/contact_status.rb
Normal file
|
@ -0,0 +1,78 @@
|
|||
class ContactStatus < ActiveRecord::Base
|
||||
include EppErrors
|
||||
|
||||
belongs_to :contact
|
||||
|
||||
CLIENT_DELETE_PROHIBITED = 'clientDeleteProhibited'
|
||||
SERVER_DELETE_PROHIBITED = 'serverDeleteProhibited'
|
||||
CLIENT_HOLD = 'clientHold'
|
||||
SERVER_HOLD = 'serverHold'
|
||||
CLIENT_RENEW_PROHIBITED = 'clientRenewProhibited'
|
||||
SERVER_RENEW_PROHIBITED = 'serverRenewProhibited'
|
||||
CLIENT_TRANSFER_PROHIBITED = 'clientTransferProhibited'
|
||||
SERVER_TRANSFER_PROHIBITED = 'serverTransferProhibited'
|
||||
CLIENT_UPDATE_PROHIBITED = 'clientUpdateProhibited'
|
||||
SERVER_UPDATE_PROHIBITED = 'serverUpdateProhibited'
|
||||
INACTIVE = 'inactive'
|
||||
OK = 'ok'
|
||||
PENDING_CREATE = 'pendingCreate'
|
||||
PENDING_DELETE = 'pendingDelete'
|
||||
PENDING_RENEW = 'pendingRenew'
|
||||
PENDING_TRANSFER = 'pendingTransfer'
|
||||
PENDING_UPDATE = 'pendingUpdate'
|
||||
|
||||
SERVER_MANUAL_INZONE = 'serverManualInzone'
|
||||
SERVER_REGISTRANT_CHANGE_PROHIBITED = 'serverRegistrantChangeProhibited'
|
||||
SERVER_ADMIN_CHANGE_PROHIBITED = 'serverAdminChangeProhibited'
|
||||
SERVER_TECH_CHANGE_PROHIBITED = 'serverTechChangeProhibited'
|
||||
FORCE_DELETE = 'forceDelete'
|
||||
DELETE_CANDIDATE = 'deleteCandidate'
|
||||
EXPIRED = 'expired'
|
||||
|
||||
STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED, CLIENT_HOLD, SERVER_HOLD,
|
||||
CLIENT_RENEW_PROHIBITED, SERVER_RENEW_PROHIBITED, CLIENT_TRANSFER_PROHIBITED,
|
||||
SERVER_TRANSFER_PROHIBITED, CLIENT_UPDATE_PROHIBITED, SERVER_UPDATE_PROHIBITED,
|
||||
INACTIVE, OK, PENDING_CREATE, PENDING_DELETE, PENDING_RENEW, PENDING_TRANSFER,
|
||||
PENDING_UPDATE, SERVER_MANUAL_INZONE, SERVER_REGISTRANT_CHANGE_PROHIBITED,
|
||||
SERVER_ADMIN_CHANGE_PROHIBITED, SERVER_TECH_CHANGE_PROHIBITED, FORCE_DELETE,
|
||||
DELETE_CANDIDATE, EXPIRED
|
||||
]
|
||||
|
||||
CLIENT_STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, CLIENT_HOLD, CLIENT_RENEW_PROHIBITED, CLIENT_TRANSFER_PROHIBITED,
|
||||
CLIENT_UPDATE_PROHIBITED
|
||||
]
|
||||
|
||||
SERVER_STATUSES = [
|
||||
SERVER_DELETE_PROHIBITED, SERVER_HOLD, SERVER_RENEW_PROHIBITED, SERVER_TRANSFER_PROHIBITED,
|
||||
SERVER_UPDATE_PROHIBITED, SERVER_MANUAL_INZONE, SERVER_REGISTRANT_CHANGE_PROHIBITED,
|
||||
SERVER_ADMIN_CHANGE_PROHIBITED, SERVER_TECH_CHANGE_PROHIBITED
|
||||
]
|
||||
|
||||
def epp_code_map
|
||||
{
|
||||
'2302' => [ # Object exists
|
||||
[:value, :taken, { value: { obj: 'status', val: value } }]
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def server_status?
|
||||
SERVER_STATUSES.include?(value)
|
||||
end
|
||||
|
||||
def client_status?
|
||||
CLIENT_STATUSES.include?(value)
|
||||
end
|
||||
|
||||
class << self
|
||||
def statuses_for_client
|
||||
CLIENT_STATUSES.map { |x| x.sub('client', '') }
|
||||
end
|
||||
|
||||
def statuses_for_admin
|
||||
SERVER_STATUSES.map { |x| x.sub('server', '') }
|
||||
end
|
||||
end
|
||||
end
|
2
app/models/whois.rb
Normal file
2
app/models/whois.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
module Whois
|
||||
end
|
5
app/models/whois/private_domain.rb
Normal file
5
app/models/whois/private_domain.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
module Whois
|
||||
class PrivateDomain < PrivateServer
|
||||
self.table_name = 'domains'
|
||||
end
|
||||
end
|
6
app/models/whois/private_server.rb
Normal file
6
app/models/whois/private_server.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
module Whois
|
||||
class PrivateServer < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
establish_connection :"#{Rails.env}_private_whois"
|
||||
end
|
||||
end
|
5
app/models/whois/public_domain.rb
Normal file
5
app/models/whois/public_domain.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
module Whois
|
||||
class PublicDomain < PublicServer
|
||||
self.table_name = 'domains'
|
||||
end
|
||||
end
|
6
app/models/whois/public_server.rb
Normal file
6
app/models/whois/public_server.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
module Whois
|
||||
class PublicServer < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
establish_connection :"#{Rails.env}_public_whois"
|
||||
end
|
||||
end
|
|
@ -1,3 +0,0 @@
|
|||
class WhoisDomain < WhoisServer
|
||||
self.table_name = 'domains'
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
class WhoisServer < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
establish_connection :"#{Rails.env}_whois"
|
||||
end
|
|
@ -16,12 +16,17 @@ xml.epp_head do
|
|||
xml.tag!('contact:crDate', @contact.created_at)
|
||||
xml.tag!('contact:upID', @contact.up_id) if @contact.up_id
|
||||
xml.tag!('contact:upDate', @contact.updated_at) unless @contact.updated_at == @contact.created_at
|
||||
xml.tag!('contact:ident', @contact.ident, type: @contact.ident_type)
|
||||
xml.tag!('contact:trDate', '123') if false
|
||||
if @owner
|
||||
xml.tag!('contact:authInfo') do
|
||||
xml.tag!('contact:pw', @contact.auth_info) # Doc says we have to return this but is it necessary?
|
||||
end
|
||||
end
|
||||
# statuses
|
||||
@contact.statuses.each do |cs|
|
||||
xml.tag!('contact:status', s: cs.value)
|
||||
end
|
||||
xml << render('/epp/contacts/disclosure_policy')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,8 +18,18 @@ production:
|
|||
<<: *default
|
||||
database: registry_production
|
||||
|
||||
development_whois:
|
||||
database: whois_development
|
||||
development_private_whois:
|
||||
<<: *default
|
||||
database: whois_private
|
||||
|
||||
test_whois:
|
||||
database: test_whois
|
||||
development_private_whois:
|
||||
<<: *default
|
||||
database: whois_public
|
||||
|
||||
production_public_whois:
|
||||
<<: *default
|
||||
database: production_whois_public
|
||||
|
||||
production_private_whois:
|
||||
<<: *default
|
||||
database: production_whois_private
|
||||
|
|
10
db/migrate/20141216075056_create_contact_statuses.rb
Normal file
10
db/migrate/20141216075056_create_contact_statuses.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
class CreateContactStatuses < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :contact_statuses do |t|
|
||||
t.string :value
|
||||
t.string :description
|
||||
t.belongs_to :contact
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -59,6 +59,14 @@ ActiveRecord::Schema.define(version: 20141218154829) do
|
|||
t.boolean "address"
|
||||
end
|
||||
|
||||
create_table "contact_statuses", force: true do |t|
|
||||
t.string "value"
|
||||
t.string "description"
|
||||
t.integer "contact_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "contact_versions", force: true do |t|
|
||||
t.string "item_type", null: false
|
||||
t.integer "item_id", null: false
|
||||
|
|
61
doc/ssl.md
Normal file
61
doc/ssl.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
Setting up client-side certificate authentication
|
||||
-------------------------------------------------
|
||||
|
||||
This is written and tested on apache2.
|
||||
Requires openSSL, tested on OpenSSL version 1.0.1f 6 Jan 2014.
|
||||
First, setup openssl for use in being a certificate authority. For that you have to edit openssl.conf ( on debian based systems should be located at /etc/ssl/ )
|
||||
There are a lot of options there but some basics for example. Your policy_match will probably look different in production, also the default days (of key validity) should probably be not 10 years for production.
|
||||
|
||||
```
|
||||
default_ca = CA_development
|
||||
|
||||
[ CA_development ]
|
||||
dir = /etc/ssl/private
|
||||
database = $dir/index.txt
|
||||
serial = $dir/serial
|
||||
private_key = $dir/ca.key.pem
|
||||
certificate = $dir/ca.crt
|
||||
default_days = 3650
|
||||
default_md = md5
|
||||
new_certs_dir = $dir
|
||||
policy = policy_match
|
||||
|
||||
[ policy_match ]
|
||||
countryName = match
|
||||
stateOrProvinceName = match
|
||||
organizationName = match
|
||||
organizationalUnitName = match
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
```
|
||||
Following commands should be run in /etc/ssl/ unless you choose another location for your keys.
|
||||
Now you need cert authority key which can be generated by
|
||||
` openssl genrsa -out private/ca.key `
|
||||
Now generate a new certificate request with `openssl req -new -key private/ca.key -out private/ca.csr`
|
||||
And sign it `openssl x509 -req -days 3650 -in private/ca.csr -signkey private/ca.key -out private/ca.crt`
|
||||
Setup the first serial number for our keys, should be a 4 digit hex string `echo FAD0 > private/serial`
|
||||
Create key database `touch private/index.txt`
|
||||
And finally, create a cert revocation list for removing user certs `openssl ca -gencrl -out /etc/ssl/private/ca.crl -crldays 7`
|
||||
|
||||
Now, we need a certificate for our webserver. Don't bother putting a password on it since you need it to start apache. If there's a good workaround for this, please let us know.
|
||||
Let's generate the apache key, `openssl genrsa -out private/apache.key`
|
||||
Create a certificate request for it ` openssl req -new -key apache.key -out apache.csr` and sign it `openssl ca -in private/apache.csr -cert private/ca.crt -keyfile private/ca.key -out private/apache.crt`
|
||||
|
||||
|
||||
Now we are ready to setup apache to use our keys for authentication. A sample apache2 conf
|
||||
```
|
||||
SSLEngine on
|
||||
SSlOptions +StrictRequire
|
||||
SSLCertificateFile /etc/ssl/private/apache.crt
|
||||
SSLCertificateKeyFile /etc/ssl/private/apache.key
|
||||
SSLCACertificateFile /etc/ssl/private/ca.crt
|
||||
SSLVerifyClient require
|
||||
```
|
||||
*replace the repeating lines from previous apache conf with lines from this one*
|
||||
|
||||
There could be some more mojo needed to check if Certificates are expired and etc but I haven't really tested it out yet.
|
||||
|
||||
Now let's create an example user certificate.
|
||||
Start off with the key `openssl genrsa -des3 -out $base/users/$1/$1.key 1024` . Now a certificate signing request for that key `openssl req -new -key $base/users/$1/$1.key -out $base/users/$1/$1.csr` and finally let's sign it `openssl ca -in $base/users/$1/$1.csr -cert $base/ca.crt -keyfile $base/ca.key -out $base/users/$1/$1.crt` and we should be done.
|
||||
|
||||
In real life (!development), user should generate their own key and cert request.
|
20
doc/whois.rm
20
doc/whois.rm
|
@ -6,18 +6,20 @@ that disables whois (effects should fully be loaded after restarting the app)
|
|||
What whois_enabled=false does is that the whois callback does not get included.
|
||||
Delayed jobs migration and everything else will still be installed tho.
|
||||
|
||||
If you wish to use the whois module, tho, you need a whois database looking something like this
|
||||
Basic whois logic - we save whois data to 2 separate databases - whois private and public.
|
||||
Those two databases are streamed to appropriate whois servers.
|
||||
|
||||
```ruby
|
||||
create_table :domains do |t|
|
||||
t.string :name
|
||||
t.text :body
|
||||
t.timestamps
|
||||
end
|
||||
```
|
||||
This is still WIP and few whois details need to be sorted out.
|
||||
|
||||
NB! Migration with rake tasks is available in whois app repo.
|
||||
Setting the databases up
|
||||
__________________________________
|
||||
Make sure username and password in DATABASES at lib/tasks/whois.rb are correct ( match the ones
|
||||
in config/database.yml whois_public and whois_private attributes ). We don't load them from
|
||||
config/database.yml at the moment. So you might have to change them manually.
|
||||
|
||||
Finally set the whois app to connect to your whois_public/whois_private database and you're good to go.
|
||||
|
||||
Then run `rake whois:create` to create and migrate the databases.
|
||||
For development, delayed_job queue can be handled by rake task
|
||||
`rake jobs:work` or if you wish to be fancy you can use a daemon with `bin/delayed_job start`
|
||||
``
|
||||
|
|
53
lib/tasks/whois.rake
Normal file
53
lib/tasks/whois.rake
Normal file
|
@ -0,0 +1,53 @@
|
|||
DATABASES = [
|
||||
{ database: 'whois_public', host: 'localhost', adapter: 'postgresql', encoding: 'unicode',
|
||||
pool: '5', username: 'whois', password: 'test', port: '5432' },
|
||||
{ database: 'whois_private', host: 'localhost', adapter: 'postgresql', encoding: 'unicode',
|
||||
pool: '5', username: 'whois', password: 'test', port: '5432' }
|
||||
]
|
||||
|
||||
namespace :whois do
|
||||
task :load_config do
|
||||
require 'active_record'
|
||||
require 'pg'
|
||||
end
|
||||
|
||||
desc 'Create whois databases'
|
||||
task create: [:load_config] do
|
||||
DATABASES.each do |conf|
|
||||
create_database(conf)
|
||||
migrate
|
||||
end
|
||||
end
|
||||
|
||||
task 'Migrate whois databases'
|
||||
task migrate: [:load_config] do
|
||||
DATABASES.each do |conf|
|
||||
ActiveRecord::Base.establish_connection(conf)
|
||||
migrate
|
||||
end
|
||||
end
|
||||
|
||||
def create_database(conf)
|
||||
ActiveRecord::Base.establish_connection(conf.merge(database: 'postgres'))
|
||||
ActiveRecord::Base.connection.create_database(conf[:database])
|
||||
ActiveRecord::Base.establish_connection(conf)
|
||||
end
|
||||
|
||||
def migrate
|
||||
CreateWhoisBase.up
|
||||
end
|
||||
end
|
||||
|
||||
class CreateWhoisBase < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :domains do |t|
|
||||
t.string :name
|
||||
t.text :body
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drob_table :domains
|
||||
end
|
||||
end
|
|
@ -153,9 +153,7 @@ describe 'EPP Contact', epp: true do
|
|||
expect(response[:results][0][:msg]).to eq('Required parameter missing: add, rem or chg')
|
||||
expect(response[:results][1][:result_code]).to eq('2003')
|
||||
expect(response[:results][1][:msg]).to eq('Required parameter missing: id')
|
||||
expect(response[:results][2][:result_code]).to eq('2003')
|
||||
expect(response[:results][2][:msg]).to eq('Required parameter missing: pw')
|
||||
expect(response[:results].count).to eq 3
|
||||
expect(response[:results].count).to eq 2
|
||||
end
|
||||
|
||||
it 'fails with wrong authentication info' do
|
||||
|
@ -163,8 +161,8 @@ describe 'EPP Contact', epp: true do
|
|||
|
||||
response = epp_request(update_contact_xml({ id: { value: 'sh8013' } }), :xml, :elkdata)
|
||||
|
||||
expect(response[:msg]).to eq('Authentication error')
|
||||
expect(response[:result_code]).to eq('2200')
|
||||
expect(response[:msg]).to eq('Authorization error')
|
||||
expect(response[:result_code]).to eq('2201')
|
||||
end
|
||||
|
||||
it 'is succesful' do
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue