Skip to content

Commit

Permalink
Merge branch 'master' into improve-epp-poll-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Artur Beljajev committed Sep 17, 2018
2 parents 7ba826b + 4bf24d8 commit 6e64d05
Show file tree
Hide file tree
Showing 37 changed files with 763 additions and 152 deletions.
1 change: 1 addition & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ exclude_patterns:
- "vendor/"
- "test/"
- "spec/"
- "CHANGELOG.md"
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
12.09.2018
* Bug: user with billing access only can now login to the portal for Regsitrars [#973](https://github.com/internetee/registry/issues/973)

06.09.2018
* Bug: registrant confirmation does not require authentication any more [#969](https://github.com/internetee/registry/issues/969)
* Whois JSON tests order independent [#965](https://github.com/internetee/registry/issues/965)

04.09.2018
* New registrant portal API [#902](https://github.com/internetee/registry/issues/902)
* Registry lock in Registrant API [#927](https://github.com/internetee/registry/issues/927)
* Password encryption for EPP [#914](https://github.com/internetee/registry/issues/914)
* Registrar: 0 amount invoices invalidated [#651](https://github.com/internetee/registry/issues/651)
* Ruby upgrade to 2.4 [#938](https://github.com/internetee/registry/issues/938)
* Admin: removig deleteCandidate status removes Que job as well [#790](https://github.com/internetee/registry/issues/790)
* Admin: Cancel force delete no possible with deleteCandidate status set [#791](https://github.com/internetee/registry/issues/791)
* Contact tests added [#930](https://github.com/internetee/registry/issues/930)
* Change test structure [#924](https://github.com/internetee/registry/issues/924)
* Grape gem update to 1.1.0 (CVE-2018-3769) [#934](https://github.com/internetee/registry/pull/934)
* Remove changelog from codeclimate analysis [#961](https://github.com/internetee/registry/issues/961)
* Remove dead code [#925](https://github.com/internetee/registry/issues/925)
* Quote value in fixture [#937](https://github.com/internetee/registry/issues/937)
* Generate <body> CSS class for every action [#939](https://github.com/internetee/registry/issues/939)
* Add TaskTestCase [#941](https://github.com/internetee/registry/issues/941)
* Set NOT NULL constraint for contact.email field [#936](https://github.com/internetee/registry/issues/936)
* Remove duplicate fixture [#946](https://github.com/internetee/registry/issues/946)

26.07.2018
* Grape (1.0.3), mustermann (1.0.2), multi_json (1.13.1) gem updates [#912](https://github.com/internetee/registry/issues/912)
* Capybara (3.3.1), mini_mime (0.1.3), nokogiri (1.8), rack (1.6.0), xpath (3.1) gem updates [#980](https://github.com/internetee/registry/issues/908)
Expand Down
21 changes: 21 additions & 0 deletions app/controllers/admin/domains/registry_lock_controller.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion app/controllers/admin/mail_templates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def update
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'
Expand Down
21 changes: 19 additions & 2 deletions app/controllers/api/v1/registrant/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module V1
module Registrant
class BaseController < ActionController::API
before_action :authenticate
before_action :set_paper_trail_whodunnit

rescue_from(ActionController::ParameterMissing) do |parameter_missing_exception|
error = {}
Expand All @@ -22,16 +23,32 @@ def bearer_token
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
Expand Down
11 changes: 0 additions & 11 deletions app/controllers/api/v1/registrant/domains_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,6 @@ def show
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
Expand Down
48 changes: 48 additions & 0 deletions app/controllers/api/v1/registrant/registry_locks_controller.rb
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Registrant::DomainDeleteConfirmsController < RegistrantController
skip_before_action :authenticate_user!, only: [:show, :update]
skip_before_action :authenticate_registrant_user!, only: [:show, :update]
skip_authorization_check only: [:show, :update]

def show
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Registrant::DomainUpdateConfirmsController < RegistrantController
skip_before_action :authenticate_user!, only: %i[show update]
skip_before_action :authenticate_registrant_user!, only: %i[show update]
skip_authorization_check only: %i[show update]

def show
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/registrar/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def mid_status
sign_in(:registrar_user, @user)
flash[:notice] = t(:welcome)
flash.keep(:notice)
render js: "window.location = '#{registrar_root_url}'"
render js: "window.location = '#{after_sign_in_path_for(@user)}'"
when 'NOT_VALID'
render json: { message: t(:user_signature_is_invalid) }, status: :bad_request
when 'EXPIRED_TRANSACTION'
Expand Down
51 changes: 51 additions & 0 deletions app/models/concerns/domain/registry_lockable.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion app/models/concerns/versions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def user_from_id_role_username(str)
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
Expand Down
1 change: 1 addition & 0 deletions app/models/domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down
50 changes: 40 additions & 10 deletions app/models/registrant_user.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -10,16 +10,46 @@ def ability
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
Expand All @@ -35,13 +65,13 @@ def find_or_create_by_idc_data(idc_data, issuer_organization)
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
Expand Down
Loading

0 comments on commit 6e64d05

Please sign in to comment.