diff --git a/.codeclimate.yml b/.codeclimate.yml
index 03f849185..21ab3742c 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -27,6 +27,7 @@ engines:
- HACK
rubocop:
enabled: true
+ channel: rubocop-0-51
reek:
enabled: true
checks:
diff --git a/.reek b/.reek
index d94291666..060f76785 100644
--- a/.reek
+++ b/.reek
@@ -1,3 +1,1171 @@
exclude_paths:
- db/migrate/
- db/data/
+UncommunicativeModuleName:
+ exclude:
+ - Repp::AccountV1
+ - Repp::ContactV1
+ - Repp::DomainV1
+UncommunicativeVariableName:
+ exclude:
+ - Repp::DomainV1
+ - Admin::AccountActivitiesController
+ - Admin::AdminUsersController
+ - Admin::ApiUsersController
+ - Admin::BankStatementsController
+ - Admin::Billing::PricesController
+ - Admin::BlockedDomainsController
+ - Admin::ContactVersionsController
+ - Admin::ContactVersionsController#index
+ - Admin::ContactsController
+ - Admin::DomainVersionsController
+ - Admin::DomainVersionsController#index
+ - Admin::DomainsController
+ - Admin::DomainsController#build_associations
+ - Admin::EppLogsController
+ - Admin::InvoicesController
+ - Admin::InvoicesController#create
+ - Admin::KeyrelaysController
+ - Admin::MailTemplatesController
+ - Admin::RegistrarsController
+ - Admin::ReppLogsController
+ - Admin::ReservedDomainsController
+ - Admin::SettingsController#casted_settings
+ - Admin::SettingsController#create
+ - Epp::DomainsController#renew
+ - Epp::DomainsController#update
+ - Epp::SessionsController#connection_limit_ok?
+ - Epp::SessionsController#login
+ - EppController
+ - EppController#create_full_selectors
+ - EppController#optional
+ - EppController#xml_attrs_present?
+ - Registrant::DomainsController
+ - Registrar::AccountActivitiesController
+ - Registrar::ContactsController
+ - Registrar::ContactsController#download_list
+ - Registrar::ContactsController#index
+ - Registrar::DeppController#response_ok?
+ - Registrar::DomainsController
+ - Registrar::DomainsController#index
+ - Registrar::DomainsController#search_contacts
+ - Registrar::InvoicesController
+ - ContactMailer#email_updated
+ - Ability#billing
+ - Ability#epp
+ - AccountActivity#to_csv
+ - AccountActivity#types_for_select
+ - ApiUser#api_pki_ok?
+ - ApiUser#registrar_pki_ok?
+ - BankLink::Request#calc_mac
+ - BankLink::Response#validate_cancel
+ - BankLink::Response#validate_success
+ - BankStatement#import_th6_file
+ - BlockedDomain#generate_json
+ - Concerns::Domain::ForceDelete#cancel_force_delete
+ - EppErrors#add_epp_error
+ - EppErrors#collect_child_errors
+ - EppErrors#find_epp_code_and_value
+ - Versions::ClassMethods#all_versions_for
+ - Contact
+ - Contact#all_domains
+ - Contact#all_registrant_domains
+ - Contact#manage_emails
+ - Contact#search_by_query
+ - Contact#status_notes_array=
+ - Depp::Contact#construct_create_disclosure_xml
+ - Depp::Contact#extract_disclosure_hash
+ - Depp::Contact#extract_info_disclosure
+ - Depp::Contact#find_by_id
+ - Depp::Contact#handle_errors
+ - Depp::Contact#type_string
+ - Depp::Domain#construct_params_from_server_data
+ - Depp::Domain#create_contacts_hash
+ - Depp::Domain#create_dnskeys_hash
+ - Depp::Domain#create_nameservers_hash
+ - Depp::Domain#default_params
+ - Depp::User#initialize
+ - Depp::User#request
+ - Depp::User#validate_existance_in_server
+ - Directo#self.send_monthly_invoices
+ - DNS::Zone#self.generate_zonefile
+ - Dnskey#bin_to_hex
+ - Dnskey#generate_ds_key_tag
+ - Dnskey#int_to_hex
+ - Domain#admin_status_update
+ - Domain#delegated_nameservers
+ - Domain#name_in_wire_format
+ - Domain#parent_valid?
+ - Domain#status_notes_array=
+ - Domain#subordinate_nameservers
+ - DomainCron#self.destroy_delete_candidates
+ - DomainMailModel#admins
+ - Epp::Contact#attrs_from
+ - Epp::Contact#check_availability
+ - Epp::Domain#check_availability
+ - Epp::Domain#copy_and_transfer_contact
+ - Epp::Domain#domain_contact_attrs_from
+ - Epp::Domain#domain_status_list_from
+ - Epp::Domain#domain_statuses_attrs
+ - Epp::Domain#nameservers_from
+ - Epp::Domain#parse_period_unit_from_frame
+ - Epp::Domain#transfer_domain_contacts
+ - Epp::Domain#validate_contacts
+ - Invoice#cancel_overdue_invoices
+ - Legacy::Db
+ - LegalDocument#save_to_filesystem
+ - Nameserver#replace_hostname_ends
+ - RegistrantUser#find_or_create_by_idc_data
+ - RegistrantUser#find_or_create_by_mid_data
+ - Registrar
+ - Registrar#search_by_query
+ - ReservedDomain#generate_json
+ - WhoisRecord#generate_json
+ - UniquenessMultiValidator#validate_each
+ - Registry::Application
+ - ActiveRecord::Base
+ - Ransack::Adapters::ActiveRecord::Context#evaluate
+ - EppConstraint#matches?
+ - Iptable#counter_update
+DuplicateMethodCall:
+ exclude:
+ - Admin::AccountActivitiesController#index
+ - Admin::AccountActivitiesController#set_default_dates
+ - Admin::AdminUsersController#update
+ - Admin::ApiUsersController#update
+ - Admin::BankStatementsController#download_import_file
+ - Admin::Billing::PricesController#index
+ - Admin::BlockedDomainsController#delete
+ - Admin::BlockedDomainsController#index
+ - Admin::CertificatesController#create
+ - Admin::CertificatesController#set_certificate
+ - Admin::ContactVersionsController#index
+ - Admin::ContactVersionsController#show
+ - Admin::ContactsController#index
+ - Admin::ContactsController#normalize_search_parameters
+ - Admin::DomainVersionsController#index
+ - Admin::DomainVersionsController#show
+ - Admin::DomainsController#build_associations
+ - Admin::DomainsController#index
+ - Admin::DomainsController#normalize_search_parameters
+ - Admin::DomainsController#schedule_force_delete
+ - Admin::EppLogsController#index
+ - Admin::EppLogsController#set_default_dates
+ - Admin::LegalDocumentsController#show
+ - Admin::PendingDeletesController#destroy
+ - Admin::PendingDeletesController#update
+ - Admin::PendingUpdatesController#destroy
+ - Admin::PendingUpdatesController#update
+ - Admin::ReppLogsController#index
+ - Admin::ReppLogsController#set_default_dates
+ - Admin::ReservedDomainsController#delete
+ - Admin::ReservedDomainsController#index
+ - Admin::SessionsController#create
+ - Admin::SettingsController#casted_settings
+ - Admin::ZonefilesController#create
+ - ApplicationController#comma_support_for
+ - Epp::ContactsController#validate_create
+ - Epp::DomainsController#create
+ - Epp::DomainsController#delete
+ - Epp::DomainsController#renew
+ - Epp::DomainsController#transfer
+ - Epp::DomainsController#update
+ - Epp::KeyrelaysController#keyrelay
+ - Epp::PollsController#ack_poll
+ - Epp::PollsController#poll
+ - Epp::PollsController#req_poll
+ - Epp::SessionsController#connection_limit_ok?
+ - Epp::SessionsController#ip_white?
+ - Epp::SessionsController#login
+ - Epp::SessionsController#login_params
+ - EppController#current_user
+ - EppController#handle_errors
+ - EppController#iptables_counter_update
+ - EppController#latin_only
+ - EppController#optional
+ - EppController#update_epp_session
+ - EppController#write_to_epp_log
+ - Registrant::DomainDeleteConfirmsController#update
+ - Registrant::DomainUpdateConfirmsController#update
+ - Registrant::DomainsController#domain_verification_url
+ - Registrant::DomainsController#download_list
+ - Registrant::DomainsController#get_confirm_path
+ - Registrant::DomainsController#index
+ - Registrant::DomainsController#normalize_search_parameters
+ - Registrant::SessionsController#id
+ - Registrant::SessionsController#mid
+ - Registrant::SessionsController#mid_status
+ - Registrant::WhoisController#index
+ - Registrar::AccountActivitiesController#index
+ - Registrar::BaseController#check_ip
+ - Registrar::ContactsController#download_list
+ - Registrar::ContactsController#index
+ - Registrar::ContactsController#normalize_search_parameters
+ - Registrar::ContactsController#update
+ - Registrar::DomainsController#check
+ - Registrar::DomainsController#destroy
+ - Registrar::DomainsController#index
+ - Registrar::DomainsController#info
+ - Registrar::DomainsController#normalize_search_parameters
+ - Registrar::DomainsController#renew
+ - Registrar::DomainsController#search_contacts
+ - Registrar::DomainsController#transfer
+ - Registrar::DomainsController#update
+ - Registrar::InvoicesController#index
+ - Registrar::InvoicesController#normalize_search_parameters
+ - Registrar::PaymentsController#back
+ - Registrar::SessionsController#create
+ - Registrar::SessionsController#mid
+ - Registrar::SessionsController#mid_status
+ - ApplicationHelper#changing_css_class
+ - ApplicationHelper#creator_link
+ - ApplicationHelper#custom_sort_link
+ - ApplicationHelper#unstable_env
+ - ApplicationHelper#updator_link
+ - Registrant::ApplicationHelper#pagination_details
+ - Registrar::ApplicationHelper#pagination_details
+ - DomainDeleteConfirmJob#raise_errors!
+ - DomainDeleteConfirmJob#run
+ - DomainUpdateConfirmJob#raise_errors!
+ - DomainUpdateConfirmJob#run
+ - UpdateWhoisRecordJob#update_domain
+ - ApplicationMailer#whitelist_blocked?
+ - DomainExpireMailer#expired
+ - DomainMailer#compose_from
+ - DomainMailer#delete_confirmation
+ - DomainMailer#pending_delete_expired_notification
+ - DomainMailer#pending_delete_rejected_notification
+ - InvoiceMailer#invoice_email
+ - Ability#epp
+ - Ability#initialize
+ - BankLink::Request#fields
+ - BankLink::Response#initialize
+ - BankStatement#import_th6_file
+ - BankStatement#parse_th6_row
+ - BankStatement#status
+ - Billing::Price#self.effective
+ - Billing::Price#self.valid
+ - BusinessRegistryCache#fetch_by_ident_and_cc
+ - BusinessRegistryCache#purge
+ - Certificate#parse_metadata
+ - Certificate#reload_apache
+ - Certificate#revoke!
+ - Certificate#status
+ - Certificate#update_id_crl
+ - Certificate#update_registry_crl
+ - EppErrors#add_epp_error
+ - UserEvents#cr_id
+ - Versions#user_from_id_role_username
+ - Versions::ClassMethods#all_versions_for
+ - Contact#all_domains
+ - Contact#all_registrant_domains
+ - Contact#destroy_orphans
+ - Contact#domain_names_with_roles
+ - Contact#generate_code
+ - Contact#related_domain_descriptions
+ - Contact#val_ident_valid_format?
+ - Deposit#validate_amount
+ - Depp::Contact#construct_check_hash_from_data
+ - Depp::Contact#construct_create_disclosure_xml
+ - Depp::Contact#extension_xml
+ - Depp::Contact#extract_info_disclosure
+ - Depp::Contact#find_by_id
+ - Depp::Contact#new_from_params
+ - Depp::Contact#update_attributes
+ - Depp::Domain#confirm_transfer
+ - Depp::Domain#construct_custom_params_hash
+ - Depp::Domain#construct_edit_hash
+ - Depp::Domain#construct_ext_edit_hash
+ - Depp::Domain#construct_params_from_server_data
+ - Depp::Domain#create
+ - Depp::Domain#create_contacts_hash
+ - Depp::Domain#create_dnskeys_hash
+ - Depp::Domain#create_key_data_hash
+ - Depp::Domain#create_nameservers_hash
+ - Depp::Domain#default_params
+ - Depp::Domain#renew
+ - Depp::Keyrelay#keyrelay
+ - Depp::User#repp_request
+ - Depp::User#validate_existance_in_server
+ - Directo#self.dump_result_to_db
+ - Directo#self.load_price
+ - Directo#self.send_monthly_invoices
+ - Directo#self.send_receipts
+ - DNS::Zone#self.generate_zonefile
+ - Dnskey#generate_digest
+ - Domain#manage_automatic_statuses
+ - Domain#parent_valid?
+ - Domain#pending_registrant
+ - Domain#renewable?
+ - Domain#set_graceful_expired
+ - DomainCron#self.clean_expired_pendings
+ - DomainCron#self.delete_legal_doc_duplicates
+ - DomainCron#self.destroy_delete_candidates
+ - DomainCron#self.start_expire_period
+ - DomainCron#self.start_redemption_grace_period
+ - DomainMailModel#registrant_pending
+ - DomainMailModel#subject
+ - DomainMailModel#verification_token
+ - Epp::Contact#attrs_from
+ - Epp::Contact#legal_document_attrs
+ - Epp::Contact#status_list_from
+ - Epp::Contact#update_attributes
+ - Epp::Domain#apply_pending_update!
+ - Epp::Domain#attrs_from
+ - Epp::Domain#dnskeys_attrs
+ - Epp::Domain#domain_contact_attrs_from
+ - Epp::Domain#domain_status_list_from
+ - Epp::Domain#new_from_epp
+ - Epp::Domain#parse_legal_document_from_frame
+ - Epp::Domain#query_transfer
+ - Epp::Domain#renew
+ - Epp::Domain#transfer_domain_contacts
+ - Epp::Domain#update
+ - Epp::Domain#validate_contacts
+ - Epp::Domain#validate_exp_dates
+ - Invoice#cancel_overdue_invoices
+ - Invoice#set_invoice_number
+ - LegalDocument#save_to_filesystem
+ - LegalDocument#self.remove_duplicates
+ - Nameserver#replace_hostname_ends
+ - Setting#self.params_errors
+ - Setting#self.reload_settings!
+ - Soap::Arireg#associated_businesses
+ - Soap::Arireg#body
+ - Soap::Arireg#debug
+ - Soap::Arireg#initialize
+ - WhoisRecord#generate_json
+ - DomainPresenter#delete_date
+ - DomainPresenter#force_delete_date
+ - DomainPresenter#on_hold_date
+ - DomainNameValidator#validate_each
+ - DomainNameValidator#validate_format
+ - DurationIso8601Validator#validate_each
+ - UniquenessMultiValidator#validate_each
+ - ActionView::Helpers::FormBuilder#label
+ - ActionDispatch::Flash#call
+ - Rack::Request#trusted_proxy?
+ - Ransack::Adapters::ActiveRecord::Context#evaluate
+ - DeviseCustomFailure#redirect_url
+ - EppConstraint#matches?
+ - PhoneValidator#validate_each
+InstanceVariableAssumption:
+ exclude:
+ - Admin::AccountActivitiesController
+ - Admin::AdminUsersController
+ - Admin::ApiUsersController
+ - Admin::BankStatementsController
+ - Admin::BankTransactionsController
+ - Admin::Billing::PricesController
+ - Admin::BlockedDomainsController
+ - Admin::CertificatesController
+ - Admin::ContactVersionsController
+ - Admin::ContactsController
+ - Admin::DNS::ZonesController
+ - Admin::DomainVersionsController
+ - Admin::DomainsController
+ - Admin::EppLogsController
+ - Admin::InvoicesController
+ - Admin::KeyrelaysController
+ - Admin::LegalDocumentsController
+ - Admin::MailTemplatesController
+ - Admin::PendingDeletesController
+ - Admin::PendingUpdatesController
+ - Admin::RegistrarsController
+ - Admin::ReppLogsController
+ - Admin::ReservedDomainsController
+ - Admin::SessionsController
+ - Admin::SettingsController
+ - Admin::WhiteIpsController
+ - Admin::ZonefilesController
+ - Epp::ContactsController
+ - Epp::DomainsController
+ - Epp::KeyrelaysController
+ - Epp::PollsController
+ - Epp::SessionsController
+ - EppController
+ - Registrant::ContactsController
+ - Registrant::DomainDeleteConfirmsController
+ - Registrant::DomainUpdateConfirmsController
+ - Registrant::DomainsController
+ - Registrant::RegistrarsController
+ - Registrant::SessionsController
+ - Registrar::AccountActivitiesController
+ - Registrar::ContactsController
+ - Registrar::DepositsController
+ - Registrar::DeppController
+ - Registrar::DomainsController
+ - Registrar::InvoicesController
+ - Registrar::PaymentsController
+ - Registrar::PollsController
+ - Registrar::SessionsController
+ - DefaultFormBuilder
+ - ContactMailer
+ - DomainMailer
+ - InvoiceMailer
+ - ApiUser
+ - BankTransaction
+ - Certificate
+ - Contact
+ - Deposit
+ - Depp::Contact
+ - Domain
+ - DomainContact
+ - WhoisRecord
+ - ActiveModel::Errors
+ - ActionDispatch::Flash
+ - Ransack::Adapters::ActiveRecord::Context
+IrresponsibleModule:
+ exclude:
+ - Admin::AccountActivitiesController
+ - Admin::AdminUsersController
+ - Admin::ApiUsersController
+ - Admin::BankStatementsController
+ - Admin::BankTransactionsController
+ - Admin::Billing::PricesController
+ - Admin::BlockedDomainsController
+ - Admin::CertificatesController
+ - Admin::ContactVersionsController
+ - Admin::ContactsController
+ - Admin::DashboardsController
+ - Admin::DelayedJobsController
+ - Admin::DNS::ZonesController
+ - Admin::DomainVersionsController
+ - Admin::DomainsController
+ - Admin::EppLogsController
+ - Admin::InvoicesController
+ - Admin::KeyrelaysController
+ - Admin::LegalDocumentsController
+ - Admin::MailTemplatesController
+ - Admin::PendingDeletesController
+ - Admin::PendingUpdatesController
+ - Admin::RegistrarsController
+ - Admin::ReppLogsController
+ - Admin::ReservedDomainsController
+ - Admin::SessionsController
+ - Admin::SettingsController
+ - Admin::WhiteIpsController
+ - Admin::ZonefilesController
+ - AdminController
+ - ApplicationController
+ - Epp::ContactsController
+ - Epp::DomainsController
+ - Epp::ErrorsController
+ - Epp::KeyrelaysController
+ - Epp::PollsController
+ - Epp::SessionsController
+ - EppController
+ - Registrant::ContactsController
+ - Registrant::DomainDeleteConfirmsController
+ - Registrant::DomainUpdateConfirmsController
+ - Registrant::DomainsController
+ - Registrant::RegistrarsController
+ - Registrant::SessionsController
+ - Registrant::WhoisController
+ - RegistrantController
+ - Registrar::AccountActivitiesController
+ - Registrar::BaseController
+ - Registrar::ContactsController
+ - Registrar::DashboardController
+ - Registrar::DepositsController
+ - Registrar::DeppController
+ - Registrar::DomainsController
+ - Registrar::InvoicesController
+ - Registrar::KeyrelaysController
+ - Registrar::PaymentsController
+ - Registrar::PollsController
+ - Registrar::SessionsController
+ - Registrar::XmlConsolesController
+ - ApplicationHelper
+ - DefaultFormBuilder
+ - FormHelper
+ - FormTagHelper
+ - Registrant::ApplicationHelper
+ - Registrar::ApplicationHelper
+ - DomainDeleteConfirmEmailJob
+ - DomainDeleteConfirmJob
+ - DomainDeleteForcedEmailJob
+ - DomainDeleteJob
+ - DomainExpireEmailJob
+ - DomainUpdateConfirmJob
+ - RegenerateRegistrarWhoisesJob
+ - RegistrantChangeConfirmEmailJob
+ - RegistrantChangeExpiredEmailJob
+ - RegistrantChangeNoticeEmailJob
+ - UpdateWhoisRecordJob
+ - ApplicationMailer
+ - ContactMailer
+ - DomainDeleteMailer
+ - DomainExpireMailer
+ - DomainMailer
+ - InvoiceMailer
+ - RegistrantChangeMailer
+ - Ability
+ - Account
+ - AccountActivity
+ - AdminDomainContact
+ - AdminUser
+ - ApiLog::EppLog
+ - ApiLog::ReppLog
+ - ApiUser
+ - BankLink::Base
+ - BankLink::Request
+ - BankLink::Response
+ - BankStatement
+ - BankTransaction
+ - Billing::Price
+ - Billing
+ - BlockedDomain
+ - Certificate
+ - Concerns::Billing::Price::Expirable
+ - DisableHtml5Validation
+ - Concerns::Domain::Activatable
+ - Concerns::Domain::Deletable
+ - Concerns::Domain::Expirable
+ - Concerns::Domain::ForceDelete
+ - EppErrors
+ - UserEvents
+ - VersionSession
+ - Versions::ClassMethods
+ - Contact
+ - Counter
+ - Deposit
+ - Depp::Contact
+ - Depp::Domain
+ - Depp::Keyrelay
+ - Depp::User
+ - Directo
+ - DNS::Zone
+ - DNS
+ - Dnskey
+ - DomainContact
+ - DomainCron
+ - DomainMailModel
+ - DomainStatus
+ - DomainTransfer
+ - Epp::Contact
+ - EppSession
+ - Invoice
+ - InvoiceItem
+ - Keyrelay
+ - Legacy::Db
+ - Legacy::Object
+ - Legacy::ObjectHistory
+ - Legacy::ObjectState
+ - Legacy::Registrar
+ - LegalDocument
+ - Message
+ - Nameserver
+ - Registrant
+ - RegistrantUser
+ - Registrar
+ - ReservedDomain
+ - Setting
+ - Soap::Arireg
+ - Soap::Arireg::NotAvailableError
+ - TechDomainContact
+ - User
+ - WhiteIp
+ - WhoisRecord
+ - DomainPresenter
+ - RegistrantPresenter
+ - Registrar::DomainListCSVPresenter
+ - RegistrarPresenter
+ - RegistrantChange
+ - DateTimeIso8601Validator
+ - DomainNameValidator
+ - DomainNameserverValidator
+ - DurationIso8601Validator
+ - ObjectCountValidator
+ - UniquenessMultiValidator
+ - PaperSession
+ - Array
+ - ActionView::Helpers::FormBuilder
+ - ActiveModel::Errors
+ - ActionDispatch::Flash
+ - Rack::Request
+ - Ransack::Adapters::ActiveRecord::Context
+ - DeviseCustomFailure
+ - EppConstraint
+ - Builder::XmlMarkup
+ - VersionGenerator
+ - Iptable
+ - SortedCountry
+ - EmailValidator
+ - PhoneValidator
+ - FakeDeppContact
+ - Features::SessionHelpers
+ - CapybaraViewMacros
+ - Matchers::EPP::Code
+ - Requests::EPPHelpers
+ - Requests::SessionHelpers
+NilCheck:
+ exclude:
+ - Admin::AccountActivitiesController#set_default_dates
+ - Admin::EppLogsController#set_default_dates
+ - Admin::ReppLogsController#set_default_dates
+ - ApplicationController#user_log_str
+ - EppController#requires
+ - ApplicationHelper#env_style
+ - Registrant::ApplicationHelper#env_style
+ - Registrar::ApplicationHelper#env_style
+ - UserEvents#cr_id
+ - Depp::Contact#handle_errors
+ - Directo#self.send_receipts
+ - DomainMailModel#format
+ - LegalDocument#val_body_length
+ - Soap::Arireg#body
+ - Soap::Arireg#country_code_3
+ - Soap::Arireg#initialize
+ - ActionDispatch::Flash#call
+TooManyStatements:
+ exclude:
+ - initialize
+ - Admin::AccountActivitiesController#index
+ - Admin::AdminUsersController#update
+ - Admin::BankTransactionsController#create
+ - Admin::Billing::PricesController#index
+ - Admin::CertificatesController#create
+ - Admin::ContactVersionsController#index
+ - Admin::ContactVersionsController#show
+ - Admin::ContactsController#index
+ - Admin::ContactsController#normalize_search_parameters
+ - Admin::DomainVersionsController#index
+ - Admin::DomainVersionsController#show
+ - Admin::DomainsController#index
+ - Admin::DomainsController#normalize_search_parameters
+ - Admin::DomainsController#schedule_force_delete
+ - Admin::DomainsController#update
+ - Admin::EppLogsController#index
+ - Admin::InvoicesController#create
+ - Admin::InvoicesController#forward
+ - Admin::RegistrarsController#create
+ - Admin::ReppLogsController#index
+ - Admin::SessionsController#create
+ - Admin::SettingsController#casted_settings
+ - Admin::SettingsController#create
+ - Admin::WhiteIpsController#create
+ - Epp::ContactsController#create
+ - Epp::ContactsController#update
+ - Epp::ContactsController#validate_create
+ - Epp::ContactsController#validate_update
+ - Epp::DomainsController#balance_ok?
+ - Epp::DomainsController#create
+ - Epp::DomainsController#delete
+ - Epp::DomainsController#info
+ - Epp::DomainsController#renew
+ - Epp::DomainsController#transfer
+ - Epp::DomainsController#update
+ - Epp::DomainsController#validate_create
+ - Epp::DomainsController#validate_transfer
+ - Epp::PollsController#req_poll
+ - Epp::SessionsController#login
+ - EppController#catch_epp_errors
+ - EppController#element_count
+ - EppController#handle_errors
+ - EppController#optional
+ - EppController#optional_attribute
+ - EppController#requires
+ - EppController#requires_attribute
+ - EppController#update_epp_session
+ - EppController#validate_request
+ - EppController#write_to_epp_log
+ - Registrant::DomainDeleteConfirmsController#update
+ - Registrant::DomainUpdateConfirmsController#update
+ - Registrant::DomainsController#domain_verification_url
+ - Registrant::DomainsController#domains
+ - Registrant::DomainsController#download_list
+ - Registrant::DomainsController#index
+ - Registrant::DomainsController#normalize_search_parameters
+ - Registrant::SessionsController#id
+ - Registrant::SessionsController#mid
+ - Registrant::SessionsController#mid_status
+ - Registrar::AccountActivitiesController#index
+ - Registrar::BaseController#check_ip
+ - Registrar::ContactsController#download_list
+ - Registrar::ContactsController#index
+ - Registrar::ContactsController#normalize_search_parameters
+ - Registrar::DepositsController#create
+ - Registrar::DomainsController#destroy
+ - Registrar::DomainsController#index
+ - Registrar::DomainsController#normalize_search_parameters
+ - Registrar::DomainsController#search_contacts
+ - Registrar::DomainsController#update
+ - Registrar::InvoicesController#forward
+ - Registrar::InvoicesController#index
+ - Registrar::InvoicesController#normalize_search_parameters
+ - Registrar::KeyrelaysController#create
+ - Registrar::PaymentsController#back
+ - Registrar::SessionsController#create
+ - Registrar::SessionsController#mid
+ - Registrar::SessionsController#mid_status
+ - ApplicationHelper#ident_for
+ - DomainDeleteConfirmJob#run
+ - DomainDeleteJob#run
+ - DomainUpdateConfirmJob#run
+ - UpdateWhoisRecordJob#run
+ - ApplicationMailer#whitelist_blocked?
+ - ContactMailer#email_updated
+ - DomainDeleteMailer#forced
+ - DomainExpireMailer#expired
+ - DomainMailer#compose_from
+ - DomainMailer#pending_delete_rejected_notification
+ - InvoiceMailer#invoice_email
+ - RegistrantChangeMailer#confirm
+ - RegistrantChangeMailer#notice
+ - Ability#admin
+ - Ability#epp
+ - AccountActivity#to_csv
+ - ApiUser#api_pki_ok?
+ - ApiUser#registrar_pki_ok?
+ - BankLink::Request#fields
+ - BankLink::Response#complete_payment
+ - BankStatement#import_th6_file
+ - BankTransaction#autobind_invoice
+ - BankTransaction#bind_invoice
+ - BusinessRegistryCache#fetch_by_ident_and_cc
+ - Certificate#parse_md_from_string
+ - Certificate#parse_metadata
+ - Certificate#revoke!
+ - Certificate#sign!
+ - Certificate#status
+ - Concerns::Domain::ForceDelete#cancel_force_delete
+ - Concerns::Domain::ForceDelete#schedule_force_delete
+ - EppErrors#add_epp_error
+ - EppErrors#collect_child_errors
+ - EppErrors#collect_parent_errors
+ - EppErrors#construct_epp_errors
+ - EppErrors#construct_msg_args_and_value
+ - EppErrors#find_epp_code_and_value
+ - UserEvents#cr_id
+ - Versions::ClassMethods#all_versions_for
+ - Contact#all_domains
+ - Contact#all_registrant_domains
+ - Contact#destroy_and_clean
+ - Contact#destroy_orphans
+ - Contact#domain_names_with_roles
+ - Contact#filter_by_states
+ - Contact#generate_code
+ - Contact#manage_emails
+ - Contact#related_domain_descriptions
+ - Contact#statuses
+ - Contact#validate_html
+ - Depp::Contact#construct_check_hash_from_data
+ - Depp::Contact#construct_create_disclosure_xml
+ - Depp::Contact#extension_xml
+ - Depp::Contact#extract_info_disclosure
+ - Depp::Contact#handle_errors
+ - Depp::Contact#save
+ - Depp::Contact#update_attributes
+ - Depp::Domain#construct_edit_hash
+ - Depp::Domain#construct_ext_edit_hash
+ - Depp::Domain#construct_params_from_server_data
+ - Depp::Domain#create
+ - Depp::Domain#create_dnskeys_hash
+ - Depp::Domain#create_nameservers_hash
+ - Depp::Domain#default_params
+ - Depp::Domain#transfer
+ - Depp::User#repp_request
+ - Depp::User#validate_existance_in_server
+ - Directo#self.send_monthly_invoices
+ - Directo#self.send_receipts
+ - DNS::Zone#self.generate_zonefile
+ - Dnskey#generate_digest
+ - Dnskey#generate_ds_key_tag
+ - Domain#children_log
+ - Domain#clean_pendings!
+ - Domain#clean_pendings_lowlevel
+ - Domain#manage_automatic_statuses
+ - Domain#name_in_wire_format
+ - Domain#pending_delete!
+ - Domain#pending_update!
+ - Domain#pricelist
+ - DomainCron#self.clean_expired_pendings
+ - DomainCron#self.destroy_delete_candidates
+ - DomainCron#self.start_expire_period
+ - DomainCron#self.start_redemption_grace_period
+ - DomainMailModel#domain_info
+ - DomainTransfer#approve_as_client
+ - Epp::Contact#add_legal_file_to_new
+ - Epp::Contact#attrs_from
+ - Epp::Contact#check_availability
+ - Epp::Contact#status_list_from
+ - Epp::Contact#statuses_attrs
+ - Epp::Contact#update_attributes
+ - Epp::Domain#add_legal_file_to_new
+ - Epp::Domain#apply_pending_delete!
+ - Epp::Domain#apply_pending_update!
+ - Epp::Domain#approve_transfer
+ - Epp::Domain#attrs_from
+ - Epp::Domain#check_availability
+ - Epp::Domain#copy_and_transfer_contact
+ - Epp::Domain#destroy_attrs
+ - Epp::Domain#dnskeys_attrs
+ - Epp::Domain#domain_contact_attrs_from
+ - Epp::Domain#domain_status_list_from
+ - Epp::Domain#domain_statuses_attrs
+ - Epp::Domain#epp_destroy
+ - Epp::Domain#keyrelay
+ - Epp::Domain#manage_permissions
+ - Epp::Domain#nameservers_attrs
+ - Epp::Domain#nameservers_from
+ - Epp::Domain#new_from_epp
+ - Epp::Domain#query_transfer
+ - Epp::Domain#reject_transfer
+ - Epp::Domain#renew
+ - Epp::Domain#transfer
+ - Epp::Domain#transfer_domain_contacts
+ - Epp::Domain#update
+ - Epp::Domain#validate_contacts
+ - Invoice#cancel
+ - Invoice#cancel_overdue_invoices
+ - Invoice#set_invoice_number
+ - LegalDocument#save_to_filesystem
+ - LegalDocument#self.remove_duplicates
+ - Nameserver#replace_hostname_ends
+ - RegistrantUser#find_or_create_by_idc_data
+ - Registrar#generate_iso_11649_reference_no
+ - Soap::Arireg#associated_businesses
+ - WhoisRecord#generate_json
+ - Registrar::DomainListCSVPresenter#domain_to_row
+ - DomainNameValidator#validate_format
+ - DomainNameserverValidator#validate_each
+ - DurationIso8601Validator#validate
+ - UniquenessMultiValidator#validate_each
+ - ActionDispatch::Flash#call
+ - Ransack::Adapters::ActiveRecord::Context#evaluate
+ - EppConstraint#matches?
+ - Iptable#counter_update
+ - fill_form
+TooManyInstanceVariables:
+ exclude:
+ - Admin::BankStatementsController
+ - Admin::DomainsController
+ - Admin::MailTemplatesController
+ - Epp::ContactsController
+ - Epp::DomainsController
+ - EppController
+ - Registrar::DomainsController
+ - DomainDeleteMailer
+ - RegistrantChangeMailer
+UtilityFunction:
+ exclude:
+ - Admin::Billing::PricesController#durations
+ - Admin::Billing::PricesController#operation_categories
+ - Admin::Billing::PricesController#statuses
+ - Admin::Billing::PricesController#zones
+ - ApplicationController#user_log_str
+ - Epp::ContactsController#address_processing?
+ - EppController#has_attribute
+ - Registrant::DomainsController#get_confirm_path
+ - Registrant::SessionsController#find_user_by_idc
+ - Registrar::ContactsController#address_processing?
+ - Registrar::PaymentsController#banks
+ - Registrar::SessionsController#find_user_by_idc
+ - ApplicationHelper#changing_css_class
+ - ApplicationHelper#ident_for
+ - ApplicationHelper#legal_document_types
+ - ApplicationHelper#plain_username
+ - ApplicationHelper#unstable_env
+ - DomainDeleteConfirmEmailJob#logger
+ - DomainDeleteForcedEmailJob#logger
+ - DomainExpireEmailJob#run
+ - RegenerateRegistrarWhoisesJob#run
+ - RegistrantChangeConfirmEmailJob#logger
+ - RegistrantChangeExpiredEmailJob#logger
+ - RegistrantChangeNoticeEmailJob#logger
+ - UpdateWhoisRecordJob#delete_domain
+ - UpdateWhoisRecordJob#delete_reserved
+ - UpdateWhoisRecordJob#update_domain
+ - UpdateWhoisRecordJob#update_reserved
+ - ApplicationMailer#format
+ - ContactMailer#address_processing
+ - RegistrantChangeMailer#address_processing
+ - EppErrors#construct_msg_args_and_value
+ - Versions#user_from_id_role_username
+ - Depp::Keyrelay#expiry
+ - Epp::Domain#copy_and_transfer_contact
+ - Epp::Domain#nameservers_from
+ - Epp::Domain::DnsSecKeys#mark
+ - Epp::Domain::DnsSecKeys#xm_copy
+ - Invoice#pdf
+ - Soap::Arireg#extract
+ - Soap::Arireg#items
+ - Registrar::DomainListCSVPresenter#domain_to_row
+ - Rack::Request#trusted_proxy?
+ - PhoneValidator#zeros_only?
+ - Requests::EPPHelpers#have_code_of
+ - Requests::EPPHelpers#valid_legal_document
+FeatureEnvy:
+ exclude:
+ - Admin::SettingsController#casted_settings
+ - ApplicationHelper#creator_link
+ - ApplicationHelper#updator_link
+ - FormHelper#legal_document_field
+ - FormHelper#money_field
+ - FormTagHelper#legal_document_field_tag
+ - DomainDeleteConfirmEmailJob#log
+ - DomainDeleteConfirmEmailJob#run
+ - DomainDeleteConfirmJob#raise_errors!
+ - DomainDeleteConfirmJob#run
+ - DomainDeleteForcedEmailJob#log
+ - DomainDeleteForcedEmailJob#run
+ - DomainDeleteJob#run
+ - DomainUpdateConfirmJob#raise_errors!
+ - DomainUpdateConfirmJob#run
+ - RegistrantChangeConfirmEmailJob#log
+ - RegistrantChangeConfirmEmailJob#run
+ - RegistrantChangeExpiredEmailJob#log
+ - RegistrantChangeExpiredEmailJob#run
+ - RegistrantChangeNoticeEmailJob#log
+ - RegistrantChangeNoticeEmailJob#run
+ - ApplicationMailer#whitelist_blocked?
+ - DomainExpireMailer#filter_invalid_emails
+ - AccountActivity#to_csv
+ - ApiUser#api_pki_ok?
+ - ApiUser#find_by_idc_data
+ - ApiUser#registrar_pki_ok?
+ - BankLink::Base#prepend_size
+ - BankLink::Request#fields
+ - BankStatement#parse_th6_row
+ - BusinessRegistryCache#fetch_by_ident_and_cc
+ - EppErrors#collect_parent_errors
+ - Contact#all_domains
+ - Contact#all_registrant_domains
+ - Contact#destroy_orphans
+ - Contact#domain_names_with_roles
+ - Contact#filter_by_states
+ - Contact#search_by_query
+ - Contact#statuses
+ - Depp::Contact#construct_check_hash_from_data
+ - Depp::Contact#find_by_id
+ - Depp::Contact#handle_errors
+ - Depp::Contact#new_from_params
+ - Depp::Domain#construct_params_from_server_data
+ - Depp::Domain#create
+ - Depp::Domain#create_dnskeys_hash
+ - Depp::Domain#renew
+ - Depp::Domain#transfer
+ - Depp::Keyrelay#keyrelay
+ - Depp::User#repp_request
+ - DomainMailModel#format
+ - Epp::Contact#attach_legal_document
+ - Epp::Contact#attrs_from
+ - Epp::Contact#check_availability
+ - Epp::Contact#ident_attrs
+ - Epp::Contact#status_list_from
+ - Epp::Domain#attach_legal_document
+ - Epp::Domain#attrs_from
+ - Epp::Domain#destroy_attrs
+ - Epp::Domain#domain_contact_attrs_from
+ - Epp::Domain#domain_status_list_from
+ - Epp::Domain#transfer_domain_contacts
+ - LegalDocument#calc_checksum
+ - Nameserver#find_by_hash_params
+ - RegistrantUser#find_or_create_by_idc_data
+ - RegistrantUser#find_or_create_by_mid_data
+ - Registrar#debit!
+ - Registrar#search_by_query
+ - ReservedDomain#new_password_for
+ - Soap::Arireg#country_code_3
+ - WhoisRecord#generate_json
+ - RegistrantPresenter#domain_names_with_roles
+ - ActionDispatch::Flash#call
+ - Ransack::Adapters::ActiveRecord::Context#evaluate
+ - EppConstraint#matches?
+ - Requests::SessionHelpers#sign_in_to_epp_area
+TooManyMethods:
+ exclude:
+ - Epp::ContactsController
+ - Epp::DomainsController
+ - EppController
+ - Contact
+ - Depp::Contact
+ - Depp::Domain
+ - Domain
+ - DomainMailModel
+ - Epp::Domain
+ - Invoice
+ - Registrar
+RepeatedConditional:
+ exclude:
+ - Epp::DomainsController
+ - EppController
+ - Registrar::DomainsController
+ - DomainMailer
+ - BankTransaction
+ - Certificate
+ - Contact
+ - Depp::Contact
+ - Domain
+ - DomainCron
+ - Epp::Domain
+ - Invoice
+ - RegistrantVerification
+ManualDispatch:
+ exclude:
+ - EppController#has_attribute
+ - EppController#validate_request
+ - ActionView::Helpers::FormBuilder#label
+ - ActionDispatch::Flash#call
+ - Ransack::Adapters::ActiveRecord::Context#evaluate
+NestedIterators:
+ exclude:
+ - Registrar::DomainsController#index
+ - AccountActivity#to_csv
+ - EppErrors#collect_child_errors
+ - EppErrors#find_epp_code_and_value
+ - Versions::ClassMethods#all_versions_for
+ - Contact#destroy_orphans
+ - Contact#to_csv
+ - Depp::Contact#extract_info_disclosure
+ - Depp::Domain#create_nameservers_hash
+ - Directo#self.send_monthly_invoices
+ - Directo#self.send_receipts
+ - Domain#name_in_wire_format
+ - Domain#self.to_csv
+ - Epp::Domain#nameservers_from
+ - LegalDocument#self.remove_duplicates
+ - Nameserver#replace_hostname_ends
+ - RegistrantPresenter#domain_names_with_roles
+ - UniquenessMultiValidator#validate_each
+UnusedParameters:
+ exclude:
+ - Registrar::PollsController#show#@data.css
+PrimaDonnaMethod:
+ exclude:
+ - DomainDeleteConfirmJob
+ - DomainUpdateConfirmJob
+ - Certificate
+ - Contact
+ - Domain
+ - Epp::Domain
+ - EppSession
+ - RegistrantVerification
+ - Registrar
+BooleanParameter:
+ exclude:
+ - ApplicationMailer#delivery_off?
+ - Directo#self.send_monthly_invoices
+ - Epp::Contact#attrs_from
+ - Epp::Domain#update
+ControlParameter:
+ exclude:
+ - ApplicationMailer#delivery_off?
+ - Ability#initialize
+ - EppErrors#find_epp_code_and_value
+ - Depp::Contact#extension_xml
+ - Directo#self.send_monthly_invoices
+ - Domain#registrant_delete_confirmable?
+ - Domain#registrant_update_confirmable?
+ - Epp::Contact#attrs_from
+ - Epp::Contact#statuses_attrs
+ - Epp::Domain#authenticate
+ - Epp::Domain#dnskeys_attrs
+ - Epp::Domain#domain_contact_attrs_from
+ - Epp::Domain#domain_statuses_attrs
+ - Epp::Domain#nameservers_attrs
+ - Epp::Domain#transfer
+ - Epp::Domain#update
+ - Legacy::Object#self.instance_method_already_implemented?
+ - Legacy::ObjectHistory#self.instance_method_already_implemented?
+ - RegistrantUser#find_or_create_by_idc_data
+LongParameterList:
+ exclude:
+ - ContactMailer#email_updated
+ - DomainDeleteMailer#forced
+ - RegistrantChangeMailer#confirm
+ - RegistrantChangeMailer#notice
+ - EppErrors#add_epp_error
+ - Contact#all_registrant_domains
+DataClump:
+ exclude:
+ - DomainMailer
+ - Epp::Domain
+Attribute:
+ exclude:
+ - ApiUser#registrar_typeahead
+ - BankLink::Request#controller
+ - BankLink::Request#invoice
+ - BankLink::Request#type
+ - BankLink::Response#invoice
+ - BankLink::Response#params
+ - BankLink::Response#type
+ - BankStatement#th6_file
+ - Versions#version_loader
+ - Contact#deliver_emails
+ - Contact#domain_transfer
+ - Contact#domains_present
+ - Contact#legal_document_id
+ - Counter#value
+ - Deposit#amount
+ - Deposit#description
+ - Deposit#registrar
+ - Deposit#registrar_id
+ - Depp::Contact#city
+ - Depp::Contact#code
+ - Depp::Contact#country_code
+ - Depp::Contact#email
+ - Depp::Contact#id
+ - Depp::Contact#ident
+ - Depp::Contact#ident_country_code
+ - Depp::Contact#ident_type
+ - Depp::Contact#legal_document
+ - Depp::Contact#name
+ - Depp::Contact#org_name
+ - Depp::Contact#password
+ - Depp::Contact#phone
+ - Depp::Contact#state
+ - Depp::Contact#statuses
+ - Depp::Contact#street
+ - Depp::Contact#zip
+ - Depp::Domain#current_user
+ - Depp::Domain#epp_xml
+ - Depp::Domain#name
+ - Depp::Keyrelay#current_user
+ - Depp::Keyrelay#epp_xml
+ - Depp::User#password
+ - Depp::User#pki
+ - Depp::User#tag
+ - Domain#deliver_emails
+ - Domain#epp_pending_delete
+ - Domain#epp_pending_update
+ - Domain#is_admin
+ - Domain#legal_document_id
+ - Domain#registrant_typeahead
+ - Domain#reserved_pw
+ - Domain#roles
+ - Domain#update_me
+ - DomainContact#value_typeahead
+ - Epp::Domain#is_renewal
+ - Epp::Domain#is_transfer
+ - Invoice#billing_email
+ - LegalDocument#body
+ - RegistrantUser#idc_data
+ - Soap::Arireg#host
+ - Soap::Arireg#password
+ - Soap::Arireg#username
+ - Soap::Arireg#wsdl
+ - Soap::Arireg::NotAvailableError#json
+ - User#phone
+ - PaperSession#session
+TooManyConstants:
+ exclude:
+ - Certificate
+ - Contact
+ - DomainStatus
+ - DomainTransfer
+UncommunicativeParameterName:
+ exclude:
+ - Counter#next
+ - Counter#prev
+ - Depp::Domain#array_difference
+ - Dnskey#bin_to_hex
+ - Dnskey#hex_to_bin
+ - Dnskey#int_to_hex
+UncommunicativeMethodName:
+ exclude:
+ - Nameserver#val_ipv4
+ - Nameserver#val_ipv6
+ - Soap::Arireg#country_code_3
+ - WhiteIp#validate_ipv4_and_ipv6
diff --git a/Gemfile b/Gemfile
index 9b65f92a9..fe8498495 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,7 +10,6 @@ source 'https://rubygems.org'
# core
gem 'SyslogLogger', '2.0', require: 'syslog/logger'
-gem 'hashie-forbidden_attributes', '0.1.1'
gem 'iso8601', '0.8.6' # for dates and times
gem 'rails', '4.2.7.1' # when update, all initializers eis_custom files needs check/update
gem 'rest-client'
@@ -60,6 +59,7 @@ gem 'devise', '3.5.4' # authenitcation
# rest api
gem 'grape', '0.12.0'
+gem 'hashie-forbidden_attributes', '0.1.1' # For grape, https://github.com/ruby-grape/grape#rails
gem 'jbuilder', '2.2.16' # json api
# registry specfic
@@ -104,6 +104,7 @@ gem 'activerecord-import', '0.7.0' # for inserting dummy data
# for generating pdf
gem 'pdfkit', '0.6.2'
gem 'jquery-ui-rails', '5.0.5'
+gem 'active_model-errors_details' # Backport from Rails 5, https://github.com/rails/rails/pull/18322
group :development do
gem 'spring'
@@ -119,10 +120,7 @@ group :development, :test do
gem 'factory_bot_rails'
gem 'capybara'
gem 'rspec-rails', '~> 3.6'
- gem 'phantomjs-binaries'
- gem 'phantomjs'
gem 'poltergeist'
- gem 'launchy', '2.4.3' # for opening browser automatically
# debug
gem 'pry', '0.10.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index f21d432ab..d4f0cf9fd 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -79,6 +79,9 @@ GEM
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
+ active_model-errors_details (1.3.1)
+ activemodel (>= 3.2.13, < 5.0.0)
+ activesupport
activejob (4.2.7.1)
activesupport (= 4.2.7.1)
globalid (>= 0.3.0)
@@ -187,7 +190,6 @@ GEM
factory_bot_rails (4.8.2)
factory_bot (~> 4.8.2)
railties (>= 3.0.0)
- ffi (1.9.18)
figaro (1.1.1)
thor (~> 0.14)
globalid (0.3.7)
@@ -250,8 +252,6 @@ GEM
kaminari (0.16.3)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
- launchy (2.4.3)
- addressable (~> 2.3)
libxml-ruby (3.0.0)
liquid (3.0.6)
loofah (2.0.3)
@@ -291,9 +291,6 @@ GEM
ast (~> 2.2)
pdfkit (0.6.2)
pg (0.19.0)
- phantomjs (1.9.8.0)
- phantomjs-binaries (2.1.1.1)
- sys-uname (= 0.9.0)
poltergeist (1.14.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
@@ -443,8 +440,6 @@ GEM
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
- sys-uname (0.9.0)
- ffi (>= 1.0.0)
thor (0.19.4)
thread_safe (0.3.6)
tilt (1.4.1)
@@ -488,6 +483,7 @@ PLATFORMS
DEPENDENCIES
SyslogLogger (= 2.0)
+ active_model-errors_details
activerecord-import (= 0.7.0)
airbrake
autodoc
@@ -523,7 +519,6 @@ DEPENDENCIES
jquery-ui-rails (= 5.0.5)
jquery-validation-rails (= 1.13.1)
kaminari (= 0.16.3)
- launchy (= 2.4.3)
liquid (= 3.0.6)
mina (= 0.3.1)
money-rails
@@ -532,8 +527,6 @@ DEPENDENCIES
paper_trail!
pdfkit (= 0.6.2)
pg (= 0.19.0)
- phantomjs
- phantomjs-binaries
poltergeist
pry (= 0.10.1)
puma
diff --git a/app/controllers/admin/contacts_controller.rb b/app/controllers/admin/contacts_controller.rb
index e930a511f..6402d09ae 100644
--- a/app/controllers/admin/contacts_controller.rb
+++ b/app/controllers/admin/contacts_controller.rb
@@ -2,6 +2,7 @@ module Admin
class ContactsController < BaseController
load_and_authorize_resource
before_action :set_contact, only: [:show]
+ helper_method :ident_types
def index
params[:q] ||= {}
@@ -79,5 +80,9 @@ module Admin
params[:q][:created_at_lteq] = ca_cache
end
+
+ def ident_types
+ Contact::Ident.types
+ end
end
end
diff --git a/app/controllers/epp_controller.rb b/app/controllers/epp_controller.rb
index 4a0a0d9d0..8eb6fbc96 100644
--- a/app/controllers/epp_controller.rb
+++ b/app/controllers/epp_controller.rb
@@ -152,9 +152,6 @@ class EppController < ApplicationController
code: '1',
msg: 'handle_errors was executed when there were actually no errors'
}
- # rubocop:disable Rails/Output
- puts "FULL MESSAGE: #{obj.errors.full_messages} #{obj.errors.inspect}" if Rails.env.test?
- # rubocop: enable Rails/Output
end
@errors.uniq!
diff --git a/app/controllers/registrar/contacts_controller.rb b/app/controllers/registrar/contacts_controller.rb
index b927df1a8..4d0de5389 100644
--- a/app/controllers/registrar/contacts_controller.rb
+++ b/app/controllers/registrar/contacts_controller.rb
@@ -2,6 +2,7 @@ class Registrar
class ContactsController < DeppController
before_action :init_epp_contact
helper_method :address_processing?
+ helper_method :ident_types
def index
authorize! :view, Depp::Contact
@@ -140,5 +141,9 @@ class Registrar
def address_processing?
Contact.address_processing?
end
+
+ def ident_types
+ Contact::Ident.types
+ end
end
end
diff --git a/app/controllers/registrar/sessions_controller.rb b/app/controllers/registrar/sessions_controller.rb
index 4ba6501f1..1a8b195ee 100644
--- a/app/controllers/registrar/sessions_controller.rb
+++ b/app/controllers/registrar/sessions_controller.rb
@@ -53,7 +53,7 @@ class Registrar
end
def id
- @user = ApiUser.find_by_idc_data(request.env['SSL_CLIENT_S_DN'])
+ @user = ApiUser.find_by_idc_data_and_allowed(request.env['SSL_CLIENT_S_DN'], request.ip)
if @user
sign_in(@user, event: :authentication)
@@ -87,7 +87,11 @@ class Registrar
return
end
- @user = find_user_by_idc(response.user_id_code)
+ if Setting.registrar_ip_whitelist_enabled
+ @user = find_user_by_idc_and_allowed(response.user_id_code)
+ else
+ @user = find_user_by_idc(response.user_id_code)
+ end
if @user.persisted?
session[:user_id_code] = response.user_id_code
@@ -112,7 +116,7 @@ class Registrar
when 'OUTSTANDING_TRANSACTION'
render json: { message: t(:check_your_phone_for_confirmation_code) }, status: :ok
when 'USER_AUTHENTICATED'
- @user = find_user_by_idc(session[:user_id_code])
+ @user = find_user_by_idc_and_allowed(session[:user_id_code])
sign_in @user
flash[:notice] = t(:welcome)
flash.keep(:notice)
@@ -149,6 +153,18 @@ class Registrar
ApiUser.find_by(identity_code: idc) || User.new
end
+ def find_user_by_idc_and_allowed(idc)
+ return User.new unless idc
+ possible_users = ApiUser.where(identity_code: idc) || User.new
+ possible_users.each do |selected_user|
+ if selected_user.registrar.white_ips.registrar_area.include_ip?(request.ip)
+ return selected_user
+ end
+ end
+ end
+
+
+
def check_ip_restriction
ip_restriction = Authorization::RestrictedIP.new(request.ip)
allowed = ip_restriction.can_access_registrar_area_sign_in_page?
diff --git a/app/models/api_user.rb b/app/models/api_user.rb
index 5e20db24a..ce32c4045 100644
--- a/app/models/api_user.rb
+++ b/app/models/api_user.rb
@@ -51,6 +51,20 @@ class ApiUser < User
find_by(identity_code: identity_code)
end
+
+ def find_by_idc_data_and_allowed(idc_data, ip)
+ return false if idc_data.blank?
+ identity_code = idc_data.scan(/serialNumber=(\d+)/).flatten.first
+
+ return false if ip.blank?
+ possible_users = where(identity_code: identity_code)
+ possible_users.each do |selected_user|
+ if selected_user.registrar.white_ips.registrar_area.include_ip?(ip)
+ return selected_user
+ end
+ end
+ end
+
end
def registrar_typeahead
diff --git a/app/models/concerns/epp_errors.rb b/app/models/concerns/epp_errors.rb
index cf3824260..7395732ca 100644
--- a/app/models/concerns/epp_errors.rb
+++ b/app/models/concerns/epp_errors.rb
@@ -11,6 +11,12 @@ module EppErrors
epp_errors << collect_child_errors(attr)
end
+ if self.class.reflect_on_aggregation(attr)
+ aggregation = send(attr)
+ epp_errors << collect_aggregation_errors(aggregation)
+ next
+ end
+
epp_errors << collect_parent_errors(attr, errors)
end
@@ -46,6 +52,31 @@ module EppErrors
epp_errors
end
+ def collect_aggregation_errors(aggregation)
+ epp_errors = []
+
+ aggregation.errors.details.each do |attr, error_details|
+ error_details.each do |error_detail|
+ aggregation.class.epp_code_map.each do |epp_code, attr_to_error|
+ epp_code_found = attr_to_error.any? { |i| i == [attr, error_detail[:error]] }
+
+ next unless epp_code_found
+
+ message = aggregation.errors.generate_message(attr, error_detail[:error], error_detail)
+ message = aggregation.errors.full_message(attr, message)
+
+ if attr != :base
+ message = "#{aggregation.model_name.human} #{message.camelize(:lower)}"
+ end
+
+ epp_errors << { code: epp_code, msg: message }
+ end
+ end
+ end
+
+ epp_errors
+ end
+
def find_epp_code_and_value(msg)
epp_code_map.each do |code, values|
values.each do |x|
diff --git a/app/models/contact.rb b/app/models/contact.rb
index 732d25e97..61a82ae0a 100644
--- a/app/models/contact.rb
+++ b/app/models/contact.rb
@@ -19,27 +19,22 @@ class Contact < ActiveRecord::Base
accepts_nested_attributes_for :legal_documents
- validates :name, :phone, :email, :ident, :ident_type, presence: true
+ validates :name, :email, presence: true
validates :street, :city, :zip, :country_code, presence: true, if: 'self.class.address_processing?'
- validates :phone, format: /\+[0-9]{1,3}\.[0-9]{1,14}?/, phone: true
+ validates :phone, presence: true, e164: true, phone: true
validates :email, format: /@/
validates :email, email_format: { message: :invalid }, if: proc { |c| c.email_changed? }
- validates :ident,
- format: { with: /\d{4}-\d{2}-\d{2}/, message: :invalid_birthday_format },
- if: proc { |c| c.ident_type == 'birthday' }
- validates :ident_country_code, presence: true, if: proc { |c| %w(org priv).include? c.ident_type }, on: :create
+
validates :code,
uniqueness: { message: :epp_id_taken },
format: { with: /\A[\w\-\:\.\_]*\z/i, message: :invalid },
length: { maximum: 100, message: :too_long_contact_code }
+ validates_associated :identifier
- validate :val_ident_type
- validate :val_ident_valid_format?
validate :validate_html
validate :validate_country_code
- validate :validate_ident_country_code
after_initialize do
self.status_notes = {} if status_notes.nil?
@@ -49,8 +44,15 @@ class Contact < ActiveRecord::Base
before_validation :to_upcase_country_code
before_validation :strip_email
before_create :generate_auth_info
-
before_update :manage_emails
+
+ composed_of :identifier,
+ class_name: 'Contact::Ident',
+ constructor: proc { |code, type, country_code| Contact::Ident.new(code: code,
+ type: type,
+ country_code: country_code) },
+ mapping: [%w[ident code], %w[ident_type type], %w[ident_country_code country_code]]
+
def manage_emails
return nil unless email_changed?
return nil unless deliver_emails == true
@@ -76,12 +78,6 @@ class Contact < ActiveRecord::Base
BIRTHDAY = 'birthday'.freeze
PASSPORT = 'passport'
- IDENT_TYPES = [
- ORG, # Company registry code (or similar)
- PRIV, # National idendtification number
- BIRTHDAY # Birthday date
- ]
-
attr_accessor :deliver_emails
attr_accessor :domain_transfer # hack but solves problem faster
@@ -219,10 +215,6 @@ class Contact < ActiveRecord::Base
STDOUT << "#{Time.zone.now.utc} - Successfully destroyed #{counter} orphaned contacts\n" unless Rails.env.test?
end
- def privs
- where("ident_type = '#{PRIV}'")
- end
-
def admin_statuses
[
SERVER_UPDATE_PROHIBITED,
@@ -299,28 +291,6 @@ class Contact < ActiveRecord::Base
name || '[no name]'
end
- def val_ident_type
- errors.add(:ident_type, :epp_ident_type_invalid, code: code) if !%w(org priv birthday).include?(ident_type)
- end
-
- def val_ident_valid_format?
- case ident_country_code
- when 'EE'.freeze
- err_msg = "invalid_EE_identity_format#{"_update" if id}".to_sym
- case ident_type
- when 'priv'.freeze
- errors.add(:ident, err_msg) unless Isikukood.new(ident).valid?
- when 'org'.freeze
- # !%w(1 7 8 9).freeze.include?(ident.first) ||
- if ident.size != 8 || !(ident =~/\A[0-9]{8}\z/)
- errors.add(:ident, err_msg)
- end
- when BIRTHDAY
- errors.add(:ident, err_msg) if id.blank? # only for create action right now. Later for all of them
- end
- end
- end
-
def validate_html
self.class.columns.each do |column|
next unless column.type == :string
@@ -334,7 +304,6 @@ class Contact < ActiveRecord::Base
end
end
-
def org?
ident_type == ORG
end
@@ -344,10 +313,6 @@ class Contact < ActiveRecord::Base
!org?
end
- def birthday?
- ident_type == BIRTHDAY
- end
-
def generate_auth_info
return if @generate_auth_info_disabled
return if auth_info.present?
@@ -420,10 +385,6 @@ class Contact < ActiveRecord::Base
errors.add(:country_code, :invalid) unless Country.new(country_code)
end
- def validate_ident_country_code
- errors.add(:ident, :invalid_country_code) unless Country.new(ident_country_code)
- end
-
def related_domain_descriptions
ActiveSupport::Deprecation.warn('Use #domain_names_with_roles')
@@ -568,7 +529,7 @@ class Contact < ActiveRecord::Base
return if changes.slice(*(self.class.column_names - ["updated_at", "created_at", "statuses", "status_notes"])).empty?
names = related_domain_descriptions.keys
- UpdateWhoisRecordJob.enqueue(names, :domain) if names.present?
+ UpdateWhoisRecordJob.enqueue(names, 'domain') if names.present?
end
def children_log
diff --git a/app/models/contact/ident.rb b/app/models/contact/ident.rb
new file mode 100644
index 000000000..d531b833c
--- /dev/null
+++ b/app/models/contact/ident.rb
@@ -0,0 +1,74 @@
+class Contact::Ident
+ include ActiveModel::Model
+
+ attr_accessor :code
+ attr_accessor :type
+ attr_accessor :country_code
+
+ validates :code, presence: true
+ validates :code, national_id: true, if: :national_id?
+ validates :code, reg_no: true, if: :reg_no?
+ validates :code, iso8601: { date_only: true }, if: :birthday?
+
+ validates :type, presence: true, inclusion: { in: proc { types } }
+ validates :country_code, presence: true, iso31661_alpha2: true
+ validates_with MismatchValidator
+
+ def self.epp_code_map
+ {
+ '2003' => [
+ [:code, :blank],
+ [:type, :blank],
+ [:country_code, :blank]
+ ],
+ '2005' => [
+ [:base, :mismatch],
+ [:code, :invalid_national_id],
+ [:code, :invalid_reg_no],
+ [:code, :invalid_iso8601_date],
+ [:country_code, :invalid_iso31661_alpha2]
+ ]
+ }
+ end
+
+ def self.types
+ %w[org priv birthday]
+ end
+
+ def marked_for_destruction?
+ false
+ end
+
+ def birthday?
+ type == 'birthday'
+ end
+
+ def national_id?
+ type == 'priv'
+ end
+
+ def reg_no?
+ type == 'org'
+ end
+
+ def country
+ Country.new(country_code)
+ end
+
+ def ==(other_ident)
+ if other_ident.is_a?(self.class)
+ (code == other_ident.code) &&
+ (type == other_ident.type) &&
+ (country_code == other_ident.country_code)
+ else
+ false
+ end
+ end
+
+ private
+
+ # https://github.com/rails/rails/issues/1513
+ def validation_context=(_value)
+ ;
+ end
+end
diff --git a/app/models/epp/contact.rb b/app/models/epp/contact.rb
index 53ebb2ee8..b280ceea6 100644
--- a/app/models/epp/contact.rb
+++ b/app/models/epp/contact.rb
@@ -109,7 +109,7 @@ class Epp::Contact < Contact
end
delegate :ident_attr_valid?, to: :class
- def epp_code_map # rubocop:disable Metrics/MethodLength
+ def epp_code_map
{
'2003' => [ # Required parameter missing
[:name, :blank],
@@ -124,31 +124,19 @@ class Epp::Contact < Contact
[:name, :invalid],
[:phone, :invalid],
[:email, :invalid],
- [:ident, :invalid],
- [:ident, :invalid_EE_identity_format],
- [:ident, :invalid_EE_identity_format_update],
- [:ident, :invalid_birthday_format],
- [:ident, :invalid_country_code],
[:country_code, :invalid],
- [:ident_type, :missing],
[:code, :invalid],
[:code, :too_long_contact_code]
],
'2302' => [ # Object exists
[:code, :epp_id_taken]
],
- '2304' => [ # Object status prohibits operation
- [:ident_type, :epp_ident_type_invalid, { value: { obj: 'code', val: code}, interpolation: {code: code}}]
- ],
'2305' => [ # Association exists
[:domains, :exist]
- ],
- '2306' => [ # Parameter policy error
]
}
end
- # rubocop:disable Metrics/AbcSize
def update_attributes(frame, current_user)
return super if frame.blank?
at = {}.with_indifferent_access
@@ -158,9 +146,6 @@ class Epp::Contact < Contact
at[:statuses] = statuses - statuses_attrs(frame.css('rem'), 'rem') + statuses_attrs(frame.css('add'), 'add')
end
- # legal_frame = frame.css('legalDocument').first
- # at[:legal_documents_attributes] = self.class.legal_document_attrs(legal_frame)
-
if doc = attach_legal_document(Epp::Domain.parse_legal_document_from_frame(frame))
frame.css("legalDocument").first.content = doc.path if doc && doc.persisted?
self.legal_document_id = doc.id
@@ -168,29 +153,28 @@ class Epp::Contact < Contact
self.deliver_emails = true # turn on email delivery for epp
+ ident_frame = frame.css('ident').first
- # allow to update ident code for legacy contacts
- if frame.css('ident').first
- self.ident_updated_at ||= Time.zone.now # not in use
- ident_frame = frame.css('ident').first
+ # https://github.com/internetee/registry/issues/576
+ if ident_frame
+ if identifier.valid?
+ submitted_ident = Ident.new(code: ident_frame.text,
+ type: ident_frame.attr('type'),
+ country_code: ident_frame.attr('cc'))
- if ident_frame && ident_attr_valid?(ident_frame)
- org_priv = %w(org priv).freeze
- if ident_country_code.blank? && org_priv.include?(ident_type) && org_priv.include?(ident_frame.attr('type'))
- at.merge!(ident_country_code: ident_frame.attr('cc'), ident_type: ident_frame.attr('type'))
- elsif ident_type == "birthday" && !ident[/\A\d{4}-\d{2}-\d{2}\z/] && (Date.parse(ident) rescue false)
- at.merge!(ident: ident_frame.text)
- at.merge!(ident_country_code: ident_frame.attr('cc')) if ident_frame.attr('cc').present?
- elsif ident_type == "birthday" && ident_country_code.blank?
- at.merge!(ident_country_code: ident_frame.attr('cc'))
- elsif ident_type.blank? && ident_country_code.blank?
- at.merge!(ident_type: ident_frame.attr('type'))
- at.merge!(ident_country_code: ident_frame.attr('cc')) if ident_frame.attr('cc').present?
- else
- throw :epp_error, {code: '2306', msg: I18n.t(:ident_update_error)}
- end
+ report_valid_ident_error if submitted_ident != identifier
else
- throw :epp_error, {code: '2306', msg: I18n.t(:ident_update_error)}
+ ident_update_attempt = ident_frame.text.present? && (ident_frame.text != ident)
+ report_ident_update_error if ident_update_attempt
+
+ identifier = Ident.new(code: ident,
+ type: ident_frame.attr('type'),
+ country_code: ident_frame.attr('cc'))
+
+ identifier.validate
+
+ self.identifier = identifier
+ self.ident_updated_at ||= Time.zone.now
end
end
@@ -199,7 +183,6 @@ class Epp::Contact < Contact
super(at)
end
- # rubocop:enable Metrics/AbcSize
def statuses_attrs(frame, action)
status_list = status_list_from(frame)
@@ -259,4 +242,13 @@ class Epp::Contact < Contact
self.legal_document_id = doc.id
end
+ private
+
+ def report_valid_ident_error
+ throw :epp_error, { code: '2308', msg: I18n.t('epp.contacts.errors.valid_ident') }
+ end
+
+ def report_ident_update_error
+ throw :epp_error, { code: '2308', msg: I18n.t('epp.contacts.errors.ident_update') }
+ end
end
diff --git a/app/models/epp/response.rb b/app/models/epp/response.rb
new file mode 100644
index 000000000..c9a5d8bb4
--- /dev/null
+++ b/app/models/epp/response.rb
@@ -0,0 +1,22 @@
+module EPP
+ class Response
+ attr_accessor :results
+
+ def self.from_xml(xml)
+ xml_doc = Nokogiri::XML(xml)
+ response = new
+
+ result_elements = xml_doc.css('result')
+
+ result_elements.each do |result_element|
+ response.results << Result.new(result_element[:code].to_s, result_element.text.strip)
+ end
+
+ response
+ end
+
+ def initialize
+ @results = []
+ end
+ end
+end
diff --git a/app/models/epp/response/result.rb b/app/models/epp/response/result.rb
new file mode 100644
index 000000000..5c870c830
--- /dev/null
+++ b/app/models/epp/response/result.rb
@@ -0,0 +1,28 @@
+module EPP
+ class Response
+ class Result
+ CODE_TO_TYPE = {
+ '1000' => :success,
+ '1001' => :success_pending,
+ '1300' => :success_empty_queue,
+ '1301' => :success_dequeue,
+ '2001' => :syntax_error,
+ '2003' => :required_param_missing,
+ '2005' => :param_syntax_error,
+ '2308' => :data_management_policy_violation
+ }
+
+ attr_accessor :code
+ attr_accessor :message
+
+ def initialize(code, message)
+ @code = code
+ @message = message
+ end
+
+ def self.codes
+ CODE_TO_TYPE
+ end
+ end
+ end
+end
diff --git a/app/models/registrar.rb b/app/models/registrar.rb
index 97ecfa32a..b410a1c76 100644
--- a/app/models/registrar.rb
+++ b/app/models/registrar.rb
@@ -9,7 +9,6 @@ class Registrar < ActiveRecord::Base
has_many :accounts
has_many :nameservers, through: :domains
has_many :whois_records
- has_many :priv_contacts, -> { privs }, class_name: 'Contact'
has_many :white_ips, dependent: :destroy
delegate :balance, to: :cash_account, allow_nil: true
diff --git a/app/validators/contact/ident/mismatch_validator.rb b/app/validators/contact/ident/mismatch_validator.rb
new file mode 100644
index 000000000..d20bb82cf
--- /dev/null
+++ b/app/validators/contact/ident/mismatch_validator.rb
@@ -0,0 +1,20 @@
+class Contact::Ident::MismatchValidator < ActiveModel::Validator
+ Mismatch = Struct.new(:type, :country)
+
+ def self.mismatches
+ [
+ Mismatch.new('birthday', Country.new('EE')),
+ ]
+ end
+
+ def validate(record)
+ record.errors.add(:base, :mismatch, type: record.type, country: record.country) if mismatched?(record)
+ end
+
+ private
+
+ def mismatched?(record)
+ mismatch = Mismatch.new(record.type, record.country)
+ self.class.mismatches.include?(mismatch)
+ end
+end
diff --git a/app/validators/contact/ident/national_id_validator.rb b/app/validators/contact/ident/national_id_validator.rb
new file mode 100644
index 000000000..2fcf019b1
--- /dev/null
+++ b/app/validators/contact/ident/national_id_validator.rb
@@ -0,0 +1,22 @@
+class Contact::Ident::NationalIdValidator < ActiveModel::EachValidator
+ def self.country_specific_validations
+ {
+ Country.new('EE') => proc { |code| Isikukood.new(code).valid? },
+ }
+ end
+
+ def validate_each(record, attribute, value)
+ validation = validation_for(record.country)
+
+ return unless validation
+
+ valid = validation.call(value)
+ record.errors.add(attribute, :invalid_national_id, country: record.country) unless valid
+ end
+
+ private
+
+ def validation_for(country)
+ self.class.country_specific_validations[country]
+ end
+end
diff --git a/app/validators/contact/ident/reg_no_validator.rb b/app/validators/contact/ident/reg_no_validator.rb
new file mode 100644
index 000000000..611d13301
--- /dev/null
+++ b/app/validators/contact/ident/reg_no_validator.rb
@@ -0,0 +1,21 @@
+class Contact::Ident::RegNoValidator < ActiveModel::EachValidator
+ def self.country_specific_formats
+ {
+ Country.new('EE') => /\A[0-9]{8}\z/,
+ }
+ end
+
+ def validate_each(record, attribute, value)
+ format = format_for(record.country)
+
+ return unless format
+
+ record.errors.add(attribute, :invalid_reg_no, country: record.country) unless value =~ format
+ end
+
+ private
+
+ def format_for(country)
+ self.class.country_specific_formats[country]
+ end
+end
diff --git a/app/views/admin/contacts/index.haml b/app/views/admin/contacts/index.haml
index d9f60c13b..cc80ac744 100644
--- a/app/views/admin/contacts/index.haml
+++ b/app/views/admin/contacts/index.haml
@@ -19,7 +19,7 @@
.col-md-3
.form-group
= label_tag t(:ident_type)
- = select_tag '[q][ident_type_eq]', options_for_select(Contact::IDENT_TYPES, params[:q][:ident_type_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' }
+ = select_tag '[q][ident_type_eq]', options_for_select(ident_types, params[:q][:ident_type_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' }
.row
.col-md-3
.form-group
@@ -75,7 +75,7 @@
.row
.col-md-12
.table-responsive
- %table.table.table-hover.table-bordered.table-condensed
+ %table.table.table-hover.table-bordered.table-condensed.contacts
%thead
%tr
%th{class: 'col-xs-2'}
diff --git a/app/views/registrar/contacts/index.haml b/app/views/registrar/contacts/index.haml
index fd4672350..5f5a667c0 100644
--- a/app/views/registrar/contacts/index.haml
+++ b/app/views/registrar/contacts/index.haml
@@ -21,7 +21,7 @@
.col-md-3
.form-group
= label_tag t(:ident_type)
- = select_tag '[q][ident_type_eq]', options_for_select(Contact::IDENT_TYPES, params[:q][:ident_type_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' }
+ = select_tag '[q][ident_type_eq]', options_for_select(ident_types, params[:q][:ident_type_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' }
.row
.col-md-3
.form-group
@@ -85,7 +85,7 @@
.row
.col-md-12
.table-responsive
- %table.table.table-hover.table-bordered.table-condensed
+ %table.table.table-hover.table-bordered.table-condensed.contacts
%thead
%tr
%th{class: 'col-xs-2'}
diff --git a/config/application-example.yml b/config/application-example.yml
index f54557828..caedd83cc 100644
--- a/config/application-example.yml
+++ b/config/application-example.yml
@@ -129,3 +129,5 @@ payments_lhv_seller_private: 'kaupmees_priv.pem'
payments_lhv_seller_account: 'testvpos'
user_session_timeout: '3600' # 1 hour
+secure_session_cookies: 'false' # true|false
+same_site_session_cookies: 'false' # false|strict|lax
diff --git a/config/initializers/eis_custom_active_model.rb b/config/initializers/eis_custom_active_model.rb
deleted file mode 100644
index ba5f29b06..000000000
--- a/config/initializers/eis_custom_active_model.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# Log all active model user errors
-# rubocop: disable Lint/AssignmentInCondition
-# rubocop: disable Style/SignalException
-module ActiveModel
- class Errors
- def add(attribute, message = :invalid, options = {})
- message = normalize_message(attribute, message, options)
- if exception = options[:strict]
- exception = ActiveModel::StrictValidationFailed if exception == true
- raise exception, full_message(attribute, message)
- end
-
- # CUSTOM logging
- Rails.logger.info "USER MSG: ACTIVEMODEL: #{@base.try(:class)} [#{attribute}] #{message}" if message.present?
- # END of CUSTOM logging
-
- self[attribute] << message
- end
- end
-end
diff --git a/config/initializers/eis_custom_flash.rb b/config/initializers/eis_custom_flash.rb
deleted file mode 100644
index 4e4d359b5..000000000
--- a/config/initializers/eis_custom_flash.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# Log all flash messages
-# rubocop: disable Metrics/CyclomaticComplexity
-# rubocop: disable Metrics/LineLength
-module ActionDispatch
- class Flash
- # rubocop: disable Metrics/PerceivedComplexity
- # rubocop: disable Style/MultilineOperationIndentation
- def call(env)
- @app.call(env)
- ensure
- session = Request::Session.find(env) || {}
- flash_hash = env[KEY]
-
- if flash_hash && (flash_hash.present? || session.key?('flash'))
- session["flash"] = flash_hash.to_session_value
-
- # EIS custom logging
- Rails.logger.info "USER MSG: FLASH: #{session['flash']['flashes'].inspect}" if session['flash']
- # END OF EIS custom logging
-
- env[KEY] = flash_hash.dup
- end
-
- if (!session.respond_to?(:loaded?) || session.loaded?) && # (reset_session uses {}, which doesn't implement #loaded?)
- session.key?('flash') && session['flash'].nil?
- session.delete('flash')
- end
- end
- end
-end
-
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
index 480996245..d063123a4 100644
--- a/config/initializers/session_store.rb
+++ b/config/initializers/session_store.rb
@@ -1,3 +1,9 @@
# Be sure to restart your server when you modify this file.
-Rails.application.config.session_store :cookie_store, key: '_registry_session'
+secure_cookies = ENV['secure_session_cookies'] == 'true'
+same_site_cookies = ENV['same_site_session_cookies'] != 'false' ? ENV['same_site_session_cookies'].to_sym : false
+
+Rails.application.config.session_store :cookie_store,
+ key: '_registry_session',
+ secure: secure_cookies,
+ same_site: same_site_cookies
diff --git a/config/locales/contacts.en.yml b/config/locales/contacts.en.yml
index 2061d2abd..0c3c1fe29 100644
--- a/config/locales/contacts.en.yml
+++ b/config/locales/contacts.en.yml
@@ -9,5 +9,20 @@ en:
models:
contact:
attributes:
+ code:
+ blank: "Required parameter missing - code"
+ too_long_contact_code: "Contact code is too long, max 100 characters"
+ name:
+ blank: "Required parameter missing - name"
+ phone:
+ blank: "Required parameter missing - phone"
+ invalid: "Phone nr is invalid"
+ email:
+ blank: "Required parameter missing - email"
+ invalid: "Email is invalid"
+ domains:
+ exist: 'Object association prohibits operation'
+ statuses:
+ not_uniq: 'not uniq'
country_code:
invalid: Country code is not valid, should be in ISO_3166-1 alpha 2 format
diff --git a/config/locales/en.yml b/config/locales/en.yml
index ef8762917..0a4a83c98 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -34,33 +34,6 @@ en:
activerecord:
errors:
models:
- contact:
- attributes:
- code:
- blank: "Required parameter missing - code"
- too_long_contact_code: "Contact code is too long, max 100 characters"
- name:
- blank: "Required parameter missing - name"
- phone:
- blank: "Required parameter missing - phone"
- invalid: "Phone nr is invalid"
- email:
- blank: "Required parameter missing - email"
- invalid: "Email is invalid"
- ident:
- blank: "Required parameter missing - ident"
- invalid_EE_identity_format: "Ident not in valid Estonian identity format."
- invalid_EE_identity_format_update: "Ident not in valid Estonian identity format. Please create new contact"
- invalid_birthday_format: "Ident not in valid birthady format, should be YYYY-MM-DD"
- invalid_country_code: "Ident country code is not valid, should be in ISO_3166-1 alpha 2 format"
- ident_type:
- ident_type_invalid: 'Ident type is invalid'
- epp_ident_type_invalid: 'Object status prohibits operation: ident_type of contact %{code} is invalid'
- domains:
- exist: 'Object association prohibits operation'
- statuses:
- not_uniq: 'not uniq'
-
epp_domain: &epp_domain_ar_attributes
attributes:
base:
@@ -262,6 +235,8 @@ en:
unimplemented_command: 'Unimplemented command'
domain_exists_but_belongs_to_other_registrar: 'Domain exists but belongs to other registrar'
required_ident_attribute_missing: "Required ident attribute missing: %{key}"
+ invalid_iso31661_alpha2: does not conform to ISO 3166-1 alpha-2 standard
+ invalid_iso8601_date: has invalid date format YYYY-MM-DD (ISO 8601)
code: 'Code'
action: 'Action'
@@ -487,7 +462,6 @@ en:
crt_revoked: 'CRT (revoked)'
contact_org_error: 'Parameter value policy error. Org must be blank'
contact_fax_error: 'Parameter value policy error. Fax must be blank'
- ident_update_error: 'Parameter value policy error. Update of ident data not allowed [ident]'
invoices: 'Invoices'
no_such_user: 'No such user'
phone_no: 'Phone number'
diff --git a/config/locales/epp/contacts.en.yml b/config/locales/epp/contacts.en.yml
index a669310ab..fe4ed7ccf 100644
--- a/config/locales/epp/contacts.en.yml
+++ b/config/locales/epp/contacts.en.yml
@@ -3,3 +3,11 @@ en:
contacts:
completed: Command completed successfully
completed_without_address: Command completed successfully; Postal address data discarded
+
+ errors:
+ valid_ident: >-
+ Ident update is not allowed.
+ Consider creating new contact object
+ ident_update: >-
+ Only ident type and country can be updated in case of invalid ident.
+ Please create new contact object to update ident code
diff --git a/config/locales/idents.yml b/config/locales/idents.yml
new file mode 100644
index 000000000..33b935833
--- /dev/null
+++ b/config/locales/idents.yml
@@ -0,0 +1,11 @@
+en:
+ activemodel:
+ errors:
+ models:
+ contact/ident:
+ attributes:
+ base:
+ mismatch: Ident type "%{type}" is invalid for %{country}
+ code:
+ invalid_national_id: does not conform to national identification number format of %{country}
+ invalid_reg_no: does not conform to registration number format of %{country}
diff --git a/doc/docker/apache2/epp-tester.conf b/doc/docker/apache2/epp-tester.conf
deleted file mode 100644
index 140785385..000000000
--- a/doc/docker/apache2/epp-tester.conf
+++ /dev/null
@@ -1,18 +0,0 @@
-Listen 8888
-
- ServerName registry.gitlab.eu
- ServerAdmin info@gitlab.eu
-
- PassengerEnabled on
- RailsEnv production
- DocumentRoot /home/app/epp-tester/current/public
-
- ErrorLog /var/log/apache2/epp-tester.error.log
- LogLevel info ssl:warn
- CustomLog /var/log/apache2/epp-tester.access.log combined
-
-
- Require all granted
- Options -MultiViews
-
-
diff --git a/doc/docker/apache2/epp.conf b/doc/docker/apache2/epp.conf
deleted file mode 100644
index 33ef057aa..000000000
--- a/doc/docker/apache2/epp.conf
+++ /dev/null
@@ -1,21 +0,0 @@
-
- Listen 700
-
- SSLEngine on
- SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
- SSLCertificateFile /etc/apache2/ssl/apache.crt
- SSLCertificateKeyFile /etc/apache2/ssl/apache.key
-
- SSLVerifyClient optional_no_ca
-
- EPPEngine On
- EPPCommandRoot /proxy/command
- EPPSessionRoot /proxy/session
- EPPErrorRoot /proxy/error
-
- ProxyPass /proxy/ http://localhost:80/epp/
-
- EPPAuthURI implicit
- EPPReturncodeHeader X-EPP-Returncode
-
-
diff --git a/doc/docker/apache2/registry-test.conf b/doc/docker/apache2/registry-test.conf
deleted file mode 100644
index dc4b0cc26..000000000
--- a/doc/docker/apache2/registry-test.conf
+++ /dev/null
@@ -1,39 +0,0 @@
-Listen 81
-
- ServerAdmin info@gitlab.eu
-
- PassengerEnabled on
- RailsEnv test
- DocumentRoot /home/app/registry-test/public
-
- ErrorLog /var/log/apache2/registry-test.error.log
- LogLevel info ssl:warn
- CustomLog /var/log/apache2/registry-test.access.log combined
-
-
- Require all granted
- Options -MultiViews
-
-
-
-
- Listen 701
-
- SSLEngine on
- SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
- SSLCertificateFile /etc/apache2/ssl/apache.crt
- SSLCertificateKeyFile /etc/apache2/ssl/apache.key
-
- SSLVerifyClient optional_no_ca
-
- EPPEngine On
- EPPCommandRoot /proxy/command
- EPPSessionRoot /proxy/session
- EPPErrorRoot /proxy/error
-
- ProxyPass /proxy/ http://localhost:81/epp/
-
- EPPAuthURI implicit
- EPPReturncodeHeader X-EPP-Returncode
-
-
diff --git a/doc/docker/apache2/registry.conf b/doc/docker/apache2/registry.conf
deleted file mode 100644
index b01ec745d..000000000
--- a/doc/docker/apache2/registry.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-
- ServerName registry.gitlab.eu
- ServerAdmin info@gitlab.eu
-
- PassengerEnabled on
- RailsEnv production
- DocumentRoot /home/app/registry/current/public
-
- ErrorLog /var/log/apache2/registry.error.log
- LogLevel info ssl:warn
- CustomLog /var/log/apache2/registry.access.log combined
-
-
- Require all granted
- Options -MultiViews
-
-
diff --git a/doc/docker/ssh/authorized_keys b/doc/docker/ssh/authorized_keys
deleted file mode 100755
index 9266ca452..000000000
--- a/doc/docker/ssh/authorized_keys
+++ /dev/null
@@ -1,3 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAz+n4Sln0oxme+9hyrgPud9k0C00Nm0T2YufHcQUAdtJssCfeKp2qo/gy0LmOXTB8efyavFn4NW2GZs8gxJ0BV5GoHLmnERAWDOi/wg3KLl4r/ei+HQX6Po/V7WOMHWzKPSSGtqW7cZc1g0y2ci571ZUmgEBoGoGPfoQToGEn2yV4hQmHIjbwtfNNCHx/i12DCoJnD+3cIvhHf4FbZRBW9Wu0I24iqLcxLOAwGWVsnzi0OqN+rj3DenPQfjcPhSsmTu+8mn2AIwMxWeLZSslEYfyBeo9dLBntj3dnxWpw/MJEfMmWgWKGqMaVGB731ZWDOrRrzgl5+s24YBv9LyYWyQ==
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDXF8qkkQg8We6c2eCRQTuQUAffuDcYijlnVNAH0V7eUMxKC/9aPIhHaM9JVY4exXDVEQOK0+KsF6twTtewK8XBFfHXcOV3k+11KOJ1LsfphQIbwS9Qufw2maxCWJHxQwKGViGLqePuecQhfQ3UAVXZ1ZO7qGrLB9JBlRimbItJsG3F2o1T7pJAMucf+zCv5KmMeeddDyhAg2ufQHnuPKIMAgr4XH/TD4mg5tqORXCdk/2apuqUz35WqAyRNt/J66bTJOJ39QJv50cyT6/Bb74MNfJSejsM5EUnKF4Nq7edR8F8tlnXmL/wvvVs81oHywCnMqP8eEISLumy1nhNpgbn martin@gitlab.eu
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC13V94raEKiCzg4sACsIFxiHPcRSUryUHxXpcyHMi7OJvTtszOPR3hZnB36c0NxnznD0t3rH2n5vIX+tBmX+JND7bvM+YKgTGcGN+HvS08nSsvwHLie/UAHkWy/4xFvyKnq8MIZtYxkPdIGph6hFMr5LljJu05V08hZF09HutBsjXw5wmZRUJoD/Jl0FO/pf6WxH1VHjhz0kGuM8VREU2SC8uzV1AIZ86zsaxJld1m0doyt+arnJkPYgjXHHpu/IWzIHYjbVo5W8JmYagDCYxaPHN7EesHAEzFi1LDtq1aIrqWrczKaJGSryxSba6pnYiK69MTojF/SAXMsJ1u5q1P andres.kesk@gmail.com
diff --git a/doc/epp/contact.md b/doc/epp/contact.md
index 3ec314b9e..b1f00aedf 100644
--- a/doc/epp/contact.md
+++ b/doc/epp/contact.md
@@ -36,7 +36,7 @@ More info: https://en.wikipedia.org/wiki/Latin_script_in_Unicode
1 E-mail
1
1 Attribute: xmlns:eis="https://epp.tld.ee/schema/eis-1.0.xsd"
- 1 Contact identificator
+ 1 Identifier
Attribute: "type"
"org" # Business registry code
"priv" # National identification number
@@ -73,7 +73,7 @@ More info: https://en.wikipedia.org/wiki/Latin_script_in_Unicode
1 Contact password. Attribute: roid="String"
0-1
0-1 Attribute: xmlns:eis="https://epp.tld.ee/schema/eis-1.0.xsd"
- 0-1 Contact identificator
+ 0-1 Identifier
Attribute: "type"
"org" # Business registry code
"priv" # National identification number
diff --git a/doc/models_brief.svg b/doc/models_brief.svg
index 76dd9a83f..22d63cfe7 100644
--- a/doc/models_brief.svg
+++ b/doc/models_brief.svg
@@ -1031,25 +1031,11 @@
-Registrar->Contact
-
-
-
-priv_contacts
-
-
Registrar->Contact
-
-Registrar->Contact
-
-
-
-priv_contacts
-
Registrar->Domain
diff --git a/doc/models_complete.svg b/doc/models_complete.svg
index 3c64e4a34..a4b16517f 100644
--- a/doc/models_complete.svg
+++ b/doc/models_complete.svg
@@ -1642,25 +1642,11 @@
-Registrar->Contact
-
-
-
-priv_contacts
-
-
Registrar->Contact
-
-Registrar->Contact
-
-
-
-priv_contacts
-
Registrar->Domain
diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake
index 2bfb5c5ae..c624b3c95 100644
--- a/lib/tasks/dev.rake
+++ b/lib/tasks/dev.rake
@@ -173,6 +173,8 @@ namespace :dev do
end
end
+ Setting.api_ip_whitelist_enabled = false
+ Setting.address_processing = false
Setting.registrar_ip_whitelist_enabled = false
ActiveRecord::Base.transaction do
diff --git a/lib/validators/e164_validator.rb b/lib/validators/e164_validator.rb
new file mode 100644
index 000000000..e5807e585
--- /dev/null
+++ b/lib/validators/e164_validator.rb
@@ -0,0 +1,12 @@
+class E164Validator < ActiveModel::EachValidator
+ def validate_each(record, attribute, _value)
+ length_validator = ActiveModel::Validations::
+ LengthValidator.new(maximum: 17, attributes: attribute)
+ length_validator.validate(record)
+
+ format_validator = ActiveModel::Validations::
+ FormatValidator.new(with: /\+[0-9]{1,3}\.[0-9]{1,14}?/,
+ attributes: attribute)
+ format_validator.validate(record)
+ end
+end
diff --git a/lib/validators/iso31661_alpha2_validator.rb b/lib/validators/iso31661_alpha2_validator.rb
new file mode 100644
index 000000000..6535e11d4
--- /dev/null
+++ b/lib/validators/iso31661_alpha2_validator.rb
@@ -0,0 +1,11 @@
+class Iso31661Alpha2Validator < ActiveModel::EachValidator
+ def validate_each(record, attribute, value)
+ record.errors.add(attribute, :invalid_iso31661_alpha2) unless valid_country_code?(value)
+ end
+
+ private
+
+ def valid_country_code?(country_code)
+ Country.new(country_code)
+ end
+end
diff --git a/lib/validators/iso8601_validator.rb b/lib/validators/iso8601_validator.rb
new file mode 100644
index 000000000..bbcf63798
--- /dev/null
+++ b/lib/validators/iso8601_validator.rb
@@ -0,0 +1,13 @@
+class Iso8601Validator < ActiveModel::EachValidator
+ def validate_each(record, attribute, value)
+ if options[:date_only]
+ record.errors.add(attribute, :invalid_iso8601_date) unless value =~ date_format
+ end
+ end
+
+ private
+
+ def date_format
+ /\d{4}-\d{2}-\d{2}/
+ end
+end
diff --git a/lib/validators/phone_validator.rb b/lib/validators/phone_validator.rb
index d0bf94f1b..a2a91e9f7 100644
--- a/lib/validators/phone_validator.rb
+++ b/lib/validators/phone_validator.rb
@@ -2,11 +2,11 @@ class PhoneValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if record.errors[:phone].any?
- splitted_phone = value.split('.')
- country_code = splitted_phone.first
- phone_number = splitted_phone.second
+ phone_parts = value.split('.')
+ country_code = phone_parts.first
+ subscriber_no = phone_parts.second
- if zeros_only?(country_code) || zeros_only?(phone_number)
+ if zeros_only?(country_code) || zeros_only?(subscriber_no)
record.errors.add(attribute, :invalid)
end
end
diff --git a/spec/features/admin/contacts/list_spec.rb b/spec/features/admin/contacts/list_spec.rb
new file mode 100644
index 000000000..80312fb17
--- /dev/null
+++ b/spec/features/admin/contacts/list_spec.rb
@@ -0,0 +1,12 @@
+require 'rails_helper'
+
+RSpec.feature 'Contact list', settings: false do
+ background do
+ sign_in_to_admin_area
+ end
+
+ it 'is visible' do
+ visit admin_contacts_path
+ expect(page).to have_css('.contacts')
+ end
+end
diff --git a/spec/features/registrar/contacts/list_spec.rb b/spec/features/registrar/contacts/list_spec.rb
new file mode 100644
index 000000000..96f1f2c98
--- /dev/null
+++ b/spec/features/registrar/contacts/list_spec.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+RSpec.feature 'Contact list', settings: false do
+ given!(:registrar) { create(:registrar) }
+ given!(:contact) { create(:contact, registrar: registrar) }
+
+ background do
+ sign_in_to_registrar_area(user: create(:api_user_with_unlimited_balance, registrar: registrar))
+ end
+
+ it 'is visible' do
+ visit registrar_contacts_path
+ expect(page).to have_css('.contacts')
+ end
+end
diff --git a/spec/lib/validators/e164.rb b/spec/lib/validators/e164.rb
new file mode 100644
index 000000000..bfb4914a3
--- /dev/null
+++ b/spec/lib/validators/e164.rb
@@ -0,0 +1,29 @@
+# https://en.wikipedia.org/wiki/E.164
+
+RSpec.shared_examples 'e164' do
+ describe 'validation' do
+ it 'rejects invalid format' do
+ model.send("#{attribute}=", '+.1')
+ model.validate
+ expect(model.errors).to be_added(attribute, :invalid)
+ end
+
+ it 'rejects longer than max length' do
+ model.send("#{attribute}=", '1' * 18)
+ model.validate
+ expect(model.errors).to be_added(attribute, :too_long, count: 17)
+ end
+
+ it 'accepts valid format' do
+ model.send("#{attribute}=", '+123.4')
+ model.validate
+ expect(model.errors).to_not be_added(attribute, :invalid)
+ end
+
+ it 'accepts max length' do
+ model.send("#{attribute}=", '1' * 17)
+ model.validate
+ expect(model.errors).to_not be_added(attribute, :too_long, count: 17)
+ end
+ end
+end
diff --git a/spec/lib/validators/iso31661_alpha2.rb b/spec/lib/validators/iso31661_alpha2.rb
new file mode 100644
index 000000000..618a68cfb
--- /dev/null
+++ b/spec/lib/validators/iso31661_alpha2.rb
@@ -0,0 +1,17 @@
+# https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
+
+RSpec.shared_examples 'iso31661_alpha2' do
+ describe 'validation' do
+ it 'rejects invalid' do
+ model.send("#{attribute}=", 'invalid')
+ model.validate
+ expect(model.errors).to be_added(attribute, :invalid_iso31661_alpha2)
+ end
+
+ it 'accepts valid' do
+ model.send("#{attribute}=", 'US')
+ model.validate
+ expect(model.errors).to_not be_added(attribute, :invalid_iso31661_alpha2)
+ end
+ end
+end
diff --git a/spec/lib/validators/iso8601.rb b/spec/lib/validators/iso8601.rb
new file mode 100644
index 000000000..78d8f2c4a
--- /dev/null
+++ b/spec/lib/validators/iso8601.rb
@@ -0,0 +1,17 @@
+# https://en.wikipedia.org/wiki/ISO_8601
+
+RSpec.shared_examples 'iso8601' do
+ describe 'validation' do
+ it 'rejects invalid' do
+ model.send("#{attribute}=", '2010-07-0')
+ model.validate
+ expect(model.errors).to be_added(attribute, :invalid_iso8601_date)
+ end
+
+ it 'accepts valid' do
+ model.send("#{attribute}=", '2010-07-05')
+ model.validate
+ expect(model.errors).to_not be_added(attribute, :invalid_iso8601_date)
+ end
+ end
+end
diff --git a/spec/models/contact/contact_phone_spec.rb b/spec/models/contact/contact_phone_spec.rb
new file mode 100644
index 000000000..cc1ecbec0
--- /dev/null
+++ b/spec/models/contact/contact_phone_spec.rb
@@ -0,0 +1,33 @@
+require 'rails_helper'
+require 'lib/validators/e164'
+
+RSpec.describe Contact do
+ let(:contact) { described_class.new }
+
+ describe 'phone', db: false do
+ it_behaves_like 'e164' do
+ let(:model) { contact }
+ let(:attribute) { :phone }
+ end
+ end
+
+ describe 'phone validation', db: false do
+ it 'rejects absent' do
+ contact.phone = nil
+ contact.validate
+ expect(contact.errors).to be_added(:phone, :blank)
+ end
+
+ it 'rejects all zeros in country code' do
+ contact.phone = '+000.1'
+ contact.validate
+ expect(contact.errors).to be_added(:phone, :invalid)
+ end
+
+ it 'rejects all zeros in subscriber number' do
+ contact.phone = '+123.0'
+ contact.validate
+ expect(contact.errors).to be_added(:phone, :invalid)
+ end
+ end
+end
diff --git a/spec/models/contact/ident_spec.rb b/spec/models/contact/ident_spec.rb
new file mode 100644
index 000000000..d26f76d0f
--- /dev/null
+++ b/spec/models/contact/ident_spec.rb
@@ -0,0 +1,227 @@
+require 'active_model'
+require 'lib/validators/iso31661_alpha2'
+require 'lib/validators/iso8601'
+
+RSpec.describe Contact::Ident, db: false do
+ let(:ident) { described_class.new }
+
+ describe 'country code' do
+ it_behaves_like 'iso31661_alpha2' do
+ let(:model) { ident }
+ let(:attribute) { :country_code }
+ end
+ end
+
+ describe 'code validation' do
+ it 'rejects absent' do
+ ident.code = nil
+ ident.validate
+ expect(ident.errors).to be_added(:code, :blank)
+ end
+
+ context 'when type is :birthday' do
+ let(:ident) { described_class.new(type: 'birthday') }
+
+ it_behaves_like 'iso8601' do
+ let(:model) { ident }
+ let(:attribute) { :code }
+ end
+ end
+
+ context 'when type is not :birthday' do
+ let(:ident) { described_class.new(type: 'priv') }
+
+ it 'accepts any' do
+ ident.code = '%123456789%'
+ ident.validate
+ expect(ident.errors).to_not include(:code)
+ end
+ end
+
+ context 'when country code is EE' do
+ context 'when type is :priv' do
+ let(:ident) { described_class.new(country_code: 'EE', type: 'priv') }
+
+ it 'rejects invalid' do
+ ident.code = 'invalid'
+ ident.validate
+ expect(ident.errors).to be_added(:code, :invalid_national_id, country: 'Estonia')
+ end
+
+ it 'accepts valid' do
+ ident.code = '47101010033'
+ ident.validate
+ expect(ident.errors).to_not be_added(:code, :invalid_national_id, country: 'Estonia')
+ end
+ end
+
+ context 'when ident type is :org' do
+ let(:ident) { described_class.new(country_code: 'EE', type: 'org') }
+
+ it 'rejects invalid' do
+ ident.code = '1' * 7
+ ident.validate
+ expect(ident.errors).to be_added(:code, :invalid_reg_no, country: 'Estonia')
+ end
+
+ it 'accepts valid length' do
+ ident.code = '1' * 8
+ ident.validate
+ expect(ident.errors).to_not be_added(:code, :invalid_reg_no, country: 'Estonia')
+ end
+ end
+ end
+
+ context 'when ident country code is not EE' do
+ let(:ident) { described_class.new(country_code: 'US') }
+
+ it 'accepts any' do
+ ident.code = 'test-123456789'
+ ident.validate
+ expect(ident.errors).to_not include(:code)
+ end
+ end
+
+ it 'translates :invalid_national_id error message' do
+ expect(ident.errors.generate_message(:code, :invalid_national_id, country: 'Germany'))
+ .to eq('does not conform to national identification number format of Germany')
+ end
+
+ it 'translates :invalid_reg_no error message' do
+ expect(ident.errors.generate_message(:code, :invalid_reg_no, country: 'Germany'))
+ .to eq('does not conform to registration number format of Germany')
+ end
+ end
+
+ describe 'type validation' do
+ before do
+ allow(described_class).to receive(:types).and_return(%w(valid))
+ end
+
+ it 'rejects absent' do
+ ident.type = nil
+ ident.validate
+ expect(ident.errors).to be_added(:type, :blank)
+ end
+
+ it 'rejects invalid' do
+ ident.type = 'invalid'
+ ident.validate
+ expect(ident.errors).to be_added(:type, :inclusion)
+ end
+
+ it 'accepts valid' do
+ ident.type = 'valid'
+ ident.validate
+ expect(ident.errors).to_not be_added(:type, :inclusion)
+ end
+ end
+
+ describe 'country code validation' do
+ it 'rejects absent' do
+ ident.country_code = nil
+ ident.validate
+ expect(ident.errors).to be_added(:country_code, :blank)
+ end
+ end
+
+ describe 'mismatch validation' do
+ let(:ident) { described_class.new(type: 'test', country_code: 'DE') }
+
+ before do
+ mismatches = [Contact::Ident::MismatchValidator::Mismatch.new('test', Country.new('DE'))]
+ allow(Contact::Ident::MismatchValidator).to receive(:mismatches).and_return(mismatches)
+ end
+
+ it 'rejects mismatched' do
+ ident.validate
+ expect(ident.errors).to be_added(:base, :mismatch, type: 'test', country: 'Germany')
+ end
+
+ it 'accepts matched' do
+ ident.validate
+ expect(ident.errors).to_not be_added(:base, :mismatch, type: 'another-test', country: 'Germany')
+ end
+
+ it 'translates :mismatch error message' do
+ expect(ident.errors.generate_message(:base, :mismatch, type: 'test', country: 'Germany'))
+ .to eq('Ident type "test" is invalid for Germany')
+ end
+ end
+
+ describe '::types' do
+ it 'returns types' do
+ types = %w[
+ org
+ priv
+ birthday
+ ]
+
+ expect(described_class.types).to eq(types)
+ end
+ end
+
+ describe '#birthday?' do
+ context 'when type is birthday' do
+ subject(:ident) { described_class.new(type: 'birthday') }
+ it { is_expected.to be_birthday }
+ end
+
+ context 'when type is not birthday' do
+ subject(:ident) { described_class.new(type: 'priv') }
+ it { is_expected.to_not be_birthday }
+ end
+ end
+
+ describe '#national_id?' do
+ context 'when type is priv' do
+ subject(:ident) { described_class.new(type: 'priv') }
+ it { is_expected.to be_national_id }
+ end
+
+ context 'when type is not' do
+ subject(:ident) { described_class.new(type: 'org') }
+ it { is_expected.to_not be_national_id }
+ end
+ end
+
+ describe '#reg_no?' do
+ context 'when type is birthday' do
+ subject(:ident) { described_class.new(type: 'org') }
+ it { is_expected.to be_reg_no }
+ end
+
+ context 'when type is not birthday' do
+ subject(:ident) { described_class.new(type: 'priv') }
+ it { is_expected.to_not be_reg_no }
+ end
+ end
+
+ describe '#country' do
+ let(:ident) { described_class.new(country_code: 'US') }
+
+ it 'returns country' do
+ expect(ident.country).to eq(Country.new('US'))
+ end
+ end
+
+ describe '#==' do
+ let(:ident) { described_class.new(code: 'test', type: 'test', country_code: 'US') }
+
+ context 'when code, type and country code are the same' do
+ let(:another_ident) { described_class.new(code: 'test', type: 'test', country_code: 'US') }
+
+ it 'returns true' do
+ expect(ident).to eq(another_ident)
+ end
+ end
+
+ context 'when code, type and country code are not the same' do
+ let(:another_ident) { described_class.new(code: 'another-test', type: 'test', country_code: 'US') }
+
+ it 'returns false' do
+ expect(ident).to_not eq(another_ident)
+ end
+ end
+ end
+end
diff --git a/spec/models/contact_spec.rb b/spec/models/contact_spec.rb
index e16ef2973..80dfb47ad 100644
--- a/spec/models/contact_spec.rb
+++ b/spec/models/contact_spec.rb
@@ -28,45 +28,6 @@ RSpec.describe Contact do
@contact.updator.should == nil
end
- it 'should require country code when org' do
- @contact.ident_type = 'org'
- @contact.valid?
- @contact.errors[:ident_country_code].should == ['is missing']
- end
-
- it 'should require country code when priv' do
- @contact.ident_type = 'priv'
- @contact.valid?
- @contact.errors[:ident_country_code].should == ['is missing']
- end
-
- it 'should validate correct country code' do
- @contact.ident = 1
- @contact.ident_type = 'org'
- @contact.ident_country_code = 'EE'
- @contact.valid?
-
- @contact.errors[:ident_country_code].should == []
- end
-
- it 'should require valid country code' do
- @contact.ident = '123'
- @contact.ident_type = 'org'
- @contact.ident_country_code = 'INVALID'
- @contact.valid?
-
- expect(@contact.errors).to have_key(:ident)
- end
-
- it 'should convert to alpha2 country code' do
- @contact.ident = 1
- @contact.ident_type = 'org'
- @contact.ident_country_code = 'ee'
- @contact.validate
-
- @contact.ident_country_code.should == 'EE'
- end
-
it 'should not have any versions' do
@contact.versions.should == []
end
@@ -119,14 +80,6 @@ RSpec.describe Contact do
@contact.domains_present?.should == false
end
- it 'org should be valid' do
- contact = build(:contact, ident_type: 'org', ident: '1' * 8)
-
- contact.validate
-
- contact.errors.full_messages.should match_array([])
- end
-
it 'should not overwrite code' do
old_code = @contact.code
@contact.code = 'CID:REG1:should-not-overwrite-old-code-12345'
@@ -217,31 +170,6 @@ RSpec.describe Contact do
end
end
- context 'as birthday' do
- before :example do
- @contact.ident_type = 'birthday'
- end
-
- it 'birthday should be valid' do
- valid = ['2012-12-11', '1990-02-16']
- valid.each do |date|
- @contact.ident = date
- @contact.valid?
- @contact.errors.full_messages.should match_array([])
- end
- end
-
- it 'birthday should be invalid' do
- invalid = ['123' '12/12/2012', 'aaaa', '12/12/12', '02-11-1999']
- invalid.each do |date|
- @contact.ident = date
- @contact.valid?
- @contact.errors.full_messages.should ==
- ["Ident Ident not in valid birthady format, should be YYYY-MM-DD"]
- end
- end
- end
-
context 'with callbacks' do
before :example do
# Ensure callbacks are not taken out from other specs
@@ -445,7 +373,7 @@ RSpec.describe Contact do
end
end
- describe 'country code validation' do
+ describe 'country code validation', db: false do
let(:contact) { described_class.new(country_code: 'test') }
it 'rejects invalid' do
@@ -455,37 +383,25 @@ RSpec.describe Contact do
end
end
- describe 'phone validation', db: false do
+ describe 'identifier validation', db: false do
let(:contact) { described_class.new }
- it 'rejects absent' do
- contact.phone = nil
+ it 'rejects invalid' do
+ ident = Contact::Ident.new
+ ident.validate
+ contact.identifier = ident
contact.validate
- expect(contact.errors).to have_key(:phone)
- end
- it 'rejects invalid format' do
- contact.phone = '123'
- contact.validate
- expect(contact.errors).to have_key(:phone)
- end
-
- it 'rejects all zeros in country code' do
- contact.phone = '+000.1'
- contact.validate
- expect(contact.errors).to have_key(:phone)
- end
-
- it 'rejects all zeros in phone number' do
- contact.phone = '+123.0'
- contact.validate
- expect(contact.errors).to have_key(:phone)
+ expect(contact.errors).to be_added(:identifier, :invalid)
end
it 'accepts valid' do
- contact.phone = '+123.4'
+ ident = Contact::Ident.new(code: 'test', type: 'priv', country_code: 'US')
+ ident.validate
+ contact.identifier = ident
contact.validate
- expect(contact.errors).to_not have_key(:phone)
+
+ expect(contact.errors).to_not be_added(:identifier, :invalid)
end
end
@@ -595,4 +511,13 @@ RSpec.describe Contact do
expect(domain_names).to eq({ 'test.com' => %i[admin_domain_contact].to_set })
end
end
+
+ it 'normalizes ident country code', db: false do
+ contact = described_class.new
+
+ contact.ident_country_code = 'ee'
+ contact.validate
+
+ expect(contact.ident_country_code).to eq('EE')
+ end
end
diff --git a/spec/models/epp/response/result_spec.rb b/spec/models/epp/response/result_spec.rb
new file mode 100644
index 000000000..606a4c2de
--- /dev/null
+++ b/spec/models/epp/response/result_spec.rb
@@ -0,0 +1,21 @@
+require 'rails_helper'
+
+RSpec.describe EPP::Response::Result, db: false do
+ # https://tools.ietf.org/html/rfc5730#section-3
+ describe '::codes' do
+ it 'returns codes' do
+ codes = {
+ '1000' => :success,
+ '1001' => :success_pending,
+ '1300' => :success_empty_queue,
+ '1301' => :success_dequeue,
+ '2001' => :syntax_error,
+ '2003' => :required_param_missing,
+ '2005' => :param_syntax_error,
+ '2308' => :data_management_policy_violation
+ }
+
+ expect(described_class.codes).to eq(codes)
+ end
+ end
+end
diff --git a/spec/models/registrar_spec.rb b/spec/models/registrar_spec.rb
index 1403ee72c..4a8110d45 100644
--- a/spec/models/registrar_spec.rb
+++ b/spec/models/registrar_spec.rb
@@ -35,10 +35,6 @@ describe Registrar do
@registrar.reference_no.should_not be_blank
@registrar.reference_no.last(10).to_i.should_not == 0
end
-
- it 'should not have priv contacts' do
- @registrar.priv_contacts.size.should == 0
- end
end
context 'with valid attributes' do
@@ -118,9 +114,5 @@ describe Registrar do
registrar.valid?
registrar.errors.full_messages.should == ['Code is forbidden to use']
end
-
- it 'should not have priv contacts' do
- @registrar.priv_contacts.size.should == 0
- end
end
end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index 966d68b60..f4dcd9cb3 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -10,6 +10,7 @@ require 'support/requests/epp_helpers'
require 'support/features/session_helpers'
require 'support/matchers/alias_attribute'
require 'support/matchers/epp/code'
+require 'support/matchers/epp/have_result'
require 'support/capybara'
require 'support/devise'
@@ -28,7 +29,8 @@ RSpec.configure do |config|
config.include AbstractController::Translation, type: :request
config.include AbstractController::Translation, type: :feature
config.include AbstractController::Translation, type: :mailer
- config.include Requests::EPPHelpers, type: :request
+ config.include Requests::EPPHelpers, epp: true
+ config.include Matchers::EPP, epp: true
config.define_derived_metadata(file_path: %r[/spec/features/]) do |metadata|
metadata[:db] = true if metadata[:db].nil?
diff --git a/spec/requests/epp/contact/create/ident_spec.rb b/spec/requests/epp/contact/create/ident_spec.rb
new file mode 100644
index 000000000..e112e2618
--- /dev/null
+++ b/spec/requests/epp/contact/create/ident_spec.rb
@@ -0,0 +1,289 @@
+require 'rails_helper'
+
+RSpec.describe 'EPP contact:create' do
+ let(:request) { post '/epp/command/create', frame: request_xml }
+
+ before do
+ Setting.address_processing = false
+ sign_in_to_epp_area
+ end
+
+ context 'when all ident params are valid' do
+ let(:ident) { Contact.first.identifier }
+ let(:request_xml) { <<-XML
+
+
+
+
+
+
+ test
+
+ +1.2
+ test@test.com
+
+
+
+
+ test
+
+
+
+
+ XML
+ }
+
+ it 'creates a contact' do
+ expect { request }.to change { Contact.count }.from(0).to(1)
+ end
+
+ it 'saves ident type' do
+ request
+ expect(ident.type).to eq('priv')
+ end
+
+ it 'saves ident country code' do
+ request
+ expect(ident.country_code).to eq('US')
+ end
+
+ specify do
+ request
+ expect(epp_response).to have_result(:success)
+ end
+ end
+
+ context 'when code is blank' do
+ let(:request_xml) { <<-XML
+
+
+
+
+
+
+ test
+
+ +1.2
+ test@test.com
+
+
+
+
+
+
+
+
+
+ XML
+ }
+
+ it 'does not create a contact' do
+ expect { request }.to_not change { Contact.count }
+ end
+
+ specify do
+ request
+ expect(epp_response).to have_result(:required_param_missing,
+ 'Required parameter missing: extension > extdata > ident [ident]')
+ end
+ end
+
+ context 'when code is not valid national id' do
+ let(:request_xml) { <<-XML
+
+
+
+
+
+
+ test
+
+ +1.2
+ test@test.com
+
+
+
+
+ invalid
+
+
+
+
+ XML
+ }
+
+ before do
+ country_specific_validations = {
+ Country.new('DE') => proc { false },
+ }
+
+ allow(Contact::Ident::NationalIdValidator).to receive(:country_specific_validations)
+ .and_return(country_specific_validations)
+ end
+
+ it 'does not create a contact' do
+ expect { request }.to_not change { Contact.count }
+ end
+
+ specify do
+ request
+
+ message = 'Ident code does not conform to national identification number format of Germany'
+ expect(epp_response).to have_result(:param_syntax_error, message)
+ end
+ end
+
+ context 'when code is not valid registration number' do
+ let(:request_xml) { <<-XML
+
+
+
+
+
+
+ test
+
+ +1.2
+ test@test.com
+
+
+
+
+ invalid
+
+
+
+
+ XML
+ }
+
+ before do
+ country_specific_formats = {
+ Country.new('DE') => /\Avalid\z/,
+ }
+
+ allow(Contact::Ident::RegNoValidator).to receive(:country_specific_formats).and_return(country_specific_formats)
+ end
+
+ it 'does not create a contact' do
+ expect { request }.to_not change { Contact.count }
+ end
+
+ specify do
+ request
+ expect(epp_response).to have_result(:param_syntax_error,
+ 'Ident code does not conform to registration number format of Germany')
+ end
+ end
+
+ context 'when country code is absent' do
+ let(:request_xml) { <<-XML
+
+
+
+
+
+
+ test
+
+ +1.2
+ test@test.com
+
+
+
+
+ test
+
+
+
+
+ XML
+ }
+
+ it 'does not create a contact' do
+ expect { request }.to_not change { Contact.count }
+ end
+
+ specify do
+ request
+ expect(epp_response).to have_result(:required_param_missing,
+ 'Required ident attribute missing: cc')
+ end
+ end
+
+ context 'when country code is blank' do
+ let(:request_xml) { <<-XML
+
+
+
+
+
+
+ test
+
+ +1.2
+ test@test.com
+
+
+
+
+ test
+
+
+
+
+ XML
+ }
+
+ it 'does not create a contact' do
+ expect { request }.to_not change { Contact.count }
+ end
+
+ specify do
+ request
+ expect(epp_response).to have_result(:syntax_error)
+ end
+ end
+
+ context 'when mismatches' do
+ let(:request_xml) { <<-XML
+
+
+
+
+
+
+ test
+
+ +1.2
+ test@test.com
+
+
+
+
+ test
+
+
+
+
+ XML
+ }
+
+ before do
+ mismatches = [
+ Contact::Ident::MismatchValidator::Mismatch.new('priv', Country.new('DE'))
+ ]
+ allow(Contact::Ident::MismatchValidator).to receive(:mismatches).and_return(mismatches)
+ end
+
+ it 'does not create a contact' do
+ expect { request }.to_not change { Contact.count }
+ end
+
+ specify do
+ request
+ expect(epp_response).to have_result(:param_syntax_error,
+ 'Ident type "priv" is invalid for Germany')
+ end
+ end
+end
diff --git a/spec/requests/epp/contact/update/ident_spec.rb b/spec/requests/epp/contact/update/ident_spec.rb
new file mode 100644
index 000000000..c93ba6390
--- /dev/null
+++ b/spec/requests/epp/contact/update/ident_spec.rb
@@ -0,0 +1,196 @@
+require 'rails_helper'
+
+# https://github.com/internetee/registry/issues/576
+
+RSpec.describe 'EPP contact:update' do
+ let(:ident) { contact.identifier }
+ let(:request) { post '/epp/command/update', frame: request_xml }
+ let(:request_xml) { <<-XML
+
+
+
+
+
+ TEST
+
+
+ test
+
+
+
+
+
+
+ test
+
+
+
+
+ XML
+ }
+
+ before do
+ sign_in_to_epp_area
+ end
+
+ context 'when contact ident is valid' do
+ context 'when submitted ident matches current one' do
+ let!(:contact) { create(:contact, code: 'TEST',
+ ident: 'test',
+ ident_type: 'priv',
+ ident_country_code: 'US') }
+
+ specify do
+ request
+ expect(epp_response).to have_result(:success)
+ end
+ end
+
+ context 'when submitted ident does not match current one' do
+ let!(:contact) { create(:contact, code: 'TEST',
+ ident: 'another-test',
+ ident_type: 'priv',
+ ident_country_code: 'US') }
+
+ it 'does not update code' do
+ expect do
+ request
+ contact.reload
+ end.to_not change { ident.code }
+ end
+
+ it 'does not update type' do
+ expect do
+ request
+ contact.reload
+ end.to_not change { ident.type }
+ end
+
+ it 'does not update country code' do
+ expect do
+ request
+ contact.reload
+ end.to_not change { ident.country_code }
+ end
+
+ specify do
+ request
+
+ expect(epp_response).to have_result(:data_management_policy_violation,
+ t('epp.contacts.errors.valid_ident'))
+ end
+ end
+ end
+
+ context 'when contact ident is invalid' do
+ let(:contact) { build(:contact, code: 'TEST', ident: 'test', ident_type: nil, ident_country_code: nil) }
+
+ before do
+ contact.save(validate: false)
+ end
+
+ context 'when submitted ident is the same as current one' do
+ let(:request_xml) { <<-XML
+
+
+
+
+
+ TEST
+
+
+ test
+
+
+
+
+
+
+ test
+
+
+
+
+ XML
+ }
+
+ it 'does not update code' do
+ expect do
+ request
+ contact.reload
+ end.to_not change { ident.code }
+ end
+
+ it 'updates type' do
+ request
+ contact.reload
+ expect(ident.type).to eq('priv')
+ end
+
+ it 'updates country code' do
+ request
+ contact.reload
+ expect(ident.country_code).to eq('US')
+ end
+
+ specify do
+ request
+ expect(epp_response).to have_result(:success)
+ end
+ end
+
+ context 'when submitted ident is different from current one' do
+ let(:request_xml) { <<-XML
+
+
+
+
+
+ TEST
+
+
+ test
+
+
+
+
+
+
+ another-test
+
+
+
+
+ XML
+ }
+
+ it 'does not update code' do
+ expect do
+ request
+ contact.reload
+ end.to_not change { ident.code }
+ end
+
+ it 'does not update type' do
+ expect do
+ request
+ contact.reload
+ end.to_not change { ident.type }
+ end
+
+ it 'does not update country code' do
+ expect do
+ request
+ contact.reload
+ end.to_not change { ident.country_code }
+ end
+
+ specify do
+ request
+
+ expect(epp_response).to have_result(:data_management_policy_violation,
+ t('epp.contacts.errors.ident_update'))
+ end
+ end
+ end
+end
diff --git a/spec/support/matchers/epp/have_result.rb b/spec/support/matchers/epp/have_result.rb
new file mode 100644
index 000000000..7850082dd
--- /dev/null
+++ b/spec/support/matchers/epp/have_result.rb
@@ -0,0 +1,37 @@
+module Matchers
+ module EPP
+ class HaveResultMatcher
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def matches?(target)
+ @target = target
+
+ if @expected.message.present?
+ @target.results.any? { |result| result.code == @expected.code && result.message == @expected.message }
+ else
+ @target.results.any? { |result| result.code == @expected.code }
+ end
+ end
+
+ def failure_message
+ "expected #{@target.results} to have result #{@expected.inspect}"
+ end
+
+ def failure_message_when_negated
+ "expected #{@target.results} not to have result #{@expected.inspect}"
+ end
+
+ def description
+ "should have EPP code of #{@expected}"
+ end
+ end
+
+ def have_result(type, message = nil)
+ code = ::EPP::Response::Result.codes.key(type)
+ result = ::EPP::Response::Result.new(code, message)
+ HaveResultMatcher.new(result)
+ end
+ end
+end
diff --git a/spec/support/requests/epp_helpers.rb b/spec/support/requests/epp_helpers.rb
index beb8ca2c2..fb0175df1 100644
--- a/spec/support/requests/epp_helpers.rb
+++ b/spec/support/requests/epp_helpers.rb
@@ -7,5 +7,9 @@ module Requests
def valid_legal_document
Base64.encode64('a' * 5000)
end
+
+ def epp_response
+ EPP::Response.from_xml(response.body)
+ end
end
end
diff --git a/spec/validators/contact/ident/mismatch_validator_spec.rb b/spec/validators/contact/ident/mismatch_validator_spec.rb
new file mode 100644
index 000000000..dfb30fe09
--- /dev/null
+++ b/spec/validators/contact/ident/mismatch_validator_spec.rb
@@ -0,0 +1,13 @@
+require 'rails_helper'
+
+RSpec.describe Contact::Ident::MismatchValidator do
+ describe '::mismatches' do
+ it 'returns mismatches' do
+ mismatches = [
+ Contact::Ident::MismatchValidator::Mismatch.new('birthday', Country.new('EE'))
+ ]
+
+ expect(described_class.mismatches).to eq(mismatches)
+ end
+ end
+end