Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2611 bsa gateway integration #2621

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ RUN mkdir -p /opt/webapps/app/tmp/pids
WORKDIR /opt/webapps/app
COPY Gemfile Gemfile.lock ./
# ADD vendor/gems/omniauth-tara ./vendor/gems/omniauth-tara

ENV LANG et_EE.UTF-8
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc -s | apt-key add -
RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
RUN apt-get update > /dev/null && apt-get install -y --no-install-recommends > /dev/null \
postgresql-client-13=* \
libpq-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN gem install bundler && bundle install --jobs 20 --retry 5

EXPOSE 3000
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ group :test do
gem 'database_cleaner'
gem 'minitest', '~> 5.17'
gem 'minitest-stub_any_instance'
gem 'mock_redis'
gem 'selenium-webdriver'
gem 'simplecov', '0.17.1', require: false # CC last supported v0.17
gem 'spy'
Expand Down
4 changes: 3 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ GEM
mini_portile2 (2.8.2)
minitest (5.18.1)
minitest-stub_any_instance (1.0.3)
mock_redis (0.37.0)
monetize (1.9.4)
money (~> 6.12)
money (6.13.8)
Expand Down Expand Up @@ -569,6 +570,7 @@ DEPENDENCIES
mimemagic (= 0.4.3)
minitest (~> 5.17)
minitest-stub_any_instance
mock_redis
money-rails
newrelic-infinite_tracing
newrelic_rpm
Expand Down Expand Up @@ -604,4 +606,4 @@ DEPENDENCIES
wkhtmltopdf-binary (~> 0.12.6.1)

BUNDLED WITH
2.4.19
2.4.20
80 changes: 80 additions & 0 deletions app/controllers/admin/bsa_protected_domains_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
module Admin
class BsaProtectedDomainsController < BaseController
load_and_authorize_resource
before_action :set_domain, only: %i[edit update]

def index
params[:q] ||= {}
domains = BsaProtectedDomain.all.order(:domain_name)
@q = domains.ransack(PartialSearchFormatter.format(params[:q]))
@result = @q.result
@domains = @result.page(params[:page])
@domains = @domains.per(params[:results_per_page]) if params[:results_per_page].to_i.positive?
end

def new
@domain = BsaProtectedDomain.new
end

def edit; end

def create
@domain = BsaProtectedDomain.new(bsa_protected_domain_params)

if @domain.save
flash[:notice] = I18n.t('domain_added')
redirect_to admin_bsa_protected_domains_path
else
flash.now[:alert] = I18n.t('failed_to_add_domain')
render 'new'
end
end

def update
if @domain.update(bsa_protected_domain_params)
flash[:notice] = I18n.t('domain_updated')
else
flash.now[:alert] = I18n.t('failed_to_update_domain')
end

render 'edit'
end

def delete
if BsaProtectedDomain.find(params[:id]).destroy
flash[:notice] = I18n.t('domain_deleted')
else
flash.now[:alert] = I18n.t('failed_to_delete_domain')
end

redirect_to admin_bsa_protected_domains_path
end

def release_to_auction
redirect_to admin_bsa_protected_domains_path and return if params[:bsa_protected_domains].nil?

bsa_protected_domains_ids = params[:bsa_protected_domains][:domain_ids]
bsa_protected_domains_domains = BsaProtectedDomain.where(id: bsa_protected_domains_ids)

bsa_protected_domains_domains.each do |domain|
Auction.create!(domain: domain.name, status: Auction.statuses[:started], platform: 'manual')
domain.destroy!
end

redirect_to admin_auctions_path
end

private

def bsa_protected_domain_params
params.require(:bsa_protected_domain).permit(:domain_name, :registration_code,
:order_id, :suborder_id, :create_date, :state).tap do |whitelisted|
whitelisted[:state] = whitelisted[:state].to_i if whitelisted[:state].is_a?(String)
end
end

def set_domain
@domain = BsaProtectedDomain.find(params[:id])
end
end
end
4 changes: 0 additions & 4 deletions app/controllers/admin/reserved_domains_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ def release_to_auction

private

def reserved_checked_elements
# params.require(:reserved_elements).permit(:name, :password)
end

def reserved_domain_params
params.require(:reserved_domain).permit(:name, :password)
end
Expand Down
1 change: 1 addition & 0 deletions app/interactions/whois/delete_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def delete_domain(name)
BlockedDomain.find_by(name: name).try(:generate_data)
ReservedDomain.find_by(name: name).try(:generate_data)
Dispute.active.find_by(domain_name: name).try(:generate_data)
BsaProtectedDomain.active.find_by(domain_name: name).try(:generate_data)
end

def delete_reserved(name)
Expand Down
1 change: 1 addition & 0 deletions app/interactions/whois/update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def execute
def determine_collection
case type
when 'reserved' then ReservedDomain
when 'bsa_protected' then BsaProtectedDomain
when 'blocked' then BlockedDomain
when 'domain' then Domain
when 'disputed' then Dispute
Expand Down
48 changes: 48 additions & 0 deletions app/jobs/fetch_godaddy_bsa_block_order_list_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

# rubocop:disable Metrics

class FetchGodaddyBsaBlockOrderListJob < ApplicationJob
queue_as :default

LIMIT = 20
LIMIT_MESSAGE = 'Limit reached. No more block orders to fetch'
QUEUED_FOR_ACTIVATION = 'QueuedForActivation'

def perform(status_name = QUEUED_FOR_ACTIVATION)
fetch_block_order_list(offset: 0, status_name: status_name)
end

def fetch_block_order_list(offset:, status_name:)
res = Bsa::BlockOrderListService.call(offset: offset, limit: LIMIT,
q: { 'blockOrderStatus.name' => status_name })
return { message: res.error.message, description: res.error.description } unless res.result?
return LIMIT_MESSAGE if res.body.total.zero? || res.body.list.blank?

bsa_attributes = collect_bsa_values(res)
BsaProtectedDomain.upsert_all(bsa_attributes, unique_by: :suborder_id)

offset_limit = res.body.total / LIMIT
return LIMIT_MESSAGE if offset >= offset_limit

offset += 1
fetch_block_order_list(offset: offset, status_name: status_name)
end

def collect_bsa_values(res)
res.body.list.map do |block_order|
{
order_id: block_order['blockOrder']['blockOrderId'],
suborder_id: block_order['blockSubOrderId'],
domain_name: "#{block_order['label']}#{block_order['tld']['displayName']}",
state: block_order['blockOrderStatus']['blockOrderStatusId'],
registration_code: SecureRandom.hex,
create_date: DateTime.parse(block_order['createdDt']),
created_at: Time.zone.now,
updated_at: Time.zone.now,
}
end
end
end

# rubocop:enable Metrics
36 changes: 36 additions & 0 deletions app/jobs/update_godaddy_domains_status_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

class UpdateGodaddyDomainsStatusJob < ApplicationJob
queue_as :default

def perform(query_state, updated_state)
BsaProtectedDomain.where(state: query_state).in_batches(of: 30) do |bsa_protected_domains|
process(suborders_block: bsa_protected_domains, state: updated_state)
end
end

private

def process(suborders_block:, state:)
payload = serialize_suborders_block(suborders_block: suborders_block, state: state)

result = Bsa::BlockOrderStatusSettingService.call(payload: payload)
return { message: result.error.message, description: result.error.description } unless result.result?

refresh_statuses(suborders_block: suborders_block, state: state)

result.body
end

def serialize_suborders_block(suborders_block:, state:)
suborders_block.map do |suborder_block|
{ blockSubOrderId: suborder_block.suborder_id, status: BsaProtectedDomain.states.key(state) }
end
end

# rubocop:disable Rails::SkipsModelValidations
def refresh_statuses(suborders_block:, state:)
suborders_block.update_all(state: state)
end
# rubocop:enable Rails::SkipsModelValidations
end
1 change: 1 addition & 0 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def admin # Admin/admin_user dynamic role
can :manage, Setting
can :manage, BlockedDomain
can :manage, ReservedDomain
can :manage, BsaProtectedDomain
can :manage, DNS::Zone
can :manage, Version::DomainVersion
can :manage, Version::ContactVersion
Expand Down
55 changes: 55 additions & 0 deletions app/models/bsa_protected_domain.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

class BsaProtectedDomain < ApplicationRecord
include BsaProtectedDomain::Ransackable

NEW = 'New'
QUEUED_FOR_ACTIVATION = 'QueuedForActivation'
ACTIVATION_IN_PROGRESS = 'ActivationInProgress'
ACTIVE = 'Active'
QUEUED_FOR_RELEASE = 'QueuedForRelease'
RELEASE_IN_PROGRESS = 'ReleaseInProgress'
CLOSED = 'Closed'

enum state: {
NEW => 1,
QUEUED_FOR_ACTIVATION => 2,
ACTIVATION_IN_PROGRESS => 3,
ACTIVE => 4,
QUEUED_FOR_RELEASE => 5,
RELEASE_IN_PROGRESS => 6,
CLOSED => 7,
}

class << self
def pw_for(domain_name)
name_in_ascii = SimpleIDN.to_ascii(domain_name)
by_domain(domain_name).first.try(:registration_code) || by_domain(name_in_ascii).first.try(:registration_code)
end

def by_domain(name)
where(domain_name: name)
end

def new_password_for(name)
record = by_domain(name).first
return unless record

record.regenerate_password
record.save
end
end

def generate_data
return if Domain.where(name: name).any?

wr = Whois::Record.find_or_initialize_by(name: name)
wr.json = @json = generate_json(wr, domain_status: 'Reserved') # we need @json to bind to class
wr.save
end
alias_method :update_whois_record, :generate_data

def regenerate_password
self.registration_code = SecureRandom.hex
end
end
13 changes: 13 additions & 0 deletions app/models/bsa_protected_domain/ransackable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module BsaProtectedDomain::Ransackable
extend ActiveSupport::Concern

class_methods do
def ransackable_associations(*)
authorizable_ransackable_associations
end

def ransackable_attributes(*)
authorizable_ransackable_attributes
end
end
end
6 changes: 5 additions & 1 deletion app/models/dns/domain_name.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ def reserved?
ReservedDomain.where(name: name).any?
end

def bsa_protected?
BsaProtectedDomain.where(domain_name: name).any?
end

def disputed?
Dispute.active.where(domain_name: name).any?
end
Expand All @@ -87,7 +91,7 @@ def to_s
attr_reader :name

def not_auctionable?
blocked? || reserved? || disputed? || pending_auction.present?
blocked? || reserved? || disputed? || pending_auction.present? || bsa_protected?
end

def zone_with_same_origin?
Expand Down
18 changes: 18 additions & 0 deletions app/models/domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def update_reserved_domains
validates :period, presence: true, numericality: { only_integer: true }
validates :transfer_code, presence: true
validate :validate_reservation
validate :validate_bsa_protection

def validate_reservation
return if persisted? || !in_reserved_list?
Expand All @@ -133,6 +134,19 @@ def validate_reservation
errors.add(:base, :invalid_auth_information_reserved)
end

def validate_bsa_protection
return if persisted? || !in_bsa_protected_list?

if reserved_pw.blank?
errors.add(:base, :required_parameter_missing_reserved)
return false
end

return if BsaProtectedDomain.pw_for(name) == reserved_pw

errors.add(:base, :invalid_auth_information_reserved)
end

validate :status_is_consistant
def status_is_consistant
has_error = (hold_status? && statuses.include?(DomainStatus::SERVER_MANUAL_INZONE))
Expand Down Expand Up @@ -371,6 +385,10 @@ def in_reserved_list?
@in_reserved_list ||= ReservedDomain.by_domain(name).any?
end

def in_bsa_protected_list?
@in_bsa_protected_list ||= BsaProtectedDomain.by_domain(name).any?
end

def pending_transfer
transfers.find_by(status: DomainTransfer::PENDING)
end
Expand Down
Loading