mirror of
https://github.com/internetee/registry.git
synced 2025-07-19 17:25:57 +02:00
Merge branch 'master' of github.com:domify/registry
This commit is contained in:
commit
2f352d8e6f
28 changed files with 432 additions and 74 deletions
|
@ -1,3 +1,6 @@
|
|||
07.07.2015
|
||||
* Before applyling 20150707104937_refactor_reserved_domains.rb migration, enable hstore extension in db
|
||||
|
||||
01.07.2015
|
||||
|
||||
* Added que init script example at doc/que directory, please setup que accornding to doc/que/README.md
|
||||
|
|
|
@ -13,10 +13,11 @@ class Admin::BlockedDomainsController < AdminController
|
|||
|
||||
if bd.update(names: names)
|
||||
flash[:notice] = I18n.t('record_updated')
|
||||
redirect_to :back
|
||||
else
|
||||
@blocked_domains = params[:blocked_domains]
|
||||
flash.now[:alert] = I18n.t('failed_to_update_record')
|
||||
render :index
|
||||
end
|
||||
|
||||
redirect_to :back
|
||||
end
|
||||
end
|
||||
|
|
30
app/controllers/admin/reserved_domains_controller.rb
Normal file
30
app/controllers/admin/reserved_domains_controller.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
class Admin::ReservedDomainsController < AdminController
|
||||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
rd = ReservedDomain.first_or_initialize
|
||||
@reserved_domains = rd.names.to_yaml
|
||||
end
|
||||
|
||||
def create
|
||||
@reserved_domains = params[:reserved_domains]
|
||||
|
||||
begin
|
||||
names = YAML.load(params[:reserved_domains])
|
||||
rescue
|
||||
flash.now[:alert] = I18n.t('invalid_yaml')
|
||||
logger.warn 'Invalid YAML'
|
||||
render :index and return
|
||||
end
|
||||
|
||||
rd = ReservedDomain.first_or_create
|
||||
|
||||
if rd.update(names: names)
|
||||
flash[:notice] = I18n.t('record_updated')
|
||||
redirect_to :back
|
||||
else
|
||||
flash.now[:alert] = I18n.t('failed_to_update_record')
|
||||
render :index
|
||||
end
|
||||
end
|
||||
end
|
|
@ -179,7 +179,7 @@ class Epp::DomainsController < EppController
|
|||
requires 'name'
|
||||
|
||||
@prefix = nil
|
||||
requires_attribute 'transfer', 'op', values: %(approve, query, reject)
|
||||
requires_attribute 'transfer', 'op', values: %(approve, query, reject, request)
|
||||
end
|
||||
|
||||
def find_domain
|
||||
|
|
|
@ -107,6 +107,7 @@ class Ability
|
|||
customer_service
|
||||
can :manage, Setting
|
||||
can :manage, BlockedDomain
|
||||
can :manage, ReservedDomain
|
||||
can :manage, ZonefileSetting
|
||||
can :manage, DomainVersion
|
||||
can :manage, Pricelist
|
||||
|
|
|
@ -79,7 +79,8 @@ module Depp
|
|||
end
|
||||
|
||||
def transfer(params)
|
||||
op = params[:query] ? 'query' : nil
|
||||
op = params[:request] ? 'request' : nil
|
||||
op = params[:query] ? 'query' : op
|
||||
op = params[:approve] ? 'approve' : op
|
||||
op = params[:reject] ? 'reject' : op
|
||||
|
||||
|
@ -132,7 +133,7 @@ module Depp
|
|||
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def construct_params_from_server_data(data)
|
||||
def construct_params_from_server_data(data)
|
||||
ret = default_params
|
||||
ret[:name] = data.css('name').text
|
||||
ret[:registrant] = data.css('registrant').text
|
||||
|
@ -182,16 +183,18 @@ module Depp
|
|||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
def construct_custom_params_hash(domain_params)
|
||||
custom_params = {}
|
||||
custom_params = { _anonymus: [] }
|
||||
if domain_params[:legal_document].present?
|
||||
type = domain_params[:legal_document].original_filename.split('.').last.downcase
|
||||
custom_params = {
|
||||
_anonymus: [
|
||||
legalDocument: { value: Base64.encode64(domain_params[:legal_document].read), attrs: { type: type } }
|
||||
]
|
||||
custom_params[:_anonymus] << {
|
||||
legalDocument: { value: Base64.encode64(domain_params[:legal_document].read), attrs: { type: type } }
|
||||
}
|
||||
end
|
||||
|
||||
if domain_params[:reserved_pw].present?
|
||||
custom_params[:_anonymus] << { reserved: { pw: { value: domain_params[:reserved_pw] } } }
|
||||
end
|
||||
|
||||
custom_params
|
||||
end
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ class Domain < ActiveRecord::Base
|
|||
|
||||
before_create :generate_auth_info
|
||||
before_create :set_validity_dates
|
||||
before_create -> { self.reserved = in_reserved_list?; nil }
|
||||
before_update :manage_statuses
|
||||
def manage_statuses
|
||||
return unless registrant_id_changed?
|
||||
|
@ -78,12 +79,32 @@ class Domain < ActiveRecord::Base
|
|||
|
||||
after_initialize -> { self.statuses = [] if statuses.nil? }
|
||||
|
||||
after_create :update_reserved_domains
|
||||
def update_reserved_domains
|
||||
return unless in_reserved_list?
|
||||
rd = ReservedDomain.first
|
||||
rd.names[name] = SecureRandom.hex
|
||||
rd.save
|
||||
end
|
||||
|
||||
validates :name_dirty, domain_name: true, uniqueness: true
|
||||
validates :puny_label, length: { maximum: 63 }
|
||||
validates :period, numericality: { only_integer: true }
|
||||
validates :registrant, :registrar, presence: true
|
||||
|
||||
validate :validate_period
|
||||
validate :validate_reservation
|
||||
def validate_reservation
|
||||
return if persisted? || !in_reserved_list?
|
||||
|
||||
if reserved_pw.blank?
|
||||
errors.add(:base, :required_parameter_missing_reserved)
|
||||
return false
|
||||
end
|
||||
|
||||
return if ReservedDomain.pw_for(name) == reserved_pw
|
||||
errors.add(:base, :invalid_auth_information_reserved)
|
||||
end
|
||||
|
||||
validates :nameservers, object_count: {
|
||||
min: -> { Setting.ns_min_count },
|
||||
|
@ -134,7 +155,7 @@ class Domain < ActiveRecord::Base
|
|||
end
|
||||
|
||||
attr_accessor :registrant_typeahead, :update_me, :deliver_emails,
|
||||
:epp_pending_update, :epp_pending_delete
|
||||
:epp_pending_update, :epp_pending_delete, :reserved_pw
|
||||
|
||||
def subordinate_nameservers
|
||||
nameservers.select { |x| x.hostname.end_with?(name) }
|
||||
|
@ -247,6 +268,10 @@ class Domain < ActiveRecord::Base
|
|||
@registrant_typeahead || registrant.try(:name) || nil
|
||||
end
|
||||
|
||||
def in_reserved_list?
|
||||
ReservedDomain.pw_for(name).present?
|
||||
end
|
||||
|
||||
def pending_transfer
|
||||
domain_transfers.find_by(status: DomainTransfer::PENDING)
|
||||
end
|
||||
|
|
|
@ -71,6 +71,7 @@ class DomainStatus < ActiveRecord::Base
|
|||
FORCE_DELETE = 'forceDelete'
|
||||
DELETE_CANDIDATE = 'deleteCandidate'
|
||||
EXPIRED = 'expired'
|
||||
RESERVED = 'reserved'
|
||||
|
||||
STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED, CLIENT_HOLD, SERVER_HOLD,
|
||||
|
|
|
@ -25,7 +25,8 @@ class Epp::Domain < Domain
|
|||
],
|
||||
'2003' => [ # Required parameter missing
|
||||
[:registrant, :blank],
|
||||
[:registrar, :blank]
|
||||
[:registrar, :blank],
|
||||
[:base, :required_parameter_missing_reserved]
|
||||
],
|
||||
'2004' => [ # Parameter value range error
|
||||
[:nameservers, :out_of_range,
|
||||
|
@ -60,6 +61,9 @@ class Epp::Domain < Domain
|
|||
'2201' => [ # Authorisation error
|
||||
[:auth_info, :wrong_pw]
|
||||
],
|
||||
'2202' => [
|
||||
[:base, :invalid_auth_information_reserved]
|
||||
],
|
||||
'2302' => [ # Object exists
|
||||
[:name_dirty, :taken, { value: { obj: 'name', val: name_dirty } }],
|
||||
[:name_dirty, :reserved, { value: { obj: 'name', val: name_dirty } }],
|
||||
|
@ -112,6 +116,8 @@ class Epp::Domain < Domain
|
|||
|
||||
at[:period_unit] = Epp::Domain.parse_period_unit_from_frame(frame) || 'y'
|
||||
|
||||
at[:reserved_pw] = frame.css('reserved > pw').text
|
||||
|
||||
# at[:statuses] = domain_statuses_attrs(frame, action)
|
||||
# binding.pry
|
||||
at[:nameservers_attributes] = nameservers_attrs(frame, action)
|
||||
|
@ -455,6 +461,8 @@ class Epp::Domain < Domain
|
|||
def transfer(frame, action, current_user)
|
||||
case action
|
||||
when 'query'
|
||||
return domain_transfers.last if domain_transfers.any?
|
||||
when 'request'
|
||||
return pending_transfer if pending_transfer
|
||||
return query_transfer(frame, current_user)
|
||||
when 'approve'
|
||||
|
@ -462,7 +470,7 @@ class Epp::Domain < Domain
|
|||
when 'reject'
|
||||
return reject_transfer(frame, current_user) if pending_transfer
|
||||
end
|
||||
add_epp_error('2303', nil, nil, I18n.t('pending_transfer_was_not_found'))
|
||||
add_epp_error('2303', nil, nil, I18n.t('no_transfers_found'))
|
||||
end
|
||||
|
||||
# TODO: Eager load problems here. Investigate how it's possible not to query contact again
|
||||
|
@ -742,7 +750,7 @@ class Epp::Domain < Domain
|
|||
next
|
||||
end
|
||||
|
||||
unless DomainNameValidator.validate_reservation(x)
|
||||
if ReservedDomain.pw_for(x).present?
|
||||
res << { name: x, avail: 0, reason: I18n.t('errors.messages.epp_domain_reserved') }
|
||||
next
|
||||
end
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
class ReservedDomain < ActiveRecord::Base
|
||||
include Versions # version/reserved_domain_version.rb
|
||||
|
||||
class << self
|
||||
def pw_for(domain_name)
|
||||
select("names -> '#{domain_name}' AS pw").first.try(:pw)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
class DomainNameValidator < ActiveModel::EachValidator
|
||||
# rubocop: disable Metrics/PerceivedComplexity
|
||||
# rubocop: disable Metrics/CyclomaticComplexity
|
||||
def validate_each(record, attribute, value)
|
||||
if !self.class.validate_format(value)
|
||||
record.errors[attribute] << (options[:message] || record.errors.generate_message(attribute, :invalid))
|
||||
elsif !self.class.validate_blocked(value)
|
||||
record.errors.add(attribute, (options[:message] || record.errors.generate_message(attribute, :blocked)))
|
||||
elsif !self.class.validate_reservation(value)
|
||||
record.errors.add(attribute, (options[:message] || record.errors.generate_message(attribute, :reserved)))
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/PerceivedComplexity
|
||||
# rubocop: enable Metrics/CyclomaticComplexity
|
||||
|
||||
class << self
|
||||
def validate_format(value)
|
||||
|
@ -41,10 +35,5 @@ class DomainNameValidator < ActiveModel::EachValidator
|
|||
return true unless value
|
||||
BlockedDomain.where("names @> ?::varchar[]", "{#{value}}").count == 0
|
||||
end
|
||||
|
||||
def validate_reservation(value)
|
||||
return true unless value
|
||||
!ReservedDomain.exists?(name: value.mb_chars.downcase.strip)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
10
app/views/admin/reserved_domains/index.haml
Normal file
10
app/views/admin/reserved_domains/index.haml
Normal file
|
@ -0,0 +1,10 @@
|
|||
= render 'shared/title', name: t(:reserved_domains)
|
||||
|
||||
= form_tag([:admin, :reserved_domains]) do |f|
|
||||
.row
|
||||
.col-md-12
|
||||
= text_area_tag :reserved_domains, @reserved_domains, class: 'form-control', rows: 30
|
||||
%hr
|
||||
.row
|
||||
.col-md-12.text-right
|
||||
%button.btn.btn-warning=t(:save)
|
|
@ -60,6 +60,7 @@
|
|||
%li= link_to t(:settings), admin_settings_path
|
||||
%li= link_to t(:zonefile), admin_zonefile_settings_path
|
||||
%li= link_to t(:blocked_domains), admin_blocked_domains_path
|
||||
%li= link_to t(:reserved_domains), admin_reserved_domains_path
|
||||
-# %li= link_to t(:domains_history), admin_domain_versions_path
|
||||
%li= link_to t(:epp_logs), admin_epp_logs_path
|
||||
%li= link_to t(:repp_logs), admin_repp_logs_path
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
= label_tag :domain_name, t(:name), class: 'required'
|
||||
.col-md-7
|
||||
- readonly = params[:domain_name] ? true : false
|
||||
= text_field_tag('domain[name]', @domain_params[:name],
|
||||
= text_field_tag('domain[name]', @domain_params[:name],
|
||||
class: 'form-control', readonly: readonly, required: true)
|
||||
|
||||
- unless params[:domain_name]
|
||||
|
@ -13,13 +13,20 @@
|
|||
.col-md-3.control-label
|
||||
= label_tag :domain_period, t(:period), class: 'required'
|
||||
.col-md-7
|
||||
= select_tag 'domain[period]',
|
||||
= select_tag 'domain[period]',
|
||||
options_for_select(Depp::Domain::PERIODS, @domain_params[:period]), { class: 'form-control' }
|
||||
|
||||
.form-group
|
||||
.col-md-3.control-label
|
||||
= label_tag :domain_registrant, t(:registrant), class: 'required'
|
||||
.col-md-7
|
||||
= select_tag "domain[registrant]",
|
||||
= select_tag "domain[registrant]",
|
||||
options_for_select(@contacts_autocomplete_map, selected: @domain_params[:registrant]),
|
||||
include_blank: true, class: 'js-combobox', required: true
|
||||
|
||||
- unless params[:domain_name]
|
||||
.form-group
|
||||
.col-md-3.control-label
|
||||
= label_tag :domain_reserved_pw, t(:reserved_pw)
|
||||
.col-md-7
|
||||
= text_field_tag('domain[reserved_pw]', @domain_params[:reserved_pw], class: 'form-control')
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
= file_field_tag 'legal_document'
|
||||
.form-group
|
||||
.col-md-10.text-right
|
||||
%button.btn.btn-warning{ name: 'query' }= t(:transfer)
|
||||
%button.btn.btn-warning{ name: 'request' }= t(:transfer)
|
||||
/%button.btn.btn-warning{ name: 'approve' }= t(:approve)
|
||||
/%button.btn.btn-warning{ name: 'reject' }= t(:reject)
|
||||
|
|
|
@ -60,6 +60,8 @@ en:
|
|||
ds_data_not_allowed: 'dsData object is not allowed'
|
||||
ds_data_with_key_not_allowed: 'dsData object with key data is not allowed'
|
||||
key_data_not_allowed: 'keyData object is not allowed'
|
||||
required_parameter_missing_reserved: 'Required parameter missing; reserved>pw element required for reserved domains'
|
||||
invalid_auth_information_reserved: 'Invalid authorization information; invalid reserved>pw value'
|
||||
name_dirty:
|
||||
invalid: 'Domain name is invalid'
|
||||
reserved: 'Domain name is reserved'
|
||||
|
@ -238,7 +240,7 @@ en:
|
|||
errors:
|
||||
messages:
|
||||
blank: 'is missing'
|
||||
epp_domain_reserved: 'Domain name is reserved or restricted'
|
||||
epp_domain_reserved: 'Domain name is reserved'
|
||||
epp_obj_does_not_exist: 'Object does not exist'
|
||||
epp_command_failed: 'Command failed'
|
||||
epp_authorization_error: 'Authorization error'
|
||||
|
@ -861,3 +863,7 @@ en:
|
|||
receipt_date_until: 'Receipt date until'
|
||||
add_credit: 'Add credit'
|
||||
export_csv: 'Export CSV'
|
||||
reserved_domains: 'Reserved domains'
|
||||
invalid_yaml: 'Invalid YAML'
|
||||
reserved_pw: 'Reserved pw'
|
||||
no_transfers_found: 'No transfers found'
|
||||
|
|
|
@ -190,6 +190,7 @@ Rails.application.routes.draw do
|
|||
resources :settings
|
||||
|
||||
resources :blocked_domains
|
||||
resources :reserved_domains
|
||||
|
||||
resources :registrars do
|
||||
resources :api_users
|
||||
|
|
6
db/migrate/20150707104937_refactor_reserved_domains.rb
Normal file
6
db/migrate/20150707104937_refactor_reserved_domains.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class RefactorReservedDomains < ActiveRecord::Migration
|
||||
def change
|
||||
remove_column :reserved_domains, :name
|
||||
add_column :reserved_domains, :names, :hstore
|
||||
end
|
||||
end
|
11
db/migrate/20150707154543_increase_decimal_precision.rb
Normal file
11
db/migrate/20150707154543_increase_decimal_precision.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
class IncreaseDecimalPrecision < ActiveRecord::Migration
|
||||
def change
|
||||
change_column :account_activities, :sum, :decimal, precision: 10, scale: 2
|
||||
change_column :accounts, :balance, :decimal, precision: 10, scale: 2, default: 0.0, null: false
|
||||
change_column :bank_transactions, :sum, :decimal, precision: 10, scale: 2
|
||||
change_column :banklink_transactions, :vk_amount, :decimal, precision: 10, scale: 2
|
||||
change_column :invoice_items, :price, :decimal, precision: 10, scale: 2
|
||||
change_column :invoices, :vat_prc, :decimal, precision: 10, scale: 2
|
||||
change_column :invoices, :sum_cache, :decimal, precision: 10, scale: 2
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class AddReservedFieldToDomain < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :domains, :reserved, :boolean, default: false
|
||||
end
|
||||
end
|
|
@ -11,10 +11,11 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150706091724) do
|
||||
ActiveRecord::Schema.define(version: 20150709092549) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
enable_extension "hstore"
|
||||
|
||||
create_table "account_activities", force: :cascade do |t|
|
||||
t.integer "account_id"
|
||||
|
@ -212,6 +213,12 @@ ActiveRecord::Schema.define(version: 20150706091724) do
|
|||
t.string "updator_str"
|
||||
end
|
||||
|
||||
create_table "data_migrations", id: false, force: :cascade do |t|
|
||||
t.string "version", null: false
|
||||
end
|
||||
|
||||
add_index "data_migrations", ["version"], name: "unique_data_migrations", unique: true, using: :btree
|
||||
|
||||
create_table "delegation_signers", force: :cascade do |t|
|
||||
t.integer "domain_id"
|
||||
t.string "key_tag"
|
||||
|
@ -316,7 +323,8 @@ ActiveRecord::Schema.define(version: 20150706091724) do
|
|||
t.string "registrant_verification_token"
|
||||
t.json "pending_json"
|
||||
t.datetime "force_delete_at"
|
||||
t.string "statuses", array: true
|
||||
t.string "statuses", array: true
|
||||
t.boolean "reserved", default: false
|
||||
end
|
||||
|
||||
add_index "domains", ["delete_at"], name: "index_domains_on_delete_at", using: :btree
|
||||
|
@ -978,11 +986,11 @@ ActiveRecord::Schema.define(version: 20150706091724) do
|
|||
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"
|
||||
t.datetime "updated_at"
|
||||
t.string "creator_str"
|
||||
t.string "updator_str"
|
||||
t.hstore "names"
|
||||
end
|
||||
|
||||
create_table "settings", force: :cascade do |t|
|
||||
|
@ -1020,7 +1028,7 @@ ActiveRecord::Schema.define(version: 20150706091724) do
|
|||
t.text "crt"
|
||||
t.string "type"
|
||||
t.string "registrant_ident"
|
||||
t.string "encrypted_password", default: ""
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
t.datetime "remember_created_at"
|
||||
t.integer "failed_attempts", default: 0, null: false
|
||||
t.datetime "locked_at"
|
||||
|
|
|
@ -23,6 +23,20 @@ CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
|
|||
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
|
||||
|
||||
|
||||
--
|
||||
-- Name: hstore; Type: EXTENSION; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;
|
||||
|
||||
|
||||
--
|
||||
-- Name: EXTENSION hstore; Type: COMMENT; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs';
|
||||
|
||||
|
||||
SET search_path = public, pg_catalog;
|
||||
|
||||
--
|
||||
|
@ -41,7 +55,7 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text
|
|||
ret text;
|
||||
BEGIN
|
||||
-- define filters
|
||||
include_filter = '%' || i_origin;
|
||||
include_filter = '%.' || i_origin;
|
||||
|
||||
-- for %.%.%
|
||||
IF i_origin ~ '\.' THEN
|
||||
|
@ -74,7 +88,7 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text
|
|||
SELECT concat(d.name_puny, '. IN NS ', ns.hostname, '.')
|
||||
FROM domains d
|
||||
JOIN nameservers ns ON ns.domain_id = d.id
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter
|
||||
WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter OR d.name = i_origin
|
||||
ORDER BY d.name
|
||||
),
|
||||
chr(10)
|
||||
|
@ -237,7 +251,7 @@ CREATE TABLE accounts (
|
|||
id integer NOT NULL,
|
||||
registrar_id integer,
|
||||
account_type character varying,
|
||||
balance numeric(10,2) DEFAULT 0 NOT NULL,
|
||||
balance numeric(10,2) DEFAULT 0.0 NOT NULL,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
currency character varying,
|
||||
|
@ -673,6 +687,15 @@ CREATE SEQUENCE countries_id_seq
|
|||
ALTER SEQUENCE countries_id_seq OWNED BY countries.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: data_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace:
|
||||
--
|
||||
|
||||
CREATE TABLE data_migrations (
|
||||
version character varying NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: delegation_signers; Type: TABLE; Schema: public; Owner: -; Tablespace:
|
||||
--
|
||||
|
@ -919,7 +942,8 @@ CREATE TABLE domains (
|
|||
registrant_verification_token character varying,
|
||||
pending_json json,
|
||||
force_delete_at timestamp without time zone,
|
||||
statuses character varying[]
|
||||
statuses character varying[],
|
||||
reserved boolean DEFAULT false
|
||||
);
|
||||
|
||||
|
||||
|
@ -2358,7 +2382,7 @@ CREATE TABLE pricelists (
|
|||
id integer NOT NULL,
|
||||
"desc" character varying,
|
||||
category character varying,
|
||||
price_cents numeric(10,2) DEFAULT 0 NOT NULL,
|
||||
price_cents numeric(10,2) DEFAULT 0.0 NOT NULL,
|
||||
price_currency character varying DEFAULT 'EUR'::character varying NOT NULL,
|
||||
valid_from timestamp without time zone,
|
||||
valid_to timestamp without time zone,
|
||||
|
@ -2497,11 +2521,11 @@ ALTER SEQUENCE registrars_id_seq OWNED BY registrars.id;
|
|||
|
||||
CREATE TABLE reserved_domains (
|
||||
id integer NOT NULL,
|
||||
name character varying,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
creator_str character varying,
|
||||
updator_str character varying
|
||||
updator_str character varying,
|
||||
names hstore
|
||||
);
|
||||
|
||||
|
||||
|
@ -2596,7 +2620,7 @@ CREATE TABLE users (
|
|||
crt text,
|
||||
type character varying,
|
||||
registrant_ident character varying,
|
||||
encrypted_password character varying DEFAULT ''::character varying,
|
||||
encrypted_password character varying DEFAULT ''::character varying NOT NULL,
|
||||
remember_created_at timestamp without time zone,
|
||||
failed_attempts integer DEFAULT 0 NOT NULL,
|
||||
locked_at timestamp without time zone
|
||||
|
@ -4452,6 +4476,13 @@ CREATE INDEX index_whois_records_on_domain_id ON whois_records USING btree (doma
|
|||
CREATE INDEX index_whois_records_on_registrar_id ON whois_records USING btree (registrar_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: unique_data_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace:
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX unique_data_migrations ON data_migrations USING btree (version);
|
||||
|
||||
|
||||
--
|
||||
-- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace:
|
||||
--
|
||||
|
@ -4667,8 +4698,6 @@ INSERT INTO schema_migrations (version) VALUES ('20150227092508');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150227113121');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150302130224');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150302161712');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150303130729');
|
||||
|
@ -4727,8 +4756,6 @@ INSERT INTO schema_migrations (version) VALUES ('20150417082723');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150421134820');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150422090645');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150422092514');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150422132631');
|
||||
|
@ -4773,8 +4800,6 @@ INSERT INTO schema_migrations (version) VALUES ('20150519115050');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150519140853');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150519142542');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150519144118');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150520163237');
|
||||
|
@ -4783,12 +4808,6 @@ INSERT INTO schema_migrations (version) VALUES ('20150520164507');
|
|||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150521120145');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150522164020');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150525075550');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150603141054');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150603141549');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150603211318');
|
||||
|
@ -4810,3 +4829,10 @@ INSERT INTO schema_migrations (version) VALUES ('20150701074344');
|
|||
INSERT INTO schema_migrations (version) VALUES ('20150703084632');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150706091724');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150707104937');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150707154543');
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('20150709092549');
|
||||
|
||||
|
|
|
@ -15,22 +15,40 @@
|
|||
Child elements found in EPP commands.
|
||||
-->
|
||||
|
||||
<element name="extdata" type="eis:legalDocAndIdentType"/>
|
||||
<element name="extdata" type="eis:eisExtType"/>
|
||||
|
||||
<!--
|
||||
Child elements supporting ident and legal documents.
|
||||
Child elements supporting EIS specific values.
|
||||
-->
|
||||
<complexType name="legalDocAndIdentType">
|
||||
<complexType name="eisExtType">
|
||||
<sequence>
|
||||
<element name="ident" type="eis:identType" minOccurs="0" maxOccurs="1"/>
|
||||
<element name="legalDocument" type="eis:legalDocType" minOccurs="0" maxOccurs="1"/>
|
||||
<element name="reserved" type="eis:reservedType" minOccurs="0" maxOccurs="1"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<!--
|
||||
Child elements of extdata
|
||||
Child elements of extdata
|
||||
-->
|
||||
|
||||
<!--
|
||||
Reserved for providing passwords for reserved domains
|
||||
-->
|
||||
|
||||
<complexType name="reservedType">
|
||||
<sequence>
|
||||
<element name="pw" type="eis:pwType" minOccurs="0" maxOccurs="1"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="pwType">
|
||||
<restriction base="normalizedString">
|
||||
<minLength value="1"/>
|
||||
<maxLength value="255"/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<!--
|
||||
Legal document, encoded in base64
|
||||
-->
|
||||
|
|
|
@ -144,6 +144,7 @@ describe 'EPP Domain', epp: true do
|
|||
response[:result_code].should == '1000'
|
||||
d = Domain.last
|
||||
d.legal_documents.count.should == 1
|
||||
d.reserved.should == false
|
||||
end
|
||||
|
||||
# it 'creates ria.ee with valid ds record' do
|
||||
|
@ -224,9 +225,47 @@ describe 'EPP Domain', epp: true do
|
|||
xml = domain_create_xml(name: { value: '1162.ee' })
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:result_code].should == '2302'
|
||||
response[:msg].should == 'Domain name is reserved [name_dirty]'
|
||||
response[:msg].should == 'Required parameter missing; reserved>pw element required for reserved domains'
|
||||
response[:result_code].should == '2003'
|
||||
response[:clTRID].should == 'ABC-12345'
|
||||
|
||||
xml = domain_create_xml({name: { value: '1162.ee' }}, {}, {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
attrs: { type: 'pdf' }
|
||||
},
|
||||
reserved: {
|
||||
pw: { value: 'wrong_pw' }
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:msg].should == 'Invalid authorization information; invalid reserved>pw value'
|
||||
response[:result_code].should == '2202'
|
||||
end
|
||||
|
||||
it 'creates a reserved domain with correct auth info' do
|
||||
xml = domain_create_xml({name: { value: '1162.ee' }}, {}, {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
attrs: { type: 'pdf' }
|
||||
},
|
||||
reserved: {
|
||||
pw: { value: 'abc' }
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:msg].should == 'Command completed successfully'
|
||||
response[:result_code].should == '1000'
|
||||
|
||||
d = Domain.last
|
||||
d.statuses.should match_array(['ok'])
|
||||
d.reserved.should == true
|
||||
end
|
||||
|
||||
it 'does not create blocked domain' do
|
||||
|
@ -800,7 +839,7 @@ describe 'EPP Domain', epp: true do
|
|||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'query', {
|
||||
}, 'request', {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
|
@ -848,7 +887,7 @@ describe 'EPP Domain', epp: true do
|
|||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'query', {
|
||||
}, 'request', {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
|
@ -926,7 +965,7 @@ describe 'EPP Domain', epp: true do
|
|||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'query', {
|
||||
}, 'request', {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
|
@ -1362,7 +1401,7 @@ describe 'EPP Domain', epp: true do
|
|||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: 'test' } }
|
||||
}, 'query', {
|
||||
}, 'request', {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
|
@ -1376,12 +1415,12 @@ describe 'EPP Domain', epp: true do
|
|||
response[:msg].should == 'Authorization error'
|
||||
end
|
||||
|
||||
it 'ignores transfer wha registrant registrar requests transfer' do
|
||||
it 'ignores transfer when domain already belongs to registrar' do
|
||||
pw = domain.auth_info
|
||||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'query', {
|
||||
}, 'request', {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
|
@ -1407,7 +1446,7 @@ describe 'EPP Domain', epp: true do
|
|||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'query', {
|
||||
}, 'request', {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
|
@ -1419,8 +1458,8 @@ describe 'EPP Domain', epp: true do
|
|||
login_as :registrar2 do
|
||||
epp_plain_request(xml) # transfer domain
|
||||
response = epp_plain_request(xml) # attempt second transfer
|
||||
response[:result_code].should == '2201'
|
||||
response[:msg].should == 'Authorization error'
|
||||
response[:result_code].should == '2201'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1439,10 +1478,118 @@ describe 'EPP Domain', epp: true do
|
|||
})
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:msg].should == 'Pending transfer was not found'
|
||||
response[:msg].should == 'No transfers found'
|
||||
response[:result_code].should == '2303'
|
||||
end
|
||||
|
||||
it 'should not return transfers when there are none' do
|
||||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: domain.auth_info } }
|
||||
}, 'query')
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:results][0][:msg].should == 'No transfers found'
|
||||
response[:results][0][:result_code].should == '2303'
|
||||
end
|
||||
|
||||
it 'should allow querying domain transfer' do
|
||||
Setting.transfer_wait_time = 1
|
||||
pw = domain.auth_info
|
||||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'request', {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
attrs: { type: 'pdf' }
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
login_as :registrar2 do
|
||||
response = epp_plain_request(xml)
|
||||
response[:results][0][:msg].should == 'Command completed successfully'
|
||||
response[:results][0][:result_code].should == '1000'
|
||||
|
||||
trn_data = response[:parsed].css('trnData')
|
||||
|
||||
dtl = domain.domain_transfers.last
|
||||
|
||||
trn_data.css('name').text.should == domain.name
|
||||
trn_data.css('trStatus').text.should == 'pending'
|
||||
trn_data.css('reID').text.should == 'REGDOMAIN2'
|
||||
trn_data.css('reDate').text.should == dtl.transfer_requested_at.in_time_zone.utc.utc.iso8601
|
||||
trn_data.css('acDate').text.should == dtl.wait_until.in_time_zone.utc.utc.iso8601
|
||||
trn_data.css('acID').text.should == 'REGDOMAIN1'
|
||||
trn_data.css('exDate').text.should == domain.valid_to.in_time_zone.utc.utc.iso8601
|
||||
|
||||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'query')
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:results][0][:msg].should == 'Command completed successfully'
|
||||
response[:results][0][:result_code].should == '1000'
|
||||
|
||||
trn_data = response[:parsed].css('trnData')
|
||||
|
||||
dtl = domain.domain_transfers.last
|
||||
trn_data.css('name').text.should == domain.name
|
||||
trn_data.css('trStatus').text.should == 'pending'
|
||||
trn_data.css('reID').text.should == 'REGDOMAIN2'
|
||||
trn_data.css('reDate').text.should == dtl.transfer_requested_at.in_time_zone.utc.utc.iso8601
|
||||
trn_data.css('acDate').text.should == dtl.wait_until.in_time_zone.utc.utc.iso8601
|
||||
trn_data.css('acID').text.should == 'REGDOMAIN1'
|
||||
trn_data.css('exDate').text.should == domain.valid_to.in_time_zone.utc.utc.iso8601
|
||||
end
|
||||
|
||||
# approves pending transfer
|
||||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'approve', {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
attrs: { type: 'pdf' }
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:results][0][:msg].should == 'Command completed successfully'
|
||||
response[:results][0][:result_code].should == '1000'
|
||||
|
||||
# query should return last completed transfer
|
||||
domain.reload
|
||||
pw = domain.auth_info
|
||||
xml = domain_transfer_xml({
|
||||
name: { value: domain.name },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'query')
|
||||
|
||||
response = epp_plain_request(xml)
|
||||
response[:results][0][:msg].should == 'Command completed successfully'
|
||||
response[:results][0][:result_code].should == '1000'
|
||||
|
||||
trn_data = response[:parsed].css('trnData')
|
||||
|
||||
dtl = domain.domain_transfers.last
|
||||
|
||||
trn_data.css('name').text.should == domain.name
|
||||
trn_data.css('trStatus').text.should == 'clientApproved'
|
||||
trn_data.css('reID').text.should == 'REGDOMAIN2'
|
||||
trn_data.css('reDate').text.should == dtl.transfer_requested_at.in_time_zone.utc.utc.iso8601
|
||||
trn_data.css('acDate').text.should == dtl.transferred_at.in_time_zone.utc.utc.iso8601
|
||||
trn_data.css('acID').text.should == 'REGDOMAIN1'
|
||||
trn_data.css('exDate').text.should == domain.valid_to.in_time_zone.utc.utc.iso8601
|
||||
|
||||
Setting.transfer_wait_time = 0
|
||||
end
|
||||
|
||||
### UPDATE ###
|
||||
it 'should update right away without update pending status' do
|
||||
existing_pw = domain.auth_info
|
||||
|
|
|
@ -10,7 +10,7 @@ describe 'EPP Helper', epp: true do
|
|||
expected = Nokogiri::XML('<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<transfer op="query">
|
||||
<transfer op="request">
|
||||
<domain:transfer
|
||||
xmlns:domain="https://raw.githubusercontent.com/internetee/registry/alpha/doc/schemas/domain-eis-1.0.xsd">
|
||||
<domain:name>' + dn + '</domain:name>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Fabricator(:reserved_domain) do
|
||||
name '1162.ee'
|
||||
names { { '1162.ee': 'abc' } }
|
||||
end
|
||||
|
|
43
spec/features/admin/reserved_domain_spec.rb
Normal file
43
spec/features/admin/reserved_domain_spec.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
require 'rails_helper'
|
||||
|
||||
feature 'ReservedDomain', type: :feature do
|
||||
before :all do
|
||||
@user = Fabricate(:admin_user)
|
||||
end
|
||||
|
||||
before do
|
||||
sign_in @user
|
||||
end
|
||||
|
||||
it 'should manage reserved domains' do
|
||||
visit admin_reserved_domains_url
|
||||
page.should have_content('Reserved domains')
|
||||
|
||||
d = Fabricate.build(:domain, name: '110.ee')
|
||||
d.valid?
|
||||
d.errors.full_messages.should match_array([])
|
||||
|
||||
fill_in 'reserved_domains', with: "110.ee: testpw"
|
||||
click_button 'Save'
|
||||
|
||||
page.should have_content('Record updated')
|
||||
page.should have_content('110.ee: testpw')
|
||||
|
||||
d.valid?.should == false
|
||||
d.errors.full_messages.should match_array(
|
||||
["Required parameter missing; reserved>pw element required for reserved domains"]
|
||||
)
|
||||
|
||||
d.reserved_pw = 'wrongpw'
|
||||
d.valid?.should == false
|
||||
|
||||
d.reserved_pw = 'testpw'
|
||||
d.valid?.should == true
|
||||
d.errors.full_messages.should match_array([])
|
||||
|
||||
d.save
|
||||
visit admin_reserved_domains_url
|
||||
page.should have_content('110.ee')
|
||||
page.should_not have_content('110.ee: testpw')
|
||||
end
|
||||
end
|
|
@ -144,7 +144,7 @@ module Epp
|
|||
end
|
||||
|
||||
# rubocop: disable Metrics/MethodLength
|
||||
def domain_create_xml(xml_params = {}, dnssec_params = {})
|
||||
def domain_create_xml(xml_params = {}, dnssec_params = {}, custom_params = {})
|
||||
defaults = {
|
||||
name: { value: next_domain_name },
|
||||
period: { value: '1', attrs: { unit: 'y' } },
|
||||
|
@ -185,7 +185,7 @@ module Epp
|
|||
|
||||
dnssec_params = dnssec_defaults.deep_merge(dnssec_params) if dnssec_params != false
|
||||
|
||||
custom_params = {
|
||||
custom_defaults = {
|
||||
_anonymus: [
|
||||
legalDocument: {
|
||||
value: 'dGVzdCBmYWlsCg==',
|
||||
|
@ -194,6 +194,8 @@ module Epp
|
|||
]
|
||||
}
|
||||
|
||||
custom_params = custom_defaults.deep_merge(custom_params) if custom_params != false
|
||||
|
||||
epp_xml = EppXml::Domain.new(cl_trid: 'ABC-12345')
|
||||
epp_xml.create(xml_params, dnssec_params, custom_params)
|
||||
end
|
||||
|
@ -347,7 +349,7 @@ module Epp
|
|||
epp_xml.check(xml_params)
|
||||
end
|
||||
|
||||
def domain_transfer_xml(xml_params = {}, op = 'query', custom_params = {})
|
||||
def domain_transfer_xml(xml_params = {}, op = 'request', custom_params = {})
|
||||
defaults = {
|
||||
name: { value: next_domain_name },
|
||||
authInfo: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue