diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb
index 0abd219f5..840a80e6e 100644
--- a/app/controllers/epp/domains_controller.rb
+++ b/app/controllers/epp/domains_controller.rb
@@ -34,7 +34,11 @@ class Epp::DomainsController < EppController
authorize! :update, @domain, @password
if @domain.update(params[:parsed_frame], current_user)
- render_epp_response '/epp/domains/success'
+ if @domain.pending_update?
+ render_epp_response '/epp/domains/success_pending'
+ else
+ render_epp_response '/epp/domains/success'
+ end
else
handle_errors(@domain)
end
diff --git a/app/mailers/domain_mailer.rb b/app/mailers/domain_mailer.rb
new file mode 100644
index 000000000..9335cc99b
--- /dev/null
+++ b/app/mailers/domain_mailer.rb
@@ -0,0 +1,13 @@
+class DomainMailer < ApplicationMailer
+ def registrant_updated(domain)
+ return if Rails.env.production? ? false : !TEST_EMAILS.include?(domain.registrant_email)
+ # turn on delivery on specific request only, thus rake tasks does not deliver anything
+ return if domain.deliver_emails != true
+
+ @old_registrant = Registrant.find(domain.registrant_id_was)
+
+ @domain = domain
+ mail(to: @old_registrant.email,
+ subject: "#{I18n.t(:domain_registrant_update_subject, name: @domain.name)} [#{@domain.name}]")
+ end
+end
diff --git a/app/mailers/invoice_mailer.rb b/app/mailers/invoice_mailer.rb
index ea30783be..eb6168d30 100644
--- a/app/mailers/invoice_mailer.rb
+++ b/app/mailers/invoice_mailer.rb
@@ -1,6 +1,6 @@
class InvoiceMailer < ApplicationMailer
def invoice_email(invoice, pdf)
- return if Rails.env.production? ? false : TEST_EMAILS.include?(invoice.billing_email)
+ return if Rails.env.production? ? false : !TEST_EMAILS.include?(invoice.billing_email)
@invoice = invoice
attachments[invoice.pdf_name] = pdf
diff --git a/app/models/domain.rb b/app/models/domain.rb
index 87d5f3d73..7c2a29929 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -40,14 +40,28 @@ 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: :registrant, prefix: true
- delegate :email, to: :registrant, prefix: true
- delegate :ident, to: :registrant, prefix: true
- delegate :phone, to: :registrant, prefix: true
- delegate :name, to: :registrar, prefix: true
+ delegate :name, to: :registrant, prefix: true
+ delegate :code, to: :registrant, prefix: true
+ delegate :ident, to: :registrant, prefix: true
+ delegate :email, to: :registrant, prefix: true
+ delegate :phone, to: :registrant, prefix: true
+ delegate :street, to: :registrant, prefix: true
+ delegate :city, to: :registrant, prefix: true
+ delegate :zip, to: :registrant, prefix: true
+ delegate :state, to: :registrant, prefix: true
+ delegate :country, to: :registrant, prefix: true
+
+ delegate :name, to: :registrar, prefix: true
+ delegate :street, to: :registrar, prefix: true
before_create :generate_auth_info
before_create :set_validity_dates
+ before_update :manage_statuses
+ def manage_statuses
+ return unless registrant_id_changed?
+ domain_statuses.build(value: DomainStatus::PENDING_UPDATE) if registrant_verification_asked_at.present?
+ end
+
before_save :touch_always_version
def touch_always_version
self.updated_at = Time.zone.now
@@ -103,7 +117,7 @@ class Domain < ActiveRecord::Base
validate :validate_nameserver_ips
- attr_accessor :registrant_typeahead, :update_me
+ attr_accessor :registrant_typeahead, :update_me, :deliver_emails
def subordinate_nameservers
nameservers.select { |x| x.hostname.end_with?(name) }
@@ -154,6 +168,13 @@ class Domain < ActiveRecord::Base
)).empty?
end
+ def pending_update?
+ (domain_statuses.pluck(:value) & %W(
+ #{DomainStatus::PENDING_UPDATE}
+ )).present?
+ end
+ alias_method :update_pending?, :pending_update?
+
### VALIDATIONS ###
def validate_nameserver_ips
@@ -230,8 +251,6 @@ class Domain < ActiveRecord::Base
# otherwise domain_statuses are in old state for domain object
domain_statuses.reload
-
- # contacts.includes(:address).each(&:manage_statuses)
end
def children_log
diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb
index 8698857b3..f9ee8c988 100644
--- a/app/models/epp/domain.rb
+++ b/app/models/epp/domain.rb
@@ -2,6 +2,13 @@
class Epp::Domain < Domain
include EppErrors
+ before_update :manage_permissions
+ def manage_permissions
+ return unless update_pending?
+ add_epp_error('2304', nil, nil, I18n.t(:object_status_prohibits_operation))
+ false
+ end
+
class << self
def new_from_epp(frame, current_user)
domain = Epp::Domain.new
@@ -88,6 +95,8 @@ class Epp::Domain < Domain
regt = Registrant.find_by(code: code)
if regt
at[:registrant_id] = regt.id
+ delivery_date = frame.css('registrant').attr('verified').to_s.downcase == 'yes' ? nil : Time.zone.now
+ at[:registrant_verification_asked_at] = delivery_date
else
add_epp_error('2303', 'registrant', code, [:registrant, :not_found])
end
@@ -115,7 +124,6 @@ class Epp::Domain < Domain
at[:dnskeys_attributes] = dnskeys_attrs(dnskey_frame, action)
at[:legal_documents_attributes] = legal_document_from(frame)
-
at
end
# rubocop: enable Metrics/PerceivedComplexity
@@ -386,6 +394,7 @@ class Epp::Domain < Domain
at[:tech_domain_contacts_attributes] += at_add[:tech_domain_contacts_attributes]
at[:dnskeys_attributes] += at_add[:dnskeys_attributes]
at[:domain_statuses_attributes] += at_add[:domain_statuses_attributes]
+ self.deliver_emails = true # turn on email delivery for epp
errors.empty? && super(at)
end
diff --git a/app/views/contact_mailer/email_updated.html.erb b/app/views/contact_mailer/email_updated.html.erb
index b5fe51ec7..c461659b1 100644
--- a/app/views/contact_mailer/email_updated.html.erb
+++ b/app/views/contact_mailer/email_updated.html.erb
@@ -22,7 +22,7 @@ Tänav: <%= @contact.street %>
Linn: <%= @contact.city %>
Riik: <%= @contact.country %>
-Lugupidamisega
+Lugupidamisega
Eesti Interneti SA
@@ -49,5 +49,5 @@ Street: <%= @contact.street %>
City: <%= @contact.city %>
Country: <%= @contact.country %>
-Best Regards,
+Best Regards,
Eesti Interneti SA
diff --git a/app/views/domain_mailer/registrant_updated.html.erb b/app/views/domain_mailer/registrant_updated.html.erb
new file mode 100644
index 000000000..b992d0fe5
--- /dev/null
+++ b/app/views/domain_mailer/registrant_updated.html.erb
@@ -0,0 +1,47 @@
+Tere,
+
+Registrisse laekus taotlus domeeni <%= @domain.name %> registreerija vahetuseks. Palun veenduge, et muudatus on korrektne ning probleemide korral pöörduge oma registripidaja poole. Teie registripidaja on <%= @domain.registrar_name %>
+
+Uued registreerija andmed:
+Nimi: <%= @domain.registrant_name %>
+<% if @domain.registrant.priv? %>
+Isikukood: <%= @domain.registrant_ident %>
+<% else %>
+Äriregistrikood: <%= @domain.registrant_ident %>
+<% end %>
+Epost: <%= @domain.registrant_email %>
+Tel: <%= @domain.registrant_phone %>
+Tänav: <%= @domain.registrant_street %>
+Linn: <%= @domain.registrant_city %>
+Riik: <%= @domain.registrant_country %>
+
+Muudatuse kinnitamiseks külastage palun allolevat võrgulehekülge, kontrollige uuesti üle muudatuse andmed ning vajutage nuppu kinnitan:
+https://testrar.internet.ee/app/owpieruaofaksj298317498324rquhetoiqhepoijfqperyfq9384yuqpohewg
+
+Lugupidamisega
+Eesti Interneti SA
+
+
+
+Hi,
+
+Application for changing registrant of your domain <%= @domain.name %> has been filed. Please make sure that the update and information are correct. Incase of problems please turn to your registrar. Your registrar is <%= @domain.registrar_name %>
+
+New registrant:
+Name: <%= @domain.registrant_name %>
+<% if @domain.registrant.priv? %>
+Personal code: <%= @domain.registrant_ident %>
+<% else %>
+Business Registry code: <%= @domain.registrant_ident %>
+<% end %>
+E-mail: <%= @domain.registrant_email %>
+Tel: <%= @domain.registrant_phone %>
+Street: <%= @domain.registrant_street %>
+City: <%= @domain.registrant_city %>
+Country: <%= @domain.registrant_country %>
+
+To confirm the update please visit this website, once again review the data and press approve:
+https://testrar.internet.ee/app/owpieruaofaksj298317498324rquhetoiqhepoijfqperyfq9384yuqpohewg
+
+Best Regards,
+Estonian Internet Foundation
diff --git a/app/views/domain_mailer/registrant_updated.text.erb b/app/views/domain_mailer/registrant_updated.text.erb
new file mode 100644
index 000000000..c4d6d6507
--- /dev/null
+++ b/app/views/domain_mailer/registrant_updated.text.erb
@@ -0,0 +1,47 @@
+Tere,
+
+Registrisse laekus taotlus domeeni <%= @domain.name %> registreerija vahetuseks. Palun veenduge, et muudatus on korrektne ning probleemide korral pöörduge oma registripidaja poole. Teie registripidaja on <%= @domain.registrar_name %>
+
+Uued registreerija andmed:
+Nimi: <%= @domain.registrant_name %>
+<% if @domain.registrant.priv? %>
+Isikukood: <%= @domain.registrant_ident %>
+<% else %>
+Äriregistrikood: <%= @domain.registrant_ident %>
+<% end %>
+Epost: <%= @domain.registrant_email %>
+Tel: <%= @domain.registrant_phone %>
+Tänav: <%= @domain.registrant_street %>
+Linn: <%= @domain.registrant_city %>
+Riik: <%= @domain.registrant_country %>
+
+Muudatuse kinnitamiseks külastage palun allolevat võrgulehekülge, kontrollige uuesti üle muudatuse andmed ning vajutage nuppu kinnitan:
+https://testrar.internet.ee/app/owpieruaofaksj298317498324rquhetoiqhepoijfqperyfq9384yuqpohewg
+
+Lugupidamisega
+Eesti Interneti SA
+
+---------------------------------------------------------------------------------
+
+Hi,
+
+Application for changing registrant of your domain <%= @domain.name %> has been filed. Please make sure that the update and information are correct. Incase of problems please turn to your registrar. Your registrar is <%= @domain.registrar_name %>
+
+New registrant:
+Name: <%= @domain.registrant_name %>
+<% if @domain.registrant.priv? %>
+Personal code: <%= @domain.registrant_ident %>
+<% else %>
+Business Registry code: <%= @domain.registrant_ident %>
+<% end %>
+E-mail: <%= @domain.registrant_email %>
+Tel: <%= @domain.registrant_phone %>
+Street: <%= @domain.registrant_street %>
+City: <%= @domain.registrant_city %>
+Country: <%= @domain.registrant_country %>
+
+To confirm the update please visit this website, once again review the data and press approve:
+https://testrar.internet.ee/app/owpieruaofaksj298317498324rquhetoiqhepoijfqperyfq9384yuqpohewg
+
+Best Regards,
+Estonian Internet Foundation
diff --git a/app/views/epp/domains/success_pending.xml.builder b/app/views/epp/domains/success_pending.xml.builder
new file mode 100644
index 000000000..3d1783009
--- /dev/null
+++ b/app/views/epp/domains/success_pending.xml.builder
@@ -0,0 +1,9 @@
+xml.epp_head do
+ xml.response do
+ xml.result('code' => '1001') do
+ xml.msg 'Command completed successfully; action pending'
+ end
+ end
+
+ xml << render('/epp/shared/trID')
+end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index b7fa7a05d..789e71fa3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -762,3 +762,5 @@ en:
forbidden_code: 'is forbidden to use'
unimplemented_object_service: 'Unimplemented object service'
contact_email_update_subject: 'Teie domeenide kontakt epostiaadress on muutunud / Contact e-mail addresses of your domains have changed'
+ object_status_prohibits_operation: 'Object status prohibits operation'
+ domain_registrant_update_subject: "Kinnitustaotlus domeeni %{name} registreerija vahetuseks / Application for approval for registrant chache of %{name}"
diff --git a/db/migrate/20150512160938_add_registrant_changed_at_to_domain.rb b/db/migrate/20150512160938_add_registrant_changed_at_to_domain.rb
new file mode 100644
index 000000000..b92b68298
--- /dev/null
+++ b/db/migrate/20150512160938_add_registrant_changed_at_to_domain.rb
@@ -0,0 +1,6 @@
+class AddRegistrantChangedAtToDomain < ActiveRecord::Migration
+ def change
+ add_column :domains, :registrant_verification_asked_at, :datetime
+ add_index :domains, :registrant_verification_asked_at
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index fc41c9a95..b2e3316fe 100644
--- a/db/schema.rb
+++ b/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: 20150511120755) do
+ActiveRecord::Schema.define(version: 20150512160938) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -292,7 +292,7 @@ ActiveRecord::Schema.define(version: 20150511120755) do
t.string "name_dirty"
t.string "name_puny"
t.integer "period"
- t.string "period_unit", limit: 1
+ t.string "period_unit", limit: 1
t.string "creator_str"
t.string "updator_str"
t.integer "legacy_id"
@@ -300,11 +300,13 @@ ActiveRecord::Schema.define(version: 20150511120755) do
t.integer "legacy_registrant_id"
t.datetime "outzone_at"
t.datetime "delete_at"
+ t.datetime "registrant_verification_asked_at"
end
add_index "domains", ["delete_at"], name: "index_domains_on_delete_at", using: :btree
add_index "domains", ["outzone_at"], name: "index_domains_on_outzone_at", using: :btree
add_index "domains", ["registrant_id"], name: "index_domains_on_registrant_id", using: :btree
+ add_index "domains", ["registrant_verification_asked_at"], name: "index_domains_on_registrant_verification_asked_at", using: :btree
add_index "domains", ["registrar_id"], name: "index_domains_on_registrar_id", using: :btree
create_table "epp_sessions", force: :cascade do |t|
diff --git a/doc/epp/domain.md b/doc/epp/domain.md
index 3fa49754a..9d13f8df3 100644
--- a/doc/epp/domain.md
+++ b/doc/epp/domain.md
@@ -19,6 +19,8 @@ Domain name mapping protocol short version:
Must add up to 1 / 2 / 3 years.
Attribute: unit="y/m/d"
1 Contact reference to the registrant
+ Attribute:
+ "verified" # optional, allowed values 'yes', 'no'
0-n Contact reference. Admin contact is required if registrant is
a juridical person. Attribute: type="admin / tech"
1
diff --git a/spec/epp/domain_spec.rb b/spec/epp/domain_spec.rb
index f8b0aed99..c1eed789d 100644
--- a/spec/epp/domain_spec.rb
+++ b/spec/epp/domain_spec.rb
@@ -1353,13 +1353,13 @@ describe 'EPP Domain', epp: true do
end
### UPDATE ###
- it 'updates a domain' do
+ it 'should update right away without update pending status' do
existing_pw = domain.auth_info
xml_params = {
name: { value: domain.name },
chg: [
- registrant: { value: 'FIXED:CITIZEN_1234' }
+ registrant: { value: 'FIXED:CITIZEN_1234', attrs: { verified: 'yes' } }
]
}
@@ -1379,6 +1379,67 @@ describe 'EPP Domain', epp: true do
d.registrant_code.should == 'FIXED:CITIZEN_1234'
d.auth_info.should == existing_pw
+ d.update_pending?.should == false
+ end
+
+ it 'updates a domain' do
+ existing_pw = domain.auth_info
+
+ xml_params = {
+ name: { value: domain.name },
+ chg: [
+ registrant: { value: 'FIXED:CITIZEN_1234' }
+ ]
+ }
+
+ response = epp_plain_request(domain_update_xml(xml_params, {}, {
+ _anonymus: [
+ legalDocument: {
+ value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
+ attrs: { type: 'pdf' }
+ }
+ ]
+ }), :xml)
+
+ response[:results][0][:msg].should == 'Command completed successfully; action pending'
+ response[:results][0][:result_code].should == '1001'
+
+ d = Domain.last
+
+ d.registrant_code.should == 'FIXED:CITIZEN_1234'
+ d.auth_info.should == existing_pw
+ d.update_pending?.should == true
+ end
+
+ it 'should not allow any update when status update_pending' do
+ domain.domain_statuses.create(value: DomainStatus::PENDING_UPDATE)
+
+ existing_pw = domain.auth_info
+
+ xml_params = {
+ name: { value: domain.name },
+ chg: [
+ registrant: { value: 'FIXED:CITIZEN_1234' }
+ ]
+ }
+
+ response = epp_plain_request(domain_update_xml(xml_params, {}, {
+ _anonymus: [
+ legalDocument: {
+ value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==',
+ attrs: { type: 'pdf' }
+ }
+ ]
+ }), :xml)
+
+ response[:results][0][:msg].should == 'Object status prohibits operation'
+ response[:results][0][:result_code].should == '2304'
+
+ d = Domain.last
+
+ d.registrant_code.should_not == 'FIXED:CITIZEN_1234'
+ d.auth_info.should == existing_pw
+ d.update_pending?.should == true
end
it 'updates domain and adds objects' do
diff --git a/spec/mailers/domain_mailer_spec.rb b/spec/mailers/domain_mailer_spec.rb
new file mode 100644
index 000000000..ac83b0732
--- /dev/null
+++ b/spec/mailers/domain_mailer_spec.rb
@@ -0,0 +1,54 @@
+require 'rails_helper'
+
+describe DomainMailer do
+ describe 'registrant changed notification when delivery turned off' do
+ before :all do
+ @registrant = Fabricate(:registrant, email: 'test@example.com')
+ @domain = Fabricate(:domain, registrant: @registrant)
+ @mail = DomainMailer.registrant_updated(@domain)
+ end
+
+ it 'should not render email subject' do
+ @mail.subject.should == nil
+ end
+
+ it 'should not have sender email' do
+ @mail.from.should == nil
+ end
+
+ it 'should not have reveiver email' do
+ @mail.to.should == nil
+ end
+
+ it 'should not render body' do
+ @mail.body.should == ''
+ end
+ end
+
+ describe 'email changed notification' do
+ before :all do
+ @registrant = Fabricate(:registrant, email: 'test@example.com')
+ @new_registrant = Fabricate(:registrant, email: 'test@example.org')
+ @domain = Fabricate(:domain, registrant: @registrant)
+ @domain.deliver_emails = true
+ @domain.registrant = @new_registrant
+ @mail = DomainMailer.registrant_updated(@domain)
+ end
+
+ it 'should render email subject' do
+ @mail.subject.should =~ /Kinnitustaotlus domeeni/
+ end
+
+ it 'should have sender email' do
+ @mail.from.should == ["noreply@internet.ee"]
+ end
+
+ it 'should send confirm email to old registrant email' do
+ @mail.to.should == ["test@example.com"]
+ end
+
+ it 'should render body' do
+ @mail.body.encoded.should =~ /Registrisse laekus taotlus domeeni/
+ end
+ end
+end