Merge pull request #374 from internetee/registry-355

Registry 355
This commit is contained in:
Timo Võhmar 2017-02-17 14:22:16 +02:00 committed by GitHub
commit 6f907e11b5
98 changed files with 1149 additions and 470 deletions

View file

@ -1,3 +1,6 @@
24.01.2017
* Disallow EPP domain:update/transfer/delete if a domain has "deleteCandidate" status
22.12.2016 22.12.2016
* Return business registry code and country for 'org' type registrants in WHOIS and Rest-WHOIS * Return business registry code and country for 'org' type registrants in WHOIS and Rest-WHOIS

View file

@ -1,6 +1,5 @@
#= require jquery #= require jquery
#= require jquery_ujs #= require jquery_ujs
#= require turbolinks
#= require bootstrap-sprockets #= require bootstrap-sprockets
#= require typeahead.bundle.min #= require typeahead.bundle.min
#= require admin/autocomplete #= require admin/autocomplete
@ -10,5 +9,6 @@
#= require jquery-ui/datepicker #= require jquery-ui/datepicker
#= require select2 #= require select2
#= require jquery.doubleScroll #= require jquery.doubleScroll
#= require shared/general
#= require admin/application #= require admin/application
#= require admin/app
#= require_tree ./admin

View file

@ -0,0 +1 @@
var RegistryAdmin = {};

View file

@ -1,4 +1,4 @@
$(document).on 'page:change', -> $(window).load ->
$('.selectize').selectize({ $('.selectize').selectize({
allowEmptyOption: true allowEmptyOption: true
}) })
@ -6,23 +6,12 @@ $(document).on 'page:change', ->
allowEmptyOption: true, create: true allowEmptyOption: true, create: true
}) })
$('.js-datepicker').datepicker({
showAnim: "",
autoclose: true,
dateFormat: "dd.mm.yy",
changeMonth: true,
changeYear: true
})
# client side validate all forms # client side validate all forms
$('form').each -> $('form').each ->
$(this).validate() $(this).validate()
$('[data-toggle="popover"]').popover() $('[data-toggle="popover"]').popover()
# doublescroll # doublescroll
$('[data-doublescroll]').doubleScroll({ $('[data-doublescroll]').doubleScroll({
onlyIfScroll: false, onlyIfScroll: false,
@ -50,4 +39,3 @@ $(document).on 'page:change', ->
$(window).scroll(positionSlider).resize positionSlider $(window).scroll(positionSlider).resize positionSlider
#due .report-table width: auto top scrollbar appears after resize so we do fake resize action #due .report-table width: auto top scrollbar appears after resize so we do fake resize action
$(window).resize() $(window).resize()

View file

@ -0,0 +1,9 @@
var comboBoxFields = $('.js-combobox');
if (comboBoxFields.length) {
comboBoxFields.select2({
width: "100%",
selectOnBlur: true,
dropdownAutoWidth: self === top
});
}

View file

@ -0,0 +1,3 @@
$('.datepicker').datepicker({
dateFormat: 'yy-mm-dd'
});

View file

@ -5,10 +5,10 @@
//= require 'select2-bootstrap' //= require 'select2-bootstrap'
@import shared/fonts @import shared/fonts
@import shared/general @import shared/general
@import nprogress
@import nprogress-bootstrap
@import typeaheadjs @import typeaheadjs
@import selectize @import selectize
@import selectize.bootstrap3 @import selectize.bootstrap3
// @import bootstrap-datepicker3 // @import bootstrap-datepicker3
@import admin/admin @import admin/admin
@import admin/bootstrap-dialog-fix

View file

@ -0,0 +1,7 @@
.modal-open {
overflow: visible;
}
.modal-open, .modal-open .navbar-fixed-top, .modal-open .navbar-fixed-bottom {
padding-right: 0px !important;
}

View file

@ -1,6 +1,7 @@
class Admin::DomainsController < AdminController class Admin::DomainsController < AdminController
load_and_authorize_resource load_and_authorize_resource
before_action :set_domain, only: [:show, :edit, :update, :zonefile] before_action :set_domain, only: [:show, :edit, :update, :zonefile]
helper_method :force_delete_templates
# rubocop: disable Metrics/PerceivedComplexity # rubocop: disable Metrics/PerceivedComplexity
# rubocop: disable Metrics/CyclomaticComplexity # rubocop: disable Metrics/CyclomaticComplexity
@ -59,22 +60,26 @@ class Admin::DomainsController < AdminController
end end
end end
def set_force_delete def schedule_force_delete
if @domain.set_force_delete raise 'Template param cannot be empty' if params[:template_name].blank?
flash[:notice] = I18n.t('domain_updated')
else @domain.transaction do
flash.now[:alert] = I18n.t('failed_to_update_domain') @domain.schedule_force_delete
end @domain.registrar.messages.create!(body: I18n.t('force_delete_set_on_domain', domain_name: @domain.name))
redirect_to [:admin, @domain] DomainDeleteForcedEmailJob.enqueue(@domain.id, params[:template_name])
end end
def unset_force_delete redirect_to edit_admin_domain_path(@domain), notice: t('.scheduled')
if @domain.unset_force_delete end
flash[:notice] = I18n.t('domain_updated')
def cancel_force_delete
if @domain.cancel_force_delete
flash[:notice] = t('.cancelled')
else else
flash.now[:alert] = I18n.t('failed_to_update_domain') flash.now[:alert] = I18n.t('failed_to_update_domain')
end end
redirect_to [:admin, @domain]
redirect_to edit_admin_domain_path(@domain)
end end
def versions def versions
@ -121,5 +126,8 @@ class Admin::DomainsController < AdminController
params[:q][:valid_to_lteq] = ca_cache params[:q][:valid_to_lteq] = ca_cache
end end
end
def force_delete_templates
%w(removed_company death)
end
end

View file

@ -1,6 +1,5 @@
class Admin::SessionsController < Devise::SessionsController class Admin::SessionsController < Devise::SessionsController
skip_authorization_check only: :create skip_authorization_check only: :create
layout 'admin/application'
def login def login
@admin_user = AdminUser.new @admin_user = AdminUser.new

View file

@ -1,5 +1,4 @@
class AdminController < ApplicationController class AdminController < ApplicationController
layout 'admin/application'
before_action :authenticate_user! before_action :authenticate_user!
helper_method :head_title_sufix helper_method :head_title_sufix

View file

@ -1,11 +1,12 @@
class DomainDeleteForcedEmailJob < Que::Job class DomainDeleteForcedEmailJob < Que::Job
def run(domain_id) def run(domain_id, template_name)
domain = Domain.find(domain_id) domain = Domain.find(domain_id)
log(domain) log(domain)
DomainDeleteMailer.forced(domain: domain, DomainDeleteMailer.forced(domain: domain,
registrar: domain.registrar, registrar: domain.registrar,
registrant: domain.registrant).deliver_now registrant: domain.registrant,
template_name: template_name).deliver_now
end end
private private

View file

@ -1,10 +0,0 @@
class DomainSetDeleteCandidateJob < Que::Job
def run(domain_id)
domain = Domain.find(domain_id)
domain.statuses << DomainStatus::DELETE_CANDIDATE
::PaperTrail.whodunnit = "job - #{self.class.name}"
domain.save(validate: false)
DomainDeleteJob.enqueue(domain.id, run_at: rand(((24*60) - (DateTime.now.hour * 60 + DateTime.now.minute))).minutes.from_now)
end
end

View file

@ -8,12 +8,17 @@ class DomainDeleteMailer < ApplicationMailer
mail(to: registrant.email, subject: subject) mail(to: registrant.email, subject: subject)
end end
def forced(domain:, registrar:, registrant:) def forced(domain:, registrar:, registrant:, template_name:)
@domain = DomainPresenter.new(domain: domain, view: view_context) @domain = DomainPresenter.new(domain: domain, view: view_context)
@registrar = RegistrarPresenter.new(registrar: registrar, view: view_context) @registrar = RegistrarPresenter.new(registrar: registrar, view: view_context)
@registrant = RegistrantPresenter.new(registrant: registrant, view: view_context) @registrant = RegistrantPresenter.new(registrant: registrant, view: view_context)
mail(to: domain.primary_contact_emails) @force_delete_set_date = Time.zone.now
@redemption_grace_period = Setting.redemption_grace_period
mail(to: domain.primary_contact_emails,
template_path: 'mailers/domain_delete_mailer/forced',
template_name: template_name)
end end
private private

View file

@ -0,0 +1,11 @@
module Concerns::Domain::Deletable
extend ActiveSupport::Concern
included do
alias_attribute :delete_time, :delete_at
end
def discarded?
statuses.include?(DomainStatus::DELETE_CANDIDATE)
end
end

View file

@ -0,0 +1,54 @@
module Concerns::Domain::ForceDelete
extend ActiveSupport::Concern
included do
alias_attribute :force_delete_time, :force_delete_at
end
def force_delete_scheduled?
statuses.include?(DomainStatus::FORCE_DELETE)
end
def schedule_force_delete
self.statuses_backup = statuses
statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
statuses.delete(DomainStatus::PENDING_UPDATE)
statuses.delete(DomainStatus::PENDING_TRANSFER)
statuses.delete(DomainStatus::PENDING_RENEW)
statuses.delete(DomainStatus::PENDING_CREATE)
statuses.delete(DomainStatus::FORCE_DELETE)
statuses.delete(DomainStatus::SERVER_RENEW_PROHIBITED)
statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_MANUAL_INZONE)
statuses.delete(DomainStatus::PENDING_DELETE)
statuses << DomainStatus::FORCE_DELETE
statuses << DomainStatus::SERVER_RENEW_PROHIBITED
statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED
statuses << DomainStatus::SERVER_UPDATE_PROHIBITED
statuses << DomainStatus::PENDING_DELETE
if (statuses & [DomainStatus::SERVER_HOLD, DomainStatus::CLIENT_HOLD]).empty?
statuses << DomainStatus::SERVER_MANUAL_INZONE
end
self.force_delete_at = (Time.zone.now + (Setting.redemption_grace_period.days + 1.day)).utc.beginning_of_day unless force_delete_at
save!(validate: false)
end
def cancel_force_delete
s = []
s << DomainStatus::EXPIRED if statuses.include?(DomainStatus::EXPIRED)
s << DomainStatus::SERVER_HOLD if statuses.include?(DomainStatus::SERVER_HOLD)
s << DomainStatus::DELETE_CANDIDATE if statuses.include?(DomainStatus::DELETE_CANDIDATE)
self.statuses = (statuses_backup + s).uniq
self.force_delete_at = nil
self.statuses_backup = []
save(validate: false)
end
end

View file

@ -1,7 +0,0 @@
module Statuses
extend ActiveSupport::Concern
def force_delete?
statuses.include?(DomainStatus::FORCE_DELETE)
end
end

View file

@ -589,4 +589,9 @@ class Contact < ActiveRecord::Base
return if priv? return if priv?
ident ident
end end
def id_code
return unless priv?
ident
end
end end

View file

@ -2,9 +2,10 @@
class Domain < ActiveRecord::Base class Domain < ActiveRecord::Base
include UserEvents include UserEvents
include Versions # version/domain_version.rb include Versions # version/domain_version.rb
include Statuses
include Concerns::Domain::Expirable include Concerns::Domain::Expirable
include Concerns::Domain::Activatable include Concerns::Domain::Activatable
include Concerns::Domain::ForceDelete
include Concerns::Domain::Deletable
has_paper_trail class_name: "DomainVersion", meta: { children: :children_log } has_paper_trail class_name: "DomainVersion", meta: { children: :children_log }
@ -13,9 +14,7 @@ class Domain < ActiveRecord::Base
attr_accessor :legal_document_id attr_accessor :legal_document_id
alias_attribute :on_hold_time, :outzone_at alias_attribute :on_hold_time, :outzone_at
alias_attribute :force_delete_time, :force_delete_at
alias_attribute :outzone_time, :outzone_at alias_attribute :outzone_time, :outzone_at
alias_attribute :delete_time, :delete_at
# TODO: whois requests ip whitelist for full info for own domains and partial info for other domains # TODO: whois requests ip whitelist for full info for own domains and partial info for other domains
# TODO: most inputs should be trimmed before validatation, probably some global logic? # TODO: most inputs should be trimmed before validatation, probably some global logic?
@ -137,7 +136,7 @@ class Domain < ActiveRecord::Base
validate :check_permissions, :unless => :is_admin validate :check_permissions, :unless => :is_admin
def check_permissions def check_permissions
return unless force_delete? return unless force_delete_scheduled?
errors.add(:base, I18n.t(:object_status_prohibits_operation)) errors.add(:base, I18n.t(:object_status_prohibits_operation))
false false
end end
@ -422,10 +421,6 @@ class Domain < ActiveRecord::Base
end end
# rubocop: enable Metrics/CyclomaticComplexity # rubocop: enable Metrics/CyclomaticComplexity
def force_deletable?
!statuses.include?(DomainStatus::FORCE_DELETE)
end
def registrant_verification_asked? def registrant_verification_asked?
registrant_verification_asked_at.present? && registrant_verification_token.present? registrant_verification_asked_at.present? && registrant_verification_token.present?
end end
@ -538,64 +533,6 @@ class Domain < ActiveRecord::Base
end end
# rubocop:enable Lint/Loop # rubocop:enable Lint/Loop
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def set_force_delete
self.statuses_backup = statuses
statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
statuses.delete(DomainStatus::PENDING_UPDATE)
statuses.delete(DomainStatus::PENDING_TRANSFER)
statuses.delete(DomainStatus::PENDING_RENEW)
statuses.delete(DomainStatus::PENDING_CREATE)
statuses.delete(DomainStatus::FORCE_DELETE)
statuses.delete(DomainStatus::SERVER_RENEW_PROHIBITED)
statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_MANUAL_INZONE)
statuses.delete(DomainStatus::PENDING_DELETE)
statuses << DomainStatus::FORCE_DELETE
statuses << DomainStatus::SERVER_RENEW_PROHIBITED
statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED
statuses << DomainStatus::SERVER_UPDATE_PROHIBITED
statuses << DomainStatus::PENDING_DELETE
if (statuses & [DomainStatus::SERVER_HOLD, DomainStatus::CLIENT_HOLD]).empty?
statuses << DomainStatus::SERVER_MANUAL_INZONE
end
self.force_delete_at = (Time.zone.now + (Setting.redemption_grace_period.days + 1.day)).utc.beginning_of_day unless force_delete_at
transaction do
save!(validate: false)
registrar.messages.create!(
body: I18n.t('force_delete_set_on_domain', domain: name)
)
DomainDeleteForcedEmailJob.enqueue(id)
return true
end
false
end
# rubocop: enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize
def unset_force_delete
s = []
s << DomainStatus::EXPIRED if statuses.include?(DomainStatus::EXPIRED)
s << DomainStatus::SERVER_HOLD if statuses.include?(DomainStatus::SERVER_HOLD)
s << DomainStatus::DELETE_CANDIDATE if statuses.include?(DomainStatus::DELETE_CANDIDATE)
self.statuses = (statuses_backup + s).uniq
self.force_delete_at = nil
self.statuses_backup = []
save(validate: false)
end
def set_graceful_expired def set_graceful_expired
self.outzone_at = expire_time + self.class.expire_warning_period self.outzone_at = expire_time + self.class.expire_warning_period
self.delete_at = outzone_at + self.class.redemption_grace_period self.delete_at = outzone_at + self.class.redemption_grace_period

View file

@ -472,6 +472,9 @@ class Epp::Domain < Domain
# rubocop: disable Metrics/CyclomaticComplexity # rubocop: disable Metrics/CyclomaticComplexity
def update(frame, current_user, verify = true) def update(frame, current_user, verify = true)
return super if frame.blank? return super if frame.blank?
check_discarded
at = {}.with_indifferent_access at = {}.with_indifferent_access
at.deep_merge!(attrs_from(frame.css('chg'), current_user, 'chg')) at.deep_merge!(attrs_from(frame.css('chg'), current_user, 'chg'))
at.deep_merge!(attrs_from(frame.css('rem'), current_user, 'rem')) at.deep_merge!(attrs_from(frame.css('rem'), current_user, 'rem'))
@ -563,6 +566,8 @@ class Epp::Domain < Domain
def epp_destroy(frame, user_id) def epp_destroy(frame, user_id)
return false unless valid? return false unless valid?
check_discarded
if doc = attach_legal_document(Epp::Domain.parse_legal_document_from_frame(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? frame.css("legalDocument").first.content = doc.path if doc && doc.persisted?
end end
@ -629,6 +634,8 @@ class Epp::Domain < Domain
# rubocop: disable Metrics/CyclomaticComplexity # rubocop: disable Metrics/CyclomaticComplexity
def transfer(frame, action, current_user) def transfer(frame, action, current_user)
check_discarded
@is_transfer = true @is_transfer = true
case action case action
@ -925,5 +932,16 @@ class Epp::Domain < Domain
res res
end end
end end
private
def check_discarded
if discarded?
throw :epp_error, {
code: '2105',
msg: I18n.t(:object_is_not_eligible_for_renewal),
}
end
end
end end
# rubocop: enable Metrics/ClassLength # rubocop: enable Metrics/ClassLength

View file

@ -38,6 +38,24 @@ class DomainPresenter
domain.nameserver_hostnames.join(', ') domain.nameserver_hostnames.join(', ')
end end
def force_delete_toggle_btn
if !domain.force_delete_scheduled?
view.content_tag(:a, view.t('admin.domains.force_delete_toggle_btn.schedule'),
class: 'btn btn-danger',
data: {
toggle: 'modal',
target: '.domain-edit-force-delete-dialog',
}
)
else
view.link_to(view.t('admin.domains.force_delete_toggle_btn.cancel'),
view.cancel_force_delete_admin_domain_path(domain),
method: :patch,
data: { confirm: view.t('admin.domains.force_delete_toggle_btn.cancel_confim') },
class: 'btn btn-primary')
end
end
private private
attr_reader :domain attr_reader :domain

View file

@ -1,5 +1,5 @@
class RegistrantPresenter class RegistrantPresenter
delegate :name, :ident, :email, :priv?, :street, :city, to: :registrant delegate :name, :ident, :email, :priv?, :street, :city, :id_code, to: :registrant
def initialize(registrant:, view:) def initialize(registrant:, view:)
@registrant = registrant @registrant = registrant

View file

@ -0,0 +1,20 @@
<% if flash[:notice] %>
<div class="alert alert-success alert-dismissible">
<button class="close" data-dismiss="alert" type=button><span>&times;</span></button>
<p><%= flash[:notice] %></p>
</div>
<% end %>
<% if flash[:alert] %>
<div class="alert alert-danger alert-dismissible">
<button class="close" data-dismiss="alert" type=button><span>&times;</span></button>
<p><%= flash[:alert] %></p>
</div>
<% end %>
<% if flash[:info] %>
<div class="alert alert-info alert-dismissible">
<button class="close" data-dismiss="alert" type=button><span>&times;</span></button>
<p><%= flash[:info] %></p>
</div>
<% end %>

View file

@ -0,0 +1,44 @@
.navbar-collapse.collapse
%ul.nav.navbar-nav
- if can? :show, Domain
%li= link_to t(:domains), admin_domains_path
- if can? :show, Contact
%li= link_to t(:contacts), admin_contacts_path
- if can? :show, Registrar
%li= link_to t(:registrars), admin_registrars_path
- if can? :show, Keyrelay
%li= link_to t(:keyrelays), admin_keyrelays_path
- if can?(:access, :settings_menu)
%li.dropdown
%a.dropdown-toggle{"data-toggle" => "dropdown", href: "#"}
= t(:settings)
%span.caret
%ul.dropdown-menu{role: "menu"}
%li.dropdown-header= t('.users')
%li= link_to t('.api_users'), admin_api_users_path
%li= link_to t('.admin_users'), admin_admin_users_path
%li.divider
%li.dropdown-header= t(:billing)
- if can? :view, Pricelist
%li= link_to t(:pricelists), admin_pricelists_path
%li= link_to t(:bank_statements), admin_bank_statements_path
%li= link_to t(:invoices), admin_invoices_path
%li= link_to t(:account_activities), admin_account_activities_path(created_after: 'today')
%li.divider
%li.dropdown-header= t('.archive')
%li= link_to t('.domain_history'), admin_domain_versions_path
%li= link_to t('.contact_history'), admin_contact_versions_path
%li.divider
%li.dropdown-header= t(:system)
%li= link_to t(:settings), admin_settings_path
%li= link_to t(:zonefile), admin_zonefile_settings_path
%li= link_to t('.blocked_domains'), admin_blocked_domains_path
%li= link_to t('.reserved_domains'), admin_reserved_domains_path
%li= link_to t(:mail_templates), admin_mail_templates_path
%li= link_to t('.epp_log'), admin_epp_logs_path(created_after: 'today')
%li= link_to t('.repp_log'), admin_repp_logs_path(created_after: 'today')
%li= link_to t('.que'), '/admin/que'
- if signed_in?
%ul.nav.navbar-nav.navbar-right
%li= link_to t(:log_out, user: current_user), '/admin/logout'

View file

@ -38,8 +38,7 @@
&nbsp; &nbsp;
%span.glyphicon.glyphicon-search %span.glyphicon.glyphicon-search
&nbsp; &nbsp;
%button.btn.btn-default.js-reset-form = link_to(t('.reset_btn'), admin_account_activities_path, class: 'btn btn-default')
= t(:clear_fields)
.row .row
.col-md-3 .col-md-3
.col-md-3 .col-md-3
@ -87,8 +86,3 @@
.row .row
.col-md-12 .col-md-12
= paginate @account_activities = paginate @account_activities
:coffee
$(".js-reset-form").on "click", (e) ->
e.preventDefault();
window.location = "#{admin_account_activities_path}"

View file

@ -59,7 +59,8 @@
.col-md-8.text-right .col-md-8.text-right
= button_tag(t(:save), class: 'btn btn-warning') = button_tag(t(:save), class: 'btn btn-warning')
:coffee :javascript
$("#admin_user_password").removeAttr('required') window.addEventListener('load', function() {
$("#admin_user_password_confirmation").removeAttr('required') $("#admin_user_password").removeAttr('required');
$("#admin_user_password_confirmation").removeAttr('required');
});

View file

@ -1,6 +1,6 @@
- content_for :actions do - content_for :actions do
= link_to(t(:create_new_user), new_admin_admin_user_path, class: 'btn btn-primary') = link_to(t('.new_btn'), new_admin_admin_user_path, class: 'btn btn-primary')
= render 'shared/title', name: t(:admin_users) = render 'shared/title', name: t('.title')
.row .row
.col-md-12 .col-md-12
@ -23,7 +23,7 @@
%td= x.email %td= x.email
%td= x.identity_code %td= x.identity_code
- if x.roles - if x.roles
%td= t(x.roles.first) %td= x.roles.first
- else - else
%td %td
.row .row

View file

@ -1,3 +1,3 @@
= render 'shared/title', name: t(:create_new_user) = render 'shared/title', name: t('.title')
= render 'form' = render 'form'

View file

@ -26,6 +26,6 @@
%dt= t(:role) %dt= t(:role)
- if @admin_user.roles - if @admin_user.roles
%dd= t(@admin_user.roles.first) %dd= @admin_user.roles.first
- else - else
%dd %dd

View file

@ -46,12 +46,12 @@
= f.label :role, class: 'required' = f.label :role, class: 'required'
.col-md-7 .col-md-7
= select_tag 'api_user[roles][]', = select_tag 'api_user[roles][]',
options_for_select(ApiUser::ROLES.map {|x| [t(x), x] }, @api_user.roles.try(:first)), options_for_select(ApiUser::ROLES.map {|x| [x, x] }, @api_user.roles.try(:first)),
class: 'form-control selectize' class: 'form-control selectize'
.checkbox .checkbox
%label{for: 'api_user_active'} %label{for: 'api_user_active'}
= f.check_box(:active) = f.check_box(:active)
= t(:active) = t('.active')
%hr %hr
@ -59,6 +59,8 @@
.col-md-8.text-right .col-md-8.text-right
= button_tag(t(:save), class: 'btn btn-primary') = button_tag(t(:save), class: 'btn btn-primary')
:coffee :javascript
Autocomplete.bindAdminRegistrarSearch() window.addEventListener('load', function() {
$("#api_user_password").removeAttr('required') Autocomplete.bindAdminRegistrarSearch();
$("#api_user_password").removeAttr('required');
});

View file

@ -1,6 +1,6 @@
- content_for :actions do - content_for :actions do
= link_to(t(:create_new_api_user), new_admin_api_user_path, class: 'btn btn-primary') = link_to(t('.new_btn'), new_admin_api_user_path, class: 'btn btn-primary')
= render 'shared/title', name: t(:api_users) = render 'shared/title', name: t('.title')
.row .row
.col-md-12 .col-md-12
@ -13,7 +13,7 @@
%th{class: 'col-xs-2'} %th{class: 'col-xs-2'}
= sort_link(@q, 'registrar_name', t(:registrar_name)) = sort_link(@q, 'registrar_name', t(:registrar_name))
%th{class: 'col-xs-2'} %th{class: 'col-xs-2'}
= sort_link(@q, 'active', t(:active)) = sort_link(@q, 'active', t('.active'))
%tbody %tbody
- @api_users.each do |x| - @api_users.each do |x|
%tr %tr

View file

@ -1,3 +1,3 @@
= render 'shared/title', name: t(:create_new_api_user) = render 'shared/title', name: t('.title')
= render 'form' = render 'form'

View file

@ -29,7 +29,7 @@
%dt= t(:role) %dt= t(:role)
%dd= @api_user.roles.join(', ') %dd= @api_user.roles.join(', ')
%dt= t(:active) %dt= t('.active')
%dd= @api_user.active %dd= @api_user.active
.row .row
.col-md-12 .col-md-12
@ -47,7 +47,7 @@
%table.table.table-hover.table-bordered.table-condensed %table.table.table-hover.table-bordered.table-condensed
%thead %thead
%tr %tr
%th{class: 'col-xs-10'}= t(:subject) %th{class: 'col-xs-10'}= t('.subject')
%th{class: 'col-xs-2'}= t(:status) %th{class: 'col-xs-2'}= t(:status)
%tbody %tbody
- @api_user.certificates.each do |x| - @api_user.certificates.each do |x|

View file

@ -1,6 +1,6 @@
- content_for :actions do - content_for :actions do
= link_to(t(:new), new_admin_blocked_domain_path, class: 'btn btn-primary') = link_to(t('.new_btn'), new_admin_blocked_domain_path, class: 'btn btn-primary')
= render 'shared/title', name: t(:blocked_domains) = render 'shared/title', name: t('.title')
.row .row
.col-md-12 .col-md-12
@ -28,8 +28,7 @@
&nbsp; &nbsp;
%span.glyphicon.glyphicon-search %span.glyphicon.glyphicon-search
&nbsp; &nbsp;
%button.btn.btn-default.js-reset-form = link_to(t('.reset_btn'), admin_blocked_domains_path, class: 'btn btn-default')
= t(:clear_fields)
%hr %hr
.row .row
.col-md-12 .col-md-12
@ -61,8 +60,3 @@
.col-md-6.text-right .col-md-6.text-right
.pagination .pagination
= t(:result_count, count: @domains.total_count) = t(:result_count, count: @domains.total_count)
:coffee
$(".js-reset-form").on "click", (e) ->
e.preventDefault();
window.location = "#{admin_blocked_domains_path}"

View file

@ -32,8 +32,7 @@
&nbsp; &nbsp;
%span.glyphicon.glyphicon-search %span.glyphicon.glyphicon-search
&nbsp; &nbsp;
%button.btn.btn-default.js-reset-form = link_to(t('.reset_btn'), admin_contact_versions_path, class: 'btn btn-default')
= t(:clear_fields)
%hr %hr
@ -78,9 +77,3 @@
.col-md-6.text-right .col-md-6.text-right
.pagination .pagination
= t(:result_count, count: @versions.total_count) = t(:result_count, count: @versions.total_count)
:coffee
$(".js-reset-form").on "click", (e) ->
e.preventDefault();
window.location = "#{admin_contact_versions_path}"

View file

@ -1,6 +1,6 @@
- content_for :actions do - content_for :actions do
= link_to(t(:add_new_status), '#', class: 'btn btn-primary js-add-status') = link_to(t('.new_status_btn'), '#', class: 'btn btn-primary js-add-status')
= link_to(t(:back_to_contact), [:admin, @contact], class: 'btn btn-default') = link_to(t('.back_btn'), [:admin, @contact], class: 'btn btn-default')
= render 'shared/title', name: "#{t(:edit)}: #{@contact.name}" = render 'shared/title', name: "#{t(:edit)}: #{@contact.name}"
= render 'form', contact: @contact = render 'form', contact: @contact

View file

@ -70,8 +70,7 @@
&nbsp; &nbsp;
%span.glyphicon.glyphicon-search %span.glyphicon.glyphicon-search
&nbsp; &nbsp;
%button.btn.btn-default.js-reset-form = link_to(t('.reset_btn'), admin_contacts_path, class: 'btn btn-default')
= t(:clear_fields)
%hr %hr
.row .row
.col-md-12 .col-md-12
@ -106,8 +105,3 @@
.col-md-6.text-right .col-md-6.text-right
.pagination .pagination
= t(:result_count, count: @contacts.total_count) = t(:result_count, count: @contacts.total_count)
:coffee
$(".js-reset-form").on "click", (e) ->
e.preventDefault();
window.location = "#{admin_contacts_path}"

View file

@ -18,7 +18,7 @@
%th{class: 'col-xs-3'}=custom_sort_link t(:domain_name), :name %th{class: 'col-xs-3'}=custom_sort_link t(:domain_name), :name
%th{class: 'col-xs-3'}=custom_sort_link t(:registrar_name), :registrar_name %th{class: 'col-xs-3'}=custom_sort_link t(:registrar_name), :registrar_name
%th{class: 'col-xs-3'}=custom_sort_link t(:valid_to), :valid_to %th{class: 'col-xs-3'}=custom_sort_link t(:valid_to), :valid_to
%th{class: 'col-xs-3'}= t(:roles) %th{class: 'col-xs-3'}= t('.roles')
%tbody %tbody
- domains.each do |x| - domains.each do |x|
%tr %tr

View file

@ -27,13 +27,13 @@
%br %br
%dt= t(:created) %dt= t('.created')
%dd %dd
= l(@contact.created_at, format: :short) = l(@contact.created_at, format: :short)
by by
= creator_link(@contact) = creator_link(@contact)
%dt= t(:updated) %dt= t('.updated')
%dd %dd
= l(@contact.updated_at, format: :short) = l(@contact.updated_at, format: :short)
by by

View file

@ -32,8 +32,7 @@
&nbsp; &nbsp;
%span.glyphicon.glyphicon-search %span.glyphicon.glyphicon-search
&nbsp; &nbsp;
%button.btn.btn-default.js-reset-form = link_to(t('.reset_btn'), admin_domain_versions_path, class: 'btn btn-default')
= t(:clear_fields)
%hr %hr
@ -84,9 +83,3 @@
.col-md-6.text-right .col-md-6.text-right
.pagination .pagination
= t(:result_count, count: @versions.total_count) = t(:result_count, count: @versions.total_count)
:coffee
$(".js-reset-form").on "click", (e) ->
e.preventDefault();
window.location = "#{admin_domain_versions_path}"

View file

@ -0,0 +1,34 @@
<div class="modal domain-edit-force-delete-dialog" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><%= t '.title' %></h4>
</div>
<div class="modal-body">
<div class="row">
<%= form_tag schedule_force_delete_admin_domain_path, method: :patch,
id: 'domain-force-delete-form', class: 'form-horizontal' do %>
<div class="form-group">
<label class="col-sm-2 control-label"><%= t '.template' %>:</label>
<div class="col-sm-9">
<%= select_tag 'template_name', options_for_select(templates), class: 'form-control' %>
</div>
</div>
<% end %>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><%= t '.close_btn' %></button>
<button type="submit" form="domain-force-delete-form" class="btn btn-danger">
<%= t '.submit_btn' %>
</button>
</div>
</div>
</div>
</div>

View file

@ -1,13 +0,0 @@
- content_for :actions do
= link_to(t(:add_new_status), '#', class: 'btn btn-primary js-add-status')
- if @domain.force_deletable?
= link_to(t(:set_force_delete), set_force_delete_admin_domain_path(@domain),
method: :post, data: { confirm: t(:are_you_sure) }, class: 'btn btn-warning')
- else
= link_to(t(:unset_force_delete), unset_force_delete_admin_domain_path(@domain),
method: :post, data: { confirm: t(:are_you_sure) }, class: 'btn btn-warning')
= link_to(t(:back_to_domain), [:admin, @domain], class: 'btn btn-default')
= render 'shared/title', name: "#{t(:edit)}: #{@domain.name}"
= render 'form'

View file

@ -0,0 +1,20 @@
<% domain = DomainPresenter.new(domain: @domain, view: self) %>
<div class="row">
<div class="col-sm-5">
<h1 class="text-center-xs">
Edit: <%= domain.name %>
</h1>
</div>
<div class="col-sm-7">
<h1 class="text-right text-center-xs">
<%= link_to t('.add_new_status_btn'), '#', class: 'btn btn-primary js-add-status' %>
<%= domain.force_delete_toggle_btn %>
<%= link_to t('.back_btn'), [:admin, @domain], class: 'btn btn-default' %>
</h1>
</div>
</div>
<hr>
<%= render 'form' %>
<%= render 'force_delete_dialog', templates: force_delete_templates %>

View file

@ -47,8 +47,7 @@
&nbsp; &nbsp;
%span.glyphicon.glyphicon-search %span.glyphicon.glyphicon-search
&nbsp; &nbsp;
%button.btn.btn-default.js-reset-form = link_to(t('.reset_btn'), admin_domains_path, class: 'btn btn-default')
= t(:clear_fields)
%hr %hr
.row .row
.col-md-12 .col-md-12
@ -80,8 +79,3 @@
.col-md-6.text-right .col-md-6.text-right
.pagination .pagination
= t(:result_count, count: @domains.total_count) = t(:result_count, count: @domains.total_count)
:coffee
$(".js-reset-form").on "click", (e) ->
e.preventDefault();
window.location = "#{admin_domains_path}"

View file

@ -22,11 +22,11 @@
%dt= t(:valid_to) %dt= t(:valid_to)
%dd= l(@domain.valid_to) %dd= l(@domain.valid_to)
%dt= t(:outzone_at) %dt= t('.outzone_time')
%dd= l(@domain.outzone_at) %dd= l(@domain.outzone_at)
%dt= t(:delete_at) %dt= t('.delete_time')
%dd= l(@domain.delete_at) %dd= l(@domain.delete_at)
%dt= t(:force_delete_at) %dt= t('.force_delete_time')
%dd= l(@domain.force_delete_at) %dd= l(@domain.force_delete_at)

View file

@ -8,11 +8,11 @@
%table.table.table-bordered.table-condensed %table.table.table-bordered.table-condensed
%thead %thead
%tr %tr
%th{class: 'col-xs-1'}= t(:timestap) %th{class: 'col-xs-1'}= t('.time')
%th{class: 'col-xs-2'}= t(:statuses) %th{class: 'col-xs-2'}= t(:statuses)
%th{class: 'col-xs-1'}= t(:period) %th{class: 'col-xs-1'}= t(:period)
%th{class: 'col-xs-2'}= t(:registrant) %th{class: 'col-xs-2'}= t(:registrant)
%th{class: 'col-xs-2'}= t(:admin) %th{class: 'col-xs-2'}= t('.admin_contact')
%th{class: 'col-xs-2'}= t(:tech) %th{class: 'col-xs-2'}= t(:tech)
%th{class: 'col-xs-2'}= t(:nameservers) %th{class: 'col-xs-2'}= t(:nameservers)
%th{class: 'col-xs-2'}= t(:dnskeys) %th{class: 'col-xs-2'}= t(:dnskeys)
@ -36,10 +36,15 @@
= render 'admin/domains/partials/version', = render 'admin/domains/partials/version',
domain: version.reify, version: version.previous domain: version.reify, version: version.previous
:coffee :javascript
$(document).on 'click', '.js-pending, .js-event', (e) -> window.addEventListener('load', function() {
e.preventDefault() $(document).on('click', '.js-pending, .js-event', function(e) {
return e.preventDefault();
});
$(document).on 'mousedown', '.js-pending, .js-event', (e) -> $(document).on('mousedown', '.js-pending, .js-event', function(e) {
target = $(e.target) var target;
target.parents('tr').nextUntil('tr.small' ,'tr.' + this.className).toggle() target = $(e.target);
return target.parents('tr').nextUntil('tr.small', 'tr.' + this.className).toggle();
});
});

View file

@ -1,4 +1,4 @@
= render 'shared/title', name: t(:epp_logs) = render 'shared/title', name: t('.title')
.row .row
.col-md-12 .col-md-12
@ -41,8 +41,7 @@
&nbsp; &nbsp;
%span.glyphicon.glyphicon-search %span.glyphicon.glyphicon-search
&nbsp; &nbsp;
%button.btn.btn-default.js-reset-form = link_to(t('.reset_btn'), admin_epp_logs_path, class: 'btn btn-default')
= t(:clear_fields)
.row .row
.col-md-12 .col-md-12
%hr %hr
@ -70,8 +69,3 @@
.row .row
.col-md-12 .col-md-12
= paginate @epp_logs = paginate @epp_logs
:coffee
$(".js-reset-form").on "click", (e) ->
e.preventDefault();
window.location = "#{admin_epp_logs_path}"

View file

@ -21,10 +21,10 @@
= f.label :valid_from, t(:valid) = f.label :valid_from, t(:valid)
.input-group .input-group
= f.text_field(:valid_from, value: f.object.valid_from.try(:to_s, :dshort), = f.text_field(:valid_from, value: f.object.valid_from.try(:to_s, :dshort),
class: 'form-control js-datepicker') class: 'form-control datepicker')
%span.input-group-addon - %span.input-group-addon -
= f.text_field(:valid_to, value: f.object.valid_to.try(:to_s, :dshort), = f.text_field(:valid_to, value: f.object.valid_to.try(:to_s, :dshort),
class: 'form-control js-datepicker') class: 'form-control datepicker')
%hr %hr
.row .row

View file

@ -68,16 +68,16 @@
#epp-users.panel.panel-default #epp-users.panel.panel-default
.panel-heading.clearfix .panel-heading.clearfix
.pull-left .pull-left
= t(:api_users) = t('.api_users')
.pull-right .pull-right
= link_to(t(:create_new_api_user), new_admin_registrar_api_user_path(@registrar), class: 'btn btn-default btn-xs') = link_to(t('.new_api_use_btn'), new_admin_registrar_api_user_path(@registrar), class: 'btn btn-default btn-xs')
.table-responsive .table-responsive
%table.table.table-hover.table-bordered.table-condensed %table.table.table-hover.table-bordered.table-condensed
%thead %thead
%tr %tr
%th{class: 'col-xs-6'}= t(:username) %th{class: 'col-xs-6'}= t(:username)
%th{class: 'col-xs-6'}= t(:active) %th{class: 'col-xs-6'}= t('.active')
%tbody %tbody
- @registrar.api_users.each do |x| - @registrar.api_users.each do |x|
%tr %tr

View file

@ -1,4 +1,4 @@
= render 'shared/title', name: t(:repp_logs) = render 'shared/title', name: t('.title')
.row .row
.col-md-12 .col-md-12
@ -39,8 +39,7 @@
&nbsp; &nbsp;
%span.glyphicon.glyphicon-search %span.glyphicon.glyphicon-search
&nbsp; &nbsp;
%button.btn.btn-default.js-reset-form = link_to(t('.reset_btn'), admin_repp_logs_path, class: 'btn btn-default')
= t(:clear_fields)
%hr %hr
.row .row
.col-md-12 .col-md-12
@ -67,8 +66,3 @@
.row .row
.col-md-12 .col-md-12
= paginate @repp_logs = paginate @repp_logs
:coffee
$(".js-reset-form").on "click", (e) ->
e.preventDefault();
window.location = "#{admin_repp_logs_path}"

View file

@ -1,6 +1,6 @@
- content_for :actions do - content_for :actions do
= link_to(t(:new), new_admin_reserved_domain_path, class: 'btn btn-primary') = link_to(t('.new_btn'), new_admin_reserved_domain_path, class: 'btn btn-primary')
= render 'shared/title', name: t(:reserved_domains) = render 'shared/title', name: t('.title')
.row .row
.col-md-12 .col-md-12
@ -28,8 +28,7 @@
&nbsp; &nbsp;
%span.glyphicon.glyphicon-search %span.glyphicon.glyphicon-search
&nbsp; &nbsp;
%button.btn.btn-default.js-reset-form = link_to(t('.reset_btn'), admin_reserved_domains_path, class: 'btn btn-default')
= t(:clear_fields)
%hr %hr
.row .row
.col-md-12 .col-md-12
@ -65,8 +64,3 @@
.col-md-6.text-right .col-md-6.text-right
.pagination .pagination
= t(:result_count, count: @domains.total_count) = t(:result_count, count: @domains.total_count)
:coffee
$(".js-reset-form").on "click", (e) ->
e.preventDefault();
window.location = "#{admin_reserved_domains_path}"

View file

@ -31,16 +31,22 @@
- value = f.object.new_record? ? '' : f.object.status_notes[s] - value = f.object.new_record? ? '' : f.object.status_notes[s]
= text_field_tag "#{model}[status_notes_array][]", value, class: 'form-control' = text_field_tag "#{model}[status_notes_array][]", value, class: 'form-control'
:coffee :javascript
$("#js-statuses").nestedAttributes window.addEventListener('load', function() {
bindAddTo: $(".js-add-status") $("#js-statuses").nestedAttributes({
afterAdd: (el) -> bindAddTo: $(".js-add-status"),
if el.find('.js-disabled-value') afterAdd: function(el) {
el.find('.js-disabled-value').remove() if (el.find('.js-disabled-value')) {
el.find('.js-select').show() el.find('.js-disabled-value').remove();
el.find('.hide-when-new').hide() el.find('.js-select').show();
el.find('.js-destroy-status').show() el.find('.hide-when-new').hide();
return el.find('.js-destroy-status').show();
}
}
});
$(document).on 'click', '.js-destroy-status', (e) -> $(document).on('click', '.js-destroy-status', function(e) {
e.preventDefault() e.preventDefault();
$(this).parents('.panel').remove() return $(this).parents('.panel').remove();
});
});

View file

@ -0,0 +1,36 @@
!!! 5
%html{lang: I18n.locale.to_s}
%head
%meta{charset: "utf-8"}/
%meta{content: "width=device-width, initial-scale=1", name: "viewport"}/
- if content_for? :head_title
= yield :head_title
- else
%title= t(:admin_head_title)
= csrf_meta_tags
= stylesheet_link_tag 'admin-manifest', media: 'all'
= favicon_link_tag 'favicon.ico'
%body{:style => env_style}
.navbar.navbar-inverse.navbar-static-top{role: "navigation"}
.container
.navbar-header
%button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
%span.sr-only Toggle navigation
%span.icon-bar
%span.icon-bar
%span.icon-bar
= link_to admin_dashboard_path, class: 'navbar-brand' do
= ENV['app_name']
- if unstable_env.present?
.text-center
%small{style: 'color: #0074B3;'}= unstable_env
= render 'menu'
.container
= render 'flash_messages'
= yield
.footer.text-right
Version
= CURRENT_COMMIT_HASH
= javascript_include_tag 'admin-manifest', async: true

View file

@ -1,85 +0,0 @@
!!! 5
%html{lang: I18n.locale.to_s}
%head
%meta{charset: "utf-8"}/
%meta{content: "IE=edge", "http-equiv" => "X-UA-Compatible"}/
%meta{content: "width=device-width, initial-scale=1", name: "viewport"}/
%meta{content: "Full stack top-level domain (TLD) management.", name: "description"}/
%meta{content: "Gitlab LTD", name: "author"}/
- if content_for? :head_title
= yield :head_title
- else
%title= t(:admin_head_title)
= csrf_meta_tags
= stylesheet_link_tag 'admin-manifest', media: 'all', 'data-turbolinks-track' => true
= javascript_include_tag 'admin-manifest', 'data-turbolinks-track' => true
= favicon_link_tag 'favicon.ico'
%body{:style => env_style}
/ Static navbar
.navbar.navbar-inverse.navbar-static-top{role: "navigation"}
.container
.navbar-header
%button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
%span.sr-only Toggle navigation
%span.icon-bar
%span.icon-bar
%span.icon-bar
= link_to admin_dashboard_path, class: 'navbar-brand' do
= ENV['app_name']
- if unstable_env.present?
.text-center
%small{style: 'color: #0074B3;'}= unstable_env
.navbar-collapse.collapse
%ul.nav.navbar-nav
- if can? :show, Domain
%li= link_to t(:domains), admin_domains_path
- if can? :show, Contact
%li= link_to t(:contacts), admin_contacts_path
- if can? :show, Registrar
%li= link_to t(:registrars), admin_registrars_path
- if can? :show, Keyrelay
%li= link_to t(:keyrelays), admin_keyrelays_path
- if can?(:access, :settings_menu)
%li.dropdown
%a.dropdown-toggle{"data-toggle" => "dropdown", href: "#"}
= t(:settings)
%span.caret
%ul.dropdown-menu{role: "menu"}
%li.dropdown-header= t(:users)
%li= link_to t(:api_users), admin_api_users_path
%li= link_to t(:admin_users), admin_admin_users_path
%li.divider
%li.dropdown-header= t(:billing)
- if can? :view, Pricelist
%li= link_to t(:pricelists), admin_pricelists_path
%li= link_to t(:bank_statements), admin_bank_statements_path
%li= link_to t(:invoices), admin_invoices_path
%li= link_to t(:account_activities), admin_account_activities_path(created_after: 'today')
%li.divider
%li.dropdown-header= t(:archive)
%li= link_to t(:domains_history), admin_domain_versions_path
%li= link_to t(:contacts_history), admin_contact_versions_path
%li.divider
%li.dropdown-header= t(:system)
%li= link_to t(:settings), admin_settings_path
%li= link_to t(:zonefile), admin_zonefile_settings_path
%li= link_to t(:blocked_domains), admin_blocked_domains_path
%li= link_to t(:reserved_domains), admin_reserved_domains_path
%li= link_to t(:mail_templates), admin_mail_templates_path
-# %li= link_to t(:domains_history), admin_domain_versions_path
%li= link_to t(:epp_logs), admin_epp_logs_path(created_after: 'today')
%li= link_to t(:repp_logs), admin_repp_logs_path(created_after: 'today')
%li= link_to t(:que), '/admin/que'
- if signed_in?
%ul.nav.navbar-nav.navbar-right
%li= link_to t(:log_out, user: current_user), '/admin/logout'
.container
= render 'shared/flash'
= yield
.footer.text-right
Version
= CURRENT_COMMIT_HASH

View file

@ -0,0 +1,29 @@
!!! 5
%html{lang: I18n.locale.to_s}
%head
%meta{charset: "utf-8"}/
- if content_for? :head_title
= yield :head_title
- else
%title= t(:admin_head_title)
= csrf_meta_tags
= stylesheet_link_tag 'admin-manifest', media: 'all'
= favicon_link_tag 'favicon.ico'
%body{:style => env_style}
.navbar.navbar-inverse.navbar-static-top{role: "navigation"}
.container
.navbar-header
%button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
%span.sr-only Toggle navigation
%span.icon-bar
%span.icon-bar
%span.icon-bar
= link_to admin_dashboard_path, class: 'navbar-brand' do
= ENV['app_name']
- if unstable_env.present?
.text-center
%small{style: 'color: #0074B3;'}= unstable_env
.container
= render 'shared/flash'
= yield

View file

@ -0,0 +1,57 @@
<table width="600" cellspacing="0" cellpadding="0" border="0" align="center"><tbody>
<tr><td>
<table cellspacing="0" cellpadding="0" border="0" align="center" style="text-align: justify; line-height: 16px; font-size: 12px;"><tbody>
<tr><td>
<br />
<p><strong>Lugupeetud domeeni <%= @domain.name %> kontaktisik</strong></p>
<p>.ee domeeniregistrisse on domeeni <strong><%= @domain.name %></strong> kohta kantud järgmised andmed:</p>
<p>Registreerija nimi: <%= @registrant.name %><br>
Isikukood: <%= @registrant.id_code %></p>
<p>Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et füüsiline isik isikukoodiga <%= @registrant.id_code %> on surnud ja sellest on möödunud vähemalt 6 kuud.</p>
<p>Domeenireeglite punktist 6.6 tulenevalt on domeeni suhtes õigust omaval registreerijal võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus Domeenireeglite p 5.3.6.2 kohaselt. Taotlusele tuleb lisada pärimisõiguse tõend, mis asendavad Domeenireeglite punktis 5.3.6.3 sätestatud üleandva registreerija nõusolekut. Vastav dokumentatsioon tuleb esitada Registripidajale <%= @redemption_grace_period %> päeva jooksul.</p>
<p>Kuna käesoleval hetkel domeenil registreerijat pole, on EIS algatanud <%= l(@force_delete_set_date, format: :date) %> vastavalt Domeenireeglite (http://www.internet.ee/domeenid/) punktile 6.6 domeeni <%= @domain.name %> suhtes <%= @redemption_grace_period %> päeva pikkuse kustutusmenetluse. Kustutamise käigus jääb domeen internetis kättesaadavaks ja selle aja jooksul on võimalik teostada domeeni üleandmine.</p>
<p>Kui üleandmine ei ole <%= @redemption_grace_period %> päeva jooksul toimunud, kustub domeen <%= @domain.name %> 24 tunni jooksul <%= @domain.force_delete_date %> juhuslikult valitud ajahetkel. Soovi korral on võimalik domeen pärast selle kustumist registrist “kes ees, see mees” põhimõttel uuesti registreerida.</p>
<p>Lisaküsimuste korral võtke palun ühendust oma registripidajaga:</p>
<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>
<hr>
<p><strong>Dear contact of <%= @domain.name %> domain</strong><br>
The following details for domain name <strong><%= @domain.name %></strong> have been entered into the Estonian Internet Foundation's (EIS) domain registry:</p>
<p>Registrant's name: <%= @registrant.name %><br>
Identification code: <%= @registrant.id_code %></p>
<p>EIS has learned that the natural person <%= @registrant.name %> with identification code <%= @registrant.id_code %> has been deceased and 6 months have passed from death.</p>
<p>According to paragraph 6.6 of the Domain Regulation, the registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @registrar.name %> in accordance with paragraph 5.3.6.2 of the Domain Regulation. The application must be submitted together with succession evidence certifying the acquisition of the domain that will replace the consent of the surrendering registrant as laid down in paragraph 5.3.6.3 of the Domain Regulation. The relevant documents should be submitted to the registrar within <%= @redemption_grace_period %> day(s).</p>
<p>As a deceased natural person is not the registrant of a domain, the EIS started the deletion process of <%= @domain.name %> domain on <%= l(@force_delete_set_date, format: :date) %> according to the Domain Regulation (http://www.internet.ee/en/domains/), using the <%= @redemption_grace_period %>-day delete procedure. The domain will remain available on the Internet during the delete procedure and within this time can be transferred to new registrant.</p>
<p>If the transfer has not been made in <%= @redemption_grace_period %> day(s), the domain <%= @domain.name %> will be deleted at a randomly chosen moment within 24 hours on <%= @domain.force_delete_date %>. After deletion it is possible to reregister the domain on a "first come, first served" basis.</p>
<p>Should you have additional questions, please contact your registrar:</p>
<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>
<br /><br />
<table width="100%" cellspacing="0" cellpadding="0" border="0" align="center" style="text-align: justify; line-height: 16px; font-size: 12px;"><tbody>
<tr><td align="left" valign="top">
<p><strong>Lugupidamisega,<br />
Best Regards,</strong></p>
<p><i>Eesti Interneti Sihtasutus<br />
Estonian Internet Foundation</i></p>
</td><td></td></tr>
</tbody>
</table>
</td></tr>
</tbody></table></table>

View file

@ -0,0 +1,44 @@
Lugupeetud domeeni <%= @domain.name %> kontaktisik
.ee domeeniregistrisse on domeeni <%= @domain.name %> kohta kantud järgmised andmed:
Registreerija nimi: <%= @registrant.name %>
Isikukood: <%= @registrant.id_code %>
Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et füüsiline isik isikukoodiga <%= @registrant.id_code %> on surnud ja sellest on möödunud vähemalt 6 kuud.
Domeenireeglite punktist 6.6 tulenevalt on domeeni suhtes õigust omaval registreerijal võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus Domeenireeglite p 5.3.6.2 kohaselt. Taotlusele tuleb lisada pärimisõiguse tõend, mis asendavad Domeenireeglite punktis 5.3.6.3 sätestatud üleandva registreerija nõusolekut. Vastav dokumentatsioon tuleb esitada Registripidajale <%= @redemption_grace_period %> päeva jooksul.
Kuna käesoleval hetkel domeenil registreerijat pole, on EIS algatanud <%= l(@force_delete_set_date, format: :date) %> vastavalt Domeenireeglite (http://www.internet.ee/domeenid/) punktile 6.6 domeeni <%= @domain.name %> suhtes <%= @redemption_grace_period %> päeva pikkuse kustutusmenetluse. Kustutamise käigus jääb domeen internetis kättesaadavaks ja selle aja jooksul on võimalik teostada domeeni üleandmine.
Kui üleandmine ei ole <%= @redemption_grace_period %> päeva jooksul toimunud, kustub domeen <%= @domain.name %> 24 tunni jooksul <%= @domain.force_delete_date %> juhuslikult valitud ajahetkel. Soovi korral on võimalik domeen pärast selle kustumist registrist “kes ees, see mees” põhimõttel uuesti registreerida.
Lisaküsimuste korral võtke palun ühendust oma registripidajaga:
<%= render 'mailers/shared/registrar/registrar.et.text', registrar: @registrar %>
Dear contact of <%= @domain.name %> domain
The following details for domain name <%= @domain.name %> have been entered into the Estonian Internet Foundation's (EIS) domain registry:
Registrant's name: <%= @registrant.name %>
Identification code: <%= @registrant.id_code %>
EIS has learned that the natural person <%= @registrant.name %> with identification code <%= @registrant.id_code %> has been deceased and 6 months have passed from death.
According to paragraph 6.6 of the Domain Regulation, the registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @registrar.name %> in accordance with paragraph 5.3.6.2 of the Domain Regulation. The application must be submitted together with succession evidence certifying the acquisition of the domain that will replace the consent of the surrendering registrant as laid down in paragraph 5.3.6.3 of the Domain Regulation. The relevant documents should be submitted to the registrar within <%= @redemption_grace_period %> day(s).
As a deceased natural person is not the registrant of a domain, the EIS started the deletion process of <%= @domain.name %> domain on <%= l(@force_delete_set_date, format: :date) %> according to the Domain Regulation (http://www.internet.ee/en/domains/), using the <%= @redemption_grace_period %>-day delete procedure. The domain will remain available on the Internet during the delete procedure and within this time can be transferred to new registrant.
If the transfer has not been made in <%= @redemption_grace_period %> day(s), the domain <%= @domain.name %> will be deleted at a randomly chosen moment within 24 hours on <%= @domain.force_delete_date %>. After deletion it is possible to reregister the domain on a "first come, first served" basis.
Should you have additional questions, please contact your registrar:
<%= render 'mailers/shared/registrar/registrar.en.text', registrar: @registrar %>
Lugupidamisega,
Best Regards,
Eesti Interneti Sihtasutus
Estonian Internet Foundation

View file

@ -1,4 +0,0 @@
- display = (flash.empty?) ? 'none' : 'block'
#flash{style: "display: #{display};"}
- type = (flash[:notice]) ? 'bg-success' : 'bg-danger'
.alert{class: type}= flash[:notice] || flash[:alert]

View file

@ -24,7 +24,7 @@ Rails.application.configure do
# Debug mode disables concatenation and preprocessing of assets. # Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large # This option may cause significant delays in view rendering with a large
# number of complex assets. # number of complex assets.
config.assets.debug = true config.assets.debug = false
# Adds additional error checking when serving assets at runtime. # Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies. # Checks for improperly declared sprockets dependencies.

View file

@ -0,0 +1,5 @@
en:
admin:
account_activities:
index:
reset_btn: Reset

View file

@ -0,0 +1,8 @@
en:
admin:
admin_users:
index:
title: Admin users
new_btn: New admin user
new:
title: New admin user

View file

@ -0,0 +1,17 @@
en:
admin:
api_users:
index:
new_btn: New API user
title: API users
active: Active
show:
active: Active
subject: Subject
new:
title: New API user
form:
active: Active

View file

@ -0,0 +1,7 @@
en:
admin:
blocked_domains:
index:
title: Blocked domains
new_btn: New blocked domain
reset_btn: Reset

View file

@ -0,0 +1,5 @@
en:
admin:
contact_versions:
index:
reset_btn: Reset

View file

@ -0,0 +1,17 @@
en:
admin:
contacts:
index:
reset_btn: Reset
edit:
new_status_btn: Add new status
back_btn: Back to contact
partials:
general:
created: Created
updated: Updated
domains:
roles: Roles

View file

@ -0,0 +1,5 @@
en:
admin:
domain_versions:
archive:
reset_btn: Reset

View file

@ -0,0 +1,36 @@
en:
admin:
domains:
index:
reset_btn: Reset
edit:
add_new_status_btn: Add new status
back_btn: Back to domain
force_delete_dialog:
title: Force delete
template: Template
close_btn: Close dialog
submit_btn: Force delete domain
schedule_force_delete:
scheduled: Force delete procedure has been scheduled
cancel_force_delete:
cancelled: Force delete procedure has been cancelled
versions:
time: Time
admin_contact: Admin contact
partials:
general:
outzone_time: Outzone time
delete_time: Delete time
force_delete_time: Force delete time
force_delete_toggle_btn:
schedule: Schedule force delete
cancel: Cancel force delete
cancel_confim: Are you sure you want cancel force delete procedure?

View file

@ -0,0 +1,6 @@
en:
admin:
epp_logs:
index:
title: EPP log
reset_btn: Reset

View file

@ -0,0 +1,14 @@
en:
admin:
menu:
users: Users
api_users: API users
admin_users: Admin users
archive: Archive
domain_history: Domain history
contact_history: Contact history
blocked_domains: Blocked domains
reserved_domains: Reserved domains
epp_log: EPP log
repp_log: REPP log
que: Que

View file

@ -0,0 +1,7 @@
en:
admin:
registrars:
show:
new_api_use_btn: New API user
active: Active
api_users: API users

View file

@ -0,0 +1,6 @@
en:
admin:
repp_logs:
index:
title: REPP log
reset_btn: Reset

View file

@ -0,0 +1,7 @@
en:
admin:
reserved_domains:
index:
title: Reserved domains
new_btn: New reserved domain
reset_btn: Reset

View file

@ -280,7 +280,6 @@ en:
system: 'System' system: 'System'
settings: 'Settings' settings: 'Settings'
domains: 'Domains' domains: 'Domains'
api_users: 'API users'
registrars: 'Registrars' registrars: 'Registrars'
valid_to: 'Valid to' valid_to: 'Valid to'
name: 'Name' name: 'Name'
@ -407,13 +406,10 @@ en:
failed_to_delete_registrar: 'Failed to delete registrar' failed_to_delete_registrar: 'Failed to delete registrar'
users: 'Users' users: 'Users'
create_new_user: 'Create new user'
admin: 'Admin'
user_details: 'User details' user_details: 'User details'
edit_user: 'Edit user' edit_user: 'Edit user'
back_to_user: 'Back to user' back_to_user: 'Back to user'
create_new_api_user: 'Create new API user'
certificate_signing_req: 'Certificate signing request' certificate_signing_req: 'Certificate signing request'
csr: 'CSR' csr: 'CSR'
crt: 'CRT' crt: 'CRT'
@ -459,11 +455,8 @@ en:
ds_digest_type: 'DS digest type' ds_digest_type: 'DS digest type'
zonefile_settings: 'Zonefile settings' zonefile_settings: 'Zonefile settings'
background_jobs: Background jobs background_jobs: Background jobs
domain_history: Domain history
domains_history: Domains history domains_history: Domains history
admin_users: Admin users
role: 'Role' role: 'Role'
admin: 'Administrator'
user: 'User' user: 'User'
customer_service: 'Customer service' customer_service: 'Customer service'
keyrelays: 'Keyrelays' keyrelays: 'Keyrelays'
@ -484,8 +477,6 @@ en:
action_failed_due_to_server_error: 'Action failed due to server error' action_failed_due_to_server_error: 'Action failed due to server error'
pending_transfer_was_not_found: 'Pending transfer was not found' pending_transfer_was_not_found: 'Pending transfer was not found'
transfer_can_be_rejected_only_by_current_registrar: 'Transfer can be rejected only by current registrar' transfer_can_be_rejected_only_by_current_registrar: 'Transfer can be rejected only by current registrar'
epp_logs: 'EPP logs'
epp_log: 'EPP log'
request_command: 'Request command' request_command: 'Request command'
request_object: 'Request object' request_object: 'Request object'
api_user: 'API user' api_user: 'API user'
@ -497,8 +488,6 @@ en:
request_method: 'Request method' request_method: 'Request method'
response_code: 'Response code' response_code: 'Response code'
request_params: 'Request params' request_params: 'Request params'
repp_log: 'REPP log'
repp_logs: 'REPP logs'
could_not_determine_object_type_check_xml_format_and_namespaces: 'Could not determine object type. Check XML format and namespaces.' could_not_determine_object_type_check_xml_format_and_namespaces: 'Could not determine object type. Check XML format and namespaces.'
unknown_expiry_relative_pattern: 'Expiry relative must be compatible to ISO 8601' unknown_expiry_relative_pattern: 'Expiry relative must be compatible to ISO 8601'
unknown_expiry_absolute_pattern: 'Expiry absolute must be compatible to ISO 8601' unknown_expiry_absolute_pattern: 'Expiry absolute must be compatible to ISO 8601'
@ -613,7 +602,6 @@ en:
new_domain: 'New domain' new_domain: 'New domain'
edit: 'Edit' edit: 'Edit'
delete: 'Delete' delete: 'Delete'
are_you_sure: 'Are you sure?'
renew: 'Renew' renew: 'Renew'
new: New new: New
renew_domain: 'Renew domain' renew_domain: 'Renew domain'
@ -850,14 +838,11 @@ en:
webserver_missing_client_cert_directive: 'Webserver missing client cert directive' webserver_missing_client_cert_directive: 'Webserver missing client cert directive'
webserver_client_cert_directive_should_be_required: 'Webserver client cert directive should be required' webserver_client_cert_directive_should_be_required: 'Webserver client cert directive should be required'
tech: Tech contact tech: Tech contact
admin: Admin contact
pricelists: Pricelists pricelists: Pricelists
new_pricelist: New Pricelist new_pricelist: New Pricelist
valid: Valid valid: Valid
category: Zone category: Zone
object_is_not_eligible_for_renewal: 'Object is not eligible for renewal' object_is_not_eligible_for_renewal: 'Object is not eligible for renewal'
set_force_delete: 'Set force delete'
unset_force_delete: 'Unset force delete'
domain_expiring: 'Domain expiring' domain_expiring: 'Domain expiring'
domain_validation_rules: 'Domain validation rules' domain_validation_rules: 'Domain validation rules'
bank_statement_desc: 'Import file row will match only when matching following attributes: <b><br>ref number<br>payment amount<br>invoice number (the first numerical value in comment field)</b>.' bank_statement_desc: 'Import file row will match only when matching following attributes: <b><br>ref number<br>payment amount<br>invoice number (the first numerical value in comment field)</b>.'
@ -884,7 +869,6 @@ en:
registry_state: 'State / Province' registry_state: 'State / Province'
registry_zip: 'Postcode' registry_zip: 'Postcode'
registry_country_code: 'Country' registry_country_code: 'Country'
blocked_domains: 'Blocked domains'
billing_failure_credit_balance_low: 'Billing failure - credit balance low' billing_failure_credit_balance_low: 'Billing failure - credit balance low'
create: 'Create' create: 'Create'
activity_type: 'Activity type' activity_type: 'Activity type'
@ -892,7 +876,6 @@ en:
receipt_date_until: 'Receipt date until' receipt_date_until: 'Receipt date until'
add_credit: 'Add credit' add_credit: 'Add credit'
export_csv: 'Export CSV' export_csv: 'Export CSV'
reserved_domains: 'Reserved domains'
invalid_yaml: 'Invalid YAML' invalid_yaml: 'Invalid YAML'
reserved_pw: 'Reserved pw' reserved_pw: 'Reserved pw'
no_transfers_found: 'No transfers found' no_transfers_found: 'No transfers found'
@ -928,7 +911,7 @@ en:
created_at_from: 'Created at from' created_at_from: 'Created at from'
created_at_until: 'Created at until' created_at_until: 'Created at until'
is_registrant: 'Is registrant' is_registrant: 'Is registrant'
force_delete_set_on_domain: 'Force delete set on domain %{domain}' force_delete_set_on_domain: 'Force delete set on domain %{domain_name}'
mail_templates: Mail Templates mail_templates: Mail Templates
new_mail_template: New mail template new_mail_template: New mail template
failure: "It was not saved" failure: "It was not saved"

View file

@ -202,9 +202,10 @@ Rails.application.routes.draw do
resources :domain_versions, controller: 'domains', action: 'versions' resources :domain_versions, controller: 'domains', action: 'versions'
resources :pending_updates resources :pending_updates
resources :pending_deletes resources :pending_deletes
member do member do
post 'set_force_delete' patch 'schedule_force_delete'
post 'unset_force_delete' patch 'cancel_force_delete'
end end
end end

View file

@ -10,5 +10,14 @@ FactoryGirl.define do
domain.admin_domain_contacts << FactoryGirl.build(:admin_domain_contact) domain.admin_domain_contacts << FactoryGirl.build(:admin_domain_contact)
domain.tech_domain_contacts << FactoryGirl.build(:tech_domain_contact) domain.tech_domain_contacts << FactoryGirl.build(:tech_domain_contact)
end end
factory :domain_without_force_delete do
force_delete_time nil
statuses []
end
factory :domain_discarded do
statuses [DomainStatus::DELETE_CANDIDATE]
end
end end
end end

View file

@ -0,0 +1,33 @@
require 'rails_helper'
RSpec.feature 'Force delete' do
context 'when domain has no force delete procedure' do
given!(:domain) { create(:domain_without_force_delete) }
scenario 'schedule' do
sign_in_to_admin_area
visit edit_admin_domain_url(domain)
click_link_or_button 'Force delete domain'
expect(page).to have_text('Force delete procedure has been scheduled')
end
end
context 'when domain has force delete procedure' do
given!(:domain) { create(:domain_without_force_delete) }
background do
domain.schedule_force_delete
end
scenario 'cancel' do
sign_in_to_admin_area
visit edit_admin_domain_url(domain)
click_link_or_button 'Cancel force delete'
expect(page).to have_text('Force delete procedure has been cancelled')
end
end
end

View file

@ -17,7 +17,8 @@ RSpec.describe DomainDeleteForcedEmailJob do
after :example do after :example do
domain_id = 1 domain_id = 1
described_class.enqueue(domain_id) template_name = 'removed_company'
described_class.enqueue(domain_id, template_name)
end end
it 'creates log record' do it 'creates log record' do
@ -32,7 +33,8 @@ RSpec.describe DomainDeleteForcedEmailJob do
it 'sends email' do it 'sends email' do
expect(DomainDeleteMailer).to receive(:forced).with(domain: domain, expect(DomainDeleteMailer).to receive(:forced).with(domain: domain,
registrar: 'registrar', registrar: 'registrar',
registrant: 'registrant') registrant: 'registrant',
template_name: 'removed_company')
.and_return(message) .and_return(message)
expect(message).to receive(:deliver_now) expect(message).to receive(:deliver_now)
end end

View file

@ -48,12 +48,16 @@ RSpec.describe DomainDeleteMailer do
describe '#forced' do describe '#forced' do
let(:domain) { instance_spy(Domain, name: 'test.com') } let(:domain) { instance_spy(Domain, name: 'test.com') }
let(:registrant) { instance_spy(Registrant) }
let(:template_name) { 'removed_company' }
let(:domain_presenter) { instance_spy(DomainPresenter) } let(:domain_presenter) { instance_spy(DomainPresenter) }
let(:registrar_presenter) { instance_spy(RegistrarPresenter) } let(:registrar_presenter) { instance_spy(RegistrarPresenter) }
let(:registrant_presenter) { instance_spy(RegistrantPresenter) } let(:registrant_presenter) { instance_spy(RegistrantPresenter) }
subject(:message) { described_class.forced(domain: domain, subject(:message) { described_class.forced(domain: domain,
registrar: 'registrar', registrar: 'registrar',
registrant: 'registrant') registrant: registrant,
template_name: template_name)
} }
before :example do before :example do
@ -75,8 +79,28 @@ RSpec.describe DomainDeleteMailer do
expect(message.subject).to eq('Kustutusmenetluse teade') expect(message.subject).to eq('Kustutusmenetluse teade')
end end
context 'when template is :death' do
let(:template_name) { 'death' }
it 'sends message' do it 'sends message' do
expect { message.deliver_now }.to change { ActionMailer::Base.deliveries.count }.by(1) expect { message.deliver_now }.to change { ActionMailer::Base.deliveries.count }.by(1)
end end
end end
context 'when registrant is private entity' do
let(:registrant) { build_stubbed(:registrant_private_entity) }
it 'sends message' do
expect { message.deliver_now }.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end
context 'when registrant is legal entity' do
let(:registrant) { build_stubbed(:registrant_legal_entity) }
it 'sends message' do
expect { message.deliver_now }.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end
end
end end

View file

@ -0,0 +1,19 @@
require 'rails_helper'
RSpec.describe Domain, db: false do
it { is_expected.to alias_attribute(:delete_time, :delete_at) }
describe '#discarded?' do
context 'when :deleteCandidate status is present' do
let(:domain) { described_class.new(statuses: [DomainStatus::DELETE_CANDIDATE]) }
specify { expect(domain).to be_discarded }
end
context 'when :deleteCandidate status is absent' do
let(:domain) { described_class.new(statuses: []) }
specify { expect(domain).to_not be_discarded }
end
end
end

View file

@ -0,0 +1,98 @@
require 'rails_helper'
RSpec.describe Domain do
it { is_expected.to alias_attribute(:force_delete_time, :force_delete_at) }
before :example do
Fabricate(:zonefile_setting, origin: 'ee')
end
it 'should set force delete time' do
domain = Fabricate(:domain)
domain.statuses = ['ok']
domain.schedule_force_delete
domain.statuses.should match_array([
"serverForceDelete",
"pendingDelete",
"serverManualInzone",
"serverRenewProhibited",
"serverTransferProhibited",
"serverUpdateProhibited"
])
domain.cancel_force_delete
domain.statuses.should == ['ok']
domain.statuses = [
DomainStatus::CLIENT_DELETE_PROHIBITED,
DomainStatus::SERVER_DELETE_PROHIBITED,
DomainStatus::PENDING_UPDATE,
DomainStatus::PENDING_TRANSFER,
DomainStatus::PENDING_RENEW,
DomainStatus::PENDING_CREATE,
DomainStatus::CLIENT_HOLD,
DomainStatus::EXPIRED,
DomainStatus::SERVER_HOLD,
DomainStatus::DELETE_CANDIDATE
]
domain.save
domain.schedule_force_delete
domain.statuses.should match_array([
"clientHold",
"deleteCandidate",
"expired",
"serverForceDelete",
"pendingDelete",
"serverHold",
"serverRenewProhibited",
"serverTransferProhibited",
"serverUpdateProhibited"
])
domain.cancel_force_delete
domain.statuses.should match_array([
"clientDeleteProhibited",
"clientHold",
"deleteCandidate",
"expired",
"pendingCreate",
"pendingRenew",
"pendingTransfer",
"pendingUpdate",
"serverDeleteProhibited",
"serverHold"
])
end
it 'should should be manual in zone and held after force delete' do
domain = create(:domain)
Setting.redemption_grace_period = 1
domain.valid?
domain.outzone_at = Time.zone.now + 1.day # before redemption grace period
# what should this be?
# domain.server_holdable?.should be true
domain.statuses.include?(DomainStatus::SERVER_HOLD).should be false
domain.statuses.include?(DomainStatus::SERVER_MANUAL_INZONE).should be false
domain.schedule_force_delete
domain.server_holdable?.should be false
domain.statuses.include?(DomainStatus::SERVER_MANUAL_INZONE).should be true
domain.statuses.include?(DomainStatus::SERVER_HOLD).should be false
end
it 'should not allow update after force delete' do
domain = create(:domain)
domain.valid?
domain.pending_update_prohibited?.should be false
domain.update_prohibited?.should be false
domain.schedule_force_delete
domain.pending_update_prohibited?.should be true
domain.update_prohibited?.should be true
end
end

View file

@ -481,4 +481,18 @@ RSpec.describe Contact, db: false do
specify { expect(reg_no).to be_nil } specify { expect(reg_no).to be_nil }
end end
end end
describe '#id_code' do
context 'when contact is private entity' do
let(:contact) { FactoryGirl.build_stubbed(:contact_private_entity, ident: '1234') }
specify { expect(contact.id_code).to eq('1234') }
end
context 'when contact is legal entity' do
let(:contact) { FactoryGirl.build_stubbed(:contact_legal_entity, ident: '1234') }
specify { expect(contact.id_code).to be_nil }
end
end
end end

View file

@ -182,98 +182,6 @@ RSpec.describe Domain do
domain.statuses.include?(DomainStatus::SERVER_HOLD).should == false domain.statuses.include?(DomainStatus::SERVER_HOLD).should == false
end end
it 'should set force delete time' do
@domain.statuses = ['ok']
@domain.set_force_delete
@domain.statuses.should match_array([
"serverForceDelete",
"pendingDelete",
"serverManualInzone",
"serverRenewProhibited",
"serverTransferProhibited",
"serverUpdateProhibited"
])
fda = Time.zone.now + Setting.redemption_grace_period.days
@domain.registrar.messages.count.should == 1
m = @domain.registrar.messages.first
m.body.should == "Force delete set on domain #{@domain.name}"
@domain.unset_force_delete
@domain.statuses.should == ['ok']
@domain.statuses = [
DomainStatus::CLIENT_DELETE_PROHIBITED,
DomainStatus::SERVER_DELETE_PROHIBITED,
DomainStatus::PENDING_UPDATE,
DomainStatus::PENDING_TRANSFER,
DomainStatus::PENDING_RENEW,
DomainStatus::PENDING_CREATE,
DomainStatus::CLIENT_HOLD,
DomainStatus::EXPIRED,
DomainStatus::SERVER_HOLD,
DomainStatus::DELETE_CANDIDATE
]
@domain.save
@domain.set_force_delete
@domain.statuses.should match_array([
"clientHold",
"deleteCandidate",
"expired",
"serverForceDelete",
"pendingDelete",
"serverHold",
"serverRenewProhibited",
"serverTransferProhibited",
"serverUpdateProhibited"
])
@domain.unset_force_delete
@domain.statuses.should match_array([
"clientDeleteProhibited",
"clientHold",
"deleteCandidate",
"expired",
"pendingCreate",
"pendingRenew",
"pendingTransfer",
"pendingUpdate",
"serverDeleteProhibited",
"serverHold"
])
end
it 'should should be manual in zone and held after force delete' do
Setting.redemption_grace_period = 1
@domain.valid?
@domain.outzone_at = Time.zone.now + 1.day # before redemption grace period
# what should this be?
# @domain.server_holdable?.should be true
@domain.statuses.include?(DomainStatus::SERVER_HOLD).should be false
@domain.statuses.include?(DomainStatus::SERVER_MANUAL_INZONE).should be false
@domain.set_force_delete
@domain.server_holdable?.should be false
@domain.statuses.include?(DomainStatus::SERVER_MANUAL_INZONE).should be true
@domain.statuses.include?(DomainStatus::SERVER_HOLD).should be false
end
it 'should not allow update after force delete' do
@domain.valid?
@domain.pending_update_prohibited?.should be false
@domain.update_prohibited?.should be false
@domain.set_force_delete
@domain.pending_update_prohibited?.should be true
@domain.update_prohibited?.should be true
end
context 'with time period settings' do context 'with time period settings' do
before :example do before :example do
@save_days_to_renew = Setting.days_to_renew_domain_before_expire @save_days_to_renew = Setting.days_to_renew_domain_before_expire
@ -302,7 +210,7 @@ RSpec.describe Domain do
it 'should not allow to renew after force delete' do it 'should not allow to renew after force delete' do
Setting.redemption_grace_period = 1 Setting.redemption_grace_period = 1
@domain.set_force_delete @domain.schedule_force_delete
@domain.renewable?.should be false @domain.renewable?.should be false
end end
end end
@ -327,7 +235,7 @@ RSpec.describe Domain do
it 'should not allow to renew after force delete' do it 'should not allow to renew after force delete' do
Setting.redemption_grace_period = 1 Setting.redemption_grace_period = 1
@domain.set_force_delete @domain.schedule_force_delete
@domain.renewable?.should be false @domain.renewable?.should be false
end end
end end
@ -699,7 +607,6 @@ end
RSpec.describe Domain, db: false do RSpec.describe Domain, db: false do
it { is_expected.to alias_attribute(:on_hold_time, :outzone_at) } it { is_expected.to alias_attribute(:on_hold_time, :outzone_at) }
it { is_expected.to alias_attribute(:delete_time, :delete_at) }
it { is_expected.to alias_attribute(:force_delete_time, :force_delete_at) } it { is_expected.to alias_attribute(:force_delete_time, :force_delete_at) }
it { is_expected.to alias_attribute(:outzone_time, :outzone_at) } it { is_expected.to alias_attribute(:outzone_time, :outzone_at) }

View file

@ -114,6 +114,40 @@ RSpec.describe DomainPresenter do
end end
end end
describe '#force_delete_toggle_btn' do
let(:domain) { build_stubbed(:domain) }
context 'when force delete is not scheduled' do
before :example do
expect(domain).to receive(:force_delete_scheduled?).and_return(false)
end
it 'returns schedule button' do
html = view.content_tag(:a, 'Schedule force delete',
class: 'btn btn-danger',
data: {
toggle: 'modal',
target: '.domain-edit-force-delete-dialog',
})
expect(presenter.force_delete_toggle_btn).to eq(html)
end
end
context 'when force delete is scheduled' do
before :example do
expect(domain).to receive(:force_delete_scheduled?).and_return(true)
end
it 'returns cancel button' do
html = link_to('Cancel force delete',
view.cancel_force_delete_admin_domain_path(domain),
method: :patch,
data: { confirm: 'Are you sure you want cancel force delete procedure?' },
class: 'btn btn-primary')
expect(presenter.force_delete_toggle_btn).to eq(html)
end
end
end
domain_delegatable_attributes = %i( domain_delegatable_attributes = %i(
name name

View file

@ -11,6 +11,7 @@ RSpec.describe RegistrantPresenter do
priv? priv?
street street
city city
id_code
) )
registrant_delegate_attributes.each do |attribute_name| registrant_delegate_attributes.each do |attribute_name|

View file

@ -6,6 +6,7 @@ require 'capybara/poltergeist'
require 'paper_trail/frameworks/rspec' require 'paper_trail/frameworks/rspec'
require 'money-rails/test_helpers' require 'money-rails/test_helpers'
require 'support/requests/session_helpers' require 'support/requests/session_helpers'
require 'support/requests/epp_helpers'
require 'support/features/session_helpers' require 'support/features/session_helpers'
if ENV['ROBOT'] if ENV['ROBOT']
@ -15,6 +16,8 @@ end
require 'support/matchers/alias_attribute' require 'support/matchers/alias_attribute'
require 'support/matchers/active_job' require 'support/matchers/active_job'
require 'support/matchers/epp/code'
require 'support/capybara' require 'support/capybara'
require 'support/factory_girl' require 'support/factory_girl'
require 'support/database_cleaner' require 'support/database_cleaner'
@ -29,6 +32,9 @@ RSpec.configure do |config|
config.include Requests::SessionHelpers, type: :request config.include Requests::SessionHelpers, type: :request
config.include Features::SessionHelpers, type: :feature config.include Features::SessionHelpers, type: :feature
config.include AbstractController::Translation, type: :feature config.include AbstractController::Translation, type: :feature
config.include Requests::EPPHelpers, epp: true
config.include Requests::EPPHelpers, epp: true
config.define_derived_metadata(file_path: %r[/spec/features/]) do |metadata| config.define_derived_metadata(file_path: %r[/spec/features/]) do |metadata|
metadata[:db] = true if metadata[:db].nil? metadata[:db] = true if metadata[:db].nil?
@ -46,10 +52,18 @@ RSpec.configure do |config|
metadata[:db] = true if metadata[:db].nil? metadata[:db] = true if metadata[:db].nil?
end end
config.define_derived_metadata(file_path: %r[/spec/requests/epp/]) do |metadata|
metadata[:epp] = true if metadata[:epp].nil?
end
config.define_derived_metadata(file_path: %r[/spec/api/]) do |metadata| config.define_derived_metadata(file_path: %r[/spec/api/]) do |metadata|
metadata[:type] = :request metadata[:type] = :request
end end
config.define_derived_metadata(file_path: %r[/spec/requests/epp/]) do |metadata|
metadata[:epp] = true if metadata[:epp].nil?
end
config.use_transactional_fixtures = false config.use_transactional_fixtures = false
config.infer_spec_type_from_file_location! config.infer_spec_type_from_file_location!

View file

@ -0,0 +1,44 @@
require 'rails_helper'
RSpec.describe 'EPP domain:delete' do
let(: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>
<delete>
<domain:delete xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>test.com</domain:name>
</domain:delete>
</delete>
<extension>
<eis:extdata xmlns:eis="https://epp.tld.ee/schema/eis-1.0.xsd">
<eis:legalDocument type="pdf">dGVzdCBmYWlsCg==</eis:legalDocument>
</eis:extdata>
</extension>
</command>
</epp>
XML
}
before :example do
sign_in_to_epp_area
end
context 'when domain is not discarded' do
let!(:domain) { create(:domain, name: 'test.com') }
it 'returns epp code of 1001' do
post '/epp/command/delete', frame: request_xml
expect(response).to have_code_of(1001)
end
end
context 'when domain is discarded' do
let!(:domain) { create(:domain_discarded, name: 'test.com') }
it 'returns epp code of 2105' do
post '/epp/command/delete', frame: request_xml
expect(response).to have_code_of(2105)
end
end
end

View file

@ -0,0 +1,42 @@
require 'rails_helper'
RSpec.describe 'EPP domain:transfer' do
let(: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>
<transfer op="request">
<domain:transfer xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>test.com</domain:name>
<domain:authInfo>
<domain:pw>98oiewslkfkd</domain:pw>
</domain:authInfo>
</domain:transfer>
</transfer>
</command>
</epp>
XML
}
before :example do
sign_in_to_epp_area
end
context 'when domain is not discarded' do
let!(:domain) { create(:domain, name: 'test.com') }
it 'returns epp code of 1000' do
post '/epp/command/transfer', frame: request_xml
expect(response).to have_code_of(1000)
end
end
context 'when domain is discarded' do
let!(:domain) { create(:domain_discarded, name: 'test.com') }
it 'returns epp code of 2105' do
post '/epp/command/transfer', frame: request_xml
expect(response).to have_code_of(2105)
end
end
end

View file

@ -0,0 +1,39 @@
require 'rails_helper'
RSpec.describe 'EPP domain:update' do
let(: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>
<update>
<domain:update xmlns:domain="https://epp.tld.ee/schema/domain-eis-1.0.xsd">
<domain:name>test.com</domain:name>
</domain:update>
</update>
</command>
</epp>
XML
}
before :example do
sign_in_to_epp_area
end
context 'when domain is not discarded' do
let!(:domain) { create(:domain, name: 'test.com') }
it 'returns epp code of 1000' do
post '/epp/command/update', frame: request_xml
expect(response).to have_code_of(1000)
end
end
context 'when domain is discarded' do
let!(:domain) { create(:domain_discarded, name: 'test.com') }
it 'returns epp code of 2105' do
post '/epp/command/update', frame: request_xml
expect(response).to have_code_of(2105)
end
end
end

View file

@ -0,0 +1,13 @@
require 'rails_helper'
RSpec.describe Admin::DomainsController do
describe 'routing' do
it 'routes to #schedule_force_delete' do
expect(patch: '/admin/domains/1/schedule_force_delete').to route_to('admin/domains#schedule_force_delete', id: '1')
end
it 'routes to #cancel_force_delete' do
expect(patch: '/admin/domains/1/cancel_force_delete').to route_to('admin/domains#cancel_force_delete', id: '1')
end
end
end

View file

@ -1,5 +1,14 @@
module Features module Features
module SessionHelpers module SessionHelpers
def sign_in_to_admin_area(user: FactoryGirl.create(:admin_user))
visit admin_login_url
fill_in 'admin_user[username]', with: user.username
fill_in 'admin_user[password]', with: user.password
click_button 'Log in'
end
def sign_in_to_registrar_area(user: FactoryGirl.create(:api_user)) def sign_in_to_registrar_area(user: FactoryGirl.create(:api_user))
visit registrar_login_url visit registrar_login_url

View file

@ -0,0 +1,35 @@
module Matchers
module EPP
class Code
def initialize(expected)
@expected = expected
end
def matches?(response)
@xml = response.body
actual == expected
end
def failure_message
"Expected EPP code of #{expected}, got #{actual} (#{description})"
end
private
attr_reader :xml
attr_reader :expected
def actual
xml_document.xpath('//xmlns:result').first['code'].to_i
end
def description
xml_document.css('result msg').text
end
def xml_document
@xml_document ||= Nokogiri::XML(xml)
end
end
end
end

View file

@ -0,0 +1,7 @@
module Requests
module EPPHelpers
def have_code_of(*args)
Matchers::EPP::Code.new(*args)
end
end
end

View file

@ -0,0 +1,22 @@
require 'rails_helper'
RSpec.describe 'admin/domains/edit' do
let(:domain) { build_stubbed(:domain) }
let(:domain_presenter) { DomainPresenter.new(domain: domain, view: view) }
before :example do
allow(DomainPresenter).to receive(:new).and_return(domain_presenter)
allow(view).to receive(:force_delete_templates)
assign(:domain, domain)
stub_template '_form' => ''
stub_template '_force_delete_dialog' => ''
end
it 'has force_delete_toggle_btn' do
expect(domain_presenter).to receive(:force_delete_toggle_btn).and_return('force_delete_toggle_btn')
render
expect(rendered).to have_content('force_delete_toggle_btn')
end
end

View file

@ -1,7 +1,7 @@
require 'rails_helper' require 'rails_helper'
require_relative 'forced_shared' require_relative 'removed_company'
RSpec.describe 'mailers/domain_delete_mailer/forced.html.erb' do RSpec.describe 'mailers/domain_delete_mailer/forced/removed_company.html.erb' do
before :example do before :example do
stub_template 'mailers/shared/registrar/_registrar.et.html' => 'test registrar estonian' stub_template 'mailers/shared/registrar/_registrar.et.html' => 'test registrar estonian'
stub_template 'mailers/shared/registrar/_registrar.en.html' => 'test registrar english' stub_template 'mailers/shared/registrar/_registrar.en.html' => 'test registrar english'

View file

@ -1,7 +1,7 @@
require 'rails_helper' require 'rails_helper'
require_relative 'forced_shared' require_relative 'removed_company'
RSpec.describe 'mailers/domain_delete_mailer/forced.text.erb' do RSpec.describe 'mailers/domain_delete_mailer/forced/removed_company.text.erb' do
before :example do before :example do
stub_template 'mailers/shared/registrar/_registrar.et.text' => 'test registrar estonian' stub_template 'mailers/shared/registrar/_registrar.et.text' => 'test registrar estonian'
stub_template 'mailers/shared/registrar/_registrar.en.text' => 'test registrar english' stub_template 'mailers/shared/registrar/_registrar.en.text' => 'test registrar english'