Merge branch 'master' into refactor-messages

# Conflicts:
#	db/structure.sql
This commit is contained in:
Artur Beljajev 2018-09-01 19:39:25 +03:00
commit 056c57530c
32 changed files with 730 additions and 148 deletions

View file

@ -27,3 +27,4 @@ exclude_patterns:
- "vendor/"
- "test/"
- "spec/"
- "CHANGELOG.md"

View file

@ -0,0 +1,21 @@
module Admin
module Domains
class RegistryLockController < BaseController
def destroy
set_domain
authorize! :manage, @domain
if @domain.remove_registry_lock
redirect_to edit_admin_domain_url(@domain), notice: t('.success')
else
redirect_to edit_admin_domain_url(@domain), alert: t('.error')
end
end
private
def set_domain
@domain = Domain.find(params[:domain_id])
end
end
end
end

View file

@ -47,7 +47,7 @@ module Admin
def destroy
@mail_template = MailTemplate.find(params[:id])
if @mail_template.destroy
redirect_to admin_mail_templates_path, notise: t(:deleted)
redirect_to admin_mail_templates_path, notice: t(:deleted)
else
flash.now[:alert] = I18n.t(:failure)
render 'show'

View file

@ -6,6 +6,7 @@ module Api
module Registrant
class BaseController < ActionController::API
before_action :authenticate
before_action :set_paper_trail_whodunnit
rescue_from(ActionController::ParameterMissing) do |parameter_missing_exception|
error = {}
@ -22,16 +23,32 @@ module Api
header.gsub(pattern, '') if header&.match(pattern)
end
def associated_domains(user)
country_code, ident = user.registrant_ident.split('-')
BusinessRegistryCache.fetch_associated_domains(ident, country_code)
rescue Soap::Arireg::NotAvailableError => error
Rails.logger.fatal("[EXCEPTION] #{error}")
user.domains
end
def authenticate
decryptor = AuthTokenDecryptor.create_with_defaults(bearer_token)
decryptor.decrypt_token
if decryptor.valid?
sign_in decryptor.user
sign_in(:registrant_user, decryptor.user)
else
render json: { errors: [{base: ['Not authorized']}] }, status: :unauthorized
render json: { errors: [{ base: ['Not authorized'] }] },
status: :unauthorized
end
end
# This controller does not inherit from ApplicationController,
# so user_for_paper_trail method is not usable.
def set_paper_trail_whodunnit
::PaperTrail.whodunnit = current_registrant_user.id_role_username
end
end
end
end

View file

@ -30,17 +30,6 @@ module Api
render json: { errors: [{ base: ['Domain not found'] }] }, status: :not_found
end
end
private
def associated_domains(user)
country_code, ident = user.registrant_ident.split('-')
BusinessRegistryCache.fetch_associated_domains(ident, country_code)
rescue Soap::Arireg::NotAvailableError => error
Rails.logger.fatal("[EXCEPTION] #{error}")
user.domains
end
end
end
end

View file

@ -0,0 +1,48 @@
module Api
module V1
module Registrant
class RegistryLocksController < BaseController
before_action :set_domain
before_action :authorized_to_manage_locks?
def create
if @domain.apply_registry_lock
render json: @domain
else
render json: { errors: [{ base: ['Domain cannot be locked'] }] },
status: :unprocessable_entity
end
end
def destroy
if @domain.remove_registry_lock
render json: @domain
else
render json: { errors: [{ base: ['Domain is not locked'] }] },
status: :unprocessable_entity
end
end
private
def set_domain
domain_pool = current_registrant_user.domains
@domain = domain_pool.find_by(uuid: params[:domain_uuid])
return if @domain
render json: { errors: [{ base: ['Domain not found'] }] },
status: :not_found and return
end
def authorized_to_manage_locks?
return if current_registrant_user.administered_domains.include?(@domain)
render json: { errors: [
{ base: ['Only administrative contacts can manage registry locks'] }
] },
status: :unauthorized and return
end
end
end
end
end

View file

@ -0,0 +1,51 @@
module Concerns
module Domain
module RegistryLockable
extend ActiveSupport::Concern
def apply_registry_lock
return unless registry_lockable?
return if locked_by_registrant?
transaction do
statuses << DomainStatus::SERVER_UPDATE_PROHIBITED
statuses << DomainStatus::SERVER_DELETE_PROHIBITED
statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED
self.locked_by_registrant_at = Time.zone.now
save!
end
end
def registry_lockable?
(statuses & [DomainStatus::PENDING_DELETE_CONFIRMATION,
DomainStatus::PENDING_CREATE, DomainStatus::PENDING_UPDATE,
DomainStatus::PENDING_DELETE, DomainStatus::PENDING_RENEW,
DomainStatus::PENDING_TRANSFER, DomainStatus::FORCE_DELETE]).empty?
end
def locked_by_registrant?
return false unless locked_by_registrant_at
lock_statuses = [DomainStatus::SERVER_UPDATE_PROHIBITED,
DomainStatus::SERVER_DELETE_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED]
(statuses & lock_statuses).count == 3
end
def remove_registry_lock
return unless locked_by_registrant?
transaction do
statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED)
self.locked_by_registrant_at = nil
save!
end
end
end
end
end

View file

@ -37,7 +37,7 @@ module Versions
registrar = Registrar.find_by(name: str)
user = registrar.api_users.first if registrar
str_match = str.match(/^(\d+)-(ApiUser:|api-|AdminUser:)/)
str_match = str.match(/^(\d+)-(ApiUser:|api-|AdminUser:|RegistrantUser:)/)
user ||= User.find_by(id: str_match[1]) if str_match
user

View file

@ -7,6 +7,7 @@ class Domain < ActiveRecord::Base
include Concerns::Domain::Discardable
include Concerns::Domain::Deletable
include Concerns::Domain::Transferable
include Concerns::Domain::RegistryLockable
has_paper_trail class_name: "DomainVersion", meta: { children: :children_log }

View file

@ -1,5 +1,5 @@
class RegistrantUser < User
ACCEPTED_ISSUER = 'AS Sertifitseerimiskeskus'
ACCEPTED_ISSUER = 'AS Sertifitseerimiskeskus'.freeze
attr_accessor :idc_data
devise :database_authenticatable, :trackable, :timeoutable
@ -10,16 +10,46 @@ class RegistrantUser < User
delegate :can?, :cannot?, to: :ability
def ident
registrant_ident.to_s.split("-").last
registrant_ident.to_s.split('-').last
end
def country_code
registrant_ident.to_s.split('-').first
end
# In Rails 5, can be replaced with a much simpler `or` query method and the raw SQL parts can be
# removed.
# https://guides.rubyonrails.org/active_record_querying.html#or-conditions
def domains
ident_cc, ident = registrant_ident.to_s.split '-'
Domain.includes(:registrar, :registrant).where(contacts: {
ident_type: 'priv',
ident: ident, #identity_code,
ident_country_code: ident_cc #country_code
})
domains_where_is_contact = begin
Domain.joins(:domain_contacts)
.where(domain_contacts: { contact_id: contacts })
end
domains_where_is_registrant = Domain.where(registrant_id: contacts)
Domain.from(
"(#{domains_where_is_registrant.to_sql} UNION " \
"#{domains_where_is_contact.to_sql}) AS domains"
)
end
def contacts
Contact.where(ident_type: 'priv', ident: ident, ident_country_code: country_code)
end
def administered_domains
domains_where_is_administrative_contact = begin
Domain.joins(:domain_contacts)
.where(domain_contacts: { contact_id: contacts, type: [AdminDomainContact] })
end
domains_where_is_registrant = Domain.where(registrant_id: contacts)
Domain.from(
"(#{domains_where_is_registrant.to_sql} UNION " \
"#{domains_where_is_administrative_contact.to_sql}) AS domains"
)
end
def to_s
@ -35,13 +65,13 @@ class RegistrantUser < User
user_data = {}
# handling here new and old mode
if idc_data.starts_with?("/")
if idc_data.starts_with?('/')
user_data[:ident] = idc_data.scan(/serialNumber=(\d+)/).flatten.first
user_data[:country_code] = idc_data.scan(/^\/C=(.{2})/).flatten.first
user_data[:first_name] = idc_data.scan(%r{/GN=(.+)/serialNumber}).flatten.first
user_data[:last_name] = idc_data.scan(%r{/SN=(.+)/GN}).flatten.first
else
parse_str = "," + idc_data
parse_str = ',' + idc_data
user_data[:ident] = parse_str.scan(/,serialNumber=(\d+)/).flatten.first
user_data[:country_code] = parse_str.scan(/,C=(.{2})/).flatten.first
user_data[:first_name] = parse_str.scan(/,GN=([^,]+)/).flatten.first

View file

@ -14,6 +14,11 @@ class DomainPresenter
html += " #{label}"
end
if domain.locked_by_registrant?
label = view.content_tag(:span, 'registryLock', class: 'label label-danger')
html += " #{label}"
end
html.html_safe
end
@ -59,20 +64,30 @@ class DomainPresenter
end
end
def remove_registry_lock_btn
return unless domain.locked_by_registrant?
view.link_to(view.t('admin.domains.registry_lock.destroy.btn'),
view.admin_domain_registry_lock_path(domain),
method: :delete,
data: { confirm: view.t('admin.domains.registry_lock.destroy.confirm') },
class: 'dropdown-item')
end
def keep_btn
return unless domain.discarded?
view.link_to view.t('admin.domains.edit.keep_btn'), view.keep_admin_domain_path(@domain),
method: :patch,
data: { confirm: view.t('admin.domains.edit.keep_btn_confirm') },
class: 'btn btn-default'
class: 'dropdown-item'
end
private
def schedule_force_delete_btn
view.content_tag(:a, view.t('admin.domains.force_delete_toggle_btn.schedule'),
class: 'btn btn-default',
class: 'dropdown-item',
data: {
toggle: 'modal',
target: '.domain-edit-force-delete-dialog',
@ -86,14 +101,14 @@ class DomainPresenter
data: {
confirm: view.t('admin.domains.force_delete_toggle_btn.cancel_confirm'),
},
class: 'btn btn-primary'
class: 'dropdown-item'
end
def inactive_schedule_force_delete_btn
view.content_tag :button, view.t('admin.domains.force_delete_toggle_btn.schedule'),
title: view.t('admin.domains.force_delete_toggle_btn.unable_to_schedule'),
disabled: true,
class: 'btn btn-default'
class: 'dropdown-item'
end
attr_reader :domain

View file

@ -5,16 +5,28 @@
<li><%= link_to @domain, admin_domain_path(@domain) %></li>
</ol>
<div class="page-header">
<div class="row">
<div class="col-sm-4">
<h1><%= t '.header', domain: domain.name %></h1>
<div class="col-sm-8">
<h1 class="text-center-xs">
<%= t '.header' %> <%= domain.name_with_status %>
</h1>
</div>
<div class="col-sm-8 text-right">
<%= link_to t('.add_new_status_btn'), '#', class: 'btn btn-primary js-add-status' %>
<%= domain.keep_btn %>
<%= domain.force_delete_toggle_btn %>
<div class="col-sm-4 text-right">
<div class="btn-group">
<button class="btn btn-primary" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Actions
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><%= domain.force_delete_toggle_btn %></li>
<li><%= domain.remove_registry_lock_btn %></li>
<li><%= domain.keep_btn %></li>
<div class="divider"></div>
<li><%= link_to t('.add_new_status_btn'), '#', class: 'js-add-status' %></li>
</ul>
</div>
</div>
</div>
</div>

View file

@ -33,6 +33,9 @@
<dt><%= Domain.human_attribute_name :force_delete_at %></dt>
<dd><%= l @domain.force_delete_at %></dd>
<dt><%= t('.locked_by_registrant_at') %></dt>
<dd><%= l(@domain.locked_by_registrant_at) %></dd>
</dl>
</div>
</div>

View file

@ -13,7 +13,7 @@ en:
reset_btn: Reset
edit:
header: "Edit: %{domain}"
header: "Edit:"
add_new_status_btn: Add new status
keep_btn: Remove deleteCandidate status
keep_btn_confirm: Are you sure you want to remove deleteCandidate status?
@ -28,6 +28,13 @@ en:
close_btn: Close dialog
submit_btn: Force delete domain
registry_lock:
destroy:
btn: Remove registry lock
confirm: Are you sure you want to remove the registry lock?
success: Registry lock removed
error: Registry lock could not be removed
versions:
time: Time
registrant: Registrant
@ -38,6 +45,8 @@ en:
general:
outzone_time: Outzone time
delete_time: Delete time
force_delete_time: Force delete time
locked_by_registrant_at: Registry lock time
admin_contacts:
title: Admin. contacts

View file

@ -23,7 +23,9 @@ Rails.application.routes.draw do
namespace :registrant do
post 'auth/eid', to: 'auth#eid'
resources :domains, only: %i[index show], param: :uuid
resources :domains, only: %i[index show], param: :uuid do
resource :registry_lock, only: %i[create destroy]
end
resources :contacts, only: %i[index show], param: :uuid
end
end
@ -195,6 +197,7 @@ Rails.application.routes.draw do
resources :pending_updates
resources :pending_deletes
resource :force_delete, controller: 'domains/force_delete', only: %i[create destroy]
resource :registry_lock, controller: 'domains/registry_lock', only: :destroy
member do
patch :keep

View file

@ -0,0 +1,7 @@
class AddRegistryLockTimeColumn < ActiveRecord::Migration
def change
change_table(:domains) do |t|
t.column :locked_by_registrant_at, :datetime, null: true
end
end
end

View file

@ -0,0 +1,9 @@
class ChangeDomainPendingJsonToJsonb < ActiveRecord::Migration
def up
change_column :domains, :pending_json, 'jsonb USING CAST(pending_json AS jsonb)'
end
def down
change_column :domains, :pending_json, 'json USING CAST(pending_json AS json)'
end
end

View file

@ -904,7 +904,7 @@ CREATE TABLE public.domains (
delete_at timestamp without time zone,
registrant_verification_asked_at timestamp without time zone,
registrant_verification_token character varying,
pending_json json,
pending_json jsonb,
force_delete_at timestamp without time zone,
statuses character varying[],
reserved boolean DEFAULT false,
@ -912,7 +912,8 @@ CREATE TABLE public.domains (
statuses_before_force_delete character varying[] DEFAULT '{}'::character varying[],
upid integer,
up_date timestamp without time zone,
uuid uuid DEFAULT public.gen_random_uuid() NOT NULL
uuid uuid DEFAULT public.gen_random_uuid() NOT NULL,
locked_by_registrant_at timestamp without time zone
);
@ -4762,6 +4763,8 @@ INSERT INTO schema_migrations (version) VALUES ('20180613045614');
INSERT INTO schema_migrations (version) VALUES ('20180713154915');
INSERT INTO schema_migrations (version) VALUES ('20180808064402');
INSERT INTO schema_migrations (version) VALUES ('20180816123540');
INSERT INTO schema_migrations (version) VALUES ('20180823161237');
@ -4772,6 +4775,8 @@ INSERT INTO schema_migrations (version) VALUES ('20180823174331');
INSERT INTO schema_migrations (version) VALUES ('20180823212823');
INSERT INTO schema_migrations (version) VALUES ('20180824092855');
INSERT INTO schema_migrations (version) VALUES ('20180824102834');
INSERT INTO schema_migrations (version) VALUES ('20180825153657');

View file

@ -7,5 +7,5 @@ Main communication specification through Registrant API:
[Authentication](registrant-api/v1/authentication.md)
[Domains](registrant-api/v1/domain.md)
[Domain Lock](registrant-api/v1/domain_lock.md)
[Registry Lock](registrant-api/v1/registry_lock.md)
[Contacts](registrant-api/v1/contact.md)

View file

@ -1,4 +1,4 @@
# Domain locks
# Registry lock
## POST api/v1/registrant/domains/$UUID/registry_lock
@ -59,12 +59,12 @@ Content-Type: application/json
#### Response for failure
```
HTTP/1.1 400
HTTP/1.1 422
Content-Type: application/json
{
"errors": [
{ "base": "domain cannot be locked" }
{ "base": "Domain cannot be locked" }
]
}
@ -76,11 +76,23 @@ Content-Type: application/json
{
"errors": [
{ "base": "domain does not exist" }
{ "base": "Domain not found" }
]
}
```
```
HTTP/1.1 401
Content-Type: application/json
{
"errors": [
{ "base": ["Only administrative contacts can manage registry locks"] }
]
}
```
## DELETE api/v1/registrant/domains/$UUID/registry_lock
@ -139,12 +151,12 @@ Content-Type: application/json
#### Response for failure
```
HTTP/1.1 400
HTTP/1.1 422
Content-Type: application/json
{
"errors": [
{ "base": "domain cannot be unlocked" }
{ "base": "Domain is not locked" }
]
}
@ -156,7 +168,19 @@ Content-Type: application/json
{
"errors": [
{ "base": "domain does not exist" }
{ "base": "Domain not found" }
]
}
```
```
HTTP/1.1 401
Content-Type: application/json
{
"errors": [
{ "base": ["Only administrative contacts can manage registry locks"] }
]
}

View file

@ -299,50 +299,6 @@ RSpec.describe Domain do
@domain.registrant_update_confirmable?('123').should == false
end
end
context 'with versioning' do
it 'should not have one version' do
with_versioning do
@domain.versions.size.should == 0
@domain.name = 'new-test-name.ee'
@domain.save
@domain.errors.full_messages.should match_array([])
@domain.versions.size.should == 1
end
end
it 'should return api_creator when created by api user' do
with_versioning do
@user = create(:admin_user)
@api_user = create(:api_user)
@user.id.should == 1
@api_user.id.should == 2
::PaperTrail.whodunnit = '2-ApiUser: testuser'
@domain = create(:domain)
@domain.creator_str.should == '2-ApiUser: testuser'
@domain.creator.should == @api_user
@domain.creator.should_not == @user
end
end
it 'should return api_creator when created by api user' do
with_versioning do
@user = create(:admin_user, id: 1000)
@api_user = create(:api_user, id: 2000)
@user.id.should == 1000
@api_user.id.should == 2000
::PaperTrail.whodunnit = '1000-AdminUser: testuser'
@domain = create(:domain)
@domain.creator_str.should == '1000-AdminUser: testuser'
@domain.creator.should == @user
@domain.creator.should_not == @api_user
end
end
end
end
it 'validates domain name' do

View file

@ -15,7 +15,7 @@ william: &william
email: william@inbox.test
phone: '+555.555'
fax: '+666.6'
ident: 1234
ident: 12345
ident_type: priv
ident_country_code: US
registrar: bestnames
@ -34,7 +34,7 @@ jane:
name: Jane
email: jane@mail.test
phone: '+555.555'
ident: 1234
ident: 123456
ident_type: priv
ident_country_code: US
registrar: bestnames
@ -46,7 +46,7 @@ acme_ltd:
name: Acme Ltd
email: acme@outlook.test
phone: '+555.555'
ident: 1234
ident: 1234567
ident_type: org
registrar: bestnames
ident_country_code: US
@ -58,7 +58,7 @@ jack:
name: Jack
email: jack@inbox.test
phone: '+555.555'
ident: 1234
ident: 12345678
ident_type: org
registrar: goodnames
ident_country_code: US

View file

@ -28,11 +28,36 @@ airport_william_tech:
contact: william
type: TechDomainContact
library_john:
library_acme_admin:
domain: library
contact: acme_ltd
type: AdminDomainContact
library_john_tech:
domain: library
contact: john
type: TechDomainContact
metro_jack_admin:
domain: metro
contact: jack
type: AdminDomainContact
metro_jack_tech:
domain: metro
contact: jack
type: TechDomainContact
hospital_john_admin:
domain: hospital
contact: john
type: AdminDomainContact
hospital_john_tech:
domain: hospital
contact: john
type: TechDomainContact
invalid_invalid_admin:
domain: invalid
contact: invalid

View file

@ -25,7 +25,7 @@ class RegistrantApiContactsTest < ApplicationIntegrationTest
assert_equal(200, response.status)
json_body = JSON.parse(response.body, symbolize_names: true)
assert_equal(5, json_body.count)
assert_equal(4, json_body.count)
array_of_contact_codes = json_body.map { |x| x[:code] }
assert(array_of_contact_codes.include?('william-001'))
assert(array_of_contact_codes.include?('jane-001'))
@ -39,7 +39,7 @@ class RegistrantApiContactsTest < ApplicationIntegrationTest
get '/api/v1/registrant/contacts', {}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert_equal(5, response_json.count)
assert_equal(4, response_json.count)
end
def test_get_contact_details_by_uuid

View file

@ -57,7 +57,7 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest
get '/api/v1/registrant/domains', {}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert_equal(5, response_json.count)
assert_equal(4, response_json.count)
end
def test_root_does_not_accept_limit_higher_than_200

View file

@ -0,0 +1,131 @@
require 'test_helper'
require 'auth_token/auth_token_creator'
class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest
def setup
super
@original_registry_time = Setting.days_to_keep_business_registry_cache
Setting.days_to_keep_business_registry_cache = 1
travel_to Time.zone.parse('2010-07-05')
@user = users(:registrant)
@domain = domains(:airport)
@auth_headers = { 'HTTP_AUTHORIZATION' => auth_token }
end
def teardown
super
Setting.days_to_keep_business_registry_cache = @original_registry_time
travel_back
end
def test_can_lock_a_not_locked_domain
post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock',
{}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert(response_json[:statuses].include?(DomainStatus::SERVER_DELETE_PROHIBITED))
assert(response_json[:statuses].include?(DomainStatus::SERVER_TRANSFER_PROHIBITED))
assert(response_json[:statuses].include?(DomainStatus::SERVER_UPDATE_PROHIBITED))
@domain.reload
assert(@domain.locked_by_registrant?)
end
def test_locking_a_domain_creates_a_version_record
assert_difference '@domain.versions.count', 1 do
post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock',
{}, @auth_headers
end
@domain.reload
assert_equal(@domain.updator, @user)
end
def test_cannot_lock_a_domain_in_pending_state
@domain.statuses << DomainStatus::PENDING_UPDATE
@domain.save
post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock',
{}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert_equal(422, response.status)
assert_equal({ errors: [{ base: ['Domain cannot be locked'] }] }, response_json)
end
def test_cannot_lock_an_already_locked_domain
@domain.apply_registry_lock
assert(@domain.locked_by_registrant?)
post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock',
{}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert_equal(422, response.status)
assert_equal({ errors: [{ base: ['Domain cannot be locked'] }] }, response_json)
end
def test_can_unlock_a_locked_domain
@domain.apply_registry_lock
delete '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock',
{}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert(response_json[:statuses].include?(DomainStatus::OK))
@domain.reload
refute(@domain.locked_by_registrant?)
end
def test_cannot_unlock_a_not_locked_domain
delete '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock',
{}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert_equal(422, response.status)
assert_equal({ errors: [{ base: ['Domain is not locked'] }] }, response_json)
end
def test_returns_404_when_domain_is_not_found
post '/api/v1/registrant/domains/random-uuid/registry_lock',
{}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert_equal(404, response.status)
assert_equal({ errors: [{ base: ['Domain not found'] }] }, response_json)
end
def test_technical_contact_cannot_lock_a_domain
post '/api/v1/registrant/domains/647bcc48-8d5e-4a04-8ce5-2a3cd17b6eab/registry_lock',
{}, @auth_headers
response_json = JSON.parse(response.body, symbolize_names: true)
assert_equal(401, response.status)
assert_equal({ errors: [{ base: ['Only administrative contacts can manage registry locks'] }] },
response_json)
end
def test_registrant_can_lock_a_domain
post '/api/v1/registrant/domains/1b3ee442-e8fe-4922-9492-8fcb9dccc69c/registry_lock',
{}, @auth_headers
assert_equal(200, response.status)
response_json = JSON.parse(response.body, symbolize_names: true)
assert(response_json[:statuses].include?(DomainStatus::SERVER_DELETE_PROHIBITED))
assert(response_json[:statuses].include?(DomainStatus::SERVER_TRANSFER_PROHIBITED))
assert(response_json[:statuses].include?(DomainStatus::SERVER_UPDATE_PROHIBITED))
end
private
def auth_token
token_creator = AuthTokenCreator.create_with_defaults(@user)
hash = token_creator.token_in_hash
"Bearer #{hash[:access_token]}"
end
end

View file

@ -0,0 +1,52 @@
require 'test_helper'
class DomainVersionTest < ActiveSupport::TestCase
def setup
super
@domain = domains(:shop)
@contacts = @domain.contacts
@user = users(:registrant)
end
def teardown
super
end
def test_assigns_creator_to_paper_trail_whodunnit
duplicate_domain = prepare_duplicate_domain
PaperTrail.whodunnit = @user.id_role_username
assert_difference 'duplicate_domain.versions.count', 1 do
duplicate_domain.save!
end
assert_equal(duplicate_domain.creator, @user)
assert_equal(duplicate_domain.updator, @user)
assert_equal(duplicate_domain.creator_str, @user.id_role_username)
assert_equal(duplicate_domain.updator_str, @user.id_role_username)
end
def test_assigns_updator_to_paper_trail_whodunnit
PaperTrail.whodunnit = @user.id_role_username
assert_difference '@domain.versions.count', 1 do
@domain.apply_registry_lock
end
assert_equal(@domain.updator, @user)
assert_equal(@domain.updator_str, @user.id_role_username)
end
private
def prepare_duplicate_domain
duplicate_domain = @domain.dup
duplicate_domain.tech_contacts << @contacts
duplicate_domain.admin_contacts << @contacts
duplicate_domain.name = 'duplicate.test'
duplicate_domain.uuid = nil
duplicate_domain
end
end

View file

@ -0,0 +1,72 @@
require 'test_helper'
class DomainRegistryLockableTest < ActiveSupport::TestCase
def setup
super
@domain = domains(:airport)
end
def test_registry_lock_on_lockable_domain
refute(@domain.locked_by_registrant?)
@domain.apply_registry_lock
assert_equal(
[DomainStatus::SERVER_UPDATE_PROHIBITED,
DomainStatus::SERVER_DELETE_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED],
@domain.statuses
)
assert(@domain.locked_by_registrant?)
assert(@domain.locked_by_registrant_at)
end
def test_registry_lock_cannot_be_applied_twice
@domain.apply_registry_lock
refute(@domain.apply_registry_lock)
assert(@domain.locked_by_registrant?)
assert(@domain.locked_by_registrant_at)
end
def test_registry_lock_cannot_be_applied_on_pending_statuses
@domain.statuses << DomainStatus::PENDING_RENEW
refute(@domain.apply_registry_lock)
refute(@domain.locked_by_registrant?)
refute(@domain.locked_by_registrant_at)
end
def test_remove_registry_lock_on_locked_domain
@domain.apply_registry_lock
assert_equal(
[DomainStatus::SERVER_UPDATE_PROHIBITED,
DomainStatus::SERVER_DELETE_PROHIBITED,
DomainStatus::SERVER_TRANSFER_PROHIBITED],
@domain.statuses
)
@domain.remove_registry_lock
assert_equal(["ok"], @domain.statuses)
refute(@domain.locked_by_registrant?)
refute(@domain.locked_by_registrant_at)
end
def test_remove_registry_lock_on_non_locked_domain
refute(@domain.locked_by_registrant?)
refute(@domain.remove_registry_lock)
assert_equal([], @domain.statuses)
refute(@domain.locked_by_registrant?)
refute(@domain.locked_by_registrant_at)
end
def test_registry_lock_cannot_be_removed_if_statuses_were_set_by_admin
@domain.statuses << DomainStatus::SERVER_UPDATE_PROHIBITED
@domain.statuses << DomainStatus::SERVER_DELETE_PROHIBITED
@domain.statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED
refute(@domain.remove_registry_lock)
end
end

View file

@ -0,0 +1,56 @@
require 'test_helper'
class RegistrantUserCreationTest < ActiveSupport::TestCase
def test_find_or_create_by_api_data_creates_a_user
user_data = {
ident: '37710100070',
first_name: 'JOHN',
last_name: 'SMITH'
}
RegistrantUser.find_or_create_by_api_data(user_data)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
end
def test_find_or_create_by_api_data_creates_a_user_after_upcasing_input
user_data = {
ident: '37710100070',
first_name: 'John',
last_name: 'Smith'
}
RegistrantUser.find_or_create_by_api_data(user_data)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
end
def test_find_or_create_by_mid_data_creates_a_user
user_data = OpenStruct.new(user_country: 'EE', user_id_code: '37710100070',
user_givenname: 'JOHN', user_surname: 'SMITH')
RegistrantUser.find_or_create_by_mid_data(user_data)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
end
def test_find_or_create_by_idc_with_legacy_header_creates_a_user
header = '/C=EE/O=ESTEID/OU=authentication/CN=SMITH,JOHN,37710100070/SN=SMITH/GN=JOHN/serialNumber=37710100070'
RegistrantUser.find_or_create_by_idc_data(header, RegistrantUser::ACCEPTED_ISSUER)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
end
def test_find_or_create_by_idc_with_rfc2253_header_creates_a_user
header = 'serialNumber=37710100070,GN=JOHN,SN=SMITH,CN=SMITH\\,JOHN\\,37710100070,OU=authentication,O=ESTEID,C=EE'
RegistrantUser.find_or_create_by_idc_data(header, RegistrantUser::ACCEPTED_ISSUER)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
end
end

View file

@ -1,62 +1,38 @@
require 'test_helper'
class RegistrantUserTest < ActiveSupport::TestCase
def setup
super
@user = users(:registrant)
end
def teardown
super
end
def test_find_or_create_by_api_data_creates_a_user
user_data = {
ident: '37710100070',
first_name: 'JOHN',
last_name: 'SMITH'
}
def test_domains_returns_an_list_of_distinct_domains_associated_with_a_specific_id_code
domain_names = @user.domains.pluck(:name)
assert_equal(4, domain_names.length)
RegistrantUser.find_or_create_by_api_data(user_data)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
# User is a registrant, but not a contact for the domain. Should be included in the list.
assert(domain_names.include?('shop.test'))
end
def test_find_or_create_by_api_data_creates_a_user_after_upcasing_input
user_data = {
ident: '37710100070',
first_name: 'John',
last_name: 'Smith'
}
def test_administered_domains_returns_a_list_of_domains
domain_names = @user.administered_domains.pluck(:name)
assert_equal(3, domain_names.length)
RegistrantUser.find_or_create_by_api_data(user_data)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
# User is a tech contact for the domain.
refute(domain_names.include?('library.test'))
end
def test_find_or_create_by_mid_data_creates_a_user
user_data = OpenStruct.new(user_country: 'EE', user_id_code: '37710100070',
user_givenname: 'JOHN', user_surname: 'SMITH')
RegistrantUser.find_or_create_by_mid_data(user_data)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
def test_contacts_returns_an_list_of_contacts_associated_with_a_specific_id_code
assert_equal(1, @user.contacts.count)
end
def test_find_or_create_by_idc_with_legacy_header_creates_a_user
header = '/C=EE/O=ESTEID/OU=authentication/CN=SMITH,JOHN,37710100070/SN=SMITH/GN=JOHN/serialNumber=37710100070'
RegistrantUser.find_or_create_by_idc_data(header, RegistrantUser::ACCEPTED_ISSUER)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
end
def test_find_or_create_by_idc_with_rfc2253_header_creates_a_user
header = 'serialNumber=37710100070,GN=JOHN,SN=SMITH,CN=SMITH\\,JOHN\\,37710100070,OU=authentication,O=ESTEID,C=EE'
RegistrantUser.find_or_create_by_idc_data(header, RegistrantUser::ACCEPTED_ISSUER)
user = User.find_by(registrant_ident: 'EE-37710100070')
assert_equal('JOHN SMITH', user.username)
def test_ident_and_country_code_helper_methods
assert_equal('1234', @user.ident)
assert_equal('US', @user.country_code)
end
end

View file

@ -0,0 +1,57 @@
require 'test_helper'
class AdminAreaRegistryLockTest < JavaScriptApplicationSystemTestCase
def setup
super
WebMock.allow_net_connect!
sign_in users(:admin)
travel_to Time.zone.parse('2010-07-05 00:30:00')
@domain = domains(:airport)
end
def teardown
travel_back
end
def test_does_not_have_link_when_domain_is_not_locked
visit edit_admin_domain_path(@domain)
click_link_or_button('Actions')
refute(page.has_link?('Remove registry lock'))
end
def test_can_remove_registry_lock_from_a_domain
@domain.apply_registry_lock
visit edit_admin_domain_path(@domain)
click_link_or_button('Actions')
assert(page.has_link?('Remove registry lock'))
accept_confirm('Are you sure you want to remove the registry lock?') do
click_link_or_button('Remove registry lock')
end
assert_text('Registry lock removed')
@domain.reload
refute @domain.locked_by_registrant?
end
def test_cannot_remove_registry_lock_from_not_locked_domain
@domain.apply_registry_lock
visit edit_admin_domain_path(@domain)
@domain.remove_registry_lock
refute @domain.locked_by_registrant?
click_link_or_button('Actions')
assert(page.has_link?('Remove registry lock'))
accept_confirm('Are you sure you want to remove the registry lock?') do
click_link_or_button('Remove registry lock')
end
assert_text('Registry lock could not be removed')
refute @domain.locked_by_registrant?
end
end

View file

@ -3,6 +3,7 @@ require 'test_helper'
class AdminDomainsTestTest < ApplicationSystemTestCase
setup do
sign_in users(:admin)
travel_to Time.zone.parse('2010-07-05 00:30:00')
@domain = domains(:shop)
end
@ -15,8 +16,19 @@ class AdminDomainsTestTest < ApplicationSystemTestCase
assert_field nil, with: @domain.transfer_code
end
def test_admin_registry_lock_date
visit admin_domain_path(@domain)
refute_text 'Registry lock time 2010-07-05 00:30'
lockable_domain = domains(:airport)
lockable_domain.apply_registry_lock
visit admin_domain_path(lockable_domain)
assert_text 'Registry lock time 2010-07-05 00:30'
assert_text 'registryLock'
end
def test_keep_a_domain
travel_to Time.zone.parse('2010-07-05 10:30')
@domain.delete_at = Time.zone.parse('2010-07-05 10:00')
@domain.discard