From 216048463d5f7e320a0334ba56cad0a1d9777315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Mon, 21 Mar 2022 09:10:34 +0200 Subject: [PATCH 1/9] Moved notifications about automatic contact name update to bulk change poll message --- app/models/ability.rb | 2 +- app/models/action.rb | 25 ++++- app/models/bulk_action.rb | 2 + app/models/epp/contact.rb | 2 +- app/models/notification.rb | 2 +- app/models/registrant_user.rb | 16 +-- app/models/registrar.rb | 11 ++- app/views/epp/contacts/check.xml.builder | 10 +- .../epp/contacts/partials/_check.xml.builder | 9 ++ app/views/epp/poll/_action.xml.builder | 5 +- app/views/epp/poll/poll_req.xml.builder | 19 +++- config/locales/notifications.en.yml | 1 + db/migrate/20220316140727_add_bulk_actions.rb | 5 + db/structure.sql | 7 +- test/fixtures/actions.yml | 22 ++++- .../epp/contact/check/base_test.rb | 6 +- test/integration/epp/poll_test.rb | 98 +++++++++---------- .../registrant_user_creation_test.rb | 55 ++++++++--- 18 files changed, 201 insertions(+), 96 deletions(-) create mode 100644 app/models/bulk_action.rb create mode 100644 app/views/epp/contacts/partials/_check.xml.builder create mode 100644 db/migrate/20220316140727_add_bulk_actions.rb diff --git a/app/models/ability.rb b/app/models/ability.rb index baa26e4cb..caca24524 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -12,7 +12,7 @@ class Ability @user.roles&.each { |role| send(role) } when 'ApiUser' @user.roles&.each { |role| send(role) } - when 'RegistrantUser' + when 'RegistrantUser' static_registrant end diff --git a/app/models/action.rb b/app/models/action.rb index ac5ee7f72..12435f3f0 100644 --- a/app/models/action.rb +++ b/app/models/action.rb @@ -2,18 +2,37 @@ class Action < ApplicationRecord has_paper_trail versions: { class_name: 'Version::ActionVersion' } belongs_to :user - belongs_to :contact + belongs_to :contact, optional: true + has_many :subactions, class_name: 'Action', foreign_key: 'bulk_action_id', dependent: :destroy + belongs_to :bulk_action, class_name: 'Action', optional: true validates :operation, inclusion: { in: proc { |action| action.class.valid_operations } } class << self def valid_operations - %w[update] + %w[update bulk_update] end end def notification_key - raise 'Action object is missing' unless contact + raise 'Action object is missing' unless bulk_action? || contact + "contact_#{operation}".to_sym end + + def bulk_action? + !!subactions.exists? + end + + def to_non_available_contact_codes + return [] unless bulk_action? + + subactions.map do |a| + { + code: a.contact&.code, + avail: 0, + reason: 'in use', + } + end + end end diff --git a/app/models/bulk_action.rb b/app/models/bulk_action.rb new file mode 100644 index 000000000..1a8cad771 --- /dev/null +++ b/app/models/bulk_action.rb @@ -0,0 +1,2 @@ +class BulkAction < Action +end \ No newline at end of file diff --git a/app/models/epp/contact.rb b/app/models/epp/contact.rb index 614be201b..35691d789 100644 --- a/app/models/epp/contact.rb +++ b/app/models/epp/contact.rb @@ -47,7 +47,7 @@ class Epp::Contact < Contact codes = codes.map { |c| c.include?(':') ? c : "#{reg}:#{c}" } res = [] - codes.map { |c| c.include?(':') ? c : "#{reg}:#{c}" }.map { |c| c.strip.upcase }.each do |x| + codes.map { |c| c.strip.upcase }.each do |x| c = find_by_epp_code(x) res << (c ? { code: c.code, avail: 0, reason: 'in use' } : { code: x, avail: 1 }) end diff --git a/app/models/notification.rb b/app/models/notification.rb index 07e824367..c9af66c56 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -2,7 +2,7 @@ class Notification < ApplicationRecord include Versions # version/notification_version.rb belongs_to :registrar - belongs_to :action + belongs_to :action, optional: true scope :unread, -> { where(read: false) } diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index 80b8ecab9..a1f6993af 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -112,13 +112,17 @@ class RegistrantUser < User end def update_related_contacts - contacts = Contact.where(ident: ident, ident_country_code: country.alpha2) + grouped_contacts = Contact.where(ident: ident, ident_country_code: country.alpha2) .where('UPPER(name) != UPPER(?)', username) - - contacts.each do |contact| - contact.update(name: username) - action = actions.create!(contact: contact, operation: :update) - contact.registrar.notify(action) + .includes(:registrar).group_by { |c| c.registrar } + grouped_contacts.each do |registrar, contacts| + bulk_action, action = actions.create!(operation: :bulk_update) if contacts.size > 1 + contacts.each do |c| + if c.update(name: username) + action = actions.create!(contact: c, operation: :update, bulk_action_id: bulk_action&.id) + end + end + registrar.notify(bulk_action || action) end end diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 8517bd6fe..d7ba62306 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -218,8 +218,15 @@ class Registrar < ApplicationRecord end def notify(action) - text = I18n.t("notifications.texts.#{action.notification_key}", contact: action.contact.code) - notifications.create!(text: text) + text = I18n.t("notifications.texts.#{action.notification_key}", contact: action.contact&.code, + count: action.subactions&.count) + if action.bulk_action? + notifications.create!(text: text, action_id: action.id, + attached_obj_type: 'BulkAction', + attached_obj_id: action.id) + else + notifications.create!(text: text) + end end def e_invoice_iban diff --git a/app/views/epp/contacts/check.xml.builder b/app/views/epp/contacts/check.xml.builder index 6b4ea4cc7..f3b1f555a 100644 --- a/app/views/epp/contacts/check.xml.builder +++ b/app/views/epp/contacts/check.xml.builder @@ -5,15 +5,7 @@ xml.epp_head do end xml.resData do - xml.tag!('contact:chkData', 'xmlns:contact' => - Xsd::Schema.filename(for_prefix: 'contact-ee', for_version: '1.1')) do - @results.each do |result| - xml.tag!('contact:cd') do - xml.tag! "contact:id", result[:code], avail: result[:avail] - xml.tag!('contact:reason', result[:reason]) unless result[:avail] == 1 - end - end - end + xml << render('epp/contacts/partials/check', builder: xml, results: @results) end render('epp/shared/trID', builder: xml) diff --git a/app/views/epp/contacts/partials/_check.xml.builder b/app/views/epp/contacts/partials/_check.xml.builder new file mode 100644 index 000000000..70bb1f4e3 --- /dev/null +++ b/app/views/epp/contacts/partials/_check.xml.builder @@ -0,0 +1,9 @@ +builder.tag!('contact:chkData', 'xmlns:contact' => + Xsd::Schema.filename(for_prefix: 'contact-ee', for_version: '1.1')) do + results.each do |result| + builder.tag!('contact:cd') do + builder.tag! 'contact:id', result[:code], avail: result[:avail] + # builder.tag!('contact:reason', result[:reason]) unless result[:avail] == 1 + end + end +end diff --git a/app/views/epp/poll/_action.xml.builder b/app/views/epp/poll/_action.xml.builder index dc0adb4e4..838ae9aaf 100644 --- a/app/views/epp/poll/_action.xml.builder +++ b/app/views/epp/poll/_action.xml.builder @@ -1,9 +1,12 @@ builder.extension do builder.tag!('changePoll:changeData', - 'xmlns:changePoll' => Xsd::Schema.filename(for_prefix: 'changePoll')) do + 'xmlns:changePoll' => Xsd::Schema.filename(for_prefix: 'changePoll', for_version: '1.0')) do builder.tag!('changePoll:operation', action.operation) builder.tag!('changePoll:date', action.created_at.utc.xmlschema) builder.tag!('changePoll:svTRID', action.id) builder.tag!('changePoll:who', action.user) + if action.bulk_action? + builder.tag!('changePoll:reason', 'Auto-update according to official data') + end end end diff --git a/app/views/epp/poll/poll_req.xml.builder b/app/views/epp/poll/poll_req.xml.builder index a1f12fd65..f6688fb48 100644 --- a/app/views/epp/poll/poll_req.xml.builder +++ b/app/views/epp/poll/poll_req.xml.builder @@ -9,13 +9,24 @@ xml.epp_head do xml.msg @notification.text end - if @notification.attached_obj_type == 'DomainTransfer' && @object - xml.resData do - xml << render('epp/domains/partials/transfer', builder: xml, dt: @object) + if @object + case @notification.attached_obj_type + when 'DomainTransfer' + xml.resData do + xml << render('epp/domains/partials/transfer', builder: xml, dt: @object) + end + when 'BulkAction' + xml.resData do + xml << render( + 'epp/contacts/partials/check', + builder: xml, + results: @object.to_non_available_contact_codes + ) + end end end - if @notification.action&.contact || @notification.registry_lock? + if @notification.action || @notification.registry_lock? if @notification.registry_lock? state = @notification.text.include?('unlocked') ? 'unlock' : 'lock' xml.extension do diff --git a/config/locales/notifications.en.yml b/config/locales/notifications.en.yml index b5c1dfd47..3bd65ea7e 100644 --- a/config/locales/notifications.en.yml +++ b/config/locales/notifications.en.yml @@ -6,6 +6,7 @@ en: It was associated with registrant %{old_registrant_code} and contacts %{old_contacts_codes}. contact_update: Contact %{contact} has been updated by registrant + contact_bulk_update: '%{count} contacts have been updated by registrant' csync: CSYNC DNSSEC %{action} for domain %{domain} registrar_locked: Domain %{domain_name} has been locked by registrant registrar_unlocked: Domain %{domain_name} has been unlocked by registrant diff --git a/db/migrate/20220316140727_add_bulk_actions.rb b/db/migrate/20220316140727_add_bulk_actions.rb new file mode 100644 index 000000000..1eae94220 --- /dev/null +++ b/db/migrate/20220316140727_add_bulk_actions.rb @@ -0,0 +1,5 @@ +class AddBulkActions < ActiveRecord::Migration[6.1] + def change + add_column :actions, :bulk_action_id, :integer, default: nil + end +end diff --git a/db/structure.sql b/db/structure.sql index 0c8420f43..f55203bb3 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -304,7 +304,8 @@ CREATE TABLE public.actions ( user_id integer, operation character varying NOT NULL, created_at timestamp without time zone, - contact_id integer + contact_id integer, + bulk_action_id integer ); @@ -5400,10 +5401,14 @@ INSERT INTO "schema_migrations" (version) VALUES ('20211126085139'), ('20211231113934'), ('20220106123143'), +<<<<<<< HEAD ('20220113201642'), ('20220113220809'), ('20220124105717'), ('20220216113112'), ('20220228093211'); +======= +('20220316140727'); +>>>>>>> f98598620 (Moved notifications about automatic contact name update to bulk change poll message) diff --git a/test/fixtures/actions.yml b/test/fixtures/actions.yml index 46736e0a1..b802679ba 100644 --- a/test/fixtures/actions.yml +++ b/test/fixtures/actions.yml @@ -2,4 +2,24 @@ contact_update: operation: update contact: john created_at: <%= Time.zone.parse('2010-07-05').to_s(:db) %> - user: registrant \ No newline at end of file + user: registrant + +contacts_update_bulk_action: + operation: bulk_update + user: registrant + +contact_update_subaction_one: + operation: update + contact: william + created_at: <%= Time.zone.parse('2010-07-05').to_s(:db) %> + user: registrant + bulk_action: contacts_update_bulk_action + +contact_update_subaction_two: + operation: update + contact: jane + created_at: <%= Time.zone.parse('2010-07-05').to_s(:db) %> + user: registrant + bulk_action: contacts_update_bulk_action + + diff --git a/test/integration/epp/contact/check/base_test.rb b/test/integration/epp/contact/check/base_test.rb index f1b9f4d16..6ad027fc6 100644 --- a/test/integration/epp/contact/check/base_test.rb +++ b/test/integration/epp/contact/check/base_test.rb @@ -76,7 +76,7 @@ class EppContactCheckBaseTest < EppTestCase response_xml = Nokogiri::XML(response.body) assert_correct_against_schema response_xml assert_equal '0', response_xml.at_xpath('//contact:id', contact: xml_schema)['avail'] - assert_equal 'in use', response_xml.at_xpath('//contact:reason', contact: xml_schema).text + # assert_equal 'in use', response_xml.at_xpath('//contact:reason', contact: xml_schema).text end def test_multiple_contacts @@ -127,7 +127,7 @@ class EppContactCheckBaseTest < EppTestCase assert_correct_against_schema response_xml assert_epp_response :completed_successfully assert_equal "#{@contact.registrar.code}:JOHN-001".upcase, response_xml.at_xpath('//contact:id', contact: xml_schema).text - assert_equal 'in use', response_xml.at_xpath('//contact:reason', contact: xml_schema).text + # assert_equal 'in use', response_xml.at_xpath('//contact:reason', contact: xml_schema).text end def test_check_contact_without_prefix @@ -154,7 +154,7 @@ class EppContactCheckBaseTest < EppTestCase assert_correct_against_schema response_xml assert_epp_response :completed_successfully assert_equal "#{@contact.registrar.code}:JOHN-001".upcase, response_xml.at_xpath('//contact:id', contact: xml_schema).text - assert_equal 'in use', response_xml.at_xpath('//contact:reason', contact: xml_schema).text + # assert_equal 'in use', response_xml.at_xpath('//contact:reason', contact: xml_schema).text end private diff --git a/test/integration/epp/poll_test.rb b/test/integration/epp/poll_test.rb index 5cdb7e524..29c24af26 100644 --- a/test/integration/epp/poll_test.rb +++ b/test/integration/epp/poll_test.rb @@ -7,16 +7,8 @@ class EppPollTest < EppTestCase # Deliberately does not conform to RFC5730, which requires the first notification to be returned def test_return_latest_notification_when_queue_is_not_empty - request_xml = <<-XML - - - - - - - XML - post epp_poll_path, params: { frame: request_xml }, - headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + post epp_poll_path, params: { frame: request_req_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } xml_doc = Nokogiri::XML(response.body) assert_epp_response :completed_successfully_ack_to_dequeue @@ -30,17 +22,9 @@ class EppPollTest < EppTestCase version = Version::DomainVersion.last @notification.update(attached_obj_type: 'DomainVersion', attached_obj_id: version.id) - request_xml = <<-XML - - - - - - - XML assert_nothing_raised do - post epp_poll_path, params: { frame: request_xml }, - headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + post epp_poll_path, params: { frame: request_req_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end xml_doc = Nokogiri::XML(response.body) @@ -54,19 +38,11 @@ class EppPollTest < EppTestCase def test_return_action_data_when_present @notification.update!(action: actions(:contact_update)) - request_xml = <<-XML - - - - - - - XML - post epp_poll_path, params: { frame: request_xml }, - headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + post epp_poll_path, params: { frame: request_req_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } xml_doc = Nokogiri::XML(response.body) - namespace = Xsd::Schema.filename(for_prefix: 'changePoll') + namespace = Xsd::Schema.filename(for_prefix: 'changePoll', for_version: '1.0') assert_equal 'update', xml_doc.xpath('//changePoll:operation', 'changePoll' => namespace).text assert_equal Time.zone.parse('2010-07-05').utc.xmlschema, xml_doc.xpath('//changePoll:date', 'changePoll' => namespace).text @@ -76,19 +52,35 @@ class EppPollTest < EppTestCase 'changePoll' => namespace).text end + def test_return_notifcation_with_bulk_action_data + bulk_action = actions(:contacts_update_bulk_action) + @notification.update!(action: bulk_action, + attached_obj_id: bulk_action.id, + attached_obj_type: 'BulkAction') + + post epp_poll_path, params: { frame: request_req_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + xml_doc = Nokogiri::XML(response.body) + namespace = Xsd::Schema.filename(for_prefix: 'changePoll', for_version: '1.0') + + assert_equal 2, xml_doc.xpath('//contact:cd', contact: xml_schema).size + assert_epp_response :completed_successfully_ack_to_dequeue + assert_equal 'bulk_update', xml_doc.xpath('//changePoll:operation', + 'changePoll' => namespace).text + assert_equal @notification.action.id.to_s, xml_doc.xpath('//changePoll:svTRID', + 'changePoll' => namespace).text + assert_equal 'Registrant User', xml_doc.xpath('//changePoll:who', + 'changePoll' => namespace).text + assert_equal 'Auto-update according to official data', + xml_doc.xpath('//changePoll:reason', 'changePoll' => namespace).text + end + def test_no_notifications registrars(:bestnames).notifications.delete_all(:delete_all) - request_xml = <<-XML - - - - - - - XML - post epp_poll_path, params: { frame: request_xml }, - headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + post epp_poll_path, params: { frame: request_req_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } assert_epp_response :completed_successfully_no_messages end @@ -106,7 +98,7 @@ class EppPollTest < EppTestCase XML post epp_poll_path, params: { frame: request_xml }, - headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } notification.reload xml_doc = Nokogiri::XML(response.body) @@ -128,7 +120,7 @@ class EppPollTest < EppTestCase XML post epp_poll_path, params: { frame: request_xml }, - headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } notification.reload assert notification.unread? @@ -145,13 +137,22 @@ class EppPollTest < EppTestCase XML post epp_poll_path, params: { frame: request_xml }, - headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } assert_epp_response :object_does_not_exist end def test_anonymous_user_cannot_access - request_xml = <<-XML + post '/epp/command/poll', params: { frame: request_req_xml }, + headers: { 'HTTP_COOKIE' => 'session=non-existent' } + + assert_epp_response :authorization_error + end + + private + + def request_req_xml + <<-XML @@ -159,10 +160,9 @@ class EppPollTest < EppTestCase XML + end - post '/epp/command/poll', params: { frame: request_xml }, - headers: { 'HTTP_COOKIE' => 'session=non-existent' } - - assert_epp_response :authorization_error + def xml_schema + Xsd::Schema.filename(for_prefix: 'contact-ee', for_version: '1.1') end end diff --git a/test/models/registrant_user/registrant_user_creation_test.rb b/test/models/registrant_user/registrant_user_creation_test.rb index 9fff4ca02..f183c94dc 100644 --- a/test/models/registrant_user/registrant_user_creation_test.rb +++ b/test/models/registrant_user/registrant_user_creation_test.rb @@ -7,34 +7,40 @@ class RegistrantUserCreationTest < ActiveSupport::TestCase first_name: 'JOHN', last_name: 'SMITH' } - - RegistrantUser.find_or_create_by_api_data(user_data) + assert_difference 'RegistrantUser.count' do + RegistrantUser.find_or_create_by_api_data(user_data) + end user = User.find_by(registrant_ident: 'EE-37710100070') assert_equal('JOHN SMITH', user.username) end - def test_find_or_create_by_api_data_creates_a_user_with_original_name + def test_find_or_create_by_api_data_updates_a_user_with_existing_ident user_data = { - ident: '37710100070', + ident: '1234', + country_code: 'US', first_name: 'John', - last_name: 'Smith' + last_name: 'Smith', } + assert_no_difference 'RegistrantUser.count' do + RegistrantUser.find_or_create_by_api_data(user_data) + end - RegistrantUser.find_or_create_by_api_data(user_data) - - user = User.find_by(registrant_ident: 'EE-37710100070') + user = User.find_by(registrant_ident: 'US-1234') assert_equal('John Smith', user.username) end - def test_updates_related_contacts_name_if_differs_from_e_identity - contact = contacts(:john) - contact.update(ident: '39708290276', ident_country_code: 'EE') + def test_updates_related_contacts_name_if_different_from_e_identity + registrars = [registrars(:bestnames), registrars(:goodnames)] + contacts = [contacts(:john), contacts(:william), contacts(:identical_to_william)] + contacts.each do |c| + c.update(ident: '39708290276', ident_country_code: 'EE') + end user_data = { ident: '39708290276', first_name: 'John', - last_name: 'Doe' + last_name: 'Doe', } RegistrantUser.find_or_create_by_api_data(user_data) @@ -42,7 +48,28 @@ class RegistrantUserCreationTest < ActiveSupport::TestCase user = User.find_by(registrant_ident: 'EE-39708290276') assert_equal('John Doe', user.username) - contact.reload - assert_equal user.username, contact.name + contacts.each do |c| + c.reload + assert_equal user.username, c.name + assert user.actions.find_by(operation: :update, contact_id: c.id) + end + + bulk_action = BulkAction.find_by(user_id: user.id, operation: :bulk_update) + assert_equal 2, bulk_action.subactions.size + + registrars.each do |r| + notification = r.notifications.unread.order('created_at DESC').take + if r == registrars(:bestnames) + assert_equal '2 contacts have been updated by registrant', notification.text + assert_equal 'BulkAction', notification.attached_obj_type + assert_equal bulk_action.id, notification.attached_obj_id + assert_equal bulk_action.id, notification.action_id + else + assert_equal 'Contact william-002 has been updated by registrant', notification.text + refute notification.action_id + refute notification.attached_obj_id + refute notification.attached_obj_type + end + end end end From dadcc9580b2dfc021a663a838a86f66bf8e57851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Mon, 21 Mar 2022 09:49:29 +0200 Subject: [PATCH 2/9] Fixed structure.sql file --- db/structure.sql | 3 --- 1 file changed, 3 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index f55203bb3..56d499289 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -5401,14 +5401,11 @@ INSERT INTO "schema_migrations" (version) VALUES ('20211126085139'), ('20211231113934'), ('20220106123143'), -<<<<<<< HEAD ('20220113201642'), ('20220113220809'), ('20220124105717'), ('20220216113112'), ('20220228093211'); -======= ('20220316140727'); ->>>>>>> f98598620 (Moved notifications about automatic contact name update to bulk change poll message) From f59c6ee5c3bff7cb15bf6f9149596fbf4668619d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Mon, 21 Mar 2022 10:03:21 +0200 Subject: [PATCH 3/9] Updated structure.sql --- .DS_Store | Bin 0 -> 8196 bytes app/.DS_Store | Bin 0 -> 6148 bytes app/controllers/.DS_Store | Bin 0 -> 6148 bytes app/controllers/repp/.DS_Store | Bin 0 -> 6148 bytes app/controllers/repp/v1/.DS_Store | Bin 0 -> 6148 bytes .../repp/v1/registrar/auth_controller.rb | 26 +++++++++++ .../repp/v1/registrar/summary_controller.rb | 44 ++++++++++++++++++ db/structure.sql | 7 +-- üpõ.preinstalled_gems | 25 ++++++++++ 9 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 .DS_Store create mode 100644 app/.DS_Store create mode 100644 app/controllers/.DS_Store create mode 100644 app/controllers/repp/.DS_Store create mode 100644 app/controllers/repp/v1/.DS_Store create mode 100644 app/controllers/repp/v1/registrar/auth_controller.rb create mode 100644 app/controllers/repp/v1/registrar/summary_controller.rb create mode 100644 üpõ.preinstalled_gems diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..05ef5629c7d8e1c4211d177d2a025725eb14b0e5 GIT binary patch literal 8196 zcmeHMTWl0n7(U-@ff+_%s09i#>DJ1O|sJ3~7%omqBfw_sDP zPZ~iJUo?uBH=;gxiK61G_r&->kSHJM#Q2{%vz0Djcrpa%B)#2NTsW`KVmlGHg(MRY>Y@Y6v$%v*RIw2@&s6n_A6|RV`7!d9xPeyjBh)xJ9+!>ognK0}@%tMdM?VQ;i6FoJ@gHu8Hp z*X?;urZhJ)du(fTP^)V5+`zD1D<3-8rbQpBMyIU}xjOhka_E5K%zMRfe1aEe`d*YVsT zl5p$kEXzFRvV+WKLyli;6HgV1_DoKMdcG8@GE-G&>AijZ1AF%kYFfd!IxWWt?4s3f z1eQOj&G9Mn%~{XgmA8r%ac|ah3L`FQ=4K5iTOea=qvLeh_Y3Q6-gBH?o^J=X=l1sn z){%hg_(D@ueFMIi58A@T`fOTXSXJ^pcILRVzsJh^L>1+g*$ZlJS$^x9+wM$tY~Im% zc8)f;Qms~%tyfPQ{O1Eo_SZ6D%7cRPK zv96a}msaU3WbDHQJ2DU#ZF!4EAy!xF z^@?W5-9CjZmRPMeDw?l!A0k8u*Jiav)=Z_xF*24TM6K#NS=*}g7DdEDSf$=2D}7mS zWQ2n8g)FVN%i72C0lx7z!w+`mESL7?q1|1p>-}85(KIcSB3M+tuu|WuZYX|{zOpn^Nfj?`&i`TNU1=gSmYte!>Y{Pc!zyPu^aS%grP(Tq!a1;;VVLXCIaSTu38Jxg#cpfM5Dqh3u zco*;CeSC{BcUyxj~a&`0V>o-o~ zPQbK;%!?5pf_zG8gdh)rP!3R0dTLD%Re^QnN)@Qh;MFRh<<_+~t2Np*suRI3T}JG5 zsu97is;{ZhBq~k8HZ<0#T7n8s34Pbr6N`vxy+c*C3MxUN+n^K6A|~BN%kYAduO8a} z3hYnV8TJMHhW$jq{tF4nSb!v!qMm@f0Vx7=J30u=yU>X)bYnjTVIV`$cHkn1!^mR{ z<9HAgc!+>~9FO5~JcXwT+|LrcPvS+qgqQIKPT_65gVQ0*KgH)bUk2N4Q(=p5%VAq~ zWK1=`{M-*ou&cI{_P|@Dio+h?*zE5hR3BPM6sozVTH*Pl} uXy`)2l!pM~C;wqc^CX#apHxIA1SJWz|NJ4~>i)it&;R)R5Ak`u4u1oy!Enp~ literal 0 HcmV?d00001 diff --git a/app/.DS_Store b/app/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..830c593b89e71e935955619df619e42d09b641be GIT binary patch literal 6148 zcmeHK!AiqG5Z!I7O(;SR3VI88E!f&pC|*LXKVU=;Dm5`dgE3o@)Er77cl{xM#P4xt zccYZrgBOu96K3D+>`az@8+NjcF+Q3FUB)cNm;s7dGokrGa2$0-YTARyP`wziu_(`XsD?xQH& z+{=DKRYFb#8J z9n9z5VZYP1dxPGhZO@0tVE222#lkf94v$XGCr|NnB3>1z96moOI~pr^17pqdUfeW^ zMe+a3o3~UqwyfJpiBUqBItt*SeT5E&efudkssqiZW3|WdH f7EAFys1)$qXaG7IONHP8p&tQB12x3JpEB?XgX&K( literal 0 HcmV?d00001 diff --git a/app/controllers/.DS_Store b/app/controllers/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a3eee7bc42595345c5e13abf3402fcbff1011646 GIT binary patch literal 6148 zcmeHK%}T>S5Z-O0O({YS3VI88E!f&pC|*LWFJMFuDm5WNgE1SD)E-J9cYPsW#OHBl zcOw?-Rm9G~?l-@?*$=Wmj4|%c!aidbW6Xqx$Wd7%=w2IY=ww8WV+8Xe3lb54{ib7o z9q`)?ma~XuEc^QXL6*ct+3UUYM$_2ZZka8!W8QiXV(yiGIV)U0zeejqh$N_WKe&ve z`PAAy6=~_mX_U)?IE*0W<|SGFabZ#VZ2h)8JZo)echFEUuR;X`^p#5h7`Tt@%b<$es6(Eku~LYm TpkI~)(nUZLLLD*i3k-Y!)458c literal 0 HcmV?d00001 diff --git a/app/controllers/repp/.DS_Store b/app/controllers/repp/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..fcb003e6543eeb63b4f0dc8a1b59afba2db039d3 GIT binary patch literal 6148 zcmeHKQA@)x5Kgw~GKSCx1$_(nI&gDiFnlR<{sAlcpfX!Jv{;+5cI(3!^j-guf5hM8 zU6O*+J&U+INWQz=UDABeT*4UR!+F?Y%wdcPXowt@4T8fPT@@RQ$Z?J!Rsrbm!8DGn z@2>-Xdxb4nC&<(3*Y8iWcKd@@s~j1Zza;9_u*rdJEqfMAcmqXmX5r0}SS62Om$79GAu&J<5Cg=()-zyB zgJ^C&6GQ+pKn#3m0M7>r4bin&7}Q4xba;J6e+>}@bbL!7N{g<=!XS7+xJd;xsoXv> zxJid`Y2#drg+Y_fxLz6Nu`8F47p_-_ajC-@cMVcc3=jkB3{;KjVEw;=7nkwfh?eu+B7xfTn9I17&J QbU?ZYXhNtX27ZBoPnbSPY5)KL literal 0 HcmV?d00001 diff --git a/app/controllers/repp/v1/.DS_Store b/app/controllers/repp/v1/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b22dad7630733675abfd34d2554a9b0a86ce7ed4 GIT binary patch literal 6148 zcmeHK%}T>S5T0$TO(;SS3VI88E!f&p5HF$D7cim+m735}gE3o@)E-J9cYPsW#OHBl zcO#Zo@FZeqVD_7xpDg=r*dG88z3H$8PzL}Dm9S)EvqmURx*{dxAr$HxDP)j<4@odv z$!5o2WPsMr#x)zk7()26e(5BLWPs7PU=oFC)@;6uQn|9VUA3xK&ARg*nhol^XEM(GFdikUARLY`<@P#^hjP}F(|DMwT2BWo+p-7sgZaF5 z(rGrFcDJ)=IP;TZv^(wYVqsf*hexLugU9G8mM@x5fxn)T9fJkDqOoRb&t4KoG9F{J zs4OZNnE_^i8Q2g8%=Ty1He|j$O=f@@_&Ec#KRBp_uEAWR+B&eI>m$W0gd}LwTY}Ir z=o-v5VgyC#Qbb)U%o9WCa`ZbU&o!89)a4-5$oL&IvM?_cp+-l)qtZdR8o6Z#n1N*m z%DP*p^Z)$&_y2Mc_m}}@;9oHyDt)it!zr1wb!BpN);g&7s3eq^Yy2!hLmkDKOGoiO bsuJ`&WFWc*bB*Xh;fsKxfg5JvR~h&K-S|z~ literal 0 HcmV?d00001 diff --git a/app/controllers/repp/v1/registrar/auth_controller.rb b/app/controllers/repp/v1/registrar/auth_controller.rb new file mode 100644 index 000000000..74737e5ca --- /dev/null +++ b/app/controllers/repp/v1/registrar/auth_controller.rb @@ -0,0 +1,26 @@ +module Repp + module V1 + module Registrar + class AuthController < BaseController + api :GET, 'repp/v1/registrar/auth' + desc 'check user auth info, track user last login datetime and return data' + + def index + registrar = current_user.registrar + + data = set_values_to_data(registrar: registrar) + + render_success(data: data) + end + + private + + def set_values_to_data(registrar:) + data = current_user.as_json(only: %i[id username roles]) + data[:registrar_name] = registrar.name + data + end + end + end + end +end \ No newline at end of file diff --git a/app/controllers/repp/v1/registrar/summary_controller.rb b/app/controllers/repp/v1/registrar/summary_controller.rb new file mode 100644 index 000000000..dfb54931c --- /dev/null +++ b/app/controllers/repp/v1/registrar/summary_controller.rb @@ -0,0 +1,44 @@ +module Repp + module V1 + module Registrar + class SummaryController < BaseController + api :GET, 'repp/v1/registrar/summary' + desc 'check user summary info and return data' + + def index + registrar = current_user.registrar + + data = evaluate_data(registrar: registrar) + + render_success(data: data) + end + + private + + def evaluate_data(registrar:) + data = current_user.as_json(only: %i[id username]) + data[:registrar_name] = registrar.name + data[:last_login_date] = last_login_date + data[:balance] = { amount: registrar.cash_account&.balance, + currency: registrar.cash_account&.currency } + data[:domains] = registrar.domains.count + data[:contacts] = registrar.contacts.count + data[:phone] = registrar.phone + data[:email] = registrar.email + data[:billing_email] = registrar.billing_email + data[:billing_address] = registrar.address + data + end + + def last_login_date + q = ApiLog::ReppLog.ransack({ request_path_eq: '/repp/v1/registrar/auth', + response_code_eq: '200', + api_user_name_cont: current_user.username, + request_method_eq: 'GET' }) + q.sorts = 'id desc' + q.result.offset(1).first&.created_at + end + end + end + end +end \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 56d499289..984a949df 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -827,8 +827,7 @@ CREATE TABLE public.dnskeys ( updator_str character varying, legacy_domain_id integer, updated_at timestamp without time zone, - validation_datetime timestamp without time zone, - failed_validation_reason character varying + validation_datetime timestamp without time zone ); @@ -1196,7 +1195,6 @@ CREATE TABLE public.invoices ( buyer_vat_no character varying, issue_date date NOT NULL, e_invoice_sent_at timestamp without time zone, - payment_link character varying, CONSTRAINT invoices_due_date_is_not_before_issue_date CHECK ((due_date >= issue_date)) ); @@ -5403,9 +5401,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220106123143'), ('20220113201642'), ('20220113220809'), -('20220124105717'), -('20220216113112'), -('20220228093211'); ('20220316140727'); diff --git a/üpõ.preinstalled_gems b/üpõ.preinstalled_gems new file mode 100644 index 000000000..0b8633422 --- /dev/null +++ b/üpõ.preinstalled_gems @@ -0,0 +1,25 @@ +FROM ghcr.io/internetee/registry:gems-latest +LABEL org.opencontainers.image.source=https://github.com/internetee/registry +ARG YARN_VER='1.22.10' +ARG RAILS_ENV +ARG SECRET_KEY_BASE + +ENV RAILS_ENV "$RAILS_ENV" +ENV SECRET_KEY_BASE "$SECRET_KEY_BASE" + +RUN npm install -g yarn@"$YARN_VER" + +RUN bash -c 'mkdir -pv -m776 {/opt/webapps/app/tmp/pids,/opt/ca,/opt/ca/newcerts}' +RUN echo -n 12 > /opt/ca/serial +RUN chmod 776 /opt/ca/serial +RUN echo '3A0e' > /opt/ca/crlnumber +RUN chmod 776 /opt/ca/crlnumber +RUN touch /opt/ca/index.txt +RUN chmod 776 /opt/ca/index.txt +WORKDIR /opt/webapps/app + +COPY . . + +RUN bundle exec rails assets:precompile + +EXPOSE 3000 From d50c3f0b453d6b288ff75eac36c1955ff402bc1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Mon, 21 Mar 2022 11:23:42 +0200 Subject: [PATCH 4/9] Fixed codeclimate issues and removed unnecessary files --- .DS_Store | Bin 8196 -> 0 bytes app/.DS_Store | Bin 6148 -> 0 bytes app/controllers/.DS_Store | Bin 6148 -> 0 bytes app/controllers/repp/.DS_Store | Bin 6148 -> 0 bytes app/controllers/repp/v1/.DS_Store | Bin 6148 -> 0 bytes .../repp/v1/registrar/auth_controller.rb | 26 ----------- .../repp/v1/registrar/summary_controller.rb | 44 ------------------ app/models/action.rb | 6 ++- app/models/bulk_action.rb | 3 +- app/models/registrant_user.rb | 9 ++-- app/views/epp/poll/_action.xml.builder | 4 +- üpõ.preinstalled_gems | 25 ---------- 12 files changed, 12 insertions(+), 105 deletions(-) delete mode 100644 .DS_Store delete mode 100644 app/.DS_Store delete mode 100644 app/controllers/.DS_Store delete mode 100644 app/controllers/repp/.DS_Store delete mode 100644 app/controllers/repp/v1/.DS_Store delete mode 100644 app/controllers/repp/v1/registrar/auth_controller.rb delete mode 100644 app/controllers/repp/v1/registrar/summary_controller.rb delete mode 100644 üpõ.preinstalled_gems diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 05ef5629c7d8e1c4211d177d2a025725eb14b0e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMTWl0n7(U-@ff+_%s09i#>DJ1O|sJ3~7%omqBfw_sDP zPZ~iJUo?uBH=;gxiK61G_r&->kSHJM#Q2{%vz0Djcrpa%B)#2NTsW`KVmlGHg(MRY>Y@Y6v$%v*RIw2@&s6n_A6|RV`7!d9xPeyjBh)xJ9+!>ognK0}@%tMdM?VQ;i6FoJ@gHu8Hp z*X?;urZhJ)du(fTP^)V5+`zD1D<3-8rbQpBMyIU}xjOhka_E5K%zMRfe1aEe`d*YVsT zl5p$kEXzFRvV+WKLyli;6HgV1_DoKMdcG8@GE-G&>AijZ1AF%kYFfd!IxWWt?4s3f z1eQOj&G9Mn%~{XgmA8r%ac|ah3L`FQ=4K5iTOea=qvLeh_Y3Q6-gBH?o^J=X=l1sn z){%hg_(D@ueFMIi58A@T`fOTXSXJ^pcILRVzsJh^L>1+g*$ZlJS$^x9+wM$tY~Im% zc8)f;Qms~%tyfPQ{O1Eo_SZ6D%7cRPK zv96a}msaU3WbDHQJ2DU#ZF!4EAy!xF z^@?W5-9CjZmRPMeDw?l!A0k8u*Jiav)=Z_xF*24TM6K#NS=*}g7DdEDSf$=2D}7mS zWQ2n8g)FVN%i72C0lx7z!w+`mESL7?q1|1p>-}85(KIcSB3M+tuu|WuZYX|{zOpn^Nfj?`&i`TNU1=gSmYte!>Y{Pc!zyPu^aS%grP(Tq!a1;;VVLXCIaSTu38Jxg#cpfM5Dqh3u zco*;CeSC{BcUyxj~a&`0V>o-o~ zPQbK;%!?5pf_zG8gdh)rP!3R0dTLD%Re^QnN)@Qh;MFRh<<_+~t2Np*suRI3T}JG5 zsu97is;{ZhBq~k8HZ<0#T7n8s34Pbr6N`vxy+c*C3MxUN+n^K6A|~BN%kYAduO8a} z3hYnV8TJMHhW$jq{tF4nSb!v!qMm@f0Vx7=J30u=yU>X)bYnjTVIV`$cHkn1!^mR{ z<9HAgc!+>~9FO5~JcXwT+|LrcPvS+qgqQIKPT_65gVQ0*KgH)bUk2N4Q(=p5%VAq~ zWK1=`{M-*ou&cI{_P|@Dio+h?*zE5hR3BPM6sozVTH*Pl} uXy`)2l!pM~C;wqc^CX#apHxIA1SJWz|NJ4~>i)it&;R)R5Ak`u4u1oy!Enp~ diff --git a/app/.DS_Store b/app/.DS_Store deleted file mode 100644 index 830c593b89e71e935955619df619e42d09b641be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!AiqG5Z!I7O(;SR3VI88E!f&pC|*LXKVU=;Dm5`dgE3o@)Er77cl{xM#P4xt zccYZrgBOu96K3D+>`az@8+NjcF+Q3FUB)cNm;s7dGokrGa2$0-YTARyP`wziu_(`XsD?xQH& z+{=DKRYFb#8J z9n9z5VZYP1dxPGhZO@0tVE222#lkf94v$XGCr|NnB3>1z96moOI~pr^17pqdUfeW^ zMe+a3o3~UqwyfJpiBUqBItt*SeT5E&efudkssqiZW3|WdH f7EAFys1)$qXaG7IONHP8p&tQB12x3JpEB?XgX&K( diff --git a/app/controllers/.DS_Store b/app/controllers/.DS_Store deleted file mode 100644 index a3eee7bc42595345c5e13abf3402fcbff1011646..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z-O0O({YS3VI88E!f&pC|*LWFJMFuDm5WNgE1SD)E-J9cYPsW#OHBl zcOw?-Rm9G~?l-@?*$=Wmj4|%c!aidbW6Xqx$Wd7%=w2IY=ww8WV+8Xe3lb54{ib7o z9q`)?ma~XuEc^QXL6*ct+3UUYM$_2ZZka8!W8QiXV(yiGIV)U0zeejqh$N_WKe&ve z`PAAy6=~_mX_U)?IE*0W<|SGFabZ#VZ2h)8JZo)echFEUuR;X`^p#5h7`Tt@%b<$es6(Eku~LYm TpkI~)(nUZLLLD*i3k-Y!)458c diff --git a/app/controllers/repp/.DS_Store b/app/controllers/repp/.DS_Store deleted file mode 100644 index fcb003e6543eeb63b4f0dc8a1b59afba2db039d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKQA@)x5Kgw~GKSCx1$_(nI&gDiFnlR<{sAlcpfX!Jv{;+5cI(3!^j-guf5hM8 zU6O*+J&U+INWQz=UDABeT*4UR!+F?Y%wdcPXowt@4T8fPT@@RQ$Z?J!Rsrbm!8DGn z@2>-Xdxb4nC&<(3*Y8iWcKd@@s~j1Zza;9_u*rdJEqfMAcmqXmX5r0}SS62Om$79GAu&J<5Cg=()-zyB zgJ^C&6GQ+pKn#3m0M7>r4bin&7}Q4xba;J6e+>}@bbL!7N{g<=!XS7+xJd;xsoXv> zxJid`Y2#drg+Y_fxLz6Nu`8F47p_-_ajC-@cMVcc3=jkB3{;KjVEw;=7nkwfh?eu+B7xfTn9I17&J QbU?ZYXhNtX27ZBoPnbSPY5)KL diff --git a/app/controllers/repp/v1/.DS_Store b/app/controllers/repp/v1/.DS_Store deleted file mode 100644 index b22dad7630733675abfd34d2554a9b0a86ce7ed4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5T0$TO(;SS3VI88E!f&p5HF$D7cim+m735}gE3o@)E-J9cYPsW#OHBl zcO#Zo@FZeqVD_7xpDg=r*dG88z3H$8PzL}Dm9S)EvqmURx*{dxAr$HxDP)j<4@odv z$!5o2WPsMr#x)zk7()26e(5BLWPs7PU=oFC)@;6uQn|9VUA3xK&ARg*nhol^XEM(GFdikUARLY`<@P#^hjP}F(|DMwT2BWo+p-7sgZaF5 z(rGrFcDJ)=IP;TZv^(wYVqsf*hexLugU9G8mM@x5fxn)T9fJkDqOoRb&t4KoG9F{J zs4OZNnE_^i8Q2g8%=Ty1He|j$O=f@@_&Ec#KRBp_uEAWR+B&eI>m$W0gd}LwTY}Ir z=o-v5VgyC#Qbb)U%o9WCa`ZbU&o!89)a4-5$oL&IvM?_cp+-l)qtZdR8o6Z#n1N*m z%DP*p^Z)$&_y2Mc_m}}@;9oHyDt)it!zr1wb!BpN);g&7s3eq^Yy2!hLmkDKOGoiO bsuJ`&WFWc*bB*Xh;fsKxfg5JvR~h&K-S|z~ diff --git a/app/controllers/repp/v1/registrar/auth_controller.rb b/app/controllers/repp/v1/registrar/auth_controller.rb deleted file mode 100644 index 74737e5ca..000000000 --- a/app/controllers/repp/v1/registrar/auth_controller.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Repp - module V1 - module Registrar - class AuthController < BaseController - api :GET, 'repp/v1/registrar/auth' - desc 'check user auth info, track user last login datetime and return data' - - def index - registrar = current_user.registrar - - data = set_values_to_data(registrar: registrar) - - render_success(data: data) - end - - private - - def set_values_to_data(registrar:) - data = current_user.as_json(only: %i[id username roles]) - data[:registrar_name] = registrar.name - data - end - end - end - end -end \ No newline at end of file diff --git a/app/controllers/repp/v1/registrar/summary_controller.rb b/app/controllers/repp/v1/registrar/summary_controller.rb deleted file mode 100644 index dfb54931c..000000000 --- a/app/controllers/repp/v1/registrar/summary_controller.rb +++ /dev/null @@ -1,44 +0,0 @@ -module Repp - module V1 - module Registrar - class SummaryController < BaseController - api :GET, 'repp/v1/registrar/summary' - desc 'check user summary info and return data' - - def index - registrar = current_user.registrar - - data = evaluate_data(registrar: registrar) - - render_success(data: data) - end - - private - - def evaluate_data(registrar:) - data = current_user.as_json(only: %i[id username]) - data[:registrar_name] = registrar.name - data[:last_login_date] = last_login_date - data[:balance] = { amount: registrar.cash_account&.balance, - currency: registrar.cash_account&.currency } - data[:domains] = registrar.domains.count - data[:contacts] = registrar.contacts.count - data[:phone] = registrar.phone - data[:email] = registrar.email - data[:billing_email] = registrar.billing_email - data[:billing_address] = registrar.address - data - end - - def last_login_date - q = ApiLog::ReppLog.ransack({ request_path_eq: '/repp/v1/registrar/auth', - response_code_eq: '200', - api_user_name_cont: current_user.username, - request_method_eq: 'GET' }) - q.sorts = 'id desc' - q.result.offset(1).first&.created_at - end - end - end - end -end \ No newline at end of file diff --git a/app/models/action.rb b/app/models/action.rb index 12435f3f0..444e31bbf 100644 --- a/app/models/action.rb +++ b/app/models/action.rb @@ -3,7 +3,10 @@ class Action < ApplicationRecord belongs_to :user belongs_to :contact, optional: true - has_many :subactions, class_name: 'Action', foreign_key: 'bulk_action_id', dependent: :destroy + has_many :subactions, class_name: 'Action', + foreign_key: 'bulk_action_id', + inverse_of: :action, + dependent: :destroy belongs_to :bulk_action, class_name: 'Action', optional: true validates :operation, inclusion: { in: proc { |action| action.class.valid_operations } } @@ -36,3 +39,4 @@ class Action < ApplicationRecord end end end + diff --git a/app/models/bulk_action.rb b/app/models/bulk_action.rb index 1a8cad771..9c98ee2db 100644 --- a/app/models/bulk_action.rb +++ b/app/models/bulk_action.rb @@ -1,2 +1 @@ -class BulkAction < Action -end \ No newline at end of file +class BulkAction < Action; end diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index a1f6993af..a095b9b22 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -110,11 +110,12 @@ class RegistrantUser < User def last_name username.split.second end - + # rubocop:disable Metrics/MethodLength def update_related_contacts grouped_contacts = Contact.where(ident: ident, ident_country_code: country.alpha2) - .where('UPPER(name) != UPPER(?)', username) - .includes(:registrar).group_by { |c| c.registrar } + .where('UPPER(name) != UPPER(?)', username) + .includes(:registrar) + .group_by(&:registrar) grouped_contacts.each do |registrar, contacts| bulk_action, action = actions.create!(operation: :bulk_update) if contacts.size > 1 contacts.each do |c| @@ -125,7 +126,7 @@ class RegistrantUser < User registrar.notify(bulk_action || action) end end - + # rubocop:enable Metrics/MethodLength class << self def find_or_create_by_api_data(user_data = {}) return false unless user_data[:ident] diff --git a/app/views/epp/poll/_action.xml.builder b/app/views/epp/poll/_action.xml.builder index 838ae9aaf..37f2acccb 100644 --- a/app/views/epp/poll/_action.xml.builder +++ b/app/views/epp/poll/_action.xml.builder @@ -5,8 +5,6 @@ builder.extension do builder.tag!('changePoll:date', action.created_at.utc.xmlschema) builder.tag!('changePoll:svTRID', action.id) builder.tag!('changePoll:who', action.user) - if action.bulk_action? - builder.tag!('changePoll:reason', 'Auto-update according to official data') - end + builder.tag!('changePoll:reason', 'Auto-update according to official data') if action.bulk_action? end end diff --git a/üpõ.preinstalled_gems b/üpõ.preinstalled_gems deleted file mode 100644 index 0b8633422..000000000 --- a/üpõ.preinstalled_gems +++ /dev/null @@ -1,25 +0,0 @@ -FROM ghcr.io/internetee/registry:gems-latest -LABEL org.opencontainers.image.source=https://github.com/internetee/registry -ARG YARN_VER='1.22.10' -ARG RAILS_ENV -ARG SECRET_KEY_BASE - -ENV RAILS_ENV "$RAILS_ENV" -ENV SECRET_KEY_BASE "$SECRET_KEY_BASE" - -RUN npm install -g yarn@"$YARN_VER" - -RUN bash -c 'mkdir -pv -m776 {/opt/webapps/app/tmp/pids,/opt/ca,/opt/ca/newcerts}' -RUN echo -n 12 > /opt/ca/serial -RUN chmod 776 /opt/ca/serial -RUN echo '3A0e' > /opt/ca/crlnumber -RUN chmod 776 /opt/ca/crlnumber -RUN touch /opt/ca/index.txt -RUN chmod 776 /opt/ca/index.txt -WORKDIR /opt/webapps/app - -COPY . . - -RUN bundle exec rails assets:precompile - -EXPOSE 3000 From 392e2844636ef520261ce42b2e8790e952b2e4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Mon, 21 Mar 2022 11:50:00 +0200 Subject: [PATCH 5/9] Fixed inverse_of issues --- app/models/action.rb | 2 +- app/models/registrant_user.rb | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/action.rb b/app/models/action.rb index 444e31bbf..231aec42a 100644 --- a/app/models/action.rb +++ b/app/models/action.rb @@ -5,7 +5,7 @@ class Action < ApplicationRecord belongs_to :contact, optional: true has_many :subactions, class_name: 'Action', foreign_key: 'bulk_action_id', - inverse_of: :action, + inverse_of: :bulk_action, dependent: :destroy belongs_to :bulk_action, class_name: 'Action', optional: true diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index a095b9b22..bbe4044b6 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -110,6 +110,7 @@ class RegistrantUser < User def last_name username.split.second end + # rubocop:disable Metrics/MethodLength def update_related_contacts grouped_contacts = Contact.where(ident: ident, ident_country_code: country.alpha2) @@ -126,7 +127,8 @@ class RegistrantUser < User registrar.notify(bulk_action || action) end end - # rubocop:enable Metrics/MethodLength + # rubocop:enable Metrics/MethodLength + class << self def find_or_create_by_api_data(user_data = {}) return false unless user_data[:ident] From 4afd32ebff0894f4c1026b6721b4ea1024f52eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Mon, 21 Mar 2022 11:58:46 +0200 Subject: [PATCH 6/9] Fixed codeclimate issue --- app/models/action.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/action.rb b/app/models/action.rb index 231aec42a..c87467949 100644 --- a/app/models/action.rb +++ b/app/models/action.rb @@ -39,4 +39,3 @@ class Action < ApplicationRecord end end end - From eb64b3aca4b31be44a99b56230b5fed2b15b4086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Tue, 29 Mar 2022 10:39:26 +0300 Subject: [PATCH 7/9] Modifications for updating business and private contacts --- .../api/v1/registrant/contacts_controller.rb | 10 +- app/models/action.rb | 2 +- app/models/contact.rb | 13 ++ app/models/registrant_user.rb | 82 +++++------- app/views/epp/poll/_action.xml.builder | 10 -- app/views/epp/poll/_extension.xml.builder | 18 +++ app/views/epp/poll/poll_req.xml.builder | 19 ++- config/routes.rb | 5 +- .../registrant_user_creation_test.rb | 43 ------- test/models/registrant_user_test.rb | 120 ++++++++++++------ 10 files changed, 159 insertions(+), 163 deletions(-) delete mode 100644 app/views/epp/poll/_action.xml.builder create mode 100644 app/views/epp/poll/_extension.xml.builder diff --git a/app/controllers/api/v1/registrant/contacts_controller.rb b/app/controllers/api/v1/registrant/contacts_controller.rb index 8e8b46631..b196c567a 100644 --- a/app/controllers/api/v1/registrant/contacts_controller.rb +++ b/app/controllers/api/v1/registrant/contacts_controller.rb @@ -34,15 +34,15 @@ module Api end end - def do_need_update_contact - result = current_registrant_user.do_need_update_contact? + def do_need_update_contacts + result = current_registrant_user.do_need_update_contacts? render json: { update_contacts: result[:result], counter: result[:counter] } end - def update_company_contacts - companies = current_registrant_user.update_company_contacts + def update_contacts + contacts = current_registrant_user.update_contacts - render json: { message: 'get it', companies: companies } + render json: { message: 'get it', contacts: contacts } end def update diff --git a/app/models/action.rb b/app/models/action.rb index c87467949..8a822f867 100644 --- a/app/models/action.rb +++ b/app/models/action.rb @@ -32,7 +32,7 @@ class Action < ApplicationRecord subactions.map do |a| { - code: a.contact&.code, + code: a.contact.code, avail: 0, reason: 'in use', } diff --git a/app/models/contact.rb b/app/models/contact.rb index 84d4ba962..8bb471e47 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -30,6 +30,19 @@ class Contact < ApplicationRecord .where('success = false and verified_at IS NOT NULL') } + scope :with_different_company_name, (lambda do |company| + where("ident = ? AND ident_country_code = 'EE' AND name != ?", + company.registration_number, + company.company_name) + end) + + scope :with_different_registrant_name, (lambda do |user| + where('ident = ? AND ident_country_code = ? AND UPPER(name) != UPPER(?)', + user.ident, + user.country.alpha2, + user.username) + end) + NAME_REGEXP = /([\u00A1-\u00B3\u00B5-\u00BF\u0021-\u0026\u0028-\u002C\u003A-\u0040]| [\u005B-\u005F\u007B-\u007E\u2040-\u206F\u20A0-\u20BF\u2100-\u218F])/x diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index bbe4044b6..96fef635e 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -26,13 +26,13 @@ class RegistrantUser < User [] end - def do_need_update_contact? - return { result: false, counter: 0 } if companies.blank? - + def do_need_update_contacts? counter = 0 + + counter += Contact.with_different_registrant_name(self).size + companies.each do |company| - counter += Contact.where(ident: company.registration_number, ident_country_code: 'EE')&. - reject { |contact| contact.name == company.company_name }.size + counter += Contact.with_different_company_name(company).size end return { result: true, counter: counter } if counter.positive? @@ -40,39 +40,35 @@ class RegistrantUser < User { result: false, counter: 0 } end - def update_company_contacts - return [] if companies.blank? - + def update_contacts + user = self + contacts = [] + contacts.concat Contact.with_different_registrant_name(user) + .each{ |c| c.write_attribute(:name, user.username) } companies.each do |company| - contacts = Contact.where(ident: company.registration_number, ident_country_code: 'EE') - - next if contacts.blank? - - contacts.each do |contact| - next if company.company_name == contact.name - - update_company_name(contact: contact, company: company) - end + contacts.concat Contact.with_different_company_name(company) + .each{ |c| c.write_attribute(:name, company.company_name) } end + + return [] if contacts.blank? - companies + grouped_contacts = contacts.group_by(&:registrar_id) + grouped_contacts.each do |registrar_id, contacts| + bulk_action, action = actions.create!(operation: :bulk_update) if contacts.size > 1 + contacts.each do |c| + if c.save(validate: false) + action = actions.create!(contact: c, operation: :update, bulk_action_id: bulk_action&.id) + end + end + notify_registrar_contacts_updated(action: bulk_action || action, + registrar_id: registrar_id) + end + contacts end - def update_company_name(contact:, company:) - old_contact_name = contact.name - contact.name = company.company_name - - contact.save(validate: false) - - notify_registrar_data_updated(company_name: company.company_name, - old_contact_name: old_contact_name, - contact: contact) - end - - def notify_registrar_data_updated(company_name:, old_contact_name:, contact:) - contact.registrar.notifications.create!( - text: "Contact update: #{contact.id} name updated from #{old_contact_name} to #{company_name} by the registry" - ) + def notify_registrar_contacts_updated(action:, registrar_id:) + registrar = Registrar.find(registrar_id) + registrar.notify(action) if registrar end def contacts(representable: true) @@ -111,24 +107,6 @@ class RegistrantUser < User username.split.second end - # rubocop:disable Metrics/MethodLength - def update_related_contacts - grouped_contacts = Contact.where(ident: ident, ident_country_code: country.alpha2) - .where('UPPER(name) != UPPER(?)', username) - .includes(:registrar) - .group_by(&:registrar) - grouped_contacts.each do |registrar, contacts| - bulk_action, action = actions.create!(operation: :bulk_update) if contacts.size > 1 - contacts.each do |c| - if c.update(name: username) - action = actions.create!(contact: c, operation: :update, bulk_action_id: bulk_action&.id) - end - end - registrar.notify(bulk_action || action) - end - end - # rubocop:enable Metrics/MethodLength - class << self def find_or_create_by_api_data(user_data = {}) return false unless user_data[:ident] @@ -165,8 +143,6 @@ class RegistrantUser < User user = find_or_create_by(registrant_ident: "#{user_data[:country_code]}-#{user_data[:ident]}") user.username = "#{user_data[:first_name]} #{user_data[:last_name]}" user.save - - user.update_related_contacts user end end diff --git a/app/views/epp/poll/_action.xml.builder b/app/views/epp/poll/_action.xml.builder deleted file mode 100644 index 37f2acccb..000000000 --- a/app/views/epp/poll/_action.xml.builder +++ /dev/null @@ -1,10 +0,0 @@ -builder.extension do - builder.tag!('changePoll:changeData', - 'xmlns:changePoll' => Xsd::Schema.filename(for_prefix: 'changePoll', for_version: '1.0')) do - builder.tag!('changePoll:operation', action.operation) - builder.tag!('changePoll:date', action.created_at.utc.xmlschema) - builder.tag!('changePoll:svTRID', action.id) - builder.tag!('changePoll:who', action.user) - builder.tag!('changePoll:reason', 'Auto-update according to official data') if action.bulk_action? - end -end diff --git a/app/views/epp/poll/_extension.xml.builder b/app/views/epp/poll/_extension.xml.builder new file mode 100644 index 000000000..a26e3db8b --- /dev/null +++ b/app/views/epp/poll/_extension.xml.builder @@ -0,0 +1,18 @@ +builder.extension do + builder.tag!('changePoll:changeData', + 'xmlns:changePoll' => Xsd::Schema.filename(for_prefix: 'changePoll', + for_version: '1.0')) do + case type + when 'action' + builder.tag!('changePoll:operation', obj.operation) + builder.tag!('changePoll:date', obj.created_at.utc.xmlschema) + builder.tag!('changePoll:svTRID', obj.id) + builder.tag!('changePoll:who', obj.user) + if obj.bulk_action? + builder.tag!('changePoll:reason', 'Auto-update according to official data') + end + when 'state' + builder.tag!('changePoll:operation', obj) + end + end +end \ No newline at end of file diff --git a/app/views/epp/poll/poll_req.xml.builder b/app/views/epp/poll/poll_req.xml.builder index f6688fb48..0a916e6ad 100644 --- a/app/views/epp/poll/poll_req.xml.builder +++ b/app/views/epp/poll/poll_req.xml.builder @@ -29,18 +29,15 @@ xml.epp_head do if @notification.action || @notification.registry_lock? if @notification.registry_lock? state = @notification.text.include?('unlocked') ? 'unlock' : 'lock' - xml.extension do - xml.tag!('changePoll:changeData', - 'xmlns:changePoll': Xsd::Schema.filename(for_prefix: 'changePoll')) do - xml.tag!('changePoll:operation', state) - end - end + render(partial: 'epp/poll/extension', + locals: { builder: xml, + obj: state, + type: 'state' }) else - render(partial: 'epp/poll/action', - locals: { - builder: xml, - action: @notification.action, - }) + render(partial: 'epp/poll/extension', + locals: { builder: xml, + obj: @notification.action, + type: 'action' }) end end diff --git a/config/routes.rb b/config/routes.rb index 79807729a..a2a4556f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -129,8 +129,9 @@ Rails.application.routes.draw do resource :registry_lock, only: %i[create destroy] end resources :contacts, only: %i[index show update], param: :uuid do - get 'do_need_update_contact', to: 'contacts#do_need_update_contact', as: :do_need_update_contact - post 'update_company_contacts', to: 'contacts#update_company_contacts', as: :update_company_contacts + get 'do_need_update_contacts', to: 'contacts#do_need_update_contacts', + as: :do_need_update_contacts + post 'update_contacts', to: 'contacts#update_contacts', as: :update_contacts end resources :companies, only: %i[index] end diff --git a/test/models/registrant_user/registrant_user_creation_test.rb b/test/models/registrant_user/registrant_user_creation_test.rb index f183c94dc..a32191db8 100644 --- a/test/models/registrant_user/registrant_user_creation_test.rb +++ b/test/models/registrant_user/registrant_user_creation_test.rb @@ -29,47 +29,4 @@ class RegistrantUserCreationTest < ActiveSupport::TestCase user = User.find_by(registrant_ident: 'US-1234') assert_equal('John Smith', user.username) end - - def test_updates_related_contacts_name_if_different_from_e_identity - registrars = [registrars(:bestnames), registrars(:goodnames)] - contacts = [contacts(:john), contacts(:william), contacts(:identical_to_william)] - contacts.each do |c| - c.update(ident: '39708290276', ident_country_code: 'EE') - end - - user_data = { - ident: '39708290276', - first_name: 'John', - last_name: 'Doe', - } - - RegistrantUser.find_or_create_by_api_data(user_data) - - user = User.find_by(registrant_ident: 'EE-39708290276') - assert_equal('John Doe', user.username) - - contacts.each do |c| - c.reload - assert_equal user.username, c.name - assert user.actions.find_by(operation: :update, contact_id: c.id) - end - - bulk_action = BulkAction.find_by(user_id: user.id, operation: :bulk_update) - assert_equal 2, bulk_action.subactions.size - - registrars.each do |r| - notification = r.notifications.unread.order('created_at DESC').take - if r == registrars(:bestnames) - assert_equal '2 contacts have been updated by registrant', notification.text - assert_equal 'BulkAction', notification.attached_obj_type - assert_equal bulk_action.id, notification.attached_obj_id - assert_equal bulk_action.id, notification.action_id - else - assert_equal 'Contact william-002 has been updated by registrant', notification.text - refute notification.action_id - refute notification.attached_obj_id - refute notification.attached_obj_type - end - end - end end diff --git a/test/models/registrant_user_test.rb b/test/models/registrant_user_test.rb index 2b1d6a880..81e57fa72 100644 --- a/test/models/registrant_user_test.rb +++ b/test/models/registrant_user_test.rb @@ -32,30 +32,61 @@ class RegistrantUserTest < ActiveSupport::TestCase assert_equal Country.new('US'), user.country end - def test_should_update_org_contact_if_data_from_business_registry_dismatch + def test_should_update_contacts_if_names_dismatch assert_equal 'US-1234', @user.registrant_ident - org = contacts(:acme_ltd) - org.ident_country_code = 'EE' - org.save(validate: false) - org.reload + registrars = [registrars(:bestnames), registrars(:goodnames)] + contacts = [contacts(:john), contacts(:william), contacts(:identical_to_william), + contacts(:acme_ltd), contacts(:registrar_ltd)] + contacts.each do |c| + if c.ident_type == 'priv' + c.ident = @user.ident + else + c.ident_country_code = 'EE' + c.registrar = registrars(:bestnames) + end + c.save(validate: false) + end - company = Company.new(org.ident, "ace") + company_one = Company.new(contacts(:acme_ltd).ident, 'ace') + company_two = Company.new(contacts(:registrar_ltd).ident, 'acer') - Spy.on(@user, :companies).and_return([company]) - @user.update_company_contacts - org.reload + Spy.on(@user, :companies).and_return([company_one, company_two]) + @user.update_contacts - assert_equal org.name, company.company_name + contacts.each do |c| + c.reload + assert_equal @user.username, c.name if c.ident_type == 'priv' + assert @user.actions.find_by(operation: :update, contact_id: c.id) + end + + bulk_action = @user.actions.where(operation: :bulk_update).last + + assert_equal 4, bulk_action.subactions.size + + registrars.each do |r| + notification = r.notifications.unread.order('created_at DESC').take + if r == registrars(:bestnames) + assert_equal '4 contacts have been updated by registrant', notification.text + assert_equal 'BulkAction', notification.attached_obj_type + assert_equal bulk_action.id, notification.attached_obj_id + assert_equal bulk_action.id, notification.action_id + else + assert_equal 'Contact william-002 has been updated by registrant', notification.text + refute notification.action_id + refute notification.attached_obj_id + refute notification.attached_obj_type + end + end end def test_queries_company_register_for_associated_companies assert_equal 'US-1234', @user.registrant_ident - company = Company.new("acme", "ace") + company = Company.new('acme', 'ace') company_register = Minitest::Mock.new company_register.expect(:representation_rights, [company], [{ citizen_personal_code: '1234', - citizen_country_code: 'USA' }]) + citizen_country_code: 'USA' }]) assert_equal [company], @user.companies(company_register) company_register.verify @@ -63,58 +94,71 @@ class RegistrantUserTest < ActiveSupport::TestCase def test_should_return_zero_count_of_companies assert_equal 'US-1234', @user.registrant_ident - org = contacts(:acme_ltd) - org.ident_country_code = 'EE' - org.save(validate: false) - org.reload + contacts = [contacts(:john), contacts(:william), contacts(:identical_to_william), + contacts(:acme_ltd), contacts(:registrar_ltd)] - company_one = Company.new(org.ident, 'Acme Ltd') + contacts.each do |c| + if c.ident_type == 'priv' + c.ident = @user.ident + c.name = @user.username + else + c.ident_country_code = 'EE' + end + c.save(validate: false) + end - Spy.on(@user, :companies).and_return([company_one]) - response = @user.do_need_update_contact? - org.reload + company_one = Company.new(contacts(:acme_ltd).ident, 'Acme Ltd') + company_two = Company.new(contacts(:registrar_ltd).ident, 'Registrar Ltd') + + Spy.on(@user, :companies).and_return([company_one, company_two]) + response = @user.do_need_update_contacts? assert_equal response[:counter], 0 end - def test_should_return_count_of_contact_which_should_be_updated + def test_should_return_count_of_contacts_which_should_be_updated assert_equal 'US-1234', @user.registrant_ident - org = contacts(:acme_ltd) - org.ident_country_code = 'EE' - org.save(validate: false) - org.reload + contacts = [contacts(:john), contacts(:william), contacts(:identical_to_william), + contacts(:acme_ltd), contacts(:registrar_ltd)] + contacts.each do |c| + if c.ident_type == 'priv' + c.ident = @user.ident + else + c.ident_country_code = 'EE' + end + c.save(validate: false) + end - company_one = Company.new(org.ident, 'ace') - company_two = Company.new(org.ident, 'acer') + company_one = Company.new(contacts(:acme_ltd).ident, 'ace') + company_two = Company.new(contacts(:registrar_ltd).ident, 'acer') Spy.on(@user, :companies).and_return([company_one, company_two]) - response = @user.do_need_update_contact? - org.reload + response = @user.do_need_update_contacts? - assert_equal response[:counter], 2 + assert_equal response[:counter], 5 end def test_returns_contacts - Contact.stub(:registrant_user_contacts, %w(john jane)) do - assert_equal %w(john jane), @user.contacts + Contact.stub(:registrant_user_contacts, %w[john jane]) do + assert_equal %w[john jane], @user.contacts end end def test_returns_direct_contacts - Contact.stub(:registrant_user_direct_contacts, %w(john jane)) do - assert_equal %w(john jane), @user.direct_contacts + Contact.stub(:registrant_user_direct_contacts, %w[john jane]) do + assert_equal %w[john jane], @user.direct_contacts end end def test_returns_domains - Domain.stub(:registrant_user_domains, %w(shop airport)) do - assert_equal %w(shop airport), @user.domains + Domain.stub(:registrant_user_domains, %w[shop airport]) do + assert_equal %w[shop airport], @user.domains end end def test_returns_administered_domains - Domain.stub(:registrant_user_administered_domains, %w(shop airport)) do - assert_equal %w(shop airport), @user.administered_domains + Domain.stub(:registrant_user_administered_domains, %w[shop airport]) do + assert_equal %w[shop airport], @user.administered_domains end end end From b2bfc9412109ec733f6c9f18e99400e7518e6347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Tue, 29 Mar 2022 11:16:09 +0300 Subject: [PATCH 8/9] Refactoring due to codeclimate issues --- app/models/registrant_user.rb | 53 +++++++++++++---------- app/views/epp/poll/_extension.xml.builder | 9 ++-- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index 96fef635e..379fac25a 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -30,7 +30,7 @@ class RegistrantUser < User counter = 0 counter += Contact.with_different_registrant_name(self).size - + companies.each do |company| counter += Contact.with_different_company_name(company).size end @@ -43,32 +43,20 @@ class RegistrantUser < User def update_contacts user = self contacts = [] - contacts.concat Contact.with_different_registrant_name(user) - .each{ |c| c.write_attribute(:name, user.username) } + contacts.concat(Contact.with_different_registrant_name(user).each do |c| + c.write_attribute(:name, user.username) + end) companies.each do |company| - contacts.concat Contact.with_different_company_name(company) - .each{ |c| c.write_attribute(:name, company.company_name) } + contacts.concat(Contact.with_different_company_name(company).each do |c| + c.write_attribute(:name, company.company_name) + end) end - + return [] if contacts.blank? - grouped_contacts = contacts.group_by(&:registrar_id) - grouped_contacts.each do |registrar_id, contacts| - bulk_action, action = actions.create!(operation: :bulk_update) if contacts.size > 1 - contacts.each do |c| - if c.save(validate: false) - action = actions.create!(contact: c, operation: :update, bulk_action_id: bulk_action&.id) - end - end - notify_registrar_contacts_updated(action: bulk_action || action, - registrar_id: registrar_id) - end - contacts - end + group_and_bulk_update(contacts) - def notify_registrar_contacts_updated(action:, registrar_id:) - registrar = Registrar.find(registrar_id) - registrar.notify(action) if registrar + contacts end def contacts(representable: true) @@ -146,4 +134,25 @@ class RegistrantUser < User user end end + + private + + def group_and_bulk_update(contacts) + grouped_contacts = contacts.group_by(&:registrar_id) + grouped_contacts.each do |registrar_id, reg_contacts| + bulk_action, action = actions.create!(operation: :bulk_update) if reg_contacts.size > 1 + reg_contacts.each do |c| + if c.save(validate: false) + action = actions.create!(contact: c, operation: :update, bulk_action_id: bulk_action&.id) + end + end + notify_registrar_contacts_updated(action: bulk_action || action, + registrar_id: registrar_id) + end + end + + def notify_registrar_contacts_updated(action:, registrar_id:) + registrar = Registrar.find(registrar_id) + registrar&.notify(action) + end end diff --git a/app/views/epp/poll/_extension.xml.builder b/app/views/epp/poll/_extension.xml.builder index a26e3db8b..3682581c0 100644 --- a/app/views/epp/poll/_extension.xml.builder +++ b/app/views/epp/poll/_extension.xml.builder @@ -8,11 +8,12 @@ builder.extension do builder.tag!('changePoll:date', obj.created_at.utc.xmlschema) builder.tag!('changePoll:svTRID', obj.id) builder.tag!('changePoll:who', obj.user) - if obj.bulk_action? - builder.tag!('changePoll:reason', 'Auto-update according to official data') - end + builder.tag!( + 'changePoll:reason', + 'Auto-update according to official data' + ) if obj.bulk_action? when 'state' builder.tag!('changePoll:operation', obj) end end -end \ No newline at end of file +end From 140e5dc22e050ec3b267e1e7b66618eb67491993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergei=20Ts=C3=B5ganov?= Date: Tue, 29 Mar 2022 11:31:31 +0300 Subject: [PATCH 9/9] Fixed codeclimate issues --- app/models/registrant_user.rb | 8 ++++---- app/views/epp/poll/_extension.xml.builder | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index 379fac25a..073ab3214 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -40,6 +40,7 @@ class RegistrantUser < User { result: false, counter: 0 } end + # rubocop:disable Metrics/MethodLength def update_contacts user = self contacts = [] @@ -47,7 +48,7 @@ class RegistrantUser < User c.write_attribute(:name, user.username) end) companies.each do |company| - contacts.concat(Contact.with_different_company_name(company).each do |c| + contacts.concat(Contact.with_different_company_name(company).each do |c| c.write_attribute(:name, company.company_name) end) end @@ -55,9 +56,9 @@ class RegistrantUser < User return [] if contacts.blank? group_and_bulk_update(contacts) - contacts end + # rubocop:enable Metrics/MethodLength def contacts(representable: true) Contact.registrant_user_contacts(self, representable: representable) @@ -138,8 +139,7 @@ class RegistrantUser < User private def group_and_bulk_update(contacts) - grouped_contacts = contacts.group_by(&:registrar_id) - grouped_contacts.each do |registrar_id, reg_contacts| + contacts.group_by(&:registrar_id).each do |registrar_id, reg_contacts| bulk_action, action = actions.create!(operation: :bulk_update) if reg_contacts.size > 1 reg_contacts.each do |c| if c.save(validate: false) diff --git a/app/views/epp/poll/_extension.xml.builder b/app/views/epp/poll/_extension.xml.builder index 3682581c0..5a17995df 100644 --- a/app/views/epp/poll/_extension.xml.builder +++ b/app/views/epp/poll/_extension.xml.builder @@ -8,10 +8,12 @@ builder.extension do builder.tag!('changePoll:date', obj.created_at.utc.xmlschema) builder.tag!('changePoll:svTRID', obj.id) builder.tag!('changePoll:who', obj.user) - builder.tag!( - 'changePoll:reason', - 'Auto-update according to official data' - ) if obj.bulk_action? + if obj.bulk_action? + builder.tag!( + 'changePoll:reason', + 'Auto-update according to official data' + ) + end when 'state' builder.tag!('changePoll:operation', obj) end