Merge remote-tracking branch 'origin/master' into 1580-registrar-api-contacts-endpoint

This commit is contained in:
Karl Erik Õunapuu 2020-11-17 09:55:32 +02:00
commit db50a89d85
No known key found for this signature in database
GPG key ID: C9DD647298A34764
51 changed files with 801 additions and 285 deletions

View file

@ -1,3 +1,35 @@
13.11.2020
* Fixed per registrar epp session limit [#729](https://github.com/internetee/registry/issues/729)
* Correct error code is returned on reaching session limit [#587](https://github.com/internetee/registry/issues/587)
* No logins within active session [#1313](https://github.com/internetee/registry/issues/1313)
06.11.2020
* Csv option to limit list of domains for bulk nameserver change in registrar portal [#1737](https://github.com/internetee/registry/issues/1737)
* New forceDelete email template for invalid contact data [#1178](https://github.com/internetee/registry/issues/1178)
05.11.2020
* Registrant API contact name update feature [#1724](https://github.com/internetee/registry/issues/1724)
* New email template for expired domains in forceDelete [#1725](https://github.com/internetee/registry/issues/1725)
* Cancelling forceDelete (FD) restores the state of the domain prior application of FD [#1136](https://github.com/internetee/registry/issues/1136)
04.11.2020
* Email notification templates for forceDelete are now automatically selected according to registrant type [#442](https://github.com/internetee/registry/issues/442)
03.11.2020
* Fixed registrant confirmation while forcedelete is set on a domain [#1729](https://github.com/internetee/registry/issues/1729)
* Fixed search in registrar domain view [#262](https://github.com/internetee/registry/issues/262)
* Fixed double status issue on setting forceDelete [#1135](https://github.com/internetee/registry/issues/1135)
28.10.2020
* Domain renew now canceles pending delete process [#1664](https://github.com/internetee/registry/issues/1664)
* Added multi-language support to whois disclaimer [#1703](https://github.com/internetee/registry/issues/1703)
27.10.2020
* Fixed 1 day delay in force delete for multi year registrations [#1720](https://github.com/internetee/registry/issues/1720)
20.10.2020
* ForceDelete mailer now respects option to not notify registrant [#1719](https://github.com/internetee/registry/pull/1719)
19.10.2020
* Improved logging for LHV-connect messages [#1712](https://github.com/internetee/registry/issues/1712)
* LHV-connect gem update to handle blank descriptions [#1714](https://github.com/internetee/registry/issues/1714)

View file

@ -22,7 +22,7 @@ module Admin
send_email
domain.update(contact_notification_sent_date: Time.zone.today)
else
domain.update(template_name: params[:template_name])
domain.update(template_name: domain.notification_template)
end
end
@ -46,7 +46,7 @@ module Admin
DomainDeleteMailer.forced(domain: domain,
registrar: domain.registrar,
registrant: domain.registrant,
template_name: params[:template_name]).deliver_now
template_name: domain.notification_template).deliver_now
end
def force_delete_type

View file

@ -2,7 +2,6 @@ module Admin
class DomainsController < BaseController
before_action :set_domain, only: %i[show edit update keep]
authorize_resource
helper_method :force_delete_templates
def index
params[:q] ||= {}
@ -105,9 +104,5 @@ module Admin
params[:q][:valid_to_lteq] = ca_cache
end
def force_delete_templates
DomainDeleteMailer.force_delete_templates
end
end
end

View file

@ -79,19 +79,32 @@ module Epp
if success && EppSession.limit_reached?(@api_user.registrar)
epp_errors << {
msg: 'Authentication error; server closing connection (connection limit reached)',
code: '2501'
msg: 'Session limit exceeded; server closing connection (connection limit reached)',
code: '2502',
}
success = false
end
if success
if params[:parsed_frame].css('newPW').first
unless @api_user.update(plain_text_password: params[:parsed_frame].css('newPW').first.text)
handle_errors(@api_user) and return
new_password = params[:parsed_frame].at_css('newPW')&.text
password_change = new_password.present?
if password_change
@api_user.plain_text_password = new_password
@api_user.save!
end
already_authenticated = EppSession.exists?(session_id: epp_session_id)
if already_authenticated
epp_errors << {
msg: 'Command use error; Already authenticated',
code: 2002,
}
handle_errors
return
end
end
epp_session = EppSession.new
epp_session.session_id = epp_session_id
@ -100,8 +113,8 @@ module Epp
render_epp_response('login_success')
else
handle_errors
end
end
end
def ip_white?
webclient_request = ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip)
@ -125,7 +138,7 @@ module Epp
@api_user = current_user # cache current_user for logging
epp_session.destroy
render_epp_response('logout')
end
end
### HELPER METHODS ###

View file

@ -11,26 +11,27 @@ class Registrar
search_params[:name_matches].present?
domain = Domain.find_by(name: search_params[:name_matches])
if domain
redirect_to info_registrar_domains_url(domain_name: domain.name) and return
end
redirect_to info_registrar_domains_url(domain_name: domain.name) and return if domain
end
if params[:statuses_contains]
domains = current_registrar_user.registrar.domains.includes(:registrar, :registrant).where(
"statuses @> ?::varchar[]", "{#{params[:statuses_contains].join(',')}}"
)
else
domains = current_registrar_user.registrar.domains.includes(:registrar, :registrant)
domains = if params[:statuses_contains]
current_domain_scope.where('domains.statuses @> ?::varchar[]',
"{#{params[:statuses_contains].join(',')}}")
else
current_domain_scope
end
if params[:contacts_ident_eq]
domains = domains.where(contacts: { ident: params[:contacts_ident_eq] })
end
normalize_search_parameters do
@q = domains.search(search_params)
@q = domains.search(search_params.except(:contacts_ident_eq))
@domains = @q.result.page(params[:page])
# if we do not get any results, add wildcards to the name field and search again
if @domains.count == 0 && search_params[:name_matches] !~ /^%.+%$/
new_search_params = search_params.to_h
new_search_params = search_params.to_h.except(:contacts_ident_eq)
new_search_params[:name_matches] = "%#{new_search_params[:name_matches]}%"
@q = domains.search(new_search_params)
@domains = @q.result.page(params[:page])
@ -56,6 +57,10 @@ class Registrar
end
end
def current_domain_scope
current_registrar_user.registrar.domains.includes(:registrar, :registrant)
end
def info
authorize! :info, Depp::Domain
@data = @domain.info(params[:domain_name]) if params[:domain_name]

View file

@ -6,9 +6,12 @@ class Registrar
ipv4 = params[:ipv4].split("\r\n")
ipv6 = params[:ipv6].split("\r\n")
domains = domain_list_from_csv
uri = URI.parse("#{ENV['repp_url']}registrar/nameservers")
request = Net::HTTP::Put.new(uri, 'Content-Type' => 'application/json')
request.body = { data: { type: 'nameserver', id: params[:old_hostname],
domains: domains,
attributes: { hostname: params[:new_hostname],
ipv4: ipv4,
ipv6: ipv6 } } }.to_json
@ -55,5 +58,13 @@ class Registrar
render file: 'registrar/bulk_change/new', locals: { active_tab: :nameserver }
end
end
def domain_list_from_csv
return [] if params[:puny_file].blank?
domains = []
CSV.read(params[:puny_file].path, headers: true).each { |b| domains << b['domain_name'] }
domains
end
end
end

View file

@ -5,10 +5,13 @@ module Repp
before_action :verify_nameserver_existance, only: %i[update]
def update
domains = current_user.registrar
.replace_nameservers(hostname, hostname_params[:data][:attributes])
domains = params[:data][:domains] || []
affected = current_user.registrar
.replace_nameservers(hostname,
hostname_params[:data][:attributes],
domains: domains)
render_success(data: data_format_for_success(domains))
render_success(data: data_format_for_success(affected))
rescue ActiveRecord::RecordInvalid => e
handle_errors(e.record)
end
@ -16,15 +19,23 @@ module Repp
private
def data_format_for_success(affected_domains)
{ type: 'nameserver', id: params[:data][:attributes][:hostname],
attributes: params[:data][:attributes], affected_domains: affected_domains }
{
type: 'nameserver',
id: params[:data][:attributes][:hostname],
attributes: params[:data][:attributes],
affected_domains: affected_domains,
}
end
def hostname_params
params.require(:data).require(%i[type id])
params.require(:data).require(:attributes).require([:hostname])
params.permit(data: [:type, :id, attributes: [:hostname, ipv4: [], ipv6: []]])
params.permit(data: [
:type, :id,
{ domains: [],
attributes: [:hostname, { ipv4: [], ipv6: [] }] },
])
end
def hostname

View file

@ -4,6 +4,10 @@ class DomainExpireEmailJob < Que::Job
return if domain.registered?
DomainExpireMailer.expired(domain: domain, registrar: domain.registrar).deliver_now
if domain.force_delete_scheduled?
DomainExpireMailer.expired_soft(domain: domain, registrar: domain.registrar).deliver_now
else
DomainExpireMailer.expired(domain: domain, registrar: domain.registrar).deliver_now
end
end
end

View file

@ -1,8 +1,4 @@
class DomainDeleteMailer < ApplicationMailer
def self.force_delete_templates
%w[private_person legal_person]
end
def confirmation_request(domain:, registrar:, registrant:)
@domain = DomainPresenter.new(domain: domain, view: view_context)
@registrar = RegistrarPresenter.new(registrar: registrar, view: view_context)

View file

@ -1,19 +1,38 @@
class DomainExpireMailer < ApplicationMailer
attr_accessor :domain, :registrar
def expired(domain:, registrar:)
@domain = domain_presenter(domain: domain)
@registrar = registrar_presenter(registrar: registrar)
process_mail(domain: domain, registrar: registrar, method_name: __method__.to_s)
end
recipient = filter_invalid_emails(emails: domain.primary_contact_emails, domain: domain)
subject = default_i18n_subject(domain_name: domain.name)
logger.info("Send DomainExpireMailer#expired email for domain #{domain.name} (##{domain.id})" \
" to #{recipient.join(', ')}")
mail(to: recipient, subject: subject)
def expired_soft(domain:, registrar:)
process_mail(domain: domain, registrar: registrar, method_name: __method__.to_s)
end
private
def process_mail(domain:, registrar:, method_name:)
init(domain, registrar)
logger.info("Send DomainExpireMailer##{method_name} email for #{domain.name} (##{domain.id})" \
" to #{recipient(domain).join(', ')}")
mail(to: recipient(domain), subject: subject(method_name))
end
def init(domain, registrar)
@domain = domain_presenter(domain: domain)
@registrar = registrar_presenter(registrar: registrar)
end
def recipient(domain)
filter_invalid_emails(emails: domain.primary_contact_emails, domain: @domain)
end
def subject(method_name)
I18n.t("domain_expire_mailer.#{method_name}.subject", domain_name: @domain.name)
end
def domain_presenter(domain:)
DomainPresenter.new(domain: domain, view: view_context)
end

View file

@ -19,6 +19,16 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
end
def notification_template
if contact_emails_verification_failed.present?
'invalid_email'
elsif registrant.org?
'legal_person'
else
'private_person'
end
end
def force_delete_scheduled?
statuses.include?(DomainStatus::FORCE_DELETE)
end
@ -80,8 +90,8 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def cancel_force_delete
restore_statuses_before_force_delete
remove_force_delete_statuses
restore_statuses_before_force_delete
clear_force_delete_data
self.force_delete_date = nil
self.force_delete_start = nil
@ -106,7 +116,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def soft_delete_dates(years)
self.force_delete_start = valid_to - years.years + 1.day
self.force_delete_start = valid_to - years.years
self.force_delete_date = force_delete_start + Setting.expire_warning_period.days +
Setting.redemption_grace_period.days
end
@ -119,7 +129,7 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def preserve_current_statuses_for_force_delete
self.statuses_before_force_delete = statuses.clone
update(statuses_before_force_delete: statuses)
end
def restore_statuses_before_force_delete
@ -128,9 +138,9 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength
end
def add_force_delete_statuses
statuses << DomainStatus::FORCE_DELETE
statuses << DomainStatus::SERVER_RENEW_PROHIBITED
statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED
self.statuses |= [DomainStatus::FORCE_DELETE,
DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED]
end
def remove_force_delete_statuses

View file

@ -15,6 +15,10 @@ module Concerns
domain: domain(billing_email))
end
def email_verification_failed?
email_verification&.failed?
end
class_methods do
def domain(email)
Mail::Address.new(email).domain&.downcase || 'not_found'

View file

@ -15,7 +15,7 @@ module Concerns
domain.registrar.notifications.create!(text: I18n.t('grace_period_started_domain',
domain_name: domain.name,
date: domain.force_delete_start))
send_mail(domain)
send_mail(domain) if domain.template_name.present?
domain.update(contact_notification_sent_date: Time.zone.today)
end

View file

@ -320,8 +320,8 @@ class Domain < ApplicationRecord
def renew_blocking_statuses
disallowed = [DomainStatus::DELETE_CANDIDATE, DomainStatus::PENDING_RENEW,
DomainStatus::PENDING_TRANSFER, DomainStatus::CLIENT_RENEW_PROHIBITED,
DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE,
DomainStatus::PENDING_DELETE_CONFIRMATION, DomainStatus::SERVER_RENEW_PROHIBITED]
DomainStatus::PENDING_UPDATE, DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::PENDING_DELETE_CONFIRMATION]
(statuses & disallowed)
end
@ -384,7 +384,7 @@ class Domain < ApplicationRecord
end
def registrant_update_confirmable?(token)
return false if (statuses & [DomainStatus::FORCE_DELETE, DomainStatus::DELETE_CANDIDATE]).any?
return false if statuses.include? DomainStatus::DELETE_CANDIDATE
return false unless pending_update?
return false unless registrant_verification_asked?
return false unless registrant_verification_token == token
@ -642,6 +642,10 @@ class Domain < ApplicationRecord
DNS::DomainName.new(name)
end
def contact_emails_verification_failed
contacts.select(&:email_verification_failed?)&.map(&:email)&.uniq
end
def self.to_csv
CSV.generate do |csv|
csv << column_names

View file

@ -612,6 +612,7 @@ class Epp::Domain < Domain
statuses.delete(DomainStatus::SERVER_HOLD)
statuses.delete(DomainStatus::EXPIRED)
statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED)
cancel_pending_delete
save
end

View file

@ -30,6 +30,7 @@ module Epp
data_management_policy_violation: 2308,
command_failed: 2400,
authentication_error_server_closing_connection: 2501,
session_limit_exceeded_server_closing_connection: 2502,
}.freeze
private_constant :KEY_TO_VALUE
@ -59,6 +60,7 @@ module Epp
2308 => 'Data management policy violation',
2400 => 'Command failed',
2501 => 'Authentication error; server closing connection',
2502 => 'Session limit exceeded; server closing connection',
}.freeze
private_constant :DEFAULT_DESCRIPTIONS

View file

@ -6,19 +6,26 @@ class EppSession < ApplicationRecord
class_attribute :timeout
self.timeout = (ENV['epp_session_timeout_seconds'] || 300).to_i.seconds
class_attribute :sessions_per_registrar
self.sessions_per_registrar = (ENV['epp_sessions_per_registrar'] || 4).to_i
alias_attribute :last_access, :updated_at
def self.limit_per_registrar
4
end
scope :not_expired,
lambda {
where(':now <= (updated_at + interval :interval)', now: Time.zone.now, interval: interval)
}
def self.limit_reached?(registrar)
count = where(user_id: registrar.api_users.ids).where('updated_at >= ?', Time.zone.now - 1.second).count
count >= limit_per_registrar
count = where(user_id: registrar.api_users.ids).not_expired.count
count >= sessions_per_registrar
end
def self.interval
"#{timeout.parts.first.second} #{timeout.parts.first.first}"
end
def self.expired
interval = "#{timeout.parts.first.second} #{timeout.parts.first.first}"
where(':now > (updated_at + interval :interval)', now: Time.zone.now, interval: interval)
end

View file

@ -54,14 +54,25 @@ class RegistrantUser < User
username.split.second
end
def update_related_contacts
contacts = Contact.where(ident: ident, ident_country_code: country.alpha2)
.where('UPPER(name) != UPPER(?)', username)
contacts.each do |contact|
contact.update(name: username)
action = actions.create!(contact: contact, operation: :update)
contact.registrar.notify(action)
end
end
class << self
def find_or_create_by_api_data(user_data = {})
return false unless user_data[:ident]
return false unless user_data[:first_name]
return false unless user_data[:last_name]
user_data.each_value { |v| v.upcase! if v.is_a?(String) }
user_data[:country_code] ||= 'EE'
%i[ident country_code].each { |f| user_data[f].upcase! if user_data[f].is_a?(String) }
find_or_create_by_user_data(user_data)
end
@ -91,6 +102,7 @@ class RegistrantUser < User
user.username = "#{user_data[:first_name]} #{user_data[:last_name]}"
user.save
user.update_related_contacts
user
end
end

View file

@ -141,11 +141,13 @@ class Registrar < ApplicationRecord
end
# Audit log is needed, therefore no raw SQL
def replace_nameservers(hostname, new_attributes)
def replace_nameservers(hostname, new_attributes, domains: [])
transaction do
domain_list = []
nameservers.where(hostname: hostname).find_each do |original_nameserver|
next unless domains.include?(original_nameserver.domain.name_puny) || domains.empty?
new_nameserver = Nameserver.new
new_nameserver.domain = original_nameserver.domain
new_nameserver.attributes = new_attributes

View file

@ -52,6 +52,10 @@ class DomainPresenter
end
end
def contact_emails_verification_failed
domain.contact_emails_verification_failed.join(', ')
end
def remove_registry_lock_btn
return unless domain.locked_by_registrant?

View file

@ -33,12 +33,6 @@
</div>
</div>
<div class="form-group email-template-row">
<label class="col-md-3 control-label"><%= t '.email_template' %></label>
<div class="col-md-9">
<%= select_tag 'template_name', options_for_select(templates), class: 'form-control' %>
</div>
</div>
<% end %>
<div class="modal-footer">

View file

@ -32,4 +32,4 @@
</div>
<%= render 'form' %>
<%= render 'force_delete_dialog', domain: @domain, templates: force_delete_templates %>
<%= render 'force_delete_dialog', domain: @domain %>

View file

@ -0,0 +1,47 @@
<p>Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt</p>
<p>Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontaktandmed on puudulikud - eposti aadress <%= @domain.contact_emails_verification_failed %>.</p>
<p>Et see olukord on vastuolus .ee <a href='https://www.internet.ee/domains/ee-domain-regulation'>domeenireeglitega</a> algatas EIS <%= @delete_period_length %> päeva pikkuse kustutusmenetluse. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.</p>
<p>Andmete parandamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole või isiklike ja oma ettevõtte andmete puhul <a href="https://registrant.internet.ee/">registreerija portaali</a>.</p>
<p>Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile <a href="https://auction.internet.ee">.ee oksjonikeskkonda</a>. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe <a href="https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused">siit</a>.</p>
<p>Lisaküsimuste korral võtke palun ühendust oma registripidajaga:</p>
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>
<%= render 'mailers/shared/signatures/signature.et.html' %>
<hr>
<p>Dear registrant/administrative contact of .ee domain,</p>
<p>Estonian Internet Foundation has learned that contact data of the domain <%= @domain.name %> s invalid - email(s) <%= @domain.contact_emails_verification_failed %>.</p>
<p>Since this is a violation of <a href='https://www.internet.ee/domains/ee-domain-regulation'>Estonian domain regulations</a>, <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.</p>
<p>Please, contact your registrar <%= @registrar.name %> with updated contact data, or in case of your personal or business data use <a href="https://registrant.internet.ee/">.ee portal for registrants</a></p>
<p>If the data is not fixed within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the <a href="https://auction.internet.ee">.ee auction environment</a>. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">here</a>.</p>
<p>Should you have additional questions, please contact your registrar:</p>
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>
<%= render 'mailers/shared/signatures/signature.en.html' %>
<hr>
<p>Уважаемый регистрант/административный контакт домена .ee</p>
<p>Целевому учреждению Eesti Internet (EIS) стало известно, что контактные данные домена <%= @registrant.reg_no %> неверны - электронная почта <%= @domain.contact_emails_verification_failed %>.</p>
<p>Так как это является нарушением <a href='https://www.internet.ee/domains/ee-domain-regulation'>Правил домена .ee</a>, <%= @delete_period_length %>-дневный процесс удаления начат для доменного имени <%= @domain.name %>. В течение первых <%= @expire_warning_period %> дней домен будет доступен в интернете.</p>
<p>Для уточнения контактных данных, пожалуйста, свяжитесь с регистратором <%= @registrar.name %>, либо воспользуйтесь <a href="https://registrant.internet.ee/">порталом для регистрантов</a></p>
<p>Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в <a href="https://auction.internet.ee">аукционной среде.ee</a>. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">здесь</a>.</p>
<p>В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором:
<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %></p>
<%= render 'mailers/shared/signatures/signature.ru.html' %>

View file

@ -0,0 +1,47 @@
<p>Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt</p>
<p>Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontaktandmed on puudulikud - eposti aadress <%= @domain.contact_emails_verification_failed %></p>
<p>Et see olukord on vastuolus .ee <a href='https://www.internet.ee/domains/ee-domain-regulation'>domeenireeglitega</a> algatas EIS <%= @delete_period_length %> päeva pikkuse kustutusmenetluse. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.</p>
<p>Andmete parandamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole või isiklike ja oma ettevõtte andmete puhul <a href="https://registrant.internet.ee/">registreerija portaali</a>.</p>
<p>Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile <a href="https://auction.internet.ee">.ee oksjonikeskkonda</a>. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe <a href="https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused">siit</a>.</p>
<p>Lisaküsimuste korral võtke palun ühendust oma registripidajaga:</p>
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>
<%= render 'mailers/shared/signatures/signature.et.html' %>
<hr>
<p>Dear registrant/administrative contact of .ee domain,</p>
<p>Estonian Internet Foundation has learned that contact data of the domain <%= @domain.name %> s invalid - email(s) <%= @domain.contact_emails_verification_failed %>.</p>
<p>Since this is a violation of <a href='https://www.internet.ee/domains/ee-domain-regulation'>Estonian domain regulations</a>, <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.</p>
<p>Please, contact your registrar <%= @registrar.name %> with updated contact data, or in case of your personal or business data use <a href="https://registrant.internet.ee/">.ee portal for registrants</a></p>
<p>If the data is not fixed within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the <a href="https://auction.internet.ee">.ee auction environment</a>. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">here</a>.</p>
<p>Should you have additional questions, please contact your registrar:</p>
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>
<%= render 'mailers/shared/signatures/signature.en.html' %>
<hr>
<p>Уважаемый регистрант/административный контакт домена .ee</p>
<p>Целевому учреждению Eesti Internet (EIS) стало известно, что контактные данные домена <%= @registrant.reg_no %> неверны - электронная почта <%= @domain.contact_emails_verification_failed %>.</p>
<p>Так как это является нарушением <a href='https://www.internet.ee/domains/ee-domain-regulation'>Правил домена .ee</a>, <%= @delete_period_length %>-дневный процесс удаления начат для доменного имени <%= @domain.name %>. В течение первых <%= @expire_warning_period %> дней домен будет доступен в интернете.</p>
<p>Для уточнения контактных данных, пожалуйста, свяжитесь с регистратором <%= @registrar.name %>, либо воспользуйтесь <a href="https://registrant.internet.ee/">порталом для регистрантов</a></p>
<p>Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в <a href="https://auction.internet.ee">аукционной среде.ee</a>. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">здесь</a>.</p>
<p>В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором:
<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %></p>
<%= render 'mailers/shared/signatures/signature.ru.html' %>

View file

@ -0,0 +1,48 @@
<p>Domeen <%= @domain.name %> on aegunud ning suunatud kustutusmenetlusse kuna oleme tuvastanud domeeniga seotud kontaktides olulisi puudusi.</p>
<p>Lugupeetud .ee domeeni registreerija/halduskontakt</p>
<p>Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Domeeniga on seotud puudulike kontakti objekte, milles tulenevalt on Eesti Interneti SA blokeerinud domeeni pikendamise ja registripidaja vahetuse, kuniks kontaktandmed korrastatakse. Andmete korrastamiseks ja registreeringu pikendamiseks pöörduge palun oma registripidaja poole.</p>
<p><%= @domain.name %> pikendamata jätmisel domeen kustub ja läheb <%= @domain.delete_date %> oksjonile .ee oksjonikeskkonda. Domeenioksjonite kohta loe lähemalt <a href="https://www.internet.ee/domeenioksjonid">siit</a>.</p>
<p>Domeeni <%= @domain.name %> registripidaja:</p>
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>
<p>Ülevaate kõikidest endaga seotud domeenidest saate <a href="https://registrant.internet.ee/registrant/">registreerija portaalist</a>.</p>
<%= render 'mailers/shared/signatures/signature.et.html' %>
<hr>
<p>Domain <%= @domain.name %> has expired</p>
<p>Dear registrant/administrative contact of .ee domain,</p>
<p>The domain name <%= @domain.name %> has expired and since <%= @domain.on_hold_date %> is no longer available on the Internet. Domain registration has invalid contact data. Renewal and registrar transfer is therefore prohibited until contact data has been fixed. To correct the data and renew your domain registration, please contact your registrar.</p>
<p>If you do not renew the <%= @domain.name %> domain registration, it is deleted and put on auction to .ee domain auction environment at <%= @domain.delete_date %>. Read more about .ee domain auctions <a href="https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment">here</a>.</p>
<p>Registrar of the <%= @domain.name %>:</p>
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>
<p>You can find an overview of all your domains at the <a href="https://registrant.internet.ee/registrant/">registrant's portal</a>.</p>
<%= render 'mailers/shared/signatures/signature.en.html' %>
<hr>
<p>Срок действия домена <%= @domain.name %> истек</p>
<p>Уважаемый регистрант/административный контакт домена .ee</p>
<p>Срок действия доменного имени <%= @domain.name %> истек, и с <%= @domain.on_hold_date %> оно больше не доступно в интернете. У домена указаны неверные контактные данные. Обновление и перенос к другому регистратору заблокированы до исправления контактных данных. Для исправления контактных данных и обновления регистрации вашего домена, пожалуйста, обратитесь в вашему регистратору.</p>
<p>Если доменное имя не продлено, домен <%= @domain.name %> будет удален и <%= @domain.delete_date %> идет на аукцион в .ee среду аукциона. О проведении доменных аукционов читайте <a href="https://www.internet.ee/domeny/dogovor-pol-zovatelya-aukcionnoj-sredy#3-usloviya-uchastiya-v-aukcione">здесь</a>.</p>
<p>Pегистратор домена <%= @domain.name %>:</p>
<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>
<p>Обзор всех связанных с вами доменов можете получить на <a href="https://registrant.internet.ee/registrant/">портале регистратора.</a></p>
<%= render 'mailers/shared/signatures/signature.ru.html' %>

View file

@ -0,0 +1,48 @@
Domeen <%= @domain.name %> on aegunud ning suunatud kustutusmenetlusse kuna oleme tuvastanud domeeniga seotud kontaktides olulisi puudusi.
Lugupeetud .ee domeeni registreerija/halduskontakt
Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Domeeniga on seotud puudulike kontakti objekte, milles tulenevalt on Eesti Interneti SA blokeerinud domeeni pikendamise ja registripidaja vahetuse, kuniks kontaktandmed korrastatakse. Andmete korrastamiseks ja registreeringu pikendamiseks pöörduge palun oma registripidaja poole.
<%= @domain.name %> pikendamata jätmisel domeen kustub ja läheb <%= @domain.delete_date %> oksjonile .ee oksjonikeskkonda. Domeenioksjonite kohta loe lähemalt siit https://www.internet.ee/domeenioksjonid.
Domeeni <%= @domain.name %> registripidaja:
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>
Ülevaate kõikidest endaga seotud domeenidest saate registreerija portaalist https://registrant.internet.ee/registrant/.
<%= render 'mailers/shared/signatures/signature.et.html' %>
--------------------------------------
Domain <%= @domain.name %> has expired
Dear registrant/administrative contact of .ee domain,
The domain name <%= @domain.name %> has expired and since <%= @domain.on_hold_date %> is no longer available on the Internet. Domain registration has invalid contact data. Renewal and registrar transfer is therefore prohibited until contact data has been fixed. To correct the data and renew your domain registration, please contact your registrar.
If you do not renew the <%= @domain.name %> domain registration, it is deleted and put on auction to .ee domain auction environment at <%= @domain.delete_date %>. Read more about .ee domain auctions here https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment.
Registrar of the <%= @domain.name %>:
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>
You can find an overview of all your domains at the registrant's portal https://registrant.internet.ee/registrant/.
<%= render 'mailers/shared/signatures/signature.en.html' %>
--------------------------------------
Срок действия домена <%= @domain.name %> истек
Уважаемый регистрант/административный контакт домена .ee
Срок действия доменного имени <%= @domain.name %> истек, и с <%= @domain.on_hold_date %> оно больше не доступно в интернете. У домена указаны неверные контактные данные. Обновление и перенос к другому регистратору заблокированы до исправления контактных данных. Для исправления контактных данных и обновления регистрации вашего домена, пожалуйста, обратитесь в вашему регистратору.
Если доменное имя не продлено, домен <%= @domain.name %> будет удален и <%= @domain.delete_date %> идет на аукцион в .ee среду аукциона. О проведении доменных аукционов читайте здесь https://www.internet.ee/domeny/dogovor-pol-zovatelya-aukcionnoj-sredy#3-usloviya-uchastiya-v-aukcione.
Pегистратор домена <%= @domain.name %>:
<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>
Обзор всех связанных с вами доменов можете получить на портале регистратора https://registrant.internet.ee/registrant/.
<%= render 'mailers/shared/signatures/signature.ru.html' %>

View file

@ -1,4 +1,4 @@
<%= form_tag registrar_nameservers_path, method: :patch, class: 'form-horizontal' do %>
<%= form_tag registrar_nameservers_path, multipart: true, method: :patch, class: 'form-horizontal' do %>
<%= render 'registrar/domain_transfers/form/api_errors' %>
<div class="form-group">
@ -44,6 +44,16 @@
</div>
</div>
<div class="form-group">
<div class="col-md-2 control-label">
<%= label_tag 'List of domains' %>
</div>
<div class="col-md-4">
<%= file_field_tag :puny_file, required: false, accept: 'text/csv' %>
<span class="help-block">CSV format, must have domain_name field. List of domains that nameserver change should be scoped to.</span>
</div>
</div>
<div class="form-group">
<div class="col-md-4 col-md-offset-2 text-right">
<button class="btn btn-warning">

View file

@ -18,7 +18,8 @@
<div class="col-md-3">
<div class="form-group">
<%= f.label :contact_ident, for: nil %>
<%= f.search_field :contacts_ident_eq, class: 'form-control', placeholder: t(:contact_ident) %>
<%= f.search_field :contacts_ident_eq, value: search_params[:contacts_ident_eq],
class: 'form-control', placeholder: t(:contact_ident) %>
</div>
</div>

View file

@ -170,6 +170,8 @@ tara_rant_redirect_uri: 'redirect_uri'
default_email_validation_type: 'regex'
epp_sessions_per_registrar: '4'
# Since the keys for staging are absent from the repo, we need to supply them separate for testing.
test:
payments_seb_bank_certificate: 'test/fixtures/files/seb_bank_cert.pem'

View file

@ -5,3 +5,8 @@ en:
Domeen %{domain_name} on aegunud
/ Domain %{domain_name} has expired
/ Срок действия домена %{domain_name} истек
expired_soft:
subject: >-
Domeen %{domain_name} on aegunud ning suunatud kustutusmenetlusse
/ Domain %{domain_name} has expired and directed into deletion process
/ Срок действия домена %{domain_name} истек

View file

@ -0,0 +1,21 @@
class MakeWhoisDisclamerI18ned < ActiveRecord::Migration[6.0]
def up
entry = SettingEntry.find_by(code: 'registry_whois_disclaimer')
hash = { en: 'Search results may not be used for commercial, advertising, recompilation, repackaging, redistribution, reuse, obscuring or other similar activities.',
et: 'Otsitulemusi ei tohi kasutada ärilistel, reklaami, ümber töötlemise, edasi levitamise, taaskasutuse, muutmise ega muul sarnasel eesmärgil.',
ru: 'Результаты поиска не могут быть использованы в коммерческих целях, включая, но не ограничиваясь, рекламу, рекомпиляцию, изменение формата, перераспределение либо переиспользование.' }
string = JSON.generate(hash)
entry.format = 'hash'
entry.value = string
entry.save!
end
def down
entry = SettingEntry.find_by(code: 'registry_whois_disclaimer')
string = 'Search results may not be used for commercial, advertising, recompilation, \
repackaging, redistribution, reuse, obscuring or other similar activities.'
entry.format = 'string'
entry.value = string
entry.save!
end
end

View file

@ -1,2 +1,2 @@
# encoding: UTF-8
DataMigrate::Data.define(version: 20200901131427)
DataMigrate::Data.define(version: 20201007104651)

View file

@ -448,10 +448,9 @@ dispute_period_in_months:
registry_whois_disclaimer:
code: registry_whois_disclaimer
value: 'Search results may not be used for commercial, advertising, recompilation,
repackaging, redistribution, reuse, obscuring or other similar activities.'
value: "{\"en\":\"111\",\"et\":\"222\",\"ru\":\"333\"}"
group: contacts
format: string
format: hash
created_at: <%= Time.zone.parse('2010-07-05') %>
updated_at: <%= Time.zone.parse('2010-07-05') %>

View file

@ -1,64 +0,0 @@
require 'test_helper'
class EppLoginCredentialsTest < EppTestCase
def test_correct_credentials
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<login>
<clID>test_bestnames</clID>
<pw>testtest</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
</svcs>
</login>
</command>
</epp>
XML
post epp_login_path, params: { frame: request_xml },
headers: { 'HTTP_COOKIE' => 'session=new_session_id' }
assert EppSession.find_by(session_id: 'new_session_id')
assert_equal users(:api_bestnames), EppSession.find_by(session_id: 'new_session_id').user
assert_epp_response :completed_successfully
end
def test_already_logged_in
assert true # Handled by EPP proxy
end
def test_wrong_credentials
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<login>
<clID>non-existent</clID>
<pw>valid-but-wrong</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
</svcs>
</login>
</command>
</epp>
XML
post epp_login_path, params: { frame: request_xml },
headers: { 'HTTP_COOKIE' => 'session=any_random_string' }
assert_epp_response :authentication_error_server_closing_connection
end
end

View file

@ -1,32 +0,0 @@
require 'test_helper'
class EppLoginPasswordChangeTest < EppTestCase
def test_password_change
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<login>
<clID>test_bestnames</clID>
<pw>testtest</pw>
<newPW>new-password</newPW>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
</svcs>
</login>
</command>
</epp>
XML
post epp_login_path, params: { frame: request_xml },
headers: { 'HTTP_COOKIE' => 'session=new_session_id' }
assert_equal 'new-password', users(:api_bestnames).plain_text_password
assert_epp_response :completed_successfully
end
end

View file

@ -1,61 +0,0 @@
require 'test_helper'
class EppLoginSessionLimitTest < EppTestCase
setup do
travel_to Time.zone.parse('2010-07-05')
EppSession.delete_all
end
def test_not_reached
(EppSession.limit_per_registrar - 1).times do
EppSession.create!(session_id: SecureRandom.hex,
user: users(:api_bestnames),
updated_at: Time.zone.parse('2010-07-05'))
end
assert_difference 'EppSession.count' do
post epp_login_path, params: { frame: request_xml },
headers: { 'HTTP_COOKIE' => 'session=new_session_id' }
end
assert_epp_response :completed_successfully
end
def test_reached
EppSession.limit_per_registrar.times do
EppSession.create!(session_id: SecureRandom.hex,
user: users(:api_bestnames),
updated_at: Time.zone.parse('2010-07-05'))
end
assert_no_difference 'EppSession.count' do
post epp_login_path, params: { frame: request_xml },
headers: { 'HTTP_COOKIE' => 'session=new_session_id' }
end
assert_epp_response :authentication_error_server_closing_connection
end
private
def request_xml
<<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<login>
<clID>test_bestnames</clID>
<pw>testtest</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
</svcs>
</login>
</command>
</epp>
XML
end
end

View file

@ -0,0 +1,189 @@
require 'test_helper'
class EppLoginTest < EppTestCase
setup do
@original_sessions_per_registrar_setting = EppSession.sessions_per_registrar
end
teardown do
EppSession.sessions_per_registrar = @original_sessions_per_registrar_setting
end
def test_logging_in_with_correct_credentials_creates_new_session
user = users(:api_bestnames)
new_session_id = 'new-session-id'
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<login>
<clID>#{user.username}</clID>
<pw>#{user.plain_text_password}</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>
</svcs>
</login>
</command>
</epp>
XML
assert_difference 'EppSession.count' do
post '/epp/session/login', params: { frame: request_xml },
headers: { 'HTTP_COOKIE' => "session=#{new_session_id}" }
end
assert_epp_response :completed_successfully
session = EppSession.last
assert_equal new_session_id, session.session_id
assert_equal user, session.user
end
def test_user_cannot_login_again
session = epp_sessions(:api_bestnames)
user = session.user
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<login>
<clID>#{user.username}</clID>
<pw>#{user.plain_text_password}</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>
</svcs>
</login>
</command>
</epp>
XML
assert_no_difference 'EppSession.count' do
post '/epp/session/login', params: { frame: request_xml },
headers: { HTTP_COOKIE: "session=#{session.session_id}" }
end
assert_epp_response :use_error
end
def test_user_cannot_login_with_wrong_credentials
user = users(:api_bestnames)
wrong_password = 'a' * ApiUser.min_password_length
assert_not_equal wrong_password, user.plain_text_password
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<login>
<clID>#{user.username}</clID>
<pw>#{wrong_password}</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>
</svcs>
</login>
</command>
</epp>
XML
assert_no_difference 'EppSession.count' do
post '/epp/session/login', params: { frame: request_xml },
headers: { 'HTTP_COOKIE' => 'session=new-session-id' }
end
assert_epp_response :authentication_error_server_closing_connection
end
def test_password_change
user = users(:api_bestnames)
new_password = 'a' * ApiUser.min_password_length
assert_not_equal new_password, user.plain_text_password
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<login>
<clID>#{user.username}</clID>
<pw>#{user.plain_text_password}</pw>
<newPW>#{new_password}</newPW>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>
</svcs>
</login>
</command>
</epp>
XML
post '/epp/session/login', params: { frame: request_xml },
headers: { 'HTTP_COOKIE' => 'session=new-session-id' }
user.reload
assert_epp_response :completed_successfully
assert_equal new_password, user.plain_text_password
end
def test_user_cannot_login_when_max_allowed_sessions_per_registrar_is_exceeded
user = users(:api_bestnames)
eliminate_effect_of_existing_epp_sessions
EppSession.sessions_per_registrar = 1
EppSession.create!(session_id: 'any', user: user)
request_xml = <<-XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="https://epp.tld.ee/schema/epp-ee-1.0.xsd">
<command>
<login>
<clID>#{user.username}</clID>
<pw>#{user.plain_text_password}</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>https://epp.tld.ee/schema/domain-eis-1.0.xsd</objURI>
<objURI>https://epp.tld.ee/schema/contact-ee-1.1.xsd</objURI>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:keyrelay-1.0</objURI>
</svcs>
</login>
</command>
</epp>
XML
assert_no_difference 'EppSession.count' do
post '/epp/session/login', params: { frame: request_xml },
headers: { 'HTTP_COOKIE' => 'session=new-session-id' }
end
assert_epp_response :session_limit_exceeded_server_closing_connection
end
private
def eliminate_effect_of_existing_epp_sessions
EppSession.delete_all
end
end

View file

@ -5,10 +5,6 @@ class DomainDeleteMailerTest < ActionMailer::TestCase
@domain = domains(:shop)
end
def test_force_delete_templates
assert_equal %w[private_person legal_person], DomainDeleteMailer.force_delete_templates
end
def test_delivers_confirmation_request_email
assert_equal 'shop.test', @domain.name
assert_equal 'john@inbox.test', @domain.registrant.email
@ -68,8 +64,7 @@ class DomainDeleteMailerTest < ActionMailer::TestCase
email = DomainDeleteMailer.forced(domain: @domain,
registrar: @domain.registrar,
registrant: @domain.registrant,
template_name: DomainDeleteMailer.force_delete_templates
.first).deliver_now
template_name: @domain.notification_template).deliver_now
assert_emails 1
assert_equal ['legal@registry.test'], email.from

View file

@ -8,7 +8,18 @@ class DomainExpireMailerTest < ActionMailer::TestCase
email = DomainExpireMailer.expired(domain: domain, registrar: domain.registrar).deliver_now
assert_emails 1
assert_equal 'Domeen shop.test on aegunud / Domain shop.test has expired' \
' / Срок действия домена shop.test истек', email.subject
assert_equal I18n.t("domain_expire_mailer.expired.subject", domain_name: domain.name),
email.subject
end
def test_delivers_domain_expiration_soft_email
domain = domains(:shop)
assert_equal 'shop.test', domain.name
email = DomainExpireMailer.expired_soft(domain: domain, registrar: domain.registrar).deliver_now
assert_emails 1
assert_equal I18n.t("domain_expire_mailer.expired_soft.subject", domain_name: domain.name),
email.subject
end
end

View file

@ -1,10 +1,11 @@
class DomainDeleteMailerPreview < ActionMailer::Preview
def self.define_forced_templates
DomainDeleteMailer.force_delete_templates.each do |template_name|
%w[private_person legal_person invalid_email].each do |template_name|
define_method "forced_#{template_name}".to_sym do
DomainDeleteMailer.forced(domain: @domain,
registrar: @domain.registrar,
registrant: @domain.registrant,
domain = Domain.first
DomainDeleteMailer.forced(domain: domain,
registrar: domain.registrar,
registrant: domain.registrant,
template_name: template_name)
end
end
@ -12,26 +13,25 @@ class DomainDeleteMailerPreview < ActionMailer::Preview
define_forced_templates
def initialize
@domain = Domain.first
super
end
def confirmation_request
DomainDeleteMailer.confirmation_request(domain: @domain,
registrar: @domain.registrar,
registrant: @domain.registrant)
domain = Domain.first
DomainDeleteMailer.confirmation_request(domain: domain,
registrar: domain.registrar,
registrant: domain.registrant)
end
def accepted
DomainDeleteMailer.accepted(@domain)
domain = Domain.first
DomainDeleteMailer.accepted(domain)
end
def rejected
DomainDeleteMailer.rejected(@domain)
domain = Domain.first
DomainDeleteMailer.rejected(domain)
end
def expired
DomainDeleteMailer.expired(@domain)
domain = Domain.first
DomainDeleteMailer.expired(domain)
end
end

View file

@ -4,4 +4,10 @@ class DomainExpireMailerPreview < ActionMailer::Preview
DomainExpireMailer.expired(domain: domain,
registrar: domain.registrar)
end
def expired_soft
domain = Domain.first
DomainExpireMailer.expired_soft(domain: domain,
registrar: domain.registrar)
end
end

View file

@ -27,8 +27,8 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase
@domain.reload
assert @domain.force_delete_scheduled?
assert_equal Date.parse('2010-09-20'), @domain.force_delete_date.to_date
assert_equal Date.parse('2010-08-06'), @domain.force_delete_start.to_date
assert_equal Date.parse('2010-09-19'), @domain.force_delete_date.to_date
assert_equal Date.parse('2010-08-05'), @domain.force_delete_start.to_date
end
def test_schedules_force_delete_soft_less_than_year_ahead
@ -137,19 +137,49 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase
assert_not @domain.force_delete_scheduled?
end
def test_cancelling_force_delete_removes_statuses_that_were_set_on_force_delete
def test_force_delete_does_not_double_statuses
statuses = [
DomainStatus::FORCE_DELETE,
DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED,
DomainStatus::FORCE_DELETE,
DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED,
]
@domain.statuses = @domain.statuses + statuses
@domain.save!
@domain.reload
@domain.schedule_force_delete(type: :fast_track)
assert_equal @domain.statuses.size, statuses.size
end
def test_cancelling_force_delete_removes_force_delete_status
@domain.schedule_force_delete(type: :fast_track)
assert @domain.statuses.include?(DomainStatus::FORCE_DELETE)
assert @domain.statuses.include?(DomainStatus::SERVER_RENEW_PROHIBITED)
assert @domain.statuses.include?(DomainStatus::SERVER_TRANSFER_PROHIBITED)
@domain.cancel_force_delete
@domain.reload
assert_empty @domain.statuses & statuses
assert_not @domain.statuses.include?(DomainStatus::FORCE_DELETE)
assert_not @domain.statuses.include?(DomainStatus::SERVER_RENEW_PROHIBITED)
assert_not @domain.statuses.include?(DomainStatus::SERVER_TRANSFER_PROHIBITED)
end
def test_cancelling_force_delete_keeps_previous_statuses
statuses = [
DomainStatus::SERVER_RENEW_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED,
]
@domain.statuses = statuses
@domain.save!
@domain.reload
@domain.schedule_force_delete(type: :fast_track)
@domain.cancel_force_delete
@domain.reload
assert_equal @domain.statuses, statuses
end
def test_hard_force_delete_should_have_outzone_and_purge_date_with_time
@ -252,4 +282,16 @@ class NewDomainForceDeleteTest < ActiveSupport::TestCase
assert @domain.force_delete_scheduled?
assert @domain.pending_update?
end
def test_force_delete_does_not_affect_registrant_update_confirmable
@domain.schedule_force_delete(type: :soft)
@domain.registrant_verification_asked!('test', User.last.id)
@domain.save!
@domain.reload
@domain.statuses << DomainStatus::PENDING_UPDATE
assert @domain.force_delete_scheduled?
assert @domain.registrant_update_confirmable?(@domain.registrant_verification_token)
end
end

View file

@ -39,6 +39,21 @@ class DomainCronTest < ActiveSupport::TestCase
assert_emails 1
end
def does_not_deliver_forced_email_if_template_empty
Setting.redemption_grace_period = 30
@domain.update(valid_to: Time.zone.parse('2012-08-05'))
assert_not @domain.force_delete_scheduled?
travel_to Time.zone.parse('2010-07-05')
@domain.schedule_force_delete(type: :soft)
@domain.reload
@domain.update(template_name: nil)
travel_to Time.zone.parse('2010-08-06')
DomainCron.start_client_hold
assert_emails 0
end
def test_does_not_sets_hold_if_already_set
Setting.redemption_grace_period = 30

View file

@ -444,6 +444,20 @@ class DomainTest < ActiveSupport::TestCase
assert_not @domain.renewable?
end
def test_renewable_if_pending_delete
assert @domain.renewable?
@domain.statuses << DomainStatus::PENDING_DELETE
assert @domain.renewable?
end
def test_not_renewable_if_pending_delete_unconfirmed
assert @domain.renewable?
@domain.statuses << DomainStatus::PENDING_DELETE_CONFIRMATION
assert_not @domain.renewable?
end
private
def valid_domain

View file

@ -51,6 +51,7 @@ class EppResponseResultCodeTest < ActiveSupport::TestCase
data_management_policy_violation: 2308,
command_failed: 2400,
authentication_error_server_closing_connection: 2501,
session_limit_exceeded_server_closing_connection: 2502,
}
assert_equal codes, Epp::Response::Result::Code.codes
end
@ -82,6 +83,7 @@ class EppResponseResultCodeTest < ActiveSupport::TestCase
2308 => 'Data management policy violation',
2400 => 'Command failed',
2501 => 'Authentication error; server closing connection',
2502 => 'Session limit exceeded; server closing connection',
}
assert_equal descriptions, Epp::Response::Result::Code.default_descriptions
end

View file

@ -49,15 +49,11 @@ class EppSessionTest < ActiveSupport::TestCase
end
end
def test_limit_per_registrar
assert_equal 4, EppSession.limit_per_registrar
end
def test_limit_is_per_registrar
travel_to Time.zone.parse('2010-07-05')
EppSession.delete_all
EppSession.limit_per_registrar.times do
EppSession.sessions_per_registrar.times do
EppSession.create!(session_id: SecureRandom.hex,
user: users(:api_goodnames),
updated_at: Time.zone.parse('2010-07-05'))

View file

@ -14,7 +14,7 @@ class RegistrantUserCreationTest < ActiveSupport::TestCase
assert_equal('JOHN SMITH', user.username)
end
def test_find_or_create_by_api_data_creates_a_user_after_upcasing_input
def test_find_or_create_by_api_data_creates_a_user_with_original_name
user_data = {
ident: '37710100070',
first_name: 'John',
@ -24,6 +24,25 @@ class RegistrantUserCreationTest < ActiveSupport::TestCase
RegistrantUser.find_or_create_by_api_data(user_data)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
assert_equal('John Smith', user.username)
end
def test_updates_related_contacts_name_if_differs_from_e_identity
contact = contacts(:john)
contact.update(ident: '39708290276', ident_country_code: 'EE')
user_data = {
ident: '39708290276',
first_name: 'John',
last_name: 'Doe'
}
RegistrantUser.find_or_create_by_api_data(user_data)
user = User.find_by(registrant_ident: 'EE-39708290276')
assert_equal('John Doe', user.username)
contact.reload
assert_equal user.username, contact.name
end
end

View file

@ -8,7 +8,7 @@ class Whois::RecordTest < ActiveSupport::TestCase
@auction = auctions(:one)
@original_disclaimer = Setting.registry_whois_disclaimer
Setting.registry_whois_disclaimer = 'disclaimer'
Setting.registry_whois_disclaimer = JSON.generate({en: 'disclaimer'})
end
teardown do
@ -16,8 +16,8 @@ class Whois::RecordTest < ActiveSupport::TestCase
end
def test_reads_disclaimer_setting
Setting.registry_whois_disclaimer = 'test disclaimer'
assert_equal 'test disclaimer', Whois::Record.disclaimer
Setting.registry_whois_disclaimer = JSON.generate({en: 'test_disclaimer'})
assert_equal Setting.registry_whois_disclaimer, Whois::Record.disclaimer
end
def test_updates_whois_record_from_auction_when_started
@ -28,7 +28,7 @@ class Whois::RecordTest < ActiveSupport::TestCase
assert_equal ({ 'name' => 'domain.test',
'status' => ['AtAuction'],
'disclaimer' => 'disclaimer' }), @whois_record.json
'disclaimer' => { 'en' => 'disclaimer' }}), @whois_record.json
end
def test_updates_whois_record_from_auction_when_no_bids
@ -49,7 +49,7 @@ class Whois::RecordTest < ActiveSupport::TestCase
assert_equal ({ 'name' => 'domain.test',
'status' => ['PendingRegistration'],
'disclaimer' => 'disclaimer',
'disclaimer' => { 'en' => 'disclaimer' },
'registration_deadline' => registration_deadline.try(:to_s, :iso8601) }),
@whois_record.json
end
@ -64,7 +64,7 @@ class Whois::RecordTest < ActiveSupport::TestCase
assert_equal ({ 'name' => 'domain.test',
'status' => ['PendingRegistration'],
'disclaimer' => 'disclaimer',
'disclaimer' => { 'en' => 'disclaimer' },
'registration_deadline' => registration_deadline.try(:to_s, :iso8601) }),
@whois_record.json
end

View file

@ -12,10 +12,7 @@ class WhoisRecordTest < ActiveSupport::TestCase
end
def test_generated_json_has_expected_values
expected_disclaimer_text = <<-TEXT.squish
Search results may not be used for commercial, advertising, recompilation,
repackaging, redistribution, reuse, obscuring or other similar activities.
TEXT
expected_disclaimer_text = SettingEntry.find_by(code: 'registry_whois_disclaimer').retrieve
expected_partial_hash = {
disclaimer: expected_disclaimer_text,

View file

@ -42,6 +42,38 @@ class AdminAreaDomainForceDeleteTest < ApplicationSystemTestCase
find(:css, '#soft_delete').set(true)
click_link_or_button 'Force delete domain'
end
@domain.reload
assert_equal @domain.notification_template, @domain.template_name
end
def test_uses_legal_template_if_registrant_org
@domain.registrant.update(ident_type: 'org')
assert_emails 0 do
visit edit_admin_domain_url(@domain)
find(:css, '#soft_delete').set(true)
click_link_or_button 'Force delete domain'
end
@domain.reload
assert_equal @domain.notification_template, @domain.template_name
end
def test_uses_legal_template_if_invalid_email
verification = @domain.contacts.first.email_verification
verification.update(verified_at: Time.zone.now - 1.day, success: false)
assert_equal @domain.notification_template, 'invalid_email'
assert_emails 0 do
visit edit_admin_domain_url(@domain)
find(:css, '#soft_delete').set(true)
click_link_or_button 'Force delete domain'
end
@domain.reload
assert_equal @domain.notification_template, @domain.template_name
end
def test_allows_to_skip_notifying_registrant_and_admin_contacts_by_email

View file

@ -8,6 +8,7 @@ class RegistrarAreaNameserverBulkChangeTest < ApplicationSystemTestCase
def test_replaces_current_registrar_nameservers
request_body = { data: { type: 'nameserver',
id: 'ns1.bestnames.test',
domains: [],
attributes: { hostname: 'new-ns.bestnames.test',
ipv4: %w[192.0.2.55 192.0.2.56],
ipv6: %w[2001:db8::55 2001:db8::56] } } }