mirror of
https://github.com/internetee/registry.git
synced 2025-05-19 10:49:39 +02:00
Merge pull request #160 from internetee/story/116761157-contact-dyn-states
Story/116761157 contact dyn states
This commit is contained in:
commit
f2f9377cd9
9 changed files with 72 additions and 108 deletions
|
@ -35,7 +35,7 @@ module Repp
|
||||||
error! I18n.t('errors.messages.epp_authorization_error'), 401 unless domain.auth_info.eql? request.headers['Auth-Code']
|
error! I18n.t('errors.messages.epp_authorization_error'), 401 unless domain.auth_info.eql? request.headers['Auth-Code']
|
||||||
|
|
||||||
contact_repp_json = proc{|contact|
|
contact_repp_json = proc{|contact|
|
||||||
contact.attributes.slice("code", "name", "ident", "ident_type", "ident_country_code", "phone", "email", "street", "city", "zip","country_code", "statuses")
|
contact.as_json.slice("code", "name", "ident", "ident_type", "ident_country_code", "phone", "email", "street", "city", "zip","country_code", "statuses")
|
||||||
}
|
}
|
||||||
|
|
||||||
@response = {
|
@response = {
|
||||||
|
|
|
@ -10,21 +10,13 @@ class Admin::ContactsController < AdminController
|
||||||
search_params[:registrant_domains_id_not_null] = 1
|
search_params[:registrant_domains_id_not_null] = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
@q = Contact.includes(:registrar).joins(:registrar).select('contacts.*, registrars.name').search(search_params)
|
|
||||||
@contacts = @q.result(distinct: :true).page(params[:page])
|
|
||||||
|
|
||||||
if params[:statuses_contains]
|
|
||||||
contacts = Contact.includes(:registrar).joins(:registrar).select('contacts.*, registrars.name').where(
|
|
||||||
"contacts.statuses @> ?::varchar[]", "{#{params[:statuses_contains].join(',')}}"
|
|
||||||
)
|
|
||||||
else
|
|
||||||
contacts = Contact.includes(:registrar).joins(:registrar).select('contacts.*, registrars.name')
|
contacts = Contact.includes(:registrar).joins(:registrar).select('contacts.*, registrars.name')
|
||||||
end
|
contacts = contacts.filter_by_states(params[:statuses_contains].join(',')) if params[:statuses_contains]
|
||||||
contacts = contacts.where("ident_country_code is null or ident_country_code=''") if params[:only_no_country_code].eql?('1')
|
contacts = contacts.where("ident_country_code is null or ident_country_code=''") if params[:only_no_country_code].eql?('1')
|
||||||
|
|
||||||
|
|
||||||
normalize_search_parameters do
|
normalize_search_parameters do
|
||||||
@q = contacts.includes(:registrar).joins(:registrar).select('contacts.*, registrars.name').search(search_params)
|
@q = contacts.search(search_params)
|
||||||
@contacts = @q.result.uniq.page(params[:page])
|
@contacts = @q.result.uniq.page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ class Admin::SettingsController < AdminController
|
||||||
:admin_contacts_max_count,
|
:admin_contacts_max_count,
|
||||||
:tech_contacts_min_count,
|
:tech_contacts_min_count,
|
||||||
:tech_contacts_max_count,
|
:tech_contacts_max_count,
|
||||||
|
:orphans_contacts_in_months,
|
||||||
:ds_digest_type,
|
:ds_digest_type,
|
||||||
:dnskeys_min_count,
|
:dnskeys_min_count,
|
||||||
:dnskeys_max_count,
|
:dnskeys_max_count,
|
||||||
|
|
|
@ -42,13 +42,8 @@ class Registrar::ContactsController < Registrar::DeppController # EPP controller
|
||||||
@contacts = Contact.find_by(name: params[:q][:name_matches])
|
@contacts = Contact.find_by(name: params[:q][:name_matches])
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:statuses_contains]
|
|
||||||
contacts = current_user.registrar.contacts.includes(:registrar).where(
|
|
||||||
"contacts.statuses @> ?::varchar[]", "{#{params[:statuses_contains].join(',')}}"
|
|
||||||
)
|
|
||||||
else
|
|
||||||
contacts = current_user.registrar.contacts.includes(:registrar)
|
contacts = current_user.registrar.contacts.includes(:registrar)
|
||||||
end
|
contacts = contacts.filter_by_states(params[:statuses_contains]) if params[:statuses_contains]
|
||||||
|
|
||||||
normalize_search_parameters do
|
normalize_search_parameters do
|
||||||
@q = contacts.search(params[:q])
|
@q = contacts.search(params[:q])
|
||||||
|
|
|
@ -36,12 +36,10 @@ class Contact < ActiveRecord::Base
|
||||||
|
|
||||||
validate :val_ident_type
|
validate :val_ident_type
|
||||||
validate :val_ident_valid_format?
|
validate :val_ident_valid_format?
|
||||||
validate :uniq_statuses?
|
|
||||||
validate :validate_html
|
validate :validate_html
|
||||||
validate :val_country_code
|
validate :val_country_code
|
||||||
|
|
||||||
after_initialize do
|
after_initialize do
|
||||||
self.statuses = [] if statuses.nil?
|
|
||||||
self.status_notes = {} if status_notes.nil?
|
self.status_notes = {} if status_notes.nil?
|
||||||
self.ident_updated_at = Time.zone.now if new_record? && ident_updated_at.blank?
|
self.ident_updated_at = Time.zone.now if new_record? && ident_updated_at.blank?
|
||||||
end
|
end
|
||||||
|
@ -64,16 +62,6 @@ class Contact < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
before_save :manage_statuses
|
|
||||||
def manage_statuses
|
|
||||||
if domain_transfer # very ugly but need better workflow
|
|
||||||
self.statuses = statuses | [OK, LINKED]
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
manage_linked
|
|
||||||
manage_ok
|
|
||||||
end
|
|
||||||
|
|
||||||
after_save :update_related_whois_records
|
after_save :update_related_whois_records
|
||||||
|
|
||||||
|
@ -176,7 +164,7 @@ class Contact < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_orphans
|
def find_orphans
|
||||||
Contact.where('
|
where('
|
||||||
NOT EXISTS(
|
NOT EXISTS(
|
||||||
select 1 from domains d where d.registrant_id = contacts.id
|
select 1 from domains d where d.registrant_id = contacts.id
|
||||||
) AND NOT EXISTS(
|
) AND NOT EXISTS(
|
||||||
|
@ -185,20 +173,49 @@ class Contact < ActiveRecord::Base
|
||||||
')
|
')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_linked
|
||||||
|
where('
|
||||||
|
EXISTS(
|
||||||
|
select 1 from domains d where d.registrant_id = contacts.id
|
||||||
|
) OR EXISTS(
|
||||||
|
select 1 from domain_contacts dc where dc.contact_id = contacts.id
|
||||||
|
)
|
||||||
|
')
|
||||||
|
end
|
||||||
|
|
||||||
|
def filter_by_states in_states
|
||||||
|
states = Array(in_states).dup
|
||||||
|
scope = all
|
||||||
|
|
||||||
|
# all contacts has state ok, so no need to filter by it
|
||||||
|
scope = scope.where("NOT contacts.statuses && ?::varchar[]", "{#{(STATUSES - [OK, LINKED]).join(',')}}") if states.delete(OK)
|
||||||
|
scope = scope.find_linked if states.delete(LINKED)
|
||||||
|
scope = scope.where("contacts.statuses @> ?::varchar[]", "{#{states.join(',')}}") if states.any?
|
||||||
|
scope
|
||||||
|
end
|
||||||
|
|
||||||
|
# To leave only new ones we need to check
|
||||||
|
# if contact was at any time used in domain.
|
||||||
|
# This can be checked by domain history.
|
||||||
|
# This can be checked by saved relations in children attribute
|
||||||
def destroy_orphans
|
def destroy_orphans
|
||||||
STDOUT << "#{Time.zone.now.utc} - Destroying orphaned contacts\n" unless Rails.env.test?
|
STDOUT << "#{Time.zone.now.utc} - Destroying orphaned contacts\n" unless Rails.env.test?
|
||||||
|
|
||||||
orphans = find_orphans
|
counter = Counter.new
|
||||||
|
find_orphans.find_each do |contact|
|
||||||
unless Rails.env.test?
|
ver_scope = []
|
||||||
orphans.each do |m|
|
%w(admin_contacts tech_contacts registrant).each do |type|
|
||||||
STDOUT << "#{Time.zone.now.utc} Contact.destroy_orphans: ##{m.id} (#{m.name})\n"
|
ver_scope << "(children->'#{type}')::jsonb <@ json_build_array(#{contact.id})::jsonb"
|
||||||
end
|
end
|
||||||
|
next if DomainVersion.where("created_at > ?", Time.now - Setting.orphans_contacts_in_months.to_i.months).where(ver_scope.join(" OR ")).any?
|
||||||
|
next if contact.domains_present?
|
||||||
|
|
||||||
|
contact.destroy
|
||||||
|
counter.next
|
||||||
|
STDOUT << "#{Time.zone.now.utc} Contact.destroy_orphans: ##{contact.id} (#{contact.name})\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
count = orphans.destroy_all.count
|
STDOUT << "#{Time.zone.now.utc} - Successfully destroyed #{counter} orphaned contacts\n" unless Rails.env.test?
|
||||||
|
|
||||||
STDOUT << "#{Time.zone.now.utc} - Successfully destroyed #{count} orphaned contacts\n" unless Rails.env.test?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def privs
|
def privs
|
||||||
|
@ -239,6 +256,23 @@ class Contact < ActiveRecord::Base
|
||||||
"EIS-#{id}"
|
"EIS-#{id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# kind of decorator in order to always return statuses
|
||||||
|
# if we use separate decorator, then we should add it
|
||||||
|
# to too many places
|
||||||
|
def statuses
|
||||||
|
calculated = Array(read_attribute(:statuses))
|
||||||
|
calculated.delete(Contact::OK)
|
||||||
|
calculated.delete(Contact::LINKED)
|
||||||
|
calculated << Contact::OK if calculated.empty?# && valid?
|
||||||
|
calculated << Contact::LINKED if domains_present?
|
||||||
|
|
||||||
|
calculated.uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
def statuses= arr
|
||||||
|
write_attribute(:statuses, Array(arr).uniq)
|
||||||
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
name || '[no name]'
|
name || '[no name]'
|
||||||
end
|
end
|
||||||
|
@ -278,11 +312,6 @@ class Contact < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def uniq_statuses?
|
|
||||||
return true unless statuses.detect { |s| statuses.count(s) > 1 }
|
|
||||||
errors.add(:statuses, :not_uniq)
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def org?
|
def org?
|
||||||
ident_type == ORG
|
ident_type == ORG
|
||||||
|
@ -412,13 +441,6 @@ class Contact < ActiveRecord::Base
|
||||||
domain_contacts.present? || registrant_domains.present?
|
domain_contacts.present? || registrant_domains.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def manage_linked
|
|
||||||
if domains_present?
|
|
||||||
set_linked
|
|
||||||
else
|
|
||||||
unset_linked
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def search_name
|
def search_name
|
||||||
"#{code} #{name}"
|
"#{code} #{name}"
|
||||||
|
@ -497,43 +519,6 @@ class Contact < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_linked
|
|
||||||
statuses << LINKED if statuses.detect { |s| s == LINKED }.blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
def unset_linked
|
|
||||||
statuses.delete_if { |s| s == LINKED }
|
|
||||||
end
|
|
||||||
|
|
||||||
# rubocop:disable Metrics/CyclomaticComplexity
|
|
||||||
def manage_ok
|
|
||||||
return unset_ok unless valid?
|
|
||||||
|
|
||||||
case statuses.size
|
|
||||||
when 0
|
|
||||||
set_ok
|
|
||||||
when 1
|
|
||||||
set_ok if statuses == [LINKED]
|
|
||||||
when 2
|
|
||||||
return if statuses.sort == [LINKED, OK]
|
|
||||||
unset_ok
|
|
||||||
else
|
|
||||||
unset_ok
|
|
||||||
end
|
|
||||||
end
|
|
||||||
# rubocop:enable Metrics/CyclomaticComplexity
|
|
||||||
|
|
||||||
def unset_ok
|
|
||||||
statuses.delete_if { |s| s == OK }
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_ok
|
|
||||||
statuses << OK if statuses.detect { |s| s == OK }.blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
def linked?
|
|
||||||
statuses.include?(LINKED)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_prohibited?
|
def update_prohibited?
|
||||||
(statuses & [
|
(statuses & [
|
||||||
|
|
|
@ -39,29 +39,12 @@ class Epp::Domain < Domain
|
||||||
|
|
||||||
before_save :link_contacts
|
before_save :link_contacts
|
||||||
def link_contacts
|
def link_contacts
|
||||||
# Based on bullet report
|
#TODO: cleanup cache if we think to cache dynamic statuses
|
||||||
if new_record?
|
|
||||||
# new record does not have correct instance contacts entries thanks to epp
|
|
||||||
unlinked_contacts = [registrant]
|
|
||||||
unlinked_contacts << admin_domain_contacts.map(&:contact)
|
|
||||||
unlinked_contacts << tech_domain_contacts.map(&:contact)
|
|
||||||
unlinked_contacts.flatten!
|
|
||||||
else
|
|
||||||
unlinked_contacts = contacts.select { |c| !c.linked? } # speed up a bit
|
|
||||||
end
|
|
||||||
|
|
||||||
unlinked_contacts.each do |uc|
|
|
||||||
uc.domains_present = true # no need to fetch domains again
|
|
||||||
uc.save(validate: false)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
after_destroy :unlink_contacts
|
after_destroy :unlink_contacts
|
||||||
def unlink_contacts
|
def unlink_contacts
|
||||||
contacts.each do |c|
|
#TODO: cleanup cache if we think to cache dynamic statuses
|
||||||
c.domains_present = false
|
|
||||||
c.save(validate: false)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
= render 'setting_row', var: :admin_contacts_max_count
|
= render 'setting_row', var: :admin_contacts_max_count
|
||||||
= render 'setting_row', var: :tech_contacts_min_count
|
= render 'setting_row', var: :tech_contacts_min_count
|
||||||
= render 'setting_row', var: :tech_contacts_max_count
|
= render 'setting_row', var: :tech_contacts_max_count
|
||||||
|
= render 'setting_row', var: :orphans_contacts_in_months
|
||||||
= render 'setting_row', var: :ds_data_allowed
|
= render 'setting_row', var: :ds_data_allowed
|
||||||
= render 'setting_row', var: :key_data_allowed
|
= render 'setting_row', var: :key_data_allowed
|
||||||
= render 'setting_row', var: :dnskeys_min_count
|
= render 'setting_row', var: :dnskeys_min_count
|
||||||
|
|
|
@ -10,6 +10,7 @@ if con.present? && con.table_exists?('settings')
|
||||||
Setting.save_default(:admin_contacts_max_count, 10)
|
Setting.save_default(:admin_contacts_max_count, 10)
|
||||||
Setting.save_default(:tech_contacts_min_count, 1)
|
Setting.save_default(:tech_contacts_min_count, 1)
|
||||||
Setting.save_default(:tech_contacts_max_count, 10)
|
Setting.save_default(:tech_contacts_max_count, 10)
|
||||||
|
Setting.save_default(:orphans_contacts_in_months, 6)
|
||||||
Setting.save_default(:expire_pending_confirmation, 48)
|
Setting.save_default(:expire_pending_confirmation, 48)
|
||||||
|
|
||||||
Setting.save_default(:ds_digest_type, 2)
|
Setting.save_default(:ds_digest_type, 2)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
class ChangeContactStatusesDefault < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
change_column_default :contacts, :statuses, []
|
||||||
|
Contact.where(statuses: nil). update_all(statuses: [])
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue