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