diff --git a/CHANGELOG.md b/CHANGELOG.md index da390d5d0..99a486683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +19.05.2015 + +* Added possibility to define NewRelic app_name at application.yml file with 'new_relic_app_name' attribute. + 18.05.2015 * Added Registrant database example file: config/database-example-registrant.yml diff --git a/app/assets/stylesheets/registrant/registrant.sass b/app/assets/stylesheets/registrant/registrant.sass index 9f046237b..6937c4b49 100644 --- a/app/assets/stylesheets/registrant/registrant.sass +++ b/app/assets/stylesheets/registrant/registrant.sass @@ -32,3 +32,15 @@ h1, h2, h3, h4 .semifooter padding: 42px 0 80px 0 + +.confirmation + padding: 40px 0 20px 0 + .column-keys + text-align: right + width: 49% + float: left + .column-values + float: right + font-weight: bold + text-align: left + width: 49% diff --git a/app/controllers/registrant/domain_delete_confirms_controller.rb b/app/controllers/registrant/domain_delete_confirms_controller.rb new file mode 100644 index 000000000..6cd0e1392 --- /dev/null +++ b/app/controllers/registrant/domain_delete_confirms_controller.rb @@ -0,0 +1,12 @@ +class Registrant::DomainDeleteConfirmsController < RegistrantController + skip_before_action :authenticate_user!, only: [:show, :create] + skip_authorization_check only: [:show, :create] + + def show + @domain = Domain.find(params[:id]) + @domain = nil unless @domain.registrant_delete_confirmable?(params[:token]) + end + + def create + end +end diff --git a/app/controllers/registrant/domain_update_confirms_controller.rb b/app/controllers/registrant/domain_update_confirms_controller.rb index fac3d0181..7cdcd3f4b 100644 --- a/app/controllers/registrant/domain_update_confirms_controller.rb +++ b/app/controllers/registrant/domain_update_confirms_controller.rb @@ -1,12 +1,40 @@ class Registrant::DomainUpdateConfirmsController < RegistrantController - skip_before_action :authenticate_user!, only: [:show, :create] - skip_authorization_check only: [:show, :create] + skip_before_action :authenticate_user!, only: [:show, :update] + skip_authorization_check only: [:show, :update] def show + return if params[:confirmed] || params[:rejected] @domain = Domain.find(params[:id]) @domain = nil unless @domain.registrant_update_confirmable?(params[:token]) end - def create + def update + @domain = Domain.find(params[:id]) + unless @domain.registrant_update_confirmable?(params[:token]) + flash[:alert] = t(:registrant_domain_verification_failed) + return render 'show' + end + + @registrant_verification = RegistrantVerification.new(domain_id: @domain.id, + domain_name: @domain.name, + verification_token: params[:token]) + + if params[:rejected] + if @registrant_verification.domain_registrant_change_reject! + flash[:notice] = t(:registrant_domain_verification_rejected) + redirect_to registrant_domain_update_confirm_path(@domain.id, rejected: true) + else + flash[:alert] = t(:registrant_domain_verification_rejected_failed) + return render 'show' + end + elsif params[:confirmed] + if @registrant_verification.domain_registrant_change_confirm! + flash[:notice] = t(:registrant_domain_verification_confirmed) + redirect_to registrant_domain_update_confirm_path(@domain.id, confirmed: true) + else + flash[:alert] = t(:registrant_domain_verification_confirmed_failed) + return render 'show' + end + end end end diff --git a/app/controllers/registrar/nameservers_controller.rb b/app/controllers/registrar/nameservers_controller.rb index 68c1dbfee..ea4d9568b 100644 --- a/app/controllers/registrar/nameservers_controller.rb +++ b/app/controllers/registrar/nameservers_controller.rb @@ -1,46 +1,48 @@ class Registrar::NameserversController < RegistrarController - load_and_authorize_resource + # turned off requested by client - def index - if can_replace_hostnames? - prc = Nameserver.replace_hostname_ends( - current_user.registrar.domains.includes( - :registrant, :nameservers, :admin_domain_contacts, :tech_domain_contacts, :domain_statuses, - :versions, :admin_contacts, :tech_contacts, :whois_record, :dnskeys - ), - params[:q][:hostname_end], - params[:hostname_end_replacement] - ) + # load_and_authorize_resource - if prc == 'replaced_none' - flash.now[:alert] = t(:no_hostnames_replaced) - elsif prc == 'replaced_all' - params[:q][:hostname_end] = params[:hostname_end_replacement] - params[:hostname_end_replacement] = nil - flash.now[:notice] = t(:all_hostnames_replaced) - else - flash.now[:warning] = t(:hostnames_partially_replaced) - end - end + # def index + # if can_replace_hostnames? + # prc = Nameserver.replace_hostname_ends( + # current_user.registrar.domains.includes( + # :registrant, :nameservers, :admin_domain_contacts, :tech_domain_contacts, :domain_statuses, + # :versions, :admin_contacts, :tech_contacts, :whois_record, :dnskeys + # ), + # params[:q][:hostname_end], + # params[:hostname_end_replacement] + # ) - nameservers = current_user.registrar.nameservers.includes(:domain) - @q = nameservers.search(params[:q]) - @q.sorts = 'id desc' if @q.sorts.empty? - @nameservers = @q.result.page(params[:page]) - end + # if prc == 'replaced_none' + # flash.now[:alert] = t(:no_hostnames_replaced) + # elsif prc == 'replaced_all' + # params[:q][:hostname_end] = params[:hostname_end_replacement] + # params[:hostname_end_replacement] = nil + # flash.now[:notice] = t(:all_hostnames_replaced) + # else + # flash.now[:warning] = t(:hostnames_partially_replaced) + # end + # end - def replace_all - @domain_params = { nameservers_attributes: { 0 => {} } } - end + # nameservers = current_user.registrar.nameservers.includes(:domain) + # @q = nameservers.search(params[:q]) + # @q.sorts = 'id desc' if @q.sorts.empty? + # @nameservers = @q.result.page(params[:page]) + # end - private + # def replace_all + # @domain_params = { nameservers_attributes: { 0 => {} } } + # end - def can_replace_hostnames? - if params[:replace] && params[:q] - flash.now[:alert] = t('hostname_end_replacement_is_required') unless params[:hostname_end_replacement].present? - flash.now[:alert] = t('hostname_end_is_required') unless params[:q][:hostname_end].present? - return true if flash[:alert].blank? - end - false - end + # private + + # def can_replace_hostnames? + # if params[:replace] && params[:q] + # flash.now[:alert] = t('hostname_end_replacement_is_required') unless params[:hostname_end_replacement].present? + # flash.now[:alert] = t('hostname_end_is_required') unless params[:q][:hostname_end].present? + # return true if flash[:alert].blank? + # end + # false + # end end diff --git a/app/models/domain.rb b/app/models/domain.rb index bbff5c1de..621f7f6e0 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -181,11 +181,16 @@ class Domain < ActiveRecord::Base return true unless registrant_verification_asked? pending_json_cache = all_changes + token = registrant_verification_token + asked_at = registrant_verification_asked_at + DomainMailer.registrant_pending_updated(self).deliver_now reload # revert back to original self.pending_json = pending_json_cache + self.registrant_verification_token = token + self.registrant_verification_asked_at = asked_at domain_statuses.create(value: DomainStatus::PENDING_UPDATE) end @@ -198,6 +203,15 @@ class Domain < ActiveRecord::Base true end + def registrant_delete_confirmable?(token) + return false unless pending_delete? + return false if registrant_verification_token.blank? + return false if registrant_verification_asked_at.blank? + return false if token.blank? + return false if registrant_verification_token != token + true + end + def registrant_verification_asked? registrant_verification_asked_at.present? && registrant_verification_token.present? end @@ -275,6 +289,15 @@ class Domain < ActiveRecord::Base name end + def pending_registrant_name + return '' if pending_json.blank? + return '' if pending_json['domain'].blank? + return '' if pending_json['domain']['registrant_id'].blank? + registrant = Registrant.find_by(id: pending_json['domain']['registrant_id'].last) + registrant.try(:name) + end + + # rubocop:disable Lint/Loop def generate_auth_info begin diff --git a/app/models/registrant_verification.rb b/app/models/registrant_verification.rb index 1b41b5a02..d56170bdd 100644 --- a/app/models/registrant_verification.rb +++ b/app/models/registrant_verification.rb @@ -1,5 +1,28 @@ # Used in Registrant portal to collect registrant verifications # Registrant postgres user can access this table directly. class RegistrantVerification < ActiveRecord::Base - validates :verification_token, :domain_name, presence: true + # actions + CONFIRMED = 'confirmed' + REJECTED = 'rejected' + + # action types + DOMAIN_REGISTRANT_CHANGE = 'domain_registrant_change' + DOMAIN_DELETE = 'domain_delete' + + belongs_to :domain + + validates :verification_token, :domain_name, :domain, :action, :action_type, presence: true + validates :domain, uniqueness: { scope: [:domain_id, :verification_token] } + + def domain_registrant_change_confirm! + self.action_type = DOMAIN_REGISTRANT_CHANGE + self.action = CONFIRMED + save + end + + def domain_registrant_change_reject! + self.action_type = DOMAIN_REGISTRANT_CHANGE + self.action = REJECTED + save + end end diff --git a/app/views/registrant/domain_delete_confirms/show.haml b/app/views/registrant/domain_delete_confirms/show.haml new file mode 100644 index 000000000..0484fc153 --- /dev/null +++ b/app/views/registrant/domain_delete_confirms/show.haml @@ -0,0 +1,4 @@ +- if @domain.present? +- else + %h1= t(:not_valid_domain_verification_title).html_safe + %p= t(:not_valid_domain_verification_body).html_safe diff --git a/app/views/registrant/domain_update_confirms/show.haml b/app/views/registrant/domain_update_confirms/show.haml index 0484fc153..d777f3bf6 100644 --- a/app/views/registrant/domain_update_confirms/show.haml +++ b/app/views/registrant/domain_update_confirms/show.haml @@ -1,4 +1,46 @@ -- if @domain.present? +- if params[:confirmed].present? + .row + .col-md-12 + %h1= t(:domain_registrant_change_confirmed_title) + .row + .col-md-12 + %p= t(:domain_registrant_change_confirmed_body) +- elsif params[:rejected].present? + .row + .col-md-12 + %h1= t(:domain_registrant_change_rejected_title) + .row + .col-md-12 + %p= t(:domain_registrant_change_rejected_body) - else - %h1= t(:not_valid_domain_verification_title).html_safe - %p= t(:not_valid_domain_verification_body).html_safe + - if @domain.present? + .row + .col-md-12 + %h1= t(:domain_registrant_change_title) + .row + .col-md-12 + %p= t(:domain_registrant_change_body) + + %hr + .row + .col-md-12.text-center.confirmation + .column-keys + %p= t(:domain_name) + ':' + %p= t(:current_registrant) + ':' + %p= t(:new_pending_registrant) + ':' + .column-values + %p= @domain.name + %p= @domain.registrant_name + %p= @domain.pending_registrant_name + + .row + .col-md-12.text-center + .confirmation + = form_for registrant_domain_update_confirm_path(@domain.id), method: :patch do |f| + = hidden_field_tag :token, params[:token] + = f.button t(:confirm_domain_registrant_update), name: 'confirmed', class: 'btn btn-primary' + = f.button t(:reject_domain_registrant_update), name: 'rejected', class: 'btn btn-warning' + %hr + - else + %h1= t(:not_valid_domain_verification_title).html_safe + %p= t(:not_valid_domain_verification_body).html_safe diff --git a/app/views/registrar/domains/index.haml b/app/views/registrar/domains/index.haml index 46b3362ff..e4faeea80 100644 --- a/app/views/registrar/domains/index.haml +++ b/app/views/registrar/domains/index.haml @@ -1,8 +1,9 @@ - content_for :actions do = link_to(t(:new), new_registrar_domain_path, class: 'btn btn-primary') = link_to(t(:transfer), transfer_registrar_domains_path, class: 'btn btn-default') + -# turned off requested by client -# = link_to(t(:keyrelay), registrar_keyrelay_path, class: 'btn btn-default') - = link_to(t(:nameservers), registrar_nameservers_path, class: 'btn btn-default') + -# = link_to(t(:nameservers), registrar_nameservers_path, class: 'btn btn-default') = render 'shared/title', name: t(:domains) .row diff --git a/config/application-example.yml b/config/application-example.yml index 840e13447..f89a2b708 100644 --- a/config/application-example.yml +++ b/config/application-example.yml @@ -5,6 +5,10 @@ zonefile_export_dir: 'export/zonefiles' bank_statement_import_dir: 'import/bank_statements' legal_documents_dir: 'import/legal_documents' +# New Relic app name, keep only current mode, remove other names. +# Example: 'Admin, EPP, REPP' will have name 'Admin, EPP, REPP - production' at New Relic. +new_relic_app_name: 'Admin, EPP, REPP, Registrar, Registrant' + # You can use `rake secret` to generate a secure secret key. # Your secret key is used for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! diff --git a/config/initializers/new_relic_app_name.rb b/config/initializers/new_relic_app_name.rb new file mode 100644 index 000000000..bc1cf7a78 --- /dev/null +++ b/config/initializers/new_relic_app_name.rb @@ -0,0 +1 @@ +NewRelic::Agent.config[:app_name] = "#{ENV['new_relic_app_name']} - #{Rails.env}" if ENV['new_relic_app_name'].present? diff --git a/config/locales/en.yml b/config/locales/en.yml index 53939d6fc..797d97177 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -540,7 +540,6 @@ en: password: 'Password' log_in: 'Log in' log_out: 'Log out (%{user})' - domain_name: 'Domain name' domains: 'Domains' register: 'Register' check: 'Check' @@ -778,3 +777,20 @@ en: ipv4_or_ipv6_must_be_present: 'IPv4 or IPv6 must be present' white_ip: 'White IP' edit_white_ip: 'Edit white IP' + confirm_domain_delete: 'Confirm domain delete' + reject_domain_delete: 'Reject domain delete' + confirm_domain_registrant_update: 'Confirm domain ownership change' + reject_domain_registrant_update: 'Reject domain ownership change' + domain_registrant_change_title: 'Please confirm or reject domain ownership change' + domain_registrant_change_body: 'There is a request to change domain ownership. Before doing it we need your confirmation.' + new_pending_registrant: 'New owner' + current_registrant: 'Current owner' + registrant_domain_verification_failed: 'Domain verification not available' + domain_registrant_change_confirmed_title: 'Domain owner change has been confirmed' + domain_registrant_change_confirmed_body: 'You have successfully confirmed domain owner change.' + registrant_domain_verification_confirmed: 'Domain owner change has successfully confirmed.' + registrant_domain_verification_confirmed_failed: 'Something went wrong' + domain_registrant_change_rejected_title: 'Domain owner change has been rejected' + domain_registrant_change_rejected_body: 'You have rejected domain owner change.' + registrant_domain_verification_rejected: 'Domain owner change has been rejected successfully.' + registrant_domain_verification_rejected_failed: 'Something went wrong' diff --git a/config/routes.rb b/config/routes.rb index 97923232d..6a128fe0c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -57,11 +57,12 @@ Rails.application.routes.draw do end end - resources :nameservers do - collection do - match 'replace_all', via: [:post, :get] - end - end + # turned off requested by client + # resources :nameservers do + # collection do + # match 'replace_all', via: [:post, :get] + # end + # end resources :contacts do member do @@ -105,6 +106,7 @@ Rails.application.routes.draw do # resources :account_activities resources :domain_update_confirms + resources :domain_delete_confirms devise_scope :user do get 'login' => 'sessions#login' diff --git a/db/migrate/20150519094929_add_aciton_to_registrant_verification.rb b/db/migrate/20150519094929_add_aciton_to_registrant_verification.rb new file mode 100644 index 000000000..d7115643a --- /dev/null +++ b/db/migrate/20150519094929_add_aciton_to_registrant_verification.rb @@ -0,0 +1,5 @@ +class AddAcitonToRegistrantVerification < ActiveRecord::Migration + def change + add_column :registrant_verifications, :action, :string + end +end diff --git a/db/migrate/20150519095416_add_domain_id_to_registrant_verifications.rb b/db/migrate/20150519095416_add_domain_id_to_registrant_verifications.rb new file mode 100644 index 000000000..3e34ea289 --- /dev/null +++ b/db/migrate/20150519095416_add_domain_id_to_registrant_verifications.rb @@ -0,0 +1,6 @@ +class AddDomainIdToRegistrantVerifications < ActiveRecord::Migration + def change + add_column :registrant_verifications, :domain_id, :integer + add_index :registrant_verifications, :domain_id + end +end diff --git a/db/migrate/20150519102521_add_action_type_to_registrant_verifications.rb b/db/migrate/20150519102521_add_action_type_to_registrant_verifications.rb new file mode 100644 index 000000000..e363b0594 --- /dev/null +++ b/db/migrate/20150519102521_add_action_type_to_registrant_verifications.rb @@ -0,0 +1,5 @@ +class AddActionTypeToRegistrantVerifications < ActiveRecord::Migration + def change + add_column :registrant_verifications, :action_type, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 2b23859cc..b6637648f 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: 20150519140853) do +ActiveRecord::Schema.define(version: 20150519102521) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -857,9 +857,13 @@ ActiveRecord::Schema.define(version: 20150519140853) do t.string "verification_token" t.datetime "created_at" t.datetime "updated_at" + t.string "action" + t.integer "domain_id" + t.string "action_type" end add_index "registrant_verifications", ["created_at"], name: "index_registrant_verifications_on_created_at", using: :btree + add_index "registrant_verifications", ["domain_id"], name: "index_registrant_verifications_on_domain_id", using: :btree create_table "registrars", force: :cascade do |t| t.string "name" diff --git a/spec/fabricators/registrant_verification_fabricator.rb b/spec/fabricators/registrant_verification_fabricator.rb index 067ecf288..c0b5fd65f 100644 --- a/spec/fabricators/registrant_verification_fabricator.rb +++ b/spec/fabricators/registrant_verification_fabricator.rb @@ -1,4 +1,7 @@ Fabricator(:registrant_verification) do domain_name { sequence(:name) { |i| "domain#{i}.ee" } } + domain(fabricate: :domain) verification_token '123' + action 'confirmed' + action_type 'registrant_change' end diff --git a/spec/features/registrant/domain_delete_confirm_spec.rb b/spec/features/registrant/domain_delete_confirm_spec.rb new file mode 100644 index 000000000..6ca4bad2e --- /dev/null +++ b/spec/features/registrant/domain_delete_confirm_spec.rb @@ -0,0 +1,44 @@ +require 'rails_helper' + +feature 'DomainDeleteConfirm', type: :feature do + context 'as unknown user with domain without token' do + before :all do + @domain = Fabricate(:domain) + end + + it 'should see warning info if token is missing request' do + visit "/registrant/domain_delete_confirms/#{@domain.id}" + current_path.should == "/registrant/domain_delete_confirms/#{@domain.id}" + page.should have_text('Domain verification not available') + end + + it 'should see warning info if token is missing request' do + visit "/registrant/domain_delete_confirms/#{@domain.id}" + current_path.should == "/registrant/domain_delete_confirms/#{@domain.id}" + page.should have_text('Domain verification not available') + end + end + + context 'as unknown user with domain with token' do + before :all do + @domain = Fabricate( + :domain, + registrant_verification_token: '123', + registrant_verification_asked_at: Time.zone.now + ) + @domain.domain_statuses.create(value: DomainStatus::PENDING_DELETE) + end + + it 'should see warning info if token is missing in request' do + visit "/registrant/domain_delete_confirms/#{@domain.id}?token=wrong_token" + current_path.should == "/registrant/domain_delete_confirms/#{@domain.id}" + page.should have_text('Domain verification not available') + end + + it 'should show domain info and confirm buttons' do + visit "/registrant/domain_delete_confirms/#{@domain.id}?token=123" + current_path.should == "/registrant/domain_delete_confirms/#{@domain.id}" + page.should_not have_text('Domain verification not available') + end + end +end diff --git a/spec/models/registrant_verification_spec.rb b/spec/models/registrant_verification_spec.rb index 7640956b0..97d165923 100644 --- a/spec/models/registrant_verification_spec.rb +++ b/spec/models/registrant_verification_spec.rb @@ -10,7 +10,10 @@ describe RegistrantVerification do @registrant_verification.valid? @registrant_verification.errors.full_messages.should match_array([ "Domain name is missing", - "Verification token is missing" + "Verification token is missing", + "Action is missing", + "Action type is missing", + "Domain is missing" ]) end end