mirror of
https://github.com/internetee/registry.git
synced 2025-07-29 22:16:19 +02:00
Merge branch 'master' into monthly-invoices-fix
This commit is contained in:
commit
3ae24f2f68
282 changed files with 2625 additions and 6669 deletions
4
.github/workflows/ruby.yml
vendored
4
.github/workflows/ruby.yml
vendored
|
@ -79,7 +79,7 @@ jobs:
|
|||
- name: Save coverage
|
||||
run: ./cc-test-reporter format-coverage --output coverage/codeclimate.${{ matrix.ruby }}.json
|
||||
|
||||
- uses: actions/upload-artifact@v3.1.0
|
||||
- uses: actions/upload-artifact@v3.1.1
|
||||
with:
|
||||
name: coverage-${{ matrix.ruby }}
|
||||
path: coverage/codeclimate.${{ matrix.ruby }}.json
|
||||
|
@ -104,7 +104,7 @@ jobs:
|
|||
- name: Give test coverage reporter executable permissions
|
||||
run: chmod +x cc-test-reporter
|
||||
|
||||
- uses: actions/download-artifact@v3.0.0
|
||||
- uses: actions/download-artifact@v3.0.1
|
||||
with:
|
||||
name: coverage-${{ matrix.ruby }}
|
||||
path: coverage
|
||||
|
|
83
CHANGELOG.md
83
CHANGELOG.md
|
@ -1,3 +1,86 @@
|
|||
01.12.2022
|
||||
* Fixed empty validation result reason in the logs https://github.com/internetee/registry/issues/2490
|
||||
* Reduced unnecessary logging from email validation logs https://github.com/internetee/registry/issues/2491
|
||||
|
||||
30.11.2022
|
||||
* Validator for incoming disclosed attributes https://github.com/internetee/registry/issues/2486
|
||||
* Endpoint for registrar xml console feature https://github.com/internetee/registry/pull/2483
|
||||
|
||||
29.11.2022
|
||||
* Fixed pantom statuse issue in REPP https://github.com/internetee/registry/issues/2470
|
||||
|
||||
24.11.2022
|
||||
* Overwrite feature to SendMonthlyInvoicesJob https://github.com/internetee/registry/pull/2485
|
||||
|
||||
23.11.2022
|
||||
* outzone rake task for invalid email domains by @OlegPhenomenon in https://github.com/internetee/registry/pull/2437
|
||||
* Update dependency paper_trail to v13 by @renovate in https://github.com/internetee/registry/pull/2419
|
||||
* Bump omniauth from 1.9.1 to 1.9.2 by @dependabot in https://github.com/internetee/registry/pull/2429
|
||||
* Update dependency pdfkit to v0.8.7.2 [SECURITY] by @renovate in https://github.com/internetee/registry/pull/2472
|
||||
* Bump google-protobuf from 3.19.4 to 3.21.9 by @dependabot in https://github.com/internetee/registry/pull/2477
|
||||
* Fix domain contacts repp by @maricavor in https://github.com/internetee/registry/pull/2475
|
||||
* Update dependency pg to v1.4.5 by @renovate in https://github.com/internetee/registry/pull/2481
|
||||
* Fixed dates for yearly domains in monthly invoices by @maricavor in https://github.com/internetee/registry/pull/2482
|
||||
|
||||
02.11.2022
|
||||
* outzone rake task for invalid email domains by @OlegPhenomenon in https://github.com/internetee/registry/pull/2437
|
||||
|
||||
28.10.2022
|
||||
* Add request throttling by @yulgolem in https://github.com/internetee/registry/pull/2028
|
||||
|
||||
26.10.2022
|
||||
* Update actions/download-artifact action to v3.0.1 by @renovate in https://github.com/internetee/registry/pull/2464
|
||||
* Update actions/upload-artifact action to v3.1.1 by @renovate in https://github.com/internetee/registry/pull/2465
|
||||
* assign the limit of validation records by @OlegPhenomenon in https://github.com/internetee/registry/pull/2466
|
||||
|
||||
20.10.2022
|
||||
* added exception for auctions with no-bids and registred-domains statuses by @OlegPhenomenon in https://github.com/internetee/registry/pull/2403
|
||||
* assign auction type for nil value rake task by @OlegPhenomenon in https://github.com/internetee/registry/pull/2404
|
||||
|
||||
17.10.2022
|
||||
* Remove registrar portal by @thiagoyoussef in https://github.com/internetee/registry/pull/2434
|
||||
* Update dependency pg to v1.4.4 by @renovate in https://github.com/internetee/registry/pull/2459
|
||||
* fix check force delete lift poll messages by @thiagoyoussef in https://github.com/internetee/registry/pull/2461
|
||||
|
||||
12.10.2022
|
||||
* Created regex only email validation domain list by @maricavor in https://github.com/internetee/registry/pull/2401
|
||||
* Fix check force delete lift bug by @thiagoyoussef in https://github.com/internetee/registry/pull/2418
|
||||
* Refactored monthly invoice generation job by @maricavor in https://github.com/internetee/registry/pull/2456
|
||||
|
||||
07.10.2022
|
||||
* Enable trimming for dnskey and email values by @thiagoyoussef in https://github.com/internetee/registry/pull/2453
|
||||
|
||||
06.10.2022
|
||||
* Update dependency pdfkit to v0.8.7 [SECURITY] by @renovate in https://github.com/internetee/registry/pull/2452
|
||||
* Admin: option to delete auction record by @thiagoyoussef in https://github.com/internetee/registry/pull/2449
|
||||
* Add monthly invoice email description by @thiagoyoussef in https://github.com/internetee/registry/pull/2442
|
||||
|
||||
03.10.2022
|
||||
* fixed zeitwerk load file issue by @OlegPhenomenon in https://github.com/internetee/registry/pull/2448
|
||||
* added sidekiq link to admin view by @OlegPhenomenon in https://github.com/internetee/registry/pull/2447
|
||||
* protected public method account activity create by @OlegPhenomenon in https://github.com/internetee/registry/pull/2443
|
||||
|
||||
29.09.2022
|
||||
* Update dependency haml to v6 by @renovate in https://github.com/internetee/registry/pull/2444
|
||||
* added endpoints to demo registry for accr results by @OlegPhenomenon in https://github.com/internetee/registry/pull/2237
|
||||
* Refactor: remove legacy que by @thiagoyoussef in https://github.com/internetee/registry/pull/2337
|
||||
* fixed type of auction for next rounds by @OlegPhenomenon in https://github.com/internetee/registry/pull/2393
|
||||
* Admin: download pdf with domain data on show by @thiagoyoussef in https://github.com/internetee/registry/pull/2396
|
||||
* Increase notification text field length on database by @thiagoyoussef in https://github.com/internetee/registry/pull/2397
|
||||
|
||||
20.09.2022
|
||||
* Created market share chart data endpoint by @maricavor in https://github.com/internetee/registry/pull/2426
|
||||
|
||||
16.09.2022
|
||||
* Removed 200 limit of records if nil by @maricavor in https://github.com/internetee/registry/pull/2440
|
||||
* fixed legal doc issue output by @OlegPhenomenon in https://github.com/internetee/registry/pull/2410
|
||||
* extended csv domain export by @OlegPhenomenon in https://github.com/internetee/registry/pull/2407
|
||||
* remove fixed top registrar navbar css class by @OlegPhenomenon in https://github.com/internetee/registry/pull/2406
|
||||
|
||||
13.09.2022
|
||||
* Ignore statuses update if invoice already paid by @OlegPhenomenon in https://github.com/internetee/registry/pull/2438
|
||||
* remove eis-billing feature toggle by @OlegPhenomenon in https://github.com/internetee/registry/pull/2433
|
||||
|
||||
08.09.2022
|
||||
* Fixed template error for multi-year registered domains in force delete process [#2435](https://github.com/internetee/registry/issues/2435)
|
||||
|
||||
|
|
14
Gemfile
14
Gemfile
|
@ -16,8 +16,8 @@ gem 'uglifier'
|
|||
gem 'figaro', '~> 1.2'
|
||||
|
||||
# model related
|
||||
gem 'paper_trail', '~> 12.1'
|
||||
gem 'pg', '1.4.3'
|
||||
gem 'paper_trail', '~> 13.0'
|
||||
gem 'pg', '1.4.5'
|
||||
# 1.8 is for Rails < 5.0
|
||||
gem 'ransack', '~> 2.6.0'
|
||||
gem 'truemail', '~> 2.4' # validates email by regexp, mail server existence and address existence
|
||||
|
@ -30,13 +30,12 @@ gem 'nokogiri', '~> 1.13.0'
|
|||
# style
|
||||
gem 'bootstrap-sass', '~> 3.4'
|
||||
gem 'cancancan'
|
||||
gem 'coderay', '1.1.3' # xml console visualize
|
||||
gem 'coffee-rails', '>= 5.0'
|
||||
gem 'devise', '~> 4.8'
|
||||
gem 'jquery-rails'
|
||||
gem 'kaminari'
|
||||
gem 'sass-rails'
|
||||
gem 'select2-rails', '4.0.13' # for autocomplete
|
||||
gem 'select2-rails', '4.0.13' # for autocomplete
|
||||
gem 'selectize-rails', '0.12.6' # include selectize.js for select
|
||||
|
||||
# registry specfic
|
||||
|
@ -48,7 +47,7 @@ gem 'simpleidn', '0.2.1' # For punycode
|
|||
gem 'whenever', '1.0.0', require: false
|
||||
|
||||
# country listing
|
||||
gem 'countries', :require => 'countries/global'
|
||||
gem 'countries', require: 'countries/global'
|
||||
|
||||
# id + mid login
|
||||
# gem 'digidoc_client', '0.3.0'
|
||||
|
@ -77,7 +76,6 @@ gem 'lhv', github: 'internetee/lhv', branch: 'master'
|
|||
gem 'rexml'
|
||||
gem 'wkhtmltopdf-binary', '~> 0.12.5.1'
|
||||
|
||||
|
||||
gem 'directo', github: 'internetee/directo', branch: 'master'
|
||||
|
||||
group :development, :test do
|
||||
|
@ -95,12 +93,12 @@ group :test do
|
|||
end
|
||||
|
||||
gem 'aws-sdk-sesv2', '~> 1.19'
|
||||
gem 'newrelic-infinite_tracing'
|
||||
gem 'newrelic_rpm'
|
||||
|
||||
# profiles
|
||||
gem 'pghero'
|
||||
gem 'pg_query', '>= 0.9.0'
|
||||
gem 'newrelic_rpm'
|
||||
gem 'newrelic-infinite_tracing'
|
||||
|
||||
# token
|
||||
gem 'jwt'
|
||||
|
|
83
Gemfile.lock
83
Gemfile.lock
|
@ -55,11 +55,11 @@ GIT
|
|||
|
||||
GIT
|
||||
remote: https://github.com/internetee/omniauth-tara.git
|
||||
revision: cec845ec3794532144c4976104a07e206d759aa6
|
||||
revision: 215f5e91b8c1a51b2fe9a72755585096252a2f93
|
||||
specs:
|
||||
omniauth-tara (0.3.0)
|
||||
omniauth-tara (0.4.0)
|
||||
addressable (~> 2.5)
|
||||
omniauth (~> 1.3)
|
||||
omniauth (>= 1.9, < 3)
|
||||
openid_connect (~> 1.1)
|
||||
|
||||
GIT
|
||||
|
@ -139,8 +139,8 @@ GEM
|
|||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
aes_key_wrap (1.1.0)
|
||||
airbrake (11.0.3)
|
||||
airbrake-ruby (~> 5.1)
|
||||
|
@ -168,7 +168,7 @@ GEM
|
|||
aws-sigv4 (1.2.4)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
bcrypt (3.1.16)
|
||||
bindata (2.4.10)
|
||||
bindata (2.4.14)
|
||||
bootsnap (1.9.3)
|
||||
msgpack (~> 1.0)
|
||||
bootstrap-sass (3.4.1)
|
||||
|
@ -224,13 +224,19 @@ GEM
|
|||
unf (>= 0.0.5, < 1.0.0)
|
||||
erubi (1.10.0)
|
||||
execjs (2.7.0)
|
||||
faraday (2.6.0)
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-follow_redirects (0.3.0)
|
||||
faraday (>= 1, < 3)
|
||||
faraday-net_http (3.0.1)
|
||||
ffi (1.15.0)
|
||||
figaro (1.2.0)
|
||||
thor (>= 0.14.0, < 2)
|
||||
globalid (0.5.2)
|
||||
activesupport (>= 5.0)
|
||||
google-protobuf (3.19.4)
|
||||
google-protobuf (3.19.4-x86_64-linux)
|
||||
google-protobuf (3.21.9)
|
||||
google-protobuf (3.21.9-x86_64-linux)
|
||||
googleapis-common-protos-types (1.3.0)
|
||||
google-protobuf (~> 3.14)
|
||||
grpc (1.41.1)
|
||||
|
@ -246,7 +252,7 @@ GEM
|
|||
thor
|
||||
tilt
|
||||
hashdiff (1.0.1)
|
||||
hashie (4.1.0)
|
||||
hashie (5.0.0)
|
||||
hpricot (0.8.6)
|
||||
http-accept (1.7.0)
|
||||
http-cookie (1.0.3)
|
||||
|
@ -268,10 +274,12 @@ GEM
|
|||
jquery-ui-rails (6.0.1)
|
||||
railties (>= 3.2.16)
|
||||
json (2.5.1)
|
||||
json-jwt (1.13.0)
|
||||
json-jwt (1.16.1)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
bindata
|
||||
faraday (~> 2.0)
|
||||
faraday-follow_redirects
|
||||
jwt (2.3.0)
|
||||
kaminari (1.2.1)
|
||||
activesupport (>= 4.1.0)
|
||||
|
@ -300,9 +308,9 @@ GEM
|
|||
mimemagic (0.4.3)
|
||||
nokogiri (~> 1)
|
||||
rake
|
||||
mini_mime (1.1.1)
|
||||
mini_mime (1.1.2)
|
||||
mini_portile2 (2.8.0)
|
||||
minitest (5.15.0)
|
||||
minitest (5.16.3)
|
||||
monetize (1.9.4)
|
||||
money (~> 6.12)
|
||||
money (6.13.8)
|
||||
|
@ -313,40 +321,46 @@ GEM
|
|||
money (~> 6.13.2)
|
||||
railties (>= 3.0)
|
||||
msgpack (1.4.2)
|
||||
net-protocol (0.1.3)
|
||||
timeout
|
||||
net-smtp (0.3.3)
|
||||
net-protocol
|
||||
netrc (0.11.0)
|
||||
newrelic-infinite_tracing (8.1.0)
|
||||
grpc (~> 1.34)
|
||||
newrelic_rpm (= 8.1.0)
|
||||
newrelic_rpm (8.1.0)
|
||||
nio4r (2.5.8)
|
||||
nokogiri (1.13.6)
|
||||
nokogiri (1.13.9)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.13.6-x86_64-linux)
|
||||
nokogiri (1.13.9-x86_64-linux)
|
||||
racc (~> 1.4)
|
||||
nori (2.6.0)
|
||||
omniauth (1.9.1)
|
||||
omniauth (2.1.0)
|
||||
hashie (>= 3.4.6)
|
||||
rack (>= 1.6.2, < 3)
|
||||
rack (>= 2.2.3)
|
||||
rack-protection
|
||||
omniauth-rails_csrf_protection (0.1.2)
|
||||
actionpack (>= 4.2)
|
||||
omniauth (>= 1.3.1)
|
||||
openid_connect (1.3.0)
|
||||
openid_connect (1.4.2)
|
||||
activemodel
|
||||
attr_required (>= 1.0.0)
|
||||
json-jwt (>= 1.5.0)
|
||||
rack-oauth2 (>= 1.6.1)
|
||||
swd (>= 1.0.0)
|
||||
json-jwt (>= 1.15.0)
|
||||
net-smtp
|
||||
rack-oauth2 (~> 1.21)
|
||||
swd (~> 1.3)
|
||||
tzinfo
|
||||
validate_email
|
||||
validate_url
|
||||
webfinger (>= 1.0.1)
|
||||
webfinger (~> 1.2)
|
||||
orm_adapter (0.5.0)
|
||||
paper_trail (12.1.0)
|
||||
paper_trail (13.0.0)
|
||||
activerecord (>= 5.2)
|
||||
request_store (~> 1.1)
|
||||
pdfkit (0.8.7)
|
||||
pg (1.4.3)
|
||||
pdfkit (0.8.7.2)
|
||||
pg (1.4.5)
|
||||
pg_query (2.1.2)
|
||||
google-protobuf (>= 3.17.1)
|
||||
pghero (2.8.1)
|
||||
|
@ -354,17 +368,19 @@ GEM
|
|||
pry (0.14.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
public_suffix (4.0.6)
|
||||
public_suffix (5.0.0)
|
||||
puma (5.6.4)
|
||||
nio4r (~> 2.0)
|
||||
racc (1.6.0)
|
||||
rack (2.2.4)
|
||||
rack-oauth2 (1.16.0)
|
||||
rack-oauth2 (1.21.3)
|
||||
activesupport
|
||||
attr_required
|
||||
httpclient
|
||||
json-jwt (>= 1.11.0)
|
||||
rack (>= 2.1.0)
|
||||
rack-protection (3.0.2)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (6.1.4.1)
|
||||
|
@ -401,7 +417,7 @@ GEM
|
|||
rbtree3 (0.6.0)
|
||||
redis (4.6.0)
|
||||
regexp_parser (2.1.1)
|
||||
request_store (1.5.0)
|
||||
request_store (1.5.1)
|
||||
rack (>= 1.4)
|
||||
responders (3.0.1)
|
||||
actionpack (>= 5.0)
|
||||
|
@ -412,6 +428,7 @@ GEM
|
|||
mime-types (>= 1.16, < 4.0)
|
||||
netrc (~> 0.8)
|
||||
rexml (3.2.5)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
sass-rails (6.0.0)
|
||||
sassc-rails (~> 2.1, >= 2.1.1)
|
||||
|
@ -464,9 +481,10 @@ GEM
|
|||
temple (0.8.2)
|
||||
thor (1.2.1)
|
||||
tilt (2.0.11)
|
||||
timeout (0.3.0)
|
||||
truemail (2.4.9)
|
||||
simpleidn (~> 0.2.1)
|
||||
tzinfo (2.0.4)
|
||||
tzinfo (2.0.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
uglifier (4.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
|
@ -506,7 +524,7 @@ GEM
|
|||
wkhtmltopdf-binary (0.12.5.4)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zeitwerk (2.5.4)
|
||||
zeitwerk (2.6.6)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
@ -521,7 +539,6 @@ DEPENDENCIES
|
|||
bootstrap-sass (~> 3.4)
|
||||
cancancan
|
||||
capybara
|
||||
coderay (= 1.1.3)
|
||||
coffee-rails (>= 5.0)
|
||||
company_register!
|
||||
countries
|
||||
|
@ -553,9 +570,9 @@ DEPENDENCIES
|
|||
nokogiri (~> 1.13.0)
|
||||
omniauth-rails_csrf_protection
|
||||
omniauth-tara!
|
||||
paper_trail (~> 12.1)
|
||||
paper_trail (~> 13.0)
|
||||
pdfkit
|
||||
pg (= 1.4.3)
|
||||
pg (= 1.4.5)
|
||||
pg_query (>= 0.9.0)
|
||||
pghero
|
||||
pry (= 0.14.1)
|
||||
|
@ -580,4 +597,4 @@ DEPENDENCIES
|
|||
wkhtmltopdf-binary (~> 0.12.5.1)
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.21
|
||||
2.3.25
|
||||
|
|
|
@ -31,7 +31,7 @@ module Admin
|
|||
def create
|
||||
auction = Auction.new(domain: params[:domain], status: Auction.statuses[:started], platform: 'manual')
|
||||
|
||||
if domain_exists_in_blocked_disputed_and_registered?(params[:domain])
|
||||
if Auction.domain_exists_in_blocked_disputed_and_registered?(params[:domain])
|
||||
flash[:alert] = "Adding #{params[:domain]} failed - domain registered or regsitration is blocked"
|
||||
redirect_to admin_auctions_path and return
|
||||
end
|
||||
|
@ -81,7 +81,7 @@ module Admin
|
|||
table.each do |row|
|
||||
record = row.to_h
|
||||
|
||||
if domain_exists_in_blocked_disputed_and_registered?(record['name'])
|
||||
if Auction.domain_exists_in_blocked_disputed_and_registered?(record['name'])
|
||||
failed_names << record['name']
|
||||
|
||||
next
|
||||
|
@ -119,13 +119,6 @@ module Admin
|
|||
Epp::Domain.check_availability(domain_name)
|
||||
end
|
||||
|
||||
def domain_exists_in_blocked_disputed_and_registered?(domain_name)
|
||||
Domain.exists?(name: domain_name) ||
|
||||
BlockedDomain.exists?(name: domain_name) ||
|
||||
Dispute.exists?(domain_name: domain_name) ||
|
||||
Auction.exists?(domain: domain_name)
|
||||
end
|
||||
|
||||
def validate_table(table)
|
||||
first_row = table.headers
|
||||
first_row.include? 'name'
|
||||
|
|
|
@ -3,7 +3,6 @@ module Api
|
|||
class ContactRequestsController < BaseController
|
||||
before_action :authenticate_shared_key
|
||||
|
||||
# POST api/v1/contact_requests/
|
||||
def create
|
||||
return head(:bad_request) if contact_request_params[:email].blank?
|
||||
|
||||
|
@ -19,6 +18,8 @@ module Api
|
|||
process_id(params[:id])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process_id(id)
|
||||
record = ContactRequest.find_by(id: id)
|
||||
return :not_found unless record
|
||||
|
|
|
@ -46,63 +46,36 @@ module Api
|
|||
end
|
||||
|
||||
def update
|
||||
logger.debug 'Received update request'
|
||||
logger.debug params
|
||||
contact = current_user_contacts.find_by!(uuid: params[:uuid])
|
||||
contact.name = params[:name] if params[:name].present?
|
||||
contact.email = params[:email] if params[:email].present?
|
||||
contact.phone = params[:phone] if params[:phone].present?
|
||||
contact = find_contact_and_update_credentials(params[:uuid], params[:name], params[:email], params[:phone])
|
||||
reparsed_request = reparsed_request(request.body.string)
|
||||
disclosed_attributes = reparsed_request[:disclosed_attributes]
|
||||
|
||||
# Needed to support passing empty array, which otherwise gets parsed to nil
|
||||
# https://github.com/rails/rails/pull/13157
|
||||
reparsed_request_json = ActiveSupport::JSON.decode(request.body.string)
|
||||
.with_indifferent_access
|
||||
logger.debug 'Reparsed request is following'
|
||||
logger.debug reparsed_request_json.to_s
|
||||
disclosed_attributes = reparsed_request_json[:disclosed_attributes]
|
||||
|
||||
if disclosed_attributes
|
||||
if disclosed_attributes.present? && contact.org?
|
||||
error_msg = "Legal person's data is visible by default and cannot be concealed." \
|
||||
' Please remove this parameter.'
|
||||
render json: { errors: [{ disclosed_attributes: [error_msg] }] }, status: :bad_request
|
||||
return
|
||||
end
|
||||
|
||||
contact.disclosed_attributes = disclosed_attributes
|
||||
if disclosed_attributes.present?
|
||||
extra_attrs = disclosed_attributes - Contact::DISCLOSE_ATTRIBUTES
|
||||
attributes_not_exist_error(extra_attrs) and return if extra_attrs.present?
|
||||
end
|
||||
|
||||
if disclosed_attributes.present? && contact.org?
|
||||
extra_attrs = disclosed_attributes - Contact::OPEN_LEGAL_ATTRIBUTES
|
||||
render_disclosed_attributes_error and return if extra_attrs.present?
|
||||
end
|
||||
|
||||
contact.disclosed_attributes = disclosed_attributes if disclosed_attributes
|
||||
publishable = reparsed_request[:registrant_publishable]
|
||||
contact.registrant_publishable = publishable if publishable.in? [true, false]
|
||||
|
||||
logger.debug "Setting.address_processing is set to #{Setting.address_processing}"
|
||||
|
||||
if Setting.address_processing && params[:address]
|
||||
address = Contact::Address.new(params[:address][:street],
|
||||
params[:address][:zip],
|
||||
params[:address][:city],
|
||||
params[:address][:state],
|
||||
params[:address][:country_code])
|
||||
contact.address = address
|
||||
end
|
||||
|
||||
if !Setting.address_processing && params[:address]
|
||||
error_msg = 'Address processing is disabled and therefore cannot be updated'
|
||||
render json: { errors: [{ address: [error_msg] }] }, status: :bad_request and return
|
||||
end
|
||||
contact.address = parse_address(params[:address]) if Setting.address_processing && params[:address]
|
||||
render_address_error and return if !Setting.address_processing && params[:address]
|
||||
|
||||
contact.fax = params[:fax] if ENV['fax_enabled'] == 'true' && params[:fax].present?
|
||||
|
||||
logger.debug "ENV['fax_enabled'] is set to #{ENV['fax_enabled']}"
|
||||
if ENV['fax_enabled'] != 'true' && params[:fax]
|
||||
error_msg = 'Fax processing is disabled and therefore cannot be updated'
|
||||
render json: { errors: [{ address: [error_msg] }] }, status: :bad_request and return
|
||||
end
|
||||
render_fax_error and return if ENV['fax_enabled'] != 'true' && params[:fax]
|
||||
|
||||
contact.transaction do
|
||||
contact.save!
|
||||
action = current_registrant_user.actions.create!(contact: contact, operation: :update)
|
||||
contact.registrar.notify(action)
|
||||
end
|
||||
contact = update_and_notify!(contact)
|
||||
|
||||
render json: serialize_contact(contact, false)
|
||||
render json: serialize_contact(contact, true)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -136,6 +109,64 @@ module Api
|
|||
def logger
|
||||
Rails.logger
|
||||
end
|
||||
|
||||
def render_disclosed_attributes_error
|
||||
error_msg = "Legal person's data is visible by default and cannot be concealed." \
|
||||
' Please remove this parameter.'
|
||||
render json: { errors: [{ disclosed_attributes: [error_msg] }] }, status: :bad_request
|
||||
end
|
||||
|
||||
def parse_address(address)
|
||||
Contact::Address.new(
|
||||
address[:street],
|
||||
address[:zip],
|
||||
address[:city],
|
||||
address[:state],
|
||||
address[:country_code]
|
||||
)
|
||||
end
|
||||
|
||||
def attributes_not_exist_error(extra_attrs)
|
||||
error_msg = "Request contains extra attributes: #{extra_attrs.join(', ')}"
|
||||
render json: { errors: [{ disclosed_attributes: [error_msg] }] }, status: :bad_request
|
||||
end
|
||||
|
||||
def render_address_error
|
||||
error_msg = 'Address processing is disabled and therefore cannot be updated'
|
||||
render json: { errors: [{ address: [error_msg] }] }, status: :bad_request
|
||||
end
|
||||
|
||||
def render_fax_error
|
||||
error_msg = 'Fax processing is disabled and therefore cannot be updated'
|
||||
render json: { errors: [{ address: [error_msg] }] }, status: :bad_request
|
||||
end
|
||||
|
||||
def update_and_notify!(contact)
|
||||
contact.transaction do
|
||||
contact.save!
|
||||
action = current_registrant_user.actions.create!(contact: contact, operation: :update)
|
||||
contact.registrar.notify(action)
|
||||
end
|
||||
|
||||
contact
|
||||
end
|
||||
|
||||
def reparsed_request(request_body)
|
||||
reparsed_request = ActiveSupport::JSON.decode(request_body).with_indifferent_access
|
||||
logger.debug 'Reparsed request is following'
|
||||
logger.debug reparsed_request.to_s
|
||||
|
||||
reparsed_request
|
||||
end
|
||||
|
||||
def find_contact_and_update_credentials(uuid, name, email, phone)
|
||||
contact = current_user_contacts.find_by!(uuid: uuid)
|
||||
contact.name = name if name.present?
|
||||
contact.email = email if email.present?
|
||||
contact.phone = phone if phone.present?
|
||||
|
||||
contact
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
63
app/controllers/concerns/epp_requestable.rb
Normal file
63
app/controllers/concerns/epp_requestable.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
module EppRequestable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
# before_action :validate_epp_user, only: :create
|
||||
end
|
||||
|
||||
def create
|
||||
result = server.request(request_params[:payload])
|
||||
render_success(data: { xml: result.force_encoding('UTF-8') })
|
||||
rescue StandardError
|
||||
handle_non_epp_errors(nil, I18n.t('errors.messages.epp_conn_error'))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# def validate_epp_user
|
||||
# return unless handle_hello_request
|
||||
|
||||
# handle_login_request
|
||||
# server.close_connection
|
||||
# rescue OpenSSL::SSL::SSLError => e
|
||||
# Rails.logger.error "INVALID CERT: #{e}"
|
||||
# Rails.logger.error "INVALID CERT DEBUG INFO: epp_hostname: #{ENV['epp_hostname']}," \
|
||||
# "port: #{ENV['epp_port']}, cert_path: #{ENV['cert_path']}, key_path: #{ENV['key_path']}"
|
||||
# handle_non_epp_errors(nil, I18n.t('errors.messages.invalid_cert'))
|
||||
# end
|
||||
|
||||
# def handle_hello_request
|
||||
# res = server.open_connection
|
||||
# unless Nokogiri::XML(res).css('greeting')
|
||||
# server.close_connection # just in case
|
||||
# handle_non_epp_errors(nil, I18n.t('errors.messages.failed_epp_conn')) and return false
|
||||
# end
|
||||
# true
|
||||
# end
|
||||
|
||||
# def handle_login_request
|
||||
# tag = current_user.username
|
||||
# ex = EppXml::Session.new(cl_trid_prefix: tag)
|
||||
# xml = ex.login(clID: { value: tag }, pw: { value: current_user.plain_text_password })
|
||||
# res = server.send_request(xml)
|
||||
|
||||
# return if Nokogiri::XML(res).css('result').first['code'] == '1000'
|
||||
|
||||
# handle_non_epp_errors(nil, Nokogiri::XML(res).css('result').text)
|
||||
# end
|
||||
|
||||
def server
|
||||
client_cert = File.read(ENV['cert_path'])
|
||||
client_key = File.read(ENV['key_path'])
|
||||
port = ENV['epp_port'] || 700
|
||||
@server ||= Epp::Server.new({ server: ENV['epp_hostname'], tag: current_user.username,
|
||||
password: current_user.plain_text_password,
|
||||
port: port,
|
||||
cert: OpenSSL::X509::Certificate.new(client_cert),
|
||||
key: OpenSSL::PKey::RSA.new(client_key) })
|
||||
end
|
||||
|
||||
def request_params
|
||||
params.require(:xml_console).permit(:payload)
|
||||
end
|
||||
end
|
|
@ -10,6 +10,8 @@ class EisBilling::EInvoiceResponseController < EisBilling::BaseController
|
|||
|
||||
def mark_e_invoice_sent_at(invoice_number)
|
||||
invoice = Invoice.find_by(number: invoice_number)
|
||||
invoice = Invoice.find_by(number: invoice_number['invoice_number']) if invoice.nil?
|
||||
|
||||
invoice.update(e_invoice_sent_at: Time.zone.now)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,13 +20,23 @@ module Epp
|
|||
|
||||
rescue_from StandardError, with: :respond_with_command_failed_error
|
||||
rescue_from AuthorizationError, with: :respond_with_authorization_error
|
||||
rescue_from Shunter::ThrottleError, with: :respond_with_session_limit_exceeded_error
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :respond_with_object_does_not_exist_error
|
||||
|
||||
before_action :set_paper_trail_whodunnit
|
||||
|
||||
skip_before_action :validate_against_schema
|
||||
|
||||
protected
|
||||
|
||||
def respond_with_session_limit_exceeded_error(exception)
|
||||
epp_errors.add(:epp_errors,
|
||||
code: '2502',
|
||||
msg: Shunter.default_error_message)
|
||||
handle_errors
|
||||
log_exception(exception) unless Rails.env.test?
|
||||
end
|
||||
|
||||
def respond_with_command_failed_error(exception)
|
||||
epp_errors.add(:epp_errors,
|
||||
code: '2400',
|
||||
|
@ -51,6 +61,11 @@ module Epp
|
|||
|
||||
private
|
||||
|
||||
def throttled_user
|
||||
authorize!(:throttled_user, @domain) unless current_user || instance_of?(Epp::SessionsController)
|
||||
current_user
|
||||
end
|
||||
|
||||
def wrap_exceptions
|
||||
yield
|
||||
rescue CanCan::AccessDenied
|
||||
|
|
|
@ -5,6 +5,9 @@ module Epp
|
|||
before_action :find_contact, only: [:info, :update, :delete]
|
||||
before_action :find_password, only: [:info, :update, :delete]
|
||||
|
||||
THROTTLED_ACTIONS = %i[info check create renew update transfer delete].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
def info
|
||||
authorize! :info, @contact, @password
|
||||
render_epp_response 'epp/contacts/info'
|
||||
|
|
|
@ -6,6 +6,9 @@ module Epp
|
|||
before_action :set_paper_trail_whodunnit
|
||||
before_action :parse_schemas_prefix_and_version
|
||||
|
||||
THROTTLED_ACTIONS = %i[info create check renew update transfer delete].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
def info
|
||||
authorize! :info, @domain
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
module Epp
|
||||
class PollsController < BaseController
|
||||
THROTTLED_ACTIONS = %i[poll].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
def poll
|
||||
authorize! :manage, :poll
|
||||
req_poll if params[:parsed_frame].css('poll').first['op'] == 'req'
|
||||
|
|
|
@ -3,6 +3,9 @@ module Epp
|
|||
skip_authorization_check only: [:hello, :login, :logout]
|
||||
before_action :set_paper_trail_whodunnit
|
||||
|
||||
THROTTLED_ACTIONS = %i[login hello].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
def hello
|
||||
render_epp_response('greeting')
|
||||
end
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
class Registrar
|
||||
class AccountActivitiesController < BaseController
|
||||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
params[:q] ||= {}
|
||||
account = current_registrar_user.registrar.cash_account
|
||||
|
||||
ca_cache = params[:q][:created_at_lteq]
|
||||
begin
|
||||
end_time = params[:q][:created_at_lteq].try(:to_date)
|
||||
params[:q][:created_at_lteq] = end_time.try(:end_of_day)
|
||||
rescue
|
||||
logger.warn('Invalid date')
|
||||
end
|
||||
|
||||
@q = account.activities.includes(:invoice).ransack(params[:q])
|
||||
@q.sorts = 'id desc' if @q.sorts.empty?
|
||||
|
||||
respond_to do |format|
|
||||
format.html { @account_activities = @q.result.page(params[:page]) }
|
||||
format.csv do
|
||||
raw_csv = CsvGenerator.generate_csv(@q.result)
|
||||
send_data raw_csv, filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv"
|
||||
end
|
||||
end
|
||||
|
||||
params[:q][:created_at_lteq] = ca_cache
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
class Registrar
|
||||
class AccountController < BaseController
|
||||
skip_authorization_check
|
||||
helper_method :iban_max_length
|
||||
helper_method :balance_auto_reload_setting
|
||||
|
||||
def show; end
|
||||
|
||||
def edit
|
||||
@registrar = current_registrar_user.registrar
|
||||
end
|
||||
|
||||
def update
|
||||
@registrar = current_registrar_user.registrar
|
||||
@registrar.update!(registrar_params)
|
||||
|
||||
redirect_to registrar_account_path, notice: t('.saved')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def registrar_params
|
||||
params.require(:registrar).permit(:billing_email, :iban)
|
||||
end
|
||||
|
||||
def iban_max_length
|
||||
Iban.max_length
|
||||
end
|
||||
|
||||
def balance_auto_reload_setting
|
||||
current_registrar_user.registrar.settings['balance_auto_reload']
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
class Registrar
|
||||
class AdminContactsController < BulkChangeController
|
||||
BASE_URL = URI.parse("#{ENV['repp_url']}domains/admin_contacts").freeze
|
||||
ACTIVE_TAB = :admin_contact
|
||||
|
||||
def update
|
||||
authorize! :manage, :repp
|
||||
uri = BASE_URL
|
||||
request = form_request(uri)
|
||||
|
||||
action = Actions::DoRequest.new(request, uri)
|
||||
response = action.call
|
||||
|
||||
start_notice = t('.replaced')
|
||||
|
||||
process_response(response: response,
|
||||
start_notice: start_notice,
|
||||
active_tab: ACTIVE_TAB)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,43 +0,0 @@
|
|||
class Registrar
|
||||
class BaseController < ApplicationController
|
||||
include Registrar::ApplicationHelper
|
||||
|
||||
before_action :authenticate_registrar_user!
|
||||
before_action :check_ip_restriction
|
||||
helper_method :depp_controller?
|
||||
helper_method :head_title_sufix
|
||||
before_action :set_paper_trail_whodunnit
|
||||
|
||||
protected
|
||||
|
||||
def current_ability
|
||||
@current_ability ||= Ability.new(current_registrar_user, request.remote_ip)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_ip_restriction
|
||||
ip_restriction = Authorization::RestrictedIp.new(request.ip)
|
||||
allowed = ip_restriction.can_access_registrar_area?(current_registrar_user.registrar)
|
||||
|
||||
return if allowed
|
||||
|
||||
sign_out current_registrar_user
|
||||
|
||||
flash[:alert] = t('registrar.authorization.ip_not_allowed', ip: request.ip)
|
||||
redirect_to new_registrar_user_session_url
|
||||
end
|
||||
|
||||
def depp_controller?
|
||||
false
|
||||
end
|
||||
|
||||
def head_title_sufix
|
||||
t(:registrar_head_title_sufix)
|
||||
end
|
||||
|
||||
def user_for_paper_trail
|
||||
current_registrar_user ? current_registrar_user.id_role_username : 'anonymous'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,105 +0,0 @@
|
|||
class Registrar
|
||||
class BulkChangeController < DeppController
|
||||
helper_method :available_contacts
|
||||
|
||||
def new
|
||||
authorize! :manage, :repp
|
||||
@expire_date = Time.zone.now.to_date
|
||||
render 'registrar/bulk_change/new', locals: { active_tab: default_tab }
|
||||
end
|
||||
|
||||
def bulk_renew
|
||||
authorize! :manage, :repp
|
||||
set_form_data
|
||||
|
||||
if ready_to_renew?
|
||||
res = ReppApi.bulk_renew(domain_ids_for_bulk_renew, params[:period],
|
||||
current_registrar_user)
|
||||
|
||||
flash_message(JSON.parse(res))
|
||||
else
|
||||
flash[:notice] = nil
|
||||
end
|
||||
|
||||
render 'registrar/bulk_change/new', locals: { active_tab: :bulk_renew }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def form_request(uri)
|
||||
request = Net::HTTP::Patch.new(uri)
|
||||
request.set_form_data(current_contact_id: params[:current_contact_id],
|
||||
new_contact_id: params[:new_contact_id])
|
||||
request.basic_auth(current_registrar_user.username,
|
||||
current_registrar_user.plain_text_password)
|
||||
request
|
||||
end
|
||||
|
||||
def process_response(response:, start_notice: '', active_tab:)
|
||||
parsed_response = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
if response.code == '200'
|
||||
notices = success_notices(parsed_response, start_notice)
|
||||
|
||||
flash[:notice] = notices.join(', ')
|
||||
redirect_to registrar_domains_url
|
||||
else
|
||||
@error = response.code == '404' ? 'Contact(s) not found' : parsed_response[:message]
|
||||
render 'registrar/bulk_change/new', locals: { active_tab: active_tab }
|
||||
end
|
||||
end
|
||||
|
||||
def success_notices(parsed_response, start_notice)
|
||||
notices = [start_notice]
|
||||
|
||||
notices << "#{t('.affected_domains')}: " \
|
||||
"#{parsed_response[:data][:affected_domains].join(', ')}"
|
||||
|
||||
if parsed_response[:data][:skipped_domains]
|
||||
notices << "#{t('.skipped_domains')}: " \
|
||||
"#{parsed_response[:data][:skipped_domains].join(', ')}"
|
||||
end
|
||||
notices
|
||||
end
|
||||
|
||||
def ready_to_renew?
|
||||
domain_ids_for_bulk_renew.present? && params[:renew].present?
|
||||
end
|
||||
|
||||
def set_form_data
|
||||
@expire_date = params[:expire_date].to_date
|
||||
@domains = domains_by_date(@expire_date)
|
||||
@period = params[:period]
|
||||
end
|
||||
|
||||
def available_contacts
|
||||
current_registrar_user.registrar.contacts.order(:name).pluck(:name, :code)
|
||||
end
|
||||
|
||||
def default_tab
|
||||
:technical_contact
|
||||
end
|
||||
|
||||
def domains_scope
|
||||
current_registrar_user.registrar.domains
|
||||
end
|
||||
|
||||
def domains_by_date(date)
|
||||
domains_scope.where('valid_to <= ?', date)
|
||||
end
|
||||
|
||||
def domain_ids_for_bulk_renew
|
||||
params['domain_ids']&.reject { |id| id.blank? }
|
||||
end
|
||||
|
||||
def renew_task(domains)
|
||||
Domains::BulkRenew::Start.run(domains: domains,
|
||||
period_element: @period,
|
||||
registrar: current_registrar_user.registrar)
|
||||
end
|
||||
|
||||
def flash_message(res)
|
||||
flash[:notice] = res['code'] == 1000 ? t(:bulk_renew_completed) : res['message']
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,163 +0,0 @@
|
|||
class Registrar
|
||||
class ContactsController < DeppController
|
||||
before_action :init_epp_contact
|
||||
helper_method :address_processing?
|
||||
helper_method :ident_types
|
||||
helper_method :domain_filter_params
|
||||
|
||||
def index
|
||||
authorize! :view, Depp::Contact
|
||||
|
||||
params[:q] ||= {}
|
||||
params[:q].delete_if { |_k, v| v.blank? }
|
||||
|
||||
search_params = params[:q].deep_dup
|
||||
|
||||
if search_params[:domain_contacts_type_in].is_a?(Array) &&
|
||||
search_params[:domain_contacts_type_in].delete('registrant')
|
||||
search_params[:registrant_domains_id_not_null] = 1
|
||||
end
|
||||
|
||||
contacts = current_registrar_user.registrar.contacts.includes(:registrar)
|
||||
status_list = params[:statuses_contains]
|
||||
|
||||
if status_list
|
||||
contacts_ids = contacts.select { |c| (c.statuses & status_list.to_a) == status_list.to_a }
|
||||
.map(&:id)
|
||||
contacts = contacts.where(id: contacts_ids)
|
||||
end
|
||||
|
||||
normalize_search_parameters do
|
||||
@q = contacts.ransack(search_params)
|
||||
end
|
||||
|
||||
contacts = @q.result
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
contacts_per_page = params[:results_per_page].to_i
|
||||
@contacts = contacts.page(params[:page])
|
||||
@contacts = @contacts.per(contacts_per_page) if contacts_per_page.positive?
|
||||
end
|
||||
format.csv do
|
||||
raw_csv = CsvGenerator.generate_csv(contacts)
|
||||
send_data raw_csv, filename: 'contacts.csv', type: "#{Mime[:csv]}; charset=utf-8"
|
||||
end
|
||||
format.pdf do
|
||||
raw_html = ApplicationController.render(
|
||||
template: 'registrar/contacts/list_pdf',
|
||||
assigns: { contacts: contacts },
|
||||
formats: [:html]
|
||||
)
|
||||
raw_pdf = contacts.pdf(raw_html)
|
||||
|
||||
send_data raw_pdf, filename: 'contacts.pdf'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
authorize! :create, Depp::Contact
|
||||
@contact = Depp::Contact.new
|
||||
end
|
||||
|
||||
def show
|
||||
authorize! :view, Depp::Contact
|
||||
@contact = Depp::Contact.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize! :edit, Depp::Contact
|
||||
@contact = Depp::Contact.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def create
|
||||
authorize! :create, Depp::Contact
|
||||
@contact = Depp::Contact.new(contact_params)
|
||||
|
||||
if @contact.save
|
||||
redirect_to registrar_contact_url(@contact.id)
|
||||
else
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :edit, Depp::Contact
|
||||
@contact = Depp::Contact.new(contact_params)
|
||||
|
||||
if @contact.update_attributes(contact_params)
|
||||
redirect_to registrar_contact_url(@contact.id)
|
||||
else
|
||||
render 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
authorize! :delete, Depp::Contact
|
||||
@contact = Depp::Contact.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Depp::Contact
|
||||
@contact = Depp::Contact.new(contact_params_for_delete)
|
||||
|
||||
if @contact.delete
|
||||
redirect_to registrar_contacts_url, notice: t(:destroyed)
|
||||
else
|
||||
render 'delete'
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def domain_filter_params
|
||||
params.permit(:domain_filter)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_epp_contact
|
||||
Depp::Contact.user = depp_current_user
|
||||
end
|
||||
|
||||
def normalize_search_parameters
|
||||
ca_cache = params[:q][:valid_to_lteq]
|
||||
begin
|
||||
end_time = params[:q][:valid_to_lteq].try(:to_date)
|
||||
params[:q][:valid_to_lteq] = end_time.try(:end_of_day)
|
||||
rescue
|
||||
logger.warn('Invalid date')
|
||||
end
|
||||
|
||||
yield
|
||||
|
||||
params[:q][:valid_to_lteq] = ca_cache
|
||||
end
|
||||
|
||||
def address_processing?
|
||||
Contact.address_processing?
|
||||
end
|
||||
|
||||
def ident_types
|
||||
Contact::Ident.types
|
||||
end
|
||||
|
||||
def contact_params
|
||||
params.require(:depp_contact).permit(:id,
|
||||
:name,
|
||||
:email,
|
||||
:phone,
|
||||
:org_name,
|
||||
:ident, :ident_type, :ident_country_code,
|
||||
:street, :city, :zip, :state, :country_code,
|
||||
:password,
|
||||
:legal_document,
|
||||
:code)
|
||||
end
|
||||
|
||||
def contact_params_for_delete
|
||||
params.require(:depp_contact).permit(:id, :password, :legal_document)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,18 +0,0 @@
|
|||
class Registrar
|
||||
class CurrentUserController < BaseController
|
||||
skip_authorization_check
|
||||
|
||||
def switch
|
||||
raise 'Cannot switch to unlinked user' unless current_registrar_user.linked_with?(new_user)
|
||||
|
||||
sign_in(:registrar_user, new_user)
|
||||
redirect_back(fallback_location: root_path, notice: t('.switched', new_user: new_user))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def new_user
|
||||
@new_user ||= ApiUser.find(params[:new_user_id])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
class Registrar
|
||||
class DepositsController < BaseController
|
||||
authorize_resource class: false
|
||||
|
||||
def new
|
||||
@deposit = Deposit.new
|
||||
end
|
||||
|
||||
def create
|
||||
@deposit = Deposit.new(deposit_params.merge(registrar: current_registrar_user.registrar))
|
||||
@invoice = @deposit.issue_prepayment_invoice
|
||||
|
||||
if @invoice
|
||||
flash[:notice] = t(:please_pay_the_following_invoice)
|
||||
redirect_to [:registrar, @invoice]
|
||||
else
|
||||
flash[:alert] = @deposit.errors.full_messages.join(', ')
|
||||
redirect_to new_registrar_deposit_path
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deposit_params
|
||||
params.require(:deposit).permit(:amount, :description)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
class Registrar
|
||||
class DeppController < BaseController
|
||||
helper_method :depp_current_user
|
||||
|
||||
rescue_from(Errno::ECONNRESET, Errno::ECONNREFUSED) do |exception|
|
||||
logger.error 'COULD NOT CONNECT TO REGISTRY'
|
||||
logger.error exception.backtrace.join("\n")
|
||||
redirect_to new_registrar_user_session_url, alert: t(:no_connection_to_registry)
|
||||
end
|
||||
|
||||
before_action :authenticate_user
|
||||
|
||||
def authenticate_user
|
||||
redirect_to new_registrar_user_session_url and return unless depp_current_user
|
||||
end
|
||||
|
||||
def depp_controller?
|
||||
true
|
||||
end
|
||||
|
||||
def depp_current_user
|
||||
return nil unless current_registrar_user
|
||||
@depp_current_user ||= Depp::User.new(
|
||||
tag: current_registrar_user.username,
|
||||
password: current_registrar_user.plain_text_password
|
||||
)
|
||||
end
|
||||
|
||||
def response_ok?
|
||||
@data.css('result').each do |x|
|
||||
success_codes = %(1000, 1001, 1300, 1301)
|
||||
return false unless success_codes.include?(x['code'])
|
||||
end
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,49 +0,0 @@
|
|||
class Registrar
|
||||
class DomainTransfersController < BulkChangeController
|
||||
before_action do
|
||||
authorize! :transfer, Depp::Domain
|
||||
end
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
if params[:batch_file].present?
|
||||
csv = CSV.read(params[:batch_file].path, headers: true)
|
||||
domain_transfers = []
|
||||
|
||||
csv.each do |row|
|
||||
domain_name = row['Domain']
|
||||
transfer_code = row['Transfer code']
|
||||
domain_transfers << { 'domain_name' => domain_name, 'transfer_code' => transfer_code }
|
||||
end
|
||||
|
||||
uri = URI.parse("#{ENV['repp_url']}domains/transfer")
|
||||
request = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
|
||||
request.body = { data: { domain_transfers: domain_transfers } }.to_json
|
||||
request.basic_auth(current_registrar_user.username,
|
||||
current_registrar_user.plain_text_password)
|
||||
|
||||
action = Actions::DoRequest.new(request, uri)
|
||||
response = action.call
|
||||
|
||||
parsed_response = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
if response.code == '200'
|
||||
failed = parsed_response[:data][:failed].pluck(:domain_name).join(', ')
|
||||
flash[:notice] = t('.transferred', count: parsed_response[:data][:success].size,
|
||||
failed: failed)
|
||||
redirect_to registrar_domains_url
|
||||
else
|
||||
@api_errors = parsed_response[:message]
|
||||
render 'registrar/bulk_change/new', locals: { active_tab: :bulk_transfer }
|
||||
end
|
||||
else
|
||||
params[:request] = true # EPP domain:transfer "op" attribute
|
||||
domain = Depp::Domain.new(current_user: depp_current_user)
|
||||
@data = domain.transfer(params)
|
||||
render :new unless response_ok?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,227 +0,0 @@
|
|||
class Registrar
|
||||
class DomainsController < DeppController
|
||||
before_action :init_domain, except: :new
|
||||
helper_method :contacts
|
||||
helper_method :search_params
|
||||
|
||||
def index
|
||||
authorize! :view, Depp::Domain
|
||||
|
||||
if search_params.to_h.delete_if { |_key, value| value.blank? }.length == 1 &&
|
||||
search_params[:name_matches].present?
|
||||
domain = Domain.find_by(name: search_params[:name_matches])
|
||||
|
||||
redirect_to info_registrar_domains_url(domain_name: domain.name) and return if domain
|
||||
end
|
||||
|
||||
domains = if params[:statuses_contains]
|
||||
current_domain_scope.where('domains.statuses @> ?::varchar[]',
|
||||
"{#{params[:statuses_contains].join(',')}}")
|
||||
else
|
||||
current_domain_scope
|
||||
end
|
||||
|
||||
domains = domains.where(contacts: { ident: params[:contacts_ident_eq] }) if params[:contacts_ident_eq]
|
||||
|
||||
normalize_search_parameters do
|
||||
@q = domains.ransack(search_params.except(:contacts_ident_eq))
|
||||
@domains = @q.result.page(params[:page])
|
||||
|
||||
# if we do not get any results, add wildcards to the name field and search again
|
||||
if @domains.count == 0 && search_params[:name_matches] !~ /^%.+%$/
|
||||
new_search_params = search_params.to_h.except(:contacts_ident_eq)
|
||||
new_search_params[:name_matches] = "%#{new_search_params[:name_matches]}%"
|
||||
@q = domains.ransack(new_search_params)
|
||||
@domains = @q.result.page(params[:page])
|
||||
end
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.csv do
|
||||
domain_presenters = []
|
||||
|
||||
@q.result.find_each do |domain|
|
||||
domain_presenters << ::DomainPresenter.new(domain: domain, view: view_context)
|
||||
end
|
||||
|
||||
raw_csv = Registrar::DomainListCsvPresenter.new(domains: domain_presenters,
|
||||
view: view_context).to_s
|
||||
filename = "Domains_#{l(Time.zone.now, format: :filename)}.csv"
|
||||
send_data raw_csv, filename: filename, type: "#{Mime[:csv]}; charset=utf-8"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def current_domain_scope
|
||||
current_registrar_user.registrar.domains.includes(:registrar, :registrant)
|
||||
end
|
||||
|
||||
def info
|
||||
authorize! :info, Depp::Domain
|
||||
@data = @domain.info(params[:domain_name]) if params[:domain_name]
|
||||
@pending_delete = domain_delete_pending(@data)
|
||||
@client_holded = client_holded(@data)
|
||||
if response_ok?
|
||||
render 'info'
|
||||
else
|
||||
flash[:alert] = @data.css('msg').text
|
||||
redirect_to registrar_domains_url and return
|
||||
end
|
||||
end
|
||||
|
||||
def check
|
||||
authorize! :check, Depp::Domain
|
||||
if params[:domain_name]
|
||||
@data = @domain.check(params[:domain_name])
|
||||
render 'check_index' and return unless response_ok?
|
||||
else
|
||||
render 'check_index'
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
authorize! :create, Depp::Domain
|
||||
@domain_params = Depp::Domain.default_params
|
||||
@domain_params[:period] = Depp::Domain.default_period
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/CognitiveComplexity
|
||||
def create
|
||||
authorize! :create, Depp::Domain
|
||||
@domain_params = domain_params.to_h
|
||||
@data = @domain.create(@domain_params)
|
||||
|
||||
if @data && response_ok?
|
||||
redirect_to info_registrar_domains_url(domain_name: @domain_params[:name])
|
||||
else
|
||||
flash[:alert] = t('.email_error_message') unless @emails_check_result
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize! :update, Depp::Domain
|
||||
@data = @domain.info(params[:domain_name])
|
||||
@domain_params = Depp::Domain.construct_params_from_server_data(@data)
|
||||
@dispute = Dispute.active.find_by(domain_name: params[:domain_name])
|
||||
end
|
||||
|
||||
def update
|
||||
authorize! :update, Depp::Domain
|
||||
@domain_params = params[:domain]
|
||||
@data = @domain.update(@domain_params)
|
||||
@dispute = Dispute.active.find_by(domain_name: @domain_params[:name])
|
||||
|
||||
if @data && response_ok?
|
||||
redirect_to info_registrar_domains_url(domain_name: @domain_params[:name])
|
||||
else
|
||||
flash[:alert] = t('.email_error_message') unless @emails_check_result
|
||||
params[:domain_name] = @domain_params[:name]
|
||||
render 'new'
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/CognitiveComplexity
|
||||
|
||||
def delete
|
||||
authorize! :delete, Depp::Domain
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :delete, Depp::Domain
|
||||
@data = @domain.delete(params[:domain])
|
||||
@results = @data.css('result')
|
||||
if response_ok?
|
||||
flash[:notice] = t('.deleting_request')
|
||||
redirect_to info_registrar_domains_url(domain_name: params[:domain][:name])
|
||||
else
|
||||
params[:domain_name] = params[:domain][:name]
|
||||
render 'delete'
|
||||
end
|
||||
end
|
||||
|
||||
def renew
|
||||
authorize! :renew, Depp::Domain
|
||||
if params[:domain_name] && params[:cur_exp_date]
|
||||
@data = @domain.renew(params)
|
||||
render 'renew_index' and return unless response_ok?
|
||||
else
|
||||
params[:period] = Depp::Domain.default_period
|
||||
render 'renew_index'
|
||||
end
|
||||
end
|
||||
|
||||
def search_contacts
|
||||
authorize! :create, Depp::Domain
|
||||
|
||||
scope = current_registrar_user.registrar.contacts.limit(10)
|
||||
if params[:query].present?
|
||||
escaped_str = ActiveRecord::Base.connection.quote_string params[:query]
|
||||
scope = scope.where("name ilike '%#{escaped_str}%' OR code ilike '%#{escaped_str}%' ")
|
||||
end
|
||||
|
||||
render json: scope.pluck(:name, :code).map { |c| { display_key: "#{c.second} #{c.first}", value: c.second } }
|
||||
end
|
||||
|
||||
def remove_hold
|
||||
authorize! :remove_hold, Depp::Domain
|
||||
return unless params[:domain_name]
|
||||
|
||||
@data = @domain.remove_hold(params)
|
||||
|
||||
flash[:alert] = @data.css('msg').text unless response_ok?
|
||||
redirect_to info_registrar_domains_url(domain_name: params[:domain_name])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_domain
|
||||
@domain = Depp::Domain.new(current_user: depp_current_user)
|
||||
end
|
||||
|
||||
def client_holded(data)
|
||||
data.css('status')&.map { |element| element.attribute('s').value }
|
||||
&.any? { |status| status == DomainStatus::CLIENT_HOLD }
|
||||
end
|
||||
|
||||
def domain_delete_pending(data)
|
||||
data.css('status')&.map { |element| element.attribute('s').value }
|
||||
&.any? { |status| status.include?(DomainStatus::PENDING_DELETE) }
|
||||
end
|
||||
|
||||
def contacts
|
||||
current_registrar_user.registrar.contacts
|
||||
end
|
||||
|
||||
def normalize_search_parameters
|
||||
ca_cache = search_params[:valid_to_lteq]
|
||||
begin
|
||||
end_time = search_params[:valid_to_lteq].try(:to_date)
|
||||
search_params[:valid_to_lteq] = end_time.try(:end_of_day)
|
||||
rescue
|
||||
logger.warn('Invalid date')
|
||||
end
|
||||
|
||||
yield
|
||||
|
||||
search_params[:valid_to_lteq] = ca_cache
|
||||
end
|
||||
|
||||
def search_params
|
||||
params.fetch(:q, {}).permit(:name_matches,
|
||||
:registrant_ident_eq,
|
||||
:contacts_ident_eq,
|
||||
:nameservers_hostname_eq,
|
||||
:valid_to_gteq,
|
||||
:valid_to_lteq,
|
||||
:s)
|
||||
end
|
||||
|
||||
def domain_params
|
||||
params.require(:domain).permit(:name, :period, :registrant, :registrant_helper, :reserved_pw,
|
||||
:verified, :legal_document, contacts_attributes: {},
|
||||
nameservers_attributes: {},
|
||||
dnskeys_attributes: {})
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
class Registrar
|
||||
module Invoices
|
||||
class DeliveryController < BaseController
|
||||
include Deliverable
|
||||
|
||||
private
|
||||
|
||||
def redirect_url
|
||||
registrar_invoice_path(@invoice)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,38 +0,0 @@
|
|||
class Registrar
|
||||
class InvoicesController < BaseController
|
||||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
params[:q] ||= {}
|
||||
invoices = current_registrar_user.registrar.invoices.includes(:items, :account_activity)
|
||||
|
||||
normalize_search_parameters do
|
||||
@q = invoices.ransack(params[:q])
|
||||
@q.sorts = 'id desc' if @q.sorts.empty?
|
||||
@invoices = @q.result.page(params[:page])
|
||||
end
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
||||
def cancel
|
||||
@invoice.cancel
|
||||
EisBilling::SendInvoiceStatus.send_info(invoice_number: @invoice.number, status: 'cancelled')
|
||||
|
||||
redirect_to [:registrar, @invoice], notice: t('.cancelled')
|
||||
end
|
||||
|
||||
def download
|
||||
filename = "invoice-#{@invoice.number}.pdf"
|
||||
send_data @invoice.as_pdf, filename: filename
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def normalize_search_parameters
|
||||
params[:q][:total_gteq].gsub!(',', '.') if params[:q][:total_gteq]
|
||||
params[:q][:total_lteq].gsub!(',', '.') if params[:q][:total_lteq]
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,65 +0,0 @@
|
|||
class Registrar
|
||||
class NameserversController < BulkChangeController
|
||||
def update
|
||||
authorize! :manage, :repp
|
||||
|
||||
ipv4 = params[:ipv4].split("\r\n")
|
||||
ipv6 = params[:ipv6].split("\r\n")
|
||||
|
||||
uri = URI.parse("#{ENV['repp_url']}registrar/nameservers")
|
||||
|
||||
domains = domain_list_from_csv
|
||||
|
||||
return csv_list_empty_guard if domains == []
|
||||
|
||||
options = {
|
||||
uri: uri,
|
||||
ipv4: ipv4,
|
||||
ipv6: ipv6,
|
||||
}
|
||||
action = Actions::BulkNameserversChange.new(params, domains, current_registrar_user, options)
|
||||
response = action.call
|
||||
|
||||
parsed_response = JSON.parse(response.body, symbolize_names: true)
|
||||
|
||||
if response.code == '200'
|
||||
redirect_to(registrar_domains_url,
|
||||
flash: { notice: compose_notice_message(parsed_response) })
|
||||
else
|
||||
@api_errors = parsed_response[:message]
|
||||
render 'registrar/bulk_change/new', locals: { active_tab: :nameserver }
|
||||
end
|
||||
end
|
||||
|
||||
def compose_notice_message(res)
|
||||
action_text = params[:old_hostname].blank? ? t('.added') : t('.replaced')
|
||||
notices = ["#{action_text}. #{t('.affected_domains')}: " \
|
||||
"#{res[:data][:affected_domains].join(', ')}"]
|
||||
|
||||
notices << "#{t('.skipped_domains')}: #{res[:data][:skipped_domains].join(', ')}" if res[:data][:skipped_domains]
|
||||
|
||||
notices.join(', ')
|
||||
end
|
||||
|
||||
def csv_list_empty_guard
|
||||
notice = 'CSV scoped domain list seems empty. Make sure that domains are added and ' \
|
||||
'"Domain" header is present.'
|
||||
redirect_to(registrar_domains_url, flash: { notice: notice })
|
||||
end
|
||||
|
||||
def domain_list_from_csv
|
||||
return if params[:puny_file].blank?
|
||||
|
||||
domains = []
|
||||
csv = CSV.read(params[:puny_file].path, headers: true)
|
||||
|
||||
return [] if csv['Domain'].blank?
|
||||
|
||||
csv.map { |b| domains << b['Domain'] }
|
||||
|
||||
domains.compact
|
||||
rescue CSV::MalformedCSVError
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,66 +0,0 @@
|
|||
class Registrar
|
||||
class PaymentsController < BaseController
|
||||
protect_from_forgery except: [:back, :callback]
|
||||
|
||||
skip_authorization_check # actually anyone can pay, no problems at all
|
||||
skip_before_action :authenticate_registrar_user!, :check_ip_restriction,
|
||||
only: [:back, :callback]
|
||||
|
||||
before_action :check_supported_payment_method, only: [:pay]
|
||||
|
||||
def pay
|
||||
invoice = Invoice.find(params[:invoice_id])
|
||||
channel = params[:bank]
|
||||
|
||||
@payment_order = PaymentOrder.new_with_type(type: channel, invoice: invoice)
|
||||
@payment_order.save
|
||||
@payment_order.reload
|
||||
|
||||
@payment_order.return_url = registrar_return_payment_with_url(@payment_order)
|
||||
@payment_order.response_url = registrar_response_payment_with_url(@payment_order)
|
||||
|
||||
@payment_order.save
|
||||
@payment_order.reload
|
||||
end
|
||||
|
||||
def back
|
||||
@payment_order = PaymentOrder.find_by!(id: params[:payment_order])
|
||||
@payment_order.update!(response: params.to_unsafe_h)
|
||||
|
||||
if @payment_order.payment_received?
|
||||
@payment_order.complete_transaction
|
||||
|
||||
if @payment_order.invoice.paid?
|
||||
flash[:notice] = t('.payment_successful')
|
||||
else
|
||||
flash[:alert] = t('.successful_payment_backend_error')
|
||||
end
|
||||
else
|
||||
@payment_order.create_failure_report
|
||||
flash[:alert] = t('.payment_not_received')
|
||||
end
|
||||
redirect_to registrar_invoice_path(@payment_order.invoice)
|
||||
end
|
||||
|
||||
def callback
|
||||
@payment_order = PaymentOrder.find_by!(id: params[:payment_order])
|
||||
@payment_order.update!(response: params.to_unsafe_h)
|
||||
|
||||
if @payment_order.payment_received?
|
||||
@payment_order.complete_transaction
|
||||
else
|
||||
@payment_order.create_failure_report
|
||||
end
|
||||
|
||||
render status: 200, json: { status: 'ok' }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_supported_payment_method
|
||||
return if PaymentOrder.supported_method?(params[:bank], shortname: true)
|
||||
|
||||
raise(StandardError, 'Not supported payment method')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,44 +0,0 @@
|
|||
class Registrar
|
||||
class PollsController < DeppController
|
||||
authorize_resource class: false
|
||||
before_action :init_epp_xml
|
||||
|
||||
def show
|
||||
if Rails.env.test? # Stub for depp server request
|
||||
@data = Object.new
|
||||
|
||||
def @data.css(key)
|
||||
; [];
|
||||
end
|
||||
else
|
||||
@data = depp_current_user.request(@ex.poll)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@data = depp_current_user.request(@ex.poll(poll: { value: '', attrs: { op: 'ack', msgID: params[:id] } }))
|
||||
|
||||
@results = @data.css('result')
|
||||
|
||||
@data = depp_current_user.request(@ex.poll)
|
||||
render 'show'
|
||||
end
|
||||
|
||||
def confirm_transfer
|
||||
domain_params = params[:domain]
|
||||
@data = @domain.confirm_transfer(domain_params)
|
||||
|
||||
@results = @data.css('result')
|
||||
@data = depp_current_user.request(@ex.poll)
|
||||
|
||||
render 'show'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_epp_xml
|
||||
@ex = EppXml::Session.new(cl_trid_prefix: depp_current_user.tag)
|
||||
@domain = Depp::Domain.new(current_user: depp_current_user)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,108 +0,0 @@
|
|||
class Registrar
|
||||
class SessionsController < Devise::SessionsController
|
||||
before_action :check_ip_restriction
|
||||
helper_method :depp_controller?
|
||||
|
||||
def create
|
||||
@depp_user = Depp::User.new(depp_user_params)
|
||||
|
||||
if @depp_user.pki && request.env['HTTP_SSL_CLIENT_S_DN_CN'].blank?
|
||||
@depp_user.errors.add(:base, :webserver_missing_user_name_directive)
|
||||
end
|
||||
|
||||
if @depp_user.pki && request.env['HTTP_SSL_CLIENT_CERT'].blank?
|
||||
@depp_user.errors.add(:base, :webserver_missing_client_cert_directive)
|
||||
end
|
||||
|
||||
if @depp_user.pki && request.env['HTTP_SSL_CLIENT_S_DN_CN'] == '(null)'
|
||||
@depp_user.errors.add(:base, :webserver_user_name_directive_should_be_required)
|
||||
end
|
||||
|
||||
if @depp_user.pki && request.env['HTTP_SSL_CLIENT_CERT'] == '(null)'
|
||||
@depp_user.errors.add(:base, :webserver_client_cert_directive_should_be_required)
|
||||
end
|
||||
|
||||
@api_user = ApiUser.find_by(username: sign_in_params[:username],
|
||||
plain_text_password: sign_in_params[:password])
|
||||
|
||||
unless @api_user
|
||||
@depp_user.errors.add(:base, t(:no_such_user))
|
||||
show_error and return
|
||||
end
|
||||
|
||||
if @depp_user.pki && !@api_user.pki_ok?(request.env['HTTP_SSL_CLIENT_CERT'],
|
||||
request.env['HTTP_SSL_CLIENT_S_DN_CN'], api: false)
|
||||
@depp_user.errors.add(:base, :invalid_cert)
|
||||
end
|
||||
|
||||
show_error and return unless @depp_user.errors.none?
|
||||
|
||||
if @api_user.active?
|
||||
sign_in_and_redirect(:registrar_user, @api_user)
|
||||
else
|
||||
@depp_user.errors.add(:base, :not_active)
|
||||
show_error
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def depp_controller?
|
||||
false
|
||||
end
|
||||
|
||||
def find_user_by_idc(idc)
|
||||
return User.new unless idc
|
||||
ApiUser.find_by(identity_code: idc) || User.new
|
||||
end
|
||||
|
||||
def find_user_by_idc_and_allowed(idc)
|
||||
return User.new unless idc
|
||||
|
||||
possible_users = ApiUser.where(identity_code: idc) || User.new
|
||||
possible_users.each do |selected_user|
|
||||
return selected_user if selected_user.registrar.white_ips.registrar_area.include_ip?(request.ip)
|
||||
end
|
||||
end
|
||||
|
||||
def check_ip_restriction
|
||||
ip_restriction = Authorization::RestrictedIp.new(request.ip)
|
||||
allowed = ip_restriction.can_access_registrar_area_sign_in_page?
|
||||
|
||||
return if allowed
|
||||
|
||||
render plain: t('registrar.authorization.ip_not_allowed', ip: request.ip)
|
||||
end
|
||||
|
||||
def current_ability
|
||||
@current_ability ||= Ability.new(current_registrar_user, request.remote_ip)
|
||||
end
|
||||
|
||||
def after_sign_in_path_for(_resource_or_scope)
|
||||
if can?(:show, :poll)
|
||||
registrar_root_path
|
||||
else
|
||||
registrar_account_path
|
||||
end
|
||||
end
|
||||
|
||||
def after_sign_out_path_for(_resource_or_scope)
|
||||
new_registrar_user_session_path
|
||||
end
|
||||
|
||||
def user_for_paper_trail
|
||||
current_registrar_user ? current_registrar_user.id_role_username : 'anonymous'
|
||||
end
|
||||
|
||||
def depp_user_params
|
||||
params = sign_in_params
|
||||
params[:tag] = params.delete(:username)
|
||||
params.merge!(pki: !(Rails.env.development? || Rails.env.test?))
|
||||
params
|
||||
end
|
||||
|
||||
def show_error
|
||||
redirect_to new_registrar_user_session_url, alert: @depp_user.errors.full_messages.first
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,52 +0,0 @@
|
|||
class Registrar
|
||||
module Settings
|
||||
class BalanceAutoReloadController < BaseController
|
||||
before_action :authorize
|
||||
|
||||
def edit
|
||||
@type = if current_registrar.settings['balance_auto_reload']
|
||||
type_params = current_registrar.settings['balance_auto_reload']['type']
|
||||
.except('name')
|
||||
BalanceAutoReloadTypes::Threshold.new(type_params)
|
||||
else
|
||||
BalanceAutoReloadTypes::Threshold.new
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
type = BalanceAutoReloadTypes::Threshold.new(type_params)
|
||||
current_registrar.update!(settings: { balance_auto_reload: { type: type } })
|
||||
|
||||
redirect_to registrar_account_path, notice: t('.saved')
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_registrar.settings.delete('balance_auto_reload')
|
||||
current_registrar.save!
|
||||
|
||||
redirect_to registrar_account_path, notice: t('.disabled')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def type_params
|
||||
permitted_params = params.require(:type).permit(:amount, :threshold)
|
||||
normalize_params(permitted_params)
|
||||
end
|
||||
|
||||
def normalize_params(params)
|
||||
params[:amount] = params[:amount].to_f
|
||||
params[:threshold] = params[:threshold].to_f
|
||||
params
|
||||
end
|
||||
|
||||
def authorize
|
||||
authorize!(:manage, :balance_auto_reload)
|
||||
end
|
||||
|
||||
def current_registrar
|
||||
current_registrar_user.registrar
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
class Registrar
|
||||
class TechContactsController < BulkChangeController
|
||||
BASE_URL = URI.parse("#{ENV['repp_url']}domains/contacts").freeze
|
||||
ACTIVE_TAB = :technical_contact
|
||||
|
||||
def update
|
||||
authorize! :manage, :repp
|
||||
|
||||
uri = BASE_URL
|
||||
request = form_request(uri)
|
||||
|
||||
action = Actions::DoRequest.new(request, uri)
|
||||
response = action.call
|
||||
|
||||
start_notice = t('.replaced')
|
||||
|
||||
process_response(response: response,
|
||||
start_notice: start_notice,
|
||||
active_tab: ACTIVE_TAB)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,62 +0,0 @@
|
|||
class Registrar
|
||||
class XmlConsolesController < DeppController
|
||||
PREFS = %w[
|
||||
domain-ee
|
||||
contact-ee
|
||||
eis
|
||||
epp-ee
|
||||
].freeze
|
||||
|
||||
authorize_resource class: false
|
||||
|
||||
def show; end
|
||||
|
||||
def create
|
||||
begin
|
||||
@result = depp_current_user.server.request(params[:payload])
|
||||
rescue StandardError
|
||||
@result = 'CONNECTION ERROR - Is the EPP server running?'
|
||||
end
|
||||
render :show
|
||||
end
|
||||
|
||||
def load_xml
|
||||
cl_trid = "#{depp_current_user.tag}-#{Time.zone.now.to_i}"
|
||||
xml_dir_path = Rails.root.join('app/views/registrar/xml_consoles/epp_requests').to_s
|
||||
xml = File.read("#{xml_dir_path}/#{params[:obj]}/#{params[:epp_action]}.xml")
|
||||
xml = prepare_payload(xml, cl_trid)
|
||||
|
||||
render plain: xml
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_payload(xml, cl_trid)
|
||||
PREFS.map do |pref|
|
||||
xml = load_schema_by_prefix(pref, xml)
|
||||
end
|
||||
|
||||
xml.gsub!('<clTRID>ABC-12345</clTRID>', "<clTRID>#{cl_trid}</clTRID>")
|
||||
xml
|
||||
end
|
||||
|
||||
def load_schema_by_prefix(pref, xml)
|
||||
case pref
|
||||
when 'epp-ee'
|
||||
insert_prefix_and_version(xml, pref, '1.0')
|
||||
when 'eis'
|
||||
insert_prefix_and_version(xml, pref, '1.0')
|
||||
when 'contact-ee'
|
||||
insert_prefix_and_version(xml, pref, '1.1')
|
||||
else
|
||||
insert_prefix_and_version(xml, pref, '1.2')
|
||||
end
|
||||
end
|
||||
|
||||
def insert_prefix_and_version(xml, pref, version)
|
||||
xml.gsub!("\"#{pref}\"",
|
||||
"\"#{Xsd::Schema.filename(for_prefix: pref.to_s, for_version: version)}\"")
|
||||
xml
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,6 +3,11 @@ module Repp
|
|||
class AccountsController < BaseController # rubocop:disable Metrics/ClassLength
|
||||
load_and_authorize_resource
|
||||
|
||||
THROTTLED_ACTIONS = %i[
|
||||
index balance details update_auto_reload_balance disable_auto_reload_balance switch_user update
|
||||
].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :get, '/repp/v1/accounts'
|
||||
desc 'Get all activities'
|
||||
def index
|
||||
|
|
|
@ -27,6 +27,10 @@ module Repp
|
|||
@response = { code: 2201, message: 'Authorization error' }
|
||||
logger.error e.to_s
|
||||
render(json: @response, status: :unauthorized)
|
||||
rescue Shunter::ThrottleError => e
|
||||
@response = { code: 2502, message: Shunter.default_error_message }
|
||||
logger.error e.to_s unless Rails.env.test?
|
||||
render(json: @response, status: :bad_request)
|
||||
ensure
|
||||
create_repp_log
|
||||
end
|
||||
|
@ -167,6 +171,11 @@ module Repp
|
|||
data[:abilities] = Ability.new(current_user).permissions
|
||||
data
|
||||
end
|
||||
|
||||
def throttled_user
|
||||
authorize!(:throttled_user, @domain) unless current_user || action_name == 'tara_callback'
|
||||
current_user
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,9 @@ module Repp
|
|||
before_action :find_contact, only: %i[show update destroy]
|
||||
skip_around_action :log_request, only: :search
|
||||
|
||||
THROTTLED_ACTIONS = %i[index check search create show update destroy].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :get, '/repp/v1/contacts'
|
||||
desc 'Get all existing contacts'
|
||||
def index
|
||||
|
|
|
@ -2,6 +2,9 @@ module Repp
|
|||
module V1
|
||||
module Domains
|
||||
class AdminContactsController < BaseContactsController
|
||||
THROTTLED_ACTIONS = %i[update].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
def update
|
||||
super
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ module Repp
|
|||
class ContactsController < BaseContactsController
|
||||
before_action :set_domain, only: %i[index create destroy]
|
||||
|
||||
THROTTLED_ACTIONS = %i[index create destroy update].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
def_param_group :contacts_apidoc do
|
||||
param :contacts, Array, required: true, desc: 'Array of new linked contacts' do
|
||||
param :code, String, required: true, desc: 'Contact code'
|
||||
|
@ -38,9 +41,7 @@ module Repp
|
|||
def cta(action = 'add')
|
||||
params[:contacts].each { |c| c[:action] = action }
|
||||
action = Actions::DomainUpdate.new(@domain, contact_create_params, false)
|
||||
# rubocop:disable Style/AndOr
|
||||
handle_errors(@domain) and return unless action.call
|
||||
# rubocop:enable Style/AndOr
|
||||
|
||||
render_success(data: { domain: { name: @domain.name } })
|
||||
end
|
||||
|
|
|
@ -4,6 +4,9 @@ module Repp
|
|||
class DnssecController < BaseController
|
||||
before_action :set_domain, only: %i[index create destroy]
|
||||
|
||||
THROTTLED_ACTIONS = %i[index create destroy].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
def_param_group :dns_keys_apidoc do
|
||||
param :flags, String, required: true, desc: '256 (KSK) or 257 (ZSK)'
|
||||
param :protocol, String, required: true, desc: 'Key protocol (3)'
|
||||
|
|
|
@ -5,6 +5,9 @@ module Repp
|
|||
before_action :set_domain, only: %i[index create destroy]
|
||||
before_action :set_nameserver, only: %i[destroy]
|
||||
|
||||
THROTTLED_ACTIONS = %i[index create destroy].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :GET, '/repp/v1/domains/:domain_name/nameservers'
|
||||
desc "Get domain's nameservers"
|
||||
def index
|
||||
|
|
|
@ -6,6 +6,9 @@ module Repp
|
|||
before_action :select_renewable_domains, only: [:bulk_renew]
|
||||
before_action :set_domain, only: [:create]
|
||||
|
||||
THROTTLED_ACTIONS = %i[create bulk_renew].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :POST, 'repp/v1/domains/:domain_name/renew'
|
||||
desc 'Renew domain'
|
||||
param :renews, Hash, required: true, desc: 'Renew parameters' do
|
||||
|
@ -43,7 +46,7 @@ module Repp
|
|||
|
||||
def validate_renew_period
|
||||
@epp_errors ||= ActiveModel::Errors.new(self)
|
||||
periods = Depp::Domain::PERIODS.map { |p| p[1] }
|
||||
periods = Domain::PERIODS.map { |p| p[1] }
|
||||
return if periods.include? bulk_renew_params[:renew_period]
|
||||
|
||||
@epp_errors.add(:epp_errors, msg: 'Invalid renew period', code: '2005')
|
||||
|
|
|
@ -5,6 +5,9 @@ module Repp
|
|||
before_action :set_domain, only: %i[update destroy]
|
||||
before_action :verify_status
|
||||
|
||||
THROTTLED_ACTIONS = %i[update destroy].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :DELETE, '/repp/v1/domains/:domain_name/statuses/:status'
|
||||
param :domain_name, String, desc: 'Domain name'
|
||||
desc 'Remove status from specific domain'
|
||||
|
|
|
@ -4,6 +4,9 @@ module Repp
|
|||
class TransfersController < BaseController
|
||||
before_action :set_domain, only: [:create]
|
||||
|
||||
THROTTLED_ACTIONS = %i[create].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :POST, 'repp/v1/domains/:domain_name/transfer'
|
||||
desc 'Transfer a specific domain'
|
||||
param :transfer, Hash, required: true, desc: 'Renew parameters' do
|
||||
|
|
|
@ -8,6 +8,9 @@ module Repp
|
|||
before_action :forward_registrar_id, only: %i[create update destroy]
|
||||
before_action :set_domain, only: %i[update]
|
||||
|
||||
THROTTLED_ACTIONS = %i[transfer_info transfer index create show update destroy].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :GET, '/repp/v1/domains'
|
||||
desc 'Get all existing domains'
|
||||
def index
|
||||
|
|
|
@ -4,6 +4,9 @@ module Repp
|
|||
class InvoicesController < BaseController # rubocop:disable Metrics/ClassLength
|
||||
load_and_authorize_resource
|
||||
|
||||
THROTTLED_ACTIONS = %i[download add_credit send_to_recipient cancel index show].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
api :get, '/repp/v1/invoices'
|
||||
desc 'Get all invoices'
|
||||
|
|
|
@ -3,8 +3,11 @@ module Repp
|
|||
module Registrar
|
||||
class AccreditationInfoController < BaseController
|
||||
if Feature.allow_accr_endspoints?
|
||||
api :GET, 'repp/v1/registrar/accreditation/get_info'
|
||||
desc 'check login user and return data'
|
||||
THROTTLED_ACTIONS = %i[index].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :GET, 'repp/v1/registrar/accreditation/get_info'
|
||||
desc 'check login user and return data'
|
||||
|
||||
def index
|
||||
login = current_user
|
||||
|
|
|
@ -6,6 +6,9 @@ module Repp
|
|||
skip_before_action :check_ip_restriction, only: :tara_callback
|
||||
skip_before_action :validate_client_certs, only: :tara_callback
|
||||
|
||||
THROTTLED_ACTIONS = %i[index tara_callback].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :GET, 'repp/v1/registrar/auth'
|
||||
desc 'check user auth info and return data'
|
||||
def index
|
||||
|
|
|
@ -4,6 +4,9 @@ module Repp
|
|||
class NameserversController < BaseController
|
||||
before_action :verify_nameserver_existance, only: %i[update]
|
||||
|
||||
THROTTLED_ACTIONS = %i[put].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :PUT, 'repp/v1/registrar/nameservers'
|
||||
desc 'bulk nameserver change'
|
||||
param :data, Hash, required: true, desc: 'Object holding nameserver changes' do
|
||||
|
|
|
@ -4,6 +4,9 @@ module Repp
|
|||
class NotificationsController < BaseController
|
||||
before_action :set_notification, only: %i[update show]
|
||||
|
||||
THROTTLED_ACTIONS = %i[all_notifications index show update].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :GET, '/repp/v1/registrar/notifications'
|
||||
desc 'Get the latest unread poll message'
|
||||
def index
|
||||
|
|
|
@ -2,6 +2,9 @@ module Repp
|
|||
module V1
|
||||
module Registrar
|
||||
class SummaryController < BaseController
|
||||
THROTTLED_ACTIONS = %i[index].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
api :GET, 'repp/v1/registrar/summary'
|
||||
desc 'check user summary info and return data'
|
||||
|
||||
|
|
55
app/controllers/repp/v1/registrar/xml_console_controller.rb
Normal file
55
app/controllers/repp/v1/registrar/xml_console_controller.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
module Repp
|
||||
module V1
|
||||
module Registrar
|
||||
class XmlConsoleController < BaseController
|
||||
include EppRequestable
|
||||
|
||||
THROTTLED_ACTIONS = %i[load_xml].freeze
|
||||
include Shunter::Integration::Throttle
|
||||
|
||||
PREFS = %w[domain-ee contact-ee eis epp-ee].freeze
|
||||
|
||||
SCHEMA_VERSIONS = {
|
||||
'epp-ee' => '1.0',
|
||||
'eis' => '1.0',
|
||||
'contact-ee' => '1.1',
|
||||
'default' => '1.2',
|
||||
}.freeze
|
||||
|
||||
def load_xml
|
||||
cl_trid = "#{current_user.username}-#{Time.zone.now.to_i}"
|
||||
obj = ActionController::Base.helpers.sanitize(params[:obj])
|
||||
epp_action = ActionController::Base.helpers.sanitize(params[:epp_action])
|
||||
xml_dir_path = Rails.root.join('app/views/epp/sample_requests').to_s
|
||||
xml = File.read("#{xml_dir_path}/#{obj}/#{epp_action}.xml")
|
||||
xml = prepare_payload(xml, cl_trid)
|
||||
|
||||
render_success(data: { xml: xml })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_payload(xml, cl_trid)
|
||||
PREFS.map do |pref|
|
||||
xml = load_schema_by_prefix(pref, xml)
|
||||
end
|
||||
|
||||
xml.gsub!('<clTRID>ABC-12345</clTRID>', "<clTRID>#{cl_trid}</clTRID>")
|
||||
xml
|
||||
end
|
||||
|
||||
def load_schema_by_prefix(pref, xml)
|
||||
version = version_by_prefix(pref)
|
||||
xml.gsub!("\"#{pref}\"",
|
||||
"\"#{Xsd::Schema.filename(for_prefix: pref.to_s, for_version: version)}\"")
|
||||
xml
|
||||
end
|
||||
|
||||
def version_by_prefix(pref)
|
||||
key = SCHEMA_VERSIONS.key?(pref) ? pref : 'default'
|
||||
SCHEMA_VERSIONS[key]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -90,6 +90,8 @@ module Repp
|
|||
|
||||
def calculate_market_share(domains_by_rar)
|
||||
sum = domains_by_rar.values.sum
|
||||
return domains_by_rar if sum.zero?
|
||||
|
||||
domains_by_rar.transform_values do |v|
|
||||
value = v.to_f / sum * 100.0
|
||||
value < 0.1 ? value.round(3) : value.round(1)
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
module Registrar::ApplicationHelper
|
||||
def env_style
|
||||
return '' if unstable_env.nil?
|
||||
"background-image: url(#{image_path("registrar/bg-#{unstable_env}.png")});"
|
||||
end
|
||||
end
|
|
@ -30,7 +30,7 @@ module Actions
|
|||
end
|
||||
|
||||
def check_for_same_contacts(contacts, contact_type)
|
||||
return unless contacts.uniq.count != contacts.count
|
||||
return if contacts.uniq.count == contacts.count
|
||||
|
||||
domain.add_epp_error('2306', contact_type, nil, %i[domain_contacts invalid])
|
||||
end
|
||||
|
@ -194,22 +194,33 @@ module Actions
|
|||
def contact_for_action(action:, method:, code:)
|
||||
contact = Epp::Contact.find_by(code: code)
|
||||
return contact if action == 'add' || !contact
|
||||
return domain.admin_domain_contacts.find_by(contact_id: contact.id) if method == 'admin'
|
||||
|
||||
domain.tech_domain_contacts.find_by(contact_id: contact.id)
|
||||
existing_contact(id: contact.id, admin: method == 'admin')
|
||||
end
|
||||
|
||||
def assign_contact(obj, add: false, admin: true, code:)
|
||||
def existing_contact(id:, admin: true)
|
||||
return domain.admin_domain_contacts.find_by(contact_id: id) if admin
|
||||
|
||||
domain.tech_domain_contacts.find_by(contact_id: id)
|
||||
end
|
||||
|
||||
def assign_contact(obj, code:, add: false, admin: true)
|
||||
if obj.blank?
|
||||
domain.add_epp_error('2303', 'contact', code, %i[domain_contacts not_found])
|
||||
elsif obj.try(:org?) && admin && add
|
||||
domain.add_epp_error('2306', 'contact', code,
|
||||
%i[domain_contacts admin_contact_can_be_only_private_person])
|
||||
else
|
||||
add ? { contact_id: obj.id, contact_code: obj.code } : { id: obj.id, _destroy: 1 }
|
||||
assigned_contact_hash(obj, add, admin)
|
||||
end
|
||||
end
|
||||
|
||||
def assigned_contact_hash(obj, add, admin)
|
||||
return if !existing_contact(id: obj.id, admin: admin).nil? && add
|
||||
|
||||
add ? { contact_id: obj.id, contact_code: obj.code } : { id: obj.id, _destroy: 1 }
|
||||
end
|
||||
|
||||
def assign_requested_statuses
|
||||
return unless params[:statuses]
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ module Actions
|
|||
def call
|
||||
result = check_email(email)
|
||||
save_result(result)
|
||||
filtering_old_failed_records(result)
|
||||
result.success ? log_success : log_failure(result)
|
||||
result.success
|
||||
end
|
||||
|
@ -26,27 +25,25 @@ module Actions
|
|||
Rails.env.test? && check_level == 'smtp' ? :mx : check_level.to_sym
|
||||
end
|
||||
|
||||
def filtering_old_failed_records(result)
|
||||
if @check_level == "mx" && !result.success && validation_eventable.validation_events.count > 3
|
||||
validation_eventable.validation_events.order!(created_at: :asc)
|
||||
while validation_eventable.validation_events.count > 3
|
||||
validation_eventable.validation_events.first.destroy
|
||||
end
|
||||
def filtering_old_failed_records(result, contact)
|
||||
ValidationEvent::INVALID_EVENTS_COUNT_BY_LEVEL.each do |level, limit|
|
||||
handle_failed_records(contact: contact, check_level: level, limit: limit, success: result.success)
|
||||
end
|
||||
end
|
||||
|
||||
if @check_level == "mx" && result.success && validation_eventable.validation_events.count > 1
|
||||
validation_eventable.validation_events.order!(created_at: :asc)
|
||||
while validation_eventable.validation_events.count > 1
|
||||
validation_eventable.validation_events.first.destroy
|
||||
def handle_failed_records(contact:, check_level:, limit:, success:)
|
||||
if @check_level.to_sym == check_level && !success && contact.validation_events.count > limit
|
||||
contact.validation_events.order!(created_at: :asc)
|
||||
while contact.validation_events.count > limit
|
||||
contact.validation_events.first.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if @check_level == "smtp" && validation_eventable.validation_events.count > 1
|
||||
validation_eventable.validation_events.order!(created_at: :asc)
|
||||
while validation_eventable.validation_events.count > 1
|
||||
validation_eventable.validation_events.first.destroy
|
||||
end
|
||||
end
|
||||
def filtering_old_records(contact:, success:)
|
||||
return unless success
|
||||
|
||||
contact.validation_events.destroy_all
|
||||
end
|
||||
|
||||
def save_result(result)
|
||||
|
@ -61,9 +58,14 @@ module Actions
|
|||
result.success = result_validation.present?
|
||||
end
|
||||
|
||||
result.configuration = nil
|
||||
|
||||
contacts.find_in_batches(batch_size: 500) do |contact_batches|
|
||||
contact_batches.each do |contact|
|
||||
# methods should be in this order!
|
||||
filtering_old_records(contact: contact, success: result.success)
|
||||
contact.validation_events.create(validation_event_attrs(result))
|
||||
filtering_old_failed_records(result, contact)
|
||||
end
|
||||
end
|
||||
rescue ActiveRecord::RecordNotSaved
|
||||
|
|
|
@ -6,8 +6,8 @@ class CheckForceDeleteLift < ApplicationJob
|
|||
.select { |d| d.registrant.need_to_lift_force_delete? }
|
||||
|
||||
handle_refresh_status(domains) if domains.present?
|
||||
domains = Domain.where("force_delete_data->'template_name' = ?", 'invalid_email')
|
||||
.where("force_delete_data->'force_delete_type' = ?", 'soft')
|
||||
domains = (domains + Domain.where("force_delete_data->'template_name' = ?", 'invalid_email')
|
||||
.where("force_delete_data->'force_delete_type' = ?", 'soft')).uniq
|
||||
|
||||
domains.each do |domain|
|
||||
Domains::ForceDeleteLift::Base.run(domain: domain)
|
||||
|
@ -39,15 +39,5 @@ class CheckForceDeleteLift < ApplicationJob
|
|||
domain.status_notes[DomainStatus::FORCE_DELETE].slice!(registrant.email_history)
|
||||
domain.status_notes[DomainStatus::FORCE_DELETE].lstrip!
|
||||
domain.save(validate: false)
|
||||
|
||||
notify_registrar(domain) unless domain.status_notes[DomainStatus::FORCE_DELETE].empty?
|
||||
end
|
||||
|
||||
def notify_registrar(domain)
|
||||
domain.registrar.notifications.create!(text: I18n.t('force_delete_auto_email',
|
||||
domain_name: domain.name,
|
||||
outzone_date: domain.outzone_date,
|
||||
purge_date: domain.purge_date,
|
||||
email: domain.status_notes[DomainStatus::FORCE_DELETE]))
|
||||
end
|
||||
end
|
||||
|
|
21
app/jobs/outzone_invalid_email_domains_job.rb
Normal file
21
app/jobs/outzone_invalid_email_domains_job.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
class OutzoneInvalidEmailDomainsJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
def perform
|
||||
domains = Domain.where("force_delete_data->'template_name' = ?", 'invalid_email')
|
||||
.where(outzone_at: nil)
|
||||
.where('Date(force_delete_start) <= ?', Time.zone.now)
|
||||
|
||||
domains.each do |domain|
|
||||
outzone(domain)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def outzone(domain)
|
||||
domain.outzone_at = domain.force_delete_start + Domain.expire_warning_period
|
||||
domain.delete_date = domain.outzone_at + Domain.redemption_grace_period
|
||||
domain.save
|
||||
end
|
||||
end
|
|
@ -2,8 +2,9 @@ class SendMonthlyInvoicesJob < ApplicationJob
|
|||
queue_as :default
|
||||
discard_on StandardError
|
||||
|
||||
def perform(dry: false, months_ago: 1)
|
||||
def perform(dry: false, months_ago: 1, overwrite: false)
|
||||
@dry = dry
|
||||
@overwrite = overwrite
|
||||
@month = Time.zone.now - months_ago.month
|
||||
@directo_data = []
|
||||
|
||||
|
@ -48,7 +49,7 @@ class SendMonthlyInvoicesJob < ApplicationJob
|
|||
|
||||
def find_or_init_monthly_invoices(invoices: [])
|
||||
Registrar.with_cash_accounts.find_each do |registrar|
|
||||
invoice = registrar.find_or_init_monthly_invoice(month: @month)
|
||||
invoice = registrar.find_or_init_monthly_invoice(month: @month, overwrite: @overwrite)
|
||||
invoices << invoice unless invoice.nil?
|
||||
end
|
||||
invoices
|
||||
|
|
36
app/lib/shunter.rb
Normal file
36
app/lib/shunter.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Shunter
|
||||
module_function
|
||||
|
||||
class ThrottleError < StandardError; end
|
||||
|
||||
BASE_LOGGER = ::Logger.new($stdout)
|
||||
ONE_MINUTE = 60
|
||||
ONE_HUNDRED_REQUESTS = 100
|
||||
|
||||
BASE_CONNECTION = {
|
||||
host: ENV['shunter_redis_host'] || 'redis',
|
||||
port: (ENV['shunter_redis_port'] || '6379').to_i,
|
||||
}.freeze
|
||||
|
||||
def default_error_message
|
||||
"Session limit exceeded. Current limit is #{default_threshold} in #{default_timespan} seconds"
|
||||
end
|
||||
|
||||
def default_timespan
|
||||
ENV['shunter_default_timespan'] || ONE_MINUTE
|
||||
end
|
||||
|
||||
def default_threshold
|
||||
ENV['shunter_default_threshold'] || ONE_HUNDRED_REQUESTS
|
||||
end
|
||||
|
||||
def default_adapter
|
||||
ENV['shunter_default_adapter'] || 'Shunter::Adapters::Redis'
|
||||
end
|
||||
|
||||
def feature_enabled?
|
||||
ActiveModel::Type::Boolean.new.cast(ENV['shunter_enabled'] || 'false')
|
||||
end
|
||||
end
|
31
app/lib/shunter/adapters/memory.rb
Normal file
31
app/lib/shunter/adapters/memory.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Shunter
|
||||
module Adapters
|
||||
class Memory
|
||||
attr_reader :store
|
||||
|
||||
def initialize(_options = {})
|
||||
@@store ||= {}
|
||||
end
|
||||
|
||||
def find_counter(key)
|
||||
@@store[key]
|
||||
end
|
||||
|
||||
def write_counter(key)
|
||||
@@store[key] = 1
|
||||
end
|
||||
|
||||
def increment_counter(key)
|
||||
@@store[key] += 1
|
||||
end
|
||||
|
||||
def clear!
|
||||
@@store = {}
|
||||
end
|
||||
|
||||
def expire_counter(_key, _timespan); end
|
||||
end
|
||||
end
|
||||
end
|
29
app/lib/shunter/adapters/redis.rb
Normal file
29
app/lib/shunter/adapters/redis.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Shunter
|
||||
module Adapters
|
||||
class Redis
|
||||
attr_reader :redis
|
||||
|
||||
def initialize(options)
|
||||
@redis = ::Redis.new(options)
|
||||
end
|
||||
|
||||
def find_counter(key)
|
||||
@redis.get(key)
|
||||
end
|
||||
|
||||
def write_counter(key)
|
||||
@redis.set(key, 1)
|
||||
end
|
||||
|
||||
def increment_counter(key)
|
||||
@redis.incr(key)
|
||||
end
|
||||
|
||||
def expire_counter(key, timespan)
|
||||
@redis.expire(key, timespan)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
63
app/lib/shunter/base.rb
Normal file
63
app/lib/shunter/base.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Shunter
|
||||
class Base
|
||||
attr_accessor :user_id, :adapter
|
||||
|
||||
def initialize(options = {})
|
||||
@user_id = options[:user_id]
|
||||
adapter_klass = Shunter.default_adapter.constantize
|
||||
@adapter = adapter_klass.new(options[:conn_options])
|
||||
end
|
||||
|
||||
def user_key
|
||||
"counting_#{@user_id}"
|
||||
end
|
||||
|
||||
def blocked_user_key
|
||||
"blocked_#{@user_id}"
|
||||
end
|
||||
|
||||
def throttle
|
||||
return false if blocked?
|
||||
|
||||
valid_counter?
|
||||
end
|
||||
|
||||
def blocked?
|
||||
adapter.find_counter(blocked_user_key).present?
|
||||
end
|
||||
|
||||
def valid_counter?
|
||||
if adapter.find_counter(user_key)
|
||||
number_of_requests = adapter.increment_counter(user_key)
|
||||
if number_of_requests > allowed_requests.to_i
|
||||
init_counter(blocked_user_key)
|
||||
return false
|
||||
end
|
||||
else
|
||||
init_counter(user_key)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_counter(key)
|
||||
adapter.write_counter(key)
|
||||
adapter.expire_counter(key, timespan)
|
||||
end
|
||||
|
||||
def allowed_requests
|
||||
Shunter.default_threshold
|
||||
end
|
||||
|
||||
def timespan
|
||||
Shunter.default_timespan
|
||||
end
|
||||
|
||||
def logger
|
||||
Shunter::BASE_LOGGER
|
||||
end
|
||||
end
|
||||
end
|
44
app/lib/shunter/integration/throttle.rb
Normal file
44
app/lib/shunter/integration/throttle.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'active_support/concern'
|
||||
|
||||
module Shunter
|
||||
module Integration
|
||||
module Throttle
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do |base|
|
||||
actions = base.const_defined?('THROTTLED_ACTIONS') && base.const_get('THROTTLED_ACTIONS')
|
||||
return if actions.blank?
|
||||
|
||||
around_action :throttle, only: actions
|
||||
|
||||
def throttle
|
||||
if throttled_user.blank? || !Shunter.feature_enabled?
|
||||
yield if block_given?
|
||||
return
|
||||
end
|
||||
|
||||
user_id = throttled_user.id
|
||||
|
||||
shunter = Shunter::Base.new(conn_options: connection_options, user_id: user_id)
|
||||
if shunter.throttle
|
||||
logger.info "Request from #{throttled_user.class}/#{throttled_user.id} is coming through throttling"
|
||||
yield if block_given?
|
||||
else
|
||||
logger.info "Too many requests from #{throttled_user.class}/#{throttled_user.id}." unless Rails.env.test?
|
||||
raise Shunter::ThrottleError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def connection_options
|
||||
Shunter::BASE_CONNECTION
|
||||
end
|
||||
|
||||
def logger
|
||||
Shunter::BASE_LOGGER
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -31,12 +31,6 @@ class Ability
|
|||
end
|
||||
|
||||
def epp # Registrar/api_user dynamic role
|
||||
if @user.registrar.api_ip_white?(@ip)
|
||||
can :manage, Depp::Contact
|
||||
can :manage, :xml_console
|
||||
can :manage, Depp::Domain
|
||||
end
|
||||
|
||||
can :manage, Account
|
||||
|
||||
# Poll
|
||||
|
@ -122,7 +116,6 @@ class Ability
|
|||
customer_service
|
||||
can :manage, :registrant_domains
|
||||
can :manage, :registrant_whois
|
||||
can :manage, Depp::Domain
|
||||
can :manage, Domain
|
||||
end
|
||||
|
||||
|
|
|
@ -37,6 +37,24 @@ class Auction < ApplicationRecord
|
|||
find_by(domain: domain_name.to_s, status: PENDING_STATUSES)
|
||||
end
|
||||
|
||||
def self.domain_exists_in_blocked_disputed_and_registered?(domain_name)
|
||||
Domain.exists?(name: domain_name) ||
|
||||
BlockedDomain.exists?(name: domain_name) ||
|
||||
Dispute.exists?(domain_name: domain_name) ||
|
||||
exception_for_registred_or_unbided_existed_auctions(domain_name)
|
||||
end
|
||||
|
||||
def self.exception_for_registred_or_unbided_existed_auctions(domain_name)
|
||||
return false unless Auction.exists?(domain: domain_name)
|
||||
|
||||
auctions = Auction.where(domain: domain_name).order(:created_at)
|
||||
last_record = auctions.last
|
||||
|
||||
return false if last_record.domain_registered? || last_record.no_bids?
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def start
|
||||
self.status = self.class.statuses[:started]
|
||||
save!
|
||||
|
|
|
@ -59,8 +59,9 @@ module Invoice::BookKeeping
|
|||
|
||||
duration.times do |dur|
|
||||
single_item_dup = single_item.dup
|
||||
single_item_dup['start_date'] = (issue_date + dur.year).end_of_month.strftime('%Y-%m-%d')
|
||||
single_item_dup['end_date'] = (issue_date + (dur + 1).year).end_of_month.strftime('%Y-%m-%d')
|
||||
date = (issue_date + dur.year).end_of_month.strftime('%Y-%m-%d')
|
||||
single_item_dup['start_date'] = date
|
||||
single_item_dup['end_date'] = date
|
||||
single_item_dup['price'] = (item['price'].to_f / duration).round(2)
|
||||
lines << single_item_dup
|
||||
end
|
||||
|
|
|
@ -38,15 +38,26 @@ module Registrar::BookKeeping
|
|||
lines.as_json
|
||||
end
|
||||
|
||||
def find_or_init_monthly_invoice(month:)
|
||||
def find_or_init_monthly_invoice(month:, overwrite:)
|
||||
invoice = invoices.find_by(monthly_invoice: true, issue_date: month.end_of_month.to_date,
|
||||
cancelled_at: nil)
|
||||
return invoice if invoice
|
||||
return invoice if invoice && !overwrite
|
||||
|
||||
summary = monthly_summary(month: month)
|
||||
return unless summary
|
||||
|
||||
init_monthly_invoice(summary)
|
||||
new_invoice = init_monthly_invoice(summary)
|
||||
return overwrite_invoice(invoice, new_invoice) if invoice && overwrite
|
||||
|
||||
new_invoice
|
||||
end
|
||||
|
||||
def overwrite_invoice(original_invoice, new_invoice)
|
||||
params_to_scrub = %i[created_at updated_at id number sent_at
|
||||
e_invoice_sent_at in_directo cancelled_at payment_link]
|
||||
attrs = new_invoice.attributes.with_indifferent_access.except(*params_to_scrub)
|
||||
original_invoice.update(attrs)
|
||||
original_invoice
|
||||
end
|
||||
|
||||
def title_for_summary(date)
|
||||
|
|
|
@ -32,27 +32,40 @@ module Zone::WhoisQueryable
|
|||
# Take note - since this concern only used to zone whois queries, dnssec keys are set to
|
||||
# empty array
|
||||
def domain_vars
|
||||
{ disclaimer: Setting.registry_whois_disclaimer, name: origin,
|
||||
{
|
||||
disclaimer: Setting.registry_whois_disclaimer, name: origin,
|
||||
registered: created_at.try(:to_s, :iso8601), status: ['ok (paid and in zone)'],
|
||||
changed: updated_at.try(:to_s, :iso8601), email: Setting.registry_email,
|
||||
admin_contacts: [contact_vars], tech_contacts: [contact_vars],
|
||||
nameservers: nameserver_vars, dnssec_keys: [], dnssec_changed: nil }
|
||||
nameservers: nameserver_vars, dnssec_keys: [],
|
||||
dnssec_changed: nil
|
||||
}
|
||||
end
|
||||
|
||||
def registrar_vars
|
||||
{ registrar: Setting.registry_juridical_name, registrar_website: Setting.registry_url,
|
||||
registrar_phone: Setting.registry_phone }
|
||||
{
|
||||
registrar: Setting.registry_juridical_name,
|
||||
registrar_website: Setting.registry_url,
|
||||
registrar_phone: Setting.registry_phone,
|
||||
}
|
||||
end
|
||||
|
||||
def registrant_vars
|
||||
{ registrant: Setting.registry_juridical_name, registrant_reg_no: Setting.registry_reg_no,
|
||||
registrant_ident_country_code: Setting.registry_country_code, registrant_kind: 'org',
|
||||
registrant_disclosed_attributes: %w[name email] }
|
||||
{
|
||||
registrant: Setting.registry_juridical_name,
|
||||
registrant_reg_no: Setting.registry_reg_no,
|
||||
registrant_ident_country_code: Setting.registry_country_code,
|
||||
registrant_kind: 'org',
|
||||
registrant_disclosed_attributes: %w[name email phone],
|
||||
}
|
||||
end
|
||||
|
||||
def contact_vars
|
||||
{ name: Setting.registry_invoice_contact, email: Setting.registry_email,
|
||||
disclosed_attributes: %w[name email] }
|
||||
{
|
||||
name: Setting.registry_invoice_contact,
|
||||
email: Setting.registry_email,
|
||||
disclosed_attributes: %w[name email],
|
||||
}
|
||||
end
|
||||
|
||||
def nameserver_vars
|
||||
|
|
|
@ -64,6 +64,8 @@ class Contact < ApplicationRecord
|
|||
|
||||
validate :validate_html
|
||||
validate :validate_country_code, if: -> { self.class.address_processing? }
|
||||
validates :registrant_publishable, inclusion: { in: [true, false] }, if: -> { registrant? }
|
||||
# validates :registrant_publishable, inclusion: { in: [false] }, unless: -> { registrant? }
|
||||
|
||||
after_initialize do
|
||||
self.status_notes = {} if status_notes.nil?
|
||||
|
@ -145,6 +147,19 @@ class Contact < ApplicationRecord
|
|||
# "clientDeleteProhibited" or "serverDeleteProhibited" status.
|
||||
PENDING_DELETE = 'pendingDelete'.freeze
|
||||
|
||||
DISCLOSE_ATTRIBUTES = %w[
|
||||
name
|
||||
email
|
||||
phone
|
||||
registrant_publishable
|
||||
address
|
||||
fax
|
||||
].freeze
|
||||
|
||||
OPEN_LEGAL_ATTRIBUTES = %w[
|
||||
phone
|
||||
].freeze
|
||||
|
||||
STATUSES = [
|
||||
CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED,
|
||||
CLIENT_TRANSFER_PROHIBITED,
|
||||
|
|
|
@ -15,15 +15,6 @@ class ContactRequest < ApplicationRecord
|
|||
attr_readonly :secret,
|
||||
:valid_to
|
||||
|
||||
def self.save_record(params)
|
||||
contact_request = new(params)
|
||||
contact_request.secret = create_random_secret
|
||||
contact_request.valid_to = set_valid_to_24_hours_from_now
|
||||
contact_request.status = STATUS_NEW
|
||||
contact_request.save!
|
||||
contact_request
|
||||
end
|
||||
|
||||
def update_record(params)
|
||||
self.status = params['status'] if params['status']
|
||||
self.ip_address = params['ip'] if params['ip']
|
||||
|
@ -31,11 +22,22 @@ class ContactRequest < ApplicationRecord
|
|||
save!
|
||||
end
|
||||
|
||||
def self.create_random_secret
|
||||
SecureRandom.hex(64)
|
||||
end
|
||||
class << self
|
||||
def save_record(params)
|
||||
contact_request = new(params)
|
||||
contact_request.secret = create_random_secret
|
||||
contact_request.valid_to = set_valid_to_24_hours_from_now
|
||||
contact_request.status = STATUS_NEW
|
||||
contact_request.save!
|
||||
contact_request
|
||||
end
|
||||
|
||||
def self.set_valid_to_24_hours_from_now
|
||||
(Time.zone.now + 24.hours)
|
||||
def create_random_secret
|
||||
SecureRandom.hex(64)
|
||||
end
|
||||
|
||||
def set_valid_to_24_hours_from_now
|
||||
(Time.zone.now + 24.hours)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,318 +0,0 @@
|
|||
module Depp
|
||||
class Contact
|
||||
include ActiveModel::Model
|
||||
|
||||
attr_accessor :id, :name, :email, :phone, :org_name,
|
||||
:ident, :ident_type, :ident_country_code,
|
||||
:street, :city, :zip, :state, :country_code,
|
||||
:password, :legal_document, :statuses, :code,
|
||||
:email_history
|
||||
|
||||
DISABLED = 'Disabled'
|
||||
DISCLOSURE_TYPES = [DISABLED, '1', '0']
|
||||
TYPES = %w( org priv birthday )
|
||||
SELECTION_TYPES = [
|
||||
['Business code', 'org'],
|
||||
['Personal identification code', 'priv'],
|
||||
['Birthday', 'birthday']
|
||||
]
|
||||
|
||||
validates :phone, e164: true, phone: true
|
||||
|
||||
class << self
|
||||
attr_reader :epp_xml, :user
|
||||
|
||||
def new_from_params(params)
|
||||
new(
|
||||
id: params[:code],
|
||||
code: params[:code],
|
||||
email: params[:email],
|
||||
phone: params[:phone],
|
||||
ident: params[:ident],
|
||||
ident_type: params[:ident_type],
|
||||
ident_country_code: params[:ident_country_code],
|
||||
|
||||
# postalInfo
|
||||
name: params[:name],
|
||||
org_name: params[:org_name],
|
||||
|
||||
# address
|
||||
street: params[:street],
|
||||
city: params[:city],
|
||||
zip: params[:zip],
|
||||
state: params[:state],
|
||||
country_code: params[:country_code]
|
||||
)
|
||||
end
|
||||
|
||||
def find_by_id(id)
|
||||
data = info_xml(id)
|
||||
|
||||
res = data.css('epp response resData infData')
|
||||
ext = data.css('epp response extension')
|
||||
new(
|
||||
id: res.css('id').text,
|
||||
code: res.css('id').text,
|
||||
email: res.css('email').text,
|
||||
phone: res.css('voice').text,
|
||||
ident: ext.css('ident').text,
|
||||
ident_type: ext.css('ident').first.try(:attributes).try(:[], 'type').try(:value),
|
||||
ident_country_code: ext.css('ident').first.try(:attributes).try(:[], 'cc').try(:value),
|
||||
|
||||
# postalInfo
|
||||
name: res.css('postalInfo name').text,
|
||||
org_name: res.css('postalInfo org').text,
|
||||
|
||||
# address
|
||||
street: res.css('postalInfo addr street').text,
|
||||
city: res.css('postalInfo addr city').text,
|
||||
zip: res.css('postalInfo addr pc').text,
|
||||
state: res.css('postalInfo addr sp').text,
|
||||
country_code: res.css('postalInfo addr cc').text,
|
||||
|
||||
# authInfo
|
||||
password: res.css('authInfo pw').text,
|
||||
|
||||
# statuses
|
||||
statuses: data.css('status').map { |s| [s['s'], s.text] }
|
||||
)
|
||||
end
|
||||
|
||||
def user=(user)
|
||||
@user = user
|
||||
@epp_xml = EppXml::Contact.new(cl_trid_prefix: user.tag, schema_prefix: 'contact-ee',
|
||||
schema_version: '1.1')
|
||||
end
|
||||
|
||||
def info_xml(id, password = nil)
|
||||
xml = epp_xml.info(
|
||||
id: { value: id },
|
||||
authInfo: { pw: { value: password } }
|
||||
)
|
||||
user.request(xml)
|
||||
end
|
||||
|
||||
def construct_check_hash_from_data(data)
|
||||
res = data.css('epp response resData chkData cd')
|
||||
@contacts = []
|
||||
res.each do |_r|
|
||||
id = res.css('id').try(:text)
|
||||
reason = res.css('reason').present? ? res.css('reason').text : I18n.t(:available)
|
||||
@contacts << { id: id, reason: reason }
|
||||
end
|
||||
@contacts
|
||||
end
|
||||
|
||||
def contact_id_from_xml(data)
|
||||
id = data.css('epp response resData creData id').text
|
||||
id.blank? ? nil : id
|
||||
end
|
||||
|
||||
def construct_create_disclosure_xml(cph, flag)
|
||||
xml = { disclose: {} }
|
||||
cph.each do |k, v|
|
||||
xml[:disclose][k] = {}
|
||||
xml[:disclose][k][:value] = v
|
||||
end
|
||||
xml[:disclose][:attrs] = {}
|
||||
xml[:disclose][:attrs][:flag] = flag
|
||||
xml.with_indifferent_access
|
||||
end
|
||||
|
||||
# cpd = contact_params[:disclose]
|
||||
def extract_disclosure_hash(cpd)
|
||||
return {} unless cpd
|
||||
|
||||
cpd.delete_if { |k, v| v if v != '1' && k == 'flag' }
|
||||
end
|
||||
|
||||
def extract_info_disclosure(data)
|
||||
hash = {}
|
||||
data.css('disclose').each do |d|
|
||||
flag = d.attributes['flag'].value
|
||||
next unless flag
|
||||
hash[flag] = {}
|
||||
d.children.each do |c|
|
||||
hash[flag][c.name] = flag if %w( name email fax voice addr org_name ).include?(c.name)
|
||||
end
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
def type_string(type_code)
|
||||
return '' if type_code.blank?
|
||||
t = SELECTION_TYPES.select { |tp| tp.second == type_code }
|
||||
t.try(:first).try(:first)
|
||||
end
|
||||
end
|
||||
|
||||
def save
|
||||
return false unless valid?
|
||||
|
||||
hash = {
|
||||
id: { value: code },
|
||||
postalInfo: {
|
||||
name: { value: name },
|
||||
org: { value: org_name },
|
||||
},
|
||||
voice: { value: phone },
|
||||
email: { value: email }
|
||||
}
|
||||
|
||||
if ::Contact.address_processing?
|
||||
hash[:postalInfo][:addr] = {
|
||||
street: { value: street },
|
||||
city: { value: city },
|
||||
sp: { value: state },
|
||||
pc: { value: zip },
|
||||
cc: { value: country_code },
|
||||
}
|
||||
end
|
||||
|
||||
hash[:id] = nil if code.blank?
|
||||
create_xml = Depp::Contact.epp_xml.create(hash, extension_xml(:create))
|
||||
data = Depp::Contact.user.request(create_xml)
|
||||
self.id = data.css('id').text
|
||||
handle_errors(data)
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def update_attributes(params)
|
||||
return false unless valid?
|
||||
|
||||
self.ident_country_code = params[:ident_country_code]
|
||||
self.ident_type = params[:ident_type]
|
||||
self.ident = params[:ident]
|
||||
|
||||
self.name = params[:name]
|
||||
self.email = params[:email]
|
||||
self.phone = params[:phone]
|
||||
|
||||
self.org_name = params[:org_name]
|
||||
|
||||
if ::Contact.address_processing?
|
||||
self.street = params[:street]
|
||||
self.city = params[:city]
|
||||
self.zip = params[:zip]
|
||||
self.state = params[:state]
|
||||
self.country_code = params[:country_code]
|
||||
end
|
||||
|
||||
attributes = {
|
||||
id: { value: id },
|
||||
chg: {
|
||||
postalInfo: {
|
||||
name: { value: name },
|
||||
org: { value: org_name },
|
||||
},
|
||||
voice: { value: phone },
|
||||
email: { value: email },
|
||||
authInfo: {
|
||||
pw: { value: password }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ::Contact.address_processing?
|
||||
attributes[:chg][:postalInfo][:addr] = {
|
||||
street: { value: street },
|
||||
city: { value: city },
|
||||
sp: { value: state },
|
||||
pc: { value: zip },
|
||||
cc: { value: country_code }
|
||||
}
|
||||
end
|
||||
|
||||
update_xml = Depp::Contact.epp_xml.update(attributes, extension_xml(:update))
|
||||
data = Depp::Contact.user.request(update_xml)
|
||||
handle_errors(data)
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
def delete
|
||||
delete_xml = Contact.epp_xml.delete(
|
||||
{
|
||||
id: { value: id },
|
||||
authInfo: { pw: { value: password } }
|
||||
},
|
||||
extension_xml(:delete)
|
||||
)
|
||||
data = Depp::Contact.user.request(delete_xml)
|
||||
handle_errors(data)
|
||||
end
|
||||
|
||||
def extension_xml(action)
|
||||
xml = { _anonymus: [] }
|
||||
|
||||
case action
|
||||
when :create
|
||||
ident = ident_xml[:_anonymus].try(:first)
|
||||
when :update
|
||||
# detect if any ident has changed, nb! ident and self.ident is not always same
|
||||
unless ident == self.ident && ident == ident_type && ident_country_code == self.ident_country_code
|
||||
ident = ident_xml[:_anonymus].try(:first)
|
||||
end
|
||||
end
|
||||
|
||||
legal = legal_document_xml[:_anonymus].try(:first)
|
||||
xml[:_anonymus] << ident if ident.present?
|
||||
xml[:_anonymus] << legal if legal.present?
|
||||
xml
|
||||
end
|
||||
|
||||
def ident_xml
|
||||
{
|
||||
_anonymus: [
|
||||
ident: { value: ident, attrs: { type: ident_type, cc: ident_country_code } }
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def legal_document_xml
|
||||
return {} if legal_document.blank?
|
||||
|
||||
type = legal_document.original_filename.split('.').last.downcase
|
||||
{
|
||||
_anonymus: [
|
||||
legalDocument: { value: Base64.encode64(legal_document.read), attrs: { type: type } }
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def check(id)
|
||||
xml = epp_xml.check(id: { value: id })
|
||||
current_user.request(xml)
|
||||
end
|
||||
|
||||
def country_name
|
||||
Country.new(country_code) || 'No access'
|
||||
end
|
||||
|
||||
def org?
|
||||
ident_type == 'org'
|
||||
end
|
||||
|
||||
def priv?
|
||||
ident_type == 'priv'
|
||||
end
|
||||
|
||||
def persisted?
|
||||
id.present?
|
||||
end
|
||||
|
||||
def handle_errors(data)
|
||||
data.css('result').each do |x|
|
||||
success_codes = %(1000, 1300, 1301)
|
||||
next if success_codes.include?(x['code'])
|
||||
|
||||
message = "#{x.css('msg').text} #{x.css('value').text}"
|
||||
attr = message.split('[').last.strip.sub(']', '') if message.include?('[')
|
||||
attr = :base if attr.nil?
|
||||
attr = 'phone' if attr == 'voice'
|
||||
attr = 'zip' if attr == 'pc'
|
||||
errors.add(attr, message)
|
||||
end
|
||||
errors.blank?
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
module Depp
|
||||
class Dnskey
|
||||
FLAGS = [
|
||||
['0 - not for DNSSEC validation', 0],
|
||||
['256 - ZSK', 256],
|
||||
['257 - KSK', 257]
|
||||
]
|
||||
|
||||
ALGORITHMS = [
|
||||
['3 - DSA/SHA-1', 3],
|
||||
['5 - RSA/SHA-1', 5],
|
||||
['6 - DSA-NSEC3-SHA1', 6],
|
||||
['7 - RSASHA1-NSEC3-SHA1', 7],
|
||||
['8 - RSA/SHA-256', 8],
|
||||
['10 - RSA/SHA-512', 10],
|
||||
['13 - ECDSA Curve P-256 with SHA-256', 13],
|
||||
['14 - ECDSA Curve P-384 with SHA-384', 14],
|
||||
['15 - Ed25519', 15],
|
||||
['16 - Ed448', 16],
|
||||
].freeze
|
||||
|
||||
PROTOCOLS = [3]
|
||||
|
||||
DS_DIGEST_TYPES = [1, 2]
|
||||
end
|
||||
end
|
|
@ -1,351 +0,0 @@
|
|||
module Depp
|
||||
class Domain
|
||||
include ActiveModel::Conversion
|
||||
include RemoveHold
|
||||
extend ActiveModel::Naming
|
||||
|
||||
attr_accessor :name, :current_user, :epp_xml
|
||||
|
||||
STATUSES = %w[
|
||||
clientDeleteProhibited
|
||||
clientHold
|
||||
clientRenewProhibited
|
||||
clientTransferProhibited
|
||||
clientUpdateProhibited
|
||||
].freeze
|
||||
|
||||
PERIODS = [
|
||||
['3 months', '3m'],
|
||||
['6 months', '6m'],
|
||||
['9 months', '9m'],
|
||||
['1 year', '1y'],
|
||||
['2 years', '2y'],
|
||||
['3 years', '3y'],
|
||||
['4 years', '4y'],
|
||||
['5 years', '5y'],
|
||||
['6 years', '6y'],
|
||||
['7 years', '7y'],
|
||||
['8 years', '8y'],
|
||||
['9 years', '9y'],
|
||||
['10 years', '10y'],
|
||||
].freeze
|
||||
|
||||
def initialize(args = {})
|
||||
self.current_user = args[:current_user]
|
||||
self.epp_xml = EppXml::Domain.new(
|
||||
cl_trid_prefix: current_user.tag,
|
||||
schema_prefix: 'domain-ee',
|
||||
schema_version: '1.1'
|
||||
)
|
||||
end
|
||||
|
||||
def info(domain_name)
|
||||
xml = epp_xml.info(name: { value: domain_name })
|
||||
current_user.request(xml)
|
||||
end
|
||||
|
||||
def check(domain_name)
|
||||
xml = epp_xml.check(
|
||||
_anonymus: [
|
||||
name: { value: domain_name }
|
||||
]
|
||||
)
|
||||
current_user.request(xml)
|
||||
end
|
||||
|
||||
def create(domain_params)
|
||||
dns_hash = {}
|
||||
keys = Domain.create_dnskeys_hash(domain_params)
|
||||
dns_hash[:_anonymus] = keys if keys.any?
|
||||
|
||||
period = domain_params[:period].to_i.to_s
|
||||
period_unit = domain_params[:period][-1].to_s
|
||||
|
||||
xml = if domain_params[:nameservers_attributes]
|
||||
.select { |_key, value| value['hostname'].present? }.any?
|
||||
epp_xml.create({
|
||||
name: { value: domain_params[:name] },
|
||||
period: { value: period, attrs: { unit: period_unit } },
|
||||
ns: Domain.create_nameservers_hash(domain_params),
|
||||
registrant: { value: domain_params[:registrant] },
|
||||
_anonymus: Domain.create_contacts_hash(domain_params)
|
||||
}, dns_hash, Domain.construct_custom_params_hash(domain_params))
|
||||
else
|
||||
epp_xml.create({
|
||||
name: { value: domain_params[:name] },
|
||||
period: { value: period, attrs: { unit: period_unit } },
|
||||
registrant: { value: domain_params[:registrant] },
|
||||
_anonymus: Domain.create_contacts_hash(domain_params)
|
||||
}, dns_hash, Domain.construct_custom_params_hash(domain_params))
|
||||
end
|
||||
|
||||
current_user.request(xml)
|
||||
end
|
||||
|
||||
def update(domain_params)
|
||||
data = current_user.request(epp_xml.info(name: { value: domain_params[:name] }))
|
||||
old_domain_params = Depp::Domain.construct_params_from_server_data(data)
|
||||
|
||||
xml = epp_xml.update(
|
||||
Depp::Domain.construct_edit_hash(domain_params, old_domain_params),
|
||||
Depp::Domain.construct_ext_edit_hash(domain_params, old_domain_params),
|
||||
Depp::Domain.construct_custom_params_hash(domain_params)
|
||||
)
|
||||
|
||||
current_user.request(xml)
|
||||
end
|
||||
|
||||
def delete(domain_params)
|
||||
xml = epp_xml.delete({
|
||||
name: { value: domain_params[:name] },
|
||||
},
|
||||
Depp::Domain.construct_custom_params_hash(domain_params),
|
||||
(domain_params[:verified].present? && 'yes'))
|
||||
|
||||
current_user.request(xml)
|
||||
end
|
||||
|
||||
def renew(params)
|
||||
period = params[:period].to_i.to_s
|
||||
period_unit = params[:period][-1].to_s
|
||||
|
||||
current_user.request(epp_xml.renew(name: { value: params[:domain_name] },
|
||||
curExpDate: { value: params[:cur_exp_date] },
|
||||
period: { value: period, attrs: { unit: period_unit } }))
|
||||
end
|
||||
|
||||
def transfer(params)
|
||||
op = params[:request] ? 'request' : nil
|
||||
op = params[:query] ? 'query' : op
|
||||
op = params[:approve] ? 'approve' : op
|
||||
op = params[:reject] ? 'reject' : op
|
||||
|
||||
current_user.request(epp_xml.transfer({
|
||||
name: { value: params[:domain_name] },
|
||||
authInfo: { pw: { value: params[:transfer_code] } }
|
||||
}, op, Domain.construct_custom_params_hash(params)))
|
||||
end
|
||||
|
||||
def confirm_transfer(domain_params)
|
||||
data = current_user.request(epp_xml.info(name: { value: domain_params[:name] }))
|
||||
pw = data.css('pw').text
|
||||
|
||||
xml = epp_xml.transfer({
|
||||
name: { value: domain_params[:name] },
|
||||
authInfo: { pw: { value: pw } }
|
||||
}, 'approve')
|
||||
|
||||
current_user.request(xml)
|
||||
end
|
||||
|
||||
class << self
|
||||
def default_period
|
||||
'1y'
|
||||
end
|
||||
|
||||
def default_params
|
||||
ret = {}
|
||||
|
||||
ret[:contacts_attributes] ||= {}
|
||||
ENV['default_admin_contacts_count'].to_i.times do |i|
|
||||
ret[:contacts_attributes][i] = { code: '', type: 'admin' }
|
||||
end
|
||||
|
||||
ret[:nameservers_attributes] ||= {}
|
||||
ENV['default_nameservers_count'].to_i.times do |i|
|
||||
ret[:nameservers_attributes][i] = {}
|
||||
end
|
||||
|
||||
ret[:dnskeys_attributes] ||= { 0 => {} }
|
||||
ret[:statuses_attributes] ||= { 0 => {} }
|
||||
ret.with_indifferent_access
|
||||
end
|
||||
|
||||
def construct_params_from_server_data(data)
|
||||
ret = default_params
|
||||
ret[:name] = data.css('name').text
|
||||
ret[:registrant] = data.css('registrant').text
|
||||
|
||||
data.css('contact').each_with_index do |x, i|
|
||||
ret[:contacts_attributes][i] = { code: x.text, type: x['type'] }
|
||||
end
|
||||
|
||||
data.css('hostAttr').each_with_index do |x, i|
|
||||
ret[:nameservers_attributes][i] = {
|
||||
hostname: x.css('hostName').text,
|
||||
ipv4: Array(x.css('hostAddr[ip="v4"]')).map(&:text).join(','),
|
||||
ipv6: Array(x.css('hostAddr[ip="v6"]')).map(&:text).join(',')
|
||||
}
|
||||
end
|
||||
|
||||
data.css('keyData').each_with_index do |x, i|
|
||||
ret[:dnskeys_attributes][i] = {
|
||||
flags: x.css('flags').text,
|
||||
protocol: x.css('protocol').text,
|
||||
alg: x.css('alg').text,
|
||||
public_key: x.css('pubKey').text,
|
||||
ds_key_tag: x.css('keyTag').first.try(:text),
|
||||
ds_alg: x.css('alg').first.try(:text),
|
||||
ds_digest_type: x.css('digestType').first.try(:text),
|
||||
ds_digest: x.css('digest').first.try(:text)
|
||||
}
|
||||
end
|
||||
|
||||
data.css('status').each_with_index do |x, i|
|
||||
next unless STATUSES.include?(x['s'])
|
||||
|
||||
ret[:statuses_attributes][i] = {
|
||||
code: x['s'],
|
||||
description: x.text
|
||||
}
|
||||
end
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
def construct_custom_params_hash(domain_params)
|
||||
custom_params = { _anonymus: [] }
|
||||
if domain_params[:legal_document].present?
|
||||
type = domain_params[:legal_document].original_filename.split('.').last.downcase
|
||||
custom_params[:_anonymus] << {
|
||||
legalDocument: { value: Base64.encode64(domain_params[:legal_document].read), attrs: { type: type } }
|
||||
}
|
||||
end
|
||||
|
||||
if domain_params[:reserved_pw].present?
|
||||
custom_params[:_anonymus] << { reserved: { pw: { value: domain_params[:reserved_pw] } } }
|
||||
end
|
||||
|
||||
custom_params
|
||||
end
|
||||
|
||||
def construct_edit_hash(domain_params, old_domain_params)
|
||||
contacts = array_difference(create_contacts_hash(domain_params), create_contacts_hash(old_domain_params))
|
||||
add_anon = contacts
|
||||
|
||||
contacts = array_difference(create_contacts_hash(old_domain_params), create_contacts_hash(domain_params))
|
||||
rem_anon = contacts
|
||||
|
||||
add_arr = []
|
||||
add_ns = create_nameservers_hash(domain_params) - create_nameservers_hash(old_domain_params)
|
||||
add_arr << { ns: add_ns } if add_ns.any?
|
||||
add_arr << { _anonymus: add_anon } if add_anon.any?
|
||||
|
||||
rem_arr = []
|
||||
rem_ns = create_nameservers_hash(old_domain_params) - create_nameservers_hash(domain_params)
|
||||
rem_arr << { ns: rem_ns } if rem_ns.any?
|
||||
rem_arr << { _anonymus: rem_anon } if rem_anon.any?
|
||||
|
||||
if domain_params[:registrant] != old_domain_params[:registrant]
|
||||
chg = [{ registrant: { value: domain_params[:registrant] } }] unless domain_params[:verified].present?
|
||||
if domain_params[:verified]
|
||||
chg = [{ registrant: { value: domain_params[:registrant], attrs: { verified: 'yes' } } }]
|
||||
end
|
||||
end
|
||||
|
||||
add_arr = nil if add_arr.none?
|
||||
rem_arr = nil if rem_arr.none?
|
||||
|
||||
{
|
||||
name: { value: domain_params[:name] },
|
||||
add: add_arr,
|
||||
rem: rem_arr,
|
||||
chg: chg
|
||||
}
|
||||
end
|
||||
|
||||
def construct_ext_edit_hash(domain_params, old_domain_params)
|
||||
rem_keys = create_dnskeys_hash(old_domain_params) - create_dnskeys_hash(domain_params)
|
||||
add_keys = create_dnskeys_hash(domain_params) - create_dnskeys_hash(old_domain_params)
|
||||
hash = {}
|
||||
hash[:rem] = rem_keys if rem_keys.any?
|
||||
hash[:add] = add_keys if add_keys.any?
|
||||
hash
|
||||
end
|
||||
|
||||
def create_nameservers_hash(domain_params)
|
||||
ret = []
|
||||
domain_params[:nameservers_attributes].each do |_k, v|
|
||||
next if v['hostname'].blank?
|
||||
|
||||
host_attr = []
|
||||
host_attr << { hostName: { value: v['hostname'] } }
|
||||
if v['ipv4'].present?
|
||||
v['ipv4'].to_s.split(',').each do |ip|
|
||||
host_attr << { hostAddr: { value: ip, attrs: { ip: 'v4' } } }
|
||||
end
|
||||
end
|
||||
|
||||
if v['ipv6'].present?
|
||||
v['ipv6'].to_s.split(',').each do |ip|
|
||||
host_attr << { hostAddr: { value: ip, attrs: { ip: 'v6' } } }
|
||||
end
|
||||
end
|
||||
|
||||
ret << { hostAttr: host_attr }
|
||||
end
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
def create_contacts_hash(domain_params)
|
||||
ret = []
|
||||
domain_params[:contacts_attributes].each do |_k, v|
|
||||
next if v['code'].blank?
|
||||
|
||||
ret << {
|
||||
contact: { value: v['code'], attrs: { type: v['type'] } }
|
||||
}
|
||||
end
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
def create_dnskeys_hash(domain_params)
|
||||
ret = []
|
||||
domain_params[:dnskeys_attributes].each do |_k, v|
|
||||
if v['ds_key_tag'].blank?
|
||||
kd = create_key_data_hash(v)
|
||||
if kd
|
||||
ret << {
|
||||
keyData: kd
|
||||
}
|
||||
end
|
||||
else
|
||||
ret << {
|
||||
dsData: [
|
||||
keyTag: { value: v['ds_key_tag'] },
|
||||
alg: { value: v['ds_alg'] },
|
||||
digestType: { value: v['ds_digest_type'] },
|
||||
digest: { value: v['ds_digest'] },
|
||||
keyData: create_key_data_hash(v)
|
||||
]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
def create_key_data_hash(key_data_params)
|
||||
return nil if key_data_params['public_key'].blank?
|
||||
|
||||
{
|
||||
flags: { value: key_data_params['flags'] },
|
||||
protocol: { value: key_data_params['protocol'] },
|
||||
alg: { value: key_data_params['alg'] },
|
||||
pubKey: { value: key_data_params['public_key'] }
|
||||
}
|
||||
end
|
||||
|
||||
def array_difference(x, y)
|
||||
ret = x.dup
|
||||
y.each do |element|
|
||||
index = ret.index(element)
|
||||
ret.delete_at(index) if index
|
||||
end
|
||||
ret
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,66 +0,0 @@
|
|||
module Depp
|
||||
class User
|
||||
include ActiveModel::Validations
|
||||
include ActiveModel::Conversion
|
||||
extend ActiveModel::Naming
|
||||
|
||||
attr_accessor :tag, :password, :pki
|
||||
|
||||
validates :tag, :password, presence: true
|
||||
|
||||
validate :validate_existance_in_server
|
||||
|
||||
def initialize(args = {})
|
||||
args.each { |k, v| send("#{k}=", v) }
|
||||
end
|
||||
|
||||
def server
|
||||
client_cert = File.read(ENV['cert_path'])
|
||||
client_key = File.read(ENV['key_path'])
|
||||
port = ENV['epp_port'] || '700'
|
||||
|
||||
@server_cache ||= Epp::Server.new({
|
||||
server: ENV['epp_hostname'],
|
||||
tag: tag,
|
||||
password: password,
|
||||
port: port,
|
||||
cert: OpenSSL::X509::Certificate.new(client_cert),
|
||||
key: OpenSSL::PKey::RSA.new(client_key)
|
||||
})
|
||||
end
|
||||
|
||||
def request(xml)
|
||||
Nokogiri::XML(server.request(xml)).remove_namespaces!
|
||||
rescue EppErrorResponse => e
|
||||
Nokogiri::XML(e.response_xml.to_s).remove_namespaces!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_existance_in_server
|
||||
return if errors.any?
|
||||
res = server.open_connection
|
||||
unless Nokogiri::XML(res).css('greeting')
|
||||
errors.add(:base, :failed_to_open_connection_to_epp_server)
|
||||
server.close_connection # just in case
|
||||
return
|
||||
end
|
||||
|
||||
ex = EppXml::Session.new(cl_trid_prefix: tag)
|
||||
xml = ex.login(clID: { value: tag }, pw: { value: password })
|
||||
res = server.send_request(xml)
|
||||
|
||||
if Nokogiri::XML(res).css('result').first['code'] != '1000'
|
||||
errors.add(:base, Nokogiri::XML(res).css('result').text)
|
||||
end
|
||||
|
||||
server.close_connection
|
||||
|
||||
rescue OpenSSL::SSL::SSLError => e
|
||||
Rails.logger.error "INVALID CERT: #{e}"
|
||||
Rails.logger.error "INVALID CERT DEBUG INFO: epp_hostname: #{ENV['epp_hostname']}," \
|
||||
"port: #{ENV['epp_port']}, cert_path: #{ENV['cert_path']}, key_path: #{ENV['key_path']}"
|
||||
errors.add(:base, :invalid_cert)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -25,10 +25,10 @@ class Dnskey < ApplicationRecord
|
|||
}
|
||||
|
||||
# IANA numbers, single authority list
|
||||
ALGORITHMS = Depp::Dnskey::ALGORITHMS.map {|pair| pair[1].to_s}.freeze
|
||||
PROTOCOLS = %w(3)
|
||||
FLAGS = %w(0 256 257) # 256 = ZSK, 257 = KSK
|
||||
DS_DIGEST_TYPE = [1,2]
|
||||
ALGORITHMS = %w[3 5 6 7 8 10 13 14 15 16].freeze
|
||||
PROTOCOLS = %w[3].freeze
|
||||
FLAGS = %w[0 256 257].freeze # 256 = ZSK, 257 = KSK
|
||||
DS_DIGEST_TYPE = [1, 2].freeze
|
||||
RESOLVERS = ENV['dnssec_resolver_ips'].to_s.strip.split(', ').freeze
|
||||
self.ignored_columns = %w[legacy_domain_id]
|
||||
|
||||
|
|
|
@ -13,6 +13,22 @@ class Domain < ApplicationRecord
|
|||
include Domain::Disputable
|
||||
include Domain::BulkUpdatable
|
||||
|
||||
PERIODS = [
|
||||
['3 months', '3m'],
|
||||
['6 months', '6m'],
|
||||
['9 months', '9m'],
|
||||
['1 year', '1y'],
|
||||
['2 years', '2y'],
|
||||
['3 years', '3y'],
|
||||
['4 years', '4y'],
|
||||
['5 years', '5y'],
|
||||
['6 years', '6y'],
|
||||
['7 years', '7y'],
|
||||
['8 years', '8y'],
|
||||
['9 years', '9y'],
|
||||
['10 years', '10y'],
|
||||
].freeze
|
||||
|
||||
attr_accessor :roles,
|
||||
:legal_document_id,
|
||||
:is_admin,
|
||||
|
@ -49,7 +65,6 @@ class Domain < ApplicationRecord
|
|||
statuses.include? DomainStatus::SERVER_REGISTRANT_CHANGE_PROHIBITED
|
||||
end
|
||||
|
||||
|
||||
# NB! contacts, admin_contacts, tech_contacts are empty for a new record
|
||||
has_many :domain_contacts, dependent: :destroy
|
||||
has_many :contacts, through: :domain_contacts, source: :contact
|
||||
|
|
|
@ -105,6 +105,9 @@ class Epp::Domain < Domain
|
|||
max: Setting.ns_max_count
|
||||
}
|
||||
],
|
||||
'2502' => [ # Rate limit exceeded
|
||||
%i[base session_limit_exceeded],
|
||||
],
|
||||
]
|
||||
}
|
||||
end
|
||||
|
|
|
@ -62,7 +62,7 @@ module Epp
|
|||
2308 => 'Data management policy violation',
|
||||
2400 => 'Command failed',
|
||||
2501 => 'Authentication error; server closing connection',
|
||||
2502 => 'Session limit exceeded; server closing connection',
|
||||
2502 => Shunter.default_error_message,
|
||||
}.freeze
|
||||
private_constant :DEFAULT_DESCRIPTIONS
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class LegalDocument < ApplicationRecord
|
||||
class LegalDocument < ApplicationRecord # rubocop:disable Metrics/ClassLength
|
||||
include EppErrors
|
||||
MIN_BODY_SIZE = (1.37 * 3.kilobytes).ceil
|
||||
MAX_BODY_SIZE = 8.megabytes
|
||||
|
@ -14,7 +14,7 @@ class LegalDocument < ApplicationRecord
|
|||
|
||||
belongs_to :documentable, polymorphic: true
|
||||
|
||||
validate :val_body_length, if: ->(file) { file.path.blank? }
|
||||
validate :val_body_length, if: ->(file) { file.path.blank? && (Rails.env.production? || Rails.env.test?) }
|
||||
|
||||
before_create :add_creator
|
||||
before_save :save_to_filesystem, if: :body
|
||||
|
@ -24,7 +24,7 @@ class LegalDocument < ApplicationRecord
|
|||
'2308' => [
|
||||
%i[body length_more_than],
|
||||
%i[body length_less_than],
|
||||
]
|
||||
],
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -41,12 +41,13 @@ class LegalDocument < ApplicationRecord
|
|||
digest = Digest::SHA1.new.update(binary).to_s
|
||||
|
||||
loop do
|
||||
rand = SecureRandom.random_number.to_s.last(4)
|
||||
next if rand.to_i == 0 || rand.length < 4
|
||||
dir = "#{ENV['legal_documents_dir']}/#{Time.zone.now.strftime('%Y/%m/%d')}"
|
||||
FileUtils.mkdir_p(dir, mode: 0775)
|
||||
self.path = "#{dir}/#{Time.zone.now.to_formatted_s(:number)}_#{rand}.#{document_type}"
|
||||
break unless File.file?(path)
|
||||
rand = SecureRandom.random_number.to_s.last(4)
|
||||
next if rand.to_i.zero? || rand.length < 4
|
||||
|
||||
dir = "#{ENV['legal_documents_dir']}/#{Time.zone.now.strftime('%Y/%m/%d')}"
|
||||
FileUtils.mkdir_p(dir, mode: 0775)
|
||||
self.path = "#{dir}/#{Time.zone.now.to_formatted_s(:number)}_#{rand}.#{document_type}"
|
||||
break unless File.file?(path)
|
||||
end
|
||||
|
||||
File.open(path, 'wb') { |f| f.write(binary) } unless Rails.env.test?
|
||||
|
@ -69,50 +70,57 @@ class LegalDocument < ApplicationRecord
|
|||
start = Time.zone.now.to_f
|
||||
Rails.logger.info '-----> Removing legal documents duplicates'
|
||||
count = 0
|
||||
modified = Array.new
|
||||
modified = []
|
||||
|
||||
LegalDocument.where(documentable_type: "Domain").where.not(checksum: [nil, ""]).find_each do |orig_legal|
|
||||
LegalDocument.where(documentable_type: 'Domain')
|
||||
.where.not(checksum: [nil, ''])
|
||||
.find_each do |orig_legal|
|
||||
next if modified.include?(orig_legal.checksum)
|
||||
next if !File.exist?(orig_legal.path)
|
||||
next unless File.exist?(orig_legal.path)
|
||||
|
||||
modified.push(orig_legal.checksum)
|
||||
|
||||
LegalDocument.where(documentable_type: "Domain", documentable_id: orig_legal.documentable_id).
|
||||
where(checksum: orig_legal.checksum).
|
||||
where.not(id: orig_legal.id).where.not(path: orig_legal.path).each do |new_legal|
|
||||
unless modified.include?(orig_legal.id)
|
||||
File.delete(new_legal.path) if File.exist?(new_legal.path)
|
||||
new_legal.update(path: orig_legal.path)
|
||||
count += 1
|
||||
Rails.logger.info "File #{new_legal.path} has been removed by Domain "\
|
||||
"#{new_legal.documentable_id}. Document id: #{new_legal.id}"
|
||||
end
|
||||
LegalDocument.where(documentable_type: 'Domain', documentable_id: orig_legal.documentable_id)
|
||||
.where(checksum: orig_legal.checksum)
|
||||
.where.not(id: orig_legal.id)
|
||||
.where.not(path: orig_legal.path).each do |new_legal|
|
||||
next if modified.include?(orig_legal.id)
|
||||
|
||||
File.delete(new_legal.path) if File.exist?(new_legal.path)
|
||||
new_legal.update(path: orig_legal.path)
|
||||
count += 1
|
||||
Rails.logger.info "File #{new_legal.path} has been removed by Domain "\
|
||||
"#{new_legal.documentable_id}. Document id: #{new_legal.id}"
|
||||
end
|
||||
|
||||
contact_ids = Version::DomainVersion.where(item_id: orig_legal.documentable_id).distinct.
|
||||
pluck("object->>'registrant_id'", "object_changes->>'registrant_id'",
|
||||
"children->>'tech_contacts'", "children->>'admin_contacts'").flatten.uniq
|
||||
contact_ids = contact_ids.map{|id|
|
||||
contact_ids = Version::DomainVersion.where(item_id: orig_legal.documentable_id).distinct
|
||||
.pluck("object->>'registrant_id'",
|
||||
"object_changes->>'registrant_id'",
|
||||
"children->>'tech_contacts'",
|
||||
"children->>'admin_contacts'")
|
||||
.flatten.uniq
|
||||
contact_ids = contact_ids.map do |id|
|
||||
case id
|
||||
when Hash
|
||||
id["id"]
|
||||
when String
|
||||
JSON.parse(id) rescue id.to_i
|
||||
else
|
||||
id
|
||||
end
|
||||
}.flatten.compact.uniq
|
||||
LegalDocument.where(documentable_type: "Contact", documentable_id: contact_ids).
|
||||
where(checksum: orig_legal.checksum).where.not(path: orig_legal.path).each do |new_legal|
|
||||
unless modified.include?(orig_legal.id)
|
||||
File.delete(new_legal.path) if File.exist?(new_legal.path)
|
||||
new_legal.update(path: orig_legal.path)
|
||||
count += 1
|
||||
Rails.logger.info "File #{new_legal.path} has been removed by Contact "\
|
||||
"#{new_legal.documentable_id}. Document id: #{new_legal.id}"
|
||||
when Hash
|
||||
id['id']
|
||||
when String
|
||||
JSON.parse(id) rescue id.to_i
|
||||
else
|
||||
id
|
||||
end
|
||||
end.flatten.compact.uniq
|
||||
LegalDocument.where(documentable_type: 'Contact', documentable_id: contact_ids)
|
||||
.where(checksum: orig_legal.checksum)
|
||||
.where.not(path: orig_legal.path).each do |new_legal|
|
||||
next if modified.include?(orig_legal.id)
|
||||
|
||||
File.delete(new_legal.path) if File.exist?(new_legal.path)
|
||||
new_legal.update(path: orig_legal.path)
|
||||
count += 1
|
||||
Rails.logger.info "File #{new_legal.path} has been removed by Contact "\
|
||||
"#{new_legal.documentable_id}. Document id: #{new_legal.id}"
|
||||
end
|
||||
end
|
||||
Rails.logger.info "-----> Duplicates fixed for #{count} rows in #{(Time.zone.now.to_f - start).round(2)} seconds"
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,4 +3,8 @@ class Registrant < Contact
|
|||
def epp_code_map
|
||||
{}
|
||||
end
|
||||
|
||||
def publishable?
|
||||
registrant_publishable
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ class ValidationEvent < ApplicationRecord
|
|||
smtp: 1,
|
||||
}.freeze
|
||||
|
||||
store_accessor :event_data, :errors, :check_level, :email
|
||||
store_accessor :event_data, :check_level, :email
|
||||
|
||||
belongs_to :validation_eventable, polymorphic: true
|
||||
|
||||
|
|
|
@ -51,7 +51,9 @@ class WhoisRecord < ApplicationRecord
|
|||
end
|
||||
|
||||
h[:email] = registrant.email
|
||||
h[:registrant_changed] = registrant.updated_at.try(:to_s, :iso8601)
|
||||
h[:phone] = registrant.phone
|
||||
h[:registrant_publishable] = registrant.publishable?
|
||||
h[:registrant_changed] = registrant.updated_at.try(:to_s, :iso8601)
|
||||
h[:registrant_disclosed_attributes] = registrant.disclosed_attributes
|
||||
|
||||
h[:admin_contacts] = []
|
||||
|
@ -78,7 +80,6 @@ class WhoisRecord < ApplicationRecord
|
|||
h[:dnssec_keys] = domain.dnskeys.map { |key| "#{key.flags} #{key.protocol} #{key.alg} #{key.public_key}" }
|
||||
h[:dnssec_changed] = domain.dnskeys.pluck(:updated_at).max.try(:to_s, :iso8601) rescue nil
|
||||
|
||||
|
||||
h
|
||||
end
|
||||
|
||||
|
@ -112,8 +113,10 @@ class WhoisRecord < ApplicationRecord
|
|||
{
|
||||
name: contact.name,
|
||||
email: contact.email,
|
||||
phone: contact.phone,
|
||||
changed: contact.updated_at.try(:to_s, :iso8601),
|
||||
disclosed_attributes: contact.disclosed_attributes,
|
||||
contact_publishable: contact.registrant_publishable?,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
class Registrar::DomainListCsvPresenter
|
||||
def initialize(domains:, view:)
|
||||
@domains = domains
|
||||
@view = view
|
||||
end
|
||||
|
||||
def to_s
|
||||
table = CSV::Table.new([header])
|
||||
|
||||
domains.each do |domain|
|
||||
table << domain_to_row(domain: domain)
|
||||
end
|
||||
|
||||
table.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def header
|
||||
columns = %w[
|
||||
domain_name
|
||||
transfer_code
|
||||
registrant_name
|
||||
registrant_code
|
||||
expire_time
|
||||
]
|
||||
|
||||
columns.map! { |column| view.t("registrar.domains.index.csv.#{column}") }
|
||||
|
||||
CSV::Row.new(columns, [], true)
|
||||
end
|
||||
|
||||
def domain_to_row(domain:)
|
||||
row = []
|
||||
row[0] = domain.name
|
||||
row[1] = domain.transfer_code
|
||||
row[2] = domain.registrant.name
|
||||
row[3] = domain.registrant.code
|
||||
row[4] = domain.expire_date
|
||||
|
||||
CSV::Row.new([], row)
|
||||
end
|
||||
|
||||
attr_reader :domains, :view
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
- content_for :actions do
|
||||
= link_to(t(:add), new_admin_invoice_path, class: 'btn btn-primary')
|
||||
= render 'shared/title', name: t(:invoices)
|
||||
= render 'search_form'
|
||||
= render 'admin/invoices/partials/search_form'
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
|
|
|
@ -20,4 +20,4 @@
|
|||
%dd= @invoice.buyer_url
|
||||
|
||||
%dt= t(:email)
|
||||
%dd= @invoice.buyer_email
|
||||
%dd= @invoice.buyer_email
|
|
@ -36,4 +36,4 @@
|
|||
%dd=@invoice.description
|
||||
|
||||
%dt= Invoice.human_attribute_name :reference_no
|
||||
%dd= @invoice.reference_no
|
||||
%dd= @invoice.reference_no
|
|
@ -29,4 +29,4 @@
|
|||
%tr
|
||||
%th.no-border{colspan: 3}
|
||||
%th= t(:total)
|
||||
%td= number_to_currency @invoice.total
|
||||
%td= number_to_currency @invoice.total
|
|
@ -16,4 +16,4 @@
|
|||
%td= payment_order.channel
|
||||
%td= payment_order.status
|
||||
%td= payment_order.created_at
|
||||
%td= payment_order.notes
|
||||
%td= payment_order.notes
|
|
@ -69,10 +69,10 @@
|
|||
<span class="glyphicon glyphicon-search"></span>
|
||||
|
||||
</button>
|
||||
<%= link_to t('.download_btn'), admin_invoices_path(format: :csv, params: params.permit!),
|
||||
"data-toggle" => "tooltip", "data-placement" => "bottom", "title" => t('.download_btn'),
|
||||
<%= link_to t('admin.invoices.search_form.download_btn'), admin_invoices_path(format: :csv, params: params.permit!),
|
||||
"data-toggle" => "tooltip", "data-placement" => "bottom", "title" => t('admin.invoices.search_form.download_btn'),
|
||||
class: 'btn btn-default' %>
|
||||
<%= link_to t('.reset_btn'), admin_invoices_path, class: 'btn btn-default' %>
|
||||
<%= link_to t('admin.invoices.search_form.reset_btn'), admin_invoices_path, class: 'btn btn-default' %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
|
@ -35,4 +35,4 @@
|
|||
%dd= @invoice.seller_email
|
||||
|
||||
%dt= t(:issuer)
|
||||
%dd= @invoice.seller_contact_name
|
||||
%dd= @invoice.seller_contact_name
|
|
@ -20,14 +20,14 @@
|
|||
= render 'shared/full_errors', object: @invoice
|
||||
|
||||
.row
|
||||
.col-md-6= render 'registrar/invoices/partials/details'
|
||||
.col-md-6= render 'admin/invoices/partials/details'
|
||||
.row
|
||||
.col-md-6= render 'registrar/invoices/partials/seller'
|
||||
.col-md-6= render 'registrar/invoices/partials/buyer'
|
||||
.col-md-6= render 'admin/invoices/partials/seller'
|
||||
.col-md-6= render 'admin/invoices/partials/buyer'
|
||||
.row
|
||||
- if @invoice.monthly_invoice
|
||||
.col-md-12= render 'registrar/invoices/partials/monthly_invoice_items'
|
||||
- if @invoice.monthly_invoice
|
||||
.col-md-12= render 'admin/invoices/partials/monthly_invoice_items'
|
||||
- else
|
||||
.col-md-12= render 'registrar/invoices/partials/items'
|
||||
.col-md-12= render 'admin/invoices/partials/items'
|
||||
.row
|
||||
.col-md-12= render 'registrar/invoices/partials/payment_orders'
|
||||
.col-md-12= render 'admin/invoices/partials/payment_orders'
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue